mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 11:35:05 +08:00
Compare commits
671 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cf571602c | ||
|
|
a125f90d12 | ||
|
|
313cda5478 | ||
|
|
fc4e7eb18b | ||
|
|
0836519b2d | ||
|
|
5eeb250907 | ||
|
|
2e579d0dd3 | ||
|
|
8cd40db261 | ||
|
|
9d03959196 | ||
|
|
acd3b0258d | ||
|
|
0b49e60c22 | ||
|
|
6719443d99 | ||
|
|
5f6577df2e | ||
|
|
e87f307ac1 | ||
|
|
7e015a268b | ||
|
|
a679c53111 | ||
|
|
9e8d248044 | ||
|
|
055d646225 | ||
|
|
a2514b6916 | ||
|
|
0ac5e78040 | ||
|
|
a82221e3df | ||
|
|
bb734456f6 | ||
|
|
a219ca7371 | ||
|
|
c3b5e43a7a | ||
|
|
e7597d2e84 | ||
|
|
386ca1b9bb | ||
|
|
da3960c4f0 | ||
|
|
cd85762b09 | ||
|
|
d92b3a730c | ||
|
|
ffa53f14e5 | ||
|
|
b8bd906832 | ||
|
|
1c73d8d6f4 | ||
|
|
2c3fdb5eee | ||
|
|
4bbe52e3b4 | ||
|
|
2d241ed96b | ||
|
|
ba4bce06b1 | ||
|
|
f7e933aea1 | ||
|
|
dbcf77c9a9 | ||
|
|
8a9aa2da6c | ||
|
|
0e8143aefc | ||
|
|
4345e9e6a6 | ||
|
|
e7fa45d5ca | ||
|
|
abda0a07c2 | ||
|
|
9d22827395 | ||
|
|
7b665b3763 | ||
|
|
58692f397a | ||
|
|
2253fcc955 | ||
|
|
cbbae0c9bf | ||
|
|
ef513f27ac | ||
|
|
e8ae48fd3d | ||
|
|
434e508186 | ||
|
|
4a2b3e89b4 | ||
|
|
6c3f8c7ec5 | ||
|
|
3fffe061d5 | ||
|
|
729c985eaf | ||
|
|
75fb6c5f34 | ||
|
|
8bc9b1865a | ||
|
|
d6993c47d6 | ||
|
|
b8792e4084 | ||
|
|
2234dd48bc | ||
|
|
c8693e1e89 | ||
|
|
3ace4a61d2 | ||
|
|
bd3f865cf7 | ||
|
|
b68e71abfd | ||
|
|
6179bef160 | ||
|
|
983427ebb3 | ||
|
|
1b2ab34745 | ||
|
|
2713f03ec2 | ||
|
|
238083c174 | ||
|
|
78de3ee6d9 | ||
|
|
695081e079 | ||
|
|
2c5e2e1ded | ||
|
|
d151c48d1f | ||
|
|
35998bce81 | ||
|
|
a10520ca9e | ||
|
|
cb4a03ded2 | ||
|
|
31a0d17de5 | ||
|
|
5f765a35b9 | ||
|
|
5606346cc1 | ||
|
|
6faee8fd89 | ||
|
|
255c9bcaed | ||
|
|
25a3fdbcec | ||
|
|
8e450d869b | ||
|
|
e8ef7ad60c | ||
|
|
216eedcdcd | ||
|
|
fd55716633 | ||
|
|
0b920be381 | ||
|
|
e6dfccb6ba | ||
|
|
3129081050 | ||
|
|
00dac928c9 | ||
|
|
3726256514 | ||
|
|
5eb43505cb | ||
|
|
f7e516b775 | ||
|
|
4edd512902 | ||
|
|
acb263368a | ||
|
|
38b3805ad8 | ||
|
|
2ebaa2ad8e | ||
|
|
018c52b998 | ||
|
|
99d01e7967 | ||
|
|
e5670afc4c | ||
|
|
5aba96ce14 | ||
|
|
6b97fc1825 | ||
|
|
42cb5fe547 | ||
|
|
6a1718aa07 | ||
|
|
f980f40f8e | ||
|
|
5506486ed1 | ||
|
|
4a90d2fbe5 | ||
|
|
8767a4d6ba | ||
|
|
34bb2665cf | ||
|
|
1a79a9488d | ||
|
|
c91b707b66 | ||
|
|
a50ea929d6 | ||
|
|
d5b481ac9d | ||
|
|
8e69be0542 | ||
|
|
5296147c6b | ||
|
|
30fa074c8c | ||
|
|
02b1d15e42 | ||
|
|
82475c3b58 | ||
|
|
c421f3136d | ||
|
|
641a3663f5 | ||
|
|
acaede2a0d | ||
|
|
d8d1ebf23c | ||
|
|
926f0ae95d | ||
|
|
c5d5ce5f43 | ||
|
|
2fe950b0af | ||
|
|
a04bb01841 | ||
|
|
2d2de9dc26 | ||
|
|
81fc511f0a | ||
|
|
d85d813d62 | ||
|
|
9f6b571d79 | ||
|
|
292f393f99 | ||
|
|
f523f04ee2 | ||
|
|
88d8115306 | ||
|
|
9a050cb67f | ||
|
|
cf8046ecd9 | ||
|
|
6a292ec68c | ||
|
|
4679359688 | ||
|
|
bca81de210 | ||
|
|
ec1a65c18f | ||
|
|
ed559d9ed7 | ||
|
|
8995a584b9 | ||
|
|
30c81c9f01 | ||
|
|
11c7c1b77d | ||
|
|
93cb146f39 | ||
|
|
59dbe1d01e | ||
|
|
d6dc77d409 | ||
|
|
f8714a57d3 | ||
|
|
9f71255d6f | ||
|
|
d8bab034c2 | ||
|
|
9a25768617 | ||
|
|
e76528d929 | ||
|
|
00ad05c92a | ||
|
|
df95baa282 | ||
|
|
f42e2f59b7 | ||
|
|
d8b784482e | ||
|
|
b136f1e078 | ||
|
|
bd73775a2f | ||
|
|
1f133ea702 | ||
|
|
8acc7e4f76 | ||
|
|
00e2e8e502 | ||
|
|
e5013196ac | ||
|
|
658a3b0c6a | ||
|
|
4e9a2dace0 | ||
|
|
f7b389b7cd | ||
|
|
dac77ec0af | ||
|
|
32d73e62f4 | ||
|
|
b353ec463a | ||
|
|
36be731893 | ||
|
|
0389ef3b04 | ||
|
|
b2886dd2e9 | ||
|
|
af5d190bc4 | ||
|
|
5ca31f0965 | ||
|
|
c19a824a42 | ||
|
|
53c5a33ffd | ||
|
|
711d15958c | ||
|
|
99d7c52b4e | ||
|
|
342a59a408 | ||
|
|
9302b8904c | ||
|
|
bdbf5c0ef2 | ||
|
|
192ed942c4 | ||
|
|
56255f6de0 | ||
|
|
7ce830ea33 | ||
|
|
9a285986c4 | ||
|
|
62c547570a | ||
|
|
88e5013623 | ||
|
|
ea0fed24ec | ||
|
|
f863e346f5 | ||
|
|
7c527d8886 | ||
|
|
e51f93a5b4 | ||
|
|
50147a3d48 | ||
|
|
26acc25018 | ||
|
|
d8e1597726 | ||
|
|
2c004e6cb7 | ||
|
|
9cf9eb91bb | ||
|
|
fc9ab68837 | ||
|
|
be6ad74e1b | ||
|
|
2bdc22fbeb | ||
|
|
382b19e458 | ||
|
|
c63c0ba04b | ||
|
|
109579fa92 | ||
|
|
005544d974 | ||
|
|
07937f5f6c | ||
|
|
8bdd6bfc5e | ||
|
|
8b0d3557f3 | ||
|
|
436fa98f33 | ||
|
|
718fbac9be | ||
|
|
abaf390dfc | ||
|
|
9205ddc5b4 | ||
|
|
6bcb98e779 | ||
|
|
4722ad6be6 | ||
|
|
baa005ff71 | ||
|
|
76363a555c | ||
|
|
de70e12bbe | ||
|
|
eacc35d9e1 | ||
|
|
3040552580 | ||
|
|
24aaeb07cb | ||
|
|
ae15886a14 | ||
|
|
b2911e6d96 | ||
|
|
2735add7d0 | ||
|
|
0abb667c28 | ||
|
|
19dfec5f52 | ||
|
|
e0f01ddae7 | ||
|
|
2f8a0510b8 | ||
|
|
dbbe75fec6 | ||
|
|
c0b15fb186 | ||
|
|
f802b0eed9 | ||
|
|
cf9f9b40e7 | ||
|
|
1b2c00e228 | ||
|
|
587eabd829 | ||
|
|
80e0d45c09 | ||
|
|
f034276354 | ||
|
|
306455280a | ||
|
|
d9221c8491 | ||
|
|
249e1404c1 | ||
|
|
dd55b77543 | ||
|
|
c772fb98d1 | ||
|
|
1c1e5c50a9 | ||
|
|
5cc784f2fa | ||
|
|
983b9611ac | ||
|
|
a7f154d05a | ||
|
|
0e75428d62 | ||
|
|
fa34092ba2 | ||
|
|
f01818a3f8 | ||
|
|
732bc50a3a | ||
|
|
e9ffe12481 | ||
|
|
cca6f8da2d | ||
|
|
d391ef1747 | ||
|
|
4804586728 | ||
|
|
d08fd5c855 | ||
|
|
9cc884dfe6 | ||
|
|
e767770647 | ||
|
|
456ad17d05 | ||
|
|
5ee21ca6ab | ||
|
|
f706b51d14 | ||
|
|
d8895ae497 | ||
|
|
a807168816 | ||
|
|
a26c56629e | ||
|
|
8ee997b1bc | ||
|
|
27c71194ba | ||
|
|
c029def67d | ||
|
|
8bb6968ab8 | ||
|
|
cc9e3a5a81 | ||
|
|
e9cd94eea6 | ||
|
|
572fd063fc | ||
|
|
1052e45928 | ||
|
|
df561147ec | ||
|
|
9ce570fe28 | ||
|
|
20a20c72d4 | ||
|
|
7a8837bf2a | ||
|
|
b83d763a50 | ||
|
|
b2ab748fcb | ||
|
|
56e5a95cb6 | ||
|
|
214b133e5d | ||
|
|
f9bbe2a2c4 | ||
|
|
c5f90aabd6 | ||
|
|
77123f710b | ||
|
|
5c5c0ad94d | ||
|
|
5232ccb6e3 | ||
|
|
bc387477ce | ||
|
|
1c6eb85a12 | ||
|
|
ed950723cd | ||
|
|
e06087cb0b | ||
|
|
8cbc7819a6 | ||
|
|
7c588540d8 | ||
|
|
0e0763c820 | ||
|
|
e5d3f180dc | ||
|
|
5cb5e76872 | ||
|
|
742265c2c4 | ||
|
|
4e49cc49f8 | ||
|
|
09ca41ea36 | ||
|
|
896bbe8fc3 | ||
|
|
ed85d3028f | ||
|
|
8e33f11dc6 | ||
|
|
4bb547fdc7 | ||
|
|
8af5ecdb06 | ||
|
|
5a0517c1b8 | ||
|
|
5ed1bca57f | ||
|
|
d5892f3794 | ||
|
|
32aee7ef2f | ||
|
|
3a5d57603f | ||
|
|
c865999302 | ||
|
|
cb69a52d65 | ||
|
|
d915ed184c | ||
|
|
bdc205b994 | ||
|
|
46ccc37cae | ||
|
|
d7b96ea8c2 | ||
|
|
de9e28700a | ||
|
|
f5b2c4f7af | ||
|
|
79f7fba83c | ||
|
|
cb7f2ad8af | ||
|
|
5cdb58431a | ||
|
|
543d6d67e6 | ||
|
|
72e8a53046 | ||
|
|
deb7b2061a | ||
|
|
8a75104cbc | ||
|
|
e7f758f380 | ||
|
|
a4e5cf8bac | ||
|
|
0976d96419 | ||
|
|
e39f8bf7c4 | ||
|
|
9ed76fbb36 | ||
|
|
4b77170136 | ||
|
|
a168719905 | ||
|
|
c950530e44 | ||
|
|
5584e6376c | ||
|
|
fcd7e7dcea | ||
|
|
548a49ed93 | ||
|
|
68a7689108 | ||
|
|
58996c3d0d | ||
|
|
41925a1aa7 | ||
|
|
c834f7c559 | ||
|
|
a66262a787 | ||
|
|
3b51708160 | ||
|
|
ee6004a88d | ||
|
|
414da98c21 | ||
|
|
30ad3556dd | ||
|
|
67a121ef8e | ||
|
|
e7743587a1 | ||
|
|
1b66367d3d | ||
|
|
bc61516083 | ||
|
|
dae8c6cb9c | ||
|
|
bed1c669aa | ||
|
|
785b2881b6 | ||
|
|
ce08f071b1 | ||
|
|
e102857735 | ||
|
|
e973c42bfa | ||
|
|
4a16ca8bc0 | ||
|
|
f9e82170ac | ||
|
|
ad01be8866 | ||
|
|
40c7c5b348 | ||
|
|
66ea91270b | ||
|
|
44fb4fb594 | ||
|
|
16c849d085 | ||
|
|
e2835a7614 | ||
|
|
837bf652c5 | ||
|
|
ae5793f258 | ||
|
|
146244f1f4 | ||
|
|
fa7a04f535 | ||
|
|
db2c2e685d | ||
|
|
324b152307 | ||
|
|
09a68bbebd | ||
|
|
2b7773d933 | ||
|
|
aaef9fd91c | ||
|
|
15f37a301f | ||
|
|
807b5df17b | ||
|
|
2a3dcecfae | ||
|
|
a858719a4b | ||
|
|
c844cf7ec1 | ||
|
|
a4431b5cfd | ||
|
|
7e730cf171 | ||
|
|
9569900b9c | ||
|
|
5c190567e5 | ||
|
|
2ef374ff4a | ||
|
|
2c20734ad3 | ||
|
|
a4f8fc2205 | ||
|
|
4ed3e539fa | ||
|
|
3bc32d6e1b | ||
|
|
e05d6ec27c | ||
|
|
cfa8e639f1 | ||
|
|
bbe659ebfa | ||
|
|
bf5821e4ea | ||
|
|
a1dc006488 | ||
|
|
31c30aeb28 | ||
|
|
2516ed71d6 | ||
|
|
acbeb8fd30 | ||
|
|
ab5ac3aae8 | ||
|
|
da133d890f | ||
|
|
2736d1fd03 | ||
|
|
c7f18d7abe | ||
|
|
d5347a82cb | ||
|
|
e32470280d | ||
|
|
ceb5cd61e4 | ||
|
|
75339193d7 | ||
|
|
07da038b4b | ||
|
|
a2b597577f | ||
|
|
9cf2d9fa86 | ||
|
|
d45ced5c66 | ||
|
|
6aadb4ceea | ||
|
|
c956c65e33 | ||
|
|
86dfbc3e34 | ||
|
|
3fc59104f3 | ||
|
|
aae59ac281 | ||
|
|
e8a2047d4c | ||
|
|
56972a811c | ||
|
|
27086bfb97 | ||
|
|
93dfcc344b | ||
|
|
c2448c8881 | ||
|
|
26df99ae41 | ||
|
|
45cff25bbc | ||
|
|
5556668fc3 | ||
|
|
1b28d183fc | ||
|
|
15bbe9892e | ||
|
|
7236094421 | ||
|
|
c85c6f80e0 | ||
|
|
dd7811e5bc | ||
|
|
28c118a4e6 | ||
|
|
49b0619c9a | ||
|
|
0c3c6345e9 | ||
|
|
747baa1e16 | ||
|
|
2e5d2c1dcc | ||
|
|
300edb3318 | ||
|
|
0dfeea5213 | ||
|
|
d9150734c9 | ||
|
|
65514b73fd | ||
|
|
d366e04682 | ||
|
|
5151f9559b | ||
|
|
62c56b877f | ||
|
|
420a907776 | ||
|
|
184e976c5d | ||
|
|
6154e54661 | ||
|
|
73950e867f | ||
|
|
822aa00bd6 | ||
|
|
681808ca3d | ||
|
|
a0b40fc2da | ||
|
|
955c5570d8 | ||
|
|
2094c72c95 | ||
|
|
0795fe92fe | ||
|
|
9ce131e6be | ||
|
|
08b718995c | ||
|
|
4900955fc1 | ||
|
|
9d00e52c42 | ||
|
|
6c2bad610f | ||
|
|
27c6004191 | ||
|
|
500d385e6b | ||
|
|
5739946330 | ||
|
|
8a94256558 | ||
|
|
a66774d65f | ||
|
|
a9f159bae5 | ||
|
|
a6108b7930 | ||
|
|
43066656bd | ||
|
|
a9bf700da4 | ||
|
|
ee7dce68b8 | ||
|
|
a14cc82d46 | ||
|
|
b3dc772cd2 | ||
|
|
9bb9575c6d | ||
|
|
359cc9b1e7 | ||
|
|
6a9f61e69f | ||
|
|
21ea83027e | ||
|
|
f22a50b680 | ||
|
|
7217c7f1b2 | ||
|
|
cfb8e0882a | ||
|
|
f1fde32c29 | ||
|
|
c6a5c64448 | ||
|
|
b8f0a89846 | ||
|
|
684f7fb75e | ||
|
|
4dabb5d1f9 | ||
|
|
ea2c864265 | ||
|
|
7315865d34 | ||
|
|
6d987d083e | ||
|
|
6e9edcdd50 | ||
|
|
7a02110a42 | ||
|
|
9330e44817 | ||
|
|
5d7cb90bea | ||
|
|
a7b466e4a9 | ||
|
|
4c7e37d5fd | ||
|
|
d8dcfc0ab3 | ||
|
|
fb56873352 | ||
|
|
8c4ef5200c | ||
|
|
a5f7314ec9 | ||
|
|
4f444ee6ea | ||
|
|
651d6a4529 | ||
|
|
851b3d6d70 | ||
|
|
5c0cc771bc | ||
|
|
acebb5b0cf | ||
|
|
5f707e37b1 | ||
|
|
af585fec08 | ||
|
|
37e9ac453b | ||
|
|
7bb630db2a | ||
|
|
0e22e8aa76 | ||
|
|
492a1cda18 | ||
|
|
01a1c2f496 | ||
|
|
cf23005ff2 | ||
|
|
5ff640b142 | ||
|
|
6c3ae914fa | ||
|
|
654d7013c6 | ||
|
|
4d300e9d30 | ||
|
|
51a9524465 | ||
|
|
6817df534b | ||
|
|
1c8e51c9f9 | ||
|
|
8d7ee70e7d | ||
|
|
0c08f113ea | ||
|
|
8022c4826f | ||
|
|
0efe65a5bc | ||
|
|
ccbb3a2841 | ||
|
|
3d132e0e83 | ||
|
|
0a5a081a9d | ||
|
|
d16ef9bf2a | ||
|
|
748c35d5ef | ||
|
|
a1d3b7d65f | ||
|
|
1834bd6076 | ||
|
|
abde9d30c6 | ||
|
|
64adb3e3d7 | ||
|
|
b4e83ca7fd | ||
|
|
3efbe205ac | ||
|
|
55a86e1df3 | ||
|
|
712c1e2f95 | ||
|
|
6d7bfc37f6 | ||
|
|
8e7a2abec5 | ||
|
|
cc5f95d1ca | ||
|
|
62a49d234f | ||
|
|
8b55d01f78 | ||
|
|
1d7690f280 | ||
|
|
4ef23543ae | ||
|
|
a366f99d7d | ||
|
|
8c2c920076 | ||
|
|
338636092f | ||
|
|
e8d8d90b39 | ||
|
|
cb7094bb2d | ||
|
|
d9567ff3f9 | ||
|
|
3d0533ad84 | ||
|
|
153b04abc3 | ||
|
|
25bfbd3a6b | ||
|
|
5015c90fd0 | ||
|
|
e830472010 | ||
|
|
04f807ef2f | ||
|
|
55d50e2815 | ||
|
|
7266c5469a | ||
|
|
47d181aa92 | ||
|
|
dce3d9d517 | ||
|
|
e5a5804ff5 | ||
|
|
821e5d7bd7 | ||
|
|
52978df139 | ||
|
|
9aab12fc27 | ||
|
|
e83ab95279 | ||
|
|
7c0045a3b7 | ||
|
|
1f88e0465d | ||
|
|
cee1e74872 | ||
|
|
1f124bad9d | ||
|
|
71cec3c069 | ||
|
|
69204aec07 | ||
|
|
8b65cd73fc | ||
|
|
7ba0818b83 | ||
|
|
cb81303ded | ||
|
|
1b1cff1cae | ||
|
|
53bf302868 | ||
|
|
ef70530226 | ||
|
|
d073218df0 | ||
|
|
40ce6c0069 | ||
|
|
3c4c6e5a1c | ||
|
|
2e852e4398 | ||
|
|
04dee4e94d | ||
|
|
96557c2ca6 | ||
|
|
bf32c49a39 | ||
|
|
9becba3bc0 | ||
|
|
c177be0dd8 | ||
|
|
a5ff9b1c84 | ||
|
|
fe9e68ed24 | ||
|
|
2106260238 | ||
|
|
eed1d26191 | ||
|
|
6115ef0821 | ||
|
|
a63db5f31d | ||
|
|
2553bd7f37 | ||
|
|
2da0db4a31 | ||
|
|
5fc104c6a4 | ||
|
|
39066bf82b | ||
|
|
03192be245 | ||
|
|
b59ba5a127 | ||
|
|
c399611fc7 | ||
|
|
ccc44f3c5f | ||
|
|
b2f4d84272 | ||
|
|
97b8fa74a7 | ||
|
|
c679037085 | ||
|
|
793de9ec3e | ||
|
|
ccff8191dd | ||
|
|
d039a08b4e | ||
|
|
c0e8827cd5 | ||
|
|
11f976d9e9 | ||
|
|
7c83aafbf5 | ||
|
|
699e178f62 | ||
|
|
598d756af1 | ||
|
|
c2e2686b6a | ||
|
|
9df2b8f1fb | ||
|
|
1ba45bde13 | ||
|
|
5106ebae58 | ||
|
|
6b6bf7e458 | ||
|
|
2daaa94666 | ||
|
|
b129ed8f76 | ||
|
|
9fda7a15cb | ||
|
|
e38dc29411 | ||
|
|
7e3dc39cdd | ||
|
|
9c6589fa03 | ||
|
|
5e53ccab55 | ||
|
|
42b0a9a13d | ||
|
|
b504876646 | ||
|
|
a0a0d58be5 | ||
|
|
03571f831e | ||
|
|
83fe4d6c59 | ||
|
|
a83c483616 | ||
|
|
4c0931cc89 | ||
|
|
e52c46ec5e | ||
|
|
dd967ffa75 | ||
|
|
6474e07472 | ||
|
|
dc1e39264b | ||
|
|
74b196d2c3 | ||
|
|
4f9eb9f229 | ||
|
|
31c5ed69a7 | ||
|
|
6e00e6c34c | ||
|
|
9df725f1e9 | ||
|
|
f0720026fc | ||
|
|
6b4a16b337 | ||
|
|
f12ef07c02 | ||
|
|
59d771c4e4 | ||
|
|
e716290523 | ||
|
|
3ca168b329 | ||
|
|
4f45df2293 | ||
|
|
af0d77caf7 | ||
|
|
3a6862f278 | ||
|
|
2ad482ee2f | ||
|
|
be0d31f408 | ||
|
|
7c8e2a598f | ||
|
|
820a001ced | ||
|
|
a5b68c5ed9 | ||
|
|
f37738f6f8 | ||
|
|
4cc009ac3e | ||
|
|
5100125fef | ||
|
|
1c0d145874 | ||
|
|
0e48f57247 | ||
|
|
f9ec8f0b85 | ||
|
|
a4614a00e9 | ||
|
|
0ba45d343e | ||
|
|
2c26601bee | ||
|
|
10ada3c141 | ||
|
|
4912e84d46 | ||
|
|
81c7ef20eb | ||
|
|
ac22de84bf | ||
|
|
70f6480a5f | ||
|
|
95bfb7cdf2 | ||
|
|
b22186b2f1 | ||
|
|
70e53f547b | ||
|
|
8047f8177b | ||
|
|
95bf2f03ad | ||
|
|
ca6de641a1 | ||
|
|
bb811310d2 | ||
|
|
cd881c079b | ||
|
|
2319d4caf9 | ||
|
|
ac412fc15e | ||
|
|
4f7a216191 | ||
|
|
d87cdd7ff8 | ||
|
|
2c53cc7e70 | ||
|
|
b7bb81fbe7 | ||
|
|
a767540a2b | ||
|
|
f1251e8767 | ||
|
|
c1c0c2761d | ||
|
|
c69a87fa89 | ||
|
|
bf7f952d0e | ||
|
|
6aecc45ce1 | ||
|
|
bfc10a732a | ||
|
|
67d1536127 | ||
|
|
56db9f73d8 | ||
|
|
250d425b34 | ||
|
|
99140fc7df | ||
|
|
8fb8ee7e22 |
19
.cirrus.yml
19
.cirrus.yml
@@ -1,10 +1,10 @@
|
|||||||
task:
|
task:
|
||||||
name: freebsd-14-amd64
|
name: freebsd-14-amd64
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-14-2
|
image_family: freebsd-14-3
|
||||||
setup_script:
|
setup_script:
|
||||||
- pkg update
|
- pkg update
|
||||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
- pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
test_script:
|
test_script:
|
||||||
- ./scripts/cirrus/build_freebsd.sh
|
- ./scripts/cirrus/build_freebsd.sh
|
||||||
@@ -12,10 +12,21 @@ task:
|
|||||||
task:
|
task:
|
||||||
name: freebsd-15-amd64
|
name: freebsd-15-amd64
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-15-0-snap
|
image_family: freebsd-15-0-amd64-zfs
|
||||||
setup_script:
|
setup_script:
|
||||||
- pkg update
|
- pkg update
|
||||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
- pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
test_script:
|
test_script:
|
||||||
- ./scripts/cirrus/build_freebsd.sh
|
- ./scripts/cirrus/build_freebsd.sh
|
||||||
|
|
||||||
|
#task:
|
||||||
|
# name: freebsd-16-amd64
|
||||||
|
# freebsd_instance:
|
||||||
|
# image_family: freebsd-16-0-snap
|
||||||
|
# setup_script:
|
||||||
|
# - pkg update
|
||||||
|
# - pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
||||||
|
# - git submodule update --init --recursive
|
||||||
|
# test_script:
|
||||||
|
# - ./scripts/cirrus/build_freebsd.sh
|
||||||
|
|||||||
55
.github/workflows/c-cpp.yml
vendored
55
.github/workflows/c-cpp.yml
vendored
@@ -21,14 +21,12 @@ jobs:
|
|||||||
- os: ubuntu-22.04
|
- os: ubuntu-22.04
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: i386
|
targetarch: i386
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-22.04-arm
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: arm64
|
targetarch: arm64
|
||||||
cross: true
|
- os: ubuntu-22.04-arm
|
||||||
- os: ubuntu-22.04
|
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: armhf
|
targetarch: armhf
|
||||||
cross: true
|
|
||||||
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: riscv64
|
targetarch: riscv64
|
||||||
@@ -37,9 +35,6 @@ jobs:
|
|||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: ppc64el
|
targetarch: ppc64el
|
||||||
cross: true
|
cross: true
|
||||||
# - os: ubuntu-aarch64-22.04
|
|
||||||
# targetos: linux
|
|
||||||
# targetarch: aarch64
|
|
||||||
# - os: ubuntu-latest
|
# - os: ubuntu-latest
|
||||||
# targetos: linux
|
# targetos: linux
|
||||||
# targetarch: e2k-8c
|
# targetarch: e2k-8c
|
||||||
@@ -66,18 +61,21 @@ jobs:
|
|||||||
- os: macos-14 # arm64 as per github documentation
|
- os: macos-14 # arm64 as per github documentation
|
||||||
targetos: apple
|
targetos: apple
|
||||||
targetarch: arm64
|
targetarch: arm64
|
||||||
- os: macos-13 # x86 as per github documentation (will they fix it before they deprecate this version?..)
|
- os: macos-latest
|
||||||
|
targetos: ios
|
||||||
|
targetarch: arm64
|
||||||
|
- os: macos-15-intel
|
||||||
targetos: apple
|
targetos: apple
|
||||||
targetarch: amd64
|
targetarch: amd64
|
||||||
env:
|
env:
|
||||||
SDL_VERSION: 2.32.8
|
SDL_VERSION: 2.32.10
|
||||||
FFMPEG_VERSION: 7.1
|
FFMPEG_VERSION: 8.1
|
||||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||||
GH_CPU_OS: ${{ matrix.targetos }}
|
GH_CPU_OS: ${{ matrix.targetos }}
|
||||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -87,7 +85,7 @@ jobs:
|
|||||||
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
||||||
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
||||||
- name: Upload engine (artifacts)
|
- name: Upload engine (artifacts)
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
||||||
path: artifacts/*
|
path: artifacts/*
|
||||||
@@ -99,11 +97,11 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- app: su.xash.Engine.Compat.i386
|
- app: su.xash.Engine.Compat.i386
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-24.08
|
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
|
||||||
options: --privileged
|
options: --privileged
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Build flatpak (Compat.i386)
|
- name: Build flatpak (Compat.i386)
|
||||||
@@ -117,31 +115,10 @@ jobs:
|
|||||||
needs: [build, flatpak]
|
needs: [build, flatpak]
|
||||||
if: ${{ github.event_name == 'push' }}
|
if: ${{ github.event_name == 'push' }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
- name: Remove old release, fetch artifacts, repackage binaries and upload new release
|
- name: Remove old release, fetch artifacts, repackage binaries and upload new release
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
RELEASE_TAG: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
|
BASE_BUILDNUM_DATE: "2015-04-01"
|
||||||
run: |
|
run: bash scripts/gha/make_release.sh "Xash3D FWGS" "${{ github.ref_name }}"
|
||||||
gh release delete "$RELEASE_TAG" \
|
|
||||||
--yes \
|
|
||||||
--cleanup-tag \
|
|
||||||
--repo "$GITHUB_REPOSITORY" || true
|
|
||||||
gh run download "$GITHUB_RUN_ID" \
|
|
||||||
--dir artifacts/ \
|
|
||||||
--repo "$GITHUB_REPOSITORY"
|
|
||||||
pushd artifacts/
|
|
||||||
echo "Found artifacts:"
|
|
||||||
ls
|
|
||||||
for i in $(find -mindepth 1 -maxdepth 1 -type d); do
|
|
||||||
mv "$i"/* .
|
|
||||||
rm -rf "$i"
|
|
||||||
done
|
|
||||||
echo "Repackaged artifacts:"
|
|
||||||
ls -R
|
|
||||||
popd
|
|
||||||
sleep 20s
|
|
||||||
gh release create "$RELEASE_TAG" artifacts/* \
|
|
||||||
--title "Xash3D FWGS Continuous ${{ github.ref_name }} Build" \
|
|
||||||
--target $GITHUB_SHA \
|
|
||||||
--repo "$GITHUB_REPOSITORY" \
|
|
||||||
--prerelease
|
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -318,6 +318,12 @@ build-*
|
|||||||
*.includes
|
*.includes
|
||||||
*.files
|
*.files
|
||||||
|
|
||||||
|
# ios
|
||||||
|
ios/cl_dlls/*
|
||||||
|
ios/dlls/*
|
||||||
|
ios/*.framework
|
||||||
|
scripts/ios/mod-build
|
||||||
|
|
||||||
# Waf
|
# Waf
|
||||||
build_current
|
build_current
|
||||||
*waf-*/
|
*waf-*/
|
||||||
@@ -339,6 +345,7 @@ __pycache__
|
|||||||
.history/*
|
.history/*
|
||||||
.cache/*
|
.cache/*
|
||||||
enc_temp_folder/
|
enc_temp_folder/
|
||||||
|
Taskfile.yml
|
||||||
|
|
||||||
# KDevelop4
|
# KDevelop4
|
||||||
*.kdev4
|
*.kdev4
|
||||||
|
|||||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -39,4 +39,7 @@
|
|||||||
url = https://github.com/ianlancetaylor/libbacktrace
|
url = https://github.com/ianlancetaylor/libbacktrace
|
||||||
[submodule "3rdparty/maintui"]
|
[submodule "3rdparty/maintui"]
|
||||||
path = 3rdparty/maintui
|
path = 3rdparty/maintui
|
||||||
url = https://github.com/numas13/xash3d-maintui.git
|
url = https://github.com/FWGS/xash3d-maintui.git
|
||||||
|
[submodule "3rdparty/library_suffix"]
|
||||||
|
path = 3rdparty/library_suffix
|
||||||
|
url = https://github.com/FWGS/library-suffix.git
|
||||||
|
|||||||
2
3rdparty/MultiEmulator
vendored
2
3rdparty/MultiEmulator
vendored
Submodule 3rdparty/MultiEmulator updated: 11ff077ca5...6a56b7b112
2
3rdparty/libbacktrace/libbacktrace
vendored
2
3rdparty/libbacktrace/libbacktrace
vendored
Submodule 3rdparty/libbacktrace/libbacktrace updated: 793921876c...b9e40069c0
13
3rdparty/libbacktrace/wscript
vendored
13
3rdparty/libbacktrace/wscript
vendored
@@ -62,7 +62,7 @@ def options(opt):
|
|||||||
|
|
||||||
def configure(conf):
|
def configure(conf):
|
||||||
# add unsupported platforms here
|
# add unsupported platforms here
|
||||||
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos']:
|
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos', 'irix']:
|
||||||
conf.env.DISABLE_LIBBACKTRACE = True
|
conf.env.DISABLE_LIBBACKTRACE = True
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ def configure(conf):
|
|||||||
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr, 'compiler': 'c'}
|
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr, 'compiler': 'c'}
|
||||||
|
|
||||||
def check_frag(frag, msg, define, **kw):
|
def check_frag(frag, msg, define, **kw):
|
||||||
return dict({'fragment': frag, 'msg':'... %s' % msg, 'mandatory': False, 'compiler': 'c'}, **kw)
|
return dict({'fragment': frag, 'msg':'... %s' % msg, 'mandatory': False, 'define_name': define, 'compiler': 'c'}, **kw)
|
||||||
|
|
||||||
conf.multicheck(
|
conf.multicheck(
|
||||||
check_header('dlfcn.h'),
|
check_header('dlfcn.h'),
|
||||||
@@ -162,8 +162,13 @@ def build(bld):
|
|||||||
if bld.env.DISABLE_LIBBACKTRACE:
|
if bld.env.DISABLE_LIBBACKTRACE:
|
||||||
return
|
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']
|
||||||
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c', 'mmap.c', 'mmapio.c']
|
|
||||||
|
if bld.env.DEST_OS == 'win32':
|
||||||
|
sources += ['read.c', 'alloc.c']
|
||||||
|
else:
|
||||||
|
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
|
||||||
|
sources += ['mmap.c', 'mmapio.c']
|
||||||
|
|
||||||
if bld.env.DEST_BINFMT == 'pe':
|
if bld.env.DEST_BINFMT == 'pe':
|
||||||
sources += ['pecoff.c']
|
sources += ['pecoff.c']
|
||||||
|
|||||||
1
3rdparty/library_suffix
vendored
Submodule
1
3rdparty/library_suffix
vendored
Submodule
Submodule 3rdparty/library_suffix added at 6e14ae31e8
2
3rdparty/maintui
vendored
2
3rdparty/maintui
vendored
Submodule 3rdparty/maintui updated: eba8d49880...e5f143ee33
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: c62ab29356...af2b5abdde
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: 9f2b9512cd...36219aedfc
@@ -29,10 +29,11 @@
|
|||||||
|
|
||||||
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
||||||
* In short:
|
* In short:
|
||||||
* Use spaces in parenthesis.
|
* Use spaces in parenthesis, but not when two parentheses are consecutive.
|
||||||
* Only tabs for indentation.
|
* Only tabs for indentation.
|
||||||
* Any brace must have it's own line.
|
* Any brace must have it's own line.
|
||||||
* Short blocks, if statements and loops on single line are allowed.
|
* Short blocks, if statements and loops on single line are allowed.
|
||||||
|
* Prefer generic utilities from libpublic over rolling your own.
|
||||||
* Avoid magic numbers.
|
* Avoid magic numbers.
|
||||||
* While macros are powerful, it's better to avoid overusing them.
|
* While macros are powerful, it's better to avoid overusing them.
|
||||||
* If you unsure, try to mimic code style from anywhere else of engine source code.
|
* If you unsure, try to mimic code style from anywhere else of engine source code.
|
||||||
|
|||||||
103
Documentation/development/setting-up-qt-creator.md
Normal file
103
Documentation/development/setting-up-qt-creator.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
## Setting up Xash3D FWGS in Qt Creator
|
||||||
|
|
||||||
|
### Intro
|
||||||
|
|
||||||
|
Most versions of Qt Creator support using `compile_commands.json` as a project
|
||||||
|
file and Waf supports generating this file in a compliant format. In this
|
||||||
|
tutorial we will leverage that features.
|
||||||
|
|
||||||
|
The tutorial is written using Qt Creator 18.0, but I urge you to use whatever
|
||||||
|
latest Qt Creator version is available, as it's often has important bug fixes.
|
||||||
|
|
||||||
|
### Step 1. Configure the build.
|
||||||
|
|
||||||
|
`compile_commands.json` file, as it can be guessed from it's name, contains
|
||||||
|
every command used to invoke compiler during build. As the build process
|
||||||
|
depends on the build configuration, we have to configure it first. I'm not
|
||||||
|
going to get into details here, as basics of compiling Xash3D FWGS already
|
||||||
|
explained in `README.md`, located in repository root.
|
||||||
|
|
||||||
|
Save the configure step command somewhere, as it's going to be used later.
|
||||||
|
|
||||||
|
### Step 2. Generate `compile_commands.json` file.
|
||||||
|
|
||||||
|
Usually, this file is located in `build` directory after a successful build.
|
||||||
|
However, it's also possible to generate it manually by running follow command:
|
||||||
|
|
||||||
|
On *nix systems:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./waf clangdb
|
||||||
|
```
|
||||||
|
|
||||||
|
Or on Windows:
|
||||||
|
|
||||||
|
```
|
||||||
|
> waf.bat clangdb
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3. Load the project in Qt Creator.
|
||||||
|
|
||||||
|
To do this, you need to be sure that `Compilation Databases` plugin is enabled.
|
||||||
|
As it's considered experimental, it probably needs to be enabled manually. It
|
||||||
|
can be done in `Help` -> `About Plugins...`. Locate it in `Build Systems`
|
||||||
|
category, put the checkbox and press `OK`. The IDE will ask for restart, so do
|
||||||
|
this.
|
||||||
|
|
||||||
|
After IDE has been restarted, you can use `File` -> `Open File or Project...`.
|
||||||
|
Navigate to Xash3D FWGS directory, then to `build` directory and select
|
||||||
|
`compile_commands.json` file. If everything is done correctly, IDE will ask to
|
||||||
|
set up the project. Press `Configure Project` button, as most options there are
|
||||||
|
usually unapplicable to us.
|
||||||
|
|
||||||
|
Next IDE will show project tree, however you might not see any files. This is
|
||||||
|
happens as Qt Creator "thinks" our project root located in `build` directory.
|
||||||
|
Thankfully it provides a way to override this. To fix it, click with right
|
||||||
|
mouse button on the root of project tree (it's usually called something like
|
||||||
|
`build [master]`) and select `Change Root Directory`. In opened window choose
|
||||||
|
Xash3D FWGS repository root and press `OK`.
|
||||||
|
|
||||||
|
### Step 4. Tell IDE how to build this project.
|
||||||
|
|
||||||
|
Open `Projects` on the left menu and choose `Build Settings` tab. You should
|
||||||
|
see an empty configuration for build and clean steps. Press on `Add Build Step`
|
||||||
|
button and choose `Custom Process Step`.
|
||||||
|
|
||||||
|
In created step you should see `Command`, `Arguments` and `Working Directory`.
|
||||||
|
|
||||||
|
For the command, choose the Python executable. For arguments, use configure
|
||||||
|
command for Waf from the first step. Working directory is usually set by IDE
|
||||||
|
to `%{buildDir}`. You need to select the upper directory, where the `waf` is
|
||||||
|
located. To save some time, it can be specified as `%{buildDir}/../`.
|
||||||
|
|
||||||
|
Add another custom step, fill it with the same command and working directory.
|
||||||
|
For arguments use `waf build`.
|
||||||
|
|
||||||
|
Below you should see `Clean steps`. Create a clean step the same way, fill the
|
||||||
|
arguments and working directory as usual, for arguments use `waf clean`.
|
||||||
|
|
||||||
|
### Step 5. Tell IDE how to copy built binaries.
|
||||||
|
|
||||||
|
Now select `Deploy Settings` tab. Press `Add Deploy Step` -> `Custom Process
|
||||||
|
Step`. Again, same command and working directory. In arguments field type:
|
||||||
|
`waf install --destdir="<here put where Xash binaries should be copied to>"`.
|
||||||
|
|
||||||
|
### Step 6. Finally, set up Qt Creator to run the engine.
|
||||||
|
|
||||||
|
Select the `Run Settings` tab. Below you might see familiar text fields:
|
||||||
|
`Executable`, `Command line arguments` and `Working directory`.
|
||||||
|
|
||||||
|
For working directory click on `Browse...` button and select the folder where
|
||||||
|
Xash3D executable will be copied to, from previous step.
|
||||||
|
|
||||||
|
For executable type `./xash3d` if you're on *nix or `xash3d.exe` if you're on
|
||||||
|
Windows. The command line arguments are the same you use to run the engine. Can
|
||||||
|
be empty as well, but I personally use `-dev 2 -log` for extra verbosity.
|
||||||
|
|
||||||
|
### Outro
|
||||||
|
|
||||||
|
At this moment, you should be able to press `Run` button, wait until build
|
||||||
|
finishes and see running Xash3D FWGS. On Windows to use the debugger you might
|
||||||
|
need the `CDB` debugger and appropriate `qtcreatorcdbext` binary for debugging
|
||||||
|
32-bit applications and a separate for 64-bit, but that's left as an exercise
|
||||||
|
for the reader and a potential improvement for this document.
|
||||||
@@ -26,3 +26,12 @@ Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of
|
|||||||
|
|
||||||
* [Boosty page](https://boosty.to/snmetamorph)
|
* [Boosty page](https://boosty.to/snmetamorph)
|
||||||
* [Other donation methods](https://snmetamorph.github.io/donate)
|
* [Other donation methods](https://snmetamorph.github.io/donate)
|
||||||
|
|
||||||
|
## [$_Vladislav](https://github.com/Vladislav4KZ)
|
||||||
|
|
||||||
|
[YaPB Project](https://github.com/yapb) member, [Xash3D FWGS](https://github.com/FWGS/xash3d-fwgs) tester,
|
||||||
|
editor of the [Official YaPB Documentation](https://github.com/yapb/docs) (in English and Russian), curator of the [YaPB Graph Database](https://github.com/yapb/graph) and author of [YaPB Waypoint/Graph Pack](https://gamebanana.com/mods/40087).
|
||||||
|
|
||||||
|
Also does the Russian localization of text, images (gfx/shell), as well as additional menu buttons in English used in Xash3D FWGS for various mods.
|
||||||
|
|
||||||
|
* [Boosty page](https://boosty.to/rasstaman1337)
|
||||||
16
Documentation/extensions/addon-folders.md
Normal file
16
Documentation/extensions/addon-folders.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Addon folders in Xash3D FWGS
|
||||||
|
|
||||||
|
Xash3D FWGS supports both GoldSource-style addon folders and has few own. Each directory can have it's own archives that will be mounted with lower priority than directory itself.
|
||||||
|
|
||||||
|
Below is the mounts map, in order of precedence from least important to most important.
|
||||||
|
|
||||||
|
|--------------------|------|
|
||||||
|
| Directory | Note |
|
||||||
|
|--------------------|------|
|
||||||
|
| `$game/downloaded` | Always added. Used to store server downloads.|
|
||||||
|
| `$game` | This is the game directory. |
|
||||||
|
| `$game/custom` | Always added. Used for user modifications content. |
|
||||||
|
| `$game_hd` | Added with `fs_mount_hd` set to non-zero value. Used for high definition content, similar to GoldSrc.. |
|
||||||
|
| `$game_addon` | Added with `fs_mount_addon` set to non-zero value. Used for user modifications content, similar to GoldSrc. |
|
||||||
|
| `$game_lv` | Added with `fs_mount_lv` set to non-zero value. Used for low-violence content, similar to GoldSrc. |
|
||||||
|
| `$game_$language` | Added with `fs_mount_l10n` set to non-zero value. Language is controlled with `ui_language` cvar or `-language` command line switch. Used for localization content, similar to GoldSrc. |
|
||||||
@@ -42,3 +42,6 @@ Issue #3: Some mods (like The Specialists, Tyrian, ...) already apply suffixes _
|
|||||||
Resolution: On x86 on **Win/Lin/Mac**, don't change anything. Otherwise, strip the _i?86 part and follow the usual scheme.
|
Resolution: On x86 on **Win/Lin/Mac**, don't change anything. Otherwise, strip the _i?86 part and follow the usual scheme.
|
||||||
|
|
||||||
See discussion: https://github.com/FWGS/xash3d-fwgs/issues/39
|
See discussion: https://github.com/FWGS/xash3d-fwgs/issues/39
|
||||||
|
|
||||||
|
Issue #4: When distributing game libraries on Android inside an APK, they couldn't be loaded.
|
||||||
|
Resolution: Enable `useLegacyPackaging` option in build.gradle, when distributing games in APK. Always force game libraries to have `lib` prefix on Android, regardless if they are packaged in APK or not..
|
||||||
|
|||||||
8
Documentation/extensions/steam-broker.md
Normal file
8
Documentation/extensions/steam-broker.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Steam broker protocol
|
||||||
|
`sb_connect <ip:port> <server's steam id> <secure> <challenge>` - used for obtaining auth ticket during connection to GoldSrc server
|
||||||
|
|
||||||
|
`sb_disconnect <ip:port> <challenge>` - used for signaling broker about disconnecting from GoldSrc server
|
||||||
|
|
||||||
|
`sb_gamedir <gamedir>` - used for signaling broker about game startup and for announcing started mod, so broker could choose proper AppID for Steam API initialization
|
||||||
|
|
||||||
|
`sb_terminate` - used for signaling broker about game shutdown, ideally broker should be terminated too (and later restarted automatically and waiting for sb_gamedir message)
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
# Support for GoldSrc network protocol
|
# Support for GoldSrc network protocol
|
||||||
This feature is still work-in-progress, but for now it's available for all users, and we appreciate any bug-reports and contributions around it.
|
|
||||||
|
|
||||||
For connecting to GoldSrc-based servers, use this command:
|
For connecting to GoldSrc-based servers, use this command:
|
||||||
```
|
```
|
||||||
connect ip:port gs
|
connect ip:port gs
|
||||||
```
|
```
|
||||||
|
|
||||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion.
|
You need to use [Steam API broker](https://github.com/FWGS/steam-broker) and have purchased Half-Life 1 on your Steam account to be able to join GoldSrc servers.
|
||||||
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).
|
Broker will run on your PC and will be responsible for communicating with Steam client and obtaining auth tickets.
|
||||||
|
Also, make sure to set that broker as current ticket generator using console or edit `config.cfg` file manually:
|
||||||
|
```
|
||||||
|
cl_ticket_generator steam
|
||||||
|
```
|
||||||
|
|
||||||
Also, we encountered that some GoldSrc-based servers are recognizing Xash3D clients as "fake clients" and banning/kicking them. Maybe this problem will be
|
If you want to join GoldSrc servers from other device (Android/iOS or console), make sure to set proper broker IP address with `cl_steam_broker_addr` console variable. Default value assumed that broker is running on the same device as game client.
|
||||||
|
|
||||||
|
By the way, we encountered that some GoldSrc-based servers are recognizing Xash3D clients as "fake clients" and banning/kicking them. Maybe this problem will be
|
||||||
solved along with better compatibility with GoldSrc behavior, but may be not - we don't know logic behind this fake client checks.
|
solved along with better compatibility with GoldSrc behavior, but may be not - we don't know logic behind this fake client checks.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
ios_lib.h - dynamic library code for iOS
|
filename.ext - do not include this file, only copy the header
|
||||||
Copyright (C) 2017-2018 mittorn
|
Copyright (C) 2015-2025 Xash3D FWGS contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/sor modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
@@ -12,14 +12,4 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
#ifndef IOS_LIB_H
|
|
||||||
#define IOS_LIB_H
|
|
||||||
|
|
||||||
#define Platform_POSIX_LoadLibrary( x ) IOS_LoadLibrary(( x ))
|
|
||||||
|
|
||||||
void *IOS_LoadLibrary( const char *dllname );
|
|
||||||
|
|
||||||
#endif // IOS_LIB_H
|
|
||||||
#endif // TARGET_OS_IPHONE
|
|
||||||
@@ -16,6 +16,9 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
|
|||||||
## Battle Grounds
|
## Battle Grounds
|
||||||
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
|
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
|
||||||
|
|
||||||
|
## Brain Bread
|
||||||
|
Official github repository - https://github.com/IronOak-Studios/BrainBread
|
||||||
|
|
||||||
## Bubblemod
|
## Bubblemod
|
||||||
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
|
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
|
||||||
|
|
||||||
@@ -50,6 +53,9 @@ Alpha 2.0 - https://www.gamers-desire.de/details/2830
|
|||||||
## ESHQ
|
## ESHQ
|
||||||
Official github repository - https://github.com/adslbarxatov/xash3d-for-ESHQ
|
Official github repository - https://github.com/adslbarxatov/xash3d-for-ESHQ
|
||||||
|
|
||||||
|
## Feline
|
||||||
|
Available on ModDB - https://www.moddb.com/mods/feline-10/downloads/feline-sdk
|
||||||
|
|
||||||
## Flat-Life
|
## Flat-Life
|
||||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_(Flat-Life)
|
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_(Flat-Life)
|
||||||
|
|
||||||
@@ -64,6 +70,9 @@ Version 3.0, mirrored on github - https://github.com/nekonomicon/Go-mod30
|
|||||||
## GT mod
|
## GT mod
|
||||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
||||||
|
|
||||||
|
## Half-Force
|
||||||
|
Available on ModDB - https://www.moddb.com/mods/half-force/downloads/half-force-v20-sdk
|
||||||
|
|
||||||
## Half-Life: Advanced Deathmatch
|
## Half-Life: Advanced Deathmatch
|
||||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
|
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
|
||||||
|
|
||||||
@@ -76,6 +85,9 @@ Available on ModDB - https://www.moddb.com/mods/half-life-echoes
|
|||||||
## Half-Life: Expanded Arsenal
|
## Half-Life: Expanded Arsenal
|
||||||
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
|
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
|
||||||
|
|
||||||
|
## Half-Life: Field Intensity
|
||||||
|
Branch **field_intensity_1.7** in halflife-featureful - https://github.com/FreeSlave/halflife-featureful/tree/field_intensity_1.7
|
||||||
|
|
||||||
## Half-Life: Gravgun mod
|
## Half-Life: Gravgun mod
|
||||||
Branch **gravgun** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/gravgun
|
Branch **gravgun** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/gravgun
|
||||||
|
|
||||||
@@ -97,6 +109,9 @@ Official github repository - https://github.com/Fograin/hl-subsmod-ex
|
|||||||
## Half-Life: Rally
|
## Half-Life: Rally
|
||||||
Official gitlab repository - https://gitlab.com/hlrally/src
|
Official gitlab repository - https://gitlab.com/hlrally/src
|
||||||
|
|
||||||
|
## Half-Life: RXT
|
||||||
|
Available on ModDB - https://www.moddb.com/mods/half-life-rxt/downloads/rxt-source-code-v57
|
||||||
|
|
||||||
## Half-Life: Weapon Edition
|
## Half-Life: Weapon Edition
|
||||||
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
|
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
|
||||||
|
|
||||||
@@ -118,12 +133,17 @@ Official github repository - https://github.com/HeathGames/half_rats_parasomnia_
|
|||||||
## Half-Screwed
|
## Half-Screwed
|
||||||
Official github repository - https://github.com/desukuran/half-screwed
|
Official github repository - https://github.com/desukuran/half-screwed
|
||||||
|
|
||||||
|
## Halo: GoldSource
|
||||||
|
Available on ModDB - https://www.moddb.com/mods/halo-goldsrc/downloads/halo-gold-source-summer-2025-release-v10-sdk
|
||||||
|
|
||||||
## Headcrab Frenzy
|
## Headcrab Frenzy
|
||||||
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
|
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
|
||||||
|
|
||||||
## Heart of Evil
|
## Heart of Evil
|
||||||
Mirrored on github - https://github.com/nekonomicon/HeartOfEvil
|
Mirrored on github - https://github.com/nekonomicon/HeartOfEvil
|
||||||
|
|
||||||
|
Mirrored on github (Includes maps and models source files) - https://github.com/malortie/heart-of-evil-source-files
|
||||||
|
|
||||||
## Ingram Chillin' Mod
|
## Ingram Chillin' Mod
|
||||||
Official SourceForge repository - https://sourceforge.net/projects/icm-hl/
|
Official SourceForge repository - https://sourceforge.net/projects/icm-hl/
|
||||||
|
|
||||||
@@ -155,6 +175,9 @@ Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient
|
|||||||
|
|
||||||
Version 1.51, mirrored on github - https://github.com/a1batross/Paranoia2_original
|
Version 1.51, mirrored on github - https://github.com/a1batross/Paranoia2_original
|
||||||
|
|
||||||
|
## Public Enemy
|
||||||
|
Official github repository - https://github.com/IronOak-Studios/Public-Enemy
|
||||||
|
|
||||||
## Raven City
|
## Raven City
|
||||||
*Unfinished mod*
|
*Unfinished mod*
|
||||||
|
|
||||||
@@ -186,6 +209,9 @@ Mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-wastelan
|
|||||||
## Wizard Wars
|
## Wizard Wars
|
||||||
Download page on official site - http://www.thothie.com/ww/
|
Download page on official site - http://www.thothie.com/ww/
|
||||||
|
|
||||||
|
## Wrong Door
|
||||||
|
Available on ModDB - https://www.moddb.com/mods/wrong-door/downloads/wrong-door-sdk
|
||||||
|
|
||||||
## XashXT
|
## XashXT
|
||||||
Mirrored on github - https://github.com/a1batross/XashXT_original
|
Mirrored on github - https://github.com/a1batross/XashXT_original
|
||||||
|
|
||||||
@@ -251,6 +277,9 @@ Reverse-engineered code of server part by s1lentq - https://github.com/s1lentq/R
|
|||||||
## Counter Strike Online
|
## Counter Strike Online
|
||||||
CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
|
CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
|
||||||
|
|
||||||
|
## Crack-Life
|
||||||
|
Reverse-engineered code: branch **cracklife** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/cracklife
|
||||||
|
|
||||||
## Crack-Life: Campaign Mode
|
## Crack-Life: Campaign Mode
|
||||||
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
|
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
|
||||||
|
|
||||||
@@ -353,6 +382,9 @@ Deathmatch Quaked - https://www.moddb.com/games/deathmatch-classic/downloads/dmq
|
|||||||
|
|
||||||
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
|
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
|
||||||
|
|
||||||
|
## Delta Particles
|
||||||
|
Branch **delta_particles** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/delta_particles
|
||||||
|
|
||||||
## Half-Life: Echoes
|
## Half-Life: Echoes
|
||||||
Branch **echoes** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/echoes
|
Branch **echoes** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/echoes
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Table is sorted by status and platform.
|
|||||||
| PSVita | Supported | @fgsfdsfgs |
|
| PSVita | Supported | @fgsfdsfgs |
|
||||||
| Switch | Supported | @fgsfdsfgs |
|
| Switch | Supported | @fgsfdsfgs |
|
||||||
| Windows | Supported | @a1batross, @SNMetamorph |
|
| Windows | Supported | @a1batross, @SNMetamorph |
|
||||||
|
| iOS | Supported | @ksagameng2 |
|
||||||
| DOS4GW | Orphaned | N/A | Haven't been confirmed to work for a very long time
|
| DOS4GW | Orphaned | N/A | Haven't been confirmed to work for a very long time
|
||||||
| Haiku | Orphaned | N/A | Was added by #478 and #483
|
| Haiku | Orphaned | N/A | Was added by #478 and #483
|
||||||
| IRIX | Orphaned | N/A | Undone, compiles but requires big endian port
|
| IRIX | Orphaned | N/A | Undone, compiles but requires big endian port
|
||||||
@@ -35,4 +36,3 @@ Table is sorted by status and platform.
|
|||||||
| Emscripten | Old Engine | N/A |
|
| Emscripten | Old Engine | N/A |
|
||||||
| 3DS | Old Engine fork | N/A | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
| 3DS | Old Engine fork | N/A | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
||||||
| Oculus Quest | Old Engine fork | N/A | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
| Oculus Quest | Old Engine fork | N/A | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
||||||
| iOS | Deprecated | N/A | See GitHub issue #61
|
|
||||||
|
|||||||
11
Documentation/protocol/01-introduction.md
Normal file
11
Documentation/protocol/01-introduction.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Xash3D FWGS protocol support
|
||||||
|
|
||||||
|
Xash3D FWGS currently supports four network protocols:
|
||||||
|
* Version 49, introduced in Xash3D in around 2018.
|
||||||
|
* Version 48, used in Xash3D FWGS 0.19 and earlier. Deprecated and to be removed in the future.
|
||||||
|
* GoldSrc version 48, used in current GoldSource version.
|
||||||
|
* Quake version 15, only used for demo playback for Quake Wrapper mod.
|
||||||
|
|
||||||
|
On the server side, we only support Xash3D 49 protocol, but bugcomp `gsmrf` mode can convert GoldSrc 48 messages into Xash3D 49 on the fly, for some mods that directly write engine internal messages.
|
||||||
|
|
||||||
|
In the following documents we will only cover version 49, as everything else is either not Xash3D specific or deprecated.
|
||||||
305
Documentation/protocol/02-connectionless.md
Normal file
305
Documentation/protocol/02-connectionless.md
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
# Xash3D 49 connectionless protocol
|
||||||
|
|
||||||
|
Connectionless protocol defines four common message sources and destinations, they can be:
|
||||||
|
* `S` for Server
|
||||||
|
* `C` for Client
|
||||||
|
* `M` for Master
|
||||||
|
* `A` for Anything else
|
||||||
|
|
||||||
|
All connectionless packets have `\xff\xff\xff\xff` (32-bit integer set to all ones) in it's header. Let's go through each of possible direction in this document.
|
||||||
|
|
||||||
|
<!--TOC-->
|
||||||
|
|
||||||
|
- [Any](#any)
|
||||||
|
- [Any to Any](#any-to-any)
|
||||||
|
- [`A2A_NETINFO`](#a2a_netinfo)
|
||||||
|
- [`A2A_INFO`](#a2a_info)
|
||||||
|
- [`A2A_PING` and `A2A_GOLDSRC_PING`](#a2a_ping-and-a2a_goldsrc_ping)
|
||||||
|
- [`A2A_ACK` and `A2A_GOLDSRC_ACK`](#a2a_ack-and-a2a_goldsrc_ack)
|
||||||
|
- [Any to Client](#any-to-client)
|
||||||
|
- [`A2C_PRINT` and `A2C_GOLDSRC_PRINT`](#a2c_print-and-a2c_goldsrc_print)
|
||||||
|
- [Any to Server and Server to Any](#any-to-server-and-server-to-any)
|
||||||
|
- [`A2S_GOLDSRC_INFO`, `A2S_GOLDSRC_RULES` and `A2S_GOLDSRC_PLAYERS` and their responses](#a2s_goldsrc_info-a2s_goldsrc_rules-and-a2s_goldsrc_players-and-their-responses)
|
||||||
|
- [Any to Master](#any-to-master)
|
||||||
|
- [`S2M_SCAN_REQUEST`](#s2m_scan_request)
|
||||||
|
- [Master to Any](#master-to-any)
|
||||||
|
- [`M2A_SERVERSLIST`](#m2a_serverslist)
|
||||||
|
- [Master and game server](#master-and-game-server)
|
||||||
|
- [Server to Master](#server-to-master)
|
||||||
|
- [`S2M_HEARTBEAT`](#s2m_heartbeat)
|
||||||
|
- [`S2M_SHUTDOWN`](#s2m_shutdown)
|
||||||
|
- [`S2M_INFO`](#s2m_info)
|
||||||
|
- [Master to Server](#master-to-server)
|
||||||
|
- [`M2S_CHALLENGE`](#m2s_challenge)
|
||||||
|
- [`M2S_NAT_CONNECT`](#m2s_nat_connect)
|
||||||
|
- [Client and game server](#client-and-game-server)
|
||||||
|
- [Client to Server](#client-to-server)
|
||||||
|
- [`C2S_BANDWIDTHTEST`](#c2s_bandwidthtest)
|
||||||
|
- [`C2S_GETCHALLENGE`](#c2s_getchallenge)
|
||||||
|
- [`C2S_CONNECT`](#c2s_connect)
|
||||||
|
- [Server to Client](#server-to-client)
|
||||||
|
- [`S2C_BANDWIDTHTEST`](#s2c_bandwidthtest)
|
||||||
|
- [`S2C_CHALLENGE`](#s2c_challenge)
|
||||||
|
- [`S2C_CONNECTION`](#s2c_connection)
|
||||||
|
- [`S2C_ERRORMSG`](#s2c_errormsg)
|
||||||
|
- [`S2C_REJECT`](#s2c_reject)
|
||||||
|
|
||||||
|
<!--TOC-->
|
||||||
|
|
||||||
|
## Any
|
||||||
|
|
||||||
|
### Any to Any
|
||||||
|
|
||||||
|
#### `A2A_NETINFO`
|
||||||
|
|
||||||
|
Used to implement Half-Life's NetAPI.
|
||||||
|
* Request message, in ASCII: `netinfo <version> <context> <request_id>`
|
||||||
|
- `version` must be 49, as text.
|
||||||
|
- `context` can be any 32-bit signed integer value, encoded as text.
|
||||||
|
- `request_id` see `common/net_api.h`
|
||||||
|
|
||||||
|
* Response message, in ASCII: `netinfo <context> <request_id> <response>`
|
||||||
|
- `context` same as in request.
|
||||||
|
- `request_id` same as in request.
|
||||||
|
- `response` is server's response, depending on request type. Always encoded as Quake info string.
|
||||||
|
|
||||||
|
Possible requests and response formats:
|
||||||
|
* Request ID `1` will make server respond with empty response string.
|
||||||
|
* Request ID `2` makes server respond with all server game rule cvars where the key is cvar name and the value is cvar value. One additional key `rules` with total amount of cvars is added.
|
||||||
|
* Request ID `3` makes server respond with players list, where:
|
||||||
|
- `p<id>name` is set to player's name
|
||||||
|
- `p<id>frags` is set to player's kill count
|
||||||
|
- `p<id>time` is set to player's total play time
|
||||||
|
- `players` is total player's list.
|
||||||
|
- Alternatively, it can respond with `neterror` set to `forbidden` if server does not wish to expose it's player list.
|
||||||
|
* Request ID `4` makes server to respond with common game details:
|
||||||
|
- `hostname` is server's name
|
||||||
|
- `gamedir` is game directory name
|
||||||
|
- `current` is total player count
|
||||||
|
- `max` is max players limit
|
||||||
|
- `map` is server's current level
|
||||||
|
* On any other server will respond with `neterror` set to `undefined`
|
||||||
|
* If protocol version doesn't match, server responds with `neterror` set to `protocol`
|
||||||
|
|
||||||
|
#### `A2A_INFO`
|
||||||
|
|
||||||
|
Used to request server's details.
|
||||||
|
* Request message, in ASCII: `info <version>`
|
||||||
|
- `version` must be 49, as text
|
||||||
|
* Response message, in ASCII: `info\n<response>`
|
||||||
|
- `response` is Quake info string, otherwise it's an error message.
|
||||||
|
|
||||||
|
* Response info string format:
|
||||||
|
- `p` is set to protocol version (FWGS extension)
|
||||||
|
- `map` is server's current level
|
||||||
|
- `dm` set to 1 if current game mode is deathmatch otherwise 0
|
||||||
|
- `team` set to 1 if current game mode includes teamplay otherwise 0
|
||||||
|
- `coop` set to 1 if current game mode is cooperative otherwise 0
|
||||||
|
- `numcl` is total player count
|
||||||
|
- `maxcl` is max players limit
|
||||||
|
- `gamedir` is game directory name
|
||||||
|
- `password` set to 1 if server is protected with password otherwise 0
|
||||||
|
- `host` is server's name
|
||||||
|
|
||||||
|
#### `A2A_PING` and `A2A_GOLDSRC_PING`
|
||||||
|
|
||||||
|
Simple ping message.
|
||||||
|
* Request, in ASCII: `ping` or `i` in GoldSrc format
|
||||||
|
* Response is always `A2A_ACK` or `A2A_GOLDSRC_ACK`
|
||||||
|
|
||||||
|
#### `A2A_ACK` and `A2A_GOLDSRC_ACK`
|
||||||
|
|
||||||
|
Simple ack message.
|
||||||
|
* Request, in ASCII: `ack` or `j` in GoldSrc format
|
||||||
|
* Response: none
|
||||||
|
|
||||||
|
### Any to Client
|
||||||
|
|
||||||
|
#### `A2C_PRINT` and `A2C_GOLDSRC_PRINT`
|
||||||
|
|
||||||
|
Simple print message.
|
||||||
|
* Header: `\xff\xff\xff\xff`
|
||||||
|
* Request, in ASCII: `print <message>` or `l<message>` in GoldSrc format.
|
||||||
|
* Response: none
|
||||||
|
|
||||||
|
### Any to Server and Server to Any
|
||||||
|
|
||||||
|
#### `A2S_GOLDSRC_INFO`, `A2S_GOLDSRC_RULES` and `A2S_GOLDSRC_PLAYERS` and their responses
|
||||||
|
|
||||||
|
These match Source Engine Query messages used in GoldSrc and Source engine and implemented for compatibility with existing tools. Read documentation for them on VDC: https://developer.valvesoftware.com/wiki/Server_queries
|
||||||
|
|
||||||
|
### Any to Master
|
||||||
|
|
||||||
|
#### `S2M_SCAN_REQUEST`
|
||||||
|
|
||||||
|
* Request: `1<region><IP:Port>\0<info>`
|
||||||
|
- Format of this message is loosely based on https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol
|
||||||
|
- `info` however adds few additional fields:
|
||||||
|
- `clver` set to engine's version
|
||||||
|
- `nat` set to 1 to filter only servers behind NAT and tell master to notify servers about scan
|
||||||
|
- `commit` set to engine's build commit hash
|
||||||
|
- `branch` set to engine's build branch
|
||||||
|
- `os` set to which operating system engine has been built
|
||||||
|
- `arch` set to which CPU architecture engine has been built
|
||||||
|
- `buildnum` set to engine's build number
|
||||||
|
- `key` set to random 32-bit value formatted as hex, used to validate master responses
|
||||||
|
* Response: `M2A_SERVERSLIST`
|
||||||
|
|
||||||
|
### Master to Any
|
||||||
|
|
||||||
|
#### `M2A_SERVERSLIST`
|
||||||
|
|
||||||
|
* Request: `f\xff<key><reserved><IP:Port>...`
|
||||||
|
- `key` is random 32-bit value set in `S2M_SCAN_REQUEST`
|
||||||
|
- `reserved` is single reserved 8-bit byte
|
||||||
|
- Following is list of IP addresses in binary form: 6-bytes for IPv4 address + port and 18-bytes for IPv6 address + port
|
||||||
|
- If port is 0, it means the end of list, otherwise it's the last IP used for pagination (not implemented in Xash3D)
|
||||||
|
* Response: client doesn't make response to master server but might request `A2S_INFO` from servers
|
||||||
|
|
||||||
|
## Master and game server
|
||||||
|
|
||||||
|
### Server to Master
|
||||||
|
|
||||||
|
#### `S2M_HEARTBEAT`
|
||||||
|
|
||||||
|
Used to update game server information on the master server.
|
||||||
|
|
||||||
|
* Request: `q\xff<heartbeat challenge>`
|
||||||
|
- `heartbeat challenge` is random 32-bit value, used to prevent faked/forged source IP addresses.
|
||||||
|
* Response: `M2S_CHALLENGE`
|
||||||
|
|
||||||
|
#### `S2M_SHUTDOWN`
|
||||||
|
|
||||||
|
Used to notify master server about server shutdown, but due to security reasons must be ignored by any master implementation.
|
||||||
|
|
||||||
|
* Request: `\x62\x0a`
|
||||||
|
* Response: none
|
||||||
|
|
||||||
|
#### `S2M_INFO`
|
||||||
|
|
||||||
|
Game server info response on `M2S_CHALLENGE`.
|
||||||
|
|
||||||
|
* Request: `0\n<info>`
|
||||||
|
- `info` is Quake info string containing server information passed to master server. It contains following fields:
|
||||||
|
- `protocol` is always 49
|
||||||
|
- `challenge` is master challenge
|
||||||
|
- `players` is total player count, without bots
|
||||||
|
- `max` is max players limits
|
||||||
|
- `bots` is total bot count
|
||||||
|
- `gamedir` is set to game directory
|
||||||
|
- `map` is server's current level
|
||||||
|
- `type` set to `d` for dedicated or `l` for listen server
|
||||||
|
- `password` set to `1` if server protected with password set otherwise `0`
|
||||||
|
- `os` always `w`
|
||||||
|
- `secure` always `0`
|
||||||
|
- `lan` always `0`
|
||||||
|
- `version` engine version
|
||||||
|
- `region` always `255`
|
||||||
|
- `product` same as `gamedir`
|
||||||
|
- `nat` set to `1` if server is behind NAT
|
||||||
|
* Response: none
|
||||||
|
|
||||||
|
### Master to Server
|
||||||
|
|
||||||
|
#### `M2S_CHALLENGE`
|
||||||
|
|
||||||
|
Master's respoonse on game server's heartbeat message.
|
||||||
|
|
||||||
|
* Request: `s<master challenge><heartbeat challenge>`
|
||||||
|
- `master challenge` contains 32-bit value, used in server response to prevent faked/forged source IP addresses.
|
||||||
|
- `heartbat challenge` cotnains 32-bit value, used in heartbeat request to prevent faked/forged source IP addresses.
|
||||||
|
* Response: `S2M_INFO`.
|
||||||
|
|
||||||
|
#### `M2S_NAT_CONNECT`
|
||||||
|
|
||||||
|
Master server's message with client IP address and port, used in NAT punching.
|
||||||
|
|
||||||
|
* Request: `c <IP:Port>`
|
||||||
|
* Response: `S2C_INFO` to a specified client address.
|
||||||
|
|
||||||
|
## Client and game server
|
||||||
|
|
||||||
|
### Client to Server
|
||||||
|
|
||||||
|
#### `C2S_BANDWIDTHTEST`
|
||||||
|
|
||||||
|
Used to figure out network MTU. The message is optional and server might choose to not implement it or respond with challenge.
|
||||||
|
|
||||||
|
* Request, in ASCII: `bandwidth <version> <max_size>`
|
||||||
|
- `version` must be 49, as text.
|
||||||
|
- `max_size` is requested maximum packet size.
|
||||||
|
|
||||||
|
* Possible responses:
|
||||||
|
- `S2C_BANDWIDTHTEST`
|
||||||
|
- `S2C_CHALLENGE`
|
||||||
|
- `A2A_PRINT` followed by `S2C_REJECT`
|
||||||
|
- `S2C_ERRORMSG` (as FWGS extension) followed by `A2A_PRINT` and `S2C_REJECT`.
|
||||||
|
|
||||||
|
#### `C2S_GETCHALLENGE`
|
||||||
|
|
||||||
|
Used to validate client's address to prevent faked/forged source IP addresses.
|
||||||
|
|
||||||
|
* Header: `\xff\xff\xff\xff`
|
||||||
|
* Request, in ASCII: `getchallenge steam`
|
||||||
|
- `steam` argument is optional and can be ignored by the server, as it's only kept for compatibility with similar GoldSrc 48 message.
|
||||||
|
|
||||||
|
* Possible responses:
|
||||||
|
- `S2C_CHALLENGE`
|
||||||
|
|
||||||
|
#### `C2S_CONNECT`
|
||||||
|
|
||||||
|
Used to build a connection with the server.
|
||||||
|
|
||||||
|
* Header: `\xff\xff\xff\xff`
|
||||||
|
* Request, in ASCII: `connect <version> <challenge> "<protinfo>" "<userinfo>"`
|
||||||
|
- `version` must be 49, as text.
|
||||||
|
- `challenge` must be challenge value, as text.
|
||||||
|
- `protinfo` is a Quake info string, containing protocol extensions and other connection information.
|
||||||
|
- `uuid` is this client's unique ID (FWGS extension) hasheed with MD5.
|
||||||
|
- `qport` is random integer value from 1 to 65535, unique for this engine run.
|
||||||
|
- `ext` is an integer value OR'ed with requested protocol extensions. Currently only extension is `NET_EXT_SPLITSIZE` with the value of `1`, which tells server to split messages based on `cl_dlmax` value from `userinfo`.
|
||||||
|
- `userinfo` contains initial user info, encoded as Quake info string.
|
||||||
|
* Possible responses:
|
||||||
|
- `A2A_PRINT` followed by `S2C_REJECT`
|
||||||
|
- `S2C_ERRORMSG` (as FWGS extension) followed by `A2A_PRINT` and `S2C_REJECT`.
|
||||||
|
- `S2C_CONNECTION`
|
||||||
|
|
||||||
|
### Server to Client
|
||||||
|
|
||||||
|
#### `S2C_BANDWIDTHTEST`
|
||||||
|
|
||||||
|
* Request: `testpacket<crc><blob>`
|
||||||
|
- `crc` is 32-bit CRC of `blob`
|
||||||
|
- `blob` random data
|
||||||
|
* There is no required response to this message
|
||||||
|
|
||||||
|
Total message size doesn't exceed request max size.
|
||||||
|
|
||||||
|
#### `S2C_CHALLENGE`
|
||||||
|
|
||||||
|
* Request, in ASCII: `challenge <value>`
|
||||||
|
- `value` is challenge value that client must include in it's response
|
||||||
|
* Response: `C2S_CONNECT`
|
||||||
|
|
||||||
|
#### `S2C_CONNECTION`
|
||||||
|
|
||||||
|
* Request, in ASCII: `client_connect <protinfo>`
|
||||||
|
- `protinfo` is an optional Quake info string, contains following optional fields:
|
||||||
|
- `ext` is an integer value OR'ed with allowed protocol extension. Bit fields match requested in `ext` field in `C2S_CONNECT`
|
||||||
|
- `cheats` set to 1 if server allows cheats otherwise 0
|
||||||
|
* Response: there is no out of band from the client but client will proceed to building netchan and switch client-server interaction to it.
|
||||||
|
|
||||||
|
#### `S2C_ERRORMSG`
|
||||||
|
|
||||||
|
Show client error message. Doesn't mean connection reject, only used for UI.
|
||||||
|
|
||||||
|
* Request, in ASCII: `errormsg <message>`
|
||||||
|
- `message` contains error message
|
||||||
|
* Response: none
|
||||||
|
|
||||||
|
#### `S2C_REJECT`
|
||||||
|
|
||||||
|
Client has been rejected in connection.
|
||||||
|
|
||||||
|
* Request, in ASCII: `disconnect`
|
||||||
|
* Response: client can cope, get depressed or mentally tell server to fuck off.
|
||||||
3
Documentation/protocol/03-netchan.md
Normal file
3
Documentation/protocol/03-netchan.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Xash3D 49 netchan protocol
|
||||||
|
|
||||||
|
TBD...
|
||||||
@@ -962,53 +962,57 @@ Client: https://github.com/Velaron/cs16-client/
|
|||||||
|
|
||||||
Server: https://github.com/rehlds/ReGameDLL_CS
|
Server: https://github.com/rehlds/ReGameDLL_CS
|
||||||
|
|
||||||
15. **[Crack-Life: Campaign Mode](https://www.moddb.com/mods/crack-life)**
|
15. **[Crack-Life](https://www.moddb.com/mods/crack-life/downloads/crack-life)**
|
||||||
|
|
||||||
|
To run this mod on specific platforms you may be need to compile libraries from **cracklife** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
|
16. **[Crack-Life: Campaign Mode](https://www.moddb.com/mods/crack-life/downloads/crack-life-campaign-mode)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **clcampaign** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **clcampaign** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
16. **[Deathmatch Classic](https://store.steampowered.com/app/40/Deathmatch_Classic/)**
|
17. **[Deathmatch Classic](https://store.steampowered.com/app/40/Deathmatch_Classic/)**
|
||||||
|
|
||||||
Steam version already supports x86 Linux.
|
Steam version already supports x86 Linux.
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
17. **[Delta Particles](https://www.moddb.com/mods/half-life-delta)**
|
18. **[Delta Particles](https://www.moddb.com/mods/half-life-delta)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
18. **[Escape from the Darkness](https://www.moddb.com/mods/escape-from-the-darkness)**
|
19. **[Escape from the Darkness](https://www.moddb.com/mods/escape-from-the-darkness)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **eftd** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **eftd** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
19. **[Gang Wars](https://www.moddb.com/mods/gangwars)**
|
20. **[Gang Wars](https://www.moddb.com/mods/gangwars)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
20. **[Half-Life: Blue Shift](https://store.steampowered.com/app/130/HalfLife_Blue_Shift/)**
|
21. **[Half-Life: Blue Shift](https://store.steampowered.com/app/130/HalfLife_Blue_Shift/)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **bshift** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **bshift** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
21. **[Half-Life: Decay](https://www.moddb.com/mods/half-life-decay)**
|
22. **[Half-Life: Decay](https://www.moddb.com/mods/half-life-decay)**
|
||||||
|
|
||||||
Currently, you can compile mod libraries for x86 Linux from **decay-pc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
Currently, you can compile mod libraries for x86 Linux from **decay-pc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
22. **[Half-Life: Echoes](https://www.moddb.com/mods/half-life-echoes)**
|
23. **[Half-Life: Echoes](https://www.moddb.com/mods/half-life-echoes)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **echoes** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **echoes** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
23. **[Half-Life: Field Intensity](https://www.moddb.com/mods/field-intensity)**
|
24. **[Half-Life: Field Intensity](https://www.moddb.com/mods/field-intensity)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
24. **Half-Life: Gravgun** (unfinished) by *mittorn*, *a1batross* and *Solexid*
|
25. **Half-Life: Gravgun** (unfinished) by *mittorn*, *a1batross* and *Solexid*
|
||||||
|
|
||||||
*Support temporary abandoned*
|
*Support temporary abandoned*
|
||||||
|
|
||||||
@@ -1018,163 +1022,163 @@ Currently, MSVC is not supported, use MinGW if you need build for Windows.
|
|||||||
|
|
||||||
Mod files: [1](http://mittorn.fwgs.ru/coop-entpatches/), [2](http://mittorn.fwgs.ru/ggm/), [3](https://github.com/nillerusr/gravgun-extras).
|
Mod files: [1](http://mittorn.fwgs.ru/coop-entpatches/), [2](http://mittorn.fwgs.ru/ggm/), [3](https://github.com/nillerusr/gravgun-extras).
|
||||||
|
|
||||||
25. **[Half-Life: Induction 1.2](https://www.moddb.com/mods/half-life-induction)**
|
26. **[Half-Life: Induction 1.2](https://www.moddb.com/mods/half-life-induction)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **induction_1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **induction_1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
26. **[Half-Life: Invasion](https://www.moddb.com/mods/half-life-invasion)**
|
27. **[Half-Life: Invasion](https://www.moddb.com/mods/half-life-invasion)**
|
||||||
|
|
||||||
This mod supports x86 Linux.
|
This mod supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
27. **[Half-Life: Intense Force](https://www.moddb.com/downloads/intense-force)**
|
28. **[Half-Life: Intense Force](https://www.moddb.com/downloads/intense-force)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **intense_force** branch of [halflife-featureful](https://github.com/FreeSlave/halflife-featureful).
|
To run this mod on specific platforms you may be need to compile libraries from **intense_force** branch of [halflife-featureful](https://github.com/FreeSlave/halflife-featureful).
|
||||||
|
|
||||||
28. **[Half-Life: Opposing Force](https://store.steampowered.com/app/50/HalfLife_Opposing_Force/)**
|
29. **[Half-Life: Opposing Force](https://store.steampowered.com/app/50/HalfLife_Opposing_Force/)**
|
||||||
|
|
||||||
Steam version already supports x86 Linux.
|
Steam version already supports x86 Linux.
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **opfor** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **opfor** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
29. **[Half-Life: Quest mod](https://csm.dev/threads/half-life-the-quest-mod-isxodniki.38030/)**
|
30. **[Half-Life: Quest mod](https://csm.dev/threads/half-life-the-quest-mod-isxodniki.38030/)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **sci** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **sci** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
30. **[Half-Life: TopDown](https://www.moddb.com/mods/half-life-top-downs)**
|
31. **[Half-Life: TopDown](https://www.moddb.com/mods/half-life-top-downs)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **topdown** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **topdown** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
31. **[Half-Life: Urbicide](https://www.moddb.com/mods/half-life-urbicide)**
|
32. **[Half-Life: Urbicide](https://www.moddb.com/mods/half-life-urbicide)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **hl_urbicide** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **hl_urbicide** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
32. **[Half-Life: Visitors](https://www.moddb.com/mods/half-life-visitors)**
|
33. **[Half-Life: Visitors](https://www.moddb.com/mods/half-life-visitors)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **visitors** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **visitors** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
33. **[Half-Rats: Parasomnia](https://www.moddb.com/mods/half-rats-parasomnia/downloads/half-rats-parasomnia-v10b-steamlinux)**
|
34. **[Half-Rats: Parasomnia](https://www.moddb.com/mods/half-rats-parasomnia/downloads/half-rats-parasomnia-v10b-steamlinux)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
34. **[Half-Screwed: Death and Rebirth](https://www.moddb.com/mods/half-screwed)**
|
35. **[Half-Screwed: Death and Rebirth](https://www.moddb.com/mods/half-screwed)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **half-screwed** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **half-screwed** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
35. **[Half-Secret](https://www.moddb.com/mods/half-secret)**
|
36. **[Half-Secret](https://www.moddb.com/mods/half-secret)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **half-secret** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **half-secret** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
36. **[Natural Selection](https://www.moddb.com/mods/natural-selection)**
|
37. **[Natural Selection](https://www.moddb.com/mods/natural-selection)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
37. **[Night at the Office](https://www.moddb.com/mods/night-at-the-office)**
|
38. **[Night at the Office](https://www.moddb.com/mods/night-at-the-office)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **noffice** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **noffice** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
38. **[Paranoia](https://www.moddb.com/mods/paranoia)**
|
39. **[Paranoia](https://www.moddb.com/mods/paranoia)**
|
||||||
|
|
||||||
*Support temporary abandoned*
|
*Support temporary abandoned*
|
||||||
|
|
||||||
[Source code](https://github.com/FWGS/paranoia_toolkit).
|
[Source code](https://github.com/FWGS/paranoia_toolkit).
|
||||||
|
|
||||||
39. **[Poke646](https://poke646.com/)**
|
40. **[Poke646](https://poke646.com/)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **poke646** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **poke646** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
40. **[Poke646: Vendetta](https://poke646.com/)**
|
41. **[Poke646: Vendetta](https://poke646.com/)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **poke646_vendetta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **poke646_vendetta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
41. [PrimeXT](https://snmetamorph.github.io/PrimeXT/)
|
42. [PrimeXT](https://snmetamorph.github.io/PrimeXT/)
|
||||||
|
|
||||||
[Source code](https://github.com/SNMetamorph/PrimeXT)
|
[Source code](https://github.com/SNMetamorph/PrimeXT)
|
||||||
|
|
||||||
42. **[Quake Remake](https://www.moddb.com/games/quake-remake)**
|
43. **[Quake Remake](https://www.moddb.com/games/quake-remake)**
|
||||||
|
|
||||||
*Support was fully abandoned due Quake Wrapper release.*
|
*Support was fully abandoned due Quake Wrapper release.*
|
||||||
|
|
||||||
[Actual source code](https://github.com/FWGS/quakeremake)
|
[Actual source code](https://github.com/FWGS/quakeremake)
|
||||||
|
|
||||||
43. **[Rebellion](https://www.moddb.com/mods/rebellion1)**
|
44. **[Rebellion](https://www.moddb.com/mods/rebellion1)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **rebellion** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **rebellion** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
44. **[Residual Life](https://www.moddb.com/mods/hl-residual-life)**
|
45. **[Residual Life](https://www.moddb.com/mods/hl-residual-life)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
45. **[Residual Point](https://www.moddb.com/mods/hl-residual-point)**
|
46. **[Residual Point](https://www.moddb.com/mods/hl-residual-point)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
46. **[Ricochet](https://store.steampowered.com/app/60/Ricochet/)**
|
47. **[Ricochet](https://store.steampowered.com/app/60/Ricochet/)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
47. [Sewer](https://www.moddb.com/games/half-life/addons/sewer-beta)
|
48. [Sewer](https://www.moddb.com/games/half-life/addons/sewer-beta)
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **sewer_beta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **sewer_beta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
48. [Spirit of Half-Life 1.2](https://www.moddb.com/mods/spirit-of-half-life)
|
49. [Spirit of Half-Life 1.2](https://www.moddb.com/mods/spirit-of-half-life)
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
49. **[Swiss Cheese Halloween](https://www.moddb.com/mods/half-life-halloween-mod)**
|
50. **[Swiss Cheese Halloween](https://www.moddb.com/mods/half-life-halloween-mod)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **halloween** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **halloween** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
50. **[Team Fortress Classic](https://store.steampowered.com/app/20/Team_Fortress_Classic/)**
|
51. **[Team Fortress Classic](https://store.steampowered.com/app/20/Team_Fortress_Classic/)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Currently, only source code of [client part](https://github.com/Velaron/tf15-client) is available.
|
Currently, only source code of [client part](https://github.com/Velaron/tf15-client) is available.
|
||||||
|
|
||||||
51. **[The Gate](https://www.moddb.com/mods/the-gate)**
|
52. **[The Gate](https://www.moddb.com/mods/the-gate)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **thegate** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **thegate** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
52. **[They Hunger: Trilogy](https://www.moddb.com/mods/they-hunger)**
|
53. **[They Hunger: Trilogy](https://www.moddb.com/mods/they-hunger)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **theyhunger** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **theyhunger** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
53. **[ThreeWave CTF](https://www.moddb.com/games/deathmatch-classic/downloads/threewave-ctf)**
|
54. **[ThreeWave CTF](https://www.moddb.com/games/deathmatch-classic/downloads/threewave-ctf)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
54. **[Times of Troubles](https://www.moddb.com/mods/times-of-troubles)**
|
55. **[Times of Troubles](https://www.moddb.com/mods/times-of-troubles)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **tot** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **tot** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
55. [XashXT](https://csm.dev/threads/xashxt-0-65-rev-4-release-stable.38319/)
|
56. [XashXT](https://csm.dev/threads/xashxt-0-65-rev-4-release-stable.38319/)
|
||||||
|
|
||||||
*Support was fully abandoned due PrimeXT development*
|
*Support was fully abandoned due PrimeXT development*
|
||||||
|
|
||||||
[Source code](https://github.com/FWGS/XashXT-FWGS/)
|
[Source code](https://github.com/FWGS/XashXT-FWGS/)
|
||||||
|
|
||||||
56. **[X-Half-Life DeathMatch](https://www.moddb.com/mods/xdm)**
|
57. **[X-Half-Life DeathMatch](https://www.moddb.com/mods/xdm)**
|
||||||
|
|
||||||
This mod already supports x86 Linux.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
Support for other platforms may be available later.
|
||||||
|
|
||||||
57. **[Xen-Warrior](https://www.moddb.com/mods/xen-warrior)**
|
58. **[Xen-Warrior](https://www.moddb.com/mods/xen-warrior)**
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
Don't forget to enable XENWARRIOR build option!!!
|
Don't forget to enable XENWARRIOR build option!!!
|
||||||
|
|
||||||
58. [Zombie-X](https://www.moddb.com/mods/zombie-x-10-final)
|
59. [Zombie-X](https://www.moddb.com/mods/zombie-x-10-final)
|
||||||
|
|
||||||
To run this mod on specific platforms you may be need to compile libraries from **zombie-x** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
To run this mod on specific platforms you may be need to compile libraries from **zombie-x** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||||
|
|
||||||
|
|||||||
39
README.md
39
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
|
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
|
||||||
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
|
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
|
||||||
[](http://fwgsdiscord.mentality.rip/) [](https://t.me/flyingwithgauss) \
|
[](http://xash.su/discord/) [](https://t.me/flyingwithgauss) \
|
||||||
[](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
|
[](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
|
||||||
|
|
||||||
Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
|
Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
|
||||||
@@ -41,10 +41,12 @@ For additional info, run Xash3D with `-help` command line key.
|
|||||||
1) Copy `valve` directory to a folder named `xash` in the Internal storage.
|
1) Copy `valve` directory to a folder named `xash` in the Internal storage.
|
||||||
2) Run games from within the app.
|
2) Run games from within the app.
|
||||||
|
|
||||||
## Contributing
|
## Reporting issues
|
||||||
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html.
|
|
||||||
* Issues are accepted in both English and Russian.
|
* Issues are accepted in both English and Russian.
|
||||||
* Before sending a PR, check if you followed our contribution guide in CONTRIBUTING.md file.
|
* They are only accepted if you run legally acquired product (e.g. Half-Life in Steam).
|
||||||
|
|
||||||
|
## Contributing code
|
||||||
|
* Check the CONTRIBUTING.md file.
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
|
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
|
||||||
@@ -81,11 +83,11 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
|||||||
|
|
||||||
##### RedHat/Fedora
|
##### RedHat/Fedora
|
||||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-devel.i686`.
|
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL3-devel.i686 sdl2-compat-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-devel.i686`.
|
||||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
|
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
|
||||||
|
|
||||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
|
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL3-devel sdl2-compat-devel opus-devel freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
|
||||||
|
|
||||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||||
|
|
||||||
@@ -98,6 +100,16 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
|||||||
|
|
||||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||||
|
|
||||||
|
#### iOS/iPadOS
|
||||||
|
* Install Xcode from the appstore.
|
||||||
|
* Install [Homebrew package manager](https://brew.sh).
|
||||||
|
|
||||||
|
* Install build dependencies by running: `brew install python`.
|
||||||
|
|
||||||
|
* Clone the SDL2 repo `$ git clone --recursive https://github.com/libsdl-org/SDL.git -b SDL2` and compile the iOS framework by navigating to SDL/Xcode/SDL and opening the Xcode project.
|
||||||
|
|
||||||
|
* Clone this repository: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
#### Windows (Visual Studio)
|
#### Windows (Visual Studio)
|
||||||
0) Open command line.
|
0) Open command line.
|
||||||
@@ -116,4 +128,17 @@ If compiling 32-bit on amd64, make sure `PKG_CONFIG_PATH` from the previous step
|
|||||||
3) Install: `./waf install --destdir=/path/to/any/output/directory`.
|
3) Install: `./waf install --destdir=/path/to/any/output/directory`.
|
||||||
|
|
||||||
#### Android (Windows/Linux/macOS)
|
#### Android (Windows/Linux/macOS)
|
||||||
You can just open the `android` folder in Android Studio and build from here, or use `gradlew` to build from command line.
|
To build you should clone [SDL](https://github.com/libsdl-org/SDL) from `SDL2` branch and [HLSDK-portable](https://github.com/FWGS/hlsdk-portable) `mobile-hacks` branch repositories to 3rdparty folder, after that you should be able to open the project in Android Studio from `android` directory or manually call Gradle to build the APK.
|
||||||
|
|
||||||
|
#### iOS/iPadOS (MacOS only)
|
||||||
|
0) (optional) Examine which build options are available: `./waf --help`.
|
||||||
|
1) Configure build: `./waf configure --ios --enable-bundled-deps --sdl2 (path/to/SDL2.framework)`, set `--ios-simulator` instead of `--ios` if you want to build for simulator.
|
||||||
|
2) Compile `./waf build`.
|
||||||
|
3) Navigate to `build` and copy your compiled SDL2.framework there, then add your game dylibs to `build/ios/libs/(gamedir)/(dlls/cl_dlls)`(You can also run `scripts/ios/buildhlsdk.sh` instead to automatically create an ipa with hlsdk dylibs)
|
||||||
|
4) Run `scripts/ios/createipa.sh` to create an installable ipa
|
||||||
|
|
||||||
|
### Running tests
|
||||||
|
|
||||||
|
Tests are enabled with `--enable-tests` passed to `./waf configure` and can be run with `./waf --alltests`.
|
||||||
|
|
||||||
|
This builds both standalone unit tests and a separate engine test binary (`xash3d_tests`) that embeds engine-level tests. The engine test binary requires no game assets.
|
||||||
|
|||||||
18
SECURITY.md
Normal file
18
SECURITY.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Xash3D FWGS Security Policy
|
||||||
|
|
||||||
|
## Supported versions
|
||||||
|
|
||||||
|
Because we don't have clear release cycle yet, support is only provided to the
|
||||||
|
latest engine versions from `master` branch. You can use `host_ver` command in
|
||||||
|
console to fetch detailed info about the engine build.
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
If you discover a security vulnerability in this project, it can be reported
|
||||||
|
privately though `Security` tab on GitHub:
|
||||||
|
https://github.com/FWGS/xash3d-fwgs/security
|
||||||
|
|
||||||
|
Alternatively, you can report them publicly on the `Issues` tab:
|
||||||
|
https://github.com/FWGS/xash3d-fwgs/issues
|
||||||
|
|
||||||
|
In both cases, expect a reply within approximately a week.
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import com.android.build.api.dsl.ApplicationExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.Month
|
import java.time.Month
|
||||||
@@ -5,12 +6,11 @@ import java.time.temporal.ChronoUnit
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.kotlin.android)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
extensions.configure<ApplicationExtension> {
|
||||||
namespace = "su.xash.engine"
|
namespace = "su.xash.engine"
|
||||||
ndkVersion = "28.2.13676358"
|
ndkVersion = "29.0.14206865"
|
||||||
compileSdk = 35
|
compileSdk = 35
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
@@ -23,7 +23,7 @@ android {
|
|||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
val engineRoot = projectDir.parentFile.parent
|
val engineRoot = projectDir.parentFile.parent
|
||||||
|
|
||||||
experimentalProperties["ninja.abiFilters"] = setOf("armeabi-v7a", "arm64-v8a")
|
experimentalProperties["ninja.abiFilters"] = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||||
experimentalProperties["ninja.path"] = File(engineRoot, "wscript").path
|
experimentalProperties["ninja.path"] = File(engineRoot, "wscript").path
|
||||||
experimentalProperties["ninja.configure"] = "run-python"
|
experimentalProperties["ninja.configure"] = "run-python"
|
||||||
experimentalProperties["ninja.arguments"] = setOf(
|
experimentalProperties["ninja.arguments"] = setOf(
|
||||||
@@ -34,7 +34,7 @@ android {
|
|||||||
"--configuration-dir=\${ndk.buildRoot}",
|
"--configuration-dir=\${ndk.buildRoot}",
|
||||||
"--ndk-version=\${ndk.moduleNdkVersion}",
|
"--ndk-version=\${ndk.moduleNdkVersion}",
|
||||||
"--min-sdk-version=\${ndk.minPlatform}",
|
"--min-sdk-version=\${ndk.minPlatform}",
|
||||||
"--ndk-root=${android.ndkDirectory}",
|
"--ndk-root=${androidComponents.sdkComponents.ndkDirectory.get()}",
|
||||||
// shut up, fake options
|
// shut up, fake options
|
||||||
"-p:Configuration=\${ndk.variantName}",
|
"-p:Configuration=\${ndk.variantName}",
|
||||||
"-p:Platform=\${ndk.abi}"
|
"-p:Platform=\${ndk.abi}"
|
||||||
@@ -62,20 +62,23 @@ android {
|
|||||||
abortOnError = false
|
abortOnError = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
androidResources {
|
androidResources {
|
||||||
noCompress += ""
|
noCompress += ""
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
packaging {
|
packaging {
|
||||||
jniLibs {
|
jniLibs {
|
||||||
keepDebugSymbols.add("**/*.so")
|
keepDebugSymbols.add("**/*.so")
|
||||||
|
useLegacyPackaging = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
getByName("main") {
|
getByName("main") {
|
||||||
assets.srcDirs("../../3rdparty/extras/xash-extras")
|
assets.directories.add("../../3rdparty/extras/xash-extras")
|
||||||
java.srcDir("../../3rdparty/SDL/android-project/app/src/main/java")
|
java.directories.add("../../3rdparty/SDL/android-project/app/src/main/java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,10 @@
|
|||||||
<!-- Allow downloading to the external storage on Android 5.1 and older -->
|
<!-- Allow downloading to the external storage on Android 5.1 and older -->
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="22" />
|
android:maxSdkVersion="29" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="32" />
|
android:maxSdkVersion="29" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||||
<!-- Allow access to Bluetooth devices -->
|
<!-- Allow access to Bluetooth devices -->
|
||||||
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
||||||
@@ -57,7 +57,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher"
|
android:roundIcon="@mipmap/ic_launcher"
|
||||||
android:theme="@style/Theme.App"
|
android:theme="@style/Theme.App"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true"
|
||||||
|
android:requestLegacyExternalStorage="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
@@ -80,4 +81,9 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="su.xash.engine.MOD" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ import org.libsdl.app.SDLActivity;
|
|||||||
|
|
||||||
import su.xash.engine.util.AndroidBug5497Workaround;
|
import su.xash.engine.util.AndroidBug5497Workaround;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class XashActivity extends SDLActivity {
|
public class XashActivity extends SDLActivity {
|
||||||
private boolean mUseVolumeKeys;
|
private boolean mUseVolumeKeys;
|
||||||
private String mPackageName;
|
private String mPackageName;
|
||||||
@@ -149,6 +152,7 @@ public class XashActivity extends SDLActivity {
|
|||||||
|
|
||||||
String argv = getIntent().getStringExtra("argv");
|
String argv = getIntent().getStringExtra("argv");
|
||||||
if (argv == null) argv = "-console -log";
|
if (argv == null) argv = "-console -log";
|
||||||
|
|
||||||
return argv.split(" ");
|
return argv.split(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,28 +6,36 @@ import android.content.pm.PackageInfo
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import androidx.core.net.toUri
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import su.xash.engine.R
|
||||||
import su.xash.engine.XashActivity
|
import su.xash.engine.XashActivity
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
|
import java.util.Arrays
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
||||||
class Game(val ctx: Context, val basedir: File) {
|
|
||||||
private var iconName = "game.ico"
|
private var iconName = "game.ico"
|
||||||
var title = "Unknown Game"
|
var title = "Unknown Game"
|
||||||
var icon: Bitmap? = null
|
var icon: Bitmap? = null
|
||||||
var cover: Bitmap? = null
|
var cover: Bitmap? = null
|
||||||
|
|
||||||
|
val mobileHacksGames = arrayOf("aom", "bdlands", "biglolly", "bshift", "caseclosed",
|
||||||
|
"hl_urbicide", "induction", "redempt", "secret",
|
||||||
|
"sewer_beta", "tot", "valve", "vendetta")
|
||||||
|
|
||||||
|
// a1ba: follow the behavior of Xash3D's game_launch.
|
||||||
|
// for hl mods we put `valve` as game directory
|
||||||
|
// for any other game that's not hl this string must be replaced with your
|
||||||
|
// main game directory
|
||||||
|
// mods always use -game command line parameter
|
||||||
|
var defaultGameDir = "valve"
|
||||||
|
|
||||||
private val pref = ctx.getSharedPreferences(basedir.name, Context.MODE_PRIVATE)
|
private val pref = ctx.getSharedPreferences(basedir.name, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val gameInfo = File(basedir, "gameinfo.txt")
|
parseGameInfo(gameInfoFile)
|
||||||
if (gameInfo.exists()) {
|
|
||||||
parseGameInfo(gameInfo)
|
|
||||||
} else {
|
|
||||||
val libListGam = File(basedir, "liblist.gam")
|
|
||||||
if (libListGam.exists()) parseGameInfo(libListGam)
|
|
||||||
}
|
|
||||||
|
|
||||||
val iconFile = File(basedir, iconName)
|
val iconFile = File(basedir, iconName)
|
||||||
if (iconFile.exists()) {
|
if (iconFile.exists()) {
|
||||||
@@ -42,14 +50,76 @@ class Game(val ctx: Context, val basedir: File) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun startEngine(ctx: Context) {
|
fun startEngine(ctx: Context) {
|
||||||
|
val packageNames = getPackageNamesForGameDir(basedir.name)
|
||||||
|
var externalGame = false
|
||||||
|
var commandLineArgs = "";
|
||||||
|
|
||||||
|
if (basedir.name != defaultGameDir)
|
||||||
|
commandLineArgs += "-game ${basedir.name} "
|
||||||
|
|
||||||
|
if (packageNames != null) {
|
||||||
|
if (packageNames.contains("su.xash.engine")) {
|
||||||
|
commandLineArgs += "-dll @hl "
|
||||||
|
} else if (packageNames.contains("su.xash.cs16client")) {
|
||||||
|
if (pref.getBoolean("enable_yapb_bots", true)) {
|
||||||
|
commandLineArgs += "-dll @yapb "
|
||||||
|
}
|
||||||
|
externalGame = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commandLineArgs += pref.getString("arguments", "-console -log")
|
||||||
|
|
||||||
|
var packageName: String? = null
|
||||||
|
var gameLibDir: String? = null
|
||||||
|
if (externalGame && packageNames != null) {
|
||||||
|
for (pn in packageNames) {
|
||||||
|
gameLibDir = try {
|
||||||
|
getGameLibDir(ctx, pn)
|
||||||
|
} catch(e: PackageManager.NameNotFoundException) {
|
||||||
|
null
|
||||||
|
} catch(e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameLibDir != null) {
|
||||||
|
packageName = pn
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameLibDir == null) {
|
||||||
|
MaterialAlertDialogBuilder(ctx).apply {
|
||||||
|
setTitle(R.string.game_apk_required)
|
||||||
|
setMessage(R.string.game_apk_message)
|
||||||
|
setPositiveButton(R.string.game_apk_install) { _, _ ->
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW,
|
||||||
|
getDownloadPageForGameDir(basedir.name).toUri())
|
||||||
|
ctx.startActivity(intent)
|
||||||
|
}
|
||||||
|
show()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx.startActivity(Intent(ctx, XashActivity::class.java).apply {
|
ctx.startActivity(Intent(ctx, XashActivity::class.java).apply {
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
putExtra("gamedir", basedir.name)
|
|
||||||
putExtra("argv", pref.getString("arguments", "-console -log"))
|
putExtra("gamedir", defaultGameDir)
|
||||||
|
putExtra("argv", commandLineArgs)
|
||||||
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
||||||
putExtra("basedir", basedir.parent)
|
putExtra("basedir", basedir.parent)
|
||||||
//.putExtra("gamelibdir", getGameLibDir(context))
|
|
||||||
//.putExtra("package", getPackageName()) }
|
if (gameLibDir != null) {
|
||||||
|
putExtra("gamelibdir", gameLibDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packageName != null) {
|
||||||
|
putExtra("package", packageName)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,44 +140,50 @@ class Game(val ctx: Context, val basedir: File) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPackageName(): String? {
|
private fun getPackageNamesForGameDir(gamedir: String): Array<String>? {
|
||||||
// return if (mDbEntry != null) {
|
if (gamedir.equals("cstrike", ignoreCase = true)
|
||||||
// mDbEntry.getPackageName()
|
|| gamedir.equals("czero", ignoreCase = true))
|
||||||
// } else null
|
return arrayOf("su.xash.cs16client.test", "su.xash.cs16client")
|
||||||
|
|
||||||
|
if (gamedir.equals("tfc", ignoreCase = true))
|
||||||
|
return arrayOf("su.xash.tf15client.test", "su.xash.tf15client")
|
||||||
|
|
||||||
|
// mobile_hacks hlsdk-portable branch allows us to have few more mods out of the box
|
||||||
|
if (mobileHacksGames.any { it.equals(gamedir, ignoreCase = true) })
|
||||||
|
return arrayOf("su.xash.engine")
|
||||||
|
|
||||||
|
// return if (mDbEntry != null) {
|
||||||
|
// mDbEntry.getPackageName()
|
||||||
|
// } else null
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGameLibDir(ctx: Context): String? {
|
private fun getDownloadPageForGameDir(gamedir: String): String {
|
||||||
val pkgName = getPackageName()
|
if (gamedir.equals("cstrike", ignoreCase = true)
|
||||||
if (pkgName != null) {
|
|| gamedir.equals("czero", ignoreCase = true))
|
||||||
val pkgInfo: PackageInfo = try {
|
return "https://github.com/Velaron/cs16-client/releases/download/continuous/CS16Client-Android.apk"
|
||||||
ctx.packageManager.getPackageInfo(pkgName, 0)
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
if (gamedir.equals("tfc", ignoreCase = true))
|
||||||
e.printStackTrace()
|
return "https://github.com/Velaron/tf15-client/releases/download/continuous/TF15Client-Android.apk"
|
||||||
ctx.startActivity(
|
|
||||||
Intent(
|
// just so we don't return null
|
||||||
Intent.ACTION_VIEW, Uri.parse("market://details?id=$pkgName")
|
return "https://github.com/FWGS/xash3d-fwgs/releases/download/continuous/xash3d-fwgs-android.apk"
|
||||||
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
}
|
||||||
)
|
|
||||||
return null
|
private fun getGameLibDir(ctx: Context, packageName: String): String? {
|
||||||
}
|
val packageInfo: PackageInfo = ctx.packageManager.getPackageInfo(packageName, 0)
|
||||||
return pkgInfo.applicationInfo?.nativeLibraryDir
|
return packageInfo.applicationInfo?.nativeLibraryDir
|
||||||
}
|
|
||||||
return ctx.applicationInfo.nativeLibraryDir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getGames(ctx: Context, file: File): List<Game> {
|
fun getGames(ctx: Context, root: File): List<Game> {
|
||||||
val games = mutableListOf<Game>()
|
val games = mutableListOf<Game>()
|
||||||
|
|
||||||
if (checkIfGamedir(file)) {
|
root.listFiles()?.forEach {
|
||||||
games.add(Game(ctx, file))
|
if (it.isDirectory) {
|
||||||
} else {
|
val subDirGameInfoFile = checkIfGamedir(it)
|
||||||
file.listFiles()?.forEach {
|
if (subDirGameInfoFile != null) {
|
||||||
if (it.isDirectory) {
|
games.add(Game(ctx, it, subDirGameInfoFile))
|
||||||
if (checkIfGamedir(it)) {
|
|
||||||
games.add(Game(ctx, it))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,24 +191,18 @@ class Game(val ctx: Context, val basedir: File) {
|
|||||||
return games
|
return games
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkIfGamedir(file: File): Boolean {
|
fun checkIfGamedir(gamedir: File): File? {
|
||||||
if (File(file, "liblist.gam").exists()) return true
|
gamedir.listFiles()?.forEach {
|
||||||
if (File(file, "gameinfo.txt").exists()) return true
|
if (it.isFile) {
|
||||||
|
if (it.name.equals("liblist.gam", ignoreCase = true))
|
||||||
|
return it
|
||||||
|
|
||||||
return false
|
if (it.name.equals("gameinfo.txt", ignoreCase = true))
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intent intent = new Intent("su.xash.engine.MOD");
|
|
||||||
// for (ResolveInfo info : context.getPackageManager()
|
|
||||||
// .queryIntentActivities(intent, PackageManager.GET_META_DATA)) {
|
|
||||||
// String packageName = info.activityInfo.applicationInfo.packageName;
|
|
||||||
// String gameDir = info.activityInfo.applicationInfo.metaData.getString(
|
|
||||||
// "su.xash.engine.gamedir");
|
|
||||||
// Log.d(TAG, "package = " + packageName + " gamedir = " + gameDir);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//public void startEngine(Context context) {
|
|
||||||
// context.startActivity(new Intent(context, XashActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP).putExtra("gamedir", getGameDir()).putExtra("argv", getArguments()).putExtra("usevolume", getVolumeState()).putExtra("gamelibdir", getGameLibDir(context)).putExtra("package", getPackageName()));
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package su.xash.engine.ui.library
|
package su.xash.engine.ui.library
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -13,7 +15,8 @@ import android.view.MenuItem
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
@@ -25,6 +28,7 @@ import su.xash.engine.R
|
|||||||
import su.xash.engine.adapters.GameAdapter
|
import su.xash.engine.adapters.GameAdapter
|
||||||
import su.xash.engine.databinding.FragmentLibraryBinding
|
import su.xash.engine.databinding.FragmentLibraryBinding
|
||||||
|
|
||||||
|
|
||||||
class LibraryFragment : Fragment(), MenuProvider {
|
class LibraryFragment : Fragment(), MenuProvider {
|
||||||
private var _binding: FragmentLibraryBinding? = null
|
private var _binding: FragmentLibraryBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
@@ -38,23 +42,85 @@ class LibraryFragment : Fragment(), MenuProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkStoragePermissions(): Boolean {
|
private val requiredPermissions = arrayOf(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
setTitle(R.string.file_access_required)
|
)
|
||||||
setMessage(R.string.file_access_message)
|
|
||||||
setPositiveButton(android.R.string.ok) { _, _ ->
|
|
||||||
startActivityForResult.launch(
|
|
||||||
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(
|
|
||||||
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
setCancelable(false)
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
private val requestPermissionLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestMultiplePermissions()
|
||||||
|
) { permissions ->
|
||||||
|
val granted = permissions.entries.all { it.value }
|
||||||
|
if (granted) {
|
||||||
|
libraryViewModel.reloadGames(requireContext())
|
||||||
|
} else {
|
||||||
|
checkStoragePermissions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkStoragePermissions(): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
if (!Environment.isExternalStorageManager()) {
|
||||||
|
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||||
|
setTitle(R.string.file_access_required)
|
||||||
|
setMessage(R.string.file_access_message)
|
||||||
|
setPositiveButton(R.string.open_settings) { _, _ ->
|
||||||
|
startActivityForResult.launch(
|
||||||
|
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(
|
||||||
|
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
setNeutralButton(R.string.done_check_permissions) { dialog, _ ->
|
||||||
|
checkStoragePermissions()
|
||||||
|
}
|
||||||
|
setCancelable(false)
|
||||||
|
show()
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
val permissionsNeeded = requiredPermissions.filter {
|
||||||
|
ContextCompat.checkSelfPermission(
|
||||||
|
requireContext(),
|
||||||
|
it
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
}.toTypedArray()
|
||||||
|
|
||||||
|
if (!permissionsNeeded.isEmpty()) {
|
||||||
|
val showRationale = permissionsNeeded.any {
|
||||||
|
ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), it)
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||||
|
setTitle(R.string.external_storage_required)
|
||||||
|
setMessage(R.string.external_storage_message)
|
||||||
|
setPositiveButton(R.string.open_settings) { _, _ ->
|
||||||
|
if (showRationale) {
|
||||||
|
requestPermissionLauncher.launch(permissionsNeeded)
|
||||||
|
} else {
|
||||||
|
val intent =
|
||||||
|
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||||
|
data =
|
||||||
|
Uri.fromParts("package", requireContext().packageName, null)
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setNeutralButton(R.string.done_check_permissions) { _, _ ->
|
||||||
|
checkStoragePermissions()
|
||||||
|
}
|
||||||
|
setCancelable(false)
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -107,4 +173,12 @@ class LibraryFragment : Fragment(), MenuProvider {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
if (checkStoragePermissions()) {
|
||||||
|
libraryViewModel.reloadGames(requireContext())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import su.xash.engine.model.Game
|
import su.xash.engine.model.Game
|
||||||
|
import su.xash.engine.util.Nomedia
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class LibraryViewModel(application: Application) : AndroidViewModel(application) {
|
class LibraryViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
@@ -39,6 +40,8 @@ class LibraryViewModel(application: Application) : AndroidViewModel(application)
|
|||||||
?: (Environment.getExternalStorageDirectory().absolutePath + "/xash")
|
?: (Environment.getExternalStorageDirectory().absolutePath + "/xash")
|
||||||
val root = File(rootPath)
|
val root = File(rootPath)
|
||||||
|
|
||||||
|
Nomedia.ensureNomedia(root)
|
||||||
|
|
||||||
_installedGames.postValue(Game.getGames(ctx, root))
|
_installedGames.postValue(Game.getGames(ctx, root))
|
||||||
_isReloading.postValue(false)
|
_isReloading.postValue(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ class GameSettingsPreferenceFragment(val game: Game) : PreferenceFragmentCompat(
|
|||||||
packageList.setValueIndex(0);
|
packageList.setValueIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game.basedir.name.equals("cstrike", ignoreCase = true)
|
||||||
|
|| game.basedir.name.equals("czero", ignoreCase = true)) {
|
||||||
|
val enableYaPBBots = findPreference<SwitchPreferenceCompat>("enable_yapb_bots")!!
|
||||||
|
enableYaPBBots.isVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
val separatePackages = findPreference<SwitchPreferenceCompat>("separate_libraries")!!
|
val separatePackages = findPreference<SwitchPreferenceCompat>("separate_libraries")!!
|
||||||
val clientPackage = findPreference<ListPreference>("client_package")!!
|
val clientPackage = findPreference<ListPreference>("client_package")!!
|
||||||
val serverPackage = findPreference<ListPreference>("server_package")!!
|
val serverPackage = findPreference<ListPreference>("server_package")!!
|
||||||
|
|||||||
52
android/app/src/main/java/su/xash/engine/util/Nomedia.kt
Normal file
52
android/app/src/main/java/su/xash/engine/util/Nomedia.kt
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Nomedia.kt - ensure that .nomedia file exists in directory
|
||||||
|
Copyright (C) 2025 Alibek Omarov
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
package su.xash.engine.util
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object Nomedia {
|
||||||
|
fun ensureNomedia(directory: File): Boolean {
|
||||||
|
try {
|
||||||
|
// ensure paths exists
|
||||||
|
if (!directory.exists() && !directory.mkdirs()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if it's a directory
|
||||||
|
if (!directory.isDirectory) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val nomediaFile = File(directory, ".nomedia")
|
||||||
|
|
||||||
|
// if the .nomedia is directory, remove it
|
||||||
|
if (nomediaFile.isDirectory) {
|
||||||
|
// it should be empty to be deleted, but that's good
|
||||||
|
// because this way we're not deleting something important
|
||||||
|
// (who would stash important files in .nomedia directory though...)
|
||||||
|
if (!nomediaFile.delete()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// it returns false if file already exists, which is fine for us
|
||||||
|
nomediaFile.createNewFile()
|
||||||
|
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
android/app/src/main/res/values-es/strings.xml
Normal file
21
android/app/src/main/res/values-es/strings.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">Xash3D FWGS</string>
|
||||||
|
<string name="library">Librería</string>
|
||||||
|
<string name="dedicated_server">Dedicado</string>
|
||||||
|
<string name="app_settings">Ajustes</string>
|
||||||
|
<string name="game_settings">Ajustes del juego</string>
|
||||||
|
<string name="game_settings_command_line">Argumentos de la línea de comandos</string>
|
||||||
|
<string name="game_settings_volume_buttons">Usar botones de volumen en el juego</string>
|
||||||
|
<string name="preferences_package_name">Paquete de librerías</string>
|
||||||
|
<string name="preferences_separate_libraries">Librerías de paquetes separados</string>
|
||||||
|
<string name="preferences_client_package">Paquete de cliente</string>
|
||||||
|
<string name="preferences_server_package">Paquete de servidor</string>
|
||||||
|
<string name="preferences_use_icons">Usar iconos en lugar de fondos</string>
|
||||||
|
<string name="game_data_location">Ubicación de los datos del juego</string>
|
||||||
|
<string name="file_access_required">Se requiere acceso a todos los archivos</string>
|
||||||
|
<string name="file_access_message">Se requiere acceso a todos los archivos para que la aplicación funcione correctamente.</string>
|
||||||
|
<string name="select_current_directory">Seleccionar directorio actual</string>
|
||||||
|
<string name="external_storage_required">Se requiere acceso al almacenamiento externo</string>
|
||||||
|
<string name="external_storage_message">Se requiere acceso al almacenamiento externo para que la aplicación funcione correctamente.</string>
|
||||||
|
</resources>
|
||||||
27
android/app/src/main/res/values-fr/strings.xml
Normal file
27
android/app/src/main/res/values-fr/strings.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">Xash3D FWGS</string>
|
||||||
|
<string name="library">Bibliothèque</string>
|
||||||
|
<string name="dedicated_server">Dédié</string>
|
||||||
|
<string name="app_settings">Paramètres</string>
|
||||||
|
<string name="game_settings">Paramètres du jeu</string>
|
||||||
|
<string name="game_settings_command_line">Arguments de ligne de commande</string>
|
||||||
|
<string name="game_settings_volume_buttons">Utiliser les boutons de volume dans le jeu</string>
|
||||||
|
<string name="game_settings_yapb_bots">Activer les bots YaPB (Uniquement pour CS)</string>
|
||||||
|
<string name="preferences_package_name">Paquet de bibliothèques</string>
|
||||||
|
<string name="preferences_separate_libraries">Bibliothèques de paquets séparés</string>
|
||||||
|
<string name="preferences_client_package">Paquet client</string>
|
||||||
|
<string name="preferences_server_package">Paquet serveur</string>
|
||||||
|
<string name="preferences_use_icons">Utiliser des icônes au lieu d\'arrière-plans</string>
|
||||||
|
<string name="game_data_location">Emplacement des données du jeu</string>
|
||||||
|
<string name="file_access_required">L\'accès à tous les fichiers est requis</string>
|
||||||
|
<string name="file_access_message">L\'accès à tous les fichiers est requis pour que l\'application fonctionne correctement.</string>
|
||||||
|
<string name="select_current_directory">Sélectionner le répertoire actuel</string>
|
||||||
|
<string name="external_storage_required">L\'accès au stockage externe est requis</string>
|
||||||
|
<string name="external_storage_message">L\'accès au stockage externe est requis pour que l\'application fonctionne correctement.</string>
|
||||||
|
<string name="open_settings">Ouvrir les paramètres</string>
|
||||||
|
<string name="done_check_permissions">Terminé ! Vérifier les permissions</string>
|
||||||
|
<string name="game_apk_required">Nécessite un APK de bibliothèques de jeu</string>
|
||||||
|
<string name="game_apk_message">Pour lancer ce jeu, vous devez installer un APK additionnel</string>
|
||||||
|
<string name="game_apk_install">Télécharger</string>
|
||||||
|
</resources>
|
||||||
@@ -6,9 +6,15 @@
|
|||||||
<string name="game_settings">Configurações do jogo</string>
|
<string name="game_settings">Configurações do jogo</string>
|
||||||
<string name="game_settings_command_line">Argumentos de linha de comando</string>
|
<string name="game_settings_command_line">Argumentos de linha de comando</string>
|
||||||
<string name="game_settings_volume_buttons">Usar botões de volume no jogo</string>
|
<string name="game_settings_volume_buttons">Usar botões de volume no jogo</string>
|
||||||
<string name="preferences_package_name">Bibliotecas de pacotes</string>
|
<string name="preferences_package_name">Pacote de bibliotecas</string>
|
||||||
<string name="preferences_separate_libraries">Bibliotecas de pacotes separados</string>
|
<string name="preferences_separate_libraries">Bibliotecas de pacotes separados</string>
|
||||||
<string name="preferences_client_package">Pacotes de Cliente</string>
|
<string name="preferences_client_package">Pacote do cliente</string>
|
||||||
<string name="preferences_server_package">Pacotes de Servidor</string>
|
<string name="preferences_server_package">Pacote do servidor</string>
|
||||||
<string name="preferences_use_icons">Usar ícones ao inves de imagens de fundo</string>
|
<string name="preferences_use_icons">Usar ícones em vez de fundos</string>
|
||||||
|
<string name="game_data_location">Local dos dados do jogo</string>
|
||||||
|
<string name="file_access_required">Acesso a todos os arquivos necessário</string>
|
||||||
|
<string name="file_access_message">É necessário acesso a todos os arquivos para que o aplicativo funcione corretamente.</string>
|
||||||
|
<string name="select_current_directory">Selecionar diretório atual</string>
|
||||||
|
<string name="external_storage_required">Acesso ao armazenamento externo necessário</string>
|
||||||
|
<string name="external_storage_message">É necessário acesso ao armazenamento externo para que o aplicativo funcione corretamente.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -6,9 +6,21 @@
|
|||||||
<string name="game_settings">Настройки игры</string>
|
<string name="game_settings">Настройки игры</string>
|
||||||
<string name="game_settings_command_line">Аргументы командной строки</string>
|
<string name="game_settings_command_line">Аргументы командной строки</string>
|
||||||
<string name="game_settings_volume_buttons">Использовать кнопки громкости</string>
|
<string name="game_settings_volume_buttons">Использовать кнопки громкости</string>
|
||||||
|
<string name="game_settings_yapb_bots">Включить YaPB ботов (только CS)</string>
|
||||||
<string name="preferences_package_name">Пакет библиотек</string>
|
<string name="preferences_package_name">Пакет библиотек</string>
|
||||||
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
||||||
<string name="preferences_client_package">Пакет клиента</string>
|
<string name="preferences_client_package">Пакет клиента</string>
|
||||||
<string name="preferences_server_package">Пакет сервера</string>
|
<string name="preferences_server_package">Пакет сервера</string>
|
||||||
<string name="preferences_use_icons">Использовать иконки вместо фона</string>
|
<string name="preferences_use_icons">Использовать иконки вместо фона</string>
|
||||||
|
<string name="game_data_location">Расположение игровых данных</string>
|
||||||
|
<string name="file_access_required">Требуется доступ ко всем файлам</string>
|
||||||
|
<string name="file_access_message">Для правильной работы приложения требуется доступ ко всем файлам.</string>
|
||||||
|
<string name="select_current_directory">Выбрать текущую директорию</string>
|
||||||
|
<string name="external_storage_required">Требуется доступ к внешнему хранилищу</string>
|
||||||
|
<string name="external_storage_message">Для правильной работы приложения требуется доступ к внешнему хранилищу.</string>
|
||||||
|
<string name="open_settings">Открыть настройки</string>
|
||||||
|
<string name="done_check_permissions">Готово! Проверить разрешения</string>
|
||||||
|
<string name="game_apk_required">Требуется APK с игровыми библиотеками</string>
|
||||||
|
<string name="game_apk_message">Чтобы запустить эту игру, нужно установить дополнительный APK</string>
|
||||||
|
<string name="game_apk_install">Скачать</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
26
android/app/src/main/res/values-zh-rCN/strings.xml
Normal file
26
android/app/src/main/res/values-zh-rCN/strings.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="library">库</string>
|
||||||
|
<string name="dedicated_server">专用服务器</string>
|
||||||
|
<string name="app_settings">设置</string>
|
||||||
|
<string name="game_settings">游戏设置</string>
|
||||||
|
<string name="game_settings_command_line">命令行参数</string>
|
||||||
|
<string name="game_settings_volume_buttons">在游戏中使用音量按钮</string>
|
||||||
|
<string name="game_settings_yapb_bots">启用yapb机器人(仅限CS)</string>
|
||||||
|
<string name="preferences_package_name">数据包</string>
|
||||||
|
<string name="preferences_separate_libraries">来自独立包的库</string>
|
||||||
|
<string name="preferences_client_package">客户端包</string>
|
||||||
|
<string name="preferences_server_package">服务器包</string>
|
||||||
|
<string name="preferences_use_icons">使用图标代替背景</string>
|
||||||
|
<string name="game_data_location">游戏数据包路径位置</string>
|
||||||
|
<string name="file_access_required">需要所有文件访问权限</string>
|
||||||
|
<string name="file_access_message">应用程序需要所有文件访问权限才能正常运行</string>
|
||||||
|
<string name="select_current_directory">选择当前目录</string>
|
||||||
|
<string name="external_storage_required">需要外部存储访问权限</string>
|
||||||
|
<string name="external_storage_message">应用程序需要外部存储访问权限才能正常运行</string>
|
||||||
|
<string name="open_settings">打开设置</string>
|
||||||
|
<string name="done_check_permissions">准备好了!检查权限</string>
|
||||||
|
<string name="game_apk_required">需要带有游戏库的APK</string>
|
||||||
|
<string name="game_apk_message">要运行此游戏,您需要安装额外的APK</string>
|
||||||
|
<string name="game_apk_install">下载</string>
|
||||||
|
</resources>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<string name="game_settings">Game Settings</string>
|
<string name="game_settings">Game Settings</string>
|
||||||
<string name="game_settings_command_line">Command-line arguments</string>
|
<string name="game_settings_command_line">Command-line arguments</string>
|
||||||
<string name="game_settings_volume_buttons">Use volume buttons in-game</string>
|
<string name="game_settings_volume_buttons">Use volume buttons in-game</string>
|
||||||
|
<string name="game_settings_yapb_bots">Enable YaPB bots (CS only)</string>
|
||||||
<string name="preferences_package_name">Libraries package</string>
|
<string name="preferences_package_name">Libraries package</string>
|
||||||
<string name="preferences_separate_libraries">Libraries from separate packages</string>
|
<string name="preferences_separate_libraries">Libraries from separate packages</string>
|
||||||
<string name="preferences_client_package">Client package</string>
|
<string name="preferences_client_package">Client package</string>
|
||||||
@@ -16,4 +17,11 @@
|
|||||||
<string name="file_access_required">All-files access required</string>
|
<string name="file_access_required">All-files access required</string>
|
||||||
<string name="file_access_message">All-files access is required for the app to function properly.</string>
|
<string name="file_access_message">All-files access is required for the app to function properly.</string>
|
||||||
<string name="select_current_directory">Select current directory</string>
|
<string name="select_current_directory">Select current directory</string>
|
||||||
|
<string name="external_storage_required">External storage access required</string>
|
||||||
|
<string name="external_storage_message">External storage access is required for the app to function properly.</string>
|
||||||
|
<string name="open_settings">Open settings</string>
|
||||||
|
<string name="done_check_permissions">Done! Check permissions</string>
|
||||||
|
<string name="game_apk_required">Game code APK required</string>
|
||||||
|
<string name="game_apk_message">To launch this game, you need additional APK installed</string>
|
||||||
|
<string name="game_apk_install">Download</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
app:defaultValue="-console -log"
|
app:defaultValue="-console -log"
|
||||||
app:key="arguments"
|
app:key="arguments"
|
||||||
@@ -12,6 +13,13 @@
|
|||||||
app:layout="@layout/switch_preference"
|
app:layout="@layout/switch_preference"
|
||||||
app:title="@string/game_settings_volume_buttons" />
|
app:title="@string/game_settings_volume_buttons" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="enable_yapb_bots"
|
||||||
|
app:layout="@layout/switch_preference"
|
||||||
|
app:title="@string/game_settings_yapb_bots"
|
||||||
|
app:defaultValue="true"
|
||||||
|
app:isPreferenceVisible="false" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="separate_libraries"
|
app:key="separate_libraries"
|
||||||
app:layout="@layout/switch_preference"
|
app:layout="@layout/switch_preference"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application) apply false
|
alias(libs.plugins.android.application) apply false
|
||||||
alias(libs.plugins.kotlin.android) apply false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,3 +25,6 @@ android.nonTransitiveRClass=true
|
|||||||
|
|
||||||
# Enable verbose output for CMake
|
# Enable verbose output for CMake
|
||||||
android.native.buildOutput=verbose
|
android.native.buildOutput=verbose
|
||||||
|
android.uniquePackageNames=false
|
||||||
|
android.dependency.useConstraints=true
|
||||||
|
android.r8.strictFullModeForKeepRules=false
|
||||||
|
|||||||
13
android/gradle/gradle-daemon-jvm.properties
Normal file
13
android/gradle/gradle-daemon-jvm.properties
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#This file is generated by updateDaemonJvm
|
||||||
|
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29ee363f71d060405f729a8f1b7f7aef/redirect
|
||||||
|
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/ecd23fd7707c683afbcd6052998cb6a9/redirect
|
||||||
|
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29ee363f71d060405f729a8f1b7f7aef/redirect
|
||||||
|
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/ecd23fd7707c683afbcd6052998cb6a9/redirect
|
||||||
|
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/10fc3bf1ee0001078a473afe6e43cfdb/redirect
|
||||||
|
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/658299a896470fbb3103ba3a430ee227/redirect
|
||||||
|
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29ee363f71d060405f729a8f1b7f7aef/redirect
|
||||||
|
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/67a0fee3c4236b6397dcbe8575ca2011/redirect
|
||||||
|
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/39846e8427e64a3824c13e399d7d813c/redirect
|
||||||
|
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/932015f6361ccaead0c6d9b8717ed96e/redirect
|
||||||
|
toolchainVendor=JETBRAINS
|
||||||
|
toolchainVersion=21
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
acraHttp = "5.12.0"
|
acraHttp = "5.12.0"
|
||||||
agp = "8.11.1"
|
agp = "9.0.1"
|
||||||
appcompat = "1.7.1"
|
appcompat = "1.7.1"
|
||||||
kotlin = "2.2.0"
|
|
||||||
material = "1.12.0"
|
material = "1.12.0"
|
||||||
navigationRuntimeKtx = "2.9.1"
|
navigationRuntimeKtx = "2.9.1"
|
||||||
preferenceKtx = "1.2.1"
|
preferenceKtx = "1.2.1"
|
||||||
@@ -20,4 +19,3 @@ swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout"
|
|||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#Tue Jul 01 19:51:06 EEST 2025
|
#Tue Jul 01 19:51:06 EEST 2025
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ pluginManagement {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
plugins {
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
||||||
|
}
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -18,17 +18,20 @@ GNU General Public License for more details.
|
|||||||
// video backends (XASH_VIDEO)
|
// video backends (XASH_VIDEO)
|
||||||
#define VIDEO_NULL 0
|
#define VIDEO_NULL 0
|
||||||
#define VIDEO_SDL 1
|
#define VIDEO_SDL 1
|
||||||
|
#define VIDEO_PSP 2
|
||||||
#define VIDEO_FBDEV 3
|
#define VIDEO_FBDEV 3
|
||||||
#define VIDEO_DOS 4
|
#define VIDEO_DOS 4
|
||||||
|
|
||||||
// audio backends (XASH_SOUND)
|
// audio backends (XASH_SOUND)
|
||||||
#define SOUND_NULL 0
|
#define SOUND_NULL 0
|
||||||
#define SOUND_SDL 1
|
#define SOUND_SDL 1
|
||||||
|
#define SOUND_PSP 2
|
||||||
#define SOUND_ALSA 3
|
#define SOUND_ALSA 3
|
||||||
|
|
||||||
// input (XASH_INPUT)
|
// input (XASH_INPUT)
|
||||||
#define INPUT_NULL 0
|
#define INPUT_NULL 0
|
||||||
#define INPUT_SDL 1
|
#define INPUT_SDL 1
|
||||||
|
#define INPUT_PSP 2
|
||||||
#define INPUT_EVDEV 3
|
#define INPUT_EVDEV 3
|
||||||
|
|
||||||
// timer (XASH_TIMER)
|
// timer (XASH_TIMER)
|
||||||
@@ -37,18 +40,21 @@ GNU General Public License for more details.
|
|||||||
#define TIMER_POSIX 2
|
#define TIMER_POSIX 2
|
||||||
#define TIMER_WIN32 3
|
#define TIMER_WIN32 3
|
||||||
#define TIMER_DOS 4
|
#define TIMER_DOS 4
|
||||||
|
#define TIMER_PSP 5
|
||||||
|
|
||||||
// messageboxes (XASH_MESSAGEBOX)
|
// messageboxes (XASH_MESSAGEBOX)
|
||||||
#define MSGBOX_STDERR 0
|
#define MSGBOX_STDERR 0
|
||||||
#define MSGBOX_SDL 1
|
#define MSGBOX_SDL 1
|
||||||
|
#define MSGBOX_PSP 2
|
||||||
#define MSGBOX_WIN32 3
|
#define MSGBOX_WIN32 3
|
||||||
#define MSGBOX_NSWITCH 4
|
#define MSGBOX_NSWITCH 4
|
||||||
|
|
||||||
// library loading (XASH_LIB)
|
// library loading (XASH_LIB)
|
||||||
#define LIB_NULL 0
|
#define LIB_NULL 0
|
||||||
#define LIB_POSIX 1
|
#define LIB_POSIX 1
|
||||||
#define LIB_WIN32 2
|
#define LIB_WIN32 2
|
||||||
#define LIB_STATIC 3
|
#define LIB_STATIC 3
|
||||||
|
#define LIB_PSP 4
|
||||||
|
|
||||||
// movies (XASH_AVI)
|
// movies (XASH_AVI)
|
||||||
#define AVI_NULL 0
|
#define AVI_NULL 0
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#ifndef BEAMDEF_H
|
#ifndef BEAMDEF_H
|
||||||
#define BEAMDEF_H
|
#define BEAMDEF_H
|
||||||
|
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
#define FBEAM_STARTENTITY 0x00000001
|
#define FBEAM_STARTENTITY 0x00000001
|
||||||
#define FBEAM_ENDENTITY 0x00000002
|
#define FBEAM_ENDENTITY 0x00000002
|
||||||
#define FBEAM_FADEIN 0x00000004
|
#define FBEAM_FADEIN 0x00000004
|
||||||
|
|||||||
344
common/bspfile.h
344
common/bspfile.h
@@ -12,10 +12,12 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BSPFILE_H
|
#ifndef BSPFILE_H
|
||||||
#define BSPFILE_H
|
#define BSPFILE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
@@ -26,288 +28,310 @@ BRUSH MODELS
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// header
|
// header
|
||||||
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
|
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
|
||||||
#define HLBSP_VERSION 30 // half-life regular version
|
#define HLBSP_VERSION 30 // half-life regular version
|
||||||
#define QBSP2_VERSION (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24))
|
#define QBSP2_VERSION (( 'B' << 0 ) | ( 'S' << 8 ) | ( 'P' << 16 ) | ( '2' << 24 ))
|
||||||
|
|
||||||
#define IDEXTRAHEADER (('H'<<24)+('S'<<16)+('A'<<8)+'X') // little-endian "XASH"
|
#define IDEXTRAHEADER (( 'X' << 0 ) | ( 'A' << 8 ) | ( 'S' << 16 ) | ( 'H' << 24 ))
|
||||||
#define EXTRA_VERSION 4 // ver. 1 was occupied by old versions of XashXT, ver. 2 was occupied by old vesrions of P2:savior
|
#define EXTRA_VERSION 4 // ver. 1 was occupied by old versions of XashXT
|
||||||
// ver. 3 was occupied by experimental versions of P2:savior change fmt
|
// ver. 2 was occupied by old vesrions of P2:savior
|
||||||
|
// ver. 3 was occupied by experimental versions of P2:savior change fmt
|
||||||
|
|
||||||
#define DELUXEMAP_VERSION 1
|
#define IDBSPXHEADER (( 'B' << 0 ) | ( 'S' << 8 ) | ( 'P' << 16 ) | ( 'X' << 24 ))
|
||||||
#define IDDELUXEMAPHEADER (('T'<<24)+('I'<<16)+('L'<<8)+'Q') // little-endian "QLIT"
|
|
||||||
|
#define DELUXEMAP_VERSION 1
|
||||||
|
#define IDDELUXEMAPHEADER (( 'Q' << 0 ) | ('L' << 8 ) | ( 'I' << 16 ) | ( 'T' << 24 ))
|
||||||
|
|
||||||
// worldcraft predefined angles
|
// worldcraft predefined angles
|
||||||
#define ANGLE_UP -1
|
#define ANGLE_UP -1
|
||||||
#define ANGLE_DOWN -2
|
#define ANGLE_DOWN -2
|
||||||
|
|
||||||
// bmodel limits
|
// bmodel limits
|
||||||
#define MAX_MAP_HULLS 4 // MAX_HULLS
|
#define MAX_MAP_HULLS 4 // MAX_HULLS
|
||||||
|
|
||||||
#define SURF_PLANEBACK BIT( 1 ) // plane should be negated
|
#define SURF_PLANEBACK BIT( 1 ) // plane should be negated
|
||||||
#define SURF_DRAWSKY BIT( 2 ) // sky surface
|
#define SURF_DRAWSKY BIT( 2 ) // sky surface
|
||||||
#define SURF_DRAWTURB_QUADS BIT( 3 ) // all subidivided polygons are quads
|
#define SURF_DRAWTURB_QUADS BIT( 3 ) // all subidivided polygons are quads
|
||||||
#define SURF_DRAWTURB BIT( 4 ) // warp surface
|
#define SURF_DRAWTURB BIT( 4 ) // warp surface
|
||||||
#define SURF_DRAWTILED BIT( 5 ) // face without lighmap
|
#define SURF_DRAWTILED BIT( 5 ) // face without lighmap
|
||||||
#define SURF_CONVEYOR BIT( 6 ) // scrolled texture (was SURF_DRAWBACKGROUND)
|
#define SURF_CONVEYOR BIT( 6 ) // scrolled texture (was SURF_DRAWBACKGROUND)
|
||||||
#define SURF_UNDERWATER BIT( 7 ) // caustics
|
#define SURF_UNDERWATER BIT( 7 ) // caustics
|
||||||
#define SURF_TRANSPARENT BIT( 8 ) // it's a transparent texture (was SURF_DONTWARP)
|
#define SURF_TRANSPARENT BIT( 8 ) // it's a transparent texture (was SURF_DONTWARP)
|
||||||
|
|
||||||
// lightstyle management
|
// lightstyle management
|
||||||
#define LM_STYLES 4 // MAXLIGHTMAPS
|
#define LM_STYLES 4 // MAXLIGHTMAPS
|
||||||
#define LS_NORMAL 0x00
|
#define LS_NORMAL 0x00
|
||||||
#define LS_UNUSED 0xFE
|
#define LS_UNUSED 0xFE
|
||||||
#define LS_NONE 0xFF
|
#define LS_NONE 0xFF
|
||||||
|
|
||||||
#define MAX_MAP_CLIPNODES_HLBSP 32767
|
#define MAX_MAP_CLIPNODES_HLBSP 32767
|
||||||
#define MAX_MAP_CLIPNODES_BSP2 524288
|
#define MAX_MAP_CLIPNODES_BSP2 524288
|
||||||
|
|
||||||
// these limis not using by modelloader but only for displaying 'mapstats' correctly
|
// these limis not using by modelloader but only for displaying 'mapstats' correctly
|
||||||
#define MAX_MAP_MODELS 2048 // embedded models
|
#define MAX_MAP_MODELS 2048 // embedded models
|
||||||
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
||||||
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
||||||
#define MAX_MAP_NODES 262144 // can be increased without problems
|
#define MAX_MAP_NODES 262144 // can be increased without problems
|
||||||
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
|
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
|
||||||
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
|
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
|
||||||
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
||||||
#define MAX_MAP_FACES 262144 // can be increased without problems
|
#define MAX_MAP_FACES 262144 // can be increased without problems
|
||||||
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
|
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
|
||||||
|
|
||||||
#define MAX_MAP_ENTITIES 8192 // network limit
|
#define MAX_MAP_ENTITIES 8192 // network limit
|
||||||
#define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo
|
#define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo
|
||||||
#define MAX_MAP_EDGES 0x100000 // can be increased but not needs
|
#define MAX_MAP_EDGES 0x100000 // can be increased but not needed
|
||||||
#define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needs
|
#define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needed
|
||||||
#define MAX_MAP_TEXTURES 2048 // can be increased but not needs
|
#define MAX_MAP_TEXTURES 2048 // can be increased but not needed
|
||||||
#define MAX_MAP_MIPTEX 0x2000000 // 32 Mb internal textures data
|
#define MAX_MAP_MIPTEX 0x2000000 // 32 Mb internal textures data
|
||||||
#define MAX_MAP_LIGHTING 0x2000000 // 32 Mb lightmap raw data (can contain deluxemaps)
|
#define MAX_MAP_LIGHTING 0x2000000 // 32 Mb lightmap raw data (can contain deluxemaps)
|
||||||
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
|
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
|
||||||
#define MAX_MAP_FACEINFO 8192 // can be increased but not needs
|
#define MAX_MAP_FACEINFO 8192 // can be increased but not needed
|
||||||
|
|
||||||
// quake lump ordering
|
// quake lump ordering
|
||||||
#define LUMP_ENTITIES 0
|
enum
|
||||||
#define LUMP_PLANES 1
|
{
|
||||||
#define LUMP_TEXTURES 2 // internal textures
|
LUMP_ENTITIES = 0,
|
||||||
#define LUMP_VERTEXES 3
|
LUMP_PLANES = 1,
|
||||||
#define LUMP_VISIBILITY 4
|
LUMP_TEXTURES = 2, // internal textures
|
||||||
#define LUMP_NODES 5
|
LUMP_VERTEXES = 3,
|
||||||
#define LUMP_TEXINFO 6
|
LUMP_VISIBILITY = 4,
|
||||||
#define LUMP_FACES 7
|
LUMP_NODES = 5,
|
||||||
#define LUMP_LIGHTING 8
|
LUMP_TEXINFO = 6,
|
||||||
#define LUMP_CLIPNODES 9
|
LUMP_FACES = 7,
|
||||||
#define LUMP_LEAFS 10
|
LUMP_LIGHTING = 8,
|
||||||
#define LUMP_MARKSURFACES 11
|
LUMP_CLIPNODES = 9,
|
||||||
#define LUMP_EDGES 12
|
LUMP_LEAFS = 10,
|
||||||
#define LUMP_SURFEDGES 13
|
LUMP_MARKSURFACES = 11,
|
||||||
#define LUMP_MODELS 14 // internal submodels
|
LUMP_EDGES = 12,
|
||||||
#define HEADER_LUMPS 15
|
LUMP_SURFEDGES = 13,
|
||||||
|
LUMP_MODELS = 14, // internal submodels
|
||||||
|
HEADER_LUMPS = 15,
|
||||||
|
};
|
||||||
|
|
||||||
// extra lump ordering
|
// extra lump ordering
|
||||||
#define LUMP_LIGHTVECS 0 // deluxemap data
|
enum
|
||||||
#define LUMP_FACEINFO 1 // landscape and lightmap resolution info
|
{
|
||||||
#define LUMP_CUBEMAPS 2 // cubemap description
|
LUMP_LIGHTVECS = 0, // deluxemap data
|
||||||
#define LUMP_VERTNORMALS 3 // phong shaded vertex normals
|
LUMP_FACEINFO = 1, // landscape and lightmap resolution info
|
||||||
#define LUMP_LEAF_LIGHTING 4 // store vertex lighting for statics
|
LUMP_CUBEMAPS = 2, // cubemap description
|
||||||
#define LUMP_WORLDLIGHTS 5 // list of all the virtual and real lights (used to relight models in-game)
|
LUMP_VERTNORMALS = 3, // phong shaded vertex normals
|
||||||
#define LUMP_COLLISION 6 // physics engine collision hull dump (userdata)
|
LUMP_LEAF_LIGHTING = 4, // store vertex lighting for statics
|
||||||
#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp (userdata)
|
LUMP_WORLDLIGHTS = 5, // list of all the virtual and real lights (used to relight models in-game)
|
||||||
#define LUMP_SHADOWMAP 8 // contains shadow map for direct light
|
LUMP_COLLISION = 6, // physics engine collision hull dump (userdata)
|
||||||
#define LUMP_VERTEX_LIGHT 9 // store vertex lighting for statics
|
LUMP_AINODEGRAPH = 7, // node graph that stored into the bsp (userdata)
|
||||||
#define LUMP_UNUSED0 10 // one lump reserved for me
|
LUMP_SHADOWMAP = 8, // contains shadow map for direct light
|
||||||
#define LUMP_UNUSED1 11 // one lump reserved for me
|
LUMP_VERTEX_LIGHT = 9, // store vertex lighting for statics
|
||||||
#define EXTRA_LUMPS 12 // count of the extra lumps
|
LUMP_UNUSED0 = 10, // one lump reserved for me
|
||||||
|
LUMP_UNUSED1 = 11, // one lump reserved for me
|
||||||
|
EXTRA_LUMPS = 12, // count of the extra lumps
|
||||||
|
};
|
||||||
|
|
||||||
// texture flags
|
// texture flags
|
||||||
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
|
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
|
||||||
#define TEX_WORLD_LUXELS BIT( 1 ) // alternative lightmap matrix will be used (luxels per world units instead of luxels per texels)
|
#define TEX_WORLD_LUXELS BIT( 1 ) // alternative lightmap matrix will be used (luxels per world units instead of luxels per texels)
|
||||||
#define TEX_AXIAL_LUXELS BIT( 2 ) // force world luxels to axial positive scales
|
#define TEX_AXIAL_LUXELS BIT( 2 ) // force world luxels to axial positive scales
|
||||||
#define TEX_EXTRA_LIGHTMAP BIT( 3 ) // bsp31 legacy - using 8 texels per luxel instead of 16 texels per luxel
|
#define TEX_EXTRA_LIGHTMAP BIT( 3 ) // bsp31 legacy - using 8 texels per luxel instead of 16 texels per luxel
|
||||||
#define TEX_SCROLL BIT( 6 ) // Doom special FX
|
#define TEX_SCROLL BIT( 6 ) // Doom special FX
|
||||||
|
|
||||||
#define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA )
|
#define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA )
|
||||||
|
|
||||||
// ambient sound types
|
// ambient sound types
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
AMBIENT_WATER = 0, // waterfall
|
AMBIENT_WATER = 0, // waterfall
|
||||||
AMBIENT_SKY, // wind
|
AMBIENT_SKY, // wind
|
||||||
AMBIENT_SLIME, // never used in quake
|
AMBIENT_SLIME, // never used in quake
|
||||||
AMBIENT_LAVA, // never used in quake
|
AMBIENT_LAVA, // never used in quake
|
||||||
NUM_AMBIENTS, // automatic ambient sounds
|
NUM_AMBIENTS, // automatic ambient sounds
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// BSP File Structures
|
// BSP File Structures
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int fileofs;
|
int32_t fileofs;
|
||||||
int filelen;
|
int32_t filelen;
|
||||||
} dlump_t;
|
} dlump_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int version;
|
int32_t version;
|
||||||
dlump_t lumps[HEADER_LUMPS];
|
dlump_t lumps[HEADER_LUMPS];
|
||||||
} dheader_t;
|
} dheader_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int id; // must be little endian XASH
|
int32_t id; // must be little endian XASH
|
||||||
int version;
|
int32_t version;
|
||||||
dlump_t lumps[EXTRA_LUMPS];
|
dlump_t lumps[EXTRA_LUMPS];
|
||||||
} dextrahdr_t;
|
} dextrahdr_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t mins;
|
char lumpname[24]; // up to 23 chars, zero-padded
|
||||||
vec3_t maxs;
|
int32_t fileofs;
|
||||||
vec3_t origin; // for sounds or lights
|
int32_t filelen;
|
||||||
int headnode[MAX_MAP_HULLS];
|
} dbspx_lump_t;
|
||||||
int visleafs; // not including the solid leaf 0
|
|
||||||
int firstface;
|
typedef struct
|
||||||
int numfaces;
|
{
|
||||||
|
int32_t id; // must be little endian BSPX
|
||||||
|
int32_t numlumps;
|
||||||
|
dbspx_lump_t lumps[];
|
||||||
|
} dbspx_hdr_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vec3_t mins;
|
||||||
|
vec3_t maxs;
|
||||||
|
vec3_t origin; // for sounds or lights
|
||||||
|
int32_t headnode[MAX_MAP_HULLS];
|
||||||
|
int32_t visleafs; // not including the solid leaf 0
|
||||||
|
int32_t firstface;
|
||||||
|
int32_t numfaces;
|
||||||
} dmodel_t;
|
} dmodel_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int nummiptex;
|
int32_t nummiptex;
|
||||||
int dataofs[4]; // [nummiptex]
|
int32_t dataofs[4]; // [nummiptex]
|
||||||
} dmiptexlump_t;
|
} dmiptexlump_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t point;
|
vec3_t point;
|
||||||
} dvertex_t;
|
} dvertex_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t normal;
|
vec3_t normal;
|
||||||
float dist;
|
float dist;
|
||||||
int type; // PLANE_X - PLANE_ANYZ ?
|
int32_t type; // PLANE_X - PLANE_ANYZ ?
|
||||||
} dplane_t;
|
} dplane_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int planenum;
|
int32_t planenum;
|
||||||
short children[2]; // negative numbers are -(leafs + 1), not nodes
|
int16_t children[2]; // negative numbers are -(leafs + 1), not nodes
|
||||||
short mins[3]; // for sphere culling
|
int16_t mins[3]; // for sphere culling
|
||||||
short maxs[3];
|
int16_t maxs[3];
|
||||||
word firstface;
|
uint16_t firstface;
|
||||||
word numfaces; // counting both sides
|
uint16_t numfaces; // counting both sides
|
||||||
} dnode_t;
|
} dnode_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int planenum;
|
int32_t planenum;
|
||||||
int children[2]; // negative numbers are -(leafs+1), not nodes
|
int32_t children[2]; // negative numbers are -(leafs+1), not nodes
|
||||||
float mins[3]; // for sphere culling
|
float mins[3]; // for sphere culling
|
||||||
float maxs[3];
|
float maxs[3];
|
||||||
int firstface;
|
int32_t firstface;
|
||||||
int numfaces; // counting both sides
|
int32_t numfaces; // counting both sides
|
||||||
} dnode32_t;
|
} dnode32_t;
|
||||||
|
|
||||||
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
|
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
|
||||||
// all other leafs need visibility info
|
// all other leafs need visibility info
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int contents;
|
int32_t contents;
|
||||||
int visofs; // -1 = no visibility info
|
int32_t visofs; // -1 = no visibility info
|
||||||
|
|
||||||
short mins[3]; // for frustum culling
|
int16_t mins[3]; // for frustum culling
|
||||||
short maxs[3];
|
int16_t maxs[3];
|
||||||
word firstmarksurface;
|
uint16_t firstmarksurface;
|
||||||
word nummarksurfaces;
|
uint16_t nummarksurfaces;
|
||||||
|
|
||||||
// automatic ambient sounds
|
// automatic ambient sounds
|
||||||
byte ambient_level[NUM_AMBIENTS]; // ambient sound level (0 - 255)
|
uint8_t ambient_level[NUM_AMBIENTS]; // ambient sound level (0 - 255)
|
||||||
} dleaf_t;
|
} dleaf_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int contents;
|
int32_t contents;
|
||||||
int visofs; // -1 = no visibility info
|
int32_t visofs; // -1 = no visibility info
|
||||||
|
|
||||||
float mins[3]; // for frustum culling
|
float mins[3]; // for frustum culling
|
||||||
float maxs[3];
|
float maxs[3];
|
||||||
|
|
||||||
int firstmarksurface;
|
int32_t firstmarksurface;
|
||||||
int nummarksurfaces;
|
int32_t nummarksurfaces;
|
||||||
|
|
||||||
byte ambient_level[NUM_AMBIENTS];
|
uint8_t ambient_level[NUM_AMBIENTS];
|
||||||
} dleaf32_t;
|
} dleaf32_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int planenum;
|
int32_t planenum;
|
||||||
short children[2]; // negative numbers are contents
|
int16_t children[2]; // negative numbers are contents
|
||||||
} dclipnode_t;
|
} dclipnode_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int planenum;
|
int32_t planenum;
|
||||||
int children[2]; // negative numbers are contents
|
int32_t children[2]; // negative numbers are contents
|
||||||
} dclipnode32_t;
|
} dclipnode32_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
float vecs[2][4]; // texmatrix [s/t][xyz offset]
|
float vecs[2][4]; // texmatrix [s/t][xyz offset]
|
||||||
int miptex;
|
int32_t miptex;
|
||||||
short flags;
|
int16_t flags;
|
||||||
short faceinfo; // -1 no face info otherwise dfaceinfo_t
|
int16_t faceinfo; // -1 no face info otherwise dfaceinfo_t
|
||||||
} dtexinfo_t;
|
} dtexinfo_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char landname[16]; // name of decsription in mapname_land.txt
|
char landname[16]; // name of decsription in mapname_land.txt
|
||||||
unsigned short texture_step; // default is 16, pixels\luxels ratio
|
uint16_t texture_step; // default is 16, pixels\luxels ratio
|
||||||
unsigned short max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step)
|
uint16_t max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step)
|
||||||
short groupid; // to determine equal landscapes from various groups, -1 - no group
|
int16_t groupid; // to determine equal landscapes from various groups, -1 - no group
|
||||||
} dfaceinfo_t;
|
} dfaceinfo_t;
|
||||||
|
|
||||||
typedef word dmarkface_t; // leaf marksurfaces indexes
|
typedef uint16_t dmarkface_t; // leaf marksurfaces indexes
|
||||||
typedef int dmarkface32_t; // leaf marksurfaces indexes
|
typedef int32_t dmarkface32_t; // leaf marksurfaces indexes
|
||||||
|
|
||||||
typedef int dsurfedge_t; // map surfedges
|
typedef int32_t dsurfedge_t; // map surfedges
|
||||||
|
|
||||||
// NOTE: that edge 0 is never used, because negative edge nums
|
// NOTE: that edge 0 is never used, because negative edge nums
|
||||||
// are used for counterclockwise use of the edge in a face
|
// are used for counterclockwise use of the edge in a face
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
word v[2]; // vertex numbers
|
uint16_t v[2]; // vertex numbers
|
||||||
} dedge_t;
|
} dedge_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int v[2]; // vertex numbers
|
int32_t v[2]; // vertex numbers
|
||||||
} dedge32_t;
|
} dedge32_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
word planenum;
|
uint16_t planenum;
|
||||||
short side;
|
int16_t side;
|
||||||
|
|
||||||
int firstedge; // we must support > 64k edges
|
int32_t firstedge; // we must support > 64k edges
|
||||||
short numedges;
|
int16_t numedges;
|
||||||
short texinfo;
|
int16_t texinfo;
|
||||||
|
|
||||||
// lighting info
|
// lighting info
|
||||||
byte styles[LM_STYLES];
|
uint8_t styles[LM_STYLES];
|
||||||
int lightofs; // start of [numstyles*surfsize] samples
|
int32_t lightofs; // start of [numstyles*surfsize] samples
|
||||||
} dface_t;
|
} dface_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int planenum;
|
int32_t planenum;
|
||||||
int side;
|
int32_t side;
|
||||||
|
|
||||||
int firstedge; // we must support > 64k edges
|
int32_t firstedge; // we must support > 64k edges
|
||||||
int numedges;
|
int32_t numedges;
|
||||||
int texinfo;
|
int32_t texinfo;
|
||||||
|
|
||||||
// lighting info
|
// lighting info
|
||||||
byte styles[LM_STYLES];
|
uint8_t styles[LM_STYLES];
|
||||||
int lightofs; // start of [numstyles*surfsize] samples
|
int32_t lightofs; // start of [numstyles*surfsize] samples
|
||||||
} dface32_t;
|
} dface32_t;
|
||||||
|
|
||||||
#endif//BSPFILE_H
|
#endif // BSPFILE_H
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#ifndef CL_ENTITY_H
|
#ifndef CL_ENTITY_H
|
||||||
#define CL_ENTITY_H
|
#define CL_ENTITY_H
|
||||||
|
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
typedef struct efrag_s
|
typedef struct efrag_s
|
||||||
{
|
{
|
||||||
struct mleaf_s *leaf;
|
struct mleaf_s *leaf;
|
||||||
|
|||||||
@@ -1,4 +1,23 @@
|
|||||||
#pragma once
|
/*
|
||||||
|
com_image.h - image definitions common between client and server
|
||||||
|
Copyright (C) 2007 Uncle Mike
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COM_IMAGE_H
|
||||||
|
#define COM_IMAGE_H
|
||||||
|
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
========================================================================
|
========================================================================
|
||||||
|
|
||||||
@@ -8,21 +27,9 @@ typically expanded to rgba buffer
|
|||||||
NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 == PF_RGB_888
|
NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 == PF_RGB_888
|
||||||
========================================================================
|
========================================================================
|
||||||
*/
|
*/
|
||||||
#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24 || type == PF_LUMINANCE)
|
#define ImageRAW( type ) ( type >= PF_RGBA_32 && type <= PF_LUMINANCE )
|
||||||
#define ImageCompressed( type ) \
|
#define ImageCompressed( type ) ( type >= PF_DXT1 && type <= PF_KTX2_RAW )
|
||||||
( type == PF_DXT1 \
|
#define ImageBigEndian( type ) ( type == PF_BGRA_32 || type == PF_BGR_24 )
|
||||||
|| type == PF_DXT3 \
|
|
||||||
|| type == PF_DXT5 \
|
|
||||||
|| type == PF_ATI2 \
|
|
||||||
|| type == PF_BC4_SIGNED \
|
|
||||||
|| type == PF_BC4_UNSIGNED \
|
|
||||||
|| type == PF_BC5_SIGNED \
|
|
||||||
|| type == PF_BC5_UNSIGNED \
|
|
||||||
|| type == PF_BC6H_SIGNED \
|
|
||||||
|| type == PF_BC6H_UNSIGNED \
|
|
||||||
|| type == PF_BC7_UNORM \
|
|
||||||
|| type == PF_BC7_SRGB \
|
|
||||||
|| type == PF_KTX2_RAW )
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -50,11 +57,20 @@ typedef enum
|
|||||||
PF_TOTALCOUNT, // must be last
|
PF_TOTALCOUNT, // must be last
|
||||||
} pixformat_t;
|
} pixformat_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RF_COMPRESSED,
|
||||||
|
RF_RGBA,
|
||||||
|
RF_BGRA,
|
||||||
|
RF_BGR,
|
||||||
|
RF_LUMINANCE
|
||||||
|
} rawformat_t;
|
||||||
|
|
||||||
typedef struct bpc_desc_s
|
typedef struct bpc_desc_s
|
||||||
{
|
{
|
||||||
int format; // pixelformat
|
int format; // pixelformat
|
||||||
char name[16]; // used for debug
|
char name[16]; // used for debug
|
||||||
uint glFormat; // RGBA format
|
rawformat_t rawformat;
|
||||||
int bpp; // channels (e.g. rgb = 3, rgba = 4)
|
int bpp; // channels (e.g. rgb = 3, rgba = 4)
|
||||||
} bpc_desc_t;
|
} bpc_desc_t;
|
||||||
|
|
||||||
@@ -70,6 +86,7 @@ typedef enum
|
|||||||
IL_OVERVIEW = BIT(6), // overview required some unque operations
|
IL_OVERVIEW = BIT(6), // overview required some unque operations
|
||||||
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
|
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
|
||||||
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
|
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
|
||||||
|
IL_ALLOW_WAD3_LUMA = BIT(9), // allow usage of luma textures in wad3 (tilde textures)
|
||||||
} ilFlags_t;
|
} ilFlags_t;
|
||||||
|
|
||||||
// goes into rgbdata_t->encode
|
// goes into rgbdata_t->encode
|
||||||
@@ -99,6 +116,8 @@ typedef enum
|
|||||||
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
|
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
|
||||||
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
|
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
|
||||||
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
|
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
|
||||||
|
IMAGE_PREMULTIPLIED = BIT(11),
|
||||||
|
IMAGE_PLAYERDECAL = BIT(12), // loaded with IL_LOAD_PLAYER_DECAL (custom player spray)
|
||||||
|
|
||||||
// Image_Process manipulation flags
|
// Image_Process manipulation flags
|
||||||
IMAGE_FLIP_X = BIT(16), // flip the image by width
|
IMAGE_FLIP_X = BIT(16), // flip the image by width
|
||||||
@@ -132,3 +151,4 @@ typedef struct rgbdata_s
|
|||||||
size_t size; // for bounds checking
|
size_t size; // for bounds checking
|
||||||
} rgbdata_t;
|
} rgbdata_t;
|
||||||
|
|
||||||
|
#endif//COM_IMAGE_H
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ GNU General Public License for more details.
|
|||||||
#ifndef COM_MODEL_H
|
#ifndef COM_MODEL_H
|
||||||
#define COM_MODEL_H
|
#define COM_MODEL_H
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
#include "const.h"
|
||||||
#include "bspfile.h" // we need some declarations from it
|
#include "bspfile.h" // we need some declarations from it
|
||||||
|
|
||||||
|
#include "xash3d_mathlib.h" // mplane_t
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
@@ -46,15 +48,6 @@ typedef enum
|
|||||||
mod_studio
|
mod_studio
|
||||||
} modtype_t;
|
} modtype_t;
|
||||||
|
|
||||||
typedef struct mplane_s
|
|
||||||
{
|
|
||||||
vec3_t normal;
|
|
||||||
float dist;
|
|
||||||
byte type; // for fast side tests
|
|
||||||
byte signbits; // signx + (signy<<1) + (signz<<1)
|
|
||||||
byte pad[2];
|
|
||||||
} mplane_t;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t position;
|
vec3_t position;
|
||||||
@@ -619,9 +612,9 @@ static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return n->children_[side];
|
return n->children_[side ? 1 : 0];
|
||||||
#else
|
#else
|
||||||
return n->children_[side];
|
return n->children_[side ? 1 : 0];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -723,8 +723,6 @@ enum
|
|||||||
typedef int func_t;
|
typedef int func_t;
|
||||||
typedef int string_t;
|
typedef int string_t;
|
||||||
|
|
||||||
typedef unsigned short word;
|
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -737,11 +735,6 @@ typedef struct
|
|||||||
unsigned r, g, b, a;
|
unsigned r, g, b, a;
|
||||||
} colorVec;
|
} colorVec;
|
||||||
|
|
||||||
typedef struct link_s
|
|
||||||
{
|
|
||||||
struct link_s *prev, *next;
|
|
||||||
} link_t;
|
|
||||||
|
|
||||||
typedef struct edict_s edict_t;
|
typedef struct edict_s edict_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||||||
#ifndef CVAR
|
#ifndef CVAR
|
||||||
#define CVAR
|
#define CVAR
|
||||||
|
|
||||||
#include STDINT_H
|
#include <stdint.h>
|
||||||
#include "xash3d_types.h"
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -26,68 +26,44 @@ SETUP BACKENDS DEFINITIONS
|
|||||||
|
|
||||||
===================================================================
|
===================================================================
|
||||||
*/
|
*/
|
||||||
#if !XASH_DEDICATED
|
//
|
||||||
#if XASH_SDL
|
// when compiling client, we need to pick video, audio and input implementations
|
||||||
// we are building using libSDL
|
//
|
||||||
#ifndef XASH_VIDEO
|
#if !XASH_DEDICATED // when compiling client, we need to pick video, audio and input implementations
|
||||||
#define XASH_VIDEO VIDEO_SDL
|
#if XASH_SDL // we are building with SDL
|
||||||
#endif // XASH_VIDEO
|
#define XASH_VIDEO VIDEO_SDL
|
||||||
|
#define XASH_INPUT INPUT_SDL
|
||||||
#ifndef XASH_INPUT
|
#define XASH_SOUND SOUND_SDL
|
||||||
#define XASH_INPUT INPUT_SDL
|
#elif XASH_LINUX // we are building for Linux without SDL, only framebuffer is supported for now
|
||||||
#endif // XASH_INPUT
|
#define XASH_VIDEO VIDEO_FBDEV
|
||||||
|
#define XASH_INPUT INPUT_EVDEV
|
||||||
#ifndef XASH_SOUND
|
#define XASH_SOUND SOUND_ALSA
|
||||||
#define XASH_SOUND SOUND_SDL
|
|
||||||
#endif // XASH_SOUND
|
|
||||||
|
|
||||||
#if XASH_SDL == 2
|
|
||||||
#ifndef XASH_TIMER
|
|
||||||
#define XASH_TIMER TIMER_SDL
|
|
||||||
#endif // XASH_TIMER
|
|
||||||
|
|
||||||
#ifndef XASH_MESSAGEBOX
|
|
||||||
#if !XASH_NSWITCH // SDL2 messageboxes not available
|
|
||||||
#define XASH_MESSAGEBOX MSGBOX_SDL
|
|
||||||
#endif
|
|
||||||
#endif // XASH_MESSAGEBOX
|
|
||||||
#endif
|
|
||||||
#elif XASH_LINUX
|
|
||||||
// we are building for Linux without SDL2, can draw only to framebuffer yet
|
|
||||||
#ifndef XASH_VIDEO
|
|
||||||
#define XASH_VIDEO VIDEO_FBDEV
|
|
||||||
#endif // XASH_VIDEO
|
|
||||||
|
|
||||||
#ifndef XASH_INPUT
|
|
||||||
#define XASH_INPUT INPUT_EVDEV
|
|
||||||
#endif // XASH_INPUT
|
|
||||||
|
|
||||||
#ifndef XASH_SOUND
|
|
||||||
#define XASH_SOUND SOUND_ALSA
|
|
||||||
#endif // XASH_SOUND
|
|
||||||
|
|
||||||
#define XASH_USE_EVDEV 1
|
#define XASH_USE_EVDEV 1
|
||||||
#elif XASH_DOS4GW
|
#elif XASH_DOS4GW
|
||||||
#ifndef XASH_VIDEO
|
#define XASH_VIDEO VIDEO_DOS
|
||||||
#define XASH_VIDEO VIDEO_DOS
|
#define XASH_REDUCE_FD 1 // usually only 10-20 fds available
|
||||||
#endif
|
#elif XASH_PSP
|
||||||
#ifndef XASH_TIMER
|
#define XASH_VIDEO VIDEO_PSP
|
||||||
#define XASH_TIMER TIMER_DOS
|
#define XASH_INPUT INPUT_PSP
|
||||||
#endif
|
#define XASH_SOUND SOUND_PSP
|
||||||
|
#define XASH_REDUCE_FD 1
|
||||||
// usually only 10-20 fds availiable
|
#define XASH_NO_TOUCH 1
|
||||||
#define XASH_REDUCE_FD
|
#define XASH_NO_ZIP 1
|
||||||
#endif
|
#endif
|
||||||
#endif // XASH_DEDICATED
|
#endif // !XASH_DEDICATED
|
||||||
|
|
||||||
//
|
//
|
||||||
// select messagebox implementation
|
// select messagebox implementation
|
||||||
//
|
//
|
||||||
#ifndef XASH_MESSAGEBOX
|
#ifndef XASH_MESSAGEBOX
|
||||||
#if XASH_WIN32
|
#if XASH_SDL >= 2 && !XASH_NSWITCH // SDL2 messageboxes are not available on NSW
|
||||||
|
#define XASH_MESSAGEBOX MSGBOX_SDL
|
||||||
|
#elif XASH_WIN32
|
||||||
#define XASH_MESSAGEBOX MSGBOX_WIN32
|
#define XASH_MESSAGEBOX MSGBOX_WIN32
|
||||||
#elif XASH_NSWITCH
|
#elif XASH_NSWITCH
|
||||||
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
|
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
|
||||||
|
#elif XASH_PSP
|
||||||
|
#define XASH_MESSAGEBOX MSGBOX_PSP
|
||||||
#else // !XASH_WIN32
|
#else // !XASH_WIN32
|
||||||
#define XASH_MESSAGEBOX MSGBOX_STDERR
|
#define XASH_MESSAGEBOX MSGBOX_STDERR
|
||||||
#endif // !XASH_WIN32
|
#endif // !XASH_WIN32
|
||||||
@@ -97,8 +73,14 @@ SETUP BACKENDS DEFINITIONS
|
|||||||
// no timer - no xash
|
// no timer - no xash
|
||||||
//
|
//
|
||||||
#ifndef XASH_TIMER
|
#ifndef XASH_TIMER
|
||||||
#if XASH_WIN32
|
#if XASH_SDL >= 2
|
||||||
|
#define XASH_TIMER TIMER_SDL
|
||||||
|
#elif XASH_WIN32
|
||||||
#define XASH_TIMER TIMER_WIN32
|
#define XASH_TIMER TIMER_WIN32
|
||||||
|
#elif XASH_DOS4GW
|
||||||
|
#define XASH_TIMER TIMER_DOS
|
||||||
|
#elif XASH_PSP
|
||||||
|
#define XASH_TIMER TIMER_PSP
|
||||||
#else // !XASH_WIN32
|
#else // !XASH_WIN32
|
||||||
#define XASH_TIMER TIMER_POSIX
|
#define XASH_TIMER TIMER_POSIX
|
||||||
#endif // !XASH_WIN32
|
#endif // !XASH_WIN32
|
||||||
@@ -115,14 +97,16 @@ SETUP BACKENDS DEFINITIONS
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XASH_STATIC_LIBS
|
#if XASH_PSP
|
||||||
#define XASH_LIB LIB_STATIC
|
#define XASH_PSP LIB_PSP
|
||||||
#define XASH_INTERNAL_GAMELIBS
|
#elif defined( XASH_STATIC_LIBS )
|
||||||
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
#define XASH_LIB LIB_STATIC
|
||||||
|
#define XASH_INTERNAL_GAMELIBS
|
||||||
|
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||||
#elif XASH_WIN32
|
#elif XASH_WIN32
|
||||||
#define XASH_LIB LIB_WIN32
|
#define XASH_LIB LIB_WIN32
|
||||||
#elif XASH_POSIX
|
#elif XASH_POSIX
|
||||||
#define XASH_LIB LIB_POSIX
|
#define XASH_LIB LIB_POSIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -149,7 +133,11 @@ Default build-depended cvar and constant values
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Platform overrides
|
// Platform overrides
|
||||||
#if XASH_NSWITCH
|
#if XASH_WIN32
|
||||||
|
// set up windowed by default on Windows to avoid problems with
|
||||||
|
// Xbox Game Bar
|
||||||
|
#define DEFAULT_FULLSCREEN "0"
|
||||||
|
#elif XASH_NSWITCH
|
||||||
#define DEFAULT_TOUCH_ENABLE "1"
|
#define DEFAULT_TOUCH_ENABLE "1"
|
||||||
#define DEFAULT_M_IGNORE "1"
|
#define DEFAULT_M_IGNORE "1"
|
||||||
#define DEFAULT_MODE_WIDTH 1280
|
#define DEFAULT_MODE_WIDTH 1280
|
||||||
@@ -168,12 +156,6 @@ Default build-depended cvar and constant values
|
|||||||
#define DEFAULT_M_IGNORE "1"
|
#define DEFAULT_M_IGNORE "1"
|
||||||
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
|
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
|
||||||
|
|
||||||
#if XASH_IOS
|
|
||||||
// this means that libraries are provided with engine, but not in game data
|
|
||||||
// You need add library loading code to library.c when adding new platform
|
|
||||||
#define XASH_INTERNAL_GAMELIBS
|
|
||||||
#endif // XASH_IOS
|
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
#ifndef DEFAULT_TOUCH_ENABLE
|
#ifndef DEFAULT_TOUCH_ENABLE
|
||||||
#define DEFAULT_TOUCH_ENABLE "0"
|
#define DEFAULT_TOUCH_ENABLE "0"
|
||||||
@@ -196,11 +178,28 @@ Default build-depended cvar and constant values
|
|||||||
#endif // DEFAULT_ALLOWCONSOLE
|
#endif // DEFAULT_ALLOWCONSOLE
|
||||||
|
|
||||||
#ifndef DEFAULT_FULLSCREEN
|
#ifndef DEFAULT_FULLSCREEN
|
||||||
#define DEFAULT_FULLSCREEN "1" // must be a string
|
#define DEFAULT_FULLSCREEN "2" // must be a string
|
||||||
#endif // DEFAULT_FULLSCREEN
|
#endif // DEFAULT_FULLSCREEN
|
||||||
|
|
||||||
#ifndef DEFAULT_MAX_EDICTS
|
#ifndef DEFAULT_MAX_EDICTS
|
||||||
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
|
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
|
||||||
#endif // DEFAULT_MAX_EDICTS
|
#endif // DEFAULT_MAX_EDICTS
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DEFAULT_ACCELERATED_RENDERER
|
||||||
|
#if XASH_PSP
|
||||||
|
#define DEFAULT_ACCELERATED_RENDERER "gu"
|
||||||
|
#elif XASH_MOBILE_PLATFORM
|
||||||
|
#define DEFAULT_ACCELERATED_RENDERER "gles1"
|
||||||
|
#elif XASH_IOS
|
||||||
|
#define DEFAULT_ACCELERATED_RENDERER "gles2"
|
||||||
|
#else // !XASH_MOBILE_PLATFORM
|
||||||
|
#define DEFAULT_ACCELERATED_RENDERER "gl"
|
||||||
|
#endif // !XASH_MOBILE_PLATFORM
|
||||||
|
#endif // DEFAULT_ACCELERATED_RENDERER
|
||||||
|
|
||||||
|
#ifndef DEFAULT_SOFTWARE_RENDERER
|
||||||
|
#define DEFAULT_SOFTWARE_RENDERER "soft" // mittorn's ref_soft
|
||||||
|
#endif // DEFAULT_SOFTWARE_RENDERER
|
||||||
|
|
||||||
#endif // DEFAULTS_H
|
#endif // DEFAULTS_H
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/***
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
||||||
*
|
|
||||||
* This product contains software technology licensed from Id
|
|
||||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use, distribution, and modification of this source code and/or resulting
|
|
||||||
* object code is restricted to non-commercial enhancements to products from
|
|
||||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
||||||
* without written permission from Valve LLC.
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
|
|
||||||
#ifndef DLIGHT_H
|
|
||||||
#define DLIGHT_H
|
|
||||||
|
|
||||||
typedef struct dlight_s
|
|
||||||
{
|
|
||||||
vec3_t origin;
|
|
||||||
float radius;
|
|
||||||
color24 color;
|
|
||||||
float die; // stop lighting after this time
|
|
||||||
float decay; // drop this each second
|
|
||||||
float minlight; // don't add when contributing less
|
|
||||||
int key;
|
|
||||||
qboolean dark; // subtracts light instead of adding
|
|
||||||
} dlight_t;
|
|
||||||
|
|
||||||
#endif//DLIGHT_H
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/***
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
||||||
*
|
|
||||||
* This product contains software technology licensed from Id
|
|
||||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use, distribution, and modification of this source code and/or resulting
|
|
||||||
* object code is restricted to non-commercial enhancements to products from
|
|
||||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
||||||
* without written permission from Valve LLC.
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
|
|
||||||
#ifndef HLTV_H
|
|
||||||
#define HLTV_H
|
|
||||||
|
|
||||||
#define TYPE_CLIENT 0 // client is a normal HL client (default)
|
|
||||||
#define TYPE_PROXY 1 // client is another proxy
|
|
||||||
#define TYPE_COMMENTATOR 3 // client is a commentator
|
|
||||||
#define TYPE_DEMO 4 // client is a demo file
|
|
||||||
|
|
||||||
// sub commands of svc_hltv:
|
|
||||||
#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands
|
|
||||||
#define HLTV_STATUS 1 // send status infos about proxy
|
|
||||||
#define HLTV_LISTEN 2 // tell client to listen to a multicast stream
|
|
||||||
|
|
||||||
// sub commands of svc_director:
|
|
||||||
#define DRC_CMD_NONE 0 // NULL director command
|
|
||||||
#define DRC_CMD_START 1 // start director mode
|
|
||||||
#define DRC_CMD_EVENT 2 // informs about director command
|
|
||||||
#define DRC_CMD_MODE 3 // switches camera modes
|
|
||||||
#define DRC_CMD_CAMERA 4 // sets camera registers
|
|
||||||
#define DRC_CMD_TIMESCALE 5 // sets time scale
|
|
||||||
#define DRC_CMD_MESSAGE 6 // send HUD centerprint
|
|
||||||
#define DRC_CMD_SOUND 7 // plays a particular sound
|
|
||||||
#define DRC_CMD_STATUS 8 // status info about broadcast
|
|
||||||
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui
|
|
||||||
#define DRC_CMD_FADE 10 // send screen fade command
|
|
||||||
#define DRC_CMD_SHAKE 11 // send screen shake command
|
|
||||||
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command
|
|
||||||
|
|
||||||
#define DRC_CMD_LAST 12
|
|
||||||
|
|
||||||
// HLTV_EVENT event flags
|
|
||||||
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
|
|
||||||
#define DRC_FLAG_SIDE (1<<4) //
|
|
||||||
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene
|
|
||||||
#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo
|
|
||||||
#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc)
|
|
||||||
#define DRC_FLAG_INTRO (1<<8) // is a introduction scene
|
|
||||||
#define DRC_FLAG_FINAL (1<<9) // is a final scene
|
|
||||||
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
|
|
||||||
|
|
||||||
#define MAX_DIRECTOR_CMD_PARAMETERS 4
|
|
||||||
#define MAX_DIRECTOR_CMD_STRING 128
|
|
||||||
|
|
||||||
#endif//HLTV_H
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (C) 1996-1997 Id Software, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef KBUTTON_H
|
|
||||||
#define KBUTTON_H
|
|
||||||
|
|
||||||
// a1ba: copied from WinQuake/client.h
|
|
||||||
//
|
|
||||||
// cl_input
|
|
||||||
//
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int down[2]; // key nums holding it down
|
|
||||||
int state; // low bit is down state
|
|
||||||
} kbutton_t;
|
|
||||||
|
|
||||||
STATIC_CHECK_SIZEOF( kbutton_t, 12, 12 );
|
|
||||||
|
|
||||||
#endif // KBUTTON_H
|
|
||||||
@@ -16,6 +16,8 @@ GNU General Public License for more details.
|
|||||||
#ifndef LIGHTSTYLE_H
|
#ifndef LIGHTSTYLE_H
|
||||||
#define LIGHTSTYLE_H
|
#define LIGHTSTYLE_H
|
||||||
|
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char pattern[256];
|
char pattern[256];
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
/***
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
||||||
*
|
|
||||||
* This product contains software technology licensed from Id
|
|
||||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use, distribution, and modification of this source code and/or resulting
|
|
||||||
* object code is restricted to non-commercial enhancements to products from
|
|
||||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
||||||
* without written permission from Valve LLC.
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
// mathlib.h
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
typedef float vec_t;
|
|
||||||
typedef vec_t vec2_t[2];
|
|
||||||
typedef vec_t vec3_t[3];
|
|
||||||
typedef vec_t vec4_t[4]; // x,y,z,w
|
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct mplane_s;
|
|
||||||
|
|
||||||
extern vec3_t vec3_origin;
|
|
||||||
extern int nanmask;
|
|
||||||
|
|
||||||
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
|
|
||||||
|
|
||||||
#ifndef VECTOR_H
|
|
||||||
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
|
||||||
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
|
|
||||||
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
|
|
||||||
#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;}
|
|
||||||
|
|
||||||
void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc);
|
|
||||||
|
|
||||||
vec_t _DotProduct (vec3_t v1, vec3_t v2);
|
|
||||||
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
|
|
||||||
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
|
|
||||||
void _VectorCopy (vec3_t in, vec3_t out);
|
|
||||||
|
|
||||||
int VectorCompare (const vec3_t v1, const vec3_t v2);
|
|
||||||
float Length (const vec3_t v);
|
|
||||||
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
|
|
||||||
float VectorNormalize (vec3_t v); // returns vector length
|
|
||||||
void VectorInverse (vec3_t v);
|
|
||||||
void VectorScale (const vec3_t in, vec_t scale, vec3_t out);
|
|
||||||
|
|
||||||
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
|
|
||||||
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
|
|
||||||
|
|
||||||
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
|
||||||
void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
|
||||||
#define AngleIVectors AngleVectorsTranspose
|
|
||||||
|
|
||||||
void AngleMatrix (const vec3_t angles, float (*matrix)[4] );
|
|
||||||
void AngleIMatrix (const vec3_t angles, float (*matrix)[4] );
|
|
||||||
void VectorTransform (const vec3_t in1, float in2[3][4], vec3_t out);
|
|
||||||
|
|
||||||
void NormalizeAngles( vec3_t angles );
|
|
||||||
void InterpolateAngles( vec3_t start, vec3_t end, vec3_t output, float frac );
|
|
||||||
float AngleBetweenVectors( const vec3_t v1, const vec3_t v2 );
|
|
||||||
|
|
||||||
void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up);
|
|
||||||
void VectorAngles( const vec3_t forward, vec3_t angles );
|
|
||||||
|
|
||||||
int InvertMatrix( const float * m, float *out );
|
|
||||||
|
|
||||||
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
|
|
||||||
float anglemod(float a);
|
|
||||||
|
|
||||||
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
|
||||||
(((p)->type < 3)? \
|
|
||||||
( \
|
|
||||||
((p)->dist <= (emins)[(p)->type])? \
|
|
||||||
1 \
|
|
||||||
: \
|
|
||||||
( \
|
|
||||||
((p)->dist >= (emaxs)[(p)->type])?\
|
|
||||||
2 \
|
|
||||||
: \
|
|
||||||
3 \
|
|
||||||
) \
|
|
||||||
) \
|
|
||||||
: \
|
|
||||||
BoxOnPlaneSide( (emins), (emaxs), (p)))
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
// Set this flag for things like broadcast requests, etc. where the engine should not
|
// Set this flag for things like broadcast requests, etc. where the engine should not
|
||||||
// kill the request hook after receiving the first response
|
// kill the request hook after receiving the first response
|
||||||
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
||||||
#define FNETAPI_LEGACY_PROTOCOL ( 1<<1 ) // xash3d-fwgs extension
|
// 1<<1 is reserved for deprecated xash3d-fwgs extension
|
||||||
|
|
||||||
struct net_response_s;
|
struct net_response_s;
|
||||||
typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||||||
#ifndef NET_ADR_H
|
#ifndef NET_ADR_H
|
||||||
#define NET_ADR_H
|
#define NET_ADR_H
|
||||||
|
|
||||||
#include STDINT_H
|
#include <stdint.h>
|
||||||
|
|
||||||
// net.h -- quake's interface to the networking layer
|
// net.h -- quake's interface to the networking layer
|
||||||
// a1ba: copied from Quake-2/qcommon/qcommon.h and modified to support IPv6
|
// a1ba: copied from Quake-2/qcommon/qcommon.h and modified to support IPv6
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
/***
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
||||||
*
|
|
||||||
* This product contains software technology licensed from Id
|
|
||||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use, distribution, and modification of this source code and/or resulting
|
|
||||||
* object code is restricted to non-commercial enhancements to products from
|
|
||||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
||||||
* without written permission from Valve LLC.
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
|
|
||||||
#ifndef PARTICLEDEF_H
|
|
||||||
#define PARTICLEDEF_H
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
pt_static,
|
|
||||||
pt_grav,
|
|
||||||
pt_slowgrav,
|
|
||||||
pt_fire,
|
|
||||||
pt_explode,
|
|
||||||
pt_explode2,
|
|
||||||
pt_blob,
|
|
||||||
pt_blob2,
|
|
||||||
pt_vox_slowgrav,
|
|
||||||
pt_vox_grav,
|
|
||||||
pt_clientcustom // Must have callback function specified
|
|
||||||
} ptype_t;
|
|
||||||
|
|
||||||
typedef struct particle_s
|
|
||||||
{
|
|
||||||
vec3_t org;
|
|
||||||
short color;
|
|
||||||
short packedColor;
|
|
||||||
struct particle_s *next;
|
|
||||||
vec3_t vel;
|
|
||||||
float ramp;
|
|
||||||
float die;
|
|
||||||
ptype_t type;
|
|
||||||
void (*deathfunc)( struct particle_s *particle );
|
|
||||||
|
|
||||||
// for pt_clientcusttom, we'll call this function each frame
|
|
||||||
void (*callback)( struct particle_s *particle, float frametime );
|
|
||||||
|
|
||||||
// For deathfunc, etc.
|
|
||||||
unsigned char context;
|
|
||||||
} particle_t;
|
|
||||||
|
|
||||||
#endif//PARTICLEDEF_H
|
|
||||||
86
common/pmove.h
Normal file
86
common/pmove.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 1996-1997 Id Software, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QW_PMOVE_H
|
||||||
|
#define QW_PMOVE_H
|
||||||
|
|
||||||
|
// a1ba: from QW's client/pmove.h
|
||||||
|
// and modified to keep binary compatibility with
|
||||||
|
// goldsrc base structs and xash extensions
|
||||||
|
typedef struct pmplane_s
|
||||||
|
{
|
||||||
|
vec3_t normal;
|
||||||
|
float dist;
|
||||||
|
} pmplane_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( pmplane_t, 16, 16 );
|
||||||
|
|
||||||
|
typedef struct pmtrace_s
|
||||||
|
{
|
||||||
|
qboolean allsolid; // if true, plane is not valid
|
||||||
|
qboolean startsolid; // if true, the initial point was in a solid area
|
||||||
|
qboolean inopen, inwater;
|
||||||
|
float fraction; // time completed, 1.0 = didn't hit anything
|
||||||
|
vec3_t endpos; // final position
|
||||||
|
pmplane_t plane; // surface normal at impact
|
||||||
|
int ent; // entity the surface is on
|
||||||
|
vec3_t deltavelocity;
|
||||||
|
int hitgroup;
|
||||||
|
} pmtrace_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( pmtrace_t, 68, 68 );
|
||||||
|
|
||||||
|
typedef struct movevars_s
|
||||||
|
{
|
||||||
|
float gravity;
|
||||||
|
float stopspeed;
|
||||||
|
float maxspeed;
|
||||||
|
float spectatormaxspeed;
|
||||||
|
float accelerate;
|
||||||
|
float airaccelerate;
|
||||||
|
float wateraccelerate;
|
||||||
|
float friction;
|
||||||
|
float edgefriction; // goldsrc binary compat
|
||||||
|
float waterfriction;
|
||||||
|
float entgravity;
|
||||||
|
|
||||||
|
// goldsrc additions
|
||||||
|
float bounce;
|
||||||
|
float stepsize;
|
||||||
|
float maxvelocity;
|
||||||
|
float zmax;
|
||||||
|
float waveHeight;
|
||||||
|
qboolean footsteps;
|
||||||
|
char skyName[32];
|
||||||
|
float rollangle;
|
||||||
|
float rollspeed;
|
||||||
|
vec3_t skycolor;
|
||||||
|
vec3_t skyvec;
|
||||||
|
|
||||||
|
// xash extensions
|
||||||
|
int features;
|
||||||
|
int fog_settings;
|
||||||
|
float wateralpha;
|
||||||
|
vec3_t skydir; // unused
|
||||||
|
float skyangle; // unused
|
||||||
|
} movevars_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( movevars_t, 160, 160 );
|
||||||
|
|
||||||
|
#endif // QW_PMOVE_H
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/***
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
||||||
*
|
|
||||||
* This product contains software technology licensed from Id
|
|
||||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use, distribution, and modification of this source code and/or resulting
|
|
||||||
* object code is restricted to non-commercial enhancements to products from
|
|
||||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
||||||
* without written permission from Valve LLC.
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
|
|
||||||
#ifndef PM_TRACE_H
|
|
||||||
#define PM_TRACE_H
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
vec3_t normal;
|
|
||||||
float dist;
|
|
||||||
} pmplane_t;
|
|
||||||
|
|
||||||
typedef struct pmtrace_s pmtrace_t;
|
|
||||||
|
|
||||||
struct pmtrace_s
|
|
||||||
{
|
|
||||||
qboolean allsolid; // if true, plane is not valid
|
|
||||||
qboolean startsolid; // if true, the initial point was in a solid area
|
|
||||||
qboolean inopen, inwater; // End point is in empty space or in water
|
|
||||||
float fraction; // time completed, 1.0 = didn't hit anything
|
|
||||||
vec3_t endpos; // final position
|
|
||||||
pmplane_t plane; // surface normal at impact
|
|
||||||
int ent; // entity at impact
|
|
||||||
vec3_t deltavelocity; // Change in player's velocity caused by impact.
|
|
||||||
// Only run on server.
|
|
||||||
int hitgroup;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif//PM_TRACE_H
|
|
||||||
114
common/port.h
114
common/port.h
@@ -17,76 +17,54 @@ GNU General Public License for more details.
|
|||||||
#ifndef PORT_H
|
#ifndef PORT_H
|
||||||
#define PORT_H
|
#define PORT_H
|
||||||
|
|
||||||
#include "build.h"
|
|
||||||
|
|
||||||
#if !XASH_WIN32
|
|
||||||
#if XASH_APPLE
|
|
||||||
#include <sys/syslimits.h>
|
|
||||||
#define OS_LIB_EXT "dylib"
|
|
||||||
#define OPEN_COMMAND "open"
|
|
||||||
#elif XASH_EMSCRIPTEN
|
|
||||||
#define OS_LIB_EXT "wasm"
|
|
||||||
#define OPEN_COMMAND "???"
|
|
||||||
#else
|
|
||||||
#define OS_LIB_EXT "so"
|
|
||||||
#define OPEN_COMMAND "xdg-open"
|
|
||||||
#endif
|
|
||||||
#define OS_LIB_PREFIX "lib"
|
|
||||||
#define VGUI_SUPPORT_DLL "libvgui_support." OS_LIB_EXT
|
|
||||||
|
|
||||||
// Windows-specific
|
|
||||||
#define __cdecl
|
|
||||||
#define __stdcall
|
|
||||||
#define _inline static inline
|
|
||||||
|
|
||||||
#if XASH_POSIX
|
|
||||||
#include <unistd.h>
|
|
||||||
#if XASH_NSWITCH
|
|
||||||
#define SOLDER_LIBDL_COMPAT
|
|
||||||
#include <solder.h>
|
|
||||||
#elif XASH_PSVITA
|
|
||||||
#define VRTLD_LIBDL_COMPAT
|
|
||||||
#include <vrtld.h>
|
|
||||||
#define O_BINARY 0
|
|
||||||
#else
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#define HAVE_DUP
|
|
||||||
#define O_BINARY 0
|
|
||||||
#endif
|
|
||||||
#define O_TEXT 0
|
|
||||||
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void* HANDLE;
|
|
||||||
typedef void* HINSTANCE;
|
|
||||||
|
|
||||||
typedef struct tagPOINT
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
} POINT;
|
|
||||||
#else // WIN32
|
|
||||||
#define open _open
|
|
||||||
#define read _read
|
|
||||||
#define alloca _alloca
|
|
||||||
|
|
||||||
#define HSPRITE WINAPI_HSPRITE
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#undef HSPRITE
|
|
||||||
|
|
||||||
#define OS_LIB_PREFIX ""
|
|
||||||
#define OS_LIB_EXT "dll"
|
|
||||||
#define VGUI_SUPPORT_DLL "../vgui_support." OS_LIB_EXT
|
|
||||||
#define HAVE_DUP
|
|
||||||
#endif //WIN32
|
|
||||||
|
|
||||||
#ifndef XASH_LOW_MEMORY
|
|
||||||
#define XASH_LOW_MEMORY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include "build.h"
|
||||||
|
|
||||||
|
#if XASH_POSIX
|
||||||
|
#include <unistd.h>
|
||||||
|
#define OS_LIB_PREFIX "lib"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if XASH_APPLE
|
||||||
|
#include <sys/syslimits.h>
|
||||||
|
#define OS_LIB_EXT "dylib"
|
||||||
|
#define OPEN_COMMAND "open"
|
||||||
|
#elif XASH_POSIX
|
||||||
|
#define OS_LIB_EXT "so"
|
||||||
|
#define OPEN_COMMAND "xdg-open"
|
||||||
|
#elif XASH_WIN32
|
||||||
|
#define HSPRITE WINAPI_HSPRITE
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define VC_EXTRALEAN
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif // NOMINMAX
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#undef HSPRITE
|
||||||
|
#define open _open
|
||||||
|
#define read _read
|
||||||
|
|
||||||
|
#ifndef alloca
|
||||||
|
#define alloca _alloca
|
||||||
|
#endif // alloca
|
||||||
|
|
||||||
|
#define OS_LIB_PREFIX ""
|
||||||
|
#define OS_LIB_EXT "dll"
|
||||||
|
#define OPEN_COMMAND "open"
|
||||||
|
#elif XASH_PSP
|
||||||
|
#define OS_LIB_EXT "prx"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !XASH_WIN32
|
||||||
|
typedef void *HINSTANCE;
|
||||||
|
typedef struct tagPOINT { int x, y; } POINT; // one nasty function in cdll_int.h needs it
|
||||||
|
#endif // !XASH_WIN32
|
||||||
|
|
||||||
|
#ifndef XASH_LOW_MEMORY
|
||||||
|
#define XASH_LOW_MEMORY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // PORT_H
|
#endif // PORT_H
|
||||||
|
|||||||
115
common/q_client.h
Normal file
115
common/q_client.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// client.h -- primary header for client
|
||||||
|
|
||||||
|
#ifndef QUAKE_CLIENT_H
|
||||||
|
#define QUAKE_CLIENT_H
|
||||||
|
|
||||||
|
// Definitions originally taken from Quake, modified for binary compatibility
|
||||||
|
|
||||||
|
typedef struct usercmd_s
|
||||||
|
{
|
||||||
|
int16_t lerp_msec; // added in HL
|
||||||
|
int8_t msec; // added in QW
|
||||||
|
uint8_t pad1;
|
||||||
|
vec3_t viewangles;
|
||||||
|
|
||||||
|
// intended velocities
|
||||||
|
float forwardmove;
|
||||||
|
float sidemove;
|
||||||
|
float upmove;
|
||||||
|
uint8_t lightlevel;
|
||||||
|
uint8_t pad2;
|
||||||
|
uint16_t buttons; // added in QW
|
||||||
|
uint8_t impulse;
|
||||||
|
|
||||||
|
// added in HL
|
||||||
|
uint8_t weaponselect;
|
||||||
|
uint8_t pad3[2];
|
||||||
|
|
||||||
|
// unused HL impact stuff, left for modders
|
||||||
|
// TODO: document how to use them in delta encoding
|
||||||
|
int32_t reserved[4];
|
||||||
|
} usercmd_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( usercmd_t, 52, 52 );
|
||||||
|
|
||||||
|
typedef struct dlight_s
|
||||||
|
{
|
||||||
|
vec3_t origin;
|
||||||
|
float radius;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t r, g, b;
|
||||||
|
} color;
|
||||||
|
float die; // stop lighting after this time
|
||||||
|
float decay; // drop this each second
|
||||||
|
float minlight; // don't add when contributing less
|
||||||
|
int key; // so entities can reuse same entry
|
||||||
|
qboolean dark; // subtracts light instead of adding
|
||||||
|
} dlight_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( dlight_t, 40, 40 );
|
||||||
|
|
||||||
|
//
|
||||||
|
// cl_input
|
||||||
|
//
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int down[2]; // key nums holding it down
|
||||||
|
int state; // low bit is down state
|
||||||
|
} kbutton_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( kbutton_t, 12, 12 );
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// Quake defined types
|
||||||
|
pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2,
|
||||||
|
|
||||||
|
// added in HL
|
||||||
|
pt_4x_slowgrav, // 4 times faster than pt_slowgrav
|
||||||
|
pt_8x_slowgrav, // 8 times faster than pt_slowgrav
|
||||||
|
pt_custom, // will call think function from particle
|
||||||
|
} ptype_t;
|
||||||
|
|
||||||
|
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||||
|
typedef struct particle_s
|
||||||
|
{
|
||||||
|
// driver-usable fields
|
||||||
|
vec3_t org;
|
||||||
|
short color; // in HL color is defnied by palette
|
||||||
|
short unused; // not used in hw
|
||||||
|
|
||||||
|
// drivers never touch the following fields
|
||||||
|
struct particle_s *next;
|
||||||
|
vec3_t vel;
|
||||||
|
float ramp;
|
||||||
|
float die;
|
||||||
|
ptype_t type;
|
||||||
|
|
||||||
|
// HL added fields
|
||||||
|
void (*on_die)( struct particle_s *p );
|
||||||
|
void (*think)( struct particle_s *p, float frametime );
|
||||||
|
unsigned char userdata;
|
||||||
|
} particle_t;
|
||||||
|
|
||||||
|
STATIC_CHECK_SIZEOF( particle_t, 56, 72 );
|
||||||
|
|
||||||
|
#endif // QUAKE_CLIENT_H
|
||||||
@@ -16,23 +16,13 @@
|
|||||||
#ifndef R_EFX_H
|
#ifndef R_EFX_H
|
||||||
#define R_EFX_H
|
#define R_EFX_H
|
||||||
|
|
||||||
// particle_t
|
|
||||||
#if !defined( PARTICLEDEFH )
|
|
||||||
#include "particledef.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// BEAM
|
// BEAM
|
||||||
#if !defined( BEAMDEFH )
|
#if !defined( BEAMDEF_H )
|
||||||
#include "beamdef.h"
|
#include "beamdef.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// dlight_t
|
|
||||||
#if !defined ( DLIGHTH )
|
|
||||||
#include "dlight.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// cl_entity_t
|
// cl_entity_t
|
||||||
#if !defined( CL_ENTITYH )
|
#if !defined( CL_ENTITY_H )
|
||||||
#include "cl_entity.h"
|
#include "cl_entity.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -114,7 +104,9 @@ typedef struct tempent_s
|
|||||||
// baseline.angles - angle velocity
|
// baseline.angles - angle velocity
|
||||||
} TEMPENTITY;
|
} TEMPENTITY;
|
||||||
|
|
||||||
|
typedef struct particle_s particle_t;
|
||||||
typedef struct efx_api_s efx_api_t;
|
typedef struct efx_api_s efx_api_t;
|
||||||
|
struct dlight_s;
|
||||||
|
|
||||||
struct efx_api_s
|
struct efx_api_s
|
||||||
{
|
{
|
||||||
@@ -182,8 +174,8 @@ struct efx_api_s
|
|||||||
BEAM *(*R_BeamLightning)( float *start, float *end, int modelIndex, float life, float width, float amplitude, float brightness, float speed );
|
BEAM *(*R_BeamLightning)( float *start, float *end, int modelIndex, float life, float width, float amplitude, float brightness, float speed );
|
||||||
BEAM *(*R_BeamPoints)( float *start, float *end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
|
BEAM *(*R_BeamPoints)( float *start, float *end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
|
||||||
BEAM *(*R_BeamRing)( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
|
BEAM *(*R_BeamRing)( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
|
||||||
dlight_t *(*CL_AllocDlight)( int key );
|
struct dlight_s *(*CL_AllocDlight)( int key );
|
||||||
dlight_t *(*CL_AllocElight)( int key );
|
struct dlight_s *(*CL_AllocElight)( int key );
|
||||||
TEMPENTITY *(*CL_TempEntAlloc)( const float *org, struct model_s *model );
|
TEMPENTITY *(*CL_TempEntAlloc)( const float *org, struct model_s *model );
|
||||||
TEMPENTITY *(*CL_TempEntAllocNoModel)( const float *org );
|
TEMPENTITY *(*CL_TempEntAllocNoModel)( const float *org );
|
||||||
TEMPENTITY *(*CL_TempEntAllocHigh)( const float *org, struct model_s *model );
|
TEMPENTITY *(*CL_TempEntAllocHigh)( const float *org, struct model_s *model );
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#ifndef REF_PARAMS_H
|
#ifndef REF_PARAMS_H
|
||||||
#define REF_PARAMS_H
|
#define REF_PARAMS_H
|
||||||
|
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
typedef struct ref_params_s
|
typedef struct ref_params_s
|
||||||
{
|
{
|
||||||
// output
|
// output
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ GNU General Public License for more details.
|
|||||||
#ifndef RENDER_API_H
|
#ifndef RENDER_API_H
|
||||||
#define RENDER_API_H
|
#define RENDER_API_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include "lightstyle.h"
|
#include "lightstyle.h"
|
||||||
#include "dlight.h"
|
|
||||||
|
|
||||||
#define CL_RENDER_INTERFACE_VERSION 37 // Xash3D 1.0
|
#define CL_RENDER_INTERFACE_VERSION 37 // Xash3D 1.0
|
||||||
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
|
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
|
||||||
@@ -101,7 +101,7 @@ typedef enum
|
|||||||
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
|
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
|
||||||
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
|
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
|
||||||
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
|
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
|
||||||
// reserved
|
TF_PREMULTIPLIED = (1<<23), // RGBA was stored premultiplied (HL gradient / indexalpha)
|
||||||
// reserved
|
// reserved
|
||||||
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
|
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
|
||||||
TF_ARB_FLOAT = (1<<26), // float textures
|
TF_ARB_FLOAT = (1<<26), // float textures
|
||||||
@@ -175,6 +175,7 @@ enum movie_parms_e
|
|||||||
|
|
||||||
struct movie_state_s;
|
struct movie_state_s;
|
||||||
struct ref_viewpass_s;
|
struct ref_viewpass_s;
|
||||||
|
struct dlight_s;
|
||||||
|
|
||||||
typedef struct render_api_s
|
typedef struct render_api_s
|
||||||
{
|
{
|
||||||
@@ -183,8 +184,8 @@ typedef struct render_api_s
|
|||||||
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
|
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
|
||||||
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
|
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
|
||||||
lightstyle_t* (*GetLightStyle)( int number );
|
lightstyle_t* (*GetLightStyle)( int number );
|
||||||
dlight_t* (*GetDynamicLight)( int number );
|
struct dlight_s* (*GetDynamicLight)( int number );
|
||||||
dlight_t* (*GetEntityLight)( int number );
|
struct dlight_s* (*GetEntityLight)( int number );
|
||||||
byte (*LightToTexGamma)( byte color ); // software gamma support
|
byte (*LightToTexGamma)( byte color ); // software gamma support
|
||||||
float (*GetFrameTime)( void );
|
float (*GetFrameTime)( void );
|
||||||
|
|
||||||
|
|||||||
196
common/sound_api.h
Normal file
196
common/sound_api.h
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
sound_api.h - Xash3D extension for client sound interface
|
||||||
|
Copyright (C) 2026 Xash3D FWGS Developers
|
||||||
|
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOUND_API_H
|
||||||
|
#define SOUND_API_H
|
||||||
|
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
|
// Experimental implementation, backward compatibility is not guaranteed.
|
||||||
|
#define CL_SOUND_INTERFACE_VERSION 1
|
||||||
|
|
||||||
|
#define FL_VOXWORD_IN_CACHE BIT( 0 ) // if set, it was loaded prior and shouldn't be freed
|
||||||
|
|
||||||
|
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
||||||
|
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
||||||
|
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
||||||
|
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
||||||
|
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
||||||
|
|
||||||
|
typedef int sound_t;
|
||||||
|
|
||||||
|
typedef struct portable_samplepair_s
|
||||||
|
{
|
||||||
|
int left;
|
||||||
|
int right;
|
||||||
|
} portable_samplepair_t;
|
||||||
|
|
||||||
|
typedef struct sfx_s
|
||||||
|
{
|
||||||
|
char name[MAX_QPATH];
|
||||||
|
wavdata_t *cache;
|
||||||
|
|
||||||
|
int servercount;
|
||||||
|
uint hashValue;
|
||||||
|
struct sfx_s *hashNext;
|
||||||
|
} sfx_t;
|
||||||
|
|
||||||
|
typedef struct voxword_s
|
||||||
|
{
|
||||||
|
sfx_t *sfx;
|
||||||
|
uint16_t volume; // volume percent
|
||||||
|
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
||||||
|
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
||||||
|
uint8_t start; // percent at which playback starts
|
||||||
|
uint8_t end; // percent at which playback ends
|
||||||
|
uint8_t flags;
|
||||||
|
} voxword_t;
|
||||||
|
|
||||||
|
typedef struct channel_s
|
||||||
|
{
|
||||||
|
char name[16]; // keep sentence name
|
||||||
|
sfx_t *sfx; // sfx number
|
||||||
|
|
||||||
|
vec3_t origin; // only use if fixed_origin is set
|
||||||
|
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||||
|
|
||||||
|
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||||
|
uint flags;
|
||||||
|
short entnum; // entity soundsource
|
||||||
|
short master_vol; // 0-255 master volume
|
||||||
|
short leftvol; // 0-255 left volume
|
||||||
|
short rightvol; // 0-255 right volume
|
||||||
|
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||||||
|
byte word_index;
|
||||||
|
|
||||||
|
// HACKHACK: count when this channel became inaudible
|
||||||
|
// to not free it when it could be respatialized soon
|
||||||
|
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
||||||
|
float inauduble_free_time;
|
||||||
|
|
||||||
|
double sample;
|
||||||
|
double forced_end;
|
||||||
|
wavdata_t *data;
|
||||||
|
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||||
|
|
||||||
|
uintptr_t engine_reserved[8]; // only for engine developers
|
||||||
|
uintptr_t game_reserved[8]; // free space for game developers
|
||||||
|
} channel_t;
|
||||||
|
|
||||||
|
typedef struct rawchan_s
|
||||||
|
{
|
||||||
|
short entnum;
|
||||||
|
short master_vol;
|
||||||
|
short leftvol; // 0-255 left volume
|
||||||
|
short rightvol; // 0-255 right volume
|
||||||
|
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||||
|
vec3_t origin; // only use if fixed_origin is set
|
||||||
|
volatile uint s_rawend;
|
||||||
|
float oldtime; // catch time jumps
|
||||||
|
|
||||||
|
uintptr_t engine_reserved[8]; // only for engine developers
|
||||||
|
uintptr_t game_reserved[8]; // free space for game developers
|
||||||
|
|
||||||
|
size_t max_samples; // buffer length
|
||||||
|
portable_samplepair_t rawsamples[]; // variable sized
|
||||||
|
} rawchan_t;
|
||||||
|
|
||||||
|
typedef struct snd_format_s
|
||||||
|
{
|
||||||
|
uint speed;
|
||||||
|
byte width;
|
||||||
|
byte channels;
|
||||||
|
} snd_format_t;
|
||||||
|
|
||||||
|
typedef struct snd_globals_s
|
||||||
|
{
|
||||||
|
// dma
|
||||||
|
const char *backend_name;
|
||||||
|
byte *buffer;
|
||||||
|
snd_format_t format;
|
||||||
|
qboolean initialized; // sound engine is active
|
||||||
|
int samples; // mono samples in buffer
|
||||||
|
int samplepos; // in mono samples
|
||||||
|
|
||||||
|
int paintedtime; // total samples that have been mixed at speed
|
||||||
|
int soundtime; // total samples that have been played out to hardware at dma speed
|
||||||
|
|
||||||
|
// listener (client, camera, etc)
|
||||||
|
vec3_t origin;
|
||||||
|
vec3_t forward, right, up;
|
||||||
|
int entnum;
|
||||||
|
qboolean streaming; // playing AVI-file
|
||||||
|
qboolean stream_paused; // pause only background track
|
||||||
|
|
||||||
|
// SoundAPI shared pointers
|
||||||
|
channel_t *const channels;
|
||||||
|
int max_channels;
|
||||||
|
int total_channels;
|
||||||
|
rawchan_t **const raw_channels;
|
||||||
|
int max_raw_channels;
|
||||||
|
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||||
|
qboolean have_ambient_sfx;
|
||||||
|
} snd_globals_t;
|
||||||
|
|
||||||
|
typedef struct voice_audio_info_s
|
||||||
|
{
|
||||||
|
uint width;
|
||||||
|
uint samplerate;
|
||||||
|
uint frame_size; // in samples
|
||||||
|
} voice_audio_info_t;
|
||||||
|
|
||||||
|
// API from engine to client (client calls these)
|
||||||
|
typedef struct sound_api_s
|
||||||
|
{
|
||||||
|
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
|
||||||
|
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
|
||||||
|
// Voice extensions
|
||||||
|
void (*pfnS_RawEntSamples)( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
|
||||||
|
void (*pfnSND_ForceInitMouth)( int entnum );
|
||||||
|
voice_audio_info_t (*pfnVoice_GetAudioInfo)( void );
|
||||||
|
} sound_api_t;
|
||||||
|
|
||||||
|
// Callbacks from client to engine (engine calls these when custom sound is active)
|
||||||
|
typedef struct sound_interface_s
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
|
||||||
|
qboolean (*pfnS_Init)( snd_globals_t *globals );
|
||||||
|
void (*pfnS_Shutdown)( void );
|
||||||
|
void (*pfnS_UpdateSound)( void );
|
||||||
|
/* Full paint: endtime (sample pairs), dma buffer, paintedtime in/out. Client does mix + transfer to dma.buffer. */
|
||||||
|
void (*pfnS_PaintChannels)( int endtime );
|
||||||
|
void (*pfnS_UpdateChannel)( int ch_idx, const channel_t *ch, sound_t handle ); // ch=NULL -> channel freed
|
||||||
|
void (*pfnS_UpdateRawChannel)( int raw_idx, rawchan_t *ch ); // ch=NULL -> channel freed
|
||||||
|
void (*pfnS_Spatialize)( channel_t *ch );
|
||||||
|
void (*pfnS_FreeSound)( sfx_t *sfx, sound_t handle );
|
||||||
|
} sound_interface_t;
|
||||||
|
|
||||||
|
#endif // SOUND_API_H
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/***
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
||||||
*
|
|
||||||
* This product contains software technology licensed from Id
|
|
||||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use, distribution, and modification of this source code and/or resulting
|
|
||||||
* object code is restricted to non-commercial enhancements to products from
|
|
||||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
||||||
* without written permission from Valve LLC.
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
|
|
||||||
#ifndef USERCMD_H
|
|
||||||
#define USERCMD_H
|
|
||||||
|
|
||||||
typedef struct usercmd_s
|
|
||||||
{
|
|
||||||
short lerp_msec; // Interpolation time on client
|
|
||||||
byte msec; // Duration in ms of command
|
|
||||||
vec3_t viewangles; // Command view angles
|
|
||||||
|
|
||||||
// intended velocities
|
|
||||||
float forwardmove; // Forward velocity
|
|
||||||
float sidemove; // Sideways velocity
|
|
||||||
float upmove; // Upward velocity
|
|
||||||
byte lightlevel; // Light level at spot where we are standing.
|
|
||||||
unsigned short buttons; // Attack and move buttons
|
|
||||||
byte impulse; // Impulse command issued
|
|
||||||
byte weaponselect; // Current weapon id
|
|
||||||
|
|
||||||
// Experimental player impact stuff.
|
|
||||||
int impact_index;
|
|
||||||
vec3_t impact_position;
|
|
||||||
} usercmd_t;
|
|
||||||
|
|
||||||
#endif//USERCMD_H
|
|
||||||
@@ -2,23 +2,28 @@
|
|||||||
#ifndef XASH_TYPES_H
|
#ifndef XASH_TYPES_H
|
||||||
#define XASH_TYPES_H
|
#define XASH_TYPES_H
|
||||||
|
|
||||||
|
#include <wchar.h> // off_t
|
||||||
|
#include <sys/types.h> // off_t
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
|
#include "port.h"
|
||||||
|
|
||||||
#if XASH_IRIX
|
#define MAX_STRING 256 // generic string
|
||||||
#include <port.h>
|
#define MAX_VA_STRING 1024 // compatibility macro
|
||||||
|
#define MAX_SYSPATH 1024 // system filepath
|
||||||
|
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
||||||
|
#define CS_SIZE 64 // size of one config string
|
||||||
|
#define CS_TIME 16 // size of time string
|
||||||
|
|
||||||
|
// platform-specific alignment for types, to not break ABI
|
||||||
|
#if XASH_PSP
|
||||||
|
#define MAYBE_ALIGNED( x ) __attribute__(( aligned( 16 )))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XASH_WIN32
|
#if !defined( MAYBE_ALIGNED )
|
||||||
#include <wchar.h> // off_t
|
#define MAYBE_ALIGNED( x )
|
||||||
#endif // _WIN32
|
#endif // !defined( MAYBE_ALIGNED )
|
||||||
|
|
||||||
#include <sys/types.h> // off_t
|
|
||||||
#ifdef STDINT_H
|
|
||||||
#include STDINT_H
|
|
||||||
#else // !STDINT_H
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif // !STDINT_H
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
typedef uint8_t byte;
|
typedef uint8_t byte;
|
||||||
typedef float vec_t;
|
typedef float vec_t;
|
||||||
@@ -26,13 +31,30 @@ typedef vec_t vec2_t[2];
|
|||||||
#ifndef vec3_t // SDK renames it to Vector
|
#ifndef vec3_t // SDK renames it to Vector
|
||||||
typedef vec_t vec3_t[3];
|
typedef vec_t vec3_t[3];
|
||||||
#endif
|
#endif
|
||||||
typedef vec_t vec4_t[4];
|
typedef vec_t vec4_t[4] MAYBE_ALIGNED( 16 );
|
||||||
typedef vec_t quat_t[4];
|
typedef vec_t quat_t[4] MAYBE_ALIGNED( 16 );
|
||||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||||
typedef vec_t matrix3x4[3][4];
|
typedef vec_t matrix3x4[3][4] MAYBE_ALIGNED( 16 );
|
||||||
typedef vec_t matrix4x4[4][4];
|
typedef vec_t matrix4x4[4][4] MAYBE_ALIGNED( 16 );
|
||||||
typedef uint32_t poolhandle_t;
|
typedef uint32_t poolhandle_t;
|
||||||
|
typedef uint16_t word;
|
||||||
|
typedef uint32_t dword;
|
||||||
|
typedef char string[MAX_STRING];
|
||||||
|
typedef off_t fs_offset_t;
|
||||||
|
#if XASH_WIN32
|
||||||
|
typedef int fs_size_t; // return type of _read, _write funcs
|
||||||
|
#else // !XASH_WIN32
|
||||||
|
typedef ssize_t fs_size_t;
|
||||||
|
#endif // !XASH_WIN32
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef void *(*pfnCreateInterface_t)( const char *, int * );
|
||||||
|
|
||||||
|
// Quake definition
|
||||||
|
typedef struct link_s
|
||||||
|
{
|
||||||
|
struct link_s *prev, *next;
|
||||||
|
} link_t;
|
||||||
|
|
||||||
#undef true
|
#undef true
|
||||||
#undef false
|
#undef false
|
||||||
@@ -43,95 +65,77 @@ enum { false, true };
|
|||||||
#endif
|
#endif
|
||||||
typedef int qboolean;
|
typedef int qboolean;
|
||||||
|
|
||||||
#define MAX_STRING 256 // generic string
|
#if XASH_LOW_MEMORY == 1 || XASH_PSP
|
||||||
#define MAX_VA_STRING 1024 // compatibility macro
|
#define MAX_QPATH 48
|
||||||
#define MAX_SYSPATH 1024 // system filepath
|
#define MAX_MODS 16
|
||||||
#define MAX_MODS 512 // environment games that engine can keep visible
|
#elif XASH_LOW_MEMORY == 2
|
||||||
|
#define MAX_QPATH 32 // should be enough for singleplayer
|
||||||
|
#define MAX_MODS 4
|
||||||
|
#else // !XASH_LOW_MEMORY
|
||||||
|
#define MAX_QPATH 64
|
||||||
|
#define MAX_MODS 512
|
||||||
|
#endif // !XASH_LOW_MEMORY
|
||||||
|
|
||||||
#define BIT( n ) ( 1U << ( n ))
|
#define BIT( n ) ( 1U << ( n ))
|
||||||
#define BIT64( n ) ( 1ULL << ( n ))
|
#define BIT64( n ) ( 1ULL << ( n ))
|
||||||
|
|
||||||
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
|
#define SetBits( bit_vector, bits ) (( bit_vector ) |= ( bits ))
|
||||||
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
|
#define ClearBits( bit_vector, bits ) (( bit_vector ) &= ~( bits ))
|
||||||
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
|
#define FBitSet( bit_vector, bits ) (( bit_vector ) & ( bits ))
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#ifdef NULL
|
|
||||||
#undef NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NULL ((void *)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// color strings
|
// color strings
|
||||||
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
#define IsColorString( p ) (( p ) && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||||
|
|
||||||
#undef EXPORT
|
|
||||||
|
|
||||||
#if defined( __GNUC__ )
|
#if defined( __GNUC__ )
|
||||||
#if defined( __i386__ )
|
#if defined( __i386__ )
|
||||||
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
||||||
#define GAME_EXPORT __attribute__(( force_align_arg_pointer ))
|
#define GAME_EXPORT __attribute__(( force_align_arg_pointer ))
|
||||||
#else
|
#else // !defined( __i386__ )
|
||||||
#define EXPORT __attribute__(( visibility ( "default" )))
|
#define EXPORT __attribute__(( visibility ( "default" )))
|
||||||
#define GAME_EXPORT
|
#endif // !defined( __i386__ )
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MALLOC __attribute__(( malloc ))
|
|
||||||
|
|
||||||
// added in GCC 11
|
|
||||||
#if __GNUC__ >= 11
|
#if __GNUC__ >= 11
|
||||||
// might want to set noclone due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116893
|
// might want to set noclone due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116893
|
||||||
// but it's easier to not force mismatched-dealloc to error yet
|
// but it's easier to not force mismatched-dealloc to error yet
|
||||||
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
|
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
|
||||||
#else
|
#else
|
||||||
#define MALLOC_LIKE( x, y ) MALLOC
|
#define MALLOC_LIKE( x, y ) __attribute__(( malloc ))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RETURNS_NONNULL __attribute__(( returns_nonnull ))
|
||||||
|
#if !__clang__ && !__MCST__
|
||||||
|
// clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
|
||||||
|
// lcc doesn't support it at all
|
||||||
|
#define PFN_RETURNS_NONNULL RETURNS_NONNULL
|
||||||
#endif
|
#endif
|
||||||
#define NORETURN __attribute__(( noreturn ))
|
#define NORETURN __attribute__(( noreturn ))
|
||||||
#define NONNULL __attribute__(( nonnull ))
|
#define NONNULL __attribute__(( nonnull ))
|
||||||
#define RETURNS_NONNULL __attribute__(( returns_nonnull ))
|
|
||||||
#if __clang__ || __MCST__
|
|
||||||
// clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
|
|
||||||
// lcc doesn't support it at all
|
|
||||||
#define PFN_RETURNS_NONNULL
|
|
||||||
#else
|
|
||||||
#define PFN_RETURNS_NONNULL RETURNS_NONNULL
|
|
||||||
#endif
|
|
||||||
#define FORMAT_CHECK( x ) __attribute__(( format( printf, x, x + 1 )))
|
#define FORMAT_CHECK( x ) __attribute__(( format( printf, x, x + 1 )))
|
||||||
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
||||||
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
|
||||||
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
|
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
|
||||||
#define RENAME_SYMBOL( x ) asm( x )
|
#define RENAME_SYMBOL( x ) asm( x )
|
||||||
#else
|
#if !defined( offsetof )
|
||||||
#if defined( _MSC_VER )
|
#define offsetof( s, m ) __builtin_offsetof( s, m )
|
||||||
#define EXPORT __declspec( dllexport )
|
#endif // !defined( offsetof )
|
||||||
#define NO_ASAN __declspec( no_sanitize_address )
|
#elif defined( _MSC_VER )
|
||||||
#else
|
#define EXPORT __declspec( dllexport )
|
||||||
#define EXPORT
|
|
||||||
#define NO_ASAN
|
|
||||||
#endif
|
|
||||||
#define GAME_EXPORT
|
|
||||||
#define NORETURN
|
|
||||||
#define NONNULL
|
|
||||||
#define RETURNS_NONNULL
|
|
||||||
#define PFN_RETURNS_NONNULL
|
|
||||||
#define FORMAT_CHECK( x )
|
|
||||||
#define ALLOC_CHECK( x )
|
|
||||||
#define RENAME_SYMBOL( x )
|
|
||||||
#define MALLOC
|
|
||||||
#define MALLOC_LIKE( x, y )
|
|
||||||
#define WARN_UNUSED_RESULT
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( __has_feature )
|
#ifdef ARRAYSIZE
|
||||||
#if __has_feature( address_sanitizer )
|
#undef ARRAYSIZE
|
||||||
#define USE_ASAN 1
|
#endif // ARRAYSIZE
|
||||||
#endif // __has_feature
|
|
||||||
#endif // defined( __has_feature )
|
|
||||||
|
|
||||||
#if !defined( USE_ASAN ) && defined( __SANITIZE_ADDRESS__ )
|
#define ARRAYSIZE( p ) ( sizeof(( p ))/ sizeof(( p )[0] ))
|
||||||
#define USE_ASAN 1
|
|
||||||
|
#if defined( __SANITIZE_ADDRESS__ )
|
||||||
|
#define USE_ASAN 1
|
||||||
|
|
||||||
|
#if defined( __GNUC__ )
|
||||||
|
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||||
|
#elif defined( _MSC_VER )
|
||||||
|
#define NO_ASAN __declspec( no_sanitize_address )
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __GNUC__ >= 3
|
#if __GNUC__ >= 3
|
||||||
@@ -144,11 +148,73 @@ typedef int qboolean;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||||
|
#define XASH_RESTRICT restrict
|
||||||
|
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||||
|
#define XASH_RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( EXPORT )
|
||||||
|
#define EXPORT
|
||||||
|
#endif // !defined( EXPORT )
|
||||||
|
|
||||||
|
#if !defined( GAME_EXPORT )
|
||||||
|
#define GAME_EXPORT
|
||||||
|
#endif // !defined( GAME_EXPORT )
|
||||||
|
|
||||||
|
#if !defined( MALLOC_LIKE )
|
||||||
|
#define MALLOC_LIKE( x, y )
|
||||||
|
#endif // !defined MALLOC_LIKE
|
||||||
|
|
||||||
|
#if !defined( NO_ASAN )
|
||||||
|
#define NO_ASAN
|
||||||
|
#endif // !defined( NO_ASAN )
|
||||||
|
|
||||||
|
#if !defined( RETURNS_NONNULL )
|
||||||
|
#define RETURNS_NONNULL
|
||||||
|
#endif // !defined( RETURNS_NONNULL )
|
||||||
|
|
||||||
|
#if !defined( PFN_RETURNS_NONNULL )
|
||||||
|
#define PFN_RETURNS_NONNULL
|
||||||
|
#endif // !defined( PFN_RETURNS_NONNULL )
|
||||||
|
|
||||||
|
#if !defined( NORETURN )
|
||||||
|
#define NORETURN
|
||||||
|
#endif // !defined( NORETURN )
|
||||||
|
|
||||||
|
#if !defined( NONNULL )
|
||||||
|
#define NONNULL
|
||||||
|
#endif // !defined( NONNULL )
|
||||||
|
|
||||||
|
#if !defined( FORMAT_CHECK )
|
||||||
|
#define FORMAT_CHECK( x )
|
||||||
|
#endif // !defined( FORMAT_CHECK )
|
||||||
|
|
||||||
|
#if !defined( ALLOC_CHECK )
|
||||||
|
#define ALLOC_CHECK( x )
|
||||||
|
#endif // !defined( ALLOC_CHECK )
|
||||||
|
|
||||||
|
#if !defined( WARN_UNUSED_RESULT )
|
||||||
|
#define WARN_UNUSED_RESULT
|
||||||
|
#endif // !defined( WARN_UNUSED_RESULT )
|
||||||
|
|
||||||
|
#if !defined( RENAME_SYMBOL )
|
||||||
|
#define RENAME_SYMBOL( x )
|
||||||
|
#endif // !defined( RENAME_SYMBOL )
|
||||||
|
|
||||||
#if !defined( unlikely ) || !defined( likely )
|
#if !defined( unlikely ) || !defined( likely )
|
||||||
#define unlikely( x ) ( x )
|
#define unlikely( x ) ( x )
|
||||||
#define likely( x ) ( x )
|
#define likely( x ) ( x )
|
||||||
|
#endif // !defined( unlikely ) || !defined( likely )
|
||||||
|
|
||||||
|
#if !defined( XASH_RESTRICT )
|
||||||
|
#define XASH_RESTRICT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined( offsetof )
|
||||||
|
#define offsetof( s, m ) (size_t)&(((s *)0)->m )
|
||||||
|
#endif // !defined( offsetof )
|
||||||
|
|
||||||
#if __STDC_VERSION__ >= 202311L || __cplusplus >= 201103L // C23 or C++ static_assert is a keyword
|
#if __STDC_VERSION__ >= 202311L || __cplusplus >= 201103L // C23 or C++ static_assert is a keyword
|
||||||
#define STATIC_ASSERT_( ignore, x, y ) static_assert( x, y )
|
#define STATIC_ASSERT_( ignore, x, y ) static_assert( x, y )
|
||||||
#define STATIC_ASSERT static_assert
|
#define STATIC_ASSERT static_assert
|
||||||
@@ -165,75 +231,36 @@ typedef int qboolean;
|
|||||||
|
|
||||||
// at least, statically check size of some public structures
|
// at least, statically check size of some public structures
|
||||||
#if XASH_64BIT
|
#if XASH_64BIT
|
||||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||||
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
||||||
#else
|
#else
|
||||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||||
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
#define Swap32( x ) (((uint32_t)((( x ) & 255 ) << 24 )) + ((uint32_t)(((( x ) >> 8 ) & 255 ) << 16 )) + ((uint32_t)((( x ) >> 16 ) & 255 ) << 8 ) + ((( x ) >> 24 ) & 255 ))
|
||||||
#define XASH_RESTRICT restrict
|
#define Swap16( x ) ((uint16_t)((((uint16_t)( x ) >> 8 ) & 255 ) + (((uint16_t)( x ) & 255 ) << 8 )))
|
||||||
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
#define Swap32Store( x ) ( x = Swap32( x ))
|
||||||
#define XASH_RESTRICT __restrict
|
#define Swap16Store( x ) ( x = Swap16( x ))
|
||||||
#else
|
|
||||||
#define XASH_RESTRICT // nothing
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XASH_BIG_ENDIAN
|
#ifdef XASH_BIG_ENDIAN
|
||||||
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
|
#define LittleLong( x ) Swap32( x )
|
||||||
#define LittleLongSW(x) (x = LittleLong(x) )
|
#define LittleShort( x ) Swap16( x )
|
||||||
#define LittleShort(x) ((short)( (((short)(x) >> 8) & 255) + (((short)(x) & 255) << 8)))
|
#define LittleLongSW( x ) Swap32Store( x )
|
||||||
#define LittleShortSW(x) (x = LittleShort(x) )
|
#define LittleShortSW( x ) Swap16Store( x )
|
||||||
_inline float LittleFloat( float f )
|
#define LittleFloat( x ) SwapFloat( x )
|
||||||
{
|
#define BigLong( x ) ( x )
|
||||||
union
|
#define BigShort( x ) ( x )
|
||||||
{
|
#define BigFloat( x ) ( x )
|
||||||
float f;
|
|
||||||
unsigned char b[4];
|
|
||||||
} dat1, dat2;
|
|
||||||
|
|
||||||
dat1.f = f;
|
|
||||||
dat2.b[0] = dat1.b[3];
|
|
||||||
dat2.b[1] = dat1.b[2];
|
|
||||||
dat2.b[2] = dat1.b[1];
|
|
||||||
dat2.b[3] = dat1.b[0];
|
|
||||||
|
|
||||||
return dat2.f;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
#define LittleLong(x) (x)
|
#define LittleLong( x ) ( x )
|
||||||
#define LittleLongSW(x)
|
#define LittleShort( x ) ( x )
|
||||||
#define LittleShort(x) (x)
|
#define LittleFloat( x ) ( x )
|
||||||
#define LittleShortSW(x)
|
#define LittleLongSW( x )
|
||||||
#define LittleFloat(x) (x)
|
#define LittleShortSW( x )
|
||||||
|
#define BigLong( x ) Swap32( x )
|
||||||
|
#define BigShort( x ) Swap16( x )
|
||||||
|
#define BigFloat( x ) SwapFloat( x )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef unsigned int dword;
|
|
||||||
typedef unsigned int uint;
|
|
||||||
typedef char string[MAX_STRING];
|
|
||||||
typedef off_t fs_offset_t;
|
|
||||||
#if XASH_WIN32
|
|
||||||
typedef int fs_size_t; // return type of _read, _write funcs
|
|
||||||
#else /* !XASH_WIN32 */
|
|
||||||
typedef ssize_t fs_size_t;
|
|
||||||
#endif /* !XASH_WIN32 */
|
|
||||||
|
|
||||||
typedef void *(*pfnCreateInterface_t)( const char *, int * );
|
|
||||||
|
|
||||||
// config strings are a general means of communication from
|
|
||||||
// the server to all connected clients.
|
|
||||||
// each config string can be at most CS_SIZE characters.
|
|
||||||
#if XASH_LOW_MEMORY == 0
|
|
||||||
#define MAX_QPATH 64 // max length of a game pathname
|
|
||||||
#elif XASH_LOW_MEMORY == 2
|
|
||||||
#define MAX_QPATH 32 // should be enough for singleplayer
|
|
||||||
#elif XASH_LOW_MEMORY == 1
|
|
||||||
#define MAX_QPATH 48
|
|
||||||
#endif
|
|
||||||
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
|
||||||
#define CS_SIZE 64 // size of one config string
|
|
||||||
#define CS_TIME 16 // size of time string
|
|
||||||
|
|
||||||
#endif // XASH_TYPES_H
|
#endif // XASH_TYPES_H
|
||||||
|
|||||||
@@ -17,8 +17,10 @@
|
|||||||
#define ALIAS_H
|
#define ALIAS_H
|
||||||
|
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include STDINT_H
|
#include <stdint.h>
|
||||||
#include "synctype.h"
|
#include "synctype.h"
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
#include "com_model.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ struct mstudioevent_s;
|
|||||||
struct engine_studio_api_s;
|
struct engine_studio_api_s;
|
||||||
struct r_studio_interface_s;
|
struct r_studio_interface_s;
|
||||||
|
|
||||||
|
struct sound_api_s;
|
||||||
|
struct sound_interface_s;
|
||||||
|
|
||||||
|
typedef struct sound_api_s sound_api_t;
|
||||||
|
typedef struct sound_interface_s sound_interface_t;
|
||||||
|
|
||||||
// NOTE: ordering is important!
|
// NOTE: ordering is important!
|
||||||
typedef struct cldll_func_s
|
typedef struct cldll_func_s
|
||||||
{
|
{
|
||||||
@@ -74,6 +80,9 @@ typedef struct cldll_func_s
|
|||||||
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
||||||
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
||||||
void (*pfnLookEvent)( float relyaw, float relpitch );
|
void (*pfnLookEvent)( float relyaw, float relpitch );
|
||||||
|
// Sound API
|
||||||
|
int (*pfnGetSoundInterface)( int version, const sound_api_t *api, sound_interface_t *callback );
|
||||||
|
int (*pfnVoice_StartChannel)( int samples, byte *data, int entnum );
|
||||||
} cldll_func_t;
|
} cldll_func_t;
|
||||||
|
|
||||||
#endif//CDLL_EXP_H
|
#endif//CDLL_EXP_H
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *dura
|
|||||||
qboolean AVI_HaveAudioTrack( const movie_state_t *Avi );
|
qboolean AVI_HaveAudioTrack( const movie_state_t *Avi );
|
||||||
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
|
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
|
||||||
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
|
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
|
||||||
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time );
|
|
||||||
void AVI_CloseVideo( movie_state_t *Avi );
|
void AVI_CloseVideo( movie_state_t *Avi );
|
||||||
qboolean AVI_IsActive( movie_state_t *Avi );
|
qboolean AVI_IsActive( movie_state_t *Avi );
|
||||||
void AVI_FreeVideo( movie_state_t *Avi );
|
void AVI_FreeVideo( movie_state_t *Avi );
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ static qboolean avi_initialized;
|
|||||||
static poolhandle_t avi_mempool;
|
static poolhandle_t avi_mempool;
|
||||||
|
|
||||||
#if XASH_AVI == AVI_FFMPEG
|
#if XASH_AVI == AVI_FFMPEG
|
||||||
#define XASH_FFMPEG_DLOPEN 1
|
|
||||||
#include "avi_ffmpeg.h"
|
#include "avi_ffmpeg.h"
|
||||||
|
|
||||||
struct movie_state_s
|
struct movie_state_s
|
||||||
@@ -222,11 +221,6 @@ int AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *duration )
|
qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *duration )
|
||||||
{
|
{
|
||||||
if( !Avi->active )
|
if( !Avi->active )
|
||||||
@@ -261,9 +255,9 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
|||||||
rawchan_t *ch = NULL;
|
rawchan_t *ch = NULL;
|
||||||
|
|
||||||
// keep the same semantics, when S_RAW_SOUND_SOUNDTRACK doesn't play if S_StartStreaming wasn't enabled
|
// keep the same semantics, when S_RAW_SOUND_SOUNDTRACK doesn't play if S_StartStreaming wasn't enabled
|
||||||
qboolean disable_stream = Avi->entnum == S_RAW_SOUND_SOUNDTRACK ? !s_listener.streaming : false;
|
qboolean disable_stream = Avi->entnum == S_RAW_SOUND_SOUNDTRACK ? !snd.streaming : false;
|
||||||
|
|
||||||
if( !dma.initialized || disable_stream || s_listener.paused || !Avi->cached_audio )
|
if( !snd.initialized || disable_stream || cl.paused || !Avi->cached_audio )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ch = S_FindRawChannel( Avi->entnum, true );
|
ch = S_FindRawChannel( Avi->entnum, true );
|
||||||
@@ -274,14 +268,14 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
|||||||
ch->master_vol = Avi->volume;
|
ch->master_vol = Avi->volume;
|
||||||
ch->dist_mult = (Avi->attn / SND_CLIP_DISTANCE);
|
ch->dist_mult = (Avi->attn / SND_CLIP_DISTANCE);
|
||||||
|
|
||||||
if( ch->s_rawend < soundtime )
|
if( ch->s_rawend < snd.soundtime )
|
||||||
ch->s_rawend = soundtime;
|
ch->s_rawend = snd.soundtime;
|
||||||
|
|
||||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
while( ch->s_rawend < snd.soundtime + ch->max_samples )
|
||||||
{
|
{
|
||||||
size_t copy;
|
size_t copy;
|
||||||
|
|
||||||
buffer_samples = ch->max_samples - (ch->s_rawend - soundtime);
|
buffer_samples = ch->max_samples - (ch->s_rawend - snd.soundtime);
|
||||||
|
|
||||||
file_samples = buffer_samples * ((float)Avi->rate / SOUND_DMA_SPEED);
|
file_samples = buffer_samples * ((float)Avi->rate / SOUND_DMA_SPEED);
|
||||||
if( file_samples <= 1 ) return; // no more samples need
|
if( file_samples <= 1 ) return; // no more samples need
|
||||||
@@ -355,6 +349,10 @@ qboolean AVI_Think( movie_state_t *Avi )
|
|||||||
qboolean decoded = false;
|
qboolean decoded = false;
|
||||||
qboolean flushing = false;
|
qboolean flushing = false;
|
||||||
qboolean redraw = false;
|
qboolean redraw = false;
|
||||||
|
|
||||||
|
if( !Avi->video_ctx )
|
||||||
|
return false;
|
||||||
|
|
||||||
const double timebase = (double)Avi->video_ctx->pkt_timebase.den / Avi->video_ctx->pkt_timebase.num;
|
const double timebase = (double)Avi->video_ctx->pkt_timebase.den / Avi->video_ctx->pkt_timebase.num;
|
||||||
int64_t curtime = round( Platform_DoubleTime() * timebase );
|
int64_t curtime = round( Platform_DoubleTime() * timebase );
|
||||||
|
|
||||||
@@ -384,7 +382,7 @@ qboolean AVI_Think( movie_state_t *Avi )
|
|||||||
|
|
||||||
if(( res = pav_read_frame( Avi->fmt_ctx, Avi->pkt )) >= 0 )
|
if(( res = pav_read_frame( Avi->fmt_ctx, Avi->pkt )) >= 0 )
|
||||||
{
|
{
|
||||||
if( Avi->pkt->stream_index == Avi->audio_stream )
|
if( Avi->pkt->stream_index == Avi->audio_stream && Avi->audio_ctx )
|
||||||
{
|
{
|
||||||
res = pavcodec_send_packet( Avi->audio_ctx, Avi->pkt );
|
res = pavcodec_send_packet( Avi->audio_ctx, Avi->pkt );
|
||||||
if( res < 0 )
|
if( res < 0 )
|
||||||
@@ -842,11 +840,6 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AVI_CloseVideo( movie_state_t *Avi )
|
void AVI_CloseVideo( movie_state_t *Avi )
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -26,35 +26,101 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
#if XASH_FFMPEG_DLOPEN
|
#if XASH_FFMPEG_DLOPEN
|
||||||
|
|
||||||
|
// using typeof gives more resilience to function declaration changes
|
||||||
|
// but it's only available in GCC and standardized in C23
|
||||||
|
#if defined(__GNUC__) || __STDC_VERSION__ >= 202311L
|
||||||
|
|
||||||
|
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
||||||
|
#define SUPPORTED_AVF_VERSION_MAJOR LIBAVFORMAT_VERSION_MAJOR
|
||||||
|
#define SUPPORTED_AVC_VERSION_MAJOR LIBAVCODEC_VERSION_MAJOR
|
||||||
|
#define SUPPORTED_SWR_VERSION_MAJOR LIBSWRESAMPLE_VERSION_MAJOR
|
||||||
|
#define SUPPORTED_SWS_VERSION_MAJOR LIBSWSCALE_VERSION_MAJOR
|
||||||
|
|
||||||
|
#define F( func ) \
|
||||||
|
typedef typeof( func ) func##_t; \
|
||||||
|
func##_t *p##func
|
||||||
|
|
||||||
|
// libavutil
|
||||||
|
F( avutil_version );
|
||||||
|
F( av_frame_alloc );
|
||||||
|
F( av_frame_free );
|
||||||
|
F( av_frame_ref );
|
||||||
|
F( av_frame_unref );
|
||||||
|
F( av_strerror );
|
||||||
|
F( av_free );
|
||||||
|
F( av_get_bytes_per_sample );
|
||||||
|
F( av_get_media_type_string );
|
||||||
|
F( av_image_alloc );
|
||||||
|
|
||||||
|
// libavformat
|
||||||
|
F( avformat_version );
|
||||||
|
F( av_find_best_stream );
|
||||||
|
F( av_read_frame );
|
||||||
|
F( av_seek_frame );
|
||||||
|
F( avformat_close_input );
|
||||||
|
F( avformat_find_stream_info );
|
||||||
|
F( avformat_open_input );
|
||||||
|
|
||||||
|
// libavcodec
|
||||||
|
F( avcodec_version );
|
||||||
|
F( av_packet_alloc );
|
||||||
|
F( av_packet_free );
|
||||||
|
F( av_packet_unref );
|
||||||
|
F( avcodec_alloc_context3 );
|
||||||
|
F( avcodec_find_decoder );
|
||||||
|
F( avcodec_flush_buffers );
|
||||||
|
F( avcodec_free_context );
|
||||||
|
F( avcodec_open2 );
|
||||||
|
F( avcodec_parameters_to_context );
|
||||||
|
F( avcodec_receive_frame );
|
||||||
|
F( avcodec_send_packet );
|
||||||
|
|
||||||
|
// libswresample
|
||||||
|
F( swresample_version );
|
||||||
|
F( swr_alloc_set_opts2 );
|
||||||
|
F( swr_convert );
|
||||||
|
F( swr_free );
|
||||||
|
F( swr_init );
|
||||||
|
|
||||||
|
// libswscale
|
||||||
|
F( swscale_version );
|
||||||
|
F( sws_freeContext );
|
||||||
|
F( sws_getContext );
|
||||||
|
F( sws_scale );
|
||||||
|
|
||||||
|
#undef F
|
||||||
|
|
||||||
|
#else // !defined(__GNUC__) && __STDC_VERSION__ < 202311L
|
||||||
|
|
||||||
// the following symbols were taken from ffmpeg public headers
|
// the following symbols were taken from ffmpeg public headers
|
||||||
// on each major ffmpeg uprgade, they must be validated
|
// on each major ffmpeg uprgade, they must be validated
|
||||||
// ffmpeg guarantees API and ABI compatibility between major versions
|
// ffmpeg guarantees API and ABI compatibility between major versions
|
||||||
// so complain if this gets compiled against unsupported yet version
|
// so complain if this gets compiled against unsupported yet version
|
||||||
// the same check will be done in runtime to ensure compatibility
|
// the same check will be done in runtime to ensure compatibility
|
||||||
#define SUPPORTED_AVU_VERSION_MAJOR 59
|
#define SUPPORTED_AVU_VERSION_MAJOR 60
|
||||||
#define SUPPORTED_AVF_VERSION_MAJOR 61
|
#define SUPPORTED_AVF_VERSION_MAJOR 62
|
||||||
#define SUPPORTED_AVC_VERSION_MAJOR 61
|
#define SUPPORTED_AVC_VERSION_MAJOR 62
|
||||||
#define SUPPORTED_SWR_VERSION_MAJOR 5
|
#define SUPPORTED_SWR_VERSION_MAJOR 6
|
||||||
#define SUPPORTED_SWS_VERSION_MAJOR 8
|
#define SUPPORTED_SWS_VERSION_MAJOR 9
|
||||||
|
|
||||||
#if SUPPORTED_AVU_VERSION_MAJOR != LIBAVUTIL_VERSION_MAJOR
|
#if SUPPORTED_AVU_VERSION_MAJOR != LIBAVUTIL_VERSION_MAJOR
|
||||||
#error
|
#error "unsupported libavutil version"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_AVF_VERSION_MAJOR != LIBAVFORMAT_VERSION_MAJOR
|
#if SUPPORTED_AVF_VERSION_MAJOR != LIBAVFORMAT_VERSION_MAJOR
|
||||||
#error
|
#error "unsupported libavformat version"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_AVC_VERSION_MAJOR != LIBAVCODEC_VERSION_MAJOR
|
#if SUPPORTED_AVC_VERSION_MAJOR != LIBAVCODEC_VERSION_MAJOR
|
||||||
#error
|
#error "unsupported libavcodec version"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_SWR_VERSION_MAJOR != LIBSWRESAMPLE_VERSION_MAJOR
|
#if SUPPORTED_SWR_VERSION_MAJOR != LIBSWRESAMPLE_VERSION_MAJOR
|
||||||
#error
|
#error "unsupported libswresample version"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_SWS_VERSION_MAJOR != LIBSWSCALE_VERSION_MAJOR
|
#if SUPPORTED_SWS_VERSION_MAJOR != LIBSWSCALE_VERSION_MAJOR
|
||||||
#error
|
#error "unsupported libswscale version"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libavutil
|
// libavutil
|
||||||
@@ -105,6 +171,8 @@ void (*psws_freeContext)( struct SwsContext *swsContext );
|
|||||||
struct SwsContext *(*psws_getContext)( int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param );
|
struct SwsContext *(*psws_getContext)( int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param );
|
||||||
int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[] );
|
int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[] );
|
||||||
|
|
||||||
|
#endif // defined(__GNUC__) || __STDC_VERSION__ >= 202311L
|
||||||
|
|
||||||
#else // !XASH_FFMPEG_DLOPEN
|
#else // !XASH_FFMPEG_DLOPEN
|
||||||
|
|
||||||
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
||||||
@@ -116,8 +184,9 @@ int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcS
|
|||||||
// libavutil
|
// libavutil
|
||||||
#define pavutil_version avutil_version
|
#define pavutil_version avutil_version
|
||||||
#define pav_frame_alloc av_frame_alloc
|
#define pav_frame_alloc av_frame_alloc
|
||||||
|
#define pav_frame_free av_frame_free
|
||||||
#define pav_frame_ref av_frame_ref
|
#define pav_frame_ref av_frame_ref
|
||||||
#define pav_frame_unref av_Frame_unref
|
#define pav_frame_unref av_frame_unref
|
||||||
#define pav_strerror av_strerror
|
#define pav_strerror av_strerror
|
||||||
#define pav_free av_free
|
#define pav_free av_free
|
||||||
#define pav_get_bytes_per_sample av_get_bytes_per_sample
|
#define pav_get_bytes_per_sample av_get_bytes_per_sample
|
||||||
|
|||||||
@@ -97,7 +97,17 @@ void CL_PlayCDTrack_f( void )
|
|||||||
if( Q_isdigit( pszTrack ))
|
if( Q_isdigit( pszTrack ))
|
||||||
{
|
{
|
||||||
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
||||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0, false );
|
|
||||||
|
// a1ba: some maps contain cd track set in worldspawn
|
||||||
|
// forcibly stopping music on changelevel
|
||||||
|
//
|
||||||
|
// server notifies us about this in sv_client.c SV_PutClientInServer
|
||||||
|
// through "cd loop" command
|
||||||
|
//
|
||||||
|
// however, it could be set to a track that doesn't contain music data (in CD terms)
|
||||||
|
// so we catch it here and music will carry over changelevels
|
||||||
|
if( !COM_StringEmpty( clgame.cdtracks[track-1] ))
|
||||||
|
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0, false );
|
||||||
}
|
}
|
||||||
else S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
|
else S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
|
||||||
paused = false;
|
paused = false;
|
||||||
@@ -136,10 +146,13 @@ void CL_PlayCDTrack_f( void )
|
|||||||
}
|
}
|
||||||
else if( !Q_stricmp( command, "info" ))
|
else if( !Q_stricmp( command, "info" ))
|
||||||
{
|
{
|
||||||
int i, maxTrack;
|
int maxTrack = 0;
|
||||||
|
|
||||||
for( maxTrack = i = 0; i < MAX_CDTRACKS; i++ )
|
for( int i = 0; i < MAX_CDTRACKS; i++ )
|
||||||
if( COM_CheckStringEmpty( clgame.cdtracks[i] ) ) maxTrack++;
|
{
|
||||||
|
if( !COM_StringEmpty( clgame.cdtracks[i] ) )
|
||||||
|
maxTrack++;
|
||||||
|
}
|
||||||
|
|
||||||
Con_Printf( "%u tracks\n", maxTrack );
|
Con_Printf( "%u tracks\n", maxTrack );
|
||||||
if( track )
|
if( track )
|
||||||
|
|||||||
@@ -16,10 +16,8 @@ GNU General Public License for more details.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "net_encode.h"
|
#include "net_encode.h"
|
||||||
#include "particledef.h"
|
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "shake.h"
|
#include "shake.h"
|
||||||
#include "hltv.h"
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#define MSG_COUNT 32 // last 32 messages parsed
|
#define MSG_COUNT 32 // last 32 messages parsed
|
||||||
@@ -57,9 +55,6 @@ const char *CL_MsgInfo( int cmd )
|
|||||||
case PROTO_CURRENT:
|
case PROTO_CURRENT:
|
||||||
svc_string = svc_strings[cmd];
|
svc_string = svc_strings[cmd];
|
||||||
break;
|
break;
|
||||||
case PROTO_LEGACY:
|
|
||||||
svc_string = svc_legacy_strings[cmd];
|
|
||||||
break;
|
|
||||||
case PROTO_QUAKE:
|
case PROTO_QUAKE:
|
||||||
svc_string = svc_quake_strings[cmd];
|
svc_string = svc_quake_strings[cmd];
|
||||||
break;
|
break;
|
||||||
@@ -149,7 +144,11 @@ static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
|||||||
file_t *fp;
|
file_t *fp;
|
||||||
|
|
||||||
fp = FS_Open( buffer_file, "wb", false );
|
fp = FS_Open( buffer_file, "wb", false );
|
||||||
if( !fp ) return;
|
if( !fp )
|
||||||
|
{
|
||||||
|
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, buffer_file );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
||||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||||
|
|||||||
@@ -117,8 +117,6 @@ static int CL_GetDemoNetProtocol( connprotocol_t proto )
|
|||||||
{
|
{
|
||||||
case PROTO_CURRENT:
|
case PROTO_CURRENT:
|
||||||
return PROTOCOL_VERSION;
|
return PROTOCOL_VERSION;
|
||||||
case PROTO_LEGACY:
|
|
||||||
return PROTOCOL_LEGACY_VERSION;
|
|
||||||
case PROTO_QUAKE:
|
case PROTO_QUAKE:
|
||||||
return PROTOCOL_VERSION_QUAKE;
|
return PROTOCOL_VERSION_QUAKE;
|
||||||
case PROTO_GOLDSRC:
|
case PROTO_GOLDSRC:
|
||||||
@@ -134,8 +132,6 @@ static connprotocol_t CL_GetProtocolFromDemo( int net_protocol )
|
|||||||
{
|
{
|
||||||
case PROTOCOL_VERSION:
|
case PROTOCOL_VERSION:
|
||||||
return PROTO_CURRENT;
|
return PROTO_CURRENT;
|
||||||
case PROTOCOL_LEGACY_VERSION:
|
|
||||||
return PROTO_LEGACY;
|
|
||||||
case PROTOCOL_VERSION_QUAKE:
|
case PROTOCOL_VERSION_QUAKE:
|
||||||
return PROTO_QUAKE;
|
return PROTO_QUAKE;
|
||||||
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
||||||
@@ -1217,7 +1213,7 @@ void CL_StopPlayback( void )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// let game known about demo state
|
// let game known about demo state
|
||||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
Cvar_DirectFullSet( &cl_background, "0", FCVAR_READ_ONLY );
|
||||||
cls.state = ca_disconnected;
|
cls.state = ca_disconnected;
|
||||||
memset( &cls.serveradr, 0, sizeof( cls.serveradr ) );
|
memset( &cls.serveradr, 0, sizeof( cls.serveradr ) );
|
||||||
cls.set_lastdemo = false;
|
cls.set_lastdemo = false;
|
||||||
@@ -1264,8 +1260,7 @@ int GAME_EXPORT CL_GetDemoComment( const char *demoname, char *comment )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(( demohdr.net_protocol != PROTOCOL_VERSION &&
|
if( demohdr.net_protocol != PROTOCOL_VERSION ||
|
||||||
demohdr.net_protocol != PROTOCOL_LEGACY_VERSION ) ||
|
|
||||||
demohdr.dem_protocol != DEMO_PROTOCOL )
|
demohdr.dem_protocol != DEMO_PROTOCOL )
|
||||||
{
|
{
|
||||||
FS_Close( demfile );
|
FS_Close( demfile );
|
||||||
@@ -1480,10 +1475,10 @@ static qboolean CL_ParseDemoHeader( const char *callee, const char *filename, fi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_LEGACY_VERSION && hdr->net_protocol != PROTOCOL_GOLDSRC_VERSION_DEMO )
|
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_GOLDSRC_VERSION_DEMO )
|
||||||
{
|
{
|
||||||
Con_Printf( S_ERROR "%s: net protocol outdated (%i should be %i or %i)\n",
|
Con_Printf( S_ERROR "%s: net protocol outdated (%i should be %i or %i)\n",
|
||||||
callee, hdr->net_protocol, PROTOCOL_VERSION, PROTOCOL_LEGACY_VERSION );
|
callee, hdr->net_protocol, PROTOCOL_VERSION, PROTOCOL_GOLDSRC_VERSION );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -200,15 +200,15 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
|
|||||||
p->type = pt_static;
|
p->type = pt_static;
|
||||||
VectorClear( p->vel );
|
VectorClear( p->vel );
|
||||||
VectorClear( p->org );
|
VectorClear( p->org );
|
||||||
p->packedColor = 0;
|
p->unused = 0;
|
||||||
p->die = cl.time;
|
p->die = cl.time;
|
||||||
p->color = 0;
|
p->color = 0;
|
||||||
p->ramp = 0;
|
p->ramp = 0;
|
||||||
|
|
||||||
if( callback )
|
if( callback )
|
||||||
{
|
{
|
||||||
p->type = pt_clientcustom;
|
p->type = pt_custom;
|
||||||
p->callback = callback;
|
p->think = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@@ -254,7 +254,7 @@ static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life
|
|||||||
p->die = cl.time + life;
|
p->die = cl.time + life;
|
||||||
p->ramp = tracerlength.value;
|
p->ramp = tracerlength.value;
|
||||||
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
||||||
p->packedColor = 255; // alpha
|
p->unused = 255; // alpha
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -1118,7 +1118,7 @@ void GAME_EXPORT R_ParticleExplosion2( const vec3_t org, int colorStart, int col
|
|||||||
|
|
||||||
p->die = cl.time + 0.3f;
|
p->die = cl.time + 0.3f;
|
||||||
p->color = colorStart + ( colorMod % colorLength );
|
p->color = colorStart + ( colorMod % colorLength );
|
||||||
p->packedColor = packedColor;
|
p->unused = packedColor;
|
||||||
colorMod++;
|
colorMod++;
|
||||||
|
|
||||||
p->type = pt_blob;
|
p->type = pt_blob;
|
||||||
@@ -1150,7 +1150,7 @@ void GAME_EXPORT R_BlobExplosion( const vec3_t org )
|
|||||||
if( !p ) return;
|
if( !p ) return;
|
||||||
|
|
||||||
p->die = cl.time + COM_RandomFloat( 1.0f, 1.4f );
|
p->die = cl.time + COM_RandomFloat( 1.0f, 1.4f );
|
||||||
p->packedColor = packedColor;
|
p->unused = packedColor;
|
||||||
|
|
||||||
if( i & 1 )
|
if( i & 1 )
|
||||||
{
|
{
|
||||||
@@ -1232,7 +1232,7 @@ void GAME_EXPORT R_Blood( const vec3_t org, const vec3_t ndir, int pcolor, int s
|
|||||||
|
|
||||||
p->die = cl.time + 1.5f;
|
p->die = cl.time + 1.5f;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||||
p->type = pt_vox_grav;
|
p->type = pt_8x_slowgrav;
|
||||||
|
|
||||||
VectorAddScalar( pos, COM_RandomFloat( -1.0f, 1.0f ), p->org );
|
VectorAddScalar( pos, COM_RandomFloat( -1.0f, 1.0f ), p->org );
|
||||||
VectorScale( vec, pspeed, p->vel );
|
VectorScale( vec, pspeed, p->vel );
|
||||||
@@ -1263,7 +1263,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor,
|
|||||||
if( !p ) return;
|
if( !p ) return;
|
||||||
|
|
||||||
p->die = cl.time + 2.0f;
|
p->die = cl.time + 2.0f;
|
||||||
p->type = pt_vox_grav;
|
p->type = pt_8x_slowgrav;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||||
|
|
||||||
VectorCopy( org, p->org );
|
VectorCopy( org, p->org );
|
||||||
@@ -1284,7 +1284,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor,
|
|||||||
|
|
||||||
p->die = cl.time + 3.0f;
|
p->die = cl.time + 3.0f;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||||
p->type = pt_vox_slowgrav;
|
p->type = pt_4x_slowgrav;
|
||||||
|
|
||||||
VectorCopy( org, p->org );
|
VectorCopy( org, p->org );
|
||||||
VectorCopy( dir, p->vel );
|
VectorCopy( dir, p->vel );
|
||||||
@@ -1306,7 +1306,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor,
|
|||||||
|
|
||||||
p->die = cl.time + 3.0f;
|
p->die = cl.time + 3.0f;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||||
p->type = pt_vox_slowgrav;
|
p->type = pt_4x_slowgrav;
|
||||||
|
|
||||||
p->org[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f );
|
p->org[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f );
|
||||||
p->org[1] = org[1] + COM_RandomFloat( -1.0f, 1.0f );
|
p->org[1] = org[1] + COM_RandomFloat( -1.0f, 1.0f );
|
||||||
@@ -1898,8 +1898,8 @@ void GAME_EXPORT R_UserTracerParticle( float *org, float *vel, float life, int c
|
|||||||
|
|
||||||
if(( p = R_AllocTracer( org, vel, life )) != NULL )
|
if(( p = R_AllocTracer( org, vel, life )) != NULL )
|
||||||
{
|
{
|
||||||
p->context = deathcontext;
|
p->userdata = deathcontext;
|
||||||
p->deathfunc = deathfunc;
|
p->on_die = deathfunc;
|
||||||
p->color = colorIndex;
|
p->color = colorIndex;
|
||||||
p->ramp = length;
|
p->ramp = length;
|
||||||
}
|
}
|
||||||
@@ -1996,9 +1996,9 @@ void R_FreeDeadParticles( particle_t **ppparticles )
|
|||||||
kill = *ppparticles;
|
kill = *ppparticles;
|
||||||
if( kill && kill->die < cl.time )
|
if( kill && kill->die < cl.time )
|
||||||
{
|
{
|
||||||
if( kill->deathfunc )
|
if( kill->on_die )
|
||||||
kill->deathfunc( kill );
|
kill->on_die( kill );
|
||||||
kill->deathfunc = NULL;
|
kill->on_die = NULL;
|
||||||
*ppparticles = kill->next;
|
*ppparticles = kill->next;
|
||||||
kill->next = cl_free_particles;
|
kill->next = cl_free_particles;
|
||||||
cl_free_particles = kill;
|
cl_free_particles = kill;
|
||||||
@@ -2015,9 +2015,9 @@ void R_FreeDeadParticles( particle_t **ppparticles )
|
|||||||
kill = p->next;
|
kill = p->next;
|
||||||
if( kill && kill->die < cl.time )
|
if( kill && kill->die < cl.time )
|
||||||
{
|
{
|
||||||
if( kill->deathfunc )
|
if( kill->on_die )
|
||||||
kill->deathfunc( kill );
|
kill->on_die( kill );
|
||||||
kill->deathfunc = NULL;
|
kill->on_die = NULL;
|
||||||
p->next = kill->next;
|
p->next = kill->next;
|
||||||
kill->next = cl_free_particles;
|
kill->next = cl_free_particles;
|
||||||
cl_free_particles = kill;
|
cl_free_particles = kill;
|
||||||
@@ -2154,7 +2154,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
float grav = frametime * clgame.movevars.gravity * 0.05f;
|
float grav = frametime * clgame.movevars.gravity * 0.05f;
|
||||||
|
|
||||||
|
|
||||||
if( p->type != pt_clientcustom )
|
if( p->type != pt_custom )
|
||||||
{
|
{
|
||||||
// update position.
|
// update position.
|
||||||
VectorMA( p->org, frametime, p->vel, p->org );
|
VectorMA( p->org, frametime, p->vel, p->org );
|
||||||
@@ -2185,7 +2185,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
p->vel[2] -= grav;
|
p->vel[2] -= grav;
|
||||||
break;
|
break;
|
||||||
case pt_blob:
|
case pt_blob:
|
||||||
if( p->packedColor == 255 )
|
if( p->unused == 255 )
|
||||||
{
|
{
|
||||||
// normal blob explosion
|
// normal blob explosion
|
||||||
VectorMA( p->vel, dvel, p->vel, p->vel );
|
VectorMA( p->vel, dvel, p->vel, p->vel );
|
||||||
@@ -2194,7 +2194,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
}
|
}
|
||||||
// intentionally fallthrough
|
// intentionally fallthrough
|
||||||
case pt_blob2:
|
case pt_blob2:
|
||||||
if( p->packedColor == 255 )
|
if( p->unused == 255 )
|
||||||
{
|
{
|
||||||
// normal blob explosion
|
// normal blob explosion
|
||||||
p->vel[0] -= p->vel[0] * dvel;
|
p->vel[0] -= p->vel[0] * dvel;
|
||||||
@@ -2217,15 +2217,15 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
case pt_slowgrav:
|
case pt_slowgrav:
|
||||||
p->vel[2] -= grav;
|
p->vel[2] -= grav;
|
||||||
break;
|
break;
|
||||||
case pt_vox_grav:
|
case pt_8x_slowgrav:
|
||||||
p->vel[2] -= grav * 8.0f;
|
p->vel[2] -= grav * 8.0f;
|
||||||
break;
|
break;
|
||||||
case pt_vox_slowgrav:
|
case pt_4x_slowgrav:
|
||||||
p->vel[2] -= grav * 4.0f;
|
p->vel[2] -= grav * 4.0f;
|
||||||
break;
|
break;
|
||||||
case pt_clientcustom:
|
case pt_custom:
|
||||||
if( p->callback )
|
if( p->think )
|
||||||
p->callback( p, frametime );
|
p->think( p, frametime );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ word CL_EventIndex( const char *name )
|
|||||||
{
|
{
|
||||||
word i;
|
word i;
|
||||||
|
|
||||||
if( !COM_CheckString( name ))
|
if( COM_StringEmptyOrNULL( name ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for( i = 1; i < MAX_EVENTS && cl.event_precache[i][0]; i++ )
|
for( i = 1; i < MAX_EVENTS && cl.event_precache[i][0]; i++ )
|
||||||
@@ -436,9 +436,8 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
|||||||
|
|
||||||
if( proto == PROTO_GOLDSRC )
|
if( proto == PROTO_GOLDSRC )
|
||||||
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
||||||
else if( proto == PROTO_LEGACY )
|
else
|
||||||
entity_bits = MAX_LEGACY_ENTITY_BITS;
|
entity_bits = MAX_ENTITY_BITS;
|
||||||
else entity_bits = MAX_ENTITY_BITS;
|
|
||||||
|
|
||||||
// parse events queue
|
// parse events queue
|
||||||
for( i = 0 ; i < num_events; i++ )
|
for( i = 0 ; i < num_events; i++ )
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ void CL_SetFontRendermode( cl_font_t *font )
|
|||||||
ref.dllFuncs.GL_SetRenderMode( CL_FontRenderMode( font->rendermode ));
|
ref.dllFuncs.GL_SetRenderMode( CL_FontRenderMode( font->rendermode ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CL_SetFontColor( cl_font_t *font, const rgba_t color )
|
||||||
|
{
|
||||||
|
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
||||||
|
}
|
||||||
|
|
||||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
|
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
|
||||||
{
|
{
|
||||||
int font_width, i;
|
int font_width, i;
|
||||||
@@ -163,7 +168,7 @@ void CL_FreeFont( cl_font_t *font )
|
|||||||
|
|
||||||
static int CL_CalcTabStop( const cl_font_t *font, int x )
|
static int CL_CalcTabStop( const cl_font_t *font, int x )
|
||||||
{
|
{
|
||||||
int space = font->charWidths[' '];
|
int space = font->charWidths['0'];
|
||||||
int tab = space * 6; // 6 spaces
|
int tab = space * 6; // 6 spaces
|
||||||
int stop = tab - x % tab;
|
int stop = tab - x % tab;
|
||||||
|
|
||||||
@@ -222,10 +227,9 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
|
|||||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||||
CL_SetFontRendermode( font );
|
CL_SetFontRendermode( font );
|
||||||
|
|
||||||
// don't apply color to fixed fonts it's already colored
|
if( !FBitSet( flags, FONT_DRAW_NOCOLOR ))
|
||||||
if( font->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, font->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
|
CL_SetFontColor( font, color );
|
||||||
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
|
||||||
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
|
|
||||||
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
|
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
|
||||||
|
|
||||||
return font->charWidths[number];
|
return font->charWidths[number];
|
||||||
@@ -233,7 +237,6 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
|
|||||||
|
|
||||||
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
|
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
|
||||||
{
|
{
|
||||||
rgba_t current_color;
|
|
||||||
int draw_len = 0;
|
int draw_len = 0;
|
||||||
|
|
||||||
if( !font || !font->valid )
|
if( !font || !font->valid )
|
||||||
@@ -245,7 +248,9 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
|||||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||||
CL_SetFontRendermode( font );
|
CL_SetFontRendermode( font );
|
||||||
|
|
||||||
Vector4Copy( color, current_color );
|
CL_SetFontColor( font, color );
|
||||||
|
|
||||||
|
SetBits( flags, FONT_DRAW_NOCOLOR | FONT_DRAW_NORENDERMODE );
|
||||||
|
|
||||||
while( *s )
|
while( *s )
|
||||||
{
|
{
|
||||||
@@ -264,7 +269,7 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
|
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
|
||||||
Vector4Copy( color, current_color );
|
CL_SetFontColor( font, color );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,14 +277,14 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
|||||||
{
|
{
|
||||||
// don't copy alpha
|
// don't copy alpha
|
||||||
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
|
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
|
||||||
VectorCopy( g_color_table[ColorIndex(*( s + 1 ))], current_color );
|
CL_SetFontColor( font, g_color_table[ColorIndex(*( s + 1 ))] );
|
||||||
|
|
||||||
s += 2;
|
s += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip setting rendermode, it was changed for this string already
|
// skip setting rendermode, it was changed for this string already
|
||||||
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, current_color, font, flags | FONT_DRAW_NORENDERMODE );
|
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, NULL, font, flags );
|
||||||
|
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
@@ -324,7 +329,7 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,
|
|||||||
if( width )
|
if( width )
|
||||||
*width = 0;
|
*width = 0;
|
||||||
|
|
||||||
if( !COM_CheckString( s ))
|
if( COM_StringEmptyOrNULL( s ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ GNU General Public License for more details.
|
|||||||
#include "pm_local.h"
|
#include "pm_local.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "studio.h"
|
#include "studio.h"
|
||||||
#include "dlight.h"
|
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
@@ -157,13 +156,6 @@ static qboolean CL_EntityCustomLerp( cl_entity_t *e )
|
|||||||
case MOVETYPE_FLY:
|
case MOVETYPE_FLY:
|
||||||
case MOVETYPE_COMPOUND:
|
case MOVETYPE_COMPOUND:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
|
|
||||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
|
||||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
|
||||||
case MOVETYPE_TOSS:
|
|
||||||
if( cls.legacymode == PROTO_LEGACY && e->model && e->model->type == mod_studio )
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -318,6 +310,21 @@ static void CL_ProcessEntityUpdate( cl_entity_t *ent )
|
|||||||
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
||||||
COM_NormalizeAngles( ent->curstate.angles );
|
COM_NormalizeAngles( ent->curstate.angles );
|
||||||
|
|
||||||
|
// a1ba: follow entities are sent with null origin, grab their aiment origin here
|
||||||
|
//
|
||||||
|
// null origin leads to triggered entity teleport check and subsequent reset of position history
|
||||||
|
// and empty position history doesn't allow entity to render correctly
|
||||||
|
//
|
||||||
|
// it's probably should be done somewhere else, as goldsrc doesn't do this here
|
||||||
|
// it has MoveAiments function but it's called after LinkPacketEntities :shrug:
|
||||||
|
if( ent->curstate.movetype == MOVETYPE_FOLLOW && VectorIsNull( ent->curstate.origin ) && ent->curstate.aiment )
|
||||||
|
{
|
||||||
|
cl_entity_t *aiment = CL_GetEntityByIndex( ent->curstate.aiment );
|
||||||
|
|
||||||
|
if( aiment )
|
||||||
|
VectorCopy( aiment->origin, ent->curstate.origin );
|
||||||
|
}
|
||||||
|
|
||||||
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
|
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
|
||||||
|
|
||||||
// allow interpolation on bmodels too
|
// allow interpolation on bmodels too
|
||||||
@@ -653,18 +660,9 @@ FRAME PARSING
|
|||||||
*/
|
*/
|
||||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
||||||
{
|
{
|
||||||
if( proto == PROTO_LEGACY )
|
*newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||||
{
|
if( *newnum == LAST_EDICT )
|
||||||
*newnum = MSG_ReadWord( msg );
|
return false;
|
||||||
if( *newnum == 0 )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
|
||||||
if( *newnum == LAST_EDICT )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -831,9 +829,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
|||||||
CL_WriteDemoJumpTime();
|
CL_WriteDemoJumpTime();
|
||||||
|
|
||||||
// sentinel count. save it for debug checking
|
// sentinel count. save it for debug checking
|
||||||
if( proto == PROTO_LEGACY )
|
count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
||||||
count = MSG_ReadWord( msg );
|
|
||||||
else count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
|
||||||
|
|
||||||
newframe = &cl.frames[cl.parsecountmod];
|
newframe = &cl.frames[cl.parsecountmod];
|
||||||
|
|
||||||
@@ -985,15 +981,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
|||||||
if( !draw_player )
|
if( !draw_player )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( entityType == ET_BEAM )
|
if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
|
||||||
{
|
|
||||||
ref.dllFuncs.CL_AddCustomBeam( ent );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// because pTemp->entity.curstate.effects
|
// because pTemp->entity.curstate.effects
|
||||||
// is already occupied by FTENT_FLICKER
|
// is already occupied by FTENT_FLICKER
|
||||||
@@ -1246,16 +1235,6 @@ static void CL_LinkPacketEntities( frame_t *frame )
|
|||||||
if( !CL_InterpolateModel( ent ))
|
if( !CL_InterpolateModel( ent ))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
|
|
||||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
|
||||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
|
||||||
else if( cls.legacymode == PROTO_LEGACY && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
|
|
||||||
{
|
|
||||||
if( !CL_InterpolateModel( ent ))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no interpolation right now
|
// no interpolation right now
|
||||||
@@ -1395,7 +1374,7 @@ qboolean CL_GetEntitySpatialization( channel_t *ch )
|
|||||||
|
|
||||||
if( ch->entnum == 0 )
|
if( ch->entnum == 0 )
|
||||||
{
|
{
|
||||||
ch->staticsound = true;
|
SetBits( ch->flags, FL_CHAN_STATIC_SOUND );
|
||||||
return true; // static sound
|
return true; // static sound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,20 @@ GNU General Public License for more details.
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
#define MAX_LINELENGTH 80
|
#define MAX_LINELENGTH 80
|
||||||
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
|
#define TEXT_MSGNAME "TextMessage"
|
||||||
#define TEXT_MSGNAME "TextMessage%i"
|
|
||||||
|
|
||||||
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||||
static client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS] =
|
||||||
|
{
|
||||||
|
{ .pName = "TextMessage0", .pMessage = cl_textbuffer[0] },
|
||||||
|
{ .pName = "TextMessage1", .pMessage = cl_textbuffer[1] },
|
||||||
|
{ .pName = "TextMessage2", .pMessage = cl_textbuffer[2] },
|
||||||
|
{ .pName = "TextMessage3", .pMessage = cl_textbuffer[3] },
|
||||||
|
{ .pName = "TextMessage4", .pMessage = cl_textbuffer[4] },
|
||||||
|
{ .pName = "TextMessage5", .pMessage = cl_textbuffer[5] },
|
||||||
|
{ .pName = "TextMessage6", .pMessage = cl_textbuffer[6] },
|
||||||
|
{ .pName = "TextMessage7", .pMessage = cl_textbuffer[7] },
|
||||||
|
};
|
||||||
|
|
||||||
static const dllfunc_t cdll_exports[] =
|
static const dllfunc_t cdll_exports[] =
|
||||||
{
|
{
|
||||||
@@ -96,6 +105,8 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
|
|||||||
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
||||||
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
||||||
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
||||||
|
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D FWGS ext
|
||||||
|
{ "Voice_StartChannel", (void **)&clgame.dllFuncs.pfnVoice_StartChannel }, // Xash3D FWGS ext
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
||||||
@@ -112,7 +123,11 @@ static void CL_CreatePlaylist( const char *filename )
|
|||||||
file_t *f;
|
file_t *f;
|
||||||
|
|
||||||
f = FS_Open( filename, "w", false );
|
f = FS_Open( filename, "w", false );
|
||||||
if( !f ) return;
|
if( !f )
|
||||||
|
{
|
||||||
|
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, filename );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// make standard cdaudio playlist
|
// make standard cdaudio playlist
|
||||||
FS_Print( f, "blank\n" ); // #1
|
FS_Print( f, "blank\n" ); // #1
|
||||||
@@ -175,7 +190,13 @@ static void CL_InitCDAudio( const char *filename )
|
|||||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||||
{
|
{
|
||||||
if( !Q_stricmp( token, "blank" ))
|
if( !Q_stricmp( token, "blank" ))
|
||||||
|
{
|
||||||
clgame.cdtracks[c][0] = '\0';
|
clgame.cdtracks[c][0] = '\0';
|
||||||
|
}
|
||||||
|
else if( token[0] == '/' ) // allow custom path
|
||||||
|
{
|
||||||
|
Q_strncpy( clgame.cdtracks[c], &token[1], sizeof( clgame.cdtracks[c] ));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Q_snprintf( clgame.cdtracks[c], sizeof( clgame.cdtracks[c] ),
|
Q_snprintf( clgame.cdtracks[c], sizeof( clgame.cdtracks[c] ),
|
||||||
@@ -266,7 +287,7 @@ void CL_CenterPrint( const char *text, float y )
|
|||||||
{
|
{
|
||||||
cl_font_t *font = Con_GetCurFont();
|
cl_font_t *font = Con_GetCurFont();
|
||||||
|
|
||||||
if( !COM_CheckString( text ) || !font || !font->valid )
|
if( COM_StringEmptyOrNULL( text ) || !font || !font->valid )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clgame.centerPrint.totalWidth = 0;
|
clgame.centerPrint.totalWidth = 0;
|
||||||
@@ -353,13 +374,13 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
|
|||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
// assume we get sizes from image
|
// assume we get sizes from image
|
||||||
ref.dllFuncs.R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
|
R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
|
||||||
|
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame );
|
texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame );
|
||||||
|
|
||||||
if( prc )
|
if( prc )
|
||||||
{
|
{
|
||||||
@@ -429,6 +450,7 @@ void CL_DrawCenterPrint( void )
|
|||||||
|
|
||||||
CL_DrawCharacterLen( font, 0, NULL, &charHeight );
|
CL_DrawCharacterLen( font, 0, NULL, &charHeight );
|
||||||
CL_SetFontRendermode( font );
|
CL_SetFontRendermode( font );
|
||||||
|
CL_SetFontColor( font, colorDefault );
|
||||||
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
||||||
{
|
{
|
||||||
lineLength = 0;
|
lineLength = 0;
|
||||||
@@ -458,7 +480,7 @@ void CL_DrawCenterPrint( void )
|
|||||||
for( j = 0; j < lineLength; j++ )
|
for( j = 0; j < lineLength; j++ )
|
||||||
{
|
{
|
||||||
if( x >= 0 && y >= 0 && x <= refState.width )
|
if( x >= 0 && y >= 0 && x <= refState.width )
|
||||||
x += CL_DrawCharacter( x, y, line[j], colorDefault, font, FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE );
|
x += CL_DrawCharacter( x, y, line[j], NULL, font, FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE | FONT_DRAW_NOCOLOR );
|
||||||
}
|
}
|
||||||
y += charHeight;
|
y += charHeight;
|
||||||
}
|
}
|
||||||
@@ -555,31 +577,18 @@ and hold them into permament memory pool
|
|||||||
*/
|
*/
|
||||||
static void CL_InitTitles( const char *filename )
|
static void CL_InitTitles( const char *filename )
|
||||||
{
|
{
|
||||||
fs_offset_t fileSize;
|
|
||||||
byte *pMemFile;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// initialize text messages (game_text)
|
|
||||||
for( i = 0; i < MAX_TEXTCHANNELS; i++ )
|
|
||||||
{
|
|
||||||
char name[MAX_VA_STRING];
|
|
||||||
|
|
||||||
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
|
||||||
|
|
||||||
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
|
|
||||||
cl_textmessage[i].pMessage = cl_textbuffer[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear out any old data that's sitting around.
|
// clear out any old data that's sitting around.
|
||||||
if( clgame.titles ) Mem_Free( clgame.titles );
|
Mem_Free( clgame.titles );
|
||||||
|
|
||||||
clgame.titles = NULL;
|
clgame.titles = NULL;
|
||||||
clgame.numTitles = 0;
|
clgame.numTitles = 0;
|
||||||
|
|
||||||
pMemFile = FS_LoadFile( filename, &fileSize, false );
|
fs_offset_t fileSize = 0;
|
||||||
if( !pMemFile ) return;
|
char *pMemFile = (char *)FS_LoadFile( filename, &fileSize, false );
|
||||||
|
if( !pMemFile )
|
||||||
|
return;
|
||||||
|
|
||||||
CL_TextMessageParse( pMemFile, fileSize );
|
clgame.titles = CL_TextMessageParse( clgame.mempool, pMemFile, fileSize, &clgame.numTitles );
|
||||||
Mem_Free( pMemFile );
|
Mem_Free( pMemFile );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,8 +601,10 @@ Template to show hud messages
|
|||||||
*/
|
*/
|
||||||
void CL_HudMessage( const char *pMessage )
|
void CL_HudMessage( const char *pMessage )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( pMessage )) return;
|
if( COM_StringEmptyOrNULL( pMessage ))
|
||||||
CL_DispatchUserMessage( "HudText", Q_strlen( pMessage ), (void *)pMessage );
|
return;
|
||||||
|
|
||||||
|
CL_DispatchUserMessage( "HudText", Q_strlen( pMessage ) + 1, (void *)pMessage );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -646,54 +657,6 @@ void CL_ParseTextMessage( sizebuf_t *msg )
|
|||||||
CL_HudMessage( text->pName );
|
CL_HudMessage( text->pName );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
CL_ParseFinaleCutscene
|
|
||||||
|
|
||||||
show display finale or cutscene message
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level )
|
|
||||||
{
|
|
||||||
static int msgindex = 0;
|
|
||||||
client_textmessage_t *text;
|
|
||||||
int channel;
|
|
||||||
|
|
||||||
cl.intermission = level;
|
|
||||||
|
|
||||||
channel = msgindex;
|
|
||||||
msgindex = (msgindex + 1) & (MAX_TEXTCHANNELS - 1);
|
|
||||||
|
|
||||||
// grab message channel
|
|
||||||
text = &cl_textmessage[channel];
|
|
||||||
|
|
||||||
// NOTE: svc_finale and svc_cutscene has a
|
|
||||||
// predefined settings like Quake-style
|
|
||||||
text->x = -1.0f;
|
|
||||||
text->y = 0.15f;
|
|
||||||
text->effect = 2; // scan out effect
|
|
||||||
text->r1 = 245;
|
|
||||||
text->g1 = 245;
|
|
||||||
text->b1 = 245;
|
|
||||||
text->a1 = 0; // unused
|
|
||||||
text->r2 = 0;
|
|
||||||
text->g2 = 0;
|
|
||||||
text->b2 = 0;
|
|
||||||
text->a2 = 0;
|
|
||||||
text->fadein = 0.15f;
|
|
||||||
text->fadeout = 0.0f;
|
|
||||||
text->holdtime = 99999.0f;
|
|
||||||
text->fxtime = 0.0f;
|
|
||||||
|
|
||||||
// to prevent grab too long messages
|
|
||||||
Q_strncpy( (char *)text->pMessage, MSG_ReadString( msg ), 2048 );
|
|
||||||
|
|
||||||
if( *text->pMessage == '\0' )
|
|
||||||
return; // no real text
|
|
||||||
|
|
||||||
CL_HudMessage( text->pName );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
====================
|
====================
|
||||||
CL_GetMaxlients
|
CL_GetMaxlients
|
||||||
@@ -1110,7 +1073,12 @@ void CL_ClearSpriteTextures( void )
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for( i = 1; i < MAX_CLIENT_SPRITES; i++ )
|
for( i = 1; i < MAX_CLIENT_SPRITES; i++ )
|
||||||
clgame.sprites[i].needload = NL_UNREFERENCED;
|
{
|
||||||
|
if( clgame.sprites[i].needload == NL_UNREFERENCED )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
clgame.sprites[i].needload = NL_FREE_UNUSED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// it's a Valve default value for LoadMapSprite (probably must be power of two)
|
// it's a Valve default value for LoadMapSprite (probably must be power of two)
|
||||||
@@ -1281,8 +1249,8 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
|
|||||||
Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Mod_LoadSpriteModel( m_pSprite, buf, &loaded );
|
Mod_LoadSpriteModel( m_pSprite, buf, size, &loaded );
|
||||||
ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf );
|
ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
Mem_Free( buf );
|
Mem_Free( buf );
|
||||||
@@ -1312,7 +1280,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
|||||||
model_t *mod;
|
model_t *mod;
|
||||||
int i, start;
|
int i, start;
|
||||||
|
|
||||||
if( !COM_CheckString( filename ))
|
if( COM_StringEmptyOrNULL( filename ))
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "%s: bad name!\n", __func__ );
|
Con_Reportf( S_ERROR "%s: bad name!\n", __func__ );
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1344,7 +1312,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
|||||||
|
|
||||||
for( i = 0, mod = &clgame.sprites[start]; i < MAX_CLIENT_SPRITES / 2; i++, mod++ )
|
for( i = 0, mod = &clgame.sprites[start]; i < MAX_CLIENT_SPRITES / 2; i++, mod++ )
|
||||||
{
|
{
|
||||||
if( !mod->name[0] )
|
if( mod->needload == NL_UNREFERENCED )
|
||||||
break; // this is a valid spot
|
break; // this is a valid spot
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1456,7 +1424,7 @@ int EXPORT pfnSPR_Frames( HSPRITE hPic )
|
|||||||
{
|
{
|
||||||
int numFrames = 0;
|
int numFrames = 0;
|
||||||
|
|
||||||
ref.dllFuncs.R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
|
R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
|
||||||
|
|
||||||
return numFrames;
|
return numFrames;
|
||||||
}
|
}
|
||||||
@@ -1471,7 +1439,7 @@ static int GAME_EXPORT pfnSPR_Height( HSPRITE hPic, int frame )
|
|||||||
{
|
{
|
||||||
int sprHeight = 0;
|
int sprHeight = 0;
|
||||||
|
|
||||||
ref.dllFuncs.R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
|
R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||||
|
|
||||||
return sprHeight;
|
return sprHeight;
|
||||||
}
|
}
|
||||||
@@ -1486,7 +1454,7 @@ static int GAME_EXPORT pfnSPR_Width( HSPRITE hPic, int frame )
|
|||||||
{
|
{
|
||||||
int sprWidth = 0;
|
int sprWidth = 0;
|
||||||
|
|
||||||
ref.dllFuncs.R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
|
R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||||
|
|
||||||
return sprWidth;
|
return sprWidth;
|
||||||
}
|
}
|
||||||
@@ -1831,7 +1799,7 @@ pfnServerCmd
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnServerCmd( const char *szCmdString )
|
static int GAME_EXPORT pfnServerCmd( const char *szCmdString )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( szCmdString ))
|
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// just like the client typed "cmd xxxxx" at the console
|
// just like the client typed "cmd xxxxx" at the console
|
||||||
@@ -1849,7 +1817,7 @@ pfnClientCmd
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
|
static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( szCmdString ))
|
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( cls.initialized )
|
if( cls.initialized )
|
||||||
@@ -1874,7 +1842,7 @@ pfnFilteredClientCmd
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( szCmdString ))
|
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// a1ba:
|
// a1ba:
|
||||||
@@ -1962,13 +1930,12 @@ client_textmessage_t *CL_TextMessageGet( const char *pName )
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
// first check internal messages
|
// first check internal messages
|
||||||
for( i = 0; i < MAX_TEXTCHANNELS; i++ )
|
if( Q_strlen( pName ) == sizeof( TEXT_MSGNAME ) // including the digit
|
||||||
|
&& !Q_strncmp( pName, TEXT_MSGNAME, sizeof( TEXT_MSGNAME ) - 1 ))
|
||||||
{
|
{
|
||||||
char name[MAX_VA_STRING];
|
i = pName[sizeof( TEXT_MSGNAME ) - 1] - '0';
|
||||||
|
|
||||||
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
if( i >= 0 && i < MAX_TEXTCHANNELS )
|
||||||
|
|
||||||
if( !Q_strcmp( pName, name ))
|
|
||||||
return cl_textmessage + i;
|
return cl_textmessage + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2056,7 +2023,7 @@ prints directly into console (can skip notify)
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT pfnConsolePrint( const char *string )
|
static void GAME_EXPORT pfnConsolePrint( const char *string )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( string ))
|
if( COM_StringEmptyOrNULL( string ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// WON GoldSrc behavior
|
// WON GoldSrc behavior
|
||||||
@@ -2428,7 +2395,7 @@ static int GAME_EXPORT CL_FindModelIndex( const char *m )
|
|||||||
char filepath[MAX_QPATH];
|
char filepath[MAX_QPATH];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( !COM_CheckString( m ))
|
if( COM_StringEmptyOrNULL( m ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Q_strncpy( filepath, m, sizeof( filepath ));
|
Q_strncpy( filepath, m, sizeof( filepath ));
|
||||||
@@ -2729,7 +2696,7 @@ static const char *pfnGetLevelName( void )
|
|||||||
// a1ba: don't return maps/.bsp if no map is loaded yet
|
// a1ba: don't return maps/.bsp if no map is loaded yet
|
||||||
// in GoldSrc this is handled by cl.levelname field but we don't have it
|
// in GoldSrc this is handled by cl.levelname field but we don't have it
|
||||||
// so emulate this behavior here
|
// so emulate this behavior here
|
||||||
if( cls.state >= ca_connected && COM_CheckStringEmpty( clgame.mapname ))
|
if( cls.state >= ca_connected && !COM_StringEmpty( clgame.mapname ))
|
||||||
Q_snprintf( mapname, sizeof( mapname ), "maps/%s.bsp", clgame.mapname );
|
Q_snprintf( mapname, sizeof( mapname ), "maps/%s.bsp", clgame.mapname );
|
||||||
else mapname[0] = '\0'; // not in game
|
else mapname[0] = '\0'; // not in game
|
||||||
|
|
||||||
@@ -2800,7 +2767,7 @@ static int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBu
|
|||||||
{
|
{
|
||||||
char result[MAX_SYSPATH];
|
char result[MAX_SYSPATH];
|
||||||
|
|
||||||
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
if( COM_StringEmptyOrNULL( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// filename examples:
|
// filename examples:
|
||||||
@@ -2913,7 +2880,7 @@ pfnServerCmdUnreliable
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
|
static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( szCmdString ))
|
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
MSG_BeginClientCmd( &cls.datagram, clc_stringcmd );
|
MSG_BeginClientCmd( &cls.datagram, clc_stringcmd );
|
||||||
@@ -2930,10 +2897,15 @@ pfnGetMousePos
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
|
static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
|
||||||
{
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
if( !ppt )
|
if( !ppt )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Platform_GetMousePos( &ppt->x, &ppt->y );
|
Platform_GetMousePos( &x, &y );
|
||||||
|
|
||||||
|
ppt->x = x;
|
||||||
|
ppt->y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3202,7 +3174,8 @@ handle colon separately
|
|||||||
*/
|
*/
|
||||||
static char *pfnParseFile( char *data, char *token )
|
static char *pfnParseFile( char *data, char *token )
|
||||||
{
|
{
|
||||||
return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL );
|
// GoldSrc uses 1024 byte tokens
|
||||||
|
return COM_ParseFileSafe( data, token, 1024, PFILE_HANDLECOLON, NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3351,7 +3324,7 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
|
|||||||
{
|
{
|
||||||
int gl_texturenum;
|
int gl_texturenum;
|
||||||
|
|
||||||
if(( gl_texturenum = ref.dllFuncs.R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
|
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );
|
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );
|
||||||
@@ -3481,7 +3454,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
|||||||
nr->flags = flags;
|
nr->flags = flags;
|
||||||
|
|
||||||
// local servers request
|
// local servers request
|
||||||
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, A2A_NETINFO" %i %i %i", FBitSet( flags, FNETAPI_LEGACY_PROTOCOL ) ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION, context, request );
|
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, A2A_NETINFO" %i %i %i", PROTOCOL_VERSION, context, request );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3944,7 +3917,7 @@ void CL_UnloadProgs( void )
|
|||||||
if( GI->internal_vgui_support )
|
if( GI->internal_vgui_support )
|
||||||
VGui_Shutdown();
|
VGui_Shutdown();
|
||||||
|
|
||||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
Cvar_DirectFullSet( &cl_background, "0", FCVAR_READ_ONLY );
|
||||||
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
|
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
|
||||||
|
|
||||||
Cvar_Unlink( FCVAR_CLIENTDLL );
|
Cvar_Unlink( FCVAR_CLIENTDLL );
|
||||||
@@ -3962,6 +3935,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
CL_EXPORT_FUNCS GetClientAPI; // single export
|
CL_EXPORT_FUNCS GetClientAPI; // single export
|
||||||
qboolean valid_single_export = false;
|
qboolean valid_single_export = false;
|
||||||
qboolean missed_exports = false;
|
qboolean missed_exports = false;
|
||||||
|
qboolean try_internal_vgui_support = GI->internal_vgui_support;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( clgame.hInstance ) CL_UnloadProgs();
|
if( clgame.hInstance ) CL_UnloadProgs();
|
||||||
@@ -3982,10 +3956,10 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
// NOTE: important stuff!
|
// NOTE: important stuff!
|
||||||
// vgui must startup BEFORE loading client.dll to avoid get error ERROR_NOACESS during LoadLibrary
|
// vgui must startup BEFORE loading client.dll to avoid get error ERROR_NOACESS during LoadLibrary
|
||||||
if( !GI->internal_vgui_support && VGui_LoadProgs( NULL ))
|
if( !try_internal_vgui_support && VGui_LoadProgs( NULL ))
|
||||||
VGui_Startup( refState.width, refState.height );
|
VGui_Startup( refState.width, refState.height );
|
||||||
else
|
else
|
||||||
GI->internal_vgui_support = true; // we failed to load vgui_support, but let's probe client.dll for support anyway
|
try_internal_vgui_support = true; // we failed to load vgui_support, but let's probe client.dll for support anyway
|
||||||
|
|
||||||
clgame.hInstance = COM_LoadLibrary( name, false, false );
|
clgame.hInstance = COM_LoadLibrary( name, false, false );
|
||||||
|
|
||||||
@@ -3993,21 +3967,21 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// delayed vgui initialization for internal support
|
// delayed vgui initialization for internal support
|
||||||
if( GI->internal_vgui_support && VGui_LoadProgs( clgame.hInstance ))
|
if( try_internal_vgui_support && VGui_LoadProgs( clgame.hInstance ))
|
||||||
VGui_Startup( refState.width, refState.height );
|
VGui_Startup( refState.width, refState.height );
|
||||||
|
|
||||||
// clear exports
|
// clear exports
|
||||||
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||||
|
|
||||||
// trying to get single export
|
// trying to get single export
|
||||||
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
if(( GetClientAPI = COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||||
{
|
{
|
||||||
Con_Reportf( "%s: found single callback export\n", __func__ );
|
Con_Reportf( "%s: found single callback export\n", __func__ );
|
||||||
|
|
||||||
// trying to fill interface now
|
// trying to fill interface now
|
||||||
GetClientAPI( &clgame.dllFuncs );
|
GetClientAPI( &clgame.dllFuncs );
|
||||||
}
|
}
|
||||||
else if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
|
else if(( GetClientAPI = COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
|
||||||
{
|
{
|
||||||
Con_Reportf( "%s: found single callback export (secured client dlls)\n", __func__ );
|
Con_Reportf( "%s: found single callback export (secured client dlls)\n", __func__ );
|
||||||
|
|
||||||
@@ -4021,7 +3995,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
||||||
{
|
{
|
||||||
if( *(cdll_exports[i].func) != NULL )
|
if( *(cdll_exports[i].func) != NULL )
|
||||||
continue; // already gott through 'F' or 'GetClientAPI'
|
continue; // already got through 'F' or 'GetClientAPI'
|
||||||
|
|
||||||
// functions are cleared before all the extensions are evaluated
|
// functions are cleared before all the extensions are evaluated
|
||||||
if(( *(cdll_exports[i].func) = (void *)COM_GetProcAddress( clgame.hInstance, cdll_exports[i].name )) == NULL )
|
if(( *(cdll_exports[i].func) = (void *)COM_GetProcAddress( clgame.hInstance, cdll_exports[i].name )) == NULL )
|
||||||
@@ -4035,6 +4009,11 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
if( missed_exports )
|
if( missed_exports )
|
||||||
{
|
{
|
||||||
|
if( clgame.dllFuncs.pfnInit && clgame.dllFuncs.pfnRedraw && clgame.dllFuncs.pfnReset && clgame.dllFuncs.pfnUpdateClientData && clgame.dllFuncs.pfnVidInit && clgame.dllFuncs.pfnInitialize )
|
||||||
|
COM_PushLibraryError( "missing essential exports; outdated DLL!!!" );
|
||||||
|
else
|
||||||
|
COM_PushLibraryError( "missing essential exports" );
|
||||||
|
|
||||||
COM_FreeLibrary( clgame.hInstance );
|
COM_FreeLibrary( clgame.hInstance );
|
||||||
clgame.hInstance = NULL;
|
clgame.hInstance = NULL;
|
||||||
return false;
|
return false;
|
||||||
@@ -4057,6 +4036,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
||||||
{
|
{
|
||||||
|
COM_PushLibraryError( "can't init client API" );
|
||||||
COM_FreeLibrary( clgame.hInstance );
|
COM_FreeLibrary( clgame.hInstance );
|
||||||
Con_Reportf( "%s: can't init client API\n", __func__ );
|
Con_Reportf( "%s: can't init client API\n", __func__ );
|
||||||
clgame.hInstance = NULL;
|
clgame.hInstance = NULL;
|
||||||
@@ -4070,14 +4050,14 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
CL_InitCDAudio( "media/cdaudio.txt" );
|
CL_InitCDAudio( "media/cdaudio.txt" );
|
||||||
CL_InitTitles( "titles.txt" );
|
CL_InitTitles( "titles.txt" );
|
||||||
CL_InitParticles ();
|
CL_InitParticles( );
|
||||||
CL_InitViewBeams ();
|
CL_InitViewBeams( );
|
||||||
CL_InitTempEnts ();
|
CL_InitTempEnts( );
|
||||||
|
|
||||||
if( !R_InitRenderAPI()) // Xash3D extension
|
if( !R_InitRenderAPI( )) // Xash3D extension
|
||||||
Con_Reportf( S_WARN "%s: couldn't get render API\n", __func__ );
|
Con_Reportf( S_WARN "%s: couldn't get render API\n", __func__ );
|
||||||
|
|
||||||
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
|
if( !Mobile_Init( )) // Xash3D FWGS extension: mobile interface
|
||||||
Con_Reportf( S_WARN "%s: couldn't get mobility API\n", __func__ );
|
Con_Reportf( S_WARN "%s: couldn't get mobility API\n", __func__ );
|
||||||
|
|
||||||
CL_InitEdicts( cl.maxclients ); // initailize local player and world
|
CL_InitEdicts( cl.maxclients ); // initailize local player and world
|
||||||
|
|||||||
@@ -37,8 +37,11 @@ void UI_UpdateMenu( float realtime )
|
|||||||
{
|
{
|
||||||
if( !gameui.hInstance ) return;
|
if( !gameui.hInstance ) return;
|
||||||
|
|
||||||
|
// don't draw menu over console
|
||||||
|
if( cls.key_dest == key_console ) return;
|
||||||
|
|
||||||
// if some deferred cmds is waiting
|
// if some deferred cmds is waiting
|
||||||
if( UI_IsVisible() && COM_CheckString( host.deferred_cmd ))
|
if( UI_IsVisible() && !COM_StringEmptyOrNULL( host.deferred_cmd ))
|
||||||
{
|
{
|
||||||
Cbuf_AddText( host.deferred_cmd );
|
Cbuf_AddText( host.deferred_cmd );
|
||||||
host.deferred_cmd[0] = '\0';
|
host.deferred_cmd[0] = '\0';
|
||||||
@@ -199,24 +202,6 @@ void UI_ShowConnectionWarning( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
UI_ShowConnectionWarning
|
|
||||||
|
|
||||||
show update dialog
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void UI_ShowUpdateDialog( qboolean preferStore )
|
|
||||||
{
|
|
||||||
if( gameui.dllFuncs2.pfnShowUpdateDialog )
|
|
||||||
{
|
|
||||||
gameui.dllFuncs2.pfnShowUpdateDialog( preferStore );
|
|
||||||
}
|
|
||||||
|
|
||||||
Con_Printf( S_WARN "This version is not supported anymore. To continue, install latest engine version\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
UI_ShowConnectionWarning
|
UI_ShowConnectionWarning
|
||||||
@@ -514,7 +499,7 @@ static HIMAGE GAME_EXPORT pfnPIC_Load( const char *szPicName, const byte *image_
|
|||||||
{
|
{
|
||||||
HIMAGE tx;
|
HIMAGE tx;
|
||||||
|
|
||||||
if( !COM_CheckString( szPicName ))
|
if( COM_StringEmptyOrNULL( szPicName ))
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "%s: refusing to load image with empty name\n", __func__ );
|
Con_Reportf( S_ERROR "%s: refusing to load image with empty name\n", __func__ );
|
||||||
return 0;
|
return 0;
|
||||||
@@ -710,7 +695,9 @@ pfnPlaySound
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT pfnPlaySound( const char *szSound )
|
static void GAME_EXPORT pfnPlaySound( const char *szSound )
|
||||||
{
|
{
|
||||||
if( !COM_CheckString( szSound )) return;
|
if( COM_StringEmptyOrNULL( szSound ))
|
||||||
|
return;
|
||||||
|
|
||||||
S_StartLocalSound( szSound, VOL_NORM, false );
|
S_StartLocalSound( szSound, VOL_NORM, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -995,7 +982,7 @@ pfnGetFilesList
|
|||||||
release prev search on a next call
|
release prev search on a next call
|
||||||
=========
|
=========
|
||||||
*/
|
*/
|
||||||
static char ** GAME_EXPORT pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly )
|
char **GAME_EXPORT CL_GetFilesList( const char *pattern, int *numFiles, int gamedironly )
|
||||||
{
|
{
|
||||||
static search_t *t = NULL;
|
static search_t *t = NULL;
|
||||||
|
|
||||||
@@ -1096,6 +1083,9 @@ UI_ShellExecute
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT UI_ShellExecute( const char *path, const char *parms, int shouldExit )
|
static void GAME_EXPORT UI_ShellExecute( const char *path, const char *parms, int shouldExit )
|
||||||
{
|
{
|
||||||
|
if( !Q_strcmp( path, GENERIC_UPDATE_PAGE ) || !Q_strcmp( path, PLATFORM_UPDATE_PAGE ))
|
||||||
|
path = DEFAULT_UPDATE_PAGE;
|
||||||
|
|
||||||
Platform_ShellExecute( path, parms );
|
Platform_ShellExecute( path, parms );
|
||||||
|
|
||||||
if( shouldExit )
|
if( shouldExit )
|
||||||
@@ -1232,7 +1222,7 @@ static const ui_enginefuncs_t gEngfuncs =
|
|||||||
pfnMemFree,
|
pfnMemFree,
|
||||||
pfnGetOldGameInfo,
|
pfnGetOldGameInfo,
|
||||||
pfnGetGamesList,
|
pfnGetGamesList,
|
||||||
pfnGetFilesList,
|
CL_GetFilesList,
|
||||||
SV_GetSaveComment,
|
SV_GetSaveComment,
|
||||||
CL_GetDemoComment,
|
CL_GetDemoComment,
|
||||||
pfnCheckGameDll,
|
pfnCheckGameDll,
|
||||||
@@ -1354,7 +1344,6 @@ qboolean UI_LoadProgs( void )
|
|||||||
UITEXTAPI GiveTextApi;
|
UITEXTAPI GiveTextApi;
|
||||||
MENUAPI GetMenuAPI;
|
MENUAPI GetMenuAPI;
|
||||||
string dllpath;
|
string dllpath;
|
||||||
int i;
|
|
||||||
|
|
||||||
if( gameui.hInstance ) UI_UnloadProgs();
|
if( gameui.hInstance ) UI_UnloadProgs();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "kbutton.h"
|
|
||||||
|
|
||||||
#if XASH_LOW_MEMORY == 0
|
#if XASH_LOW_MEMORY == 0
|
||||||
#define NET_TIMINGS 1024
|
#define NET_TIMINGS 1024
|
||||||
@@ -172,7 +171,7 @@ get frame data info, like chokes, packet losses, also update graph, packet and c
|
|||||||
static void NetGraph_GetFrameData( float *latency, int *latency_count )
|
static void NetGraph_GetFrameData( float *latency, int *latency_count )
|
||||||
{
|
{
|
||||||
int i, choke_count = 0, loss_count = 0;
|
int i, choke_count = 0, loss_count = 0;
|
||||||
double newtime = Sys_DoubleTime();
|
double newtime = Platform_DoubleTime();
|
||||||
static double nexttime = 0;
|
static double nexttime = 0;
|
||||||
float loss, choke;
|
float loss, choke;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,633 +0,0 @@
|
|||||||
/*
|
|
||||||
cl_parse.c - parse a message received from the server
|
|
||||||
Copyright (C) 2008 Uncle Mike
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "net_encode.h"
|
|
||||||
#include "particledef.h"
|
|
||||||
#include "cl_tent.h"
|
|
||||||
#include "shake.h"
|
|
||||||
#include "hltv.h"
|
|
||||||
#include "input.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
CL_ParseStaticEntity
|
|
||||||
|
|
||||||
static client entity
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
static void CL_LegacyParseStaticEntity( sizebuf_t *msg )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
entity_state_t state = { 0 };
|
|
||||||
cl_entity_t *ent;
|
|
||||||
|
|
||||||
if( !clgame.static_entities )
|
|
||||||
clgame.static_entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
|
|
||||||
|
|
||||||
state.modelindex = MSG_ReadShort( msg );
|
|
||||||
state.sequence = MSG_ReadByte( msg );
|
|
||||||
state.frame = MSG_ReadByte( msg );
|
|
||||||
state.colormap = MSG_ReadWord( msg );
|
|
||||||
state.skin = MSG_ReadByte( msg );
|
|
||||||
|
|
||||||
for( i = 0; i < 3; i++ )
|
|
||||||
{
|
|
||||||
state.origin[i] = MSG_ReadCoord( msg );
|
|
||||||
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
|
|
||||||
}
|
|
||||||
|
|
||||||
state.rendermode = MSG_ReadByte( msg );
|
|
||||||
|
|
||||||
if( state.rendermode != kRenderNormal )
|
|
||||||
{
|
|
||||||
state.renderamt = MSG_ReadByte( msg );
|
|
||||||
state.rendercolor.r = MSG_ReadByte( msg );
|
|
||||||
state.rendercolor.g = MSG_ReadByte( msg );
|
|
||||||
state.rendercolor.b = MSG_ReadByte( msg );
|
|
||||||
state.renderfx = MSG_ReadByte( msg );
|
|
||||||
}
|
|
||||||
|
|
||||||
i = clgame.numStatics;
|
|
||||||
if( i >= MAX_STATIC_ENTITIES )
|
|
||||||
{
|
|
||||||
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = &clgame.static_entities[i];
|
|
||||||
clgame.numStatics++;
|
|
||||||
|
|
||||||
// all states are same
|
|
||||||
ent->baseline = ent->curstate = ent->prevstate = state;
|
|
||||||
ent->index = 0; // static entities doesn't has the numbers
|
|
||||||
|
|
||||||
// statics may be respawned in game e.g. for demo recording
|
|
||||||
if( cls.state == ca_connected || cls.state == ca_validate )
|
|
||||||
ent->trivial_accept = INVALID_HANDLE;
|
|
||||||
|
|
||||||
// setup the new static entity
|
|
||||||
VectorCopy( ent->curstate.origin, ent->origin );
|
|
||||||
VectorCopy( ent->curstate.angles, ent->angles );
|
|
||||||
ent->model = CL_ModelHandle( state.modelindex );
|
|
||||||
ent->curstate.framerate = 1.0f;
|
|
||||||
CL_ResetLatchedVars( ent, true );
|
|
||||||
|
|
||||||
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
|
|
||||||
{
|
|
||||||
// auto 'solid' faces
|
|
||||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
|
|
||||||
{
|
|
||||||
ent->curstate.rendermode = kRenderTransAlpha;
|
|
||||||
ent->curstate.renderamt = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
R_AddEfrags( ent ); // add link
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
|
|
||||||
{
|
|
||||||
vec3_t pos;
|
|
||||||
int chan, sound;
|
|
||||||
float volume, attn;
|
|
||||||
int flags, pitch, entnum;
|
|
||||||
sound_t handle = 0;
|
|
||||||
|
|
||||||
flags = MSG_ReadWord( msg );
|
|
||||||
if( flags & SND_LEGACY_LARGE_INDEX )
|
|
||||||
{
|
|
||||||
sound = MSG_ReadWord( msg );
|
|
||||||
flags &= ~SND_LEGACY_LARGE_INDEX;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sound = MSG_ReadByte( msg );
|
|
||||||
chan = MSG_ReadByte( msg );
|
|
||||||
|
|
||||||
if( FBitSet( flags, SND_VOLUME ))
|
|
||||||
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
|
||||||
else volume = VOL_NORM;
|
|
||||||
|
|
||||||
if( FBitSet( flags, SND_ATTENUATION ))
|
|
||||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
|
||||||
else attn = ATTN_NONE;
|
|
||||||
|
|
||||||
if( FBitSet( flags, SND_PITCH ))
|
|
||||||
pitch = MSG_ReadByte( msg );
|
|
||||||
else pitch = PITCH_NORM;
|
|
||||||
|
|
||||||
// entity reletive
|
|
||||||
entnum = MSG_ReadWord( msg );
|
|
||||||
|
|
||||||
// positioned in space
|
|
||||||
MSG_ReadVec3Coord( msg, pos );
|
|
||||||
|
|
||||||
if( FBitSet( flags, SND_SENTENCE ))
|
|
||||||
{
|
|
||||||
char sentenceName[32];
|
|
||||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
|
||||||
handle = S_RegisterSound( sentenceName );
|
|
||||||
}
|
|
||||||
else handle = cl.sound_index[sound]; // see precached sound
|
|
||||||
|
|
||||||
if( !cl.audio_prepped )
|
|
||||||
return; // too early
|
|
||||||
|
|
||||||
// g-cont. sound and ambient sound have only difference with channel
|
|
||||||
if( is_ambient )
|
|
||||||
{
|
|
||||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
CL_PrecacheSound
|
|
||||||
|
|
||||||
prceache sound from server
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void CL_LegacyPrecacheSound( sizebuf_t *msg )
|
|
||||||
{
|
|
||||||
int soundIndex;
|
|
||||||
|
|
||||||
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
|
||||||
|
|
||||||
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
|
|
||||||
Host_Error( "%s: bad soundindex %i\n", __func__, soundIndex );
|
|
||||||
|
|
||||||
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
|
|
||||||
|
|
||||||
// when we loading map all resources is precached sequentially
|
|
||||||
//if( !cl.audio_prepped ) return;
|
|
||||||
|
|
||||||
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CL_LegacyPrecacheModel( sizebuf_t *msg )
|
|
||||||
{
|
|
||||||
int modelIndex;
|
|
||||||
string model;
|
|
||||||
|
|
||||||
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
|
|
||||||
|
|
||||||
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
|
|
||||||
Host_Error( "%s: bad modelindex %i\n", __func__, modelIndex );
|
|
||||||
|
|
||||||
Q_strncpy( model, MSG_ReadString( msg ), sizeof( model ));
|
|
||||||
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
|
|
||||||
|
|
||||||
// when we loading map all resources is precached sequentially
|
|
||||||
//if( !cl.video_prepped ) return;
|
|
||||||
if( modelIndex == 1 && !cl.worldmodel )
|
|
||||||
{
|
|
||||||
CL_ClearWorld ();
|
|
||||||
|
|
||||||
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
|
|
||||||
|
|
||||||
cl.models[modelIndex] = Mod_ForName( model, false, false );
|
|
||||||
cl.nummodels = Q_max( cl.nummodels, modelIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CL_LegacyPrecacheEvent( sizebuf_t *msg )
|
|
||||||
{
|
|
||||||
int eventIndex;
|
|
||||||
|
|
||||||
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
|
||||||
|
|
||||||
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
|
|
||||||
Host_Error( "%s: bad eventindex %i\n", __func__, eventIndex );
|
|
||||||
|
|
||||||
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
|
|
||||||
|
|
||||||
// can be set now
|
|
||||||
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if XASH_LOW_MEMORY == 0
|
|
||||||
#define MAX_LEGACY_RESOURCES 2048
|
|
||||||
#elif XASH_LOW_MEMORY == 2
|
|
||||||
#define MAX_LEGACY_RESOURCES 1
|
|
||||||
#elif XASH_LOW_MEMORY == 1
|
|
||||||
#define MAX_LEGACY_RESOURCES 512
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
==============
|
|
||||||
CL_ParseResourceList
|
|
||||||
|
|
||||||
==============
|
|
||||||
*/
|
|
||||||
static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
int rescount;
|
|
||||||
int restype[MAX_LEGACY_RESOURCES];
|
|
||||||
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
|
|
||||||
} reslist;
|
|
||||||
|
|
||||||
memset( &reslist, 0, sizeof( reslist ));
|
|
||||||
reslist.rescount = MSG_ReadWord( msg ) - 1;
|
|
||||||
|
|
||||||
if( reslist.rescount > MAX_LEGACY_RESOURCES )
|
|
||||||
Host_Error( "MAX_RESOURCES reached\n" );
|
|
||||||
|
|
||||||
for( i = 0; i < reslist.rescount; i++ )
|
|
||||||
{
|
|
||||||
reslist.restype[i] = MSG_ReadWord( msg );
|
|
||||||
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), sizeof( reslist.resnames[i] ));
|
|
||||||
}
|
|
||||||
|
|
||||||
if( cls.demoplayback )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( !cl_allow_download.value )
|
|
||||||
{
|
|
||||||
Con_DPrintf( "Refusing new resource, cl_allowdownload set to 0\n" );
|
|
||||||
reslist.rescount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( cls.state == ca_active && !cl_download_ingame.value )
|
|
||||||
{
|
|
||||||
Con_DPrintf( "Refusing new resource, cl_download_ingame set to 0\n" );
|
|
||||||
reslist.rescount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HTTP_ResetProcessState();
|
|
||||||
|
|
||||||
host.downloadcount = 0;
|
|
||||||
|
|
||||||
for( i = 0; i < reslist.rescount; i++ )
|
|
||||||
{
|
|
||||||
char soundpath[MAX_VA_STRING];
|
|
||||||
const char *path;
|
|
||||||
|
|
||||||
if( reslist.restype[i] == t_sound )
|
|
||||||
{
|
|
||||||
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
|
|
||||||
|
|
||||||
path = soundpath;
|
|
||||||
}
|
|
||||||
else path = reslist.resnames[i];
|
|
||||||
|
|
||||||
if( FS_FileExists( path, false ))
|
|
||||||
continue; // already exists
|
|
||||||
|
|
||||||
host.downloadcount++;
|
|
||||||
HTTP_AddDownload( path, -1, true, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !host.downloadcount )
|
|
||||||
{
|
|
||||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
|
||||||
MSG_WriteString( &cls.netchan.message, "continueloading" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=====================
|
|
||||||
CL_ParseLegacyServerMessage
|
|
||||||
|
|
||||||
dispatch messages
|
|
||||||
=====================
|
|
||||||
*/
|
|
||||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
|
||||||
{
|
|
||||||
size_t bufStart, playerbytes;
|
|
||||||
int cmd;
|
|
||||||
int old_background;
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
// parse the message
|
|
||||||
while( 1 )
|
|
||||||
{
|
|
||||||
if( MSG_CheckOverflow( msg ))
|
|
||||||
{
|
|
||||||
Host_Error( "%s: overflow!\n", __func__ );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark start position
|
|
||||||
bufStart = MSG_GetNumBytesRead( msg );
|
|
||||||
|
|
||||||
// end of message (align bits)
|
|
||||||
if( MSG_GetNumBitsLeft( msg ) < 8 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
cmd = MSG_ReadServerCmd( msg );
|
|
||||||
|
|
||||||
// record command for debugging spew on parse problem
|
|
||||||
CL_Parse_RecordCommand( cmd, bufStart );
|
|
||||||
|
|
||||||
if( CL_ParseCommonDLLMessage( msg, PROTO_LEGACY, cmd, bufStart ))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// other commands
|
|
||||||
switch( cmd )
|
|
||||||
{
|
|
||||||
case svc_bad:
|
|
||||||
Host_Error( "svc_bad\n" );
|
|
||||||
break;
|
|
||||||
case svc_nop:
|
|
||||||
// this does nothing
|
|
||||||
break;
|
|
||||||
case svc_disconnect:
|
|
||||||
CL_Drop ();
|
|
||||||
Host_AbortCurrentFrame ();
|
|
||||||
break;
|
|
||||||
case svc_legacy_event:
|
|
||||||
CL_ParseEvent( msg, PROTO_LEGACY );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
break;
|
|
||||||
case svc_legacy_changing:
|
|
||||||
old_background = cl.background;
|
|
||||||
if( MSG_ReadOneBit( msg ))
|
|
||||||
{
|
|
||||||
int maxclients = cl.maxclients;
|
|
||||||
|
|
||||||
// we can only changelevel in singleplayer
|
|
||||||
// and singleplayer always runs in current protocol
|
|
||||||
// cls.changelevel = true;
|
|
||||||
S_StopAllSounds( true );
|
|
||||||
|
|
||||||
Con_Printf( "Server changing, reconnecting\n" );
|
|
||||||
|
|
||||||
if( cls.demoplayback )
|
|
||||||
{
|
|
||||||
SCR_BeginLoadingPlaque( cl.background );
|
|
||||||
cls.changedemo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CL_ClearState( );
|
|
||||||
|
|
||||||
// a1ba: need to restore cl.maxclients because engine chooses
|
|
||||||
// frame backups count depending on this value
|
|
||||||
// In general, it's incorrect to call CL_InitEdicts right after
|
|
||||||
// CL_ClearState because of this bug. Some time later this logic
|
|
||||||
// should be re-done.
|
|
||||||
CL_InitEdicts( maxclients ); // re-arrange edicts
|
|
||||||
}
|
|
||||||
else Con_Printf( "Server disconnected, reconnecting\n" );
|
|
||||||
|
|
||||||
if( cls.demoplayback )
|
|
||||||
{
|
|
||||||
cl.background = (cls.demonum != -1) ? true : false;
|
|
||||||
cls.state = ca_connected;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// g-cont. local client skip the challenge
|
|
||||||
if( SV_Active( ))
|
|
||||||
cls.state = ca_disconnected;
|
|
||||||
else cls.state = ca_connecting;
|
|
||||||
cl.background = old_background;
|
|
||||||
cls.connect_time = MAX_HEARTBEAT;
|
|
||||||
cls.connect_retry = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case svc_setview:
|
|
||||||
CL_ParseViewEntity( msg );
|
|
||||||
break;
|
|
||||||
case svc_sound:
|
|
||||||
CL_LegacyParseSoundPacket( msg, false );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
break;
|
|
||||||
case svc_legacy_ambientsound:
|
|
||||||
CL_LegacyParseSoundPacket( msg, true );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case svc_time:
|
|
||||||
CL_ParseServerTime( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_print:
|
|
||||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
|
||||||
break;
|
|
||||||
case svc_stufftext:
|
|
||||||
s = MSG_ReadString( msg );
|
|
||||||
if( cl_trace_stufftext.value )
|
|
||||||
{
|
|
||||||
size_t len = Q_strlen( s );
|
|
||||||
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HACKS_RELATED_HLMODS
|
|
||||||
// disable Cry Of Fear antisave protection
|
|
||||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
|
||||||
break; // too early
|
|
||||||
#endif
|
|
||||||
Cbuf_AddFilteredText( s );
|
|
||||||
break;
|
|
||||||
case svc_setangle:
|
|
||||||
CL_ParseSetAngle( msg );
|
|
||||||
break;
|
|
||||||
case svc_serverdata:
|
|
||||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
|
||||||
CL_ParseServerData( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_lightstyle:
|
|
||||||
CL_ParseLightStyle( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_updateuserinfo:
|
|
||||||
CL_UpdateUserinfo( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_deltatable:
|
|
||||||
Delta_ParseTableField( msg );
|
|
||||||
break;
|
|
||||||
case svc_clientdata:
|
|
||||||
CL_ParseClientData( msg, PROTO_LEGACY );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
break;
|
|
||||||
case svc_resource:
|
|
||||||
CL_ParseResource( msg );
|
|
||||||
break;
|
|
||||||
case svc_pings:
|
|
||||||
CL_UpdateUserPings( msg );
|
|
||||||
break;
|
|
||||||
case svc_particle:
|
|
||||||
CL_ParseParticles( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_restoresound:
|
|
||||||
Con_Printf( S_ERROR "%s: svc_restoresound: implement me!\n", __func__ );
|
|
||||||
break;
|
|
||||||
case svc_spawnstatic:
|
|
||||||
CL_LegacyParseStaticEntity( msg );
|
|
||||||
break;
|
|
||||||
case svc_event_reliable:
|
|
||||||
CL_ParseReliableEvent( msg, PROTO_LEGACY );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
break;
|
|
||||||
case svc_spawnbaseline:
|
|
||||||
CL_ParseBaseline( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_setpause:
|
|
||||||
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
|
|
||||||
break;
|
|
||||||
case svc_signonnum:
|
|
||||||
CL_ParseSignon( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_centerprint:
|
|
||||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
|
||||||
break;
|
|
||||||
case svc_legacy_modelindex:
|
|
||||||
CL_LegacyPrecacheModel( msg );
|
|
||||||
break;
|
|
||||||
case svc_legacy_soundindex:
|
|
||||||
CL_LegacyPrecacheSound( msg );
|
|
||||||
break;
|
|
||||||
case svc_restore:
|
|
||||||
CL_ParseRestore( msg );
|
|
||||||
break;
|
|
||||||
case svc_legacy_eventindex:
|
|
||||||
CL_LegacyPrecacheEvent(msg);
|
|
||||||
break;
|
|
||||||
case svc_bspdecal:
|
|
||||||
CL_ParseStaticDecal( msg );
|
|
||||||
break;
|
|
||||||
case svc_addangle:
|
|
||||||
CL_ParseAddAngle( msg );
|
|
||||||
break;
|
|
||||||
case svc_usermessage:
|
|
||||||
CL_RegisterUserMessage( msg, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_packetentities:
|
|
||||||
playerbytes = CL_ParsePacketEntities( msg, false, PROTO_LEGACY );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
|
||||||
break;
|
|
||||||
case svc_deltapacketentities:
|
|
||||||
playerbytes = CL_ParsePacketEntities( msg, true, PROTO_LEGACY );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
|
||||||
break;
|
|
||||||
case svc_legacy_chokecount:
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
i = MSG_ReadByte( msg );
|
|
||||||
j = cls.netchan.incoming_acknowledged - 1;
|
|
||||||
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
|
|
||||||
{
|
|
||||||
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
|
|
||||||
{
|
|
||||||
cl.frames[j & CL_UPDATE_MASK].choked = true;
|
|
||||||
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
|
||||||
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
|
||||||
break;
|
|
||||||
case svc_resourcelist:
|
|
||||||
CL_LegacyParseResourceList( msg );
|
|
||||||
break;
|
|
||||||
case svc_deltamovevars:
|
|
||||||
CL_ParseMovevars( msg );
|
|
||||||
break;
|
|
||||||
case svc_resourcerequest:
|
|
||||||
CL_ParseResourceRequest( msg );
|
|
||||||
break;
|
|
||||||
case svc_customization:
|
|
||||||
CL_ParseCustomization( msg );
|
|
||||||
break;
|
|
||||||
case svc_crosshairangle:
|
|
||||||
CL_ParseCrosshairAngle( msg );
|
|
||||||
break;
|
|
||||||
case svc_soundfade:
|
|
||||||
CL_ParseSoundFade( msg );
|
|
||||||
break;
|
|
||||||
case svc_filetxferfailed:
|
|
||||||
CL_ParseFileTransferFailed( msg );
|
|
||||||
break;
|
|
||||||
case svc_hltv:
|
|
||||||
CL_ParseHLTV( msg );
|
|
||||||
break;
|
|
||||||
case svc_resourcelocation:
|
|
||||||
CL_ParseResLocation( msg );
|
|
||||||
break;
|
|
||||||
case svc_querycvarvalue:
|
|
||||||
CL_ParseCvarValue( msg, false, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
case svc_querycvarvalue2:
|
|
||||||
CL_ParseCvarValue( msg, true, PROTO_LEGACY );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CL_LegacyPrecache_f( void )
|
|
||||||
{
|
|
||||||
int spawncount, i;
|
|
||||||
model_t *mod;
|
|
||||||
|
|
||||||
if( cls.legacymode != PROTO_LEGACY )
|
|
||||||
return;
|
|
||||||
|
|
||||||
spawncount = Q_atoi( Cmd_Argv( 1 ));
|
|
||||||
|
|
||||||
Con_Printf( "Setting up renderer...\n" );
|
|
||||||
|
|
||||||
// load tempent sprites (glowshell, muzzleflashes etc)
|
|
||||||
CL_LoadClientSprites ();
|
|
||||||
|
|
||||||
// invalidate all decal indexes
|
|
||||||
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
|
|
||||||
cl.video_prepped = true;
|
|
||||||
cl.audio_prepped = true;
|
|
||||||
if( clgame.entities )
|
|
||||||
clgame.entities->model = cl.worldmodel;
|
|
||||||
|
|
||||||
// load skybox
|
|
||||||
R_SetupSky( clgame.movevars.skyName );
|
|
||||||
|
|
||||||
// tell rendering system we have a new set of models.
|
|
||||||
ref.dllFuncs.R_NewMap ();
|
|
||||||
|
|
||||||
CL_SetupOverviewParams();
|
|
||||||
|
|
||||||
// release unused SpriteTextures
|
|
||||||
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
|
|
||||||
{
|
|
||||||
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
|
|
||||||
Mod_FreeModel( mod );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mod_FreeUnused ();
|
|
||||||
|
|
||||||
if( host_developer.value <= DEV_NONE )
|
|
||||||
Con_ClearNotify(); // clear any lines of console text
|
|
||||||
|
|
||||||
// done with all resources, issue prespawn command.
|
|
||||||
// Include server count in case server disconnects and changes level during d/l
|
|
||||||
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
|
|
||||||
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
|
|
||||||
cls.signon = SIGNONS - 1;
|
|
||||||
}
|
|
||||||
@@ -16,10 +16,8 @@ GNU General Public License for more details.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "net_encode.h"
|
#include "net_encode.h"
|
||||||
#include "particledef.h"
|
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "shake.h"
|
#include "shake.h"
|
||||||
#include "hltv.h"
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
@@ -28,18 +26,11 @@ static void CL_ParseExtraInfo( sizebuf_t *msg )
|
|||||||
string clientfallback;
|
string clientfallback;
|
||||||
|
|
||||||
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
|
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
|
||||||
if( COM_CheckStringEmpty( clientfallback ))
|
if( !COM_StringEmpty( clientfallback ))
|
||||||
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__, clientfallback );
|
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__, clientfallback );
|
||||||
|
|
||||||
if( MSG_ReadByte( msg ))
|
cls.allow_cheats = MSG_ReadByte( msg ) ? true : false;
|
||||||
{
|
CL_SetCheatState( cl.maxclients > 1, cls.allow_cheats );
|
||||||
Cvar_FullSet( "sv_cheats", "1", FCVAR_READ_ONLY | FCVAR_SERVER );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cvar_SetCheatState();
|
|
||||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CL_ParseNewMovevars( sizebuf_t *msg )
|
static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||||
@@ -65,12 +56,12 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
|
|||||||
clgame.movevars.footsteps = MSG_ReadByte( msg );
|
clgame.movevars.footsteps = MSG_ReadByte( msg );
|
||||||
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skycolor_r = MSG_ReadFloat( msg );
|
clgame.movevars.skycolor[0] = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skycolor_g = MSG_ReadFloat( msg );
|
clgame.movevars.skycolor[1] = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skycolor_b = MSG_ReadFloat( msg );
|
clgame.movevars.skycolor[2] = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skyvec_x = MSG_ReadFloat( msg );
|
clgame.movevars.skyvec[0] = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skyvec_y = MSG_ReadFloat( msg );
|
clgame.movevars.skyvec[1] = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skyvec_z = MSG_ReadFloat( msg );
|
clgame.movevars.skyvec[2] = MSG_ReadFloat( msg );
|
||||||
|
|
||||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||||
|
|
||||||
@@ -213,6 +204,7 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
|
|||||||
qboolean newent = from == NULL;
|
qboolean newent = from == NULL;
|
||||||
int pack = frame->num_entities;
|
int pack = frame->num_entities;
|
||||||
qboolean has_update = msg != NULL;
|
qboolean has_update = msg != NULL;
|
||||||
|
static entity_state_t nullent;
|
||||||
|
|
||||||
// alloc next slot to store update
|
// alloc next slot to store update
|
||||||
to = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
to = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
||||||
@@ -240,7 +232,17 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
|
|||||||
if( hdr->instanced )
|
if( hdr->instanced )
|
||||||
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
||||||
else if( hdr->offset != 0 )
|
else if( hdr->offset != 0 )
|
||||||
from = &cls.packet_entities[(cls.next_client_entities - hdr->offset) % cls.num_client_entities];
|
{
|
||||||
|
// FIXME: the usage of `offset` is incorrect here as the entities might
|
||||||
|
// not be ordered in cls.packet_entities the same way as on server
|
||||||
|
// catch the error, print the scary message and fix it up to nullent
|
||||||
|
if( cls.next_client_entities - hdr->offset < 0 )
|
||||||
|
{
|
||||||
|
Con_Printf( S_ERROR "%s: prevented delta-ing from invalid entity (%d - %d < 0)\n", __func__, cls.next_client_entities, hdr->offset );
|
||||||
|
from = &nullent;
|
||||||
|
}
|
||||||
|
else from = &cls.packet_entities[(cls.next_client_entities - hdr->offset ) % cls.num_client_entities];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
from = &ent->baseline;
|
from = &ent->baseline;
|
||||||
}
|
}
|
||||||
@@ -474,7 +476,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
|||||||
|
|
||||||
chan = MSG_ReadUBitLong( msg, 3 );
|
chan = MSG_ReadUBitLong( msg, 3 );
|
||||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||||
if( FBitSet( flags, SND_LEGACY_LARGE_INDEX ))
|
if( FBitSet( flags, SND_GOLDSRC_LARGE_INDEX ))
|
||||||
sound = MSG_ReadWord( msg );
|
sound = MSG_ReadWord( msg );
|
||||||
else sound = MSG_ReadByte( msg );
|
else sound = MSG_ReadByte( msg );
|
||||||
MSG_ReadGSBitVec3Coord( msg, pos );
|
MSG_ReadGSBitVec3Coord( msg, pos );
|
||||||
@@ -485,7 +487,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
|||||||
|
|
||||||
MSG_EndBitWriting( msg );
|
MSG_EndBitWriting( msg );
|
||||||
|
|
||||||
ClearBits( flags, SND_LEGACY_LARGE_INDEX );
|
ClearBits( flags, SND_GOLDSRC_LARGE_INDEX );
|
||||||
|
|
||||||
if( FBitSet( flags, SND_SENTENCE ))
|
if( FBitSet( flags, SND_SENTENCE ))
|
||||||
{
|
{
|
||||||
@@ -567,25 +569,18 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
// record command for debugging spew on parse problem
|
// record command for debugging spew on parse problem
|
||||||
CL_Parse_RecordCommand( cmd, bufStart );
|
CL_Parse_RecordCommand( cmd, bufStart );
|
||||||
|
|
||||||
if( CL_ParseCommonDLLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
if( CL_ParseCommonMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( CL_ParseCommonHLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// other commands
|
// other commands
|
||||||
switch( cmd )
|
switch( cmd )
|
||||||
{
|
{
|
||||||
case svc_bad:
|
|
||||||
Host_Error( "svc_bad\n" );
|
|
||||||
break;
|
|
||||||
case svc_nop:
|
|
||||||
case svc_spawnstatic:
|
|
||||||
case svc_goldsrc_damage:
|
|
||||||
case svc_goldsrc_killedmonster:
|
|
||||||
case svc_goldsrc_foundsecret:
|
|
||||||
// this does nothing
|
|
||||||
break;
|
|
||||||
case svc_disconnect:
|
case svc_disconnect:
|
||||||
s = MSG_ReadString( msg );
|
s = MSG_ReadString( msg );
|
||||||
if( COM_CheckStringEmpty( s ))
|
if( !COM_StringEmpty( s ))
|
||||||
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
||||||
CL_Drop ();
|
CL_Drop ();
|
||||||
Host_AbortCurrentFrame ();
|
Host_AbortCurrentFrame ();
|
||||||
@@ -601,47 +596,10 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
||||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
||||||
break;
|
break;
|
||||||
case svc_setview:
|
|
||||||
CL_ParseViewEntity( msg );
|
|
||||||
break;
|
|
||||||
case svc_sound:
|
case svc_sound:
|
||||||
CL_ParseSoundPacketGS( msg );
|
CL_ParseSoundPacketGS( msg );
|
||||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
break;
|
break;
|
||||||
case svc_time:
|
|
||||||
CL_ParseServerTime( msg, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_print:
|
|
||||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
|
||||||
break;
|
|
||||||
case svc_stufftext:
|
|
||||||
s = MSG_ReadString( msg );
|
|
||||||
if( cl_trace_stufftext.value )
|
|
||||||
{
|
|
||||||
size_t len = Q_strlen( s );
|
|
||||||
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HACKS_RELATED_HLMODS
|
|
||||||
// disable Cry Of Fear antisave protection
|
|
||||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
|
||||||
break; // too early
|
|
||||||
#endif
|
|
||||||
Cbuf_AddFilteredText( s );
|
|
||||||
break;
|
|
||||||
case svc_setangle:
|
|
||||||
CL_ParseSetAngle( msg );
|
|
||||||
break;
|
|
||||||
case svc_serverdata:
|
|
||||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
|
||||||
CL_ParseServerData( msg, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_lightstyle:
|
|
||||||
CL_ParseLightStyle( msg, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_updateuserinfo:
|
|
||||||
CL_UpdateUserinfo( msg, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_deltatable:
|
case svc_deltatable:
|
||||||
Delta_ParseTableField_GS( msg );
|
Delta_ParseTableField_GS( msg );
|
||||||
break;
|
break;
|
||||||
@@ -661,8 +619,9 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
CL_UpdateUserPings( msg );
|
CL_UpdateUserPings( msg );
|
||||||
MSG_EndBitWriting( msg );
|
MSG_EndBitWriting( msg );
|
||||||
break;
|
break;
|
||||||
case svc_particle:
|
case svc_goldsrc_damage:
|
||||||
CL_ParseParticles( msg, PROTO_GOLDSRC );
|
case svc_spawnstatic:
|
||||||
|
// this does nothing
|
||||||
break;
|
break;
|
||||||
case svc_event_reliable:
|
case svc_event_reliable:
|
||||||
MSG_StartBitWriting( msg );
|
MSG_StartBitWriting( msg );
|
||||||
@@ -678,35 +637,18 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
case svc_setpause:
|
case svc_setpause:
|
||||||
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
||||||
break;
|
break;
|
||||||
case svc_signonnum:
|
case svc_goldsrc_killedmonster:
|
||||||
CL_ParseSignon( msg, PROTO_GOLDSRC );
|
case svc_goldsrc_foundsecret:
|
||||||
break;
|
// this does nothing
|
||||||
case svc_centerprint:
|
|
||||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
|
||||||
break;
|
break;
|
||||||
case svc_goldsrc_spawnstaticsound:
|
case svc_goldsrc_spawnstaticsound:
|
||||||
CL_ParseSpawnStaticSound( msg );
|
CL_ParseSpawnStaticSound( msg );
|
||||||
break;
|
break;
|
||||||
case svc_finale:
|
|
||||||
CL_ParseFinaleCutscene( msg, 2 );
|
|
||||||
break;
|
|
||||||
case svc_restore:
|
|
||||||
CL_ParseRestore( msg );
|
|
||||||
break;
|
|
||||||
case svc_cutscene:
|
|
||||||
CL_ParseFinaleCutscene( msg, 3 );
|
|
||||||
break;
|
|
||||||
case svc_goldsrc_decalname:
|
case svc_goldsrc_decalname:
|
||||||
param1 = MSG_ReadByte( msg );
|
param1 = MSG_ReadByte( msg );
|
||||||
s = MSG_ReadString( msg );
|
s = MSG_ReadString( msg );
|
||||||
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
||||||
break;
|
break;
|
||||||
case svc_addangle:
|
|
||||||
CL_ParseAddAngle( msg );
|
|
||||||
break;
|
|
||||||
case svc_usermessage:
|
|
||||||
CL_RegisterUserMessage( msg, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_packetentities:
|
case svc_packetentities:
|
||||||
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
||||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||||
@@ -717,10 +659,6 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||||
break;
|
break;
|
||||||
case svc_choke:
|
|
||||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
|
||||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
|
||||||
break;
|
|
||||||
case svc_resourcelist:
|
case svc_resourcelist:
|
||||||
MSG_StartBitWriting( msg );
|
MSG_StartBitWriting( msg );
|
||||||
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
||||||
@@ -729,34 +667,6 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
case svc_deltamovevars:
|
case svc_deltamovevars:
|
||||||
CL_ParseNewMovevars( msg );
|
CL_ParseNewMovevars( msg );
|
||||||
break;
|
break;
|
||||||
case svc_resourcerequest:
|
|
||||||
CL_ParseResourceRequest( msg );
|
|
||||||
break;
|
|
||||||
case svc_customization:
|
|
||||||
CL_ParseCustomization( msg );
|
|
||||||
break;
|
|
||||||
case svc_crosshairangle:
|
|
||||||
CL_ParseCrosshairAngle( msg );
|
|
||||||
break;
|
|
||||||
case svc_soundfade:
|
|
||||||
CL_ParseSoundFade( msg );
|
|
||||||
break;
|
|
||||||
case svc_filetxferfailed:
|
|
||||||
CL_ParseFileTransferFailed( msg );
|
|
||||||
break;
|
|
||||||
case svc_hltv:
|
|
||||||
CL_ParseHLTV( msg );
|
|
||||||
break;
|
|
||||||
case svc_voiceinit:
|
|
||||||
CL_ParseVoiceInit( msg );
|
|
||||||
break;
|
|
||||||
case svc_voicedata:
|
|
||||||
CL_ParseVoiceData( msg, PROTO_GOLDSRC );
|
|
||||||
cl.frames[cl.parsecountmod].graphdata.voicebytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
|
||||||
break;
|
|
||||||
case svc_resourcelocation:
|
|
||||||
CL_ParseResLocation( msg );
|
|
||||||
break;
|
|
||||||
case svc_goldsrc_sendextrainfo:
|
case svc_goldsrc_sendextrainfo:
|
||||||
CL_ParseExtraInfo( msg );
|
CL_ParseExtraInfo( msg );
|
||||||
break;
|
break;
|
||||||
@@ -766,17 +676,8 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
||||||
MSG_ReadFloat( msg );
|
MSG_ReadFloat( msg );
|
||||||
break;
|
break;
|
||||||
case svc_querycvarvalue:
|
|
||||||
CL_ParseCvarValue( msg, false, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_querycvarvalue2:
|
|
||||||
CL_ParseCvarValue( msg, true, PROTO_GOLDSRC );
|
|
||||||
break;
|
|
||||||
case svc_exec:
|
|
||||||
CL_ParseExec( msg );
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
CL_ParseUserMessage( msg, cmd, PROTO_GOLDSRC );
|
||||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ GNU General Public License for more details.
|
|||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "pm_local.h"
|
#include "pm_local.h"
|
||||||
#include "particledef.h"
|
|
||||||
#include "studio.h"
|
#include "studio.h"
|
||||||
|
|
||||||
#define MAX_FORWARD 6 // forward probes for set idealpitch
|
#define MAX_FORWARD 6 // forward probes for set idealpitch
|
||||||
@@ -776,7 +775,7 @@ void CL_InitClientMove( void )
|
|||||||
clgame.pmove->COM_FileSize = COM_FileSize;
|
clgame.pmove->COM_FileSize = COM_FileSize;
|
||||||
clgame.pmove->COM_LoadFile = COM_LoadFile;
|
clgame.pmove->COM_LoadFile = COM_LoadFile;
|
||||||
clgame.pmove->COM_FreeFile = COM_FreeFile;
|
clgame.pmove->COM_FreeFile = COM_FreeFile;
|
||||||
clgame.pmove->memfgets = COM_MemFgets;
|
clgame.pmove->memfgets = Q_memfgets;
|
||||||
clgame.pmove->PM_PlaySound = pfnPlaySound;
|
clgame.pmove->PM_PlaySound = pfnPlaySound;
|
||||||
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
|
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
|
||||||
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
|
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
|
||||||
@@ -827,7 +826,6 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
|
|||||||
pmove->flFallVelocity = ps->flFallVelocity;
|
pmove->flFallVelocity = ps->flFallVelocity;
|
||||||
pmove->flSwimTime = (float)cd->flSwimTime;
|
pmove->flSwimTime = (float)cd->flSwimTime;
|
||||||
VectorCopy( cd->punchangle, pmove->punchangle );
|
VectorCopy( cd->punchangle, pmove->punchangle );
|
||||||
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
|
|
||||||
pmove->effects = ps->effects;
|
pmove->effects = ps->effects;
|
||||||
pmove->flags = cd->flags;
|
pmove->flags = cd->flags;
|
||||||
pmove->gravity = ps->gravity;
|
pmove->gravity = ps->gravity;
|
||||||
@@ -1011,6 +1009,11 @@ void CL_PredictMovement( qboolean repredicting )
|
|||||||
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
|
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// goldsrc checks for intermission here, so it technically allows sending commands
|
||||||
|
// during intermission but completely disables any client updates, predicted or not
|
||||||
|
if( cl.intermission )
|
||||||
|
return;
|
||||||
|
|
||||||
// this is the last frame received from the server
|
// this is the last frame received from the server
|
||||||
frame = &cl.frames[cl.parsecountmod];
|
frame = &cl.frames[cl.parsecountmod];
|
||||||
|
|
||||||
@@ -1098,7 +1101,7 @@ void CL_PredictMovement( qboolean repredicting )
|
|||||||
|
|
||||||
// now interpolate some fraction of the final frame
|
// now interpolate some fraction of the final frame
|
||||||
if( to_cmd->senttime != from_cmd->senttime )
|
if( to_cmd->senttime != from_cmd->senttime )
|
||||||
f = bound( 0.0, (host.realtime - from_cmd->senttime) / (to_cmd->senttime - from_cmd->senttime) * 0.1, 1.0 );
|
f = bound( 0.0, ( host.realtime - from_cmd->senttime ) / ( to_cmd->senttime - from_cmd->senttime ), 1.0 );
|
||||||
else f = 0.0;
|
else f = 0.0;
|
||||||
|
|
||||||
if( CL_PlayerTeleported( from, to ))
|
if( CL_PlayerTeleported( from, to ))
|
||||||
|
|||||||
@@ -16,11 +16,10 @@ GNU General Public License for more details.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "net_encode.h"
|
#include "net_encode.h"
|
||||||
#include "particledef.h"
|
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "shake.h"
|
#include "shake.h"
|
||||||
#include "hltv.h"
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "base_cmd.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STAT_HEALTH = 0,
|
STAT_HEALTH = 0,
|
||||||
@@ -188,7 +187,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
Con_Reportf( "Serverdata packet received.\n" );
|
Con_Reportf( "Serverdata packet received.\n" );
|
||||||
cls.timestart = Sys_DoubleTime();
|
cls.timestart = Platform_DoubleTime();
|
||||||
|
|
||||||
cls.demowaiting = false; // server is changed
|
cls.demowaiting = false; // server is changed
|
||||||
|
|
||||||
@@ -214,6 +213,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
||||||
clgame.maxModels = MAX_MODELS;
|
clgame.maxModels = MAX_MODELS;
|
||||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||||
|
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, ENGINE_QUAKE_COMPATIBLE );
|
||||||
|
|
||||||
// Re-init hud video, especially if we changed game directories
|
// Re-init hud video, especially if we changed game directories
|
||||||
clgame.dllFuncs.pfnVidInit();
|
clgame.dllFuncs.pfnVidInit();
|
||||||
@@ -239,9 +239,8 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
}
|
}
|
||||||
else Cvar_DirectSet( &r_decals, NULL );
|
else Cvar_DirectSet( &r_decals, NULL );
|
||||||
|
|
||||||
if( cl.background ) // tell the game parts about background state
|
// tell the game parts about background state
|
||||||
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
|
Cvar_DirectFullSet( &cl_background, cl.background ? "1" : "0", FCVAR_READ_ONLY );
|
||||||
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
|
||||||
|
|
||||||
S_StopBackgroundTrack ();
|
S_StopBackgroundTrack ();
|
||||||
|
|
||||||
@@ -267,7 +266,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
{
|
{
|
||||||
pResName = MSG_ReadString( msg );
|
pResName = MSG_ReadString( msg );
|
||||||
|
|
||||||
if( !COM_CheckString( pResName ))
|
if( COM_StringEmptyOrNULL( pResName ))
|
||||||
break; // end of list
|
break; // end of list
|
||||||
|
|
||||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||||
@@ -285,7 +284,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
{
|
{
|
||||||
pResName = MSG_ReadString( msg );
|
pResName = MSG_ReadString( msg );
|
||||||
|
|
||||||
if( !COM_CheckString( pResName ))
|
if( COM_StringEmptyOrNULL( pResName ))
|
||||||
break; // end of list
|
break; // end of list
|
||||||
|
|
||||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||||
@@ -840,7 +839,7 @@ static void CL_QuakeExecStuff( void )
|
|||||||
int argc = 0;
|
int argc = 0;
|
||||||
|
|
||||||
// check if no commands this frame
|
// check if no commands this frame
|
||||||
if( !COM_CheckString( text ))
|
if( COM_StringEmptyOrNULL( text ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
@@ -867,7 +866,13 @@ static void CL_QuakeExecStuff( void )
|
|||||||
if( argc == 0 )
|
if( argc == 0 )
|
||||||
{
|
{
|
||||||
// debug: find all missed commands and cvars to add them into QWrap
|
// debug: find all missed commands and cvars to add them into QWrap
|
||||||
if( !Cvar_Exists( token ) && !Cmd_Exists( token ))
|
cmdalias_t *alias;
|
||||||
|
cmd_t *cmd;
|
||||||
|
convar_t *cvar;
|
||||||
|
|
||||||
|
BaseCmd_FindAll( token, &cmd, &alias, &cvar );
|
||||||
|
|
||||||
|
if( !cvar && !cmd )
|
||||||
Con_Printf( S_WARN "'%s' is not exist\n", token );
|
Con_Printf( S_WARN "'%s' is not exist\n", token );
|
||||||
// else Msg( "cmd: %s\n", token );
|
// else Msg( "cmd: %s\n", token );
|
||||||
|
|
||||||
@@ -925,12 +930,12 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
// record command for debugging spew on parse problem
|
// record command for debugging spew on parse problem
|
||||||
CL_Parse_RecordCommand( cmd, bufStart );
|
CL_Parse_RecordCommand( cmd, bufStart );
|
||||||
|
|
||||||
|
if( CL_ParseCommonMessage( msg, PROTO_QUAKE, cmd, bufStart ))
|
||||||
|
continue;
|
||||||
|
|
||||||
// other commands
|
// other commands
|
||||||
switch( cmd )
|
switch( cmd )
|
||||||
{
|
{
|
||||||
case svc_nop:
|
|
||||||
// this does nothing
|
|
||||||
break;
|
|
||||||
case svc_disconnect:
|
case svc_disconnect:
|
||||||
CL_DemoCompleted ();
|
CL_DemoCompleted ();
|
||||||
break;
|
break;
|
||||||
@@ -942,9 +947,6 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
if( param1 != PROTOCOL_VERSION_QUAKE )
|
if( param1 != PROTOCOL_VERSION_QUAKE )
|
||||||
Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION_QUAKE );
|
Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION_QUAKE );
|
||||||
break;
|
break;
|
||||||
case svc_setview:
|
|
||||||
CL_ParseViewEntity( msg );
|
|
||||||
break;
|
|
||||||
case svc_sound:
|
case svc_sound:
|
||||||
CL_ParseQuakeSound( msg );
|
CL_ParseQuakeSound( msg );
|
||||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
@@ -969,9 +971,6 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||||
CL_ParseQuakeServerInfo( msg );
|
CL_ParseQuakeServerInfo( msg );
|
||||||
break;
|
break;
|
||||||
case svc_lightstyle:
|
|
||||||
CL_ParseLightStyle( msg, PROTO_QUAKE );
|
|
||||||
break;
|
|
||||||
case svc_updatename:
|
case svc_updatename:
|
||||||
param1 = MSG_ReadByte( msg );
|
param1 = MSG_ReadByte( msg );
|
||||||
Q_strncpy( cl.players[param1].name, MSG_ReadString( msg ), sizeof( cl.players[0].name ));
|
Q_strncpy( cl.players[param1].name, MSG_ReadString( msg ), sizeof( cl.players[0].name ));
|
||||||
@@ -1024,8 +1023,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
CL_ParseQuakeSignon( msg );
|
CL_ParseQuakeSignon( msg );
|
||||||
break;
|
break;
|
||||||
case svc_centerprint:
|
case svc_centerprint:
|
||||||
str = MSG_ReadString( msg );
|
CL_HudMessage( MSG_ReadString( msg ));
|
||||||
CL_DispatchUserMessage( "HudText", Q_strlen( str ), (void *)str );
|
|
||||||
break;
|
break;
|
||||||
case svc_killedmonster:
|
case svc_killedmonster:
|
||||||
CL_DispatchQuakeMessage( "KillMonster" ); // just an event
|
CL_DispatchQuakeMessage( "KillMonster" ); // just an event
|
||||||
@@ -1036,12 +1034,6 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
case svc_spawnstaticsound:
|
case svc_spawnstaticsound:
|
||||||
CL_ParseQuakeStaticSound( msg );
|
CL_ParseQuakeStaticSound( msg );
|
||||||
break;
|
break;
|
||||||
case svc_intermission:
|
|
||||||
cl.intermission = 1;
|
|
||||||
break;
|
|
||||||
case svc_finale:
|
|
||||||
CL_ParseFinaleCutscene( msg, 2 );
|
|
||||||
break;
|
|
||||||
case svc_cdtrack:
|
case svc_cdtrack:
|
||||||
param1 = MSG_ReadByte( msg );
|
param1 = MSG_ReadByte( msg );
|
||||||
param1 = bound( 0, param1, MAX_CDTRACKS - 1 ); // tracknum
|
param1 = bound( 0, param1, MAX_CDTRACKS - 1 ); // tracknum
|
||||||
@@ -1054,15 +1046,12 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
case svc_sellscreen:
|
case svc_sellscreen:
|
||||||
Cmd_ExecuteString( "help" ); // open quake menu
|
Cmd_ExecuteString( "help" ); // open quake menu
|
||||||
break;
|
break;
|
||||||
case svc_cutscene:
|
case svc_showlmp:
|
||||||
CL_ParseFinaleCutscene( msg, 3 );
|
CL_ParseNehahraShowLMP( msg );
|
||||||
break;
|
break;
|
||||||
case svc_hidelmp:
|
case svc_hidelmp:
|
||||||
CL_ParseNehahraHideLMP( msg );
|
CL_ParseNehahraHideLMP( msg );
|
||||||
break;
|
break;
|
||||||
case svc_showlmp:
|
|
||||||
CL_ParseNehahraShowLMP( msg );
|
|
||||||
break;
|
|
||||||
case svc_skybox:
|
case svc_skybox:
|
||||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user