mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-23 08:00:18 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a9075748e | ||
|
|
3733761696 | ||
|
|
cde7cbc3a3 | ||
|
|
e927da56cf | ||
|
|
3b8bffe39c | ||
|
|
19da377064 | ||
|
|
4d1380b5c4 | ||
|
|
25c2904d66 | ||
|
|
53565663d9 | ||
|
|
76f0e17987 | ||
|
|
5052449e38 | ||
|
|
a539da3200 | ||
|
|
fb875501f0 | ||
|
|
89d805ab92 | ||
|
|
7852929da3 | ||
|
|
595e6fcb8b | ||
|
|
a9792bd4c3 | ||
|
|
c19bc7e7a2 | ||
|
|
3e980ed371 | ||
|
|
a9a7c7fdb8 | ||
|
|
5baf5bccf2 | ||
|
|
981d72ac5a | ||
|
|
a9b8cdce64 | ||
|
|
f3222fc36a | ||
|
|
e5aee8d206 | ||
|
|
96d16bcbc1 | ||
|
|
010a5ffc74 | ||
|
|
bed9bbbd05 | ||
|
|
5cc168111c | ||
|
|
bdec6aab07 | ||
|
|
56cbab8661 | ||
|
|
29c3bece4e | ||
|
|
dc24a4a067 | ||
|
|
c4683e2417 | ||
|
|
11f5870a8b | ||
|
|
9de71e3529 | ||
|
|
81866d96e0 | ||
|
|
70fcc70348 | ||
|
|
1911f04079 | ||
|
|
b7288ba3f4 | ||
|
|
be655e2b9c | ||
|
|
915269e017 | ||
|
|
6071b5303c | ||
|
|
e59a24ded3 | ||
|
|
2239efa439 | ||
|
|
99fcec9f26 | ||
|
|
2fe4e85543 | ||
|
|
68f2635c06 | ||
|
|
0147677412 | ||
|
|
89133bf05d | ||
|
|
7a0a671f18 | ||
|
|
c7d1f42edb | ||
|
|
2b9d31fe7f | ||
|
|
1f71bb714d | ||
|
|
6b21f7e92e | ||
|
|
8b5074b6ac | ||
|
|
7f7d797fce | ||
|
|
0b3aad5ad2 | ||
|
|
ad88215b85 | ||
|
|
ccb1465e17 | ||
|
|
fde4d8d54f | ||
|
|
37db2e8acc | ||
|
|
9413eb0d58 | ||
|
|
06d2eaf409 | ||
|
|
444ce284ae | ||
|
|
a150c1b18b | ||
|
|
194e898d90 | ||
|
|
0b1a20dcff | ||
|
|
93e7561cb3 | ||
|
|
6ab654264b | ||
|
|
7023184892 | ||
|
|
07f13d1ae9 | ||
|
|
ac22b1cfbf | ||
|
|
e70cdfb898 | ||
|
|
022181fcfd | ||
|
|
e021289d36 | ||
|
|
91b80a8e21 | ||
|
|
322ca2b42e | ||
|
|
d399ffd609 | ||
|
|
bf2626f804 | ||
|
|
00f27ac02d | ||
|
|
5134aed352 | ||
|
|
b457a84ed9 | ||
|
|
8188d46ee7 | ||
|
|
d64e88451f | ||
|
|
c70c578194 | ||
|
|
54ceff5107 | ||
|
|
3b94904ea8 | ||
|
|
1c8b4a1922 | ||
|
|
32b0b2dfac | ||
|
|
6506577787 | ||
|
|
56775399d3 | ||
|
|
d6d40975e5 | ||
|
|
e3936f52a2 | ||
|
|
53d5dd1e40 | ||
|
|
b2ef0fd6e3 | ||
|
|
8832fbe55d | ||
|
|
b5ffe756d6 | ||
|
|
01a0173a2f | ||
|
|
7bebb2adab | ||
|
|
8c41576daa | ||
|
|
a529b37f25 | ||
|
|
f84ed6b794 | ||
|
|
9526a92fc1 | ||
|
|
5e60b89a0d | ||
|
|
e46625a52c | ||
|
|
037cb0f5cb | ||
|
|
f67a7c6621 | ||
|
|
4839a2026b | ||
|
|
219dbbb5b7 | ||
|
|
d78de51bc2 | ||
|
|
faa50352e0 | ||
|
|
f2b49f7ccb | ||
|
|
13911b051a | ||
|
|
694167d352 | ||
|
|
3b2e4ff9c1 | ||
|
|
16e0dc17a8 | ||
|
|
1f4b7718e8 | ||
|
|
8c59d6020e | ||
|
|
377b0896c2 | ||
|
|
a399fdf6cf | ||
|
|
783c24d6f7 | ||
|
|
1254146223 | ||
|
|
f776d842d1 | ||
|
|
74acf35a89 | ||
|
|
81b8fe3f61 | ||
|
|
679bfb90ea | ||
|
|
deb18c53b7 | ||
|
|
bbb7aa3771 | ||
|
|
eb04e26823 | ||
|
|
3af24ee0ea | ||
|
|
513fe7773f | ||
|
|
9150d1cc44 | ||
|
|
e19b72647e | ||
|
|
d809975882 | ||
|
|
7b92d99afa | ||
|
|
b463c905cf | ||
|
|
7f8a0c9931 | ||
|
|
53d812666c | ||
|
|
7b59f07181 | ||
|
|
d22dea5e8e | ||
|
|
8817467216 | ||
|
|
236afa7c3f | ||
|
|
cd6ec5e3a7 | ||
|
|
434aaf3eaf | ||
|
|
5b80ea20c7 | ||
|
|
1d60405eaa | ||
|
|
64f4f59165 | ||
|
|
192f9ac514 | ||
|
|
279b1413ec | ||
|
|
9c5297882c | ||
|
|
a6d508d791 | ||
|
|
6b3402c631 | ||
|
|
d5da32b8a9 | ||
|
|
39b3ed3d44 | ||
|
|
f8b97405ff | ||
|
|
1d4fe357c8 | ||
|
|
c7900b6048 | ||
|
|
6e3f959684 | ||
|
|
eb9a3b1bbf | ||
|
|
391450f090 | ||
|
|
f804476fbc | ||
|
|
60e4fa7005 | ||
|
|
c13f9dc9a8 | ||
|
|
f213943b2d | ||
|
|
5159a534bb | ||
|
|
c7a4e705cb | ||
|
|
864ea08393 | ||
|
|
ebfb6d1846 | ||
|
|
6b89ec615a | ||
|
|
af432e6d3f | ||
|
|
44c17409a7 | ||
|
|
0f48c39bc1 | ||
|
|
572e6652cc | ||
|
|
fecb601fc4 | ||
|
|
7b238e9d34 | ||
|
|
73c8ff11b3 | ||
|
|
682dc89067 | ||
|
|
ee514710c5 | ||
|
|
2d15696a5e | ||
|
|
769d06b0f0 | ||
|
|
dcb0369e10 | ||
|
|
1b35d3ce05 | ||
|
|
31d254cb9f | ||
|
|
bf4780bbdb | ||
|
|
5af8e127f8 | ||
|
|
016e062fef | ||
|
|
c093122764 | ||
|
|
11ec6270da | ||
|
|
81df55310b | ||
|
|
e5fb85ad08 | ||
|
|
c5ef60040a | ||
|
|
757b4849f8 | ||
|
|
2198bdec21 | ||
|
|
8bd377ce85 | ||
|
|
89eae68318 | ||
|
|
d1e94f3934 | ||
|
|
fc0a995c66 | ||
|
|
eee0eaac4a | ||
|
|
535da856a4 | ||
|
|
422bf647a7 | ||
|
|
93cd470659 | ||
|
|
81b86d61da | ||
|
|
eac8580f64 | ||
|
|
d56498e622 | ||
|
|
551fccb761 | ||
|
|
5317b8424f | ||
|
|
5816391e9b | ||
|
|
543c00037a | ||
|
|
d5f435ee90 | ||
|
|
02e2e92d36 | ||
|
|
040f8db0ef | ||
|
|
14927df9fa | ||
|
|
dca9709b12 | ||
|
|
d6571820fe | ||
|
|
a0d3333ebb | ||
|
|
9615fafc1e | ||
|
|
5fc2425f3a | ||
|
|
63445c4fc1 | ||
|
|
eefe8ee2d1 | ||
|
|
edb1cb0ebe | ||
|
|
140242a761 | ||
|
|
ae13be0c37 | ||
|
|
74ff3b920e | ||
|
|
2cd6b981f1 | ||
|
|
f866dcbcfc | ||
|
|
0d394a7e67 | ||
|
|
7059f32ecc | ||
|
|
87baa69d7c | ||
|
|
408c901342 | ||
|
|
d709dda87a | ||
|
|
cda6225659 | ||
|
|
563182c14c | ||
|
|
303ed30a38 | ||
|
|
0a6c745ffb | ||
|
|
9d654faa3d | ||
|
|
9407b64fe3 | ||
|
|
1f0f5764a8 | ||
|
|
13197acb3a | ||
|
|
2f48ca6adb | ||
|
|
01d938b5ba | ||
|
|
186d7a12e5 | ||
|
|
5192d36f81 | ||
|
|
dfb6c37c9e | ||
|
|
cb208b9ad2 | ||
|
|
e4d20c3fa1 | ||
|
|
0b747bf1c5 | ||
|
|
e207715b5e | ||
|
|
bef1b456e1 | ||
|
|
11349f9ad5 | ||
|
|
2a485a6b69 | ||
|
|
f41e92de6e | ||
|
|
835c0b0d9a | ||
|
|
d9dc34f06d | ||
|
|
907ff36018 | ||
|
|
64626a767c | ||
|
|
a7df73073d | ||
|
|
40492daecd | ||
|
|
a5691d7779 | ||
|
|
d1ecd4a3c8 | ||
|
|
5482b31c66 | ||
|
|
15f2f6c798 | ||
|
|
46b3f4eb5e | ||
|
|
f5aadbb788 | ||
|
|
bbb54ea36d | ||
|
|
d7a5eb5d2f | ||
|
|
cc716c3fa4 | ||
|
|
141574a0d7 | ||
|
|
2df8ed10d0 | ||
|
|
40e3977664 | ||
|
|
7ddee0100e | ||
|
|
6b869c4c0d | ||
|
|
91497d8fa7 | ||
|
|
85bf56ae03 | ||
|
|
84d702838d | ||
|
|
fd3a36f162 | ||
|
|
10e3192f85 | ||
|
|
de874874e4 | ||
|
|
72e315bce1 | ||
|
|
02ef85e390 | ||
|
|
aeba0e0f6f | ||
|
|
f8fa944054 | ||
|
|
1d50fa088a | ||
|
|
546ded324e | ||
|
|
332a635031 | ||
|
|
de02c868a2 | ||
|
|
a74b966b7c | ||
|
|
ca4b1ebdee | ||
|
|
42c20ac008 | ||
|
|
a26e5b74c2 | ||
|
|
ee5faedaf9 | ||
|
|
874b034698 | ||
|
|
dfb2cb6bbf | ||
|
|
fb15f0f2b3 | ||
|
|
4d231fbc50 | ||
|
|
dd85118a9c | ||
|
|
531340627d | ||
|
|
6b6e5291dd | ||
|
|
79b0e6998d | ||
|
|
445814b144 | ||
|
|
ebb3173322 | ||
|
|
c16f2029b1 | ||
|
|
abefdd772c | ||
|
|
e550d244df | ||
|
|
84cc66ad48 | ||
|
|
fa5a97031d | ||
|
|
6e454cdfb3 | ||
|
|
52f43a3aa6 | ||
|
|
907aa21ba8 | ||
|
|
ac01ad6751 | ||
|
|
c84702b490 | ||
|
|
edd2a9d8f6 | ||
|
|
a19c7afce0 | ||
|
|
849f1ee7d1 | ||
|
|
c60c2c09e1 | ||
|
|
3254b3f044 | ||
|
|
9a35d34fc3 | ||
|
|
4da5e26cdc | ||
|
|
8a28ad0c36 | ||
|
|
e08b2fe382 | ||
|
|
8b16e94829 | ||
|
|
618223f01b | ||
|
|
13c63d3e1f | ||
|
|
8e0aa5185b | ||
|
|
2b01f092b3 | ||
|
|
1fd238567e | ||
|
|
cb59edc963 | ||
|
|
0ce70b9f8f | ||
|
|
57175cfa5c | ||
|
|
8aacdcefb8 | ||
|
|
69766ae87a | ||
|
|
d3d2082e41 | ||
|
|
de621f6acb | ||
|
|
a7c5067475 | ||
|
|
7282426736 | ||
|
|
0333fd86f8 | ||
|
|
ab91ade685 | ||
|
|
005afcd53d | ||
|
|
c1604c0c8c | ||
|
|
5155c10136 | ||
|
|
28c6e3b398 | ||
|
|
41244095b1 | ||
|
|
a5535fa789 | ||
|
|
6796a8b3fe | ||
|
|
819dffcb86 | ||
|
|
b54db17069 | ||
|
|
e27f2443e8 | ||
|
|
a1e0bc5d7c | ||
|
|
28ea95b9ff | ||
|
|
e3b9e48d8c | ||
|
|
026b6b2562 | ||
|
|
0fa380ecff | ||
|
|
ebd885f053 | ||
|
|
74ccb03e54 | ||
|
|
50264c4968 | ||
|
|
be222b64a1 | ||
|
|
db7ae4ffef | ||
|
|
884a76db4c | ||
|
|
18e5c6e714 | ||
|
|
468341b7d0 | ||
|
|
e03b976ffd | ||
|
|
34ea099d87 | ||
|
|
5f2827e2ab | ||
|
|
1d887b4655 | ||
|
|
6250380f61 | ||
|
|
6bb475abe7 | ||
|
|
31ea951357 | ||
|
|
091c8b4d12 | ||
|
|
c4523db991 | ||
|
|
2b66672d2d | ||
|
|
77de0b78ba | ||
|
|
0181fbcfa0 | ||
|
|
e1f2433c36 | ||
|
|
c753dcafd8 | ||
|
|
57ac7d8c19 | ||
|
|
d64ef13b79 | ||
|
|
911e87c6ec | ||
|
|
b75c7b64f1 | ||
|
|
135b519dd8 | ||
|
|
b7a0607d52 | ||
|
|
2ee1a2099d | ||
|
|
7fe7e74fe2 | ||
|
|
0a3a23af41 | ||
|
|
e89262ed3b | ||
|
|
21fda4cabd | ||
|
|
a85694b548 | ||
|
|
16464c5a68 | ||
|
|
85c8769512 | ||
|
|
c3abbd9014 | ||
|
|
98239050d8 | ||
|
|
dc7caf04a8 | ||
|
|
db01f72adc | ||
|
|
170b4b0972 | ||
|
|
ff6e81d44f | ||
|
|
88bc0e1e85 | ||
|
|
c5b46529b0 | ||
|
|
e5dbfba55e | ||
|
|
daa7aceecf | ||
|
|
35681e7a1f | ||
|
|
d4dfde3340 | ||
|
|
05a6b43e08 | ||
|
|
16f775c78c | ||
|
|
af919dadca | ||
|
|
41c322ec81 | ||
|
|
ac8c18250d | ||
|
|
4b05c400b2 | ||
|
|
cc85d0c100 | ||
|
|
56dce21538 | ||
|
|
3cd5acf3aa | ||
|
|
48fc5a72b8 | ||
|
|
26c3375112 | ||
|
|
e89543710c | ||
|
|
ee48193f15 | ||
|
|
6d10ed27c5 | ||
|
|
19c68aa25d | ||
|
|
5ee7cb16bb | ||
|
|
4630a1f386 | ||
|
|
06dab5d8b0 | ||
|
|
054201bea9 | ||
|
|
f39a4c0bc7 | ||
|
|
0e20d7e880 | ||
|
|
927f4bb4bd | ||
|
|
f9901787b5 | ||
|
|
6731f56aea | ||
|
|
d6870ecbee | ||
|
|
eea8c42268 | ||
|
|
99647e677a | ||
|
|
a5d637dbb3 | ||
|
|
048a973290 | ||
|
|
fa80e0bd75 | ||
|
|
a23de7b361 | ||
|
|
dc60cb45b2 | ||
|
|
2bf1144a14 | ||
|
|
ab5efa5a64 | ||
|
|
ccc98e4c62 | ||
|
|
52424f63f0 | ||
|
|
881df7193b | ||
|
|
e859bba61d | ||
|
|
e3beec985e | ||
|
|
9eec50d69f | ||
|
|
5a8cc83e6e | ||
|
|
724aeb22ed | ||
|
|
6fdc756b59 | ||
|
|
25418b7857 | ||
|
|
b4de0b53e4 | ||
|
|
cacf1ca1b7 | ||
|
|
98c61529b9 | ||
|
|
6675a491be | ||
|
|
b6485ad7db | ||
|
|
9f5df368d1 | ||
|
|
e970e29953 | ||
|
|
9fb559bdb1 | ||
|
|
61e9146385 | ||
|
|
897c2322b9 | ||
|
|
7b8be9fed1 | ||
|
|
cebb351505 | ||
|
|
b4bce3431b | ||
|
|
c6e3dfdbe6 | ||
|
|
22d2790735 | ||
|
|
5d3b76b249 | ||
|
|
7b07be1502 | ||
|
|
3acb796b59 | ||
|
|
25bbc1793d | ||
|
|
63456beeb0 | ||
|
|
2e32395cf2 | ||
|
|
d04ed0aace | ||
|
|
302f06f8d2 | ||
|
|
4cf4ca2943 | ||
|
|
fe35e02ed4 | ||
|
|
5fa1b98d34 | ||
|
|
bebe117487 | ||
|
|
26495fe0f8 | ||
|
|
4c4ac9f90e | ||
|
|
bf5fdb8f06 | ||
|
|
01e68fd5ee | ||
|
|
e930b5481a | ||
|
|
9bd4d40f09 | ||
|
|
40035f4df3 | ||
|
|
a7b3fdd70b | ||
|
|
b77af7fced | ||
|
|
52c89f1de3 | ||
|
|
e7cd70b8ee | ||
|
|
e06ee0f26a | ||
|
|
76c9e4e048 | ||
|
|
06d8ddbfc7 | ||
|
|
8b9840d37f | ||
|
|
960469be77 | ||
|
|
77ef0f3579 | ||
|
|
07c840a4a9 | ||
|
|
35a8c4edfa | ||
|
|
36af9e6589 | ||
|
|
ea14ab5664 | ||
|
|
1ed8538745 | ||
|
|
12e36b987a | ||
|
|
8324c599de | ||
|
|
d972c85fba | ||
|
|
d8b9abe7f5 | ||
|
|
4f868d9585 | ||
|
|
e27ac45f44 | ||
|
|
58d0e43f78 | ||
|
|
a6c1cbfd50 | ||
|
|
e32222884d | ||
|
|
49a7a1f8ff | ||
|
|
e5275c0f05 | ||
|
|
c391605f61 | ||
|
|
73c9e6f1d8 | ||
|
|
2d6ac6f0be | ||
|
|
57870103a6 | ||
|
|
64604b5c44 | ||
|
|
9960884e3c | ||
|
|
593982d586 | ||
|
|
f229c1c5a8 | ||
|
|
35e9f9982c | ||
|
|
a0cb46d4a1 | ||
|
|
e8a48184b9 | ||
|
|
d2aa26248f | ||
|
|
0f1de72ae6 | ||
|
|
efaea69c09 | ||
|
|
a67dbff603 | ||
|
|
35e6435382 | ||
|
|
7a2735885f | ||
|
|
cc721a3db6 | ||
|
|
1a5cac2c6a | ||
|
|
ef08f1c8f3 | ||
|
|
8919890dbe | ||
|
|
cf6335d180 | ||
|
|
a86a707e4a | ||
|
|
9d61993878 | ||
|
|
6eb20a3524 | ||
|
|
7314543c88 | ||
|
|
bb4b10d752 | ||
|
|
416c568c51 | ||
|
|
65d3a51a17 | ||
|
|
e55f5902d5 | ||
|
|
b0180383df | ||
|
|
61f0fc665f | ||
|
|
b0c1d79132 | ||
|
|
7945c2ca66 | ||
|
|
8b2b1a9a47 | ||
|
|
b76f9a9a6c | ||
|
|
8af5da5fca | ||
|
|
cbe6d85bcd | ||
|
|
6b6e2c947c | ||
|
|
66fcc2cd14 | ||
|
|
af829772f9 | ||
|
|
7b6a558fe5 | ||
|
|
4122ee4168 | ||
|
|
b77f62ab58 | ||
|
|
783bf1b63c | ||
|
|
a0728b4a8a | ||
|
|
ea6e865cc8 | ||
|
|
1da4113110 | ||
|
|
7956746b65 | ||
|
|
10a8d13ade | ||
|
|
65b47a2b3a | ||
|
|
46cc00d669 | ||
|
|
5521cf9ab3 | ||
|
|
a770df1e0b | ||
|
|
03943a23ac | ||
|
|
685dc0336a | ||
|
|
776012fedf | ||
|
|
6ba9f2655c | ||
|
|
8a3b62e93f | ||
|
|
bd999a6d9c | ||
|
|
f46078965d | ||
|
|
60f6bb17e3 | ||
|
|
fdf1dac618 | ||
|
|
373a35acf0 | ||
|
|
abfdac59ba | ||
|
|
efc1354dcb | ||
|
|
c9f2603692 | ||
|
|
aab24260e2 | ||
|
|
e450156bf7 | ||
|
|
1533c02a41 | ||
|
|
c4855029a9 | ||
|
|
4fa457118f | ||
|
|
33b403d6eb | ||
|
|
a5c6654dcb | ||
|
|
07ec6adecb | ||
|
|
ceb901e9ca | ||
|
|
651b86b066 | ||
|
|
a4003dd61c | ||
|
|
5e461786f9 | ||
|
|
45108c6f4b | ||
|
|
bc0d373dcd | ||
|
|
0f37a8f6ea | ||
|
|
03ceaf82ce | ||
|
|
1e5e5e24f6 | ||
|
|
eb993dbd43 | ||
|
|
4f5abb3412 | ||
|
|
6418d79d76 | ||
|
|
796a3a711f | ||
|
|
0ef743d945 | ||
|
|
7c33f98ae9 | ||
|
|
51ba1e2951 | ||
|
|
0b16d599d5 | ||
|
|
3b2223ad22 | ||
|
|
186583148a | ||
|
|
5475624b7f | ||
|
|
d5be69239a | ||
|
|
304645d720 | ||
|
|
0591152f99 | ||
|
|
74e8a38c00 | ||
|
|
5cadab46ab | ||
|
|
1577927d99 | ||
|
|
5a0aeb2f88 | ||
|
|
7a1f7773bf | ||
|
|
b0e597cf55 | ||
|
|
c40d073d7a | ||
|
|
dd8b3f607a | ||
|
|
5cc599984d | ||
|
|
b95b8c4c20 | ||
|
|
3e190ca4b3 | ||
|
|
3853d1ef39 | ||
|
|
bf700186d0 | ||
|
|
ca7cacfdcc | ||
|
|
b893f4f89f | ||
|
|
109686aca2 | ||
|
|
6840df4eca | ||
|
|
ed3f212bd8 | ||
|
|
e1f2a51f2b | ||
|
|
d3870309fb | ||
|
|
1fa2031f11 | ||
|
|
1d765125c7 | ||
|
|
5aa70d91f3 | ||
|
|
f018c2c15a | ||
|
|
1b8ad12b25 | ||
|
|
078aa01895 | ||
|
|
f0aad4bb21 | ||
|
|
8fe054b063 | ||
|
|
ac63e6c627 | ||
|
|
434a48af7d | ||
|
|
c5dcf96717 | ||
|
|
84791c42bc | ||
|
|
e032a1a627 | ||
|
|
1f2b5dcc86 | ||
|
|
8bd30ffb22 | ||
|
|
fbf67fccc3 | ||
|
|
b848ee0fac | ||
|
|
4a39e5411f | ||
|
|
336ba6181e | ||
|
|
c9aedf242d | ||
|
|
500c70016f | ||
|
|
cf1dbf07c7 | ||
|
|
13ec3435b4 | ||
|
|
fce0f7b357 | ||
|
|
0fabdc8c44 | ||
|
|
2174f2ff85 | ||
|
|
ac40373c09 | ||
|
|
d5908bd75c | ||
|
|
8cf3be3526 | ||
|
|
0290fa3351 | ||
|
|
937f3993ec | ||
|
|
d501285057 | ||
|
|
0ed92943de | ||
|
|
56044dd8f8 | ||
|
|
e8109076f4 | ||
|
|
0a31ab7558 | ||
|
|
e73be7ef5c | ||
|
|
aa209e0aaf | ||
|
|
570dddddd8 | ||
|
|
534176423e | ||
|
|
ca2c2fb8fe | ||
|
|
4388b7b187 | ||
|
|
368f94ce3b | ||
|
|
e7fd0f7419 | ||
|
|
92f7c3633f | ||
|
|
bf27caa61e | ||
|
|
808916029e | ||
|
|
5f3ee10bc0 | ||
|
|
45f50cfe25 | ||
|
|
42c0605abf | ||
|
|
f83839e01b | ||
|
|
24dbc1ce4e | ||
|
|
d8505eff2b | ||
|
|
bca71ade85 | ||
|
|
7518d7b418 | ||
|
|
3f8aeac7e6 | ||
|
|
c4a9a87929 | ||
|
|
7eca455795 | ||
|
|
cb9ac23b23 | ||
|
|
4a66a41f91 | ||
|
|
665c35d089 | ||
|
|
0a634c633b | ||
|
|
eb70b30e7a | ||
|
|
8d188073b4 | ||
|
|
ceea855c6f | ||
|
|
9b7f192dce | ||
|
|
23a866f6f8 | ||
|
|
946a7a406c | ||
|
|
e209290073 | ||
|
|
2c441ee541 | ||
|
|
dd768ec9ef | ||
|
|
adaeaea596 | ||
|
|
5a44740592 | ||
|
|
97a0bd90ec | ||
|
|
92ee1d9caf | ||
|
|
9ab28dc7da | ||
|
|
840501c8dd | ||
|
|
ef4b79b1f5 | ||
|
|
b6b35079ef | ||
|
|
b8e8aead93 | ||
|
|
dd378db4d0 | ||
|
|
cc048f5099 | ||
|
|
ac02afaae6 | ||
|
|
bff58ae615 | ||
|
|
748934edcd | ||
|
|
d9fb375812 | ||
|
|
55582a85ab | ||
|
|
9255c5259d | ||
|
|
f1e2a45520 | ||
|
|
cb9e69238c | ||
|
|
56b2971dee | ||
|
|
ad917d96c8 | ||
|
|
1fd7bd3fa5 | ||
|
|
1234bd89c7 | ||
|
|
187ee87f10 | ||
|
|
5ae88b816d | ||
|
|
3418691f88 | ||
|
|
4e8a51db81 | ||
|
|
2629ef17c3 | ||
|
|
9b63625c2b | ||
|
|
970d72cf07 | ||
|
|
d88870bc04 | ||
|
|
9b35e13923 | ||
|
|
032eb11cfb | ||
|
|
9ea7b77231 | ||
|
|
318dc18891 | ||
|
|
8d327cd0a0 | ||
|
|
d3de937ee0 | ||
|
|
3be1673eb9 | ||
|
|
13f23ace76 | ||
|
|
26c50f15dc | ||
|
|
46aa58d0cd | ||
|
|
aac9dd40de | ||
|
|
71dba1b7dc | ||
|
|
8b85e4e075 | ||
|
|
028489d673 | ||
|
|
5c4c14a17d | ||
|
|
2e10a96d11 | ||
|
|
09ad42ba47 | ||
|
|
88ccaee5cc | ||
|
|
e936a0b995 | ||
|
|
ff5b0b7607 | ||
|
|
edd2fd5e63 | ||
|
|
08d97e0277 | ||
|
|
21d0675035 | ||
|
|
1dfb81917c | ||
|
|
af8c92f090 | ||
|
|
04e0242422 | ||
|
|
110ffc3a01 | ||
|
|
6b4a8bd627 | ||
|
|
0d851fdb68 | ||
|
|
5064f2c16d | ||
|
|
ac46d0eef0 | ||
|
|
70c71b69ee | ||
|
|
4487113c58 | ||
|
|
983f5b9ca4 | ||
|
|
13612d3de9 | ||
|
|
6317ca7183 | ||
|
|
2b96aac1c8 | ||
|
|
a6b75aefa4 | ||
|
|
7dc72b435e | ||
|
|
5a586f4700 | ||
|
|
ef50a5f2cd | ||
|
|
c2c3f6aa1b | ||
|
|
9c8ca98e68 | ||
|
|
3a18c9f327 | ||
|
|
9438f6497d | ||
|
|
5c3c3f8e70 | ||
|
|
3d3c99cd22 | ||
|
|
b3464e620e | ||
|
|
72a38b0b68 | ||
|
|
46e7f29820 | ||
|
|
cb36015a38 | ||
|
|
66cb10a3bf | ||
|
|
bfdd99a028 | ||
|
|
63ef75222e | ||
|
|
072ba0a38f | ||
|
|
576869bda0 | ||
|
|
0d556b1b40 | ||
|
|
0cd217b484 | ||
|
|
907255837e | ||
|
|
ebf33349a3 | ||
|
|
ea6920b711 | ||
|
|
53a47d470a | ||
|
|
7fe7b6ce79 | ||
|
|
0110704abd | ||
|
|
aca23fc62f | ||
|
|
c0a284927e | ||
|
|
2d911c37a4 | ||
|
|
1e7af27227 | ||
|
|
06678a8b0a | ||
|
|
e1706610c4 | ||
|
|
7bb940d819 | ||
|
|
b4e0120428 | ||
|
|
db1013d926 | ||
|
|
759dacd345 | ||
|
|
903fd28953 | ||
|
|
6c520babf0 | ||
|
|
9bb2fda6df | ||
|
|
d48b37ece1 | ||
|
|
f4164e84e1 | ||
|
|
33aabadaf5 | ||
|
|
e815fda908 | ||
|
|
fe04adee1d | ||
|
|
115647a8c0 | ||
|
|
ddd70eadf6 | ||
|
|
319e00214e | ||
|
|
6bdcfc2b6f | ||
|
|
ae0a2238da | ||
|
|
a69f9fe88b | ||
|
|
696b57f990 | ||
|
|
998c1b78c7 | ||
|
|
8c207f094d | ||
|
|
09c9c0ef51 | ||
|
|
8cd571c96c | ||
|
|
979af2925d | ||
|
|
f092eab842 | ||
|
|
3d4832ca85 | ||
|
|
b120fc6f2f | ||
|
|
c299ad92aa | ||
|
|
956cd59385 | ||
|
|
acbd802790 | ||
|
|
c4bcecf5e0 | ||
|
|
09949251ac | ||
|
|
43218f1685 | ||
|
|
eb7d01b3e7 | ||
|
|
c58e6d58b4 | ||
|
|
3a892e1a47 | ||
|
|
5bb487e1fa | ||
|
|
4ae091be4b | ||
|
|
7654ab6be6 | ||
|
|
193cc9dc10 | ||
|
|
a6d268e1a1 | ||
|
|
7822e94e61 | ||
|
|
eb663fdbc1 | ||
|
|
c738a40c05 | ||
|
|
2ca3443b7f | ||
|
|
06be4c03fa | ||
|
|
32d77f4a7d | ||
|
|
d217b1d561 | ||
|
|
0167f0a3a4 | ||
|
|
4304ad0faa | ||
|
|
3be17376e4 | ||
|
|
0b4fd4c17e | ||
|
|
66c4499b2e | ||
|
|
cde13177a4 | ||
|
|
9fce2575ab | ||
|
|
8f8e92c8c3 | ||
|
|
8683d317fe | ||
|
|
1178c619bc | ||
|
|
2fa568eb01 | ||
|
|
d62242d653 | ||
|
|
991bf2f1f5 | ||
|
|
2f241343ff | ||
|
|
035de09c15 | ||
|
|
d3a4407391 | ||
|
|
395c16ce24 | ||
|
|
f7accc01ad | ||
|
|
3733154e63 | ||
|
|
2ef95ddba9 | ||
|
|
043f8cba22 | ||
|
|
09ab172630 | ||
|
|
c23a182bec | ||
|
|
c321470382 | ||
|
|
932bdd402c | ||
|
|
3692671f49 | ||
|
|
1cd4c35a79 | ||
|
|
c0f7a48649 | ||
|
|
c1258f160b | ||
|
|
bdb9feb7c5 | ||
|
|
830cbe7af2 | ||
|
|
4eb83c0766 | ||
|
|
210f2fef77 | ||
|
|
d19a6160d2 | ||
|
|
cd773cf73f | ||
|
|
f3b9a10f7a | ||
|
|
709283ff33 | ||
|
|
fae261d7da | ||
|
|
6b5e527b6b | ||
|
|
b7005a310e | ||
|
|
edd25b9264 | ||
|
|
65a8b03ee4 | ||
|
|
0044ec0ac0 | ||
|
|
73111d854d | ||
|
|
065ab98175 | ||
|
|
cbeaeba828 | ||
|
|
7af2a9444e | ||
|
|
f476f3690a | ||
|
|
fae02da4b1 | ||
|
|
b0e4e29ce3 | ||
|
|
11f7728b9d | ||
|
|
7510b05d25 | ||
|
|
e467f91262 | ||
|
|
b03afb899d | ||
|
|
ec71ff3c3c | ||
|
|
02ce50ace2 | ||
|
|
4a4a552a05 | ||
|
|
5b3615d262 | ||
|
|
2821488c93 | ||
|
|
9814887b10 | ||
|
|
3f86381541 | ||
|
|
7736966dc1 |
No files matched your search
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots (OPTIONAL)**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Logs**
|
||||
- Paste the output of the console window in a text file, and attach the text file.
|
||||
- If applicable (`logfile` set to 2), attach the `qconsole.log` file. On Windows, it can be found in **%APPDATA%\...\qconsole.log** and on Linux, it can be found on the home directory **~/.openmohaa/.../qconsole.log**.
|
||||
|
||||
**Version information (please complete the following information):**
|
||||
- OS: [e.g. `Debian`]
|
||||
- OS Version [e.g `12`]
|
||||
- OpenMoHAA Version: [e.g `0.70.0-alpha+0.0b1a20dcf win_msvc64-x86_64-debug`, can be found below **Common Initialization** in the console, or by typing `version`]
|
||||
|
||||
**Dump (OPTIONAL)**
|
||||
You can include a core dump generated by the OS (`.dmp` file). If you compiled OpenMoHAA yourself, also add all output openmohaa binaries (except libopenal and libSDL).
|
||||
|
||||
**Additional context (OPTIONAL)**
|
||||
Add any other context about the problem here.
|
||||
@@ -2,6 +2,8 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
@@ -18,10 +20,13 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'amd64', triple: 'x86_64-linux-gnu'},
|
||||
{name: 'i686', triple: 'i686-linux-gnu'},
|
||||
{name: 'aarch64', triple: 'aarch64-linux-gnu'},
|
||||
{name: 'armhf', triple: 'arm-linux-gnueabihf'}
|
||||
{name: 'amd64', triple: 'x86_64-linux-gnu'},
|
||||
{name: 'i686', triple: 'i686-linux-gnu'},
|
||||
{name: 'arm64', triple: 'aarch64-linux-gnu'},
|
||||
{name: 'armhf', triple: 'arm-linux-gnueabihf'},
|
||||
{name: 'powerpc', triple: 'powerpc-linux-gnu'},
|
||||
{name: 'ppc64', triple: 'powerpc64-linux-gnu'},
|
||||
{name: 'ppc64el', triple: 'powerpc64le-linux-gnu'}
|
||||
]
|
||||
|
||||
name: "Building for platform linux-${{matrix.architecture.name}}"
|
||||
@@ -36,7 +41,8 @@ jobs:
|
||||
|
||||
- name: Install required packages
|
||||
run: |
|
||||
sudo apt update && sudo apt install -y flex bison
|
||||
sudo apt update && sudo apt install -y flex bison \
|
||||
libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
|
||||
|
||||
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
if: matrix.architecture.name != 'amd64'
|
||||
@@ -54,7 +60,27 @@ jobs:
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
# soft-oal setup
|
||||
# Use GCC instead of Clang because of missing SSE intrinsics
|
||||
# It also doesn't enable altivec support on PowerPC by default
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.23.1'
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DCMAKE_C_COMPILER=${{ matrix.architecture.triple }}-gcc-12 \
|
||||
-DCMAKE_CXX_COMPILER=${{ matrix.architecture.triple }}-g++-12
|
||||
cmake --build ./build --config ${{env.BUILD_TYPE}}
|
||||
cmake --install ./build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
@@ -67,6 +93,8 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
@@ -92,9 +120,11 @@ jobs:
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
cp '${{steps.sdl.outputs.prefix}}/lib/libSDL2.so' '${{github.workspace}}/install'
|
||||
# Create hard-link and copy symbolic links
|
||||
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/install/'
|
||||
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/install/'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-linux-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
@@ -119,7 +149,7 @@ jobs:
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
|
||||
|
||||
# Setup SDL
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
@@ -137,7 +167,38 @@ jobs:
|
||||
cmake --build winflexbison-build --config Release --parallel
|
||||
cmake --install winflexbison-build
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
# soft-oal setup
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.23.1'
|
||||
|
||||
# soft-oal build
|
||||
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build -A ${{ matrix.architecture.config }} `
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' `
|
||||
-DALSOFT_BUILD_ROUTER=OFF `
|
||||
-DALSOFT_REQUIRE_WINMM=ON `
|
||||
-DALSOFT_REQUIRE_DSOUND=ON `
|
||||
-DALSOFT_REQUIRE_WASAPI=ON `
|
||||
-DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_C_FLAGS_MINSIZEREL="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" `
|
||||
-DCMAKE_C_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG"
|
||||
cmake --build ./build --config ${{env.BUILD_TYPE}}
|
||||
cmake --install ./build --config ${{env.BUILD_TYPE}}
|
||||
# Unfortunately soft-oal produces a binary called OpenAL32 even in 64-bit
|
||||
if (("x64", "ARM64") -icontains "${{ matrix.architecture.config }}") { Rename-Item -Path '.\install\bin\OpenAL32.dll' -NewName 'OpenAL64.dll' }
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
@@ -149,6 +210,8 @@ jobs:
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
|
||||
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' `
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' `
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
@@ -175,8 +238,9 @@ jobs:
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
@@ -184,7 +248,7 @@ jobs:
|
||||
${{github.workspace}}/install
|
||||
!${{github.workspace}}/install/**/*.pdb
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}-pdb
|
||||
if-no-files-found: error
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -79,6 +79,6 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -25,8 +25,11 @@ jobs:
|
||||
target_os: [
|
||||
'linux-amd64',
|
||||
'linux-i686',
|
||||
'linux-aarch64',
|
||||
'linux-arm64',
|
||||
'linux-armhf',
|
||||
'linux-powerpc',
|
||||
'linux-ppc64',
|
||||
'linux-ppc64el',
|
||||
'windows-x64',
|
||||
'windows-x86',
|
||||
'windows-x64-pdb',
|
||||
@@ -43,7 +46,7 @@ jobs:
|
||||
RELEASE_NAME: ${{ github.event.repository.name }}-${{github.ref_name}}-${{matrix.target_os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: 'out-${{matrix.target_os}}'
|
||||
path: ${{github.workspace}}/${{matrix.target_os}}
|
||||
@@ -53,7 +56,7 @@ jobs:
|
||||
run: zip -r ../${{ env.RELEASE_NAME }}.zip ./
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: '${{github.ref_name}}-${{env.RELEASE_TYPE}}'
|
||||
prerelease: ${{env.RELEASE_IS_PRERELEASE}}
|
||||
|
||||
+4
-1
@@ -5,6 +5,8 @@ Makefile.local
|
||||
*.swp
|
||||
*tags
|
||||
*~
|
||||
/.vscode/
|
||||
/baseq3
|
||||
|
||||
# OS X
|
||||
####################
|
||||
@@ -44,5 +46,6 @@ profile
|
||||
*.suo
|
||||
|
||||
.vs
|
||||
out
|
||||
code_unfinished/*
|
||||
thirdparties/
|
||||
code/parser/generated/*
|
||||
+12
-12
@@ -16,8 +16,17 @@ set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Treat no return type as error
|
||||
add_compile_options(/we4715)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(-Wno-comment)
|
||||
# Treat no return type as error
|
||||
add_compile_options(-Werror=return-type)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Ignore warnings for code like 'assert("Assert string")'
|
||||
add_compile_options(-Wno-pointer-bool-conversion)
|
||||
endif()
|
||||
@@ -96,10 +105,10 @@ INSTALL(TARGETS omohaaded DESTINATION "./")
|
||||
|
||||
if (NOT BUILD_NO_CLIENT)
|
||||
## Client app
|
||||
|
||||
|
||||
add_subdirectory("code/client")
|
||||
add_subdirectory("code/renderer")
|
||||
add_subdirectory("code/sdl")
|
||||
add_subdirectory("code/client")
|
||||
|
||||
#include("code/renderergl2/glsl/shaders.cmake")
|
||||
#file(GLOB_RECURSE SOURCES_RENDERER "code/sdl/*.c" "code/renderercommon/*.c" "code/renderergl2/*.c" "code/renderergl2/*.cpp")
|
||||
@@ -119,15 +128,6 @@ if (NOT BUILD_NO_CLIENT)
|
||||
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
target_link_libraries(openmohaa PRIVATE jpeg8)
|
||||
if (USE_OPENAL)
|
||||
# Try to use OpenAL
|
||||
find_package(OpenAL)
|
||||
if (OPENAL_FOUND)
|
||||
target_compile_definitions(openmohaa PRIVATE USE_OPENAL=1)
|
||||
target_include_directories(openmohaa PRIVATE ${OPENAL_INCLUDE_DIR})
|
||||
target_link_libraries(openmohaa PRIVATE ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
|
||||
|
||||
@@ -15,139 +15,38 @@
|
||||
|_|
|
||||
```
|
||||
|
||||
## Current State
|
||||
|
||||
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully stable. But the `training` map can be played from start to end. The current focus is on multiplayer.
|
||||
|
||||
## Intro
|
||||
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault**. It has always been a dream in the community to provide patches and security fixes for the game. Thanks to the ioquake3 project, F.A.K.K SDK and other quality tools, OpenMoHAA has already reached more than half of its goal: to create an open-source version of MoH:AA (based on version 2.40) that is fully compatible with the original game (in terms of protocol, assets, and scripts).
|
||||
|
||||
## Running
|
||||
## Getting started
|
||||
|
||||
Ensure that you download the binaries compatible with your platform.
|
||||
- [Installing OpenMoHAA](docs/getting_started_installation.md)
|
||||
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
|
||||
|
||||
### Requirements
|
||||
## Current state
|
||||
|
||||
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
|
||||
### Single-player
|
||||
|
||||
### Client
|
||||
The entire single-player campaign can be played from start to end. There may be occasional bugs though; if you encounter any, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
|
||||
|
||||
a) extract archive to your MOHAA installation directory.
|
||||
### Multiplayer
|
||||
|
||||
-or-
|
||||
The Multiplayer part is almost fully stable.
|
||||
|
||||
b) extract archive somewhere on your hard drive, create a shortcut to openmohaa (or omohaaded), and set the start directory to your MOHAA installation directory.
|
||||
Server admins can use OpenMoHAA to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server. Bugs must be reported by creating a new [issue](https://github.com/openmoh/openmohaa/issues) on the OpenMoHAA GitHub project. Players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on a mohaa/mohaas/mohaab server.
|
||||
|
||||
### Server
|
||||
All game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
|
||||
|
||||
Extract the archive to your MOHAA server installation directory. Then proceed like you would do with mohaa server:
|
||||
## Features
|
||||
|
||||
- `.\omohaaded.exe +exec server.cfg` on Windows
|
||||
- `./omohaaded +exec server.cfg` on Linux
|
||||
|
||||
Only `omohaaded*` and `game*` binaries are required for the server version, other binaries can be omitted.
|
||||
|
||||
### Config file
|
||||
|
||||
The config file can be found in different locations depending on the platform:
|
||||
|
||||
- `%APPDATA%\openmohaa\<game_name>\configs\omconfig.cfg` on Windows
|
||||
- `~/.openmohaa/<game_name>/configs/omconfig.cfg` on Linux
|
||||
|
||||
This has two advantages:
|
||||
- On a multi-user system, each user will have their own configuration file
|
||||
- It doesn't overwrite the existing MOHAA configuration in the MOHAA installation directory.
|
||||
|
||||
### Game selection
|
||||
|
||||
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA using the `com_target_game` variable. To play an expansion, append the following command-line arguments to the executable:
|
||||
|
||||
- `+set com_target_game 1` for Spearhead (mohaas/mohta)
|
||||
- `+set com_target_game 2` for Breakthrough (mohaab/mohtt)
|
||||
|
||||
On Windows, you can create a shortcut to OpenMoHAA with these command-line arguments.
|
||||
The default value of `com_target_game` is 0 for the base game (main).
|
||||
|
||||
With `com_target_game`, OpenMoHAA will support the network protocol accordingly.
|
||||
|
||||
You can now start a local OpenMOHAA server or play on a server.
|
||||
|
||||
### Playing with bots
|
||||
|
||||
OpenMoHAA has a basic bot system that emulates real players. The maximum number of bots is defined by the `sv_maxbots` variable, and the number of initial bots is defined by the `sv_numbots` variable. Bots can also be added or removed using the `addbot` and `removebot` commands.
|
||||
|
||||
This feature is a great way to test the gameplay and mods.
|
||||
|
||||
## Builds
|
||||
|
||||
### Server
|
||||
|
||||
The server version can be built successfully, but some features are not functional. For example, the Actor system is almost fully implemented, but it is not yet stable. This means that Actor may not work as expected and could cause crashes.
|
||||
|
||||
Overall, the server and the fgame components are almost fully implemented, but they may not be completely stable. There could be some minor bugs (and rare crashes), but the game should be playable.
|
||||
|
||||
### Client
|
||||
|
||||
The client version of OpenMoHAA has undergone partial implementation, with the cgame module being nearly completed. Credits to the SDK of **Heavy Metal: F.A.K.K. 2** both the cgame and fgame modules.
|
||||
|
||||
The current operational status for each component is as follow:
|
||||
|
||||
| Component | Full | Almost | Half | Early | Bad | Not working | Comment |
|
||||
|-------------------------|------|--------|------|-------|-----|-------------|-------------------------------------------------------------------|
|
||||
| Audio | | | | | x | | Very basic implementation from Quake III |
|
||||
| CG Module | | x | | | | | Missing FX, Marks and decals |
|
||||
| Client | | x | | | | | Missing GameSpy, server list, binds, map picker, ... |
|
||||
| Collision | x | | | | | | |
|
||||
| Model/TIKI/Skeletor | x | | | | | | |
|
||||
| Renderer | | x | | | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
|
||||
| Server | | x | | | | | Probably a few bugs remaining |
|
||||
| Server module (fgame) | | x | | | | | Actor, and few gameplay bugs |
|
||||
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
|
||||
- [What's working](docs/features_implementation.md)
|
||||
- [New features](docs/features.md)
|
||||
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
|
||||
|
||||
## Compiling
|
||||
|
||||
OpenMoHAA supports any architecture, thanks to the CMake build system and cross-platform code/libraries. While the most common little-Endian architectures (arm, aarch64, x86, x86_64) have been tested and confirmed to work, big-Endian architectures should be supported as well; however, they remain untested.
|
||||
|
||||
The following tools are required for all platforms:
|
||||
- CMake >= 3.5
|
||||
- Flex (>= 2.6.4) and Bison (>= 3.5.1)
|
||||
- A C++11 compiler is also required.
|
||||
|
||||
The installation directory can be set to the MOHAA directory.
|
||||
|
||||
By default, the build will produce both the client and dedicated server versions. The client can be omitted from the build by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
|
||||
|
||||
### Linux
|
||||
|
||||
These are the tools required on Linux :
|
||||
- Clang >= 3.3 or GCC >= 4.8.5
|
||||
- libsdl2-dev
|
||||
|
||||
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04), but the latest version should be used.
|
||||
|
||||
Ubuntu 20.04 is the minimum version required to fully compile the project successfully.
|
||||
|
||||
1 line install command with clang:
|
||||
```sh
|
||||
sudo apt-get install -y cmake ninja-build clang lld flex bison libsdl2-dev
|
||||
```
|
||||
|
||||
Example with **CMake** and **ninja-build** installed:
|
||||
```sh
|
||||
mkdir .cmake && cd .cmake
|
||||
cmake -G Ninja ../
|
||||
```
|
||||
|
||||
Other compilers can be specified by appending `-DCMAKE_C_COMPILER=/path/to/compiler -DCMAKE_CXX_COMPILER=path/to/compiler` to the CMake command-line.
|
||||
|
||||
### Windows
|
||||
|
||||
Visual Studio (2019 or 2022) is generally preferred.
|
||||
|
||||
Flex and Bison can be downloaded from here: https://github.com/lexxmark/winflexbison/releases/tag/v2.5.25
|
||||
|
||||
Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe` to the CMake command-line to use the package from the link above.
|
||||
- See [Compiling OpenMoHAA](docs/compiling.md)
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -159,41 +58,6 @@ Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe`
|
||||
|
||||
*More screenshots [here](docs/images)*
|
||||
|
||||
## Features
|
||||
|
||||
### Features added and not present in MOH:AA
|
||||
|
||||
#### Server-side
|
||||
|
||||
- Bots
|
||||
- Spectate players in first-person
|
||||
- Demo recording
|
||||
- More script commands for mods
|
||||
- Non-PVS optimization
|
||||
|
||||
##### Non-PVS optimization
|
||||
|
||||
For each client, the server optimizes by only sending them information about other players that they can see. Clients won't see other players they can't see.
|
||||
|
||||
Enable this feature with `set sv_netoptimize 2`.
|
||||
|
||||
#### Client-side and server-side
|
||||
|
||||
- Security fixes and features from ioquake3
|
||||
- IPv6 support (from ioquake3)
|
||||
|
||||
### Objectives / planned features
|
||||
|
||||
This is a non-exhaustive list of objectives and planned features.
|
||||
|
||||
#### Server-side
|
||||
|
||||
- 100% compatibility with mohaa content
|
||||
- More feature for mods
|
||||
- Anticheat
|
||||
- Stats system
|
||||
- Multiple roles/abilities for server admins to reduce password-stealing
|
||||
|
||||
## Third party
|
||||
|
||||
### SDL
|
||||
|
||||
+13
-5
@@ -3,8 +3,12 @@ set(archdetect_c_code "
|
||||
# error cmake_ARCH x86
|
||||
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
# error cmake_ARCH x86_64
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__)
|
||||
# error cmake_ARCH ppc64
|
||||
#elif defined(__PPC64__) || defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64)
|
||||
# if __BIG_ENDIAN__
|
||||
# error cmake_ARCH ppc64
|
||||
# else
|
||||
# error cmake_ARCH ppc64el
|
||||
# endif
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__)
|
||||
# error cmake_ARCH ppc
|
||||
#elif defined __s390__
|
||||
@@ -19,10 +23,14 @@ set(archdetect_c_code "
|
||||
# error cmake_ARCH alpha
|
||||
#elif defined __sparc__
|
||||
# error cmake_ARCH sparc
|
||||
#elif defined __arm__ || defined (_M_ARM)
|
||||
# error cmake_ARCH arm
|
||||
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
|
||||
# error cmake_ARCH aarch64
|
||||
# error cmake_ARCH arm64
|
||||
#elif defined __arm__ || defined (_M_ARM)
|
||||
# if defined(__ARM_PCS_VFP) && (__ARM_PCS_VFP)
|
||||
# error cmake_ARCH armhf
|
||||
# else
|
||||
# error cmake_ARCH armel
|
||||
# endif
|
||||
#elif defined __cris__
|
||||
# error cmake_ARCH cris
|
||||
#elif defined __hppa__
|
||||
|
||||
@@ -933,10 +933,13 @@ static void waitToApplyUpdates(void)
|
||||
OS forcibly closes the pipe), we will unblock. Then we can loop on
|
||||
kill() until the process is truly gone. */
|
||||
int x = 0;
|
||||
struct timespec req;
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = 100000000;
|
||||
read(3, &x, sizeof (x));
|
||||
info("Pipe has closed, waiting for process to fully go away now.");
|
||||
while (kill(options.waitforprocess, 0) == 0) {
|
||||
usleep(100000);
|
||||
nanosleep(&req, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterModel(tmp.c_str());
|
||||
} else {
|
||||
*handle = NULL;
|
||||
*handle = (qhandle_t)0;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
@@ -135,7 +135,7 @@ void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterShader(tmp.c_str());
|
||||
} else {
|
||||
*handle = NULL;
|
||||
*handle = (qhandle_t)0;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
@@ -163,7 +163,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
|
||||
archiver.ArchiveVec3(ref->axis[2]);
|
||||
archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
|
||||
archiver.ArchiveVec3(ref->origin);
|
||||
archiver.ArchiveRaw(ref->frameInfo, 192);
|
||||
archiver.ArchiveRaw(ref->frameInfo, sizeof(ref->frameInfo));
|
||||
archiver.ArchiveFloat(&ref->actionWeight);
|
||||
archiver.ArchiveShort(&ref->wasframe);
|
||||
archiver.ArchiveFloat(&ref->scale);
|
||||
@@ -171,7 +171,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
|
||||
archiver.ArchiveInteger(&ref->skinNum);
|
||||
|
||||
CG_ArchiveShaderHandle(archiver, &ref->customShader);
|
||||
archiver.ArchiveRaw(ref->shaderRGBA, 4);
|
||||
archiver.ArchiveRaw(ref->shaderRGBA, sizeof(ref->shaderRGBA));
|
||||
archiver.ArchiveFloat(ref->shaderTexCoord);
|
||||
archiver.ArchiveFloat(&ref->shaderTexCoord[1]);
|
||||
archiver.ArchiveFloat(&ref->shaderTime);
|
||||
|
||||
@@ -196,7 +196,8 @@ Event EV_Client_SetColorVelocity
|
||||
"rVel gVel bVel",
|
||||
"Set the color velocity of the spawned dlight tempmodel"
|
||||
);
|
||||
Event EV_Client_SetRandomVelocity(
|
||||
Event EV_Client_SetRandomVelocity
|
||||
(
|
||||
"randvel",
|
||||
EV_DEFAULT,
|
||||
"SfFSfFSfF",
|
||||
@@ -210,7 +211,8 @@ Event EV_Client_SetRandomVelocity(
|
||||
"without randomness.\n"
|
||||
"This velocity is applied using the world axis"
|
||||
);
|
||||
Event EV_Client_SetRandomVelocityAlongAxis(
|
||||
Event EV_Client_SetRandomVelocityAlongAxis
|
||||
(
|
||||
"randvelaxis",
|
||||
EV_DEFAULT,
|
||||
"SfFSfFSfF",
|
||||
@@ -225,6 +227,14 @@ Event EV_Client_SetRandomVelocityAlongAxis(
|
||||
"without randomness.\n"
|
||||
"This velocity is applied using the parent axis"
|
||||
);
|
||||
Event EV_Client_NoTagAxis
|
||||
(
|
||||
"notagaxis",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Forces the effect to use the model's orientation for randvelaxis and offsetalongaxis"
|
||||
);
|
||||
Event EV_Client_SetAccel
|
||||
(
|
||||
"accel",
|
||||
@@ -1221,6 +1231,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
|
||||
{&EV_Client_SetColorVelocity, &ClientGameCommandManager::SetAngularVelocity },
|
||||
{&EV_Client_SetRandomVelocity, &ClientGameCommandManager::SetRandomVelocity },
|
||||
{&EV_Client_SetRandomVelocityAlongAxis, &ClientGameCommandManager::SetRandomVelocityAlongAxis},
|
||||
{&EV_Client_NoTagAxis, &ClientGameCommandManager::SetNoTagAxis },
|
||||
{&EV_Client_SetAccel, &ClientGameCommandManager::SetAccel },
|
||||
{&EV_Client_SetFriction, &ClientGameCommandManager::SetFriction },
|
||||
{&EV_Client_SetSpin, &ClientGameCommandManager::SetSpin },
|
||||
@@ -2157,7 +2168,9 @@ void ClientGameCommandManager::SetInwardSphere(Event *ev)
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.flags |= T_INWARDSPHERE;
|
||||
m_spawnthing->sphereRadius = ev->GetFloat(1);
|
||||
if (ev->NumArgs() > 0) {
|
||||
m_spawnthing->sphereRadius = ev->GetFloat(1);
|
||||
}
|
||||
}
|
||||
|
||||
//=============
|
||||
@@ -2666,6 +2679,15 @@ void ClientGameCommandManager::SetRandomVelocityAlongAxis(Event *ev)
|
||||
SetRandomVelocity(ev);
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::SetNoTagAxis(Event* ev)
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.flags2 |= T2_NOTAGAXIS;
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::SetRadialVelocity(Event *ev)
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
|
||||
@@ -113,6 +113,7 @@ TIKI file, similar to ScriptMaster in the server game dll.
|
||||
#define T2_VARYCOLOR (1 << 20)
|
||||
#define T2_SPIN (1 << 21)
|
||||
#define T2_RELATIVEANGLES (1 << 22)
|
||||
#define T2_NOTAGAXIS (1 << 23)
|
||||
|
||||
class spawnthing_t;
|
||||
class specialeffect_t;
|
||||
@@ -788,6 +789,7 @@ private:
|
||||
void SetScaleRate(Event *ev);
|
||||
void SetRandomVelocity(Event *ev);
|
||||
void SetRandomVelocityAlongAxis(Event *ev);
|
||||
void SetNoTagAxis(Event *ev); // Added in 2.0
|
||||
void SetAccel(Event *ev);
|
||||
void SetFriction(Event *ev);
|
||||
void SetSpin(Event *ev);
|
||||
|
||||
+60
-50
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// text commands typed in at the local console, or executed by a key binding
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../fgame/bg_voteoptions.h"
|
||||
|
||||
void CG_TargetCommand_f(void);
|
||||
|
||||
@@ -339,56 +340,65 @@ typedef struct {
|
||||
} consoleCommand_t;
|
||||
|
||||
static consoleCommand_t commands[] = {
|
||||
{"useweaponclass", &CG_UseWeaponClass_f },
|
||||
{"weapnext", &CG_NextWeapon_f },
|
||||
{"weapprev", &CG_PrevWeapon_f },
|
||||
{"uselast", &CG_UseLastWeapon_f },
|
||||
{"holster", &CG_HolsterWeapon_f },
|
||||
{"weapdrop", &CG_DropWeapon_f },
|
||||
{"toggleitem", &CG_ToggleItem_f },
|
||||
{"+scores", &CG_ScoresDown_f },
|
||||
{"-scores", &CG_ScoresUp_f },
|
||||
{"viewpos", &CG_Viewpos_f },
|
||||
{"sizeup", &CG_SizeUp_f },
|
||||
{"sizedown", &CG_SizeDown_f },
|
||||
{"cg_eventlist", &CG_EventList_f },
|
||||
{"cg_eventhelp", &CG_EventHelp_f },
|
||||
{"cg_dumpevents", &CG_DumpEventHelp_f },
|
||||
{"cg_pendingevents", &CG_PendingEvents_f },
|
||||
{"cg_classlist", &CG_ClassList_f },
|
||||
{"cg_classtree", &CG_ClassTree_f },
|
||||
{"cg_classevents", &CG_ClassEvents_f },
|
||||
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
|
||||
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
|
||||
{"testemitter", &CG_TestEmitter_f },
|
||||
{"triggertestemitter", &CG_TriggerTestEmitter_f },
|
||||
{"prevemittercommand", &CG_PrevEmitterCommand_f },
|
||||
{"nextemittercommand", &CG_NextEmitterCommand_f },
|
||||
{"newemittercommand", &CG_NewEmitterCommand_f },
|
||||
{"deleteemittercommand", &CG_DeleteEmitterCommand_f},
|
||||
{"dumpemitter", &CG_DumpEmitter_f },
|
||||
{"loademitter", &CG_LoadEmitter_f },
|
||||
{"resetvss", &CG_ResetVSSSources },
|
||||
{"getchshader", &CG_GetCHShader },
|
||||
{"editchshader", &CG_EditCHShader },
|
||||
{"messagemode", &CG_MessageMode_f },
|
||||
{"messagemode_all", &CG_MessageMode_All_f },
|
||||
{"messagemode_team", &CG_MessageMode_Team_f },
|
||||
{"messagemode_private", &CG_MessageMode_Private_f },
|
||||
{"say", &CG_MessageSingleAll_f },
|
||||
{"sayteam", &CG_MessageSingleTeam_f },
|
||||
{"teamsay", &CG_MessageSingleTeam_f },
|
||||
{"sayprivate", &CG_MessageSingleClient_f },
|
||||
{"sayone", &CG_MessageSingleClient_f },
|
||||
{"wisper", &CG_MessageSingleClient_f },
|
||||
{"instamsg_main", &CG_InstaMessageMain_f },
|
||||
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
|
||||
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
|
||||
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
|
||||
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
|
||||
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
|
||||
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
|
||||
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f},
|
||||
{"useweaponclass", &CG_UseWeaponClass_f },
|
||||
{"weapnext", &CG_NextWeapon_f },
|
||||
{"weapprev", &CG_PrevWeapon_f },
|
||||
{"uselast", &CG_UseLastWeapon_f },
|
||||
{"holster", &CG_HolsterWeapon_f },
|
||||
{"weapdrop", &CG_DropWeapon_f },
|
||||
{"toggleitem", &CG_ToggleItem_f },
|
||||
{"+scores", &CG_ScoresDown_f },
|
||||
{"-scores", &CG_ScoresUp_f },
|
||||
{"viewpos", &CG_Viewpos_f },
|
||||
{"sizeup", &CG_SizeUp_f },
|
||||
{"sizedown", &CG_SizeDown_f },
|
||||
{"cg_eventlist", &CG_EventList_f },
|
||||
{"cg_eventhelp", &CG_EventHelp_f },
|
||||
{"cg_dumpevents", &CG_DumpEventHelp_f },
|
||||
{"cg_pendingevents", &CG_PendingEvents_f },
|
||||
{"cg_classlist", &CG_ClassList_f },
|
||||
{"cg_classtree", &CG_ClassTree_f },
|
||||
{"cg_classevents", &CG_ClassEvents_f },
|
||||
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
|
||||
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
|
||||
{"testemitter", &CG_TestEmitter_f },
|
||||
{"triggertestemitter", &CG_TriggerTestEmitter_f },
|
||||
{"prevemittercommand", &CG_PrevEmitterCommand_f },
|
||||
{"nextemittercommand", &CG_NextEmitterCommand_f },
|
||||
{"newemittercommand", &CG_NewEmitterCommand_f },
|
||||
{"deleteemittercommand", &CG_DeleteEmitterCommand_f },
|
||||
{"dumpemitter", &CG_DumpEmitter_f },
|
||||
{"loademitter", &CG_LoadEmitter_f },
|
||||
{"resetvss", &CG_ResetVSSSources },
|
||||
{"getchshader", &CG_GetCHShader },
|
||||
{"editchshader", &CG_EditCHShader },
|
||||
{"messagemode", &CG_MessageMode_f },
|
||||
{"messagemode_all", &CG_MessageMode_All_f },
|
||||
{"messagemode_team", &CG_MessageMode_Team_f },
|
||||
{"messagemode_private", &CG_MessageMode_Private_f },
|
||||
{"say", &CG_MessageSingleAll_f },
|
||||
{"sayteam", &CG_MessageSingleTeam_f },
|
||||
{"teamsay", &CG_MessageSingleTeam_f },
|
||||
{"sayprivate", &CG_MessageSingleClient_f },
|
||||
{"sayone", &CG_MessageSingleClient_f },
|
||||
{"wisper", &CG_MessageSingleClient_f },
|
||||
{"instamsg_main", &CG_InstaMessageMain_f },
|
||||
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
|
||||
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
|
||||
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
|
||||
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
|
||||
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
|
||||
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
|
||||
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
|
||||
// Added in 2.0
|
||||
{"pushcallvote", &CG_PushCallVote_f },
|
||||
{"pushcallvotesublist", &CG_PushCallVoteSubList_f },
|
||||
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
|
||||
{"pushcallvotesubinteger",&CG_PushCallVoteSubInteger_f },
|
||||
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
|
||||
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
|
||||
{"pushvote", &CG_PushVote_f },
|
||||
{"callentryvote", &CG_CallEntryVote_f },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -1180,7 +1180,7 @@ void CG_DrawCrosshair()
|
||||
float x, y;
|
||||
float width, height;
|
||||
|
||||
shader = NULL;
|
||||
shader = (qhandle_t)0;
|
||||
|
||||
if (!cg_hud->integer || !ui_crosshair->integer) {
|
||||
return;
|
||||
|
||||
@@ -59,7 +59,7 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
|
||||
|
||||
time = realtime / 50;
|
||||
frac = (realtime - (time * 50.0f)) / 50.0f;
|
||||
memset(color, 0, sizeof(color));
|
||||
VectorClear4(color);
|
||||
if ((style < 0) || (style >= (MAX_LIGHTSTYLES * 2))) {
|
||||
cgi.DPrintf("CG_LightStyleColor: style out of range.\n");
|
||||
return qtrue;
|
||||
|
||||
@@ -187,6 +187,7 @@ extern "C" {
|
||||
float min_dist;
|
||||
float width;
|
||||
char shader[MAX_RAIN_SHADERS][MAX_STRING_CHARS];
|
||||
char currentShader[MAX_STRING_CHARS];
|
||||
int numshaders;
|
||||
} crain_t;
|
||||
|
||||
@@ -340,6 +341,7 @@ extern "C" {
|
||||
float ObjectivesBaseAlpha;
|
||||
float ObjectivesDesiredAlpha;
|
||||
float ObjectivesCurrentAlpha;
|
||||
int ObjectivesCurrentIndex;
|
||||
|
||||
// misc
|
||||
crain_t rain;
|
||||
@@ -429,6 +431,7 @@ extern "C" {
|
||||
extern cgs_t cgs;
|
||||
extern cg_t cg;
|
||||
extern clientGameImport_t cgi;
|
||||
extern target_game_e cg_target_game;
|
||||
extern int cg_protocol;
|
||||
extern centity_t cg_entities[MAX_GENTITIES];
|
||||
extern markPoly_t *cg_markPolys;
|
||||
|
||||
+28
-16
@@ -35,12 +35,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
clientGameImport_t cgi;
|
||||
static clientGameExport_t cge;
|
||||
|
||||
cvar_t *paused;
|
||||
cvar_t *developer;
|
||||
cg_t cg;
|
||||
cgs_t cgs;
|
||||
int cg_protocol;
|
||||
centity_t cg_entities[MAX_GENTITIES];
|
||||
cvar_t *paused;
|
||||
cvar_t *developer;
|
||||
cg_t cg;
|
||||
cgs_t cgs;
|
||||
target_game_e cg_target_game = TG_INVALID;
|
||||
int cg_protocol;
|
||||
centity_t cg_entities[MAX_GENTITIES];
|
||||
|
||||
cvar_t *cg_animSpeed;
|
||||
cvar_t *cg_debugAnim;
|
||||
@@ -154,9 +155,9 @@ void CG_RegisterCvars(void)
|
||||
cg_shadowdebug = cgi.Cvar_Get("cg_shadowdebug", "0", 0);
|
||||
developer = cgi.Cvar_Get("developer", "0", 0);
|
||||
dm_playermodel = cgi.Cvar_Get("dm_playermodel", "american_army", 3);
|
||||
dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", 3);
|
||||
dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", CVAR_ARCHIVE | CVAR_USERINFO);
|
||||
cg_forceModel = cgi.Cvar_Get("cg_forceModel", "0", CVAR_ARCHIVE);
|
||||
cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", 8);
|
||||
cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", CVAR_SYSTEMINFO);
|
||||
cg_hitmessages = cgi.Cvar_Get("cg_hitmessages", "1", CVAR_ARCHIVE);
|
||||
cg_acidtrip = cgi.Cvar_Get("cg_acidtrip", "0", CVAR_CHEAT);
|
||||
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
|
||||
@@ -252,13 +253,11 @@ CG_IsHandleUnique
|
||||
Check if the model handle is unique
|
||||
================
|
||||
*/
|
||||
static qboolean CG_IsHandleUnique(int num) {
|
||||
qhandle_t handle;
|
||||
static qboolean CG_IsHandleUnique(qhandle_t handle) {
|
||||
int i;
|
||||
int numRef;
|
||||
|
||||
numRef = 0;
|
||||
handle = cgs.model_draw[num];
|
||||
for (i = 0; i < MAX_MODELS; i++) {
|
||||
if (cgs.model_draw[i] == handle) {
|
||||
numRef++;
|
||||
@@ -335,22 +334,33 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
Q_strncpyz(cg.rain.currentShader, str, sizeof(cg.rain.currentShader));
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
// Fixed in OPM
|
||||
// not sure why some maps set a digit at the end...
|
||||
int len = strlen(cg.rain.currentShader);
|
||||
if (isdigit(cg.rain.currentShader[len - 1])) {
|
||||
cg.rain.currentShader[len - 1] = 0;
|
||||
}
|
||||
} else {
|
||||
strcpy(cg.rain.shader[0], str);
|
||||
}
|
||||
for (i = 0; i < cg.rain.numshaders; ++i) {
|
||||
Com_sprintf(cg.rain.shader[i], sizeof(cg.rain.shader[i]), "%s%i", cg.rain.currentShader, i);
|
||||
}
|
||||
if (!cg.rain.numshaders) {
|
||||
Q_strncpyz(cg.rain.shader[0], cg.rain.currentShader, sizeof(cg.rain.shader[0]));
|
||||
}
|
||||
return;
|
||||
case CS_RAIN_NUMSHADERS:
|
||||
cg.rain.numshaders = atoi(str);
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
Com_sprintf(cg.rain.shader[i], sizeof(cg.rain.shader[i]), "%s%i", cg.rain.currentShader, i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case CS_CURRENT_OBJECTIVE:
|
||||
cg.ObjectivesCurrentIndex = atoi(str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
@@ -623,6 +633,8 @@ void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverComma
|
||||
cgi = *imported;
|
||||
|
||||
cg_protocol = cgi.Cvar_Get("com_protocol", "", 0)->integer;
|
||||
cg_target_game = (target_game_e)cgi.Cvar_Get("com_target_game", "0", 0)->integer;
|
||||
|
||||
CG_InitCGMessageAPI(&cge);
|
||||
CG_InitScoresAPI(&cge);
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ int CG_GetMarkFragments(
|
||||
}
|
||||
|
||||
iNewPoints = 0;
|
||||
for (j = 0, pFragment = pCurrFragment; j < iNewPoints; j++, pFragment++) {
|
||||
for (j = 0, pFragment = pCurrFragment; j < iNewFragments; j++, pFragment++) {
|
||||
pFragment->firstPoint += iCurrPoints;
|
||||
pFragment->iIndex = -pEnt->number;
|
||||
iNewPoints += pFragment->numPoints;
|
||||
@@ -219,10 +219,11 @@ static qboolean CG_GetMarkInlineModelOrientation(int iIndex) {
|
||||
}
|
||||
|
||||
pCEnt = &cg_entities[-iIndex];
|
||||
if (pCEnt->currentValid && pCEnt->currentState.modelindex < cgs.inlineDrawModel[ENTITYNUM_NONE])
|
||||
if (pCEnt->currentValid && pCEnt->currentState.modelindex < cgs.numInlineModels)
|
||||
{
|
||||
VectorCopy(pCEnt->lerpAngles, cg_vEntAngles);
|
||||
VectorCopy(pCEnt->lerpOrigin, cg_vEntOrigin);
|
||||
cg_bLastEntValid = qtrue;
|
||||
|
||||
if (cg_vEntAngles[0] || cg_vEntAngles[1] || cg_vEntAngles[2]) {
|
||||
AngleVectorsLeft(cg_vEntAngles, cg_fEntAxis[0], cg_fEntAxis[1], cg_fEntAxis[2]);
|
||||
@@ -937,15 +938,15 @@ void CG_AddMarks(void)
|
||||
}
|
||||
|
||||
if (pMark->markPolys->iIndex < 0) {
|
||||
if (CG_FrustumCullSphere(pMark->pos, pMark->radius)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
vec3_t vWorldPos;
|
||||
CG_FragmentPosToWorldPos(pMark->pos, vWorldPos);
|
||||
if (CG_FrustumCullSphere(vWorldPos, pMark->radius)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (CG_FrustumCullSphere(pMark->pos, pMark->radius)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
pMark->lastVisTime = cg.time;
|
||||
|
||||
@@ -1323,7 +1323,12 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
if (model.frameInfo[i].weight) {
|
||||
if (!((cent->animLastWeight >> i) & 1) || model.frameInfo[i].index != cent->animLast[i]) {
|
||||
CG_ProcessEntityCommands(TIKI_FRAME_ENTRY, model.frameInfo[i].index, s1->number, &model, cent);
|
||||
cent->animLastTimes[i] = 0.0;
|
||||
if (cent->animLastTimes[i] == -1) {
|
||||
cent->animLast[i] = model.frameInfo[i].index;
|
||||
cent->animLastTimes[i] = model.frameInfo[i].time;
|
||||
} else {
|
||||
cent->animLastTimes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CG_ClientCommands(&model, cent, i);
|
||||
|
||||
@@ -58,7 +58,7 @@ void ClientGameCommandManager::InitializeRainCvars()
|
||||
{
|
||||
int i;
|
||||
|
||||
cg_rain = cgi.Cvar_Get("cg_rain", "0", CVAR_ARCHIVE);
|
||||
cg_rain = cgi.Cvar_Get("cg_rain", "1", CVAR_ARCHIVE);
|
||||
cg_rain_drawcoverage =
|
||||
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_SERVER_CREATED | CVAR_SYSTEMINFO);
|
||||
|
||||
|
||||
+222
-167
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -160,49 +160,49 @@ static void CG_MakeBulletHoleType(
|
||||
float fVolume;
|
||||
|
||||
switch (iEffectNum) {
|
||||
case 0:
|
||||
case SFX_BHIT_PAPER_LITE:
|
||||
sBulletHole += "paper";
|
||||
break;
|
||||
case 2:
|
||||
case SFX_BHIT_WOOD_LITE:
|
||||
sBulletHole += "wood";
|
||||
break;
|
||||
case 4:
|
||||
case SFX_BHIT_METAL_LITE:
|
||||
sBulletHole += "metal";
|
||||
break;
|
||||
case 6:
|
||||
case SFX_BHIT_STONE_LITE:
|
||||
sBulletHole += "stone";
|
||||
break;
|
||||
case 8:
|
||||
case SFX_BHIT_DIRT_LITE:
|
||||
sBulletHole += "dirt";
|
||||
break;
|
||||
case 10:
|
||||
case SFX_BHIT_GRILL_LITE:
|
||||
sBulletHole += "grill";
|
||||
break;
|
||||
case 12:
|
||||
case SFX_BHIT_GRASS_LITE:
|
||||
sBulletHole += "grass";
|
||||
break;
|
||||
case 14:
|
||||
case SFX_BHIT_MUD_LITE:
|
||||
sBulletHole += "mud";
|
||||
break;
|
||||
case 16:
|
||||
case SFX_BHIT_PUDDLE_LITE:
|
||||
sBulletHole += "puddle";
|
||||
break;
|
||||
case 18:
|
||||
case SFX_BHIT_GLASS_LITE:
|
||||
sBulletHole += "glass";
|
||||
break;
|
||||
case 20:
|
||||
case SFX_BHIT_GRAVEL_LITE:
|
||||
sBulletHole += "gravel";
|
||||
break;
|
||||
case 22:
|
||||
case SFX_BHIT_SAND_LITE:
|
||||
sBulletHole += "sand";
|
||||
break;
|
||||
case 24:
|
||||
case SFX_BHIT_FOLIAGE_LITE:
|
||||
sBulletHole += "foliage";
|
||||
break;
|
||||
case 26:
|
||||
case SFX_BHIT_SNOW_LITE:
|
||||
sBulletHole += "snow";
|
||||
break;
|
||||
case 28:
|
||||
case SFX_BHIT_CARPET_LITE:
|
||||
sBulletHole += "carpet";
|
||||
break;
|
||||
default:
|
||||
@@ -267,7 +267,7 @@ CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
sBulletHole += "snow";
|
||||
iEffect = SFX_BHIT_FOLIAGE_LITE;
|
||||
iEffect = SFX_BHIT_SNOW_LITE;
|
||||
break;
|
||||
case SURF_CARPET:
|
||||
sBulletHole += "carpet";
|
||||
@@ -283,7 +283,7 @@ CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t
|
||||
break;
|
||||
case SURF_GLASS:
|
||||
sBulletHole += "glass";
|
||||
iEffect = SFX_BHIT_GRASS_LITE;
|
||||
iEffect = SFX_BHIT_GLASS_LITE;
|
||||
break;
|
||||
case SURF_GRAVEL:
|
||||
fRadius = 0.f;
|
||||
@@ -366,7 +366,7 @@ static void CG_MakeBubbleTrail(const vec3_t i_vStart, const vec3_t i_vEnd, int i
|
||||
fDist -= fMove;
|
||||
while (fDist > 0.f) {
|
||||
VectorMA(vPos, fMove, vDir, vPos);
|
||||
sfxManager.MakeEffect_Angles(32, vPos, vec_zero);
|
||||
sfxManager.MakeEffect_Angles(SFX_WATER_TRAIL_BUBBLE, vPos, vec_zero);
|
||||
|
||||
fMove = 16.f + crandom() * 8.f * alpha;
|
||||
fDist -= fMove;
|
||||
@@ -535,7 +535,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
|
||||
while (trace.fraction < 1) {
|
||||
if (bIgnoreEntities) {
|
||||
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT, qfalse);
|
||||
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT_FLUID, qfalse);
|
||||
|
||||
if (trace.fraction == 1.0f) {
|
||||
trace.entityNum = ENTITYNUM_NONE;
|
||||
@@ -554,7 +554,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
vec_zero,
|
||||
vTraceStart,
|
||||
ENTITYNUM_NONE,
|
||||
MASK_SHOT,
|
||||
MASK_SHOT_FLUID,
|
||||
qfalse,
|
||||
qfalse,
|
||||
"CG_MakeBulletTracerInternal"
|
||||
@@ -564,11 +564,11 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (trace.contents & CONTENTS_FLUID) {
|
||||
fDist = DotProduct(vDir, trace.plane.normal) * -2.0f;
|
||||
VectorMA(vDir, fDist, trace.plane.normal, vTmp);
|
||||
VectorAdd(vTmp, vTmp, trace.plane.normal);
|
||||
VectorMA(trace.plane.normal, 2.0, vTmp, trace.plane.normal);
|
||||
VectorNormalizeFast(trace.plane.normal);
|
||||
}
|
||||
|
||||
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127) {
|
||||
if (!bInWater && trace.fraction < 1.0f && iNumImpacts < ARRAY_LEN(tImpacts)) {
|
||||
memcpy(&tImpacts[iNumImpacts], &trace, sizeof(trace_t));
|
||||
iNumImpacts++;
|
||||
}
|
||||
@@ -859,14 +859,14 @@ void CG_AddBulletImpacts()
|
||||
}
|
||||
|
||||
if (fImpSndDistRA < fImpSndDistLA) {
|
||||
if (wall_impact_type[iImpSndIndexRA]) {
|
||||
if (wall_impact_type[iImpSndIndexRA] != SFX_BHIT_PAPER_LITE) {
|
||||
if (wall_impact_large[iImpSndIndexRA]) {
|
||||
fVolume = 1.f;
|
||||
} else {
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexRA] == 2 || wall_impact_type[iImpSndIndexRA] == 3) {
|
||||
if (wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -897,7 +897,7 @@ void CG_AddBulletImpacts()
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexRB] == 2 || wall_impact_type[iImpSndIndexRB] == 3) {
|
||||
if (wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -923,14 +923,14 @@ void CG_AddBulletImpacts()
|
||||
}
|
||||
|
||||
if (fImpSndDistLA > 9999.0f) {
|
||||
if (wall_impact_type[0]) {
|
||||
if (wall_impact_type[0] != SFX_BHIT_PAPER_LITE) {
|
||||
if (wall_impact_large[0]) {
|
||||
fVolume = 1.f;
|
||||
} else {
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[0] == 2 || wall_impact_type[0] == 3) {
|
||||
if (wall_impact_type[0] == SFX_BHIT_WOOD_LITE || wall_impact_type[0] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -945,14 +945,14 @@ void CG_AddBulletImpacts()
|
||||
}
|
||||
|
||||
if (fImpSndDistLB < fImpSndDistLA) {
|
||||
if (wall_impact_type[iImpSndIndexLB]) {
|
||||
if (wall_impact_type[iImpSndIndexLB] != SFX_BHIT_PAPER_LITE) {
|
||||
if (wall_impact_large[iImpSndIndexLB]) {
|
||||
fVolume = 1.f;
|
||||
} else {
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexLB] == 2 || wall_impact_type[iImpSndIndexLB] == 3) {
|
||||
if (wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -987,14 +987,16 @@ void CG_AddBulletImpacts()
|
||||
if (flesh_impact_count) {
|
||||
if (flesh_impact_count > 1) {
|
||||
fImpSndDistRA = 9999.0;
|
||||
fImpSndDistRB = 9999.0;
|
||||
iImpSndIndexRA = 0;
|
||||
iImpSndIndexRB = 0;
|
||||
|
||||
for (i = 0; i < flesh_impact_count; i++) {
|
||||
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
|
||||
VectorSubtract(flesh_impact_pos[i], cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
if (iHeadDist < fImpSndDistRB) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRA = i;
|
||||
}
|
||||
@@ -1003,6 +1005,30 @@ void CG_AddBulletImpacts()
|
||||
iImpSndIndexRA = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (fImpSndDistRA < 9999) {
|
||||
sfxManager.MakeEffect_Normal(
|
||||
flesh_impact_large[iImpSndIndexRA] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
|
||||
flesh_impact_pos[iImpSndIndexRA],
|
||||
flesh_impact_norm[iImpSndIndexRA]
|
||||
);
|
||||
}
|
||||
|
||||
if (fImpSndDistRB < 9999) {
|
||||
sfxManager.MakeEffect_Normal(
|
||||
flesh_impact_large[iImpSndIndexRB] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
|
||||
flesh_impact_pos[iImpSndIndexRB],
|
||||
flesh_impact_norm[iImpSndIndexRB]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < flesh_impact_count; i++) {
|
||||
sfxManager.MakeEffect_Normal(
|
||||
flesh_impact_large[i] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
|
||||
flesh_impact_pos[i],
|
||||
flesh_impact_norm[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
flesh_impact_count = 0;
|
||||
@@ -1031,22 +1057,33 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (iType) {
|
||||
case 13:
|
||||
iBaseEffect = SFX_EXP_GREN_BASE;
|
||||
break;
|
||||
case 14:
|
||||
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
|
||||
break;
|
||||
case 15:
|
||||
iBaseEffect = SFX_EXP_HEAVYSHELL_BASE;
|
||||
break;
|
||||
case 16:
|
||||
iBaseEffect = SFX_EXP_TANK_BASE;
|
||||
break;
|
||||
default:
|
||||
iBaseEffect = SFX_EXP_GREN_BASE;
|
||||
break;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
switch (iType) {
|
||||
case CGM_EXPLOSION_EFFECT_1:
|
||||
iBaseEffect = SFX_EXP_GREN_BASE;
|
||||
break;
|
||||
case CGM_EXPLOSION_EFFECT_2:
|
||||
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
|
||||
break;
|
||||
case CGM_EXPLOSION_EFFECT_3:
|
||||
iBaseEffect = SFX_EXP_HEAVYSHELL_BASE;
|
||||
break;
|
||||
case CGM_EXPLOSION_EFFECT_4:
|
||||
iBaseEffect = SFX_EXP_TANK_BASE;
|
||||
break;
|
||||
default:
|
||||
iBaseEffect = SFX_EXP_GREN_BASE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (iType) {
|
||||
case CGM6_EXPLOSION_EFFECT_2:
|
||||
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
|
||||
break;
|
||||
default:
|
||||
iBaseEffect = SFX_EXP_GREN_BASE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CG_Trace(
|
||||
@@ -1074,14 +1111,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
break;
|
||||
case SFX_EXP_BAZOOKA_BASE:
|
||||
iSurfEffect = SFX_EXP_BAZOOKA_SNOW;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_BASE:
|
||||
iSurfEffect = SFX_EXP_HEAVYSHELL_SNOW;
|
||||
break;
|
||||
default:
|
||||
iSurfEffect = SFX_EXP_GREN_SNOW;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
@@ -1115,14 +1156,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
break;
|
||||
case SFX_EXP_BAZOOKA_BASE:
|
||||
iSurfEffect = SFX_EXP_BAZOOKA_DIRT;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_BASE:
|
||||
iSurfEffect = SFX_EXP_HEAVYSHELL_DIRT;
|
||||
break;
|
||||
default:
|
||||
iSurfEffect = SFX_EXP_GREN_DIRT;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
@@ -1144,7 +1189,9 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
break;
|
||||
default:
|
||||
iSurfEffect = SFX_EXP_GREN_GRASS;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
@@ -1156,14 +1203,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
break;
|
||||
case SFX_EXP_BAZOOKA_BASE:
|
||||
iSurfEffect = SFX_EXP_BAZOOKA_STONE;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_BASE:
|
||||
iSurfEffect = SFX_EXP_HEAVYSHELL_STONE;
|
||||
break;
|
||||
default:
|
||||
iSurfEffect = SFX_EXP_GREN_STONE;
|
||||
iBaseEffect = -1;
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
iBaseEffect = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1211,7 +1262,9 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
);
|
||||
}
|
||||
|
||||
sfxManager.MakeEffect_Normal(iBaseEffect, vEnd, trace.plane.normal);
|
||||
if (iBaseEffect != -1) {
|
||||
sfxManager.MakeEffect_Normal(iBaseEffect, vEnd, trace.plane.normal);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_MakeVehicleEffect(vec3_t i_vStart, vec3_t i_vEnd, vec3_t i_vDir)
|
||||
@@ -1247,10 +1300,10 @@ void CG_ParseCGMessage_ver_15()
|
||||
iType = cgi.MSG_ReadBits(6);
|
||||
|
||||
switch (iType) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
if (iType == 1) {
|
||||
case CGM_BULLET_1:
|
||||
case CGM_BULLET_2:
|
||||
case CGM_BULLET_5:
|
||||
if (iType == CGM_BULLET_1) {
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1259,7 +1312,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
|
||||
if (iType != 1) {
|
||||
if (iType != CGM_BULLET_1) {
|
||||
vTmp[0] = vStart[0];
|
||||
vTmp[1] = vStart[1];
|
||||
vTmp[2] = vStart[2];
|
||||
@@ -1279,18 +1332,18 @@ void CG_ParseCGMessage_ver_15()
|
||||
alpha = 1.0f;
|
||||
}
|
||||
|
||||
if (iType == 1) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
|
||||
} else if (iType == 2) {
|
||||
if (iType == CGM_BULLET_1) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
|
||||
} else if (iType == CGM_BULLET_2) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
|
||||
} else {
|
||||
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge, alpha);
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if (iType == 3) {
|
||||
case CGM_BULLET_3:
|
||||
case CGM_BULLET_4:
|
||||
if (iType == CGM_BULLET_3) {
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1324,12 +1377,12 @@ void CG_ParseCGMessage_ver_15()
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue, alpha);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case CGM_BULLET_6:
|
||||
case CGM_BULLET_7:
|
||||
case CGM_BULLET_8:
|
||||
case CGM_BULLET_9:
|
||||
case CGM_BULLET_10:
|
||||
case CGM_BULLET_11:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1337,7 +1390,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
iLarge = cgi.MSG_ReadBits(2);
|
||||
|
||||
switch (iType) {
|
||||
case 6:
|
||||
case CGM_BULLET_6:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
@@ -1346,16 +1399,16 @@ void CG_ParseCGMessage_ver_15()
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case CGM_BULLET_7:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 6;
|
||||
wall_impact_type[wall_impact_count] = SFX_BHIT_STONE_LITE;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
case CGM_BULLET_8:
|
||||
if (flesh_impact_count < MAX_IMPACTS) {
|
||||
// negative
|
||||
VectorNegate(vEnd, vEnd);
|
||||
@@ -1365,7 +1418,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
flesh_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
case CGM_BULLET_9:
|
||||
if (flesh_impact_count < MAX_IMPACTS) {
|
||||
// negative
|
||||
VectorNegate(vEnd, vEnd);
|
||||
@@ -1375,21 +1428,21 @@ void CG_ParseCGMessage_ver_15()
|
||||
flesh_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
case CGM_BULLET_10:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 2;
|
||||
wall_impact_type[wall_impact_count] = SFX_BHIT_WOOD_LITE;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
case CGM_BULLET_11:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 4;
|
||||
wall_impact_type[wall_impact_count] = SFX_BHIT_METAL_LITE;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
@@ -1398,7 +1451,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
case CGM_MELEE_IMPACT:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1407,33 +1460,33 @@ void CG_ParseCGMessage_ver_15()
|
||||
vEnd[2] = cgi.MSG_ReadCoord();
|
||||
CG_MeleeImpact(vStart, vEnd);
|
||||
break;
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case CGM_EXPLOSION_EFFECT_1:
|
||||
case CGM_EXPLOSION_EFFECT_2:
|
||||
case CGM_EXPLOSION_EFFECT_3:
|
||||
case CGM_EXPLOSION_EFFECT_4:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
CG_MakeExplosionEffect(vStart, iType);
|
||||
break;
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case CGM_MAKE_EFFECT_1:
|
||||
case CGM_MAKE_EFFECT_2:
|
||||
case CGM_MAKE_EFFECT_3:
|
||||
case CGM_MAKE_EFFECT_4:
|
||||
case CGM_MAKE_EFFECT_5:
|
||||
case CGM_MAKE_EFFECT_6:
|
||||
case CGM_MAKE_EFFECT_7:
|
||||
case CGM_MAKE_EFFECT_8:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadDir(vEnd);
|
||||
|
||||
sfxManager.MakeEffect_Normal(iType + SFX_EXP_GREN_PUDDLE, vStart, vEnd);
|
||||
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
|
||||
break;
|
||||
|
||||
case 26:
|
||||
case 27:
|
||||
case CGM_MAKE_CRATE_DEBRIS:
|
||||
case CGM_MAKE_WINDOW_DEBRIS:
|
||||
{
|
||||
str sEffect;
|
||||
char cTmp[8];
|
||||
@@ -1446,7 +1499,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
// get the integer as string
|
||||
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
|
||||
|
||||
if (iType == 26) {
|
||||
if (iType == CGM_MAKE_CRATE_DEBRIS) {
|
||||
sEffect = "models/fx/crates/debris_";
|
||||
} else {
|
||||
sEffect = "models/fx/windows/debris_";
|
||||
@@ -1463,7 +1516,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
}
|
||||
break;
|
||||
|
||||
case 28:
|
||||
case CGM_BULLET_NO_BARREL_1:
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1474,6 +1527,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
vEndArray[0][1] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(2);
|
||||
|
||||
if (cgi.MSG_ReadBits(1)) {
|
||||
int iAlpha = cgi.MSG_ReadBits(10);
|
||||
alpha = (float)iAlpha / 512.0;
|
||||
@@ -1487,7 +1541,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
|
||||
break;
|
||||
|
||||
case 29:
|
||||
case CGM_BULLET_NO_BARREL_2:
|
||||
memset(vTmp, 0, sizeof(vTmp));
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
@@ -1496,6 +1550,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
vEndArray[0][1] = cgi.MSG_ReadCoord();
|
||||
vEndArray[0][2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(1);
|
||||
|
||||
if (cgi.MSG_ReadBits(1)) {
|
||||
int iAlpha = cgi.MSG_ReadBits(10);
|
||||
alpha = (float)iAlpha / 512.0;
|
||||
@@ -1509,7 +1564,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
|
||||
break;
|
||||
|
||||
case 30:
|
||||
case CGM_HUDDRAW_SHADER:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
|
||||
cgi.HudDrawElements[iInfo].string[0] = 0;
|
||||
@@ -1519,13 +1574,13 @@ void CG_ParseCGMessage_ver_15()
|
||||
CG_HudDrawShader(iInfo);
|
||||
break;
|
||||
|
||||
case 31:
|
||||
case CGM_HUDDRAW_ALIGN:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
|
||||
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
case CGM_HUDDRAW_RECT:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
|
||||
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
|
||||
@@ -1533,30 +1588,30 @@ void CG_ParseCGMessage_ver_15()
|
||||
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
|
||||
break;
|
||||
|
||||
case 33:
|
||||
case CGM_HUDDRAW_VIRTUALSIZE:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
|
||||
break;
|
||||
|
||||
case 34:
|
||||
case CGM_HUDDRAW_COLOR:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 35:
|
||||
case CGM_HUDDRAW_ALPHA:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 36:
|
||||
case CGM_HUDDRAW_STRING:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
|
||||
break;
|
||||
|
||||
case 37:
|
||||
case CGM_HUDDRAW_FONT:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
@@ -1565,14 +1620,14 @@ void CG_ParseCGMessage_ver_15()
|
||||
CG_HudDrawFont(iInfo);
|
||||
break;
|
||||
|
||||
case 38:
|
||||
case 39:
|
||||
case CGM_NOTIFY_KILL:
|
||||
case CGM_NOTIFY_HIT:
|
||||
{
|
||||
int iOldEnt;
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
if (iType == 36) {
|
||||
if (iType == CGM_NOTIFY_HIT) {
|
||||
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
} else {
|
||||
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
@@ -1582,7 +1637,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
}
|
||||
break;
|
||||
|
||||
case 40:
|
||||
case CGM_VOICE_CHAT:
|
||||
{
|
||||
int iOldEnt;
|
||||
|
||||
@@ -1608,7 +1663,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
current_entity_number = iOldEnt;
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
case CGM_FENCEPOST:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1647,10 +1702,10 @@ void CG_ParseCGMessage_ver_6()
|
||||
iType = cgi.MSG_ReadBits(6);
|
||||
|
||||
switch (iType) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
if (iType == 1) {
|
||||
case CGM6_BULLET_1:
|
||||
case CGM6_BULLET_2:
|
||||
case CGM6_BULLET_5:
|
||||
if (iType == CGM6_BULLET_1) {
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1659,7 +1714,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
|
||||
if (iType != 1) {
|
||||
if (iType != CGM6_BULLET_1) {
|
||||
vTmp[0] = vStart[0];
|
||||
vTmp[1] = vStart[1];
|
||||
vTmp[2] = vStart[2];
|
||||
@@ -1670,18 +1725,18 @@ void CG_ParseCGMessage_ver_6()
|
||||
vEndArray[0][2] = cgi.MSG_ReadCoord();
|
||||
iLarge = cgi.MSG_ReadBits(1);
|
||||
|
||||
if (iType == 1) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
|
||||
} else if (iType == 2) {
|
||||
if (iType == CGM6_BULLET_1) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue);
|
||||
} else if (iType == CGM6_BULLET_2) {
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
|
||||
} else {
|
||||
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge);
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if (iType == 3) {
|
||||
case CGM6_BULLET_3:
|
||||
case CGM6_BULLET_4:
|
||||
if (iType == CGM6_BULLET_3) {
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1705,11 +1760,11 @@ void CG_ParseCGMessage_ver_6()
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case CGM6_BULLET_6:
|
||||
case CGM6_BULLET_7:
|
||||
case CGM6_BULLET_8:
|
||||
case CGM6_BULLET_9:
|
||||
case CGM6_BULLET_10:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1717,16 +1772,16 @@ void CG_ParseCGMessage_ver_6()
|
||||
iLarge = cgi.MSG_ReadBits(1);
|
||||
|
||||
switch (iType) {
|
||||
case 6:
|
||||
case CGM6_BULLET_6:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = 0;
|
||||
wall_impact_type[wall_impact_count] = SFX_BHIT_PAPER_LITE;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case CGM6_BULLET_7:
|
||||
if (flesh_impact_count < MAX_IMPACTS) {
|
||||
// negative
|
||||
VectorNegate(vEnd, vEnd);
|
||||
@@ -1736,7 +1791,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
flesh_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
case CGM6_BULLET_8:
|
||||
if (flesh_impact_count < MAX_IMPACTS) {
|
||||
// negative
|
||||
VectorNegate(vEnd, vEnd);
|
||||
@@ -1746,21 +1801,21 @@ void CG_ParseCGMessage_ver_6()
|
||||
flesh_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
case CGM6_BULLET_9:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = (iLarge != 0) + 2;
|
||||
wall_impact_type[wall_impact_count] = iLarge ? SFX_BHIT_WOOD_HARD : SFX_BHIT_WOOD_LITE;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
case CGM6_BULLET_10:
|
||||
if (wall_impact_count < MAX_IMPACTS) {
|
||||
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
|
||||
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
|
||||
wall_impact_large[wall_impact_count] = iLarge;
|
||||
wall_impact_type[wall_impact_count] = (iLarge != 0) + 4;
|
||||
wall_impact_type[wall_impact_count] = iLarge ? SFX_BHIT_METAL_HARD : SFX_BHIT_METAL_LITE;
|
||||
wall_impact_count++;
|
||||
}
|
||||
break;
|
||||
@@ -1769,7 +1824,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case CGM6_MELEE_IMPACT:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1778,31 +1833,31 @@ void CG_ParseCGMessage_ver_6()
|
||||
vEnd[2] = cgi.MSG_ReadCoord();
|
||||
CG_MeleeImpact(vStart, vEnd);
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case CGM6_EXPLOSION_EFFECT_1:
|
||||
case CGM6_EXPLOSION_EFFECT_2:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
CG_MakeExplosionEffect(vStart, iType);
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case CGM6_MAKE_EFFECT_1:
|
||||
case CGM6_MAKE_EFFECT_2:
|
||||
case CGM6_MAKE_EFFECT_3:
|
||||
case CGM6_MAKE_EFFECT_4:
|
||||
case CGM6_MAKE_EFFECT_5:
|
||||
case CGM6_MAKE_EFFECT_6:
|
||||
case CGM6_MAKE_EFFECT_7:
|
||||
case CGM6_MAKE_EFFECT_8:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadDir(vEnd);
|
||||
|
||||
sfxManager.MakeEffect_Normal(iType + SFX_EXP_GREN_PUDDLE, vStart, vEnd);
|
||||
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
|
||||
break;
|
||||
|
||||
case 23:
|
||||
case 24:
|
||||
case CGM6_MAKE_CRATE_DEBRIS:
|
||||
case CGM6_MAKE_WINDOW_DEBRIS:
|
||||
{
|
||||
str sEffect;
|
||||
char cTmp[8];
|
||||
@@ -1815,7 +1870,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
// get the integer as string
|
||||
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
|
||||
|
||||
if (iType == 23) {
|
||||
if (iType == CGM6_MAKE_CRATE_DEBRIS) {
|
||||
sEffect = "models/fx/crates/debris_";
|
||||
} else {
|
||||
sEffect = "models/fx/windows/debris_";
|
||||
@@ -1832,7 +1887,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
}
|
||||
break;
|
||||
|
||||
case 25:
|
||||
case CGM6_BULLET_NO_BARREL_1:
|
||||
vTmp[0] = cgi.MSG_ReadCoord();
|
||||
vTmp[1] = cgi.MSG_ReadCoord();
|
||||
vTmp[2] = cgi.MSG_ReadCoord();
|
||||
@@ -1847,7 +1902,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue);
|
||||
break;
|
||||
|
||||
case 26:
|
||||
case CGM6_BULLET_NO_BARREL_2:
|
||||
memset(vTmp, 0, sizeof(vTmp));
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
@@ -1860,7 +1915,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
|
||||
break;
|
||||
|
||||
case 27:
|
||||
case CGM6_HUDDRAW_SHADER:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
|
||||
cgi.HudDrawElements[iInfo].string[0] = 0;
|
||||
@@ -1870,13 +1925,13 @@ void CG_ParseCGMessage_ver_6()
|
||||
CG_HudDrawShader(iInfo);
|
||||
break;
|
||||
|
||||
case 28:
|
||||
case CGM6_HUDDRAW_ALIGN:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
|
||||
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
|
||||
break;
|
||||
|
||||
case 29:
|
||||
case CGM6_HUDDRAW_RECT:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
|
||||
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
|
||||
@@ -1884,30 +1939,30 @@ void CG_ParseCGMessage_ver_6()
|
||||
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
|
||||
break;
|
||||
|
||||
case 30:
|
||||
case CGM6_HUDDRAW_VIRTUALSIZE:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
|
||||
break;
|
||||
|
||||
case 31:
|
||||
case CGM6_HUDDRAW_COLOR:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
case CGM6_HUDDRAW_ALPHA:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 33:
|
||||
case CGM6_HUDDRAW_STRING:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
|
||||
break;
|
||||
|
||||
case 34:
|
||||
case CGM6_HUDDRAW_FONT:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
@@ -1916,14 +1971,14 @@ void CG_ParseCGMessage_ver_6()
|
||||
CG_HudDrawFont(iInfo);
|
||||
break;
|
||||
|
||||
case 35:
|
||||
case 36:
|
||||
case CGM6_NOTIFY_KILL:
|
||||
case CGM6_NOTIFY_HIT:
|
||||
{
|
||||
int iOldEnt;
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
if (iType == 36) {
|
||||
if (iType == CGM6_NOTIFY_HIT) {
|
||||
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
} else {
|
||||
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
@@ -1933,7 +1988,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
}
|
||||
break;
|
||||
|
||||
case 37:
|
||||
case CGM6_VOICE_CHAT:
|
||||
{
|
||||
int iOldEnt;
|
||||
|
||||
|
||||
@@ -430,6 +430,8 @@ functions exported to the main executable
|
||||
void (*CL_RestoreSavedCgameState)();
|
||||
void (*CL_ClearSavedCgameState)();
|
||||
|
||||
size_t (*getConfigStringIdNormalized)(size_t num);
|
||||
|
||||
cvar_t *fsDebug;
|
||||
hdelement_t *HudDrawElements;
|
||||
clientAnim_t *anim;
|
||||
|
||||
@@ -296,7 +296,7 @@ static void CG_ServerCommand(qboolean modelOnly)
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "cs")) {
|
||||
CG_ConfigStringModified(atoi(cgi.Argv(1)), modelOnly);
|
||||
CG_ConfigStringModified(cgi.getConfigStringIdNormalized(atoi(cgi.Argv(1))), modelOnly);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+175
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -38,7 +38,8 @@ static vec3_t g_vLadderstepMaxs;
|
||||
|
||||
ClientSpecialEffectsManager sfxManager;
|
||||
|
||||
Event EV_SFX_EffectDelay(
|
||||
Event EV_SFX_EffectDelay
|
||||
(
|
||||
"effectdelay",
|
||||
EV_DEFAULT,
|
||||
"iivvvvv",
|
||||
@@ -234,9 +235,15 @@ void ClientSpecialEffectsManager::LoadEffects()
|
||||
szEffectModel = "models/fx/bazookaexp_base.tik";
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_BASE:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/heavyshellexp_base.tik";
|
||||
break;
|
||||
case SFX_EXP_TANK_BASE:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/tankexp_base.tik";
|
||||
break;
|
||||
case SFX_EXP_GREN_PAPER:
|
||||
@@ -285,30 +292,57 @@ void ClientSpecialEffectsManager::LoadEffects()
|
||||
szEffectModel = "models/fx/grenexp_carpet.tik";
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_DIRT:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/heavyshellexp_dirt.tik";
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_STONE:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/heavyshellexp_stone.tik";
|
||||
break;
|
||||
case SFX_EXP_HEAVYSHELL_SNOW:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/heavyshellexp_snow.tik";
|
||||
break;
|
||||
case SFX_EXP_TANK_DIRT:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/tankexp_dirt.tik";
|
||||
break;
|
||||
case SFX_EXP_TANK_STONE:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/tankexp_stone.tik";
|
||||
break;
|
||||
case SFX_EXP_TANK_SNOW:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/tankexp_snow.tik";
|
||||
break;
|
||||
case SFX_EXP_BAZOOKA_DIRT:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/bazookaexp_dirt.tik";
|
||||
break;
|
||||
case SFX_EXP_BAZOOKA_STONE:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/bazookaexp_stone.tik";
|
||||
break;
|
||||
case SFX_EXP_BAZOOKA_SNOW:
|
||||
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
continue;
|
||||
}
|
||||
szEffectModel = "models/fx/bazookaexp_snow.tik";
|
||||
break;
|
||||
case SFX_WATER_RIPPLE_STILL:
|
||||
@@ -486,7 +520,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
|
||||
AxisCopy(axis, pCommand->emitter->tag_axis);
|
||||
pCommand->emitter->cgd.createTime = cg.time;
|
||||
commandManager.SetSpawnthing(pCommand->emitter);
|
||||
|
||||
|
||||
(commandManager.*pCommand->endfcn)();
|
||||
}
|
||||
}
|
||||
@@ -904,7 +938,144 @@ void CG_LandingSound(centity_t *ent, refEntity_t *pREnt, float volume, int iEqui
|
||||
|
||||
void CG_BodyFallSound(centity_t *ent, refEntity_t *pREnt, float volume)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
int contents;
|
||||
int surftype;
|
||||
int iEffectNum = -1;
|
||||
vec3_t vStart, vEnd;
|
||||
vec3_t midlegs;
|
||||
str sSoundName;
|
||||
trace_t trace;
|
||||
|
||||
VectorCopy(ent->lerpOrigin, vStart);
|
||||
vStart[2] += 8;
|
||||
|
||||
VectorCopy(vStart, vEnd);
|
||||
vEnd[2] -= 64;
|
||||
|
||||
if (ent->currentState.eType == ET_PLAYER) {
|
||||
CG_Trace(
|
||||
&trace,
|
||||
vStart,
|
||||
g_vFootstepMins,
|
||||
g_vFootstepMaxs,
|
||||
vEnd,
|
||||
ent->currentState.number,
|
||||
MASK_PLAYERSOLID,
|
||||
qtrue,
|
||||
qtrue,
|
||||
"Player Landing"
|
||||
);
|
||||
} else {
|
||||
CG_Trace(
|
||||
&trace,
|
||||
vStart,
|
||||
g_vFootstepMins,
|
||||
g_vFootstepMaxs,
|
||||
vEnd,
|
||||
ent->currentState.number,
|
||||
MASK_MONSTERSOLID,
|
||||
qfalse,
|
||||
qfalse,
|
||||
"Monster Landing"
|
||||
);
|
||||
}
|
||||
|
||||
if (trace.fraction == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
sSoundName = "snd_bodyfall_";
|
||||
contents = CG_PointContents(trace.endpos, -1);
|
||||
if (contents & MASK_WATER) {
|
||||
// take our ground position and trace upwards
|
||||
VectorCopy(trace.endpos, midlegs);
|
||||
midlegs[2] += WATER_NO_SPLASH_HEIGHT;
|
||||
contents = CG_PointContents(midlegs, -1);
|
||||
if (contents & MASK_WATER) {
|
||||
sSoundName += "wade";
|
||||
} else {
|
||||
sSoundName += "puddle";
|
||||
iEffectNum = SFX_FOOT_PUDDLE;
|
||||
}
|
||||
} else {
|
||||
surftype = trace.surfaceFlags & MASK_SURF_TYPE;
|
||||
switch (surftype) {
|
||||
case SURF_FOLIAGE:
|
||||
sSoundName += "foliage";
|
||||
iEffectNum = SFX_FOOT_GRASS;
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
sSoundName += "snow";
|
||||
iEffectNum = SFX_FOOT_SNOW;
|
||||
break;
|
||||
case SURF_CARPET:
|
||||
sSoundName += "carpet";
|
||||
iEffectNum = SFX_FOOT_LIGHT_DUST;
|
||||
break;
|
||||
case SURF_SAND:
|
||||
sSoundName += "sand";
|
||||
iEffectNum = SFX_FOOT_SAND;
|
||||
break;
|
||||
case SURF_PUDDLE:
|
||||
sSoundName += "puddle";
|
||||
iEffectNum = SFX_FOOT_PUDDLE;
|
||||
break;
|
||||
case SURF_GLASS:
|
||||
sSoundName += "glass";
|
||||
iEffectNum = SFX_FOOT_LIGHT_DUST;
|
||||
break;
|
||||
case SURF_GRAVEL:
|
||||
sSoundName += "gravel";
|
||||
iEffectNum = SFX_FOOT_HEAVY_DUST;
|
||||
break;
|
||||
case SURF_MUD:
|
||||
sSoundName += "mud";
|
||||
iEffectNum = SFX_FOOT_MUD;
|
||||
break;
|
||||
case SURF_DIRT:
|
||||
sSoundName += "dirt";
|
||||
iEffectNum = SFX_FOOT_DIRT;
|
||||
break;
|
||||
case SURF_GRILL:
|
||||
sSoundName += "grill";
|
||||
iEffectNum = SFX_FOOT_LIGHT_DUST;
|
||||
break;
|
||||
case SURF_GRASS:
|
||||
sSoundName += "grass";
|
||||
iEffectNum = SFX_FOOT_GRASS;
|
||||
break;
|
||||
case SURF_ROCK:
|
||||
sSoundName += "stone";
|
||||
iEffectNum = SFX_FOOT_HEAVY_DUST;
|
||||
break;
|
||||
case SURF_PAPER:
|
||||
sSoundName += "paper";
|
||||
iEffectNum = SFX_FOOT_LIGHT_DUST;
|
||||
break;
|
||||
case SURF_WOOD:
|
||||
sSoundName += "wood";
|
||||
iEffectNum = SFX_FOOT_LIGHT_DUST;
|
||||
break;
|
||||
case SURF_METAL:
|
||||
sSoundName += "metal";
|
||||
iEffectNum = SFX_FOOT_LIGHT_DUST;
|
||||
break;
|
||||
default:
|
||||
sSoundName += "stone";
|
||||
iEffectNum = SFX_FOOT_HEAVY_DUST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cg_debugFootsteps->integer) {
|
||||
cgi.DPrintf("BodyFall: %s volume: %.2f effect = %i\n", sSoundName.c_str(), volume, iEffectNum);
|
||||
}
|
||||
|
||||
commandManager.PlaySound(sSoundName, trace.endpos, -1, volume, -1, -1, 1);
|
||||
|
||||
if (iEffectNum != -1) {
|
||||
sfxManager.MakeEffect_Angles(iEffectNum, trace.endpos, Vector(270, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1146,7 +1146,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
newForward = p->cgd.origin - m_spawnthing->cgd.origin;
|
||||
newForward.normalize();
|
||||
}
|
||||
} else if (m_spawnthing->cgd.flags & T_SPHERE) {
|
||||
} else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
|
||||
// Project the origin along a random ray, and set the forward
|
||||
// vector pointing back to the origin
|
||||
Vector dir, end;
|
||||
@@ -1182,10 +1182,9 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
cosa = cos(fAngle);
|
||||
|
||||
p->cgd.origin = start + vForward * fHeight;
|
||||
p->cgd.origin += start + vLeft * (cosa * fRadius);
|
||||
p->cgd.origin += start + vUp * (sina * fRadius);
|
||||
} else if (m_spawnthing->sphereRadius != 0) // Offset in a spherical pattern
|
||||
{
|
||||
p->cgd.origin += vLeft * (cosa * fRadius);
|
||||
p->cgd.origin += vUp * (sina * fRadius);
|
||||
} else if (m_spawnthing->sphereRadius != 0) { // Offset in a spherical pattern
|
||||
Vector dir, end;
|
||||
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
|
||||
@@ -560,17 +560,6 @@ static int CG_CalcViewValues(void)
|
||||
CG_CalcVrect();
|
||||
CG_SetupFog();
|
||||
|
||||
// setup fog and far clipping plane
|
||||
cg.refdef.farplane_distance = cg.farplane_distance;
|
||||
VectorCopy(cg.farplane_color, cg.refdef.farplane_color);
|
||||
cg.refdef.farplane_cull = cg.farplane_cull;
|
||||
|
||||
// setup portal sky
|
||||
cg.refdef.sky_alpha = cg.sky_alpha;
|
||||
cg.refdef.sky_portal = cg.sky_portal;
|
||||
memcpy(cg.refdef.sky_axis, cg.sky_axis, sizeof(cg.sky_axis));
|
||||
VectorCopy(cg.sky_origin, cg.refdef.sky_origin);
|
||||
|
||||
ps = &cg.predicted_player_state;
|
||||
|
||||
VectorCopy(ps->origin, cg.refdef.vieworg);
|
||||
|
||||
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
static const char *AnimPrefixList[] = {
|
||||
"",
|
||||
"unarmed",
|
||||
"papers",
|
||||
"colt45",
|
||||
"p38",
|
||||
@@ -45,7 +46,6 @@ static const char *AnimPrefixList[] = {
|
||||
"bazooka",
|
||||
"panzerschreck",
|
||||
"shotgun",
|
||||
"unarmed",
|
||||
//
|
||||
// Team Assault and Team Tactics weapons
|
||||
"mg42portable",
|
||||
@@ -82,6 +82,7 @@ static const char *AnimPrefixList[] = {
|
||||
|
||||
enum animPrefix_e {
|
||||
WPREFIX_NONE,
|
||||
WPREFIX_UNARMED,
|
||||
WPREFIX_PAPERS,
|
||||
WPREFIX_COLT45,
|
||||
WPREFIX_P38,
|
||||
@@ -99,7 +100,6 @@ enum animPrefix_e {
|
||||
WPREFIX_BAZOOKA,
|
||||
WPREFIX_PANZERSCHRECK,
|
||||
WPREFIX_SHOTGUN,
|
||||
WPREFIX_UNARMED,
|
||||
//
|
||||
// Team Assault and Team Tactics weapons
|
||||
WPREFIX_MG42_PORTABLE,
|
||||
@@ -308,6 +308,9 @@ int CG_GetVMAnimPrefixIndex()
|
||||
if (!Q_stricmp(szWeaponName, "Panzerschreck")) {
|
||||
return WPREFIX_PANZERSCHRECK;
|
||||
}
|
||||
if (!Q_stricmp(szWeaponName, "Gewehrgranate")) {
|
||||
return WPREFIX_KAR98_MORTAR;
|
||||
}
|
||||
if (!Q_stricmp(szWeaponName, "Shotgun")) {
|
||||
return WPREFIX_SHOTGUN;
|
||||
}
|
||||
@@ -335,9 +338,11 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
char szAnimName[MAX_QPATH];
|
||||
dtiki_t *pTiki;
|
||||
qboolean bAnimChanged;
|
||||
qboolean bWeaponChanged;
|
||||
|
||||
fCrossblendFrac = 0.0;
|
||||
bAnimChanged = 0;
|
||||
bAnimChanged = qfalse;
|
||||
bWeaponChanged = qfalse; // Added in OPM
|
||||
pTiki = pModel->tiki;
|
||||
|
||||
if (cgi.anim->g_iLastEquippedWeaponStat == cg.snap->ps.stats[STAT_EQUIPPED_WEAPON]
|
||||
@@ -348,7 +353,9 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
cgi.anim->g_iLastEquippedWeaponStat = cg.snap->ps.stats[STAT_EQUIPPED_WEAPON];
|
||||
strcpy(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]));
|
||||
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
|
||||
bAnimChanged = qtrue;
|
||||
|
||||
bAnimChanged = qtrue;
|
||||
bWeaponChanged = qtrue;
|
||||
}
|
||||
|
||||
if (cgi.anim->g_iLastVMAnim == -1) {
|
||||
@@ -422,20 +429,27 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
}
|
||||
|
||||
sprintf(szAnimName, "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
|
||||
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
|
||||
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0;
|
||||
if (!bWeaponChanged) {
|
||||
fCrossblendTime =
|
||||
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
|
||||
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0;
|
||||
|
||||
if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) {
|
||||
fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
|
||||
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
|
||||
if (cgi.anim->g_VMFrameInfo[i].weight) {
|
||||
if (i == cgi.anim->g_iCurrentVMAnimSlot) {
|
||||
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
|
||||
} else {
|
||||
cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac);
|
||||
if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) {
|
||||
fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
|
||||
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
|
||||
if (cgi.anim->g_VMFrameInfo[i].weight) {
|
||||
if (i == cgi.anim->g_iCurrentVMAnimSlot) {
|
||||
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
|
||||
} else {
|
||||
cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fCrossblendTime = 0;
|
||||
fCrossblendAmount = 0;
|
||||
fCrossblendFrac = 0;
|
||||
}
|
||||
|
||||
cgi.anim->g_iCurrentVMAnimSlot = (cgi.anim->g_iCurrentVMAnimSlot + 1) % MAX_FRAMEINFOS;
|
||||
@@ -450,17 +464,31 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].weight = 1.0;
|
||||
cgi.anim->g_iCurrentVMDuration = 0;
|
||||
|
||||
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
|
||||
if (!fCrossblendTime) {
|
||||
if (!bWeaponChanged) {
|
||||
fCrossblendTime =
|
||||
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
|
||||
if (!fCrossblendTime) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
|
||||
if (i != cgi.anim->g_iCurrentVMAnimSlot) {
|
||||
cgi.anim->g_VMFrameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
cgi.anim->g_bCrossblending = qfalse;
|
||||
} else {
|
||||
cgi.anim->g_bCrossblending = qtrue;
|
||||
}
|
||||
} else {
|
||||
// Added in OPM
|
||||
// If there is a new weapon, don't do any crossblend
|
||||
cgi.anim->g_bCrossblending = qfalse;
|
||||
|
||||
// clear crossblend values
|
||||
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
|
||||
if (i != cgi.anim->g_iCurrentVMAnimSlot) {
|
||||
cgi.anim->g_VMFrameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
cgi.anim->g_bCrossblending = qfalse;
|
||||
} else {
|
||||
cgi.anim->g_bCrossblending = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+283
-280
@@ -42,7 +42,9 @@ const char *cg_vsstypes[] = {
|
||||
"debris"
|
||||
};
|
||||
|
||||
cvssource_t *vss_sorttable[16384];
|
||||
#define MAX_VSS_SORTS 16384
|
||||
|
||||
cvssource_t *vss_sorttable[MAX_VSS_SORTS];
|
||||
|
||||
static int lastVSSFrameTime;
|
||||
static constexpr float MAX_VSS_COORDS = 8096.0;
|
||||
@@ -78,56 +80,57 @@ void VSS_AddRepulsion(cvssource_t *pA, cvssource_t *pB)
|
||||
|
||||
VectorSubtract(pA->newOrigin, pB->newOrigin, vPush);
|
||||
|
||||
if (vPush[0] || vPush[1] || vPush[2]) {
|
||||
fDist = VectorNormalize(vPush);
|
||||
f = fDist - pB->newRadius;
|
||||
|
||||
if (f > 0.0) {
|
||||
f *= pA->ooRadius;
|
||||
if (f > 1.49) {
|
||||
f = 0.0;
|
||||
} else {
|
||||
f = f * (f * 0.0161 + -0.3104) + 1.2887;
|
||||
}
|
||||
|
||||
if (f < 0.0) {
|
||||
f = f * 1.1;
|
||||
}
|
||||
|
||||
fForce = f;
|
||||
} else {
|
||||
fForce = 1.0;
|
||||
}
|
||||
|
||||
f = fDist - pA->newRadius;
|
||||
if (f > 0.0) {
|
||||
f *= pB->ooRadius;
|
||||
if (f > 1.49) {
|
||||
f = 0.0;
|
||||
} else {
|
||||
f = f * (f * 0.0161 + -0.3104) + 1.2887;
|
||||
}
|
||||
|
||||
if (f < 0.0) {
|
||||
f = f * 1.1;
|
||||
}
|
||||
|
||||
fForce += f;
|
||||
} else {
|
||||
fForce += 1.0;
|
||||
}
|
||||
|
||||
if (fForce <= -0.05 && fForce >= 0.05) {
|
||||
fForce = (pA->newRadius + pB->newRadius) * 0.03 * fForce;
|
||||
VectorScale(vPush, fForce, vPush);
|
||||
|
||||
VectorAdd(pA->repulsion, vPush, pA->repulsion);
|
||||
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
|
||||
}
|
||||
} else {
|
||||
if (!vPush[0] && !vPush[1] && !vPush[2]) {
|
||||
VectorSet(vPush, crandom(), crandom(), crandom());
|
||||
VectorAdd(pA->repulsion, vPush, pA->repulsion);
|
||||
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
|
||||
return;
|
||||
}
|
||||
|
||||
fDist = VectorNormalize(vPush);
|
||||
f = fDist - pB->newRadius;
|
||||
|
||||
if (f > 0.0f) {
|
||||
f *= pA->ooRadius;
|
||||
if (f > 1.49f) {
|
||||
f = 0.0f;
|
||||
} else {
|
||||
f = f * (f * 0.0161f + -0.3104f) + 1.2887f;
|
||||
}
|
||||
|
||||
if (f < 0.0) {
|
||||
f *= 1.1f;
|
||||
}
|
||||
|
||||
fForce = f;
|
||||
} else {
|
||||
fForce = 1.0;
|
||||
}
|
||||
|
||||
f = fDist - pA->newRadius;
|
||||
if (f > 0.0) {
|
||||
f *= pB->ooRadius;
|
||||
if (f > 1.49f) {
|
||||
f = 0.0f;
|
||||
} else {
|
||||
f = f * (f * 0.0161f + -0.3104f) + 1.2887f;
|
||||
}
|
||||
|
||||
if (f < 0.0) {
|
||||
f *= 1.1f;
|
||||
}
|
||||
|
||||
fForce += f;
|
||||
} else {
|
||||
fForce += 1.0f;
|
||||
}
|
||||
|
||||
if (fForce <= -0.05f || fForce >= 0.05f) {
|
||||
fForce = (pA->newRadius + pB->newRadius) * 0.03f * fForce;
|
||||
VectorScale(vPush, fForce, vPush);
|
||||
|
||||
VectorAdd(pA->repulsion, vPush, pA->repulsion);
|
||||
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,6 +337,8 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
float fDot;
|
||||
vec3_t vNorm;
|
||||
|
||||
VectorCopy(trace.plane.normal, vNorm);
|
||||
|
||||
VectorAdd(trace.endpos, trace.plane.normal, pSource->newOrigin);
|
||||
fDot = DotProduct(vNorm, pSource->velocity);
|
||||
VectorMA(pSource->velocity, fDot, vNorm, pSource->velocity);
|
||||
@@ -890,251 +895,249 @@ void VSS_CalcRepulsionForces(cvssource_t *pActiveSources)
|
||||
{
|
||||
cvssource_t *pCurrent;
|
||||
cvssource_t *pComp;
|
||||
qboolean bXUp, bXDown;
|
||||
qboolean bYUp, bYDown;
|
||||
qboolean bZDown;
|
||||
int i;
|
||||
int iIndex;
|
||||
int iX, iY, iZ;
|
||||
int iMinX, iMinY, iMinZ;
|
||||
int iMaxX, iMaxY, iMaxZ;
|
||||
float fOfs;
|
||||
cvssource_t *pSTLatch;
|
||||
|
||||
pCurrent = pActiveSources->prev;
|
||||
if (pCurrent != pActiveSources) {
|
||||
qboolean bXUp, bXDown;
|
||||
qboolean bYUp, bYDown;
|
||||
qboolean bZDown;
|
||||
int i;
|
||||
int iIndex;
|
||||
int iX, iY, iZ;
|
||||
int iMinX, iMinY, iMinZ;
|
||||
int iMaxX, iMaxY, iMaxZ;
|
||||
float fOfs;
|
||||
cvssource_t *pSTLatch;
|
||||
if (pCurrent == pActiveSources) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(vss_sorttable, 0, sizeof(vss_sorttable));
|
||||
memset(vss_sorttable, 0, sizeof(vss_sorttable));
|
||||
|
||||
while (pCurrent != pActiveSources) {
|
||||
VectorClear(pCurrent->repulsion);
|
||||
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
|
||||
VectorClear(pCurrent->repulsion);
|
||||
|
||||
iIndex = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
|
||||
iIndex |= ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32;
|
||||
iIndex |= (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
|
||||
iIndex = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
|
||||
iIndex |= (((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32) << 5;
|
||||
iIndex |= (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
|
||||
|
||||
pCurrent->stnext = vss_sorttable[iIndex];
|
||||
vss_sorttable[iIndex] = pCurrent;
|
||||
pCurrent->stindex = iIndex;
|
||||
pCurrent = pCurrent->prev;
|
||||
pCurrent->stnext = vss_sorttable[iIndex];
|
||||
vss_sorttable[iIndex] = pCurrent;
|
||||
pCurrent->stindex = iIndex;
|
||||
}
|
||||
|
||||
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
|
||||
if (vss_sorttable[pCurrent->stindex] == pCurrent) {
|
||||
pSTLatch = (cvssource_t *)-1;
|
||||
pComp = pCurrent->stnext;
|
||||
} else {
|
||||
pSTLatch = 0;
|
||||
pComp = vss_sorttable[pCurrent->stindex];
|
||||
}
|
||||
|
||||
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
|
||||
if (vss_sorttable[pCurrent->stindex] == pCurrent) {
|
||||
pSTLatch = (cvssource_t *)-1;
|
||||
pComp = pCurrent->stnext;
|
||||
} else {
|
||||
pSTLatch = 0;
|
||||
pComp = vss_sorttable[pCurrent->stindex];
|
||||
for(; pComp; pComp = pComp->stnext) {
|
||||
VSS_AddRepulsion(pCurrent, pComp);
|
||||
if (!pSTLatch && pComp->stnext == pCurrent) {
|
||||
pSTLatch = pComp;
|
||||
// skip current
|
||||
pComp = pComp->stnext;
|
||||
}
|
||||
}
|
||||
|
||||
iX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
|
||||
iY = (((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32) << 5;
|
||||
iZ = (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
|
||||
|
||||
fOfs = pCurrent->newRadius + 1.49 + 48.0;
|
||||
iMaxX = ((int)floor(pCurrent->newOrigin[0] + fOfs + 8192.0 + 0.5) / 96) % 32;
|
||||
iMaxY = (((int)floor(pCurrent->newOrigin[1] + fOfs + 8192.0 + 0.5) / 96) % 32) << 5;
|
||||
iMaxZ = (((int)floor(pCurrent->newOrigin[2] + fOfs + 8192.0 + 0.5) / 96) % 16) << 10;
|
||||
|
||||
iMinX = ((int)floor(pCurrent->newOrigin[0] - fOfs + 8192.0 + 0.5) / 96) % 32;
|
||||
iMinY = (((int)floor(pCurrent->newOrigin[1] - fOfs + 8192.0 + 0.5) / 96) % 32) << 5;
|
||||
iMinZ = (((int)floor(pCurrent->newOrigin[2] - fOfs + 8192.0 + 0.5) / 96) % 16) << 10;
|
||||
|
||||
bXUp = (iMaxX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
|
||||
bXDown = (iMinX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
|
||||
bYUp = (iMaxY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
|
||||
bYDown = (iMinY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
|
||||
|
||||
iIndex = iMinZ | (pCurrent->stindex & 0xFFFFC3FF);
|
||||
bZDown = iIndex != pCurrent->stindex;
|
||||
|
||||
if (iIndex == pCurrent->stindex) {
|
||||
iIndex = iMaxY | (pCurrent->stindex & 0xFFFFFC1F);
|
||||
|
||||
i = 9;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for (; i < (bZDown ? 26 : 17); i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
iIndex = iMaxZ | (pCurrent->stindex & 0xFFFFC3FF);
|
||||
break;
|
||||
case 1:
|
||||
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 2:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 3:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 4:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFFE0);
|
||||
if (bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 5:
|
||||
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXDown && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 6:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 7:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 8:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 9:
|
||||
iIndex = iZ | (iIndex & 0xFFFFFFC3);
|
||||
if (bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 10:
|
||||
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXUp && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 11:
|
||||
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXDown && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 12:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 13:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 14:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 15:
|
||||
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXUp && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 16:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 17:
|
||||
iIndex = iMinZ | (iIndex & 0xFFFFFCC3);
|
||||
if (bXUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 18:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 19:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 20:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 21:
|
||||
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXDown && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 22:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 23:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 24:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 25:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
break;
|
||||
default:
|
||||
assert(0); // This can't happen
|
||||
break;
|
||||
}
|
||||
|
||||
while (pComp) {
|
||||
for (pComp = vss_sorttable[iIndex]; pComp; pComp = pComp->stnext) {
|
||||
VSS_AddRepulsion(pCurrent, pComp);
|
||||
if (!pSTLatch && pComp->stnext == pCurrent) {
|
||||
pSTLatch = pComp;
|
||||
pComp = pComp->stnext;
|
||||
}
|
||||
|
||||
pComp = pComp->stnext;
|
||||
}
|
||||
iX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
|
||||
iY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32;
|
||||
iY *= 2;
|
||||
iZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16;
|
||||
iZ <<= 10;
|
||||
}
|
||||
|
||||
fOfs = pCurrent->newRadius + 1.49 + 48.0;
|
||||
iMaxX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 + fOfs) / 96) % 32;
|
||||
iMaxY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 + fOfs) / 96) % 32;
|
||||
iMaxY *= 2;
|
||||
iMaxZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5 + fOfs) / 96) % 16;
|
||||
iMaxZ <<= 10;
|
||||
|
||||
iMinX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 - fOfs) / 96) % 32;
|
||||
iMinY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 - fOfs) / 96) % 32;
|
||||
iMinY *= 2;
|
||||
iMinZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5 - fOfs) / 96) % 16;
|
||||
iMinZ <<= 10;
|
||||
|
||||
bXUp = (iMaxX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
|
||||
bXDown = (iMinX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
|
||||
bYUp = (iMaxY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
|
||||
bYDown = (iMinY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
|
||||
|
||||
iIndex = iMinZ | (pCurrent->stindex & 0xFFFFFCC3);
|
||||
bZDown = iIndex != pCurrent->stindex;
|
||||
|
||||
if (iIndex == pCurrent->stindex) {
|
||||
iIndex = iMaxY | pCurrent->stindex & 0xFFFFFC1F;
|
||||
i = 9;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for(; i < (bZDown ? 26 : 17); i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
iIndex = iMaxZ | (pCurrent->stindex & 0xFFFFFCC3);
|
||||
break;
|
||||
case 1:
|
||||
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 2:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 3:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 4:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFFE0);
|
||||
if (bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 5:
|
||||
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXDown && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 6:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 7:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 8:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 9:
|
||||
iIndex = iZ | (iIndex & 0xFFFFFFC3);
|
||||
if (bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 10:
|
||||
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXUp && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 11:
|
||||
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXDown && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 12:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 13:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 14:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 15:
|
||||
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXUp && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 16:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 17:
|
||||
iIndex = iMinZ | (iIndex & 0xFFFFFCC3);
|
||||
if (bXUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 18:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 19:
|
||||
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXUp && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 20:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 21:
|
||||
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
|
||||
if (bXDown && bYDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 22:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 23:
|
||||
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
|
||||
if (bXDown && bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 24:
|
||||
iIndex = iX | (iIndex & 0xFFFFFFE0);
|
||||
if (bYUp) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case 25:
|
||||
iIndex = iY | (iIndex & 0xFFFFFC1F);
|
||||
break;
|
||||
}
|
||||
|
||||
for (pComp = vss_sorttable[iIndex]; pComp; pComp = pComp->stnext) {
|
||||
VSS_AddRepulsion(pCurrent, pComp);
|
||||
}
|
||||
}
|
||||
|
||||
if (pSTLatch == (cvssource_t *)-1) {
|
||||
vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
|
||||
} else {
|
||||
pSTLatch->stnext = pCurrent->stnext;
|
||||
}
|
||||
if (pSTLatch == (cvssource_t *)-1) {
|
||||
vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
|
||||
} else {
|
||||
pSTLatch->stnext = pCurrent->stnext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,23 +42,23 @@ MemArchiver::~MemArchiver()
|
||||
|
||||
void MemArchiver::SetupForWriting(size_t initialSize)
|
||||
{
|
||||
state = MEMARC_WRITING;
|
||||
buffer = (byte*)cgi.Malloc(initialSize);
|
||||
allocatedSize = initialSize;
|
||||
bufferSize = 0;
|
||||
this->state = MEMARC_WRITING;
|
||||
this->buffer = (byte*)cgi.Malloc(initialSize);
|
||||
this->allocatedSize = initialSize;
|
||||
this->bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForReading(byte* buffer, size_t size)
|
||||
{
|
||||
state = MEMARC_READING;
|
||||
buffer = buffer;
|
||||
allocatedSize = size;
|
||||
bufferSize = 0;
|
||||
this->state = MEMARC_READING;
|
||||
this->buffer = buffer;
|
||||
this->allocatedSize = size;
|
||||
this->bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetBaseTime(unsigned int time)
|
||||
{
|
||||
svsTime = time;
|
||||
this->svsTime = time;
|
||||
}
|
||||
|
||||
size_t MemArchiver::BufferSize() const
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(omohclient)
|
||||
|
||||
option(NO_OPENAL "Use older sound-system" FALSE)
|
||||
|
||||
add_subdirectory("../cgame" "./cgame")
|
||||
|
||||
file(GLOB_RECURSE SOURCES_CLIENT "./*.c*")
|
||||
file(GLOB SOURCES_CLIENT "./*.c*")
|
||||
file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*")
|
||||
|
||||
# Made as an interface and not static, as static only links used methods
|
||||
add_library(omohclient INTERFACE)
|
||||
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
|
||||
target_compile_definitions(omohclient INTERFACE APP_MODULE)
|
||||
target_compile_definitions(omohclient INTERFACE USE_OPENAL_DLOPEN=1)
|
||||
target_compile_features(omohclient INTERFACE cxx_nullptr)
|
||||
target_compile_features(omohclient INTERFACE c_variadic_macros)
|
||||
target_link_libraries(omohclient INTERFACE omohsdl)
|
||||
@@ -18,5 +20,50 @@ target_link_libraries(omohclient INTERFACE gcd)
|
||||
# Sound stuff
|
||||
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
|
||||
|
||||
add_subdirectory("../libmad-0.15.1b" "./libmad")
|
||||
target_link_libraries(omohclient INTERFACE libmad)
|
||||
if (NOT NO_OPENAL)
|
||||
# Use OpenAL
|
||||
find_package(OpenAL REQUIRED)
|
||||
|
||||
if (OPENAL_FOUND)
|
||||
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1 NO_MODERN_DMA=0)
|
||||
if (MSVC)
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
|
||||
else()
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR})
|
||||
endif()
|
||||
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
|
||||
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.c$")
|
||||
file(GLOB SOURCES_CLIENT_SND "./snd_*_new.c*" "./snd_codec*.c*")
|
||||
list(APPEND SOURCES_CLIENT ${SOURCES_CLIENT_SND})
|
||||
else()
|
||||
#
|
||||
# Fallback to old DMA sound system
|
||||
#
|
||||
message(NOTICE "OpenAL was explicitly disabled - fallback to old SDL sound system")
|
||||
target_compile_definitions(omohclient INTERFACE NO_MODERN_DMA=1)
|
||||
set(NO_MODERN_DMA TRUE)
|
||||
|
||||
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.cpp$")
|
||||
file(GLOB_RECURSE SOURCES_CLIENT_SND "./new/*.c*")
|
||||
list(APPEND SOURCES_CLIENT ${SOURCES_CLIENT_SND})
|
||||
endif()
|
||||
|
||||
set(OLD_VALUE ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(omohclient INTERFACE mad)
|
||||
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
|
||||
|
||||
if (USE_OPENAL)
|
||||
# Try to use OpenAL
|
||||
find_package(OpenAL)
|
||||
if (OPENAL_FOUND)
|
||||
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1)
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
|
||||
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
|
||||
@@ -334,6 +334,9 @@ writing the actual data can begin
|
||||
*/
|
||||
qboolean CL_OpenAVIForWriting( const char *fileName )
|
||||
{
|
||||
return qfalse;
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
if( afd.fileOpen )
|
||||
return qfalse;
|
||||
|
||||
@@ -425,6 +428,7 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
|
||||
afd.fileOpen = qtrue;
|
||||
|
||||
return qtrue;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+54
-18
@@ -211,20 +211,20 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
|
||||
}
|
||||
|
||||
snapshot->numEntities = 0;
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
for(i = 0; i < MAX_ENTITIES_IN_SNAPSHOT; i++) {
|
||||
parents[i] = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
pnum = s1->parent;
|
||||
|
||||
if (pnum == ENTITYNUM_NONE) {
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (parents[pnum] == -2) {
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// add it later
|
||||
parents[s1->number] = pnum;
|
||||
continue;
|
||||
@@ -234,20 +234,20 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
|
||||
snapshot->entities[snapshot->numEntities++] = *s1;
|
||||
}
|
||||
|
||||
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++) {
|
||||
for (i = 0; i < count; i++) {
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
pnum = parents[s1->number];
|
||||
if (pnum >= 0 && parents[pnum] == -2) {
|
||||
parents[s1->number] = -2;
|
||||
snapshot->entities[snapshot->numEntities++] = *s1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pcount >= 8)
|
||||
{
|
||||
if (snapshot->numEntities != count) {
|
||||
Com_DPrintf("CL_GetSnapshot: Not all children could find their parents.\n");
|
||||
|
||||
for (i = count; i < snapshot->numEntities; i++)
|
||||
{
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
@@ -261,6 +261,8 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
|
||||
s1->origin[1],
|
||||
s1->origin[2]
|
||||
);
|
||||
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,7 +360,9 @@ qboolean CL_ProcessServerCommand(const char* origString, const char* cmd, qboole
|
||||
// because this function might be called from a module that would be unloaded
|
||||
// inside Com_Error
|
||||
UI_ForceMenuOff(1);
|
||||
Cbuf_AddText("disconnect;pushmenu disconnected");
|
||||
// Fixed in OPM
|
||||
// Added a newline for next commands
|
||||
Cbuf_AddText("disconnect;pushmenu disconnected\n");
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
@@ -395,8 +399,8 @@ Set up argc/argv for the given command
|
||||
===================
|
||||
*/
|
||||
qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer ) {
|
||||
char *s;
|
||||
char *cmd;
|
||||
char *s;
|
||||
char *cmd;
|
||||
static char bigConfigString[BIG_INFO_STRING];
|
||||
|
||||
// if we have irretrievably lost a reliable command, drop the connection
|
||||
@@ -421,9 +425,39 @@ qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer
|
||||
Com_DPrintf( "serverCommand: %i : %s\n", serverCommandNumber, s );
|
||||
}
|
||||
|
||||
Cmd_TokenizeString( s );
|
||||
Cmd_TokenizeString(s);
|
||||
cmd = Cmd_Argv(0);
|
||||
|
||||
// Readded in OPM (from ioquake)
|
||||
// Configstring big buffer
|
||||
if (!strcmp(cmd, "bcs0")) {
|
||||
Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "bcs1")) {
|
||||
s = Cmd_Argv(2);
|
||||
if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) {
|
||||
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
|
||||
}
|
||||
strcat(bigConfigString, s);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "bcs2")) {
|
||||
s = Cmd_Argv(2);
|
||||
if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) {
|
||||
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
|
||||
}
|
||||
strcat(bigConfigString, s);
|
||||
strcat(bigConfigString, "\"");
|
||||
s = bigConfigString;
|
||||
|
||||
// reparse
|
||||
Cmd_TokenizeString(s);
|
||||
cmd = Cmd_Argv(0);
|
||||
}
|
||||
|
||||
return CL_ProcessServerCommand(s, cmd, differentServer);
|
||||
}
|
||||
|
||||
@@ -548,7 +582,7 @@ CL_RestoreSavedCgameState
|
||||
*/
|
||||
void CL_RestoreSavedCgameState() {
|
||||
if (cls.savedCgameState) {
|
||||
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
|
||||
cge->CG_LoadStateToBuffer(cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,6 +817,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
|
||||
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
|
||||
|
||||
cgi->getConfigStringIdNormalized = CPT_NormalizeConfigstring;
|
||||
|
||||
cgi->fsDebug = fs_debug;
|
||||
cgi->HudDrawElements = cls.HudDrawElements;
|
||||
cgi->anim = &cls.anim;
|
||||
|
||||
@@ -1091,6 +1091,8 @@ static void RoQReset( void ) {
|
||||
|
||||
static void RoQInterrupt(void)
|
||||
{
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
byte *framedata;
|
||||
short sbuf[32768];
|
||||
int ssize;
|
||||
@@ -1214,6 +1216,7 @@ redump:
|
||||
// assert(cinTable[currentHandle].RoQFrameSize <= 65536);
|
||||
// r = FS_Read( cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile );
|
||||
cinTable[currentHandle].RoQPlayed += cinTable[currentHandle].RoQFrameSize+8;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -1397,6 +1400,9 @@ CIN_PlayCinematic
|
||||
==================
|
||||
*/
|
||||
int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBits ) {
|
||||
return 0;
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
unsigned short RoQID;
|
||||
char name[MAX_OSPATH];
|
||||
int i;
|
||||
@@ -1478,6 +1484,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||
|
||||
RoQShutdown();
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIN_SetExtents (int handle, int x, int y, int w, int h) {
|
||||
|
||||
@@ -432,7 +432,7 @@ void CL_MouseEvent( int dx, int dy, int time ) {
|
||||
if( cl.mousey > cls.glconfig.vidHeight )
|
||||
cl.mousey = cls.glconfig.vidHeight;
|
||||
}
|
||||
else
|
||||
else if ( !paused->integer )
|
||||
{
|
||||
cl.mouseDx[cl.mouseIndex] += dx;
|
||||
cl.mouseDy[cl.mouseIndex] += dy;
|
||||
@@ -575,6 +575,14 @@ void CL_MouseMove( usercmd_t *cmd ) {
|
||||
cl.viewangles[PITCH] += m_pitch->value * my;
|
||||
else
|
||||
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
|
||||
|
||||
if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) {
|
||||
Com_DPrintf("Invalid client viewangles encountered (view pitch: %f, view yaw: %f)!\n", cl.viewangles[PITCH], cl.viewangles[YAW]);
|
||||
Com_DPrintf("cgameSensitivity: %f | mx: %f | my: %f | m_pitch: %f | m_yaw: %f\n", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value);
|
||||
Com_DPrintf("Resetting client viewangles\n");
|
||||
cl.viewangles[PITCH] = 0;
|
||||
cl.viewangles[YAW] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -991,7 +999,7 @@ void CL_SendCmd( void ) {
|
||||
}
|
||||
|
||||
// don't send commands if paused
|
||||
if ( com_sv_running->integer && paused->integer && paused->integer ) {
|
||||
if ( com_sv_running->integer && paused->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+973
-130
File diff suppressed because it is too large.
Load diff
+173
-150
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,175 +20,198 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_INV_H__
|
||||
#define __CL_INV_H__
|
||||
#pragma once
|
||||
|
||||
typedef enum { INV_MOVE_NONE, INV_MOVE_BOB, INV_MOVE_SPIN } inv_move_type;
|
||||
typedef enum { INV_CASCADE_LEFT, INV_CASCADE_RIGHT } inv_cascade_type;
|
||||
typedef enum { INV_HUDANGLES_BASE, INV_HUDANGLES_COMPASS, INV_HUDANGLES_COMPASS_NEEDLE } inv_hudangles_type;
|
||||
typedef enum {
|
||||
INV_MOVE_NONE,
|
||||
INV_MOVE_BOB,
|
||||
INV_MOVE_SPIN
|
||||
} inv_move_type;
|
||||
|
||||
class item_properties_t : public Class {
|
||||
public:
|
||||
float scale;
|
||||
Vector angles;
|
||||
Vector angledeltas;
|
||||
Vector rotateoffset;
|
||||
Vector offset;
|
||||
inv_move_type move;
|
||||
str model;
|
||||
str anim;
|
||||
};
|
||||
typedef enum {
|
||||
INV_ALIGN_NONE,
|
||||
INV_ALIGN_LEFT,
|
||||
INV_ALIGN_RIGHT
|
||||
} inv_align_type;
|
||||
|
||||
class inventory_item_t : public Class {
|
||||
public:
|
||||
str name;
|
||||
str ammoname;
|
||||
int equip;
|
||||
int width;
|
||||
int height;
|
||||
int barwidth;
|
||||
int barheight;
|
||||
int baroffsetY;
|
||||
int baroffsetX;
|
||||
float modelWindowX;
|
||||
float modelWindowY;
|
||||
float modelWindowWidth;
|
||||
float modelWindowHeight;
|
||||
bool selShaderOnTop;
|
||||
bool checkammo;
|
||||
str command;
|
||||
inv_hudangles_type anglesType;
|
||||
item_properties_t hudprops;
|
||||
item_properties_t invprops;
|
||||
UIReggedMaterial *bgshader;
|
||||
UIReggedMaterial *barshader;
|
||||
UIReggedMaterial *selshader;
|
||||
};
|
||||
typedef enum {
|
||||
INV_CASCADE_LEFT,
|
||||
INV_CASCADE_RIGHT
|
||||
} inv_cascade_type;
|
||||
|
||||
class inventory_type_t {
|
||||
public:
|
||||
str name;
|
||||
bool bg_tile;
|
||||
UIReggedMaterial *texture;
|
||||
UIReggedMaterial *bg;
|
||||
UIReggedMaterial *hoverTexture;
|
||||
UIReggedMaterial *selTexture;
|
||||
Container<inventory_item_t *> items;
|
||||
typedef enum {
|
||||
INV_HUDANGLES_BASE,
|
||||
INV_HUDANGLES_COMPASS,
|
||||
INV_HUDANGLES_COMPASS_NEEDLE
|
||||
} inv_hudangles_type;
|
||||
|
||||
int IndexOfItemPtr( inventory_item_t *item );
|
||||
};
|
||||
|
||||
inline
|
||||
int inventory_type_t::IndexOfItemPtr( inventory_item_t *item )
|
||||
class item_properties_t : public Class
|
||||
{
|
||||
for( int i = items.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
if( items.ObjectAt( i ) == item )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
public:
|
||||
float scale;
|
||||
Vector angles;
|
||||
Vector angledeltas;
|
||||
Vector rotateoffset;
|
||||
Vector offset;
|
||||
inv_move_type move;
|
||||
str model;
|
||||
str anim;
|
||||
};
|
||||
|
||||
return 0;
|
||||
class inventory_item_t : public Class
|
||||
{
|
||||
public:
|
||||
str name;
|
||||
str ammoname;
|
||||
int equip;
|
||||
int width;
|
||||
int height;
|
||||
int barwidth;
|
||||
int barheight;
|
||||
int baroffsetY;
|
||||
int baroffsetX;
|
||||
float modelWindowX;
|
||||
float modelWindowY;
|
||||
float modelWindowWidth;
|
||||
float modelWindowHeight;
|
||||
bool selShaderOnTop;
|
||||
bool checkammo;
|
||||
str command;
|
||||
inv_hudangles_type anglesType;
|
||||
item_properties_t hudprops;
|
||||
item_properties_t invprops;
|
||||
UIReggedMaterial *bgshader;
|
||||
UIReggedMaterial *barshader;
|
||||
UIReggedMaterial *selshader;
|
||||
};
|
||||
|
||||
class inventory_type_t
|
||||
{
|
||||
public:
|
||||
str name;
|
||||
bool bg_tile;
|
||||
UIReggedMaterial *texture;
|
||||
UIReggedMaterial *bg;
|
||||
UIReggedMaterial *hoverTexture;
|
||||
UIReggedMaterial *selTexture;
|
||||
Container<inventory_item_t *> items;
|
||||
|
||||
int IndexOfItemPtr(inventory_item_t *item);
|
||||
};
|
||||
|
||||
inline int inventory_type_t::IndexOfItemPtr(inventory_item_t *item)
|
||||
{
|
||||
for (int i = items.NumObjects(); i > 0; i--) {
|
||||
if (items.ObjectAt(i) == item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
class inventory_t {
|
||||
class inventory_t
|
||||
{
|
||||
public:
|
||||
int typewidth;
|
||||
int typeheight;
|
||||
int horizoffset;
|
||||
int vertoffset;
|
||||
int align;
|
||||
inv_cascade_type cascade;
|
||||
str selectsound;
|
||||
str rejectsound;
|
||||
str changesound;
|
||||
Container<inventory_type_t *> types;
|
||||
int typewidth;
|
||||
int typeheight;
|
||||
int horizoffset;
|
||||
int vertoffset;
|
||||
inv_align_type align;
|
||||
inv_cascade_type cascade;
|
||||
str selectsound;
|
||||
str rejectsound;
|
||||
str changesound;
|
||||
Container<inventory_type_t *> types;
|
||||
|
||||
void Clear() { types.ClearObjectList(); }
|
||||
public:
|
||||
inventory_t();
|
||||
~inventory_t();
|
||||
inventory_t(const inventory_t& other);
|
||||
inventory_t& operator=(const inventory_t& other);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
class invlistener : public Listener {
|
||||
class invlistener : public Listener
|
||||
{
|
||||
protected:
|
||||
inventory_t *inv;
|
||||
inventory_type_t *curtype;
|
||||
inventory_item_t *curitem;
|
||||
int defaultWidth;
|
||||
int defaultHeight;
|
||||
int defaultBarWidth;
|
||||
int defaultBarHeight;
|
||||
int defaultBarOffsetX;
|
||||
int defaultBarOffsetY;
|
||||
inventory_t *inv;
|
||||
inventory_type_t *curtype;
|
||||
inventory_item_t *curitem;
|
||||
int defaultWidth;
|
||||
int defaultHeight;
|
||||
int defaultBarWidth;
|
||||
int defaultBarHeight;
|
||||
int defaultBarOffsetX;
|
||||
int defaultBarOffsetY;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( invlistener );
|
||||
CLASS_PROTOTYPE(invlistener);
|
||||
|
||||
protected:
|
||||
void verify_curitem( void );
|
||||
void verify_curtype( void );
|
||||
void verify_one_arg( Event *ev );
|
||||
void verify_curitem(void);
|
||||
void verify_curtype(void);
|
||||
void verify_one_arg(Event *ev);
|
||||
|
||||
public:
|
||||
invlistener( inventory_t *i );
|
||||
invlistener();
|
||||
invlistener(inventory_t *i);
|
||||
invlistener();
|
||||
|
||||
bool Load( Script& script );
|
||||
void InvSelectSound( Event *ev );
|
||||
void InvRejectSound( Event *ev );
|
||||
void InvChangeSound( Event *ev );
|
||||
void InvWidth( Event *ev );
|
||||
void InvHeight( Event *ev );
|
||||
void InvHorizOffset( Event *ev );
|
||||
void InvVertOffset( Event *ev );
|
||||
void InvAlign( Event *ev );
|
||||
void InvCascade( Event *ev );
|
||||
void Typedef( Event *ev );
|
||||
void OpenBrace( Event *ev );
|
||||
void CloseBrace( Event *ev );
|
||||
void ButtonShader( Event *ev );
|
||||
void HoverShader( Event *ev );
|
||||
void SelShader( Event *ev );
|
||||
void Background( Event *ev );
|
||||
void BackgroundTile( Event *ev );
|
||||
void Width( Event *ev );
|
||||
void Height( Event *ev );
|
||||
void BarWidth( Event *ev );
|
||||
void BarHeight( Event *ev );
|
||||
void BarOffsetX( Event *ev );
|
||||
void BarOffsetY( Event *ev );
|
||||
void Item( Event *ev );
|
||||
void Ammo( Event *ev );
|
||||
void Equip( Event *ev );
|
||||
void CheckAmmo( Event *ev );
|
||||
void Command( Event *ev );
|
||||
void BGShader( Event *ev );
|
||||
void BarShader( Event *ev );
|
||||
void SelItemShader( Event *ev );
|
||||
void SelItemShaderOnTop( Event *ev );
|
||||
void RotateOffset( Event *ev );
|
||||
void Offset( Event *ev );
|
||||
void Model( Event *ev );
|
||||
void Anim( Event *ev );
|
||||
void Scale( Event *ev );
|
||||
void Angles( Event *ev );
|
||||
void AngleDeltas( Event *ev );
|
||||
void Move( Event *ev );
|
||||
void ModelWindow( Event *ev );
|
||||
void HudRotateOffset( Event *ev );
|
||||
void HudOffset( Event *ev );
|
||||
void HudModel( Event *ev );
|
||||
void HudAnim( Event *ev );
|
||||
void HudScale( Event *ev );
|
||||
void HudAngles( Event *ev );
|
||||
void HudAngleDeltas( Event *ev );
|
||||
void HudMove( Event *ev );
|
||||
void HudCompassAngles( Event *ev );
|
||||
void HudCompassNeedleAngles( Event *ev );
|
||||
bool Load(Script& script);
|
||||
void InvSelectSound(Event *ev);
|
||||
void InvRejectSound(Event *ev);
|
||||
void InvChangeSound(Event *ev);
|
||||
void InvWidth(Event *ev);
|
||||
void InvHeight(Event *ev);
|
||||
void InvHorizOffset(Event *ev);
|
||||
void InvVertOffset(Event *ev);
|
||||
void InvAlign(Event *ev);
|
||||
void InvCascade(Event *ev);
|
||||
void Typedef(Event *ev);
|
||||
void OpenBrace(Event *ev);
|
||||
void CloseBrace(Event *ev);
|
||||
void ButtonShader(Event *ev);
|
||||
void HoverShader(Event *ev);
|
||||
void SelShader(Event *ev);
|
||||
void Background(Event *ev);
|
||||
void BackgroundTile(Event *ev);
|
||||
void Width(Event *ev);
|
||||
void Height(Event *ev);
|
||||
void BarWidth(Event *ev);
|
||||
void BarHeight(Event *ev);
|
||||
void BarOffsetX(Event *ev);
|
||||
void BarOffsetY(Event *ev);
|
||||
void Item(Event *ev);
|
||||
void Ammo(Event *ev);
|
||||
void Equip(Event *ev);
|
||||
void CheckAmmo(Event *ev);
|
||||
void Command(Event *ev);
|
||||
void BGShader(Event *ev);
|
||||
void BarShader(Event *ev);
|
||||
void SelItemShader(Event *ev);
|
||||
void SelItemShaderOnTop(Event *ev);
|
||||
void RotateOffset(Event *ev);
|
||||
void Offset(Event *ev);
|
||||
void Model(Event *ev);
|
||||
void Anim(Event *ev);
|
||||
void Scale(Event *ev);
|
||||
void Angles(Event *ev);
|
||||
void AngleDeltas(Event *ev);
|
||||
void Move(Event *ev);
|
||||
void ModelWindow(Event *ev);
|
||||
void HudRotateOffset(Event *ev);
|
||||
void HudOffset(Event *ev);
|
||||
void HudModel(Event *ev);
|
||||
void HudAnim(Event *ev);
|
||||
void HudScale(Event *ev);
|
||||
void HudAngles(Event *ev);
|
||||
void HudAngleDeltas(Event *ev);
|
||||
void HudMove(Event *ev);
|
||||
void HudCompassAngles(Event *ev);
|
||||
void HudCompassNeedleAngles(Event *ev);
|
||||
};
|
||||
|
||||
bool CL_LoadInventory( const char *filename, inventory_t *inv );
|
||||
inventory_item_t *CL_GetInvItemByName( inventory_t *inv, const char *name );
|
||||
qboolean CL_HasInventoryItem( const char *name );
|
||||
void CL_AmmoCount( const char *name, int *ammo_count, int *max_ammo_count );
|
||||
|
||||
#endif // __CL_INV_H__
|
||||
bool CL_LoadInventory(const char *filename, inventory_t *inv);
|
||||
inventory_item_t *CL_GetInvItemByName(inventory_t *inv, const char *name);
|
||||
qboolean CL_HasInventoryItem(const char *name);
|
||||
void CL_AmmoCount(const char *name, int *ammo_count, int *max_ammo_count);
|
||||
+965
-132
File diff suppressed because it is too large.
Load diff
+81
-58
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,79 +20,102 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_INVRENDER_H__
|
||||
#define __CL_INVRENDER_H__
|
||||
#pragma once
|
||||
|
||||
class FakkInventory;
|
||||
|
||||
typedef enum { selectsound, rejectsound, changesound } invsound_t;
|
||||
class FakkItemList : public UIWidget {
|
||||
typedef enum {
|
||||
selectsound,
|
||||
rejectsound,
|
||||
changesound
|
||||
} invsound_t;
|
||||
|
||||
class FakkItemList : public UIWidget
|
||||
{
|
||||
protected:
|
||||
inventory_type_t *type;
|
||||
uipopup_describe m_describe[ 10 ];
|
||||
inventory_item_t *m_hoveritem;
|
||||
inventory_item_t *m_lastmenuitem;
|
||||
FakkInventory *m_parent;
|
||||
float m_hovertop;
|
||||
inventory_type_t *type;
|
||||
uipopup_describe m_describe[10];
|
||||
inventory_item_t *m_hoveritem;
|
||||
inventory_item_t *m_lastmenuitem;
|
||||
FakkInventory *m_parent;
|
||||
float m_hovertop;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FakkItemList );
|
||||
CLASS_PROTOTYPE(FakkItemList);
|
||||
|
||||
FakkItemList();
|
||||
~FakkItemList();
|
||||
FakkItemList();
|
||||
~FakkItemList();
|
||||
|
||||
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
|
||||
void setType( inventory_type_t *t );
|
||||
void Create( float x, float y, FakkInventory *parent );
|
||||
bool HasAnyItems( void );
|
||||
void Draw( void ) override;
|
||||
void OnLeftMouseDown( Event *ev );
|
||||
void OnRightMouseDown( Event *ev );
|
||||
void OnLeftMouseUp( Event *ev );
|
||||
void OnRightMouseUp( Event *ev );
|
||||
void OnMouseMove( Event *ev );
|
||||
void OnMouseEnter( Event *ev );
|
||||
void OnMouseLeave( Event *ev );
|
||||
void OnMenuKilled( Event *ev );
|
||||
void EquipItem( Event *ev );
|
||||
void VerifyItemUp(inventory_item_t *item, qboolean warpmouse);
|
||||
void setType(inventory_type_t *t);
|
||||
void Create(float x, float y, FakkInventory *parent);
|
||||
bool HasAnyItems(void);
|
||||
void Draw(void) override;
|
||||
void OnLeftMouseDown(Event *ev);
|
||||
void OnRightMouseDown(Event *ev);
|
||||
void OnLeftMouseUp(Event *ev);
|
||||
void OnRightMouseUp(Event *ev);
|
||||
void OnMouseMove(Event *ev);
|
||||
void OnMouseEnter(Event *ev);
|
||||
void OnMouseLeave(Event *ev);
|
||||
void OnMenuKilled(Event *ev);
|
||||
void EquipItem(Event *ev);
|
||||
|
||||
inventory_item_t *getHoverItem() const;
|
||||
};
|
||||
|
||||
class FakkInventory : public UIWidget {
|
||||
class FakkInventory : public UIWidget
|
||||
{
|
||||
protected:
|
||||
inventory_t *m_inv;
|
||||
SafePtr<FakkItemList> m_currentlist;
|
||||
inventory_type_t *m_currenttype;
|
||||
int m_currentitemnum;
|
||||
inventory_t *m_inv;
|
||||
SafePtr<FakkItemList> m_currentlist;
|
||||
inventory_type_t *m_currenttype;
|
||||
int m_currentitemnum;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FakkInventory );
|
||||
|
||||
protected:
|
||||
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
|
||||
CLASS_PROTOTYPE(FakkInventory);
|
||||
|
||||
public:
|
||||
FakkInventory();
|
||||
~FakkInventory();
|
||||
qboolean m_mouse_active;
|
||||
|
||||
void setInventory( inventory_t *i );
|
||||
void Draw( void ) override;
|
||||
void OnMouseMove( Event *ev );
|
||||
void OnMouseLeave( Event *ev );
|
||||
void OnMouseEnter( Event *ev );
|
||||
void OnMouseDown( Event *ev );
|
||||
void WarpTo( const char *name );
|
||||
void WarpTo( int slotnum );
|
||||
void NextItem( void );
|
||||
void PrevItem( void );
|
||||
qboolean isDying( void );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void PlaySound( invsound_t type );
|
||||
void Timeout( Event *ev );
|
||||
void ChangeItem( int sign );
|
||||
int FindFirstItem( int itemindex, int sign );
|
||||
protected:
|
||||
void VerifyTypeUp(inventory_type_t *t, qboolean warpmouse);
|
||||
|
||||
public:
|
||||
FakkInventory();
|
||||
~FakkInventory();
|
||||
|
||||
void setInventory(inventory_t *i);
|
||||
void Draw(void) override;
|
||||
void OnMouseMove(Event *ev);
|
||||
void OnMouseLeave(Event *ev);
|
||||
void OnMouseEnter(Event *ev);
|
||||
void OnMouseDown(Event *ev);
|
||||
void WarpTo(const char *name);
|
||||
void WarpTo(int slotnum);
|
||||
void NextItem(void);
|
||||
void PrevItem(void);
|
||||
qboolean isDying(void);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void PlaySound(invsound_t type);
|
||||
void Timeout(Event *ev);
|
||||
void ChangeItem(int sign);
|
||||
int FindFirstItem(int itemindex, int sign);
|
||||
};
|
||||
|
||||
void CL_Draw3DModel( float x, float y, float w, float h, qhandle_t model, vec3_t origin, vec3_t rotateoffset, vec3_t offset, vec3_t angle, vec3_t color, str anim );
|
||||
qboolean UI_CloseInventory( void );
|
||||
void CL_Draw3DModel(
|
||||
float x,
|
||||
float y,
|
||||
float w,
|
||||
float h,
|
||||
qhandle_t model,
|
||||
vec3_t origin,
|
||||
vec3_t rotateoffset,
|
||||
vec3_t offset,
|
||||
vec3_t angle,
|
||||
vec3_t color,
|
||||
str anim
|
||||
);
|
||||
|
||||
#endif // __CL_INVRENDER_H__
|
||||
void UI_DoInventory(qboolean activate_mouse);
|
||||
qboolean UI_CloseInventory(void);
|
||||
+927
-915
File diff suppressed because it is too large.
Load diff
+395
-183
@@ -769,7 +769,9 @@ void CL_ShutdownAll(qboolean shutdownRef) {
|
||||
CL_cURL_Shutdown();
|
||||
#endif
|
||||
// clear sounds
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
S_DisableSounds();
|
||||
#endif
|
||||
// shutdown CGame
|
||||
CL_ShutdownCGame();
|
||||
// shutdown UI
|
||||
@@ -1484,7 +1486,7 @@ void CL_SendPureChecksums( void ) {
|
||||
Q_strcat(cMsg, sizeof(cMsg), va("%d ", cl.serverId) );
|
||||
Q_strcat(cMsg, sizeof(cMsg), pChecksums);
|
||||
for (i = 0; i < 2; i++) {
|
||||
cMsg[i] += 10;
|
||||
cMsg[i] += '\n';
|
||||
}
|
||||
CL_AddReliableCommand( cMsg, qfalse );
|
||||
}
|
||||
@@ -1513,6 +1515,12 @@ because the renderer doesn't know what graphics to reload
|
||||
=================
|
||||
*/
|
||||
void CL_Vid_Restart_f( void ) {
|
||||
soundsystemsavegame_t save;
|
||||
char tm_filename[MAX_RES_NAME];
|
||||
int tm_loopcount;
|
||||
int tm_offset;
|
||||
char current_soundtrack[128];
|
||||
|
||||
if (!CL_Allowed_Vid_Restart()) {
|
||||
return;
|
||||
}
|
||||
@@ -1520,11 +1528,18 @@ void CL_Vid_Restart_f( void ) {
|
||||
Com_Printf("-------- CL_Vid_Restart_f --------\n");
|
||||
cls.vid_restart = qtrue;
|
||||
|
||||
// don't let them loop during the restart
|
||||
S_StopAllSounds2(qtrue);
|
||||
//
|
||||
// Save the current music
|
||||
//
|
||||
Q_strncpyz(tm_filename, S_GetMusicFilename(), sizeof(tm_filename));
|
||||
tm_loopcount = S_GetMusicLoopCount();
|
||||
tm_offset = S_GetMusicOffset();
|
||||
|
||||
SV_ClearSvsTimeFixups();
|
||||
|
||||
S_SaveData(&save);
|
||||
Q_strncpyz(current_soundtrack, S_CurrentSoundtrack(), sizeof(current_soundtrack));
|
||||
|
||||
S_BeginRegistration();
|
||||
|
||||
// shutdown the renderer and clear the renderer interface
|
||||
@@ -1545,9 +1560,22 @@ void CL_Vid_Restart_f( void ) {
|
||||
|
||||
CL_StartHunkUsers(qfalse);
|
||||
|
||||
#if !defined(NO_MODERN_DMA) || !NO_MODERN_DMA
|
||||
s_bSoundPaused = true;
|
||||
S_LoadData(&save);
|
||||
#else
|
||||
S_Init();
|
||||
#endif
|
||||
|
||||
SV_FinishSvsTimeFixups();
|
||||
|
||||
S_Init();
|
||||
S_ReLoad(&save);
|
||||
|
||||
if (tm_filename[0]) {
|
||||
S_TriggeredMusic_SetupHandle(tm_filename, tm_loopcount, tm_offset, 0);
|
||||
}
|
||||
|
||||
MUSIC_NewSoundtrack(current_soundtrack);
|
||||
|
||||
if (clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC)
|
||||
{
|
||||
@@ -1569,10 +1597,52 @@ handles will be invalid
|
||||
=================
|
||||
*/
|
||||
void CL_Snd_Restart_f( void ) {
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
S_Shutdown();
|
||||
S_Init();
|
||||
CL_Vid_Restart_f();
|
||||
#else
|
||||
qboolean full;
|
||||
soundsystemsavegame_t save;
|
||||
char tm_filename[MAX_RES_NAME];
|
||||
int tm_loopcount;
|
||||
int tm_offset;
|
||||
char current_soundtrack[128];
|
||||
|
||||
CL_Vid_Restart_f();
|
||||
full = S_NeedFullRestart();
|
||||
|
||||
//
|
||||
// Save the current music
|
||||
//
|
||||
Q_strncpyz(tm_filename, S_GetMusicFilename(), sizeof(tm_filename));
|
||||
tm_loopcount = S_GetMusicLoopCount();
|
||||
tm_offset = S_GetMusicOffset();
|
||||
|
||||
SV_ClearSvsTimeFixups();
|
||||
|
||||
S_SaveData(&save);
|
||||
Q_strncpyz(current_soundtrack, S_CurrentSoundtrack(), sizeof(current_soundtrack));
|
||||
|
||||
S_Shutdown(qfalse);
|
||||
S_Init(qfalse);
|
||||
|
||||
s_bSoundPaused = true;
|
||||
|
||||
S_LoadData(&save);
|
||||
|
||||
SV_FinishSvsTimeFixups();
|
||||
S_ReLoad(&save);
|
||||
|
||||
if (tm_filename[0]) {
|
||||
S_TriggeredMusic_SetupHandle(tm_filename, tm_loopcount, tm_offset, 0);
|
||||
}
|
||||
|
||||
MUSIC_NewSoundtrack(current_soundtrack);
|
||||
|
||||
if (full) {
|
||||
CL_Vid_Restart_f();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -2017,13 +2087,8 @@ void CL_MotdPacket( netadr_t from ) {
|
||||
CL_InitServerInfo
|
||||
===================
|
||||
*/
|
||||
void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
|
||||
server->adr.type = NA_IP;
|
||||
server->adr.ip[0] = address->ip[0];
|
||||
server->adr.ip[1] = address->ip[1];
|
||||
server->adr.ip[2] = address->ip[2];
|
||||
server->adr.ip[3] = address->ip[3];
|
||||
server->adr.port = address->port;
|
||||
void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
|
||||
server->adr = *address;
|
||||
server->clients = 0;
|
||||
server->hostName[0] = '\0';
|
||||
server->mapName[0] = '\0';
|
||||
@@ -2043,14 +2108,14 @@ void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
|
||||
CL_ServersResponsePacket
|
||||
===================
|
||||
*/
|
||||
void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
||||
int i, count, max, total;
|
||||
serverAddress_t addresses[MAX_SERVERSPERPACKET];
|
||||
void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extended ) {
|
||||
int i, j, count, total;
|
||||
netadr_t addresses[MAX_SERVERSPERPACKET];
|
||||
int numservers;
|
||||
byte* buffptr;
|
||||
byte* buffend;
|
||||
|
||||
Com_Printf("CL_ServersResponsePacket\n");
|
||||
|
||||
Com_Printf("CL_ServersResponsePacket from %s\n", NET_AdrToStringwPort(*from));
|
||||
|
||||
if (cls.numglobalservers == -1) {
|
||||
// state to detect lack of servers or lack of response
|
||||
@@ -2058,71 +2123,84 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
||||
cls.numGlobalServerAddresses = 0;
|
||||
}
|
||||
|
||||
if (cls.nummplayerservers == -1) {
|
||||
cls.nummplayerservers = 0;
|
||||
}
|
||||
|
||||
// parse through server response string
|
||||
numservers = 0;
|
||||
buffptr = msg->data;
|
||||
buffend = buffptr + msg->cursize;
|
||||
while (buffptr+1 < buffend) {
|
||||
// advance to initial token
|
||||
do {
|
||||
if (*buffptr++ == '\\')
|
||||
break;
|
||||
}
|
||||
while (buffptr < buffend);
|
||||
|
||||
if ( buffptr >= buffend - 6 ) {
|
||||
// advance to initial token
|
||||
do
|
||||
{
|
||||
if(*buffptr == '\\' || (extended && *buffptr == '/'))
|
||||
break;
|
||||
|
||||
buffptr++;
|
||||
} while (buffptr < buffend);
|
||||
|
||||
while (buffptr + 1 < buffend)
|
||||
{
|
||||
// IPv4 address
|
||||
if (*buffptr == '\\')
|
||||
{
|
||||
buffptr++;
|
||||
|
||||
if (buffend - buffptr < sizeof(addresses[numservers].ip) + sizeof(addresses[numservers].port) + 1)
|
||||
break;
|
||||
|
||||
for(i = 0; i < sizeof(addresses[numservers].ip); i++)
|
||||
addresses[numservers].ip[i] = *buffptr++;
|
||||
|
||||
addresses[numservers].type = NA_IP;
|
||||
}
|
||||
// IPv6 address, if it's an extended response
|
||||
else if (extended && *buffptr == '/')
|
||||
{
|
||||
buffptr++;
|
||||
|
||||
// parse out ip
|
||||
addresses[numservers].ip[0] = *buffptr++;
|
||||
addresses[numservers].ip[1] = *buffptr++;
|
||||
addresses[numservers].ip[2] = *buffptr++;
|
||||
addresses[numservers].ip[3] = *buffptr++;
|
||||
|
||||
if (buffend - buffptr < sizeof(addresses[numservers].ip6) + sizeof(addresses[numservers].port) + 1)
|
||||
break;
|
||||
|
||||
for(i = 0; i < sizeof(addresses[numservers].ip6); i++)
|
||||
addresses[numservers].ip6[i] = *buffptr++;
|
||||
|
||||
addresses[numservers].type = NA_IP6;
|
||||
addresses[numservers].scope_id = from->scope_id;
|
||||
}
|
||||
else
|
||||
// syntax error!
|
||||
break;
|
||||
|
||||
// parse out port
|
||||
addresses[numservers].port = (*buffptr++)<<8;
|
||||
addresses[numservers].port = (*buffptr++) << 8;
|
||||
addresses[numservers].port += *buffptr++;
|
||||
addresses[numservers].port = BigShort( addresses[numservers].port );
|
||||
|
||||
// syntax check
|
||||
if (*buffptr != '\\') {
|
||||
if (*buffptr != '\\' && *buffptr != '/')
|
||||
break;
|
||||
}
|
||||
|
||||
Com_DPrintf( "server: %d ip: %d.%d.%d.%d:%d\n",numservers,
|
||||
addresses[numservers].ip[0],
|
||||
addresses[numservers].ip[1],
|
||||
addresses[numservers].ip[2],
|
||||
addresses[numservers].ip[3],
|
||||
addresses[numservers].port );
|
||||
|
||||
|
||||
numservers++;
|
||||
if (numservers >= MAX_SERVERSPERPACKET) {
|
||||
if (numservers >= MAX_SERVERSPERPACKET)
|
||||
break;
|
||||
}
|
||||
|
||||
// parse out EOT
|
||||
if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cls.masterNum == 0) {
|
||||
count = cls.numglobalservers;
|
||||
max = MAX_GLOBAL_SERVERS;
|
||||
} else {
|
||||
count = cls.nummplayerservers;
|
||||
max = MAX_OTHER_SERVERS;
|
||||
}
|
||||
count = cls.numglobalservers;
|
||||
|
||||
for (i = 0; i < numservers && count < max; i++) {
|
||||
for (i = 0; i < numservers && count < MAX_GLOBAL_SERVERS; i++) {
|
||||
// build net address
|
||||
serverInfo_t *server = (cls.masterNum == 0) ? &cls.globalServers[count] : &cls.mplayerServers[count];
|
||||
serverInfo_t *server = &cls.globalServers[count];
|
||||
|
||||
// Tequila: It's possible to have sent many master server requests. Then
|
||||
// we may receive many times the same addresses from the master server.
|
||||
// We just avoid to add a server if it is still in the global servers list.
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
if (NET_CompareAdr(cls.globalServers[j].adr, addresses[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < count)
|
||||
continue;
|
||||
|
||||
CL_InitServerInfo( server, &addresses[i] );
|
||||
// advance to next slot
|
||||
@@ -2130,29 +2208,18 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
||||
}
|
||||
|
||||
// if getting the global list
|
||||
if (cls.masterNum == 0) {
|
||||
if ( cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) {
|
||||
// if we couldn't store the servers in the main list anymore
|
||||
for (; i < numservers && count >= max; i++) {
|
||||
serverAddress_t *addr;
|
||||
// just store the addresses in an additional list
|
||||
addr = &cls.globalServerAddresses[cls.numGlobalServerAddresses++];
|
||||
addr->ip[0] = addresses[i].ip[0];
|
||||
addr->ip[1] = addresses[i].ip[1];
|
||||
addr->ip[2] = addresses[i].ip[2];
|
||||
addr->ip[3] = addresses[i].ip[3];
|
||||
addr->port = addresses[i].port;
|
||||
}
|
||||
if ( count >= MAX_GLOBAL_SERVERS && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS )
|
||||
{
|
||||
// if we couldn't store the servers in the main list anymore
|
||||
for (; i < numservers && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS; i++)
|
||||
{
|
||||
// just store the addresses in an additional list
|
||||
cls.globalServerAddresses[cls.numGlobalServerAddresses++] = addresses[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (cls.masterNum == 0) {
|
||||
cls.numglobalservers = count;
|
||||
total = count + cls.numGlobalServerAddresses;
|
||||
} else {
|
||||
cls.nummplayerservers = count;
|
||||
total = count;
|
||||
}
|
||||
cls.numglobalservers = count;
|
||||
total = count + cls.numGlobalServerAddresses;
|
||||
|
||||
Com_Printf("%d servers parsed (total %d)\n", numservers, total);
|
||||
}
|
||||
@@ -2280,7 +2347,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
||||
|
||||
// echo request from server
|
||||
if ( !Q_strncmp(c, "getserversResponse", 18) ) {
|
||||
CL_ServersResponsePacket( from, msg );
|
||||
CL_ServersResponsePacket( &from, msg, qfalse );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2375,6 +2442,13 @@ CL_CheckTimeout
|
||||
==================
|
||||
*/
|
||||
void CL_CheckTimeout( void ) {
|
||||
if (com_sv_running->integer) {
|
||||
// Added in OPM
|
||||
// Timeout should not be possible if the client is hosting the game
|
||||
// (like in single-player mode)
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// check timeout
|
||||
//
|
||||
@@ -2382,10 +2456,37 @@ void CL_CheckTimeout( void ) {
|
||||
&& clc.state >= CA_CONNECTED && clc.state != CA_CINEMATIC
|
||||
&& cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) {
|
||||
if (++cl.timeoutcount > 5) { // timeoutcount saves debugger
|
||||
Com_Printf ("\nServer connection timed out.\n");
|
||||
Cbuf_AddText( "pushmenu servertimeout\n" );
|
||||
CL_Disconnect();
|
||||
return;
|
||||
const char* info;
|
||||
const char* maxclients;
|
||||
|
||||
info = &cl.gameState.stringData[cl.gameState.stringOffsets[CS_SERVERINFO]];
|
||||
maxclients = Info_ValueForKey(info, "maxclients");
|
||||
//
|
||||
// Disconnect if the player isn't alone (single-player mode)
|
||||
//
|
||||
if (!maxclients || atoi(maxclients) != 1) {
|
||||
qboolean bConsoleState;
|
||||
|
||||
bConsoleState = UI_ConsoleIsOpen();
|
||||
|
||||
Com_Printf("\nServer connection timed out.\n");
|
||||
SV_Shutdown("\nServer connection timed out\n");
|
||||
|
||||
if (com_cl_running && com_cl_running->integer) {
|
||||
CL_AbnormalDisconnect();
|
||||
CL_FlushMemory();
|
||||
CL_StartHunkUsers(qfalse);
|
||||
}
|
||||
|
||||
UI_ForceMenuOff(qtrue);
|
||||
UI_PushMenu("servertimeout");
|
||||
|
||||
if (bConsoleState) {
|
||||
UI_OpenConsole();
|
||||
} else {
|
||||
UI_CloseConsole();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cl.timeoutcount = 0;
|
||||
@@ -2478,6 +2579,7 @@ void CL_Frame ( int msec ) {
|
||||
&& !com_sv_running->integer ) {
|
||||
// if disconnected, bring up the menu
|
||||
S_StopAllSounds2( qtrue );
|
||||
S_TriggeredMusic_PlayIntroMusic();
|
||||
UI_MenuEscape( "main" );
|
||||
}
|
||||
|
||||
@@ -3390,7 +3492,11 @@ void CL_Init( void ) {
|
||||
|
||||
Cvar_Set( "cl_running", "1" );
|
||||
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
S_Init2();
|
||||
#else
|
||||
S_Init(qtrue);
|
||||
#endif
|
||||
|
||||
// fixme: should we leave it?
|
||||
CL_GenerateQKey();
|
||||
@@ -3431,7 +3537,11 @@ void CL_Shutdown(const char* finalmsg, qboolean disconnect, qboolean quit) {
|
||||
if(disconnect)
|
||||
CL_Disconnect();
|
||||
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
S_Shutdown();
|
||||
#else
|
||||
S_Shutdown(qtrue);
|
||||
#endif
|
||||
CL_ShutdownRef();
|
||||
|
||||
CL_ShutdownUI();
|
||||
@@ -3523,15 +3633,39 @@ CL_ServerInfoPacket
|
||||
void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
||||
int i, type;
|
||||
char info[MAX_INFO_STRING];
|
||||
const char* str;
|
||||
char *infoString;
|
||||
int prot;
|
||||
char *gamename;
|
||||
qboolean gameMismatch;
|
||||
|
||||
infoString = MSG_ReadString( msg );
|
||||
|
||||
// if this isn't the correct gamename, ignore it
|
||||
gamename = Info_ValueForKey( infoString, "gamename" );
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
// gamename is optional for legacy protocol
|
||||
if (com_legacyprotocol->integer && !*gamename)
|
||||
gameMismatch = qfalse;
|
||||
else
|
||||
#endif
|
||||
gameMismatch = !*gamename || strcmp(gamename, com_gamename->string) != 0;
|
||||
|
||||
if (gameMismatch)
|
||||
{
|
||||
Com_DPrintf( "Game mismatch in info packet: %s\n", infoString );
|
||||
return;
|
||||
}
|
||||
|
||||
// if this isn't the correct protocol version, ignore it
|
||||
prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
|
||||
if ( prot != PROTOCOL_VERSION ) {
|
||||
|
||||
if(prot != com_protocol->integer
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
&& prot != com_legacyprotocol->integer
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Com_DPrintf( "Different protocol info packet: %s\n", infoString );
|
||||
return;
|
||||
}
|
||||
@@ -3542,7 +3676,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
||||
if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) )
|
||||
{
|
||||
// calc ping time
|
||||
cl_pinglist[i].time = cls.realtime - cl_pinglist[i].start + 1;
|
||||
cl_pinglist[i].time = Sys_Milliseconds() - cl_pinglist[i].start;
|
||||
Com_DPrintf( "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) );
|
||||
|
||||
// save of info
|
||||
@@ -3554,12 +3688,12 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
||||
{
|
||||
case NA_BROADCAST:
|
||||
case NA_IP:
|
||||
str = "udp";
|
||||
type = 1;
|
||||
break;
|
||||
|
||||
case NA_IP6:
|
||||
type = 2;
|
||||
break;
|
||||
default:
|
||||
str = "???";
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
@@ -3594,24 +3728,16 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
||||
|
||||
// add this to the list
|
||||
cls.numlocalservers = i+1;
|
||||
cls.localServers[i].adr = from;
|
||||
cls.localServers[i].clients = 0;
|
||||
cls.localServers[i].hostName[0] = '\0';
|
||||
cls.localServers[i].mapName[0] = '\0';
|
||||
cls.localServers[i].maxClients = 0;
|
||||
cls.localServers[i].maxPing = 0;
|
||||
cls.localServers[i].minPing = 0;
|
||||
cls.localServers[i].ping = -1;
|
||||
cls.localServers[i].game[0] = '\0';
|
||||
cls.localServers[i].gameType = 0;
|
||||
cls.localServers[i].netType = from.type;
|
||||
cls.bNewLocalServerInfo = true;
|
||||
CL_InitServerInfo( &cls.localServers[i], &from );
|
||||
CL_SetServerInfo( &cls.localServers[i], infoString, 0 );
|
||||
|
||||
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
|
||||
if (strlen(info)) {
|
||||
if (info[strlen(info)-1] != '\n') {
|
||||
strncat(info, "\n", sizeof(info) - 1);
|
||||
Q_strcat(info, sizeof(info), "\n");
|
||||
}
|
||||
Com_Printf( "%s: %s", NET_AdrToString( from ), info );
|
||||
Com_Printf( "%s: %s", NET_AdrToStringwPort( from ), info );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3621,10 +3747,8 @@ CL_GetServerStatus
|
||||
===================
|
||||
*/
|
||||
serverStatus_t *CL_GetServerStatus( netadr_t from ) {
|
||||
serverStatus_t *serverStatus;
|
||||
int i, oldest, oldestTime;
|
||||
|
||||
serverStatus = NULL;
|
||||
for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
|
||||
if ( NET_CompareAdr( from, cl_serverStatusList[i].address ) ) {
|
||||
return &cl_serverStatusList[i];
|
||||
@@ -3643,11 +3767,7 @@ serverStatus_t *CL_GetServerStatus( netadr_t from ) {
|
||||
oldestTime = cl_serverStatusList[i].startTime;
|
||||
}
|
||||
}
|
||||
if (oldest != -1) {
|
||||
return &cl_serverStatusList[oldest];
|
||||
}
|
||||
serverStatusCount++;
|
||||
return &cl_serverStatusList[serverStatusCount & (MAX_SERVERSTATUSREQUESTS-1)];
|
||||
return &cl_serverStatusList[oldest];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3669,7 +3789,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
|
||||
return qfalse;
|
||||
}
|
||||
// get the address
|
||||
if ( !NET_StringToAdr( serverAddress, &to, NA_IP ) ) {
|
||||
if ( !NET_StringToAdr( serverAddress, &to, NA_UNSPEC) ) {
|
||||
return qfalse;
|
||||
}
|
||||
serverStatus = CL_GetServerStatus( to );
|
||||
@@ -3681,7 +3801,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
|
||||
|
||||
// if this server status request has the same address
|
||||
if ( NET_CompareAdr( to, serverStatus->address) ) {
|
||||
// if we recieved an response for this server status request
|
||||
// if we received a response for this server status request
|
||||
if (!serverStatus->pending) {
|
||||
Q_strncpyz(serverStatusString, serverStatus->string, maxLen);
|
||||
serverStatus->retrieved = qtrue;
|
||||
@@ -3719,10 +3839,10 @@ CL_ServerStatusResponse
|
||||
===================
|
||||
*/
|
||||
void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
|
||||
const char *s;
|
||||
char *s;
|
||||
char info[MAX_INFO_STRING];
|
||||
int i, l, score, ping;
|
||||
size_t len;
|
||||
int len;
|
||||
serverStatus_t *serverStatus;
|
||||
|
||||
serverStatus = NULL;
|
||||
@@ -3821,6 +3941,7 @@ void CL_LocalServers_f( void ) {
|
||||
|
||||
// reset the list, waiting for response
|
||||
cls.numlocalservers = 0;
|
||||
cls.bNewLocalServerInfo = true;
|
||||
cls.pingUpdateSource = AS_LOCAL;
|
||||
|
||||
for (i = 0; i < MAX_OTHER_SERVERS; i++) {
|
||||
@@ -3845,6 +3966,9 @@ void CL_LocalServers_f( void ) {
|
||||
|
||||
to.type = NA_BROADCAST;
|
||||
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
|
||||
// Added in OPM (from ioquake3)
|
||||
to.type = NA_MULTICAST6;
|
||||
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3972,47 +4096,101 @@ void CL_GamespyServers_f( void ) {
|
||||
/*
|
||||
==================
|
||||
CL_GlobalServers_f
|
||||
|
||||
Originally master 0 was Internet and master 1 was MPlayer.
|
||||
ioquake3 2008; added support for requesting five separate master servers using 0-4.
|
||||
ioquake3 2017; made master 0 fetch all master servers and 1-5 request a single master server.
|
||||
==================
|
||||
*/
|
||||
void CL_GlobalServers_f( void ) {
|
||||
netadr_t to;
|
||||
int i;
|
||||
int count;
|
||||
char *buffptr;
|
||||
char command[1024];
|
||||
int count, i, masterNum;
|
||||
char command[1024], *masteraddress;
|
||||
|
||||
if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > MAX_MASTER_SERVERS)
|
||||
{
|
||||
Com_Printf("usage: globalservers <master# 0-%d> <protocol> [keywords]\n", MAX_MASTER_SERVERS);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Cmd_Argc() < 3) {
|
||||
Com_Printf( "usage: globalservers <master# 0-1> <protocol> [keywords]\n");
|
||||
// request from all master servers
|
||||
if ( masterNum == 0 ) {
|
||||
int numAddress = 0;
|
||||
|
||||
for ( i = 1; i <= MAX_MASTER_SERVERS; i++ ) {
|
||||
sprintf(command, "sv_master%d", i);
|
||||
masteraddress = Cvar_VariableString(command);
|
||||
|
||||
if(!*masteraddress)
|
||||
continue;
|
||||
|
||||
numAddress++;
|
||||
|
||||
Com_sprintf(command, sizeof(command), "globalservers %d %s %s\n", i, Cmd_Argv(2), Cmd_ArgsFrom(3));
|
||||
Cbuf_AddText(command);
|
||||
}
|
||||
|
||||
if ( !numAddress ) {
|
||||
Com_Printf( "CL_GlobalServers_f: Error: No master server addresses.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cls.masterNum = atoi( Cmd_Argv(1) );
|
||||
|
||||
Com_Printf( "Requesting servers from the master...\n");
|
||||
sprintf(command, "sv_master%d", masterNum);
|
||||
masteraddress = Cvar_VariableString(command);
|
||||
|
||||
if(!*masteraddress)
|
||||
{
|
||||
Com_Printf( "CL_GlobalServers_f: Error: No master server address given.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// reset the list, waiting for response
|
||||
// -1 is used to distinguish a "no response"
|
||||
|
||||
NET_StringToAdr( cl_master->string, &to, NA_IP );
|
||||
|
||||
if( cls.masterNum == 1 ) {
|
||||
cls.nummplayerservers = -1;
|
||||
cls.pingUpdateSource = AS_MPLAYER;
|
||||
i = NET_StringToAdr(masteraddress, &to, NA_UNSPEC);
|
||||
|
||||
if(!i)
|
||||
{
|
||||
Com_Printf( "CL_GlobalServers_f: Error: could not resolve address of master %s\n", masteraddress);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
cls.numglobalservers = -1;
|
||||
cls.pingUpdateSource = AS_GLOBAL;
|
||||
else if(i == 2)
|
||||
to.port = BigShort(PORT_MASTER);
|
||||
|
||||
Com_Printf("Requesting servers from %s (%s)...\n", masteraddress, NET_AdrToStringwPort(to));
|
||||
|
||||
cls.numglobalservers = -1;
|
||||
cls.pingUpdateSource = AS_GLOBAL;
|
||||
|
||||
// Use the extended query for IPv6 masters
|
||||
if (to.type == NA_IP6 || to.type == NA_MULTICAST6)
|
||||
{
|
||||
int v4enabled = Cvar_VariableIntegerValue("net_enabled") & NET_ENABLEV4;
|
||||
|
||||
if(v4enabled)
|
||||
{
|
||||
Com_sprintf(command, sizeof(command), "getserversExt %s %s",
|
||||
com_gamename->string, Cmd_Argv(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_sprintf(command, sizeof(command), "getserversExt %s %s ipv6",
|
||||
com_gamename->string, Cmd_Argv(2));
|
||||
}
|
||||
}
|
||||
to.type = NA_IP;
|
||||
to.port = BigShort(PORT_MASTER);
|
||||
//else if ( !Q_stricmp( com_gamename->string, LEGACY_MASTER_GAMENAME ) )
|
||||
// Com_sprintf(command, sizeof(command), "getservers %s",
|
||||
// Cmd_Argv(2));
|
||||
else
|
||||
Com_sprintf(command, sizeof(command), "getservers %s %s",
|
||||
com_gamename->string, Cmd_Argv(2));
|
||||
|
||||
sprintf( command, "getservers %s", Cmd_Argv(2) );
|
||||
|
||||
// tack on keywords
|
||||
buffptr = command + strlen( command );
|
||||
count = Cmd_Argc();
|
||||
for (i=3; i<count; i++)
|
||||
buffptr += sprintf( buffptr, " %s", Cmd_Argv(i) );
|
||||
for (i=3; i < count; i++)
|
||||
{
|
||||
Q_strcat(command, sizeof(command), " ");
|
||||
Q_strcat(command, sizeof(command), Cmd_Argv(i));
|
||||
}
|
||||
|
||||
NET_OutOfBandPrint( NS_SERVER, to, "%s", command );
|
||||
}
|
||||
@@ -4029,22 +4207,22 @@ void CL_GetPing( int n, char *buf, int buflen, int *pingtime )
|
||||
int time;
|
||||
int maxPing;
|
||||
|
||||
if (!cl_pinglist[n].adr.port)
|
||||
if (n < 0 || n >= MAX_PINGREQUESTS || !cl_pinglist[n].adr.port)
|
||||
{
|
||||
// empty slot
|
||||
// empty or invalid slot
|
||||
buf[0] = '\0';
|
||||
*pingtime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
str = NET_AdrToString( cl_pinglist[n].adr );
|
||||
str = NET_AdrToStringwPort( cl_pinglist[n].adr );
|
||||
Q_strncpyz( buf, str, buflen );
|
||||
|
||||
time = cl_pinglist[n].time;
|
||||
if (!time)
|
||||
{
|
||||
// check for timeout
|
||||
time = cls.realtime - cl_pinglist[n].start;
|
||||
time = Sys_Milliseconds() - cl_pinglist[n].start;
|
||||
maxPing = Cvar_VariableIntegerValue( "cl_maxPing" );
|
||||
if( maxPing < 100 ) {
|
||||
maxPing = 100;
|
||||
@@ -4083,9 +4261,9 @@ CL_GetPingInfo
|
||||
*/
|
||||
void CL_GetPingInfo( int n, char *buf, int buflen )
|
||||
{
|
||||
if (!cl_pinglist[n].adr.port)
|
||||
if (n < 0 || n >= MAX_PINGREQUESTS || !cl_pinglist[n].adr.port)
|
||||
{
|
||||
// empty slot
|
||||
// empty or invalid slot
|
||||
if (buflen)
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
@@ -4138,7 +4316,7 @@ CL_GetFreePing
|
||||
ping_t* CL_GetFreePing( void )
|
||||
{
|
||||
ping_t* pingptr;
|
||||
ping_t* best;
|
||||
ping_t* best;
|
||||
int oldest;
|
||||
int i;
|
||||
int time;
|
||||
@@ -4151,7 +4329,7 @@ ping_t* CL_GetFreePing( void )
|
||||
{
|
||||
if (!pingptr->time)
|
||||
{
|
||||
if (cls.realtime - pingptr->start < 500)
|
||||
if (Sys_Milliseconds() - pingptr->start < 500)
|
||||
{
|
||||
// still waiting for response
|
||||
continue;
|
||||
@@ -4176,7 +4354,7 @@ ping_t* CL_GetFreePing( void )
|
||||
for (i=0; i<MAX_PINGREQUESTS; i++, pingptr++ )
|
||||
{
|
||||
// scan for oldest
|
||||
time = cls.realtime - pingptr->start;
|
||||
time = Sys_Milliseconds() - pingptr->start;
|
||||
if (time > oldest)
|
||||
{
|
||||
oldest = time;
|
||||
@@ -4196,29 +4374,45 @@ void CL_Ping_f( void ) {
|
||||
netadr_t to;
|
||||
ping_t* pingptr;
|
||||
char* server;
|
||||
int argc;
|
||||
netadrtype_t family = NA_UNSPEC;
|
||||
|
||||
if ( Cmd_Argc() != 2 ) {
|
||||
Com_Printf( "usage: ping [server]\n");
|
||||
return;
|
||||
argc = Cmd_Argc();
|
||||
|
||||
if ( argc != 2 && argc != 3 ) {
|
||||
Com_Printf( "usage: ping [-4|-6] server\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(argc == 2)
|
||||
server = Cmd_Argv(1);
|
||||
else
|
||||
{
|
||||
if(!strcmp(Cmd_Argv(1), "-4"))
|
||||
family = NA_IP;
|
||||
else if(!strcmp(Cmd_Argv(1), "-6"))
|
||||
family = NA_IP6;
|
||||
else
|
||||
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
|
||||
|
||||
server = Cmd_Argv(2);
|
||||
}
|
||||
|
||||
Com_Memset( &to, 0, sizeof(netadr_t) );
|
||||
|
||||
server = Cmd_Argv(1);
|
||||
|
||||
if ( !NET_StringToAdr( server, &to, NA_IP ) ) {
|
||||
if ( !NET_StringToAdr( server, &to, family ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
pingptr = CL_GetFreePing();
|
||||
|
||||
memcpy( &pingptr->adr, &to, sizeof (netadr_t) );
|
||||
pingptr->start = cls.realtime;
|
||||
pingptr->start = Sys_Milliseconds();
|
||||
pingptr->time = 0;
|
||||
|
||||
CL_SetServerInfoByAddress(pingptr->adr, NULL, 0);
|
||||
|
||||
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo" );
|
||||
|
||||
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo xxx" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4342,16 +4536,11 @@ qboolean CL_UpdateVisiblePings_f(int source) {
|
||||
if (slots < MAX_PINGREQUESTS) {
|
||||
serverInfo_t *server = NULL;
|
||||
|
||||
max = (source == AS_GLOBAL) ? MAX_GLOBAL_SERVERS : MAX_OTHER_SERVERS;
|
||||
switch (source) {
|
||||
case AS_LOCAL :
|
||||
server = &cls.localServers[0];
|
||||
max = cls.numlocalservers;
|
||||
break;
|
||||
case AS_MPLAYER :
|
||||
server = &cls.mplayerServers[0];
|
||||
max = cls.nummplayerservers;
|
||||
break;
|
||||
case AS_GLOBAL :
|
||||
server = &cls.globalServers[0];
|
||||
max = cls.numglobalservers;
|
||||
@@ -4360,6 +4549,8 @@ qboolean CL_UpdateVisiblePings_f(int source) {
|
||||
server = &cls.favoriteServers[0];
|
||||
max = cls.numfavoriteservers;
|
||||
break;
|
||||
default:
|
||||
return qfalse;
|
||||
}
|
||||
for (i = 0; i < max; i++) {
|
||||
if (server[i].visible) {
|
||||
@@ -4386,7 +4577,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
|
||||
}
|
||||
}
|
||||
memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t));
|
||||
cl_pinglist[j].start = cls.realtime;
|
||||
cl_pinglist[j].start = Sys_Milliseconds();
|
||||
cl_pinglist[j].time = 0;
|
||||
NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" );
|
||||
slots++;
|
||||
@@ -4408,7 +4599,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (slots) {
|
||||
status = qtrue;
|
||||
@@ -4433,32 +4624,53 @@ CL_ServerStatus_f
|
||||
==================
|
||||
*/
|
||||
void CL_ServerStatus_f(void) {
|
||||
netadr_t to;
|
||||
netadr_t to, *toptr = NULL;
|
||||
char *server;
|
||||
serverStatus_t *serverStatus;
|
||||
int argc;
|
||||
netadrtype_t family = NA_UNSPEC;
|
||||
|
||||
Com_Memset( &to, 0, sizeof(netadr_t) );
|
||||
argc = Cmd_Argc();
|
||||
|
||||
if ( Cmd_Argc() != 2 ) {
|
||||
if ( clc.state != CA_ACTIVE || clc.demoplaying ) {
|
||||
if ( argc != 2 && argc != 3 )
|
||||
{
|
||||
if (clc.state != CA_ACTIVE || clc.demoplaying)
|
||||
{
|
||||
Com_Printf ("Not connected to a server.\n");
|
||||
Com_Printf( "Usage: serverstatus [server]\n");
|
||||
Com_Printf( "usage: serverstatus [-4|-6] server\n");
|
||||
return;
|
||||
}
|
||||
server = cls.servername;
|
||||
|
||||
toptr = &clc.serverAddress;
|
||||
}
|
||||
else {
|
||||
server = Cmd_Argv(1);
|
||||
|
||||
if(!toptr)
|
||||
{
|
||||
Com_Memset( &to, 0, sizeof(netadr_t) );
|
||||
|
||||
if(argc == 2)
|
||||
server = Cmd_Argv(1);
|
||||
else
|
||||
{
|
||||
if(!strcmp(Cmd_Argv(1), "-4"))
|
||||
family = NA_IP;
|
||||
else if(!strcmp(Cmd_Argv(1), "-6"))
|
||||
family = NA_IP6;
|
||||
else
|
||||
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
|
||||
|
||||
server = Cmd_Argv(2);
|
||||
}
|
||||
|
||||
toptr = &to;
|
||||
if ( !NET_StringToAdr( server, toptr, family ) )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !NET_StringToAdr( server, &to, NA_IP ) ) {
|
||||
return;
|
||||
}
|
||||
NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
|
||||
|
||||
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
|
||||
|
||||
serverStatus = CL_GetServerStatus( to );
|
||||
serverStatus->address = to;
|
||||
serverStatus = CL_GetServerStatus( *toptr );
|
||||
serverStatus->address = *toptr;
|
||||
serverStatus->print = qtrue;
|
||||
serverStatus->pending = qtrue;
|
||||
}
|
||||
|
||||
+181
-84
@@ -149,6 +149,7 @@ static str ui_sCurrentLoadingMenu;
|
||||
static Container<Menu *> hudList;
|
||||
|
||||
void UI_MultiplayerMenuWidgetsUpdate(void);
|
||||
void UI_MultiplayerMainMenuWidgetsUpdate(void);
|
||||
void UI_MainMenuWidgetsUpdate(void);
|
||||
|
||||
static UIRect2D getDefaultGMBoxRectangle(void);
|
||||
@@ -1250,20 +1251,22 @@ UI_PrintConsole
|
||||
*/
|
||||
void UI_PrintConsole(const char *msg)
|
||||
{
|
||||
UColor *pColor = NULL;
|
||||
char szString[1024];
|
||||
char szBlah[1024];
|
||||
qboolean bPrintedDMBox = qfalse;
|
||||
UColor *pColor = NULL;
|
||||
const char *pszString;
|
||||
char szString[1024];
|
||||
char szBlah[1024];
|
||||
qboolean bPrintedDMBox = qfalse;
|
||||
|
||||
memcpy(szString, msg, sizeof(szString));
|
||||
pszString = msg;
|
||||
strncpy(szString, msg, 1024);
|
||||
|
||||
if (*szString < MESSAGE_MAX) {
|
||||
if (*pszString < MESSAGE_MAX) {
|
||||
qboolean bNormalMessage = qfalse;
|
||||
qboolean bDMMessage = qfalse;
|
||||
qboolean bBold = qfalse;
|
||||
qboolean bDeathMessage = qfalse;
|
||||
|
||||
switch (*szString) {
|
||||
switch (*pszString) {
|
||||
case MESSAGE_YELLOW:
|
||||
bNormalMessage = qtrue;
|
||||
pColor = &UHudColor;
|
||||
@@ -1277,16 +1280,18 @@ void UI_PrintConsole(const char *msg)
|
||||
pColor = &UWhite;
|
||||
break;
|
||||
case MESSAGE_CHAT_RED:
|
||||
bDeathMessage = qtrue;
|
||||
bDeathMessage = MESSAGE_CHAT_RED;
|
||||
pColor = &ULightRed;
|
||||
break;
|
||||
case MESSAGE_CHAT_GREEN:
|
||||
bDeathMessage = qtrue;
|
||||
bDeathMessage = MESSAGE_CHAT_GREEN;
|
||||
pColor = &UGreen;
|
||||
break;
|
||||
}
|
||||
|
||||
msg++;
|
||||
if (*pszString != 0) {
|
||||
pszString++;
|
||||
}
|
||||
|
||||
//
|
||||
// print to the deathmatch console
|
||||
@@ -1306,10 +1311,11 @@ void UI_PrintConsole(const char *msg)
|
||||
if (bDMMessage) {
|
||||
*szString = MESSAGE_CHAT_WHITE;
|
||||
dmbox->Print(szString);
|
||||
pszString = msg + 1;
|
||||
bPrintedDMBox = qtrue;
|
||||
} else if (bDeathMessage) {
|
||||
dmbox->Print(szString);
|
||||
*szString = MESSAGE_CHAT_RED;
|
||||
*szString = bDeathMessage;
|
||||
bPrintedDMBox = qtrue;
|
||||
}
|
||||
}
|
||||
@@ -1322,6 +1328,7 @@ void UI_PrintConsole(const char *msg)
|
||||
*szString = MESSAGE_WHITE;
|
||||
gmbox->Print(szString);
|
||||
uii.Snd_PlaySound("objective_text");
|
||||
pszString = msg + 1;
|
||||
} else {
|
||||
gmbox->Print(szString + 1);
|
||||
}
|
||||
@@ -1330,15 +1337,18 @@ void UI_PrintConsole(const char *msg)
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(szBlah, "Game Message: ", 15);
|
||||
Q_strcat(szBlah, sizeof(szBlah), szString + 1);
|
||||
if (!bDMMessage) {
|
||||
memcpy(szBlah, "Game Message: ", 15);
|
||||
Q_strcat(szBlah, sizeof(szBlah), pszString);
|
||||
pszString = szBlah;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*msg == 7) {
|
||||
msg++;
|
||||
if (*pszString == '\a') {
|
||||
pszString++;
|
||||
if (mini_console) {
|
||||
mini_console->Print(msg + 1);
|
||||
mini_console->Print(pszString);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1350,10 +1360,10 @@ void UI_PrintConsole(const char *msg)
|
||||
s_intermediateconsole = NULL;
|
||||
}
|
||||
|
||||
fakk_console->AddText(msg, pColor);
|
||||
fakk_console->AddText(pszString, pColor);
|
||||
|
||||
if (mini_console) {
|
||||
mini_console->Print(msg);
|
||||
mini_console->Print(pszString);
|
||||
}
|
||||
} else {
|
||||
if (!s_intermediateconsole) {
|
||||
@@ -1767,6 +1777,8 @@ void UI_Update(void)
|
||||
hud_compass->GetContainerWidget()->Display(frame, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (fakk_console) {
|
||||
@@ -1792,6 +1804,8 @@ void UI_Update(void)
|
||||
|
||||
if (currentMenu == menuManager.FindMenu("main")) {
|
||||
UI_MainMenuWidgetsUpdate();
|
||||
} else if (currentMenu == menuManager.FindMenu("dm_main")) {
|
||||
UI_MultiplayerMainMenuWidgetsUpdate();
|
||||
}
|
||||
|
||||
// don't care about the intro
|
||||
@@ -1820,7 +1834,7 @@ void UI_Update(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (clc.connectTime >= cls.realtime - 1000 * cl_connect_timeout->integer) {
|
||||
if (clc.connectStartTime >= cls.realtime - 1000 * cl_connect_timeout->integer) {
|
||||
if (currentMenu != ui_pConnectingMenu) {
|
||||
UI_ForceMenuOff(true);
|
||||
UI_DeactiveFloatingWindows();
|
||||
@@ -1877,7 +1891,7 @@ void UI_Update(void)
|
||||
UI_CloseConsole();
|
||||
}
|
||||
} else if (ui_static_materials.loading) {
|
||||
ui_static_materials.loading->ReregisterMaterial();
|
||||
ui_static_materials.loading->GetMaterial();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2382,6 +2396,44 @@ void UI_MainMenuWidgetsUpdate(void)
|
||||
UI_UpdateContinueGame();
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_MultiplayerMainMenuWidgetsUpdate
|
||||
====================
|
||||
*/
|
||||
// Added in 2.0
|
||||
void UI_MultiplayerMainMenuWidgetsUpdate(void)
|
||||
{
|
||||
static const cvar_t *cg_allowvote = Cvar_Get("cg_allowvote", "1", 0);
|
||||
|
||||
if (cg_allowvote->integer) {
|
||||
menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Disable));
|
||||
|
||||
if (atoi(CL_ConfigString(CS_VOTE_TIME))) {
|
||||
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable));
|
||||
|
||||
if (cl.snap.ps.voted) {
|
||||
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
|
||||
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Enable));
|
||||
} else {
|
||||
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Enable));
|
||||
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
|
||||
}
|
||||
} else {
|
||||
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Enable));
|
||||
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
|
||||
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
|
||||
}
|
||||
} else {
|
||||
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable));
|
||||
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
|
||||
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
|
||||
menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Enable));
|
||||
}
|
||||
|
||||
UI_UpdateContinueGame();
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_ToggleMenu
|
||||
@@ -2446,9 +2498,11 @@ void UI_PopMenu(qboolean restore_cvars)
|
||||
menu = menuManager.CurrentMenu();
|
||||
|
||||
if (menu) {
|
||||
if (!memcmp(menu->m_name.c_str(), "main", 5)) {
|
||||
if (!str::cmp(menu->m_name, "main")) {
|
||||
UI_MainMenuWidgetsUpdate();
|
||||
} else if (!memcmp(menu->m_name.c_str(), "multiplayer", 12)) {
|
||||
} else if (!str::cmp(menu->m_name, "dm_main")) {
|
||||
UI_MultiplayerMainMenuWidgetsUpdate();
|
||||
} else if (!str::cmp(menu->m_name, "multiplayer")) {
|
||||
UI_MultiplayerMenuWidgetsUpdate();
|
||||
}
|
||||
}
|
||||
@@ -2484,9 +2538,11 @@ void UI_PushMenu(const char *name)
|
||||
|
||||
UI_FocusMenuIfExists();
|
||||
|
||||
if (!memcmp(name, "main", 5)) {
|
||||
if (!str::cmp(name, "main")) {
|
||||
UI_MainMenuWidgetsUpdate();
|
||||
} else if (!memcmp(name, "multiplayer", 12)) {
|
||||
} else if (!str::cmp(name, "dm_main")) {
|
||||
UI_MultiplayerMainMenuWidgetsUpdate();
|
||||
} else if (!str::cmp(name, "multiplayer")) {
|
||||
UI_MultiplayerMenuWidgetsUpdate();
|
||||
}
|
||||
}
|
||||
@@ -2819,9 +2875,11 @@ qboolean UI_PushReturnMenu()
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!memcmp(sMenuName.c_str(), "main", 5)) {
|
||||
if (!str::cmp(sMenuName, "main")) {
|
||||
UI_MainMenuWidgetsUpdate();
|
||||
} else if (!memcmp(sMenuName.c_str(), "multiplayer", 12)) {
|
||||
} else if (!str::cmp(sMenuName, "dm_main")) {
|
||||
UI_MultiplayerMainMenuWidgetsUpdate();
|
||||
} else if (!str::cmp(sMenuName, "multiplayer")) {
|
||||
UI_MultiplayerMenuWidgetsUpdate();
|
||||
}
|
||||
|
||||
@@ -2851,33 +2909,44 @@ void UI_MenuEscape(const char *name)
|
||||
|
||||
if (uWinMan.BindActive()) {
|
||||
UI_KeyEvent(K_ESCAPE, qfalse);
|
||||
} else if (menuManager.CurrentMenu() != mainmenu || clc.state != CA_DISCONNECTED) {
|
||||
if (uWinMan.DialogExists()) {
|
||||
uWinMan.RemoveAllDialogBoxes();
|
||||
} else {
|
||||
if (menuManager.CurrentMenu()) {
|
||||
menuManager.PopMenu(qtrue);
|
||||
} else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) {
|
||||
UI_PushMenu("dm_main");
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuManager.CurrentMenu() == mainmenu && clc.state == CA_DISCONNECTED) {
|
||||
if (developer->integer) {
|
||||
if (UI_ConsoleIsVisible()) {
|
||||
UI_CloseConsole();
|
||||
} else {
|
||||
UI_PushMenu(name);
|
||||
}
|
||||
|
||||
UI_FocusMenuIfExists();
|
||||
|
||||
if (menuManager.CurrentMenu()) {
|
||||
if (!memcmp(name, "main", 5)) {
|
||||
UI_MainMenuWidgetsUpdate();
|
||||
} else if (!memcmp(name, "multiplayer", 12)) {
|
||||
UI_MultiplayerMenuWidgetsUpdate();
|
||||
}
|
||||
UI_OpenConsole();
|
||||
}
|
||||
}
|
||||
} else if (developer->integer) {
|
||||
if (UI_ConsoleIsVisible()) {
|
||||
UI_CloseConsole();
|
||||
} else {
|
||||
UI_OpenConsole();
|
||||
return;
|
||||
}
|
||||
|
||||
if (uWinMan.DialogExists()) {
|
||||
uWinMan.RemoveAllDialogBoxes();
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuManager.CurrentMenu()) {
|
||||
menuManager.PopMenu(qtrue);
|
||||
} else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) {
|
||||
// multiplayer
|
||||
UI_PushMenu("dm_main");
|
||||
} else {
|
||||
// single-player
|
||||
UI_PushMenu(name);
|
||||
}
|
||||
|
||||
UI_FocusMenuIfExists();
|
||||
|
||||
if (menuManager.CurrentMenu()) {
|
||||
if (!str::cmp(name, "main")) {
|
||||
UI_MainMenuWidgetsUpdate();
|
||||
} else if (!str::cmp(name, "dm_main")) {
|
||||
UI_MultiplayerMainMenuWidgetsUpdate();
|
||||
} else if (!str::cmp(name, "multiplayer")) {
|
||||
UI_MultiplayerMenuWidgetsUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2989,7 +3058,7 @@ void UI_MapList_f(void)
|
||||
}
|
||||
|
||||
MapRunnerClass *map = new MapRunnerClass;
|
||||
map->Setup("maps", mappath, ".bsp");
|
||||
map->Setup("maps", mappath, ".bsp", "_sml");
|
||||
|
||||
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
|
||||
}
|
||||
@@ -3002,20 +3071,34 @@ UI_DMMapSelect_f
|
||||
void UI_DMMapSelect_f(void)
|
||||
{
|
||||
str basepath = "maps";
|
||||
str mappath = "maps";
|
||||
str mappath;
|
||||
str gametype;
|
||||
|
||||
if (Cmd_Argc() > 1) {
|
||||
mappath += "/";
|
||||
mappath += Cmd_Argv(1);
|
||||
}
|
||||
const char *path;
|
||||
|
||||
if (Cmd_Argc() > 2) {
|
||||
basepath += "/";
|
||||
basepath += Cmd_Argv(2);
|
||||
path = Cmd_Argv(1);
|
||||
|
||||
if (strcmp(path, ".")) {
|
||||
basepath += "/";
|
||||
basepath += path;
|
||||
}
|
||||
|
||||
if (Cmd_Argc() > 2) {
|
||||
path = Cmd_Argv(2);
|
||||
if (strcmp(path, ".")) {
|
||||
mappath += "maps/";
|
||||
mappath += path;
|
||||
}
|
||||
}
|
||||
|
||||
if (Cmd_Argc() > 3) {
|
||||
gametype = Cmd_Argv(3);
|
||||
}
|
||||
}
|
||||
|
||||
MpMapPickerClass *map = new MpMapPickerClass;
|
||||
map->Setup(basepath, mappath);
|
||||
map->Setup(basepath, mappath, gametype);
|
||||
|
||||
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
|
||||
}
|
||||
@@ -3200,6 +3283,8 @@ void UI_PlayerModel_f(void)
|
||||
|
||||
PlayerModelPickerClass *picker = new PlayerModelPickerClass;
|
||||
picker->Setup("models/player", modelpath, bGermanModel);
|
||||
|
||||
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3210,14 +3295,20 @@ UI_ApplyPlayerModel_f
|
||||
void UI_ApplyPlayerModel_f(void)
|
||||
{
|
||||
const char *pszUIPlayerModel;
|
||||
char donotshowssindeorfr[64];
|
||||
|
||||
pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel", "american_army");
|
||||
pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel_set", "american_army");
|
||||
Cvar_Set("dm_playermodel", pszUIPlayerModel);
|
||||
|
||||
pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel", "german_wehrmacht_soldier");
|
||||
Cvar_Set("ui_dm_playergermanmodel", pszUIPlayerModel);
|
||||
pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel_set", "german_wehrmacht_soldier");
|
||||
if (!Q_stricmpn(pszUIPlayerModel, "german_waffen", 14)) {
|
||||
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
|
||||
Cvar_Set("dm_playergermanmodel", donotshowssindeorfr);
|
||||
} else {
|
||||
Cvar_Set("dm_playergermanmodel", pszUIPlayerModel);
|
||||
}
|
||||
|
||||
Cvar_Set("name", CvarGetForUI("ui_name", "*** Blank Name ***"));
|
||||
Cvar_Set("name", CvarGetForUI("ui_name", "UnnamedSoldier"));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3230,24 +3321,30 @@ void UI_GetPlayerModel_f(void)
|
||||
const char *pszUIPlayerModel;
|
||||
char donotshowssindeorfr[64];
|
||||
|
||||
//
|
||||
// Allies
|
||||
//
|
||||
pszUIPlayerModel = CvarGetForUI("dm_playermodel", "american_army");
|
||||
Cvar_Set("ui_dm_playermodel", pszUIPlayerModel);
|
||||
|
||||
Cvar_Set("ui_dm_playermodel", PM_FilenameToDisplayname(pszUIPlayerModel));
|
||||
Cvar_Set("ui_dm_playermodel_set", pszUIPlayerModel);
|
||||
Cvar_Set("ui_disp_playermodel", va("models/player/%s.tik", pszUIPlayerModel));
|
||||
|
||||
//
|
||||
// Axis
|
||||
//
|
||||
pszUIPlayerModel = CvarGetForUI("dm_playergermanmodel", "german_wehrmacht_soldier");
|
||||
Cvar_Set("ui_dm_playergermanmodel", pszUIPlayerModel);
|
||||
Cvar_Set("ui_dm_playergermanmodel", PM_FilenameToDisplayname(pszUIPlayerModel));
|
||||
Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel);
|
||||
|
||||
if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) {
|
||||
memcpy(donotshowssindeorfr, "german_waffenss_", 17);
|
||||
strncat(donotshowssindeorfr, pszUIPlayerModel + 14, 48);
|
||||
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
|
||||
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
|
||||
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
|
||||
} else {
|
||||
strncpy(donotshowssindeorfr, pszUIPlayerModel, sizeof(donotshowssindeorfr));
|
||||
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", pszUIPlayerModel));
|
||||
}
|
||||
|
||||
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
|
||||
|
||||
Cvar_Set("ui_name", CvarGetForUI("name", "*** Blank Name ***"));
|
||||
Cvar_Set("ui_name", CvarGetForUI("name", "UnnamedSoldier"));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3582,7 +3679,7 @@ void CL_FillUIImports(void)
|
||||
uii.Cvar_GetString = CvarGetForUI;
|
||||
uii.Cvar_Reset = Cvar_Reset;
|
||||
uii.Cvar_Find = Cvar_FindVar;
|
||||
uii.Cvar_Set = Cvar_Set;
|
||||
uii.Cvar_Set = UI_Cvar_Set;
|
||||
uii.File_PickFile = PickFile;
|
||||
uii.File_FreeFile = FS_FreeFile;
|
||||
uii.File_ListFiles = ListFilesForUI;
|
||||
@@ -3773,7 +3870,7 @@ void UI_CreateDialog(
|
||||
dlg->Create(NULL, rect, title, bgColor, UHudColor);
|
||||
dlg->LinkCvar(cvarname);
|
||||
dlg->SetOKCommand(command);
|
||||
dlg->SetCancelCommand(command);
|
||||
dlg->SetCancelCommand(cancelCommand);
|
||||
dlg->SetLabelMaterial(uWinMan.RegisterShader(shader));
|
||||
dlg->SetOkMaterial(uWinMan.RegisterShader(okshader));
|
||||
|
||||
@@ -3879,13 +3976,13 @@ void S_ServerLoaded(void)
|
||||
Com_DPrintf("Loading Previous Sound State.\n");
|
||||
S_StopAllSounds2(qfalse);
|
||||
|
||||
//S_TriggeredMusic_Stop();
|
||||
//s_bSoundPaused = qtrue;
|
||||
//S_ReLoad( &svs.soundSystem );
|
||||
//
|
||||
//if( svs.tm_filename[ 0 ] ) {
|
||||
// S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
|
||||
//}
|
||||
S_TriggeredMusic_Stop();
|
||||
s_bSoundPaused = qtrue;
|
||||
S_ReLoad( &svs.soundSystem );
|
||||
|
||||
if( svs.tm_filename[ 0 ] ) {
|
||||
S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4178,7 +4275,7 @@ public:
|
||||
virtual griditemtype_t getListItemType(int which) const;
|
||||
virtual str getListItemString(int i) const;
|
||||
virtual int getListItemValue(int which) const;
|
||||
virtual void DrawListItem(int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont);
|
||||
virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont);
|
||||
virtual qboolean IsHeaderEntry(void) const;
|
||||
};
|
||||
|
||||
@@ -4342,8 +4439,8 @@ public:
|
||||
virtual griditemtype_t getListItemType(int which) const;
|
||||
virtual str getListItemString(int i) const;
|
||||
virtual int getListItemValue(int which) const;
|
||||
virtual void DrawListItem(int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont);
|
||||
void SetColors(const UColor &newTextColor, const UColor &newBackColor);
|
||||
virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont);
|
||||
void SetColors(const UColor& newTextColor, const UColor& newBackColor);
|
||||
void ClearColors(void);
|
||||
void SetTitleItem(qboolean bSet);
|
||||
virtual qboolean IsHeaderEntry(void) const;
|
||||
|
||||
@@ -49,6 +49,7 @@ void CL_ShutdownUI(void);
|
||||
extern inventory_t client_inv;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t *cl_greenfps;
|
||||
extern qboolean server_loading;
|
||||
|
||||
const char *CvarGetForUI(const char *name, const char *defval);
|
||||
void UI_ClearState(void);
|
||||
|
||||
+430
-182
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,281 +24,529 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
bind_t::bind_t()
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
|
||||
commandwidth = 100;
|
||||
commandheight = 20;
|
||||
primarykeywidth = 100;
|
||||
primarykeyheight = 20;
|
||||
alternatekeywidth = 100;
|
||||
alternatekeyheight = 20;
|
||||
fillwidth = 16;
|
||||
fillmaterial = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(headermats); i++) {
|
||||
headermats[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bind_t::~bind_t()
|
||||
{
|
||||
Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
void bind_t::Clear
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void bind_t::Clear(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
for (int i = binds.NumObjects(); i > 0; i--) {
|
||||
bind_item_t *bi;
|
||||
|
||||
bi = binds.ObjectAt(i);
|
||||
binds.RemoveObjectAt(i);
|
||||
|
||||
if (bi) {
|
||||
delete bi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( Listener, bindlistener, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
Event EV_Bind_Header
|
||||
(
|
||||
"header",
|
||||
EV_DEFAULT,
|
||||
"iss",
|
||||
"column_num name material",
|
||||
"Set the header of each column"
|
||||
);
|
||||
Event EV_Bind_Width
|
||||
(
|
||||
"bind_width",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the bind menu"
|
||||
);
|
||||
Event EV_Bind_Height
|
||||
(
|
||||
"bind_height",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the bind menu"
|
||||
);
|
||||
Event EV_Bind_FillWidth
|
||||
(
|
||||
"bind_fillwidth",
|
||||
EV_DEFAULT,
|
||||
"iS",
|
||||
"width material",
|
||||
"Width of the filling between widgets"
|
||||
);
|
||||
Event EV_Bind_CommandWidth
|
||||
(
|
||||
"bind_commandwidth",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the command item"
|
||||
);
|
||||
Event EV_Bind_CommandHeight
|
||||
(
|
||||
"bind_commandheight",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the command item"
|
||||
);
|
||||
Event EV_Bind_PrimaryKeyWidth
|
||||
(
|
||||
"bind_primarykeywidth",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the primary key item"
|
||||
);
|
||||
Event EV_Bind_PrimaryKeyHeight
|
||||
(
|
||||
"bind_primarykeyheight",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the primary key item"
|
||||
);
|
||||
Event EV_Bind_AlternateKeyWidth
|
||||
(
|
||||
"bind_alternatekeywidth",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the alternate key item"
|
||||
);
|
||||
Event EV_Bind_AlternateKeyHeight
|
||||
(
|
||||
"bind_alternatekeyheight",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the alternate key item"
|
||||
);
|
||||
Event EV_Bind_NewItem
|
||||
(
|
||||
"binditem",
|
||||
EV_DEFAULT,
|
||||
"ss",
|
||||
"name command",
|
||||
"Create a new bind item in the interface"
|
||||
);
|
||||
Event EV_Bind_Align
|
||||
(
|
||||
"align",
|
||||
EV_DEFAULT,
|
||||
"sSSSSS",
|
||||
"arg1 arg2 arg3 arg4 arg5 arg6",
|
||||
"Set the alignment on the bind menu"
|
||||
);
|
||||
Event EV_Bind_TitleForegroundColor
|
||||
(
|
||||
"titleforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the title foreground"
|
||||
);
|
||||
Event EV_Bind_TitleBackgroundColor
|
||||
(
|
||||
"titlebackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the title background"
|
||||
);
|
||||
Event EV_Bind_InactiveForegroundColor
|
||||
(
|
||||
"inactiveforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the inactive button foreground"
|
||||
);
|
||||
Event EV_Bind_InactiveBackgroundColor
|
||||
(
|
||||
"inactivebackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the inactive button background"
|
||||
);
|
||||
Event EV_Bind_ActiveForegroundColor
|
||||
(
|
||||
"activeforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the active button foreground"
|
||||
);
|
||||
Event EV_Bind_ActiveBackgroundColor
|
||||
(
|
||||
"activebackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the active button background"
|
||||
);
|
||||
Event EV_Bind_ActiveBorderColor
|
||||
(
|
||||
"activebordercolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the active button border"
|
||||
);
|
||||
Event EV_Bind_HighlightForegroundColor
|
||||
(
|
||||
"highlightforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the highlighted button foreground"
|
||||
);
|
||||
Event EV_Bind_HighlightBackgroundColor
|
||||
(
|
||||
"highlightbackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the highlighted button background"
|
||||
);
|
||||
Event EV_Bind_SelectForegroundColor
|
||||
(
|
||||
"selectforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the selected button foreground"
|
||||
);
|
||||
Event EV_Bind_SelectBackgroundColor
|
||||
(
|
||||
"selectbackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the selected button background"
|
||||
);
|
||||
Event EV_Bind_ChangeSound
|
||||
(
|
||||
"changesound",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"soundname",
|
||||
"Set the name of the sound to play when the highlighted item changes"
|
||||
);
|
||||
Event EV_Bind_ActiveSound
|
||||
(
|
||||
"activesound",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"soundname",
|
||||
"Set the name of the sound to play when the item is made active"
|
||||
);
|
||||
Event EV_Bind_EnterSound
|
||||
(
|
||||
"entersound",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"soundname",
|
||||
"Set the name of the sound to play when the key is entered"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(Listener, bindlistener, NULL) {
|
||||
{&EV_Bind_Width, &bindlistener::Width },
|
||||
{&EV_Bind_Height, &bindlistener::Height },
|
||||
{&EV_Bind_FillWidth, &bindlistener::FillWidth },
|
||||
{&EV_Bind_CommandWidth, &bindlistener::CommandWidth },
|
||||
{&EV_Bind_CommandHeight, &bindlistener::CommandHeight },
|
||||
{&EV_Bind_PrimaryKeyWidth, &bindlistener::PrimaryKeyWidth },
|
||||
{&EV_Bind_PrimaryKeyHeight, &bindlistener::PrimaryKeyHeight },
|
||||
{&EV_Bind_AlternateKeyWidth, &bindlistener::AlternateKeyWidth },
|
||||
{&EV_Bind_AlternateKeyHeight, &bindlistener::AlternateKeyHeight },
|
||||
{&EV_Bind_Header, &bindlistener::Header },
|
||||
{&EV_Bind_NewItem, &bindlistener::NewItem },
|
||||
{&EV_Bind_Align, &bindlistener::Align },
|
||||
{&EV_Bind_TitleForegroundColor, &bindlistener::TitleForegroundColor },
|
||||
{&EV_Bind_TitleBackgroundColor, &bindlistener::TitleBackgroundColor },
|
||||
{&EV_Bind_InactiveForegroundColor, &bindlistener::InactiveForegroundColor },
|
||||
{&EV_Bind_InactiveBackgroundColor, &bindlistener::InactiveBackgroundColor },
|
||||
{&EV_Bind_ActiveForegroundColor, &bindlistener::ActiveForegroundColor },
|
||||
{&EV_Bind_ActiveBackgroundColor, &bindlistener::ActiveBackgroundColor },
|
||||
{&EV_Bind_ActiveBorderColor, &bindlistener::ActiveBorderColor },
|
||||
{&EV_Bind_HighlightForegroundColor, &bindlistener::HighlightForegroundColor},
|
||||
{&EV_Bind_HighlightBackgroundColor, &bindlistener::HighlightBackgroundColor},
|
||||
{&EV_Bind_SelectForegroundColor, &bindlistener::SelectForegroundColor },
|
||||
{&EV_Bind_SelectBackgroundColor, &bindlistener::SelectBackgroundColor },
|
||||
{&EV_Bind_ChangeSound, &bindlistener::ChangeSound },
|
||||
{&EV_Bind_ActiveSound, &bindlistener::ActiveSound },
|
||||
{&EV_Bind_EnterSound, &bindlistener::EnterSound },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
bindlistener::bindlistener()
|
||||
bindlistener::bindlistener() {}
|
||||
|
||||
bindlistener::bindlistener(bind_t *b)
|
||||
{
|
||||
bind = b;
|
||||
}
|
||||
|
||||
bindlistener::bindlistener
|
||||
(
|
||||
bind_t *b
|
||||
)
|
||||
|
||||
void bindlistener::Header(Event *ev)
|
||||
{
|
||||
bind = b;
|
||||
int num;
|
||||
|
||||
num = ev->GetInteger(1) - 1;
|
||||
if (num > ARRAY_LEN(bind_t::headers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bind->headers[num] = ev->GetString(2);
|
||||
if (ev->NumArgs() > 2) {
|
||||
bind->headermats[num] = uWinMan.RegisterShader(ev->GetString(3));
|
||||
}
|
||||
}
|
||||
|
||||
bool bindlistener::Load
|
||||
(
|
||||
Script& script
|
||||
)
|
||||
|
||||
void bindlistener::ChangeSound(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return false;
|
||||
bind->changesound = ev->GetString(1);
|
||||
}
|
||||
|
||||
void bindlistener::Header
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveSound(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activesound = ev->GetString(1);
|
||||
}
|
||||
|
||||
void bindlistener::Width
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::EnterSound(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->entersound = ev->GetString(1);
|
||||
}
|
||||
|
||||
void bindlistener::FillWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::SelectForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->selectfgcolor.r = ev->GetFloat(1);
|
||||
bind->selectfgcolor.g = ev->GetFloat(2);
|
||||
bind->selectfgcolor.b = ev->GetFloat(3);
|
||||
bind->selectfgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::Height
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::SelectBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->selectbgcolor.r = ev->GetFloat(1);
|
||||
bind->selectbgcolor.g = ev->GetFloat(2);
|
||||
bind->selectbgcolor.b = ev->GetFloat(3);
|
||||
bind->selectbgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::CommandWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::TitleForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->titlefgcolor.r = ev->GetFloat(1);
|
||||
bind->titlefgcolor.g = ev->GetFloat(2);
|
||||
bind->titlefgcolor.b = ev->GetFloat(3);
|
||||
bind->titlefgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::CommandHeight
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::TitleBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->titlebgcolor.r = ev->GetFloat(1);
|
||||
bind->titlebgcolor.g = ev->GetFloat(2);
|
||||
bind->titlebgcolor.b = ev->GetFloat(3);
|
||||
bind->titlebgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::PrimaryKeyWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveBorderColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activebordercolor.r = ev->GetFloat(1);
|
||||
bind->activebordercolor.g = ev->GetFloat(2);
|
||||
bind->activebordercolor.b = ev->GetFloat(3);
|
||||
bind->activebordercolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::PrimaryKeyHeight
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activefgcolor.r = ev->GetFloat(1);
|
||||
bind->activefgcolor.g = ev->GetFloat(2);
|
||||
bind->activefgcolor.b = ev->GetFloat(3);
|
||||
bind->activefgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::AlternateKeyWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activebgcolor.r = ev->GetFloat(1);
|
||||
bind->activebgcolor.g = ev->GetFloat(2);
|
||||
bind->activebgcolor.b = ev->GetFloat(3);
|
||||
bind->activebgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::AlternateKeyHeight
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::InactiveForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->inactivefgcolor.r = ev->GetFloat(1);
|
||||
bind->inactivefgcolor.g = ev->GetFloat(2);
|
||||
bind->inactivefgcolor.b = ev->GetFloat(3);
|
||||
bind->inactivefgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::NewItem
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::InactiveBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->inactivebgcolor.r = ev->GetFloat(1);
|
||||
bind->inactivebgcolor.g = ev->GetFloat(2);
|
||||
bind->inactivebgcolor.b = ev->GetFloat(3);
|
||||
bind->inactivebgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::Align
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::HighlightForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->highlightfgcolor.r = ev->GetFloat(1);
|
||||
bind->highlightfgcolor.g = ev->GetFloat(2);
|
||||
bind->highlightfgcolor.b = ev->GetFloat(3);
|
||||
bind->highlightfgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::TitleForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::HighlightBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->highlightbgcolor.r = ev->GetFloat(1);
|
||||
bind->highlightbgcolor.g = ev->GetFloat(2);
|
||||
bind->highlightbgcolor.b = ev->GetFloat(3);
|
||||
bind->highlightbgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::TitleBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::Align(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= ev->NumArgs(); i++) {
|
||||
str align = ev->GetString(i);
|
||||
|
||||
if (!str::icmp(align, "left")) {
|
||||
bind->align |= WA_LEFT;
|
||||
} else if (!str::icmp(align, "right")) {
|
||||
bind->align |= WA_RIGHT;
|
||||
} else if (!str::icmp(align, "top")) {
|
||||
bind->align |= WA_TOP;
|
||||
} else if (!str::icmp(align, "bottom")) {
|
||||
bind->align |= WA_BOTTOM;
|
||||
} else if (!str::icmp(align, "centerx")) {
|
||||
bind->align |= WA_CENTERX;
|
||||
} else if (!str::icmp(align, "centery")) {
|
||||
bind->align |= WA_CENTERY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bindlistener::InactiveForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::NewItem(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind_item_t *bt;
|
||||
UIReggedMaterial *mat = NULL;
|
||||
|
||||
if (ev->NumArgs() > 2) {
|
||||
mat = uWinMan.RegisterShader(ev->GetString(3));
|
||||
}
|
||||
|
||||
str n = ev->GetString(1);
|
||||
str c = ev->GetString(2);
|
||||
|
||||
bt = new bind_item_t;
|
||||
bt->name = n;
|
||||
bt->command = c;
|
||||
bt->nameMaterial = mat;
|
||||
|
||||
bind->binds.AddObject(bt);
|
||||
}
|
||||
|
||||
void bindlistener::InactiveBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::Width(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->width = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ActiveForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::Height(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->height = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ActiveBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::FillWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->fillwidth = ev->GetInteger(1);
|
||||
|
||||
if (ev->NumArgs() > 1) {
|
||||
bind->fillmaterial = uWinMan.RegisterShader(ev->GetString(2));
|
||||
}
|
||||
}
|
||||
|
||||
void bindlistener::ActiveBorderColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::CommandWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->commandwidth = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::HighlightForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::CommandHeight(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->commandheight = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::HighlightBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::PrimaryKeyWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->primarykeywidth = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::SelectForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::PrimaryKeyHeight(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->primarykeyheight = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::SelectBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::AlternateKeyWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->alternatekeywidth = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ChangeSound
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::AlternateKeyHeight(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->alternatekeyheight = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ActiveSound
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
bool bindlistener::Load(Script& script)
|
||||
{
|
||||
// FIXME: stub
|
||||
str token;
|
||||
str errortext;
|
||||
|
||||
while (script.TokenAvailable(true)) {
|
||||
token = script.GetToken(true);
|
||||
|
||||
if (!token.length() || !ValidEvent(token)) {
|
||||
throw "invalid token";
|
||||
}
|
||||
|
||||
Event *event = new Event(token);
|
||||
|
||||
while (script.TokenAvailable(false)) {
|
||||
event->AddToken(script.GetToken(false));
|
||||
}
|
||||
|
||||
ProcessEvent(event);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void bindlistener::EnterSound
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
bool CL_LoadBind(const char *filename, bind_t *bind)
|
||||
{
|
||||
// FIXME: stub
|
||||
Script script;
|
||||
|
||||
bind->Clear();
|
||||
|
||||
bindlistener listener(bind);
|
||||
script.LoadFile(filename);
|
||||
// Load the bind file
|
||||
return listener.Load(script);
|
||||
}
|
||||
+82
-88
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,115 +20,109 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIBIND_H__
|
||||
#define __CL_UIBIND_H__
|
||||
#pragma once
|
||||
|
||||
class bind_item_t {
|
||||
class bind_item_t
|
||||
{
|
||||
public:
|
||||
str name;
|
||||
str command;
|
||||
UIReggedMaterial *nameMaterial;
|
||||
str name;
|
||||
str command;
|
||||
UIReggedMaterial *nameMaterial;
|
||||
|
||||
bind_item_t();
|
||||
bind_item_t( str name, str command, UIReggedMaterial *nameMaterial );
|
||||
bind_item_t();
|
||||
bind_item_t(str name, str command, UIReggedMaterial *nameMaterial);
|
||||
};
|
||||
|
||||
inline
|
||||
bind_item_t::bind_item_t()
|
||||
inline bind_item_t::bind_item_t()
|
||||
{
|
||||
nameMaterial = NULL;
|
||||
nameMaterial = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
bind_item_t::bind_item_t
|
||||
(
|
||||
str name,
|
||||
str command,
|
||||
UIReggedMaterial *nameMaterial
|
||||
)
|
||||
|
||||
inline bind_item_t::bind_item_t(str name, str command, UIReggedMaterial *nameMaterial)
|
||||
{
|
||||
this->name = name;
|
||||
this->command = command;
|
||||
this->nameMaterial = nameMaterial;
|
||||
this->name = name;
|
||||
this->command = command;
|
||||
this->nameMaterial = nameMaterial;
|
||||
}
|
||||
|
||||
class bind_t {
|
||||
class bind_t
|
||||
{
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
int fillwidth;
|
||||
int commandwidth;
|
||||
int commandheight;
|
||||
int primarykeywidth;
|
||||
int primarykeyheight;
|
||||
int alternatekeywidth;
|
||||
int alternatekeyheight;
|
||||
int align;
|
||||
UColor titlebgcolor;
|
||||
UColor titlefgcolor;
|
||||
UColor activefgcolor;
|
||||
UColor activebgcolor;
|
||||
UColor activebordercolor;
|
||||
UColor inactivefgcolor;
|
||||
UColor inactivebgcolor;
|
||||
UColor highlightfgcolor;
|
||||
UColor highlightbgcolor;
|
||||
UColor selectfgcolor;
|
||||
UColor selectbgcolor;
|
||||
str changesound;
|
||||
str activesound;
|
||||
str entersound;
|
||||
str headers[ 3 ];
|
||||
UIReggedMaterial *headermats[ 3 ];
|
||||
UIReggedMaterial *fillmaterial;
|
||||
Container<bind_item_t *> binds;
|
||||
int width;
|
||||
int height;
|
||||
int fillwidth;
|
||||
int commandwidth;
|
||||
int commandheight;
|
||||
int primarykeywidth;
|
||||
int primarykeyheight;
|
||||
int alternatekeywidth;
|
||||
int alternatekeyheight;
|
||||
int align;
|
||||
UColor titlebgcolor;
|
||||
UColor titlefgcolor;
|
||||
UColor activefgcolor;
|
||||
UColor activebgcolor;
|
||||
UColor activebordercolor;
|
||||
UColor inactivefgcolor;
|
||||
UColor inactivebgcolor;
|
||||
UColor highlightfgcolor;
|
||||
UColor highlightbgcolor;
|
||||
UColor selectfgcolor;
|
||||
UColor selectbgcolor;
|
||||
str changesound;
|
||||
str activesound;
|
||||
str entersound;
|
||||
str headers[3];
|
||||
UIReggedMaterial *headermats[3];
|
||||
UIReggedMaterial *fillmaterial;
|
||||
Container<bind_item_t *> binds;
|
||||
|
||||
public:
|
||||
bind_t();
|
||||
~bind_t();
|
||||
bind_t();
|
||||
~bind_t();
|
||||
|
||||
void Clear( void );
|
||||
void Clear(void);
|
||||
};
|
||||
|
||||
class bindlistener : public Listener {
|
||||
class bindlistener : public Listener
|
||||
{
|
||||
protected:
|
||||
bind_t *bind;
|
||||
bind_t *bind;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( bindlistener );
|
||||
CLASS_PROTOTYPE(bindlistener);
|
||||
|
||||
public:
|
||||
bindlistener();
|
||||
bindlistener( bind_t *b );
|
||||
bindlistener();
|
||||
bindlistener(bind_t *b);
|
||||
|
||||
bool Load( Script& script );
|
||||
void Header( Event *ev );
|
||||
void Width( Event *ev );
|
||||
void FillWidth( Event *ev );
|
||||
void Height( Event *ev );
|
||||
void CommandWidth( Event *ev );
|
||||
void CommandHeight( Event *ev );
|
||||
void PrimaryKeyWidth( Event *ev );
|
||||
void PrimaryKeyHeight( Event *ev );
|
||||
void AlternateKeyWidth( Event *ev );
|
||||
void AlternateKeyHeight( Event *ev );
|
||||
void NewItem( Event *ev );
|
||||
void Align( Event *ev );
|
||||
void TitleForegroundColor( Event *ev );
|
||||
void TitleBackgroundColor( Event *ev );
|
||||
void InactiveForegroundColor( Event *ev );
|
||||
void InactiveBackgroundColor( Event *ev );
|
||||
void ActiveForegroundColor( Event *ev );
|
||||
void ActiveBackgroundColor( Event *ev );
|
||||
void ActiveBorderColor( Event *ev );
|
||||
void HighlightForegroundColor( Event *ev );
|
||||
void HighlightBackgroundColor( Event *ev );
|
||||
void SelectForegroundColor( Event *ev );
|
||||
void SelectBackgroundColor( Event *ev );
|
||||
void ChangeSound( Event *ev );
|
||||
void ActiveSound( Event *ev );
|
||||
void EnterSound( Event *ev );
|
||||
bool Load(Script& script);
|
||||
void Header(Event *ev);
|
||||
void Width(Event *ev);
|
||||
void FillWidth(Event *ev);
|
||||
void Height(Event *ev);
|
||||
void CommandWidth(Event *ev);
|
||||
void CommandHeight(Event *ev);
|
||||
void PrimaryKeyWidth(Event *ev);
|
||||
void PrimaryKeyHeight(Event *ev);
|
||||
void AlternateKeyWidth(Event *ev);
|
||||
void AlternateKeyHeight(Event *ev);
|
||||
void NewItem(Event *ev);
|
||||
void Align(Event *ev);
|
||||
void TitleForegroundColor(Event *ev);
|
||||
void TitleBackgroundColor(Event *ev);
|
||||
void InactiveForegroundColor(Event *ev);
|
||||
void InactiveBackgroundColor(Event *ev);
|
||||
void ActiveForegroundColor(Event *ev);
|
||||
void ActiveBackgroundColor(Event *ev);
|
||||
void ActiveBorderColor(Event *ev);
|
||||
void HighlightForegroundColor(Event *ev);
|
||||
void HighlightBackgroundColor(Event *ev);
|
||||
void SelectForegroundColor(Event *ev);
|
||||
void SelectBackgroundColor(Event *ev);
|
||||
void ChangeSound(Event *ev);
|
||||
void ActiveSound(Event *ev);
|
||||
void EnterSound(Event *ev);
|
||||
};
|
||||
|
||||
#endif
|
||||
bool CL_LoadBind(const char* filename, bind_t* bind);
|
||||
+209
-27
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,72 +22,254 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( USignal, FilePickerClass, NULL )
|
||||
class FilePickerItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str strings[3];
|
||||
|
||||
public:
|
||||
FilePickerItem(const str& fileName, const str& date, const str& size);
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
CLASS_DECLARATION(USignal, FilePickerClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &FilePickerClass::FileSelected },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &FilePickerClass::FileChosen },
|
||||
{&W_Deactivated, &FilePickerClass::OnDeactivated},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
FilePickerClass::FilePickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
|
||||
"File Picker",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
);
|
||||
window->Connect(this, W_Deactivated, W_Deactivated);
|
||||
listbox = new UIListCtrl();
|
||||
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
|
||||
listbox->setBackgroundColor(UColor(0.02f, 0.07f, 0.005f), true);
|
||||
listbox->setForegroundColor(UHudColor);
|
||||
listbox->AddColumn("File Name", 0, 175, false, false);
|
||||
listbox->AddColumn("Date", 1, 125, false, false);
|
||||
listbox->AddColumn("Size", 2, 100, true, false);
|
||||
|
||||
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
listbox->AllowActivate(true);
|
||||
|
||||
// Added in 2.0
|
||||
// Don't localize elements
|
||||
listbox->SetDontLocalize();
|
||||
}
|
||||
|
||||
FilePickerClass::~FilePickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
if (listbox) {
|
||||
delete listbox;
|
||||
listbox = NULL;
|
||||
}
|
||||
|
||||
if (window) {
|
||||
delete window;
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FilePickerClass::SetupFiles( void )
|
||||
void FilePickerClass::Setup(
|
||||
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
Initialize(root_directory, current_directory, ext, ignore_files);
|
||||
}
|
||||
|
||||
void FilePickerClass::GotoParentDirectory( void )
|
||||
void FilePickerClass::Initialize(
|
||||
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
rootDirectory = root_directory;
|
||||
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
|
||||
rootDirectory += "/";
|
||||
}
|
||||
|
||||
currentDirectory = current_directory;
|
||||
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
extension = ext;
|
||||
ignoredFiles = ignore_files;
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void FilePickerClass::GotoSubDirectory( str subdir )
|
||||
void FilePickerClass::GotoParentDirectory(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
|
||||
if (currentDirectory == rootDirectory) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = currentDirectory.length() - 2; i > 0; i--) {
|
||||
if (currentDirectory[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentDirectory[i] == '/') {
|
||||
i++;
|
||||
}
|
||||
|
||||
currentDirectory = str(currentDirectory, 0, i);
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void FilePickerClass::Initialize( const char *root_directory, const char *current_directory, const char *ext )
|
||||
void FilePickerClass::GotoSubDirectory(str subdir)
|
||||
{
|
||||
// FIXME: stub
|
||||
currentDirectory += subdir + "/";
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void FilePickerClass::CloseWindow( void )
|
||||
void FilePickerClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
str mappath;
|
||||
str work;
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
char date[128];
|
||||
char size[128];
|
||||
|
||||
listbox->DeleteAllItems();
|
||||
|
||||
if (currentDirectory != rootDirectory) {
|
||||
// create the parent directory item
|
||||
listbox->AddItem(new FilePickerItem("..", "", ""));
|
||||
}
|
||||
|
||||
// retrieve directories
|
||||
filenames = FS_ListFiles(currentDirectory, "/", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
|
||||
if (filename[0] == '.' || !strlen(filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
work = "[";
|
||||
work += filename;
|
||||
work += "]";
|
||||
|
||||
FS_FileTime(currentDirectory + filename, date, size);
|
||||
|
||||
listbox->AddItem(new FilePickerItem(work, date, size));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
filenames = FS_ListFiles(currentDirectory, extension, qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
|
||||
if (ignoredFiles.length() && strstr(filename, ignoredFiles)) {
|
||||
// Added in 2.0
|
||||
// Check for ignored files
|
||||
continue;
|
||||
}
|
||||
|
||||
work = filename;
|
||||
|
||||
FS_FileTime(currentDirectory + work, date, size);
|
||||
|
||||
listbox->AddItem(new FilePickerItem(work, date, size));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
window->setTitle(currentDirectory);
|
||||
}
|
||||
|
||||
void FilePickerClass::FileSelected( Event *ev )
|
||||
void FilePickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) {}
|
||||
|
||||
void FilePickerClass::FileSelected(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
|
||||
if (*name != '[' && *name != '.') {
|
||||
FileSelected(currentDirectory, name, currentDirectory + name);
|
||||
}
|
||||
|
||||
uii.Snd_PlaySound("sound/menu/scroll.wav");
|
||||
}
|
||||
|
||||
void FilePickerClass::FileSelected( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void FilePickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) {}
|
||||
|
||||
void FilePickerClass::FileChosen(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str filename = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
|
||||
if (*filename == '[') {
|
||||
uii.Snd_PlaySound("sound/menu/scroll.wav");
|
||||
|
||||
GotoSubDirectory(str(filename, 1, filename.length() - 1));
|
||||
} else if (*filename == '.') {
|
||||
GotoParentDirectory();
|
||||
} else {
|
||||
uii.Snd_PlaySound("sound/menu/apply.wav");
|
||||
|
||||
FileChosen(currentDirectory, filename, currentDirectory + filename);
|
||||
}
|
||||
}
|
||||
|
||||
void FilePickerClass::FileChosen( Event *ev )
|
||||
void FilePickerClass::CloseWindow(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
void FilePickerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void FilePickerClass::OnDeactivated(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void FilePickerClass::OnDeactivated( Event *ev )
|
||||
FilePickerItem::FilePickerItem(const str& fileName, const str& date, const str& size)
|
||||
{
|
||||
// FIXME: stub
|
||||
strings[0] = fileName;
|
||||
strings[1] = date;
|
||||
strings[2] = size;
|
||||
}
|
||||
|
||||
void FilePickerClass::Setup( const char *root_directory, const char *current_directory, const char *ext )
|
||||
int FilePickerItem::getListItemValue(int which) const
|
||||
{
|
||||
// FIXME: stub
|
||||
return atoi(strings[which]);
|
||||
}
|
||||
|
||||
griditemtype_t FilePickerItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str FilePickerItem::getListItemString(int which) const
|
||||
{
|
||||
return strings[which];
|
||||
}
|
||||
|
||||
void FilePickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean FilePickerItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,40 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIFILEPICKER_H__
|
||||
#define __CL_UIFILEPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class UIListCtrl;
|
||||
|
||||
class FilePickerClass : public USignal {
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
str extension;
|
||||
class FilePickerClass : public USignal
|
||||
{
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
str extension;
|
||||
// Added in 2.0
|
||||
str ignoredFiles;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FilePickerClass );
|
||||
CLASS_PROTOTYPE(FilePickerClass);
|
||||
|
||||
private:
|
||||
void SetupFiles( void );
|
||||
void GotoParentDirectory( void );
|
||||
void GotoSubDirectory( str subdir );
|
||||
void Initialize( const char *root_directory, const char *current_directory, const char *ext );
|
||||
void SetupFiles(void);
|
||||
void GotoParentDirectory(void);
|
||||
void GotoSubDirectory(str subdir);
|
||||
// ignore_files parameter, added in 2.0
|
||||
void Initialize(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files);
|
||||
|
||||
protected:
|
||||
void CloseWindow( void );
|
||||
void FileSelected( Event *ev );
|
||||
virtual void FileSelected( str ¤tDirectory, str &partialName, str &fullname );
|
||||
void FileChosen( Event *ev );
|
||||
virtual void FileChosen( str ¤tDirectory, str &partialName, str &fullname );
|
||||
void OnDeactivated( Event *ev );
|
||||
void CloseWindow(void);
|
||||
void FileSelected(Event *ev);
|
||||
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void FileChosen(Event *ev);
|
||||
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void OnDeactivated(Event *ev);
|
||||
|
||||
public:
|
||||
FilePickerClass();
|
||||
~FilePickerClass();
|
||||
FilePickerClass();
|
||||
~FilePickerClass();
|
||||
|
||||
void Setup( const char *root_directory, const char *current_directory, const char *ext );
|
||||
void Setup(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files = NULL);
|
||||
};
|
||||
|
||||
#endif /* __CL_UIFILEPICKER_H__ */
|
||||
+183
-17
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -21,44 +21,210 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( UIListCtrl, UILANGameClass, NULL )
|
||||
class LANGameItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str strings[5];
|
||||
|
||||
public:
|
||||
LANGameItem();
|
||||
LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
|
||||
);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
Event EV_LANGame_JoinGame
|
||||
(
|
||||
"joingame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Join the currently selected server"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(UIListCtrl, UILANGameClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &UILANGameClass::SelectServer},
|
||||
{&EV_UIListBase_ItemDoubleClicked, &UILANGameClass::JoinServer },
|
||||
{&EV_LANGame_JoinGame, &UILANGameClass::JoinServer },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UILANGameClass::UILANGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
AllowActivate(true);
|
||||
setHeaderFont("facfont-20");
|
||||
|
||||
m_iLastUpdateTime = 0;
|
||||
m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers");
|
||||
}
|
||||
|
||||
void UILANGameClass::SetupServers( void )
|
||||
void UILANGameClass::Draw(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (cls.bNewLocalServerInfo) {
|
||||
SetupServers();
|
||||
}
|
||||
|
||||
UIListCtrl::Draw();
|
||||
|
||||
if (!getNumItems() && m_noservers_mat) {
|
||||
float x, y, w, h;
|
||||
|
||||
w = re.GetShaderWidth(m_noservers_mat->GetMaterial()) * m_vVirtualScale[0];
|
||||
h = re.GetShaderHeight(m_noservers_mat->GetMaterial()) * m_vVirtualScale[1];
|
||||
|
||||
UIRect2D frame = getClientFrame();
|
||||
x = (frame.size.width - w) * 0.5f;
|
||||
y = (frame.size.height - h) * 0.5f;
|
||||
|
||||
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, m_noservers_mat->GetMaterial());
|
||||
}
|
||||
|
||||
if (m_iLastUpdateTime && m_iLastUpdateTime < cls.realtime) {
|
||||
Cvar_Set("cl_langamerefreshstatus", "Ready");
|
||||
m_iLastUpdateTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UILANGameClass::Draw( void )
|
||||
void UILANGameClass::UpdateUIElement(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float width;
|
||||
|
||||
RemoveAllColumns();
|
||||
|
||||
width = getClientFrame().size.width - 16.f;
|
||||
|
||||
AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.4f, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.15f, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.165f, true, true);
|
||||
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.22f, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.065f, true, false);
|
||||
|
||||
uWinMan.ActivateControl(this);
|
||||
|
||||
SetupServers();
|
||||
}
|
||||
|
||||
void UILANGameClass::SelectServer( Event *ev )
|
||||
void UILANGameClass::SetupServers(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
LANGameItem *pItem;
|
||||
const serverInfo_t *pServerInfo;
|
||||
|
||||
for (i = 1; i <= cls.numlocalservers; i++) {
|
||||
pServerInfo = &cls.localServers[i - 1];
|
||||
|
||||
if (i > getNumItems()) {
|
||||
pItem = new LANGameItem();
|
||||
AddItem(pItem);
|
||||
} else {
|
||||
pItem = static_cast<LANGameItem *>(GetItem(i));
|
||||
}
|
||||
|
||||
*pItem = LANGameItem(
|
||||
pServerInfo->hostName,
|
||||
pServerInfo->mapName,
|
||||
va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients),
|
||||
pServerInfo->gameTypeString,
|
||||
str(pServerInfo->ping)
|
||||
);
|
||||
}
|
||||
|
||||
while (cls.numlocalservers < getNumItems()) {
|
||||
DeleteItem(getNumItems());
|
||||
}
|
||||
|
||||
cls.bNewLocalServerInfo = false;
|
||||
m_iLastUpdateTime = 0;
|
||||
}
|
||||
|
||||
void UILANGameClass::JoinServer( Event *ev )
|
||||
void UILANGameClass::SelectServer(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
|
||||
static const char info[] = "\xFF\xFF\xFF\xFF\x02getinfo xxx";
|
||||
|
||||
Com_Printf("Requesting updated info from server...\n");
|
||||
Cvar_Set("cl_langamerefreshstatus", "Requesting updated info from server...");
|
||||
|
||||
NET_SendPacket(NS_CLIENT, sizeof(info), info, serverInfo.adr);
|
||||
m_iLastUpdateTime = cls.realtime + 3000;
|
||||
}
|
||||
|
||||
qboolean UILANGameClass::KeyEvent( int key, unsigned int time )
|
||||
void UILANGameClass::JoinServer(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
if (!getCurrentItem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
|
||||
|
||||
UI_SetReturnMenuToCurrent();
|
||||
CL_Connect(NET_AdrToString(serverInfo.adr), netadrtype_t::NA_UNSPEC);
|
||||
}
|
||||
|
||||
void UILANGameClass::UpdateUIElement( void )
|
||||
qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
// FIXME: stub
|
||||
switch (key) {
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
JoinServer(NULL);
|
||||
return true;
|
||||
case K_UPARROW:
|
||||
if (getCurrentItem() > 1) {
|
||||
TrySelectItem(getCurrentItem() - 1);
|
||||
SelectServer(NULL);
|
||||
}
|
||||
return false;
|
||||
case K_DOWNARROW:
|
||||
if (getCurrentItem() < getNumItems()) {
|
||||
TrySelectItem(getCurrentItem() + 1);
|
||||
SelectServer(NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return UIListBase::KeyEvent(key, time);
|
||||
}
|
||||
|
||||
LANGameItem::LANGameItem() {}
|
||||
|
||||
LANGameItem::LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
|
||||
)
|
||||
{
|
||||
strings[0] = hostName;
|
||||
strings[1] = mapName;
|
||||
strings[2] = players;
|
||||
strings[3] = gameTypeString;
|
||||
strings[4] = ping;
|
||||
}
|
||||
|
||||
int LANGameItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(strings[which]);
|
||||
}
|
||||
|
||||
griditemtype_t LANGameItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str LANGameItem::getListItemString(int which) const
|
||||
{
|
||||
return strings[which];
|
||||
}
|
||||
|
||||
void LANGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean LANGameItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
+14
-16
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,29 +20,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UILANGAME_H__
|
||||
#define __CL_UILANGAME_H__
|
||||
#pragma once
|
||||
|
||||
class UILANGameClass : public UIListCtrl {
|
||||
class UILANGameClass : public UIListCtrl
|
||||
{
|
||||
protected:
|
||||
int m_iLastUpdateTime;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
int m_iLastUpdateTime;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UILANGameClass );
|
||||
CLASS_PROTOTYPE(UILANGameClass);
|
||||
|
||||
private:
|
||||
void SetupServers( void );
|
||||
void SetupServers(void);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void SelectServer( Event *ev );
|
||||
void JoinServer( Event *ev );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void UpdateUIElement( void ) override;
|
||||
void Draw(void) override;
|
||||
void SelectServer(Event *ev);
|
||||
void JoinServer(Event *ev);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void UpdateUIElement(void) override;
|
||||
|
||||
public:
|
||||
UILANGameClass();
|
||||
UILANGameClass();
|
||||
};
|
||||
|
||||
#endif /* __CL_UILANGAME_H__ */
|
||||
+319
-25
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -21,63 +21,357 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( UIListCtrl, UIFAKKLoadGameClass, NULL )
|
||||
class FAKKLoadGameItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str strings[4];
|
||||
|
||||
public:
|
||||
FAKKLoadGameItem(const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
static UIFAKKLoadGameClass *loadgame_ui = NULL;
|
||||
|
||||
Event EV_FAKKLoadGame_LoadGame
|
||||
(
|
||||
"loadgame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Load the currently selected game"
|
||||
);
|
||||
Event EV_FAKKLoadGame_RemoveGame
|
||||
(
|
||||
"removegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete the currently selected game"
|
||||
);
|
||||
Event EV_FAKKLoadGame_DeleteGame
|
||||
(
|
||||
"deletegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete the currently selected game... for real"
|
||||
);
|
||||
Event EV_FAKKLoadGame_NoDeleteGame
|
||||
(
|
||||
"nodeletegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete the currently selected game... for real"
|
||||
);
|
||||
Event EV_FAKKLoadGame_SaveGame
|
||||
(
|
||||
"savegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Save the currently selected game"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(UIListCtrl, UIFAKKLoadGameClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &UIFAKKLoadGameClass::SelectGame },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &UIFAKKLoadGameClass::LoadGame },
|
||||
{&EV_FAKKLoadGame_RemoveGame, &UIFAKKLoadGameClass::RemoveGame },
|
||||
{&EV_FAKKLoadGame_DeleteGame, &UIFAKKLoadGameClass::DeleteGame },
|
||||
{&EV_FAKKLoadGame_NoDeleteGame, &UIFAKKLoadGameClass::NoDeleteGame},
|
||||
{&EV_FAKKLoadGame_LoadGame, &UIFAKKLoadGameClass::LoadGame },
|
||||
{&EV_FAKKLoadGame_SaveGame, &UIFAKKLoadGameClass::SaveGame },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIFAKKLoadGameClass::UIFAKKLoadGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
AllowActivate(false);
|
||||
m_bRemovePending = false;
|
||||
|
||||
setHeaderFont("facfont-20");
|
||||
loadgame_ui = this;
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SelectGame( Event *ev )
|
||||
UIFAKKLoadGameClass::~UIFAKKLoadGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
loadgame_ui = NULL;
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::LoadGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::UpdateUIElement(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float width;
|
||||
|
||||
RemoveAllColumns();
|
||||
|
||||
width = getClientFrame().size.width;
|
||||
AddColumn(Sys_LV_CL_ConvertString("Mission"), 0, width * 0.555, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Elapsed Time"), 1, width * 0.17f, true, true);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Date & Time Logged"), 2, width * 0.275f, true, true);
|
||||
|
||||
uWinMan.ActivateControl(this);
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SaveGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
const char *searchFolder = Com_GetArchiveFolder();
|
||||
|
||||
// cleanup
|
||||
DeleteAllItems();
|
||||
|
||||
filenames = FS_ListFiles(searchFolder, "ssv", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename;
|
||||
str work;
|
||||
str gametime;
|
||||
str date;
|
||||
fileHandle_t f;
|
||||
savegamestruct_t save;
|
||||
|
||||
filename = filenames[i];
|
||||
work = searchFolder;
|
||||
work += "/";
|
||||
work += filename;
|
||||
|
||||
FS_FOpenFileRead(work, &f, qfalse, qtrue);
|
||||
if (!f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FS_Read(&save, sizeof(savegamestruct_t), f);
|
||||
FS_FCloseFile(f);
|
||||
Com_SwapSaveStruct(&save);
|
||||
|
||||
if (save.version != SAVEGAME_STRUCT_VERSION) {
|
||||
// wrong save game version
|
||||
continue;
|
||||
}
|
||||
|
||||
if (save.type != com_target_game->integer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gametime = (save.mapTime / 1000);
|
||||
date = save.time;
|
||||
|
||||
AddItem(new FAKKLoadGameItem(save.comment, gametime, date, save.saveName));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
// sort by date
|
||||
SortByColumn(2);
|
||||
|
||||
// select the first item
|
||||
TrySelectItem(1);
|
||||
SelectGame(NULL);
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::RemoveGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::SelectGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
UIWidget *wid;
|
||||
const char *shotName;
|
||||
|
||||
if (getCurrentItem() > 0) {
|
||||
shotName = Com_GetArchiveFileName(GetItem(getCurrentItem())->getListItemString(3), "tga");
|
||||
} else {
|
||||
shotName = "textures/menu/no_saved_games.tga";
|
||||
}
|
||||
|
||||
wid = findSibling("LoadSaveShot");
|
||||
if (!wid) {
|
||||
return;
|
||||
}
|
||||
|
||||
wid->setMaterial(uWinMan.RefreshShader(shotName));
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::DeleteGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::RemoveGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_bRemovePending || getCurrentItem() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cbuf_ExecuteText(
|
||||
EXEC_NOW,
|
||||
"dialog \"\" \"\" \"widgetcommand LoadSaveList deletegame\" \"widgetcommand LoadSaveList nodeletegame\" 256 64 "
|
||||
"confirm_delete menu_button_trans menu_button_trans\n"
|
||||
);
|
||||
m_bRemovePending = true;
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::NoDeleteGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::NoDeleteGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_bRemovePending = false;
|
||||
}
|
||||
|
||||
qboolean UIFAKKLoadGameClass::KeyEvent( int key, unsigned int time )
|
||||
void UIFAKKLoadGameClass::DeleteGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
str name;
|
||||
cvar_t *var;
|
||||
m_bRemovePending = false;
|
||||
|
||||
if (getCurrentItem() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = GetItem(getCurrentItem())->getListItemString(3);
|
||||
var = Cvar_Get("g_lastsave", "", 0);
|
||||
|
||||
if (!strcmp(name, var->string)) {
|
||||
// Make sure the last save is not the save being deleted
|
||||
Cvar_Set("g_lastsave", "");
|
||||
}
|
||||
|
||||
Com_WipeSavegame(name);
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::UpdateUIElement( void )
|
||||
void UIFAKKLoadGameClass::LoadGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
char cmdString[266];
|
||||
str name;
|
||||
|
||||
if (getCurrentItem() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = GetItem(getCurrentItem())->getListItemString(3);
|
||||
// Execute the command
|
||||
Com_sprintf(cmdString, sizeof(cmdString), "loadgame %s\n", name.c_str());
|
||||
Cbuf_AddText(cmdString);
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SetupFiles( void )
|
||||
void UIFAKKLoadGameClass::SaveGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
Cbuf_ExecuteText(EXEC_NOW, "savegame");
|
||||
}
|
||||
|
||||
void UI_SetupFiles( void ) {
|
||||
// FIXME: stub
|
||||
qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
switch (key) {
|
||||
case K_DEL:
|
||||
RemoveGame(NULL);
|
||||
return qtrue;
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
LoadGame(NULL);
|
||||
return qtrue;
|
||||
case K_UPARROW:
|
||||
if (getCurrentItem() > 1) {
|
||||
TrySelectItem(getCurrentItem() - 1);
|
||||
SelectGame(NULL);
|
||||
return qtrue;
|
||||
}
|
||||
break;
|
||||
case K_DOWNARROW:
|
||||
if (getCurrentItem() < getNumItems()) {
|
||||
TrySelectItem(getCurrentItem() + 1);
|
||||
SelectGame(NULL);
|
||||
return qtrue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return UIListBase::KeyEvent(key, time);
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void UI_SetupFiles(void)
|
||||
{
|
||||
if (loadgame_ui && loadgame_ui->getShow()) {
|
||||
loadgame_ui->SetupFiles();
|
||||
}
|
||||
}
|
||||
|
||||
FAKKLoadGameItem::FAKKLoadGameItem(
|
||||
const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName
|
||||
)
|
||||
{
|
||||
strings[0] = missionName;
|
||||
strings[1] = elapsedTime;
|
||||
strings[2] = dateTime;
|
||||
strings[3] = fileName;
|
||||
}
|
||||
|
||||
int FAKKLoadGameItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(strings[which]);
|
||||
}
|
||||
|
||||
griditemtype_t FAKKLoadGameItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str FAKKLoadGameItem::getListItemString(int which) const
|
||||
{
|
||||
str itemstring;
|
||||
|
||||
switch (which) {
|
||||
case 0:
|
||||
case 3:
|
||||
itemstring = strings[which];
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
int numseconds;
|
||||
int numseconds_hours;
|
||||
|
||||
// hours
|
||||
numseconds = atol(strings[1]);
|
||||
itemstring += (numseconds / 3600);
|
||||
itemstring += ":";
|
||||
|
||||
// minutes
|
||||
numseconds_hours = numseconds % 3600;
|
||||
if (numseconds_hours / 60 <= 9) {
|
||||
itemstring += "0";
|
||||
}
|
||||
itemstring += (numseconds_hours / 60);
|
||||
itemstring += ":";
|
||||
|
||||
// seconds
|
||||
if (numseconds_hours / 60 <= 9) {
|
||||
itemstring += "0";
|
||||
}
|
||||
itemstring += (numseconds_hours % 60);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
time_t time;
|
||||
char buffer[2048];
|
||||
|
||||
time = atol(strings[2]);
|
||||
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", localtime(&time));
|
||||
itemstring = buffer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return itemstring;
|
||||
}
|
||||
|
||||
void FAKKLoadGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean FAKKLoadGameItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
+18
-15
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,23 +22,26 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#pragma once
|
||||
|
||||
class UIFAKKLoadGameClass : public UIListCtrl {
|
||||
bool m_bRemovePending;
|
||||
class UIFAKKLoadGameClass : public UIListCtrl
|
||||
{
|
||||
bool m_bRemovePending;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFAKKLoadGameClass );
|
||||
CLASS_PROTOTYPE(UIFAKKLoadGameClass);
|
||||
|
||||
protected:
|
||||
void SelectGame( Event *ev );
|
||||
void LoadGame( Event *ev );
|
||||
void SaveGame( Event *ev );
|
||||
void RemoveGame( Event *ev );
|
||||
void DeleteGame( Event *ev );
|
||||
void NoDeleteGame( Event *ev );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void UpdateUIElement( void ) override;
|
||||
public:
|
||||
UIFAKKLoadGameClass();
|
||||
void SelectGame(Event *ev);
|
||||
void LoadGame(Event *ev);
|
||||
void SaveGame(Event *ev);
|
||||
void RemoveGame(Event *ev);
|
||||
void DeleteGame(Event *ev);
|
||||
void NoDeleteGame(Event *ev);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void UpdateUIElement(void) override;
|
||||
|
||||
void SetupFiles( void );
|
||||
public:
|
||||
UIFAKKLoadGameClass();
|
||||
~UIFAKKLoadGameClass();
|
||||
|
||||
void SetupFiles(void);
|
||||
};
|
||||
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "cl_uimaprotationsetup.h"
|
||||
|
||||
Event EV_MapListBox_RefreshMapList
|
||||
(
|
||||
"RefreshMapList",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Refreshes the map list."
|
||||
);
|
||||
|
||||
Event EV_MapRotationListBox_RefreshRotationList
|
||||
(
|
||||
"RefreshRotationList",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Refreshed the map rotation list."
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(UIListBox, UIMapRotationListBox, NULL) {
|
||||
{&EV_MapRotationListBox_RefreshRotationList, &UIMapRotationListBox::RefreshRotationList},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIMapRotationListBox::UIMapRotationListBox() {}
|
||||
|
||||
void UIMapRotationListBox::RefreshRotationList(Event *ev)
|
||||
{
|
||||
DeleteAllItems();
|
||||
PopulateRotationList();
|
||||
}
|
||||
|
||||
void UIMapRotationListBox::PopulateRotationList()
|
||||
{
|
||||
cvar_t *filter;
|
||||
cvar_t *maplistVar;
|
||||
const char *token;
|
||||
char mapBuffer[1024];
|
||||
|
||||
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
|
||||
if (!Q_stricmp(filter->string, "obj")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_obj", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "tow")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_tow", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "lib")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_lib", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "team")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_team", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "round")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_round", "", 0);
|
||||
} else {
|
||||
maplistVar = Cvar_Get("ui_maplist_ffa", "", 0);
|
||||
}
|
||||
|
||||
strcpy(mapBuffer, maplistVar->string);
|
||||
|
||||
for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) {
|
||||
if (!Q_stricmp(token, "dm")) {
|
||||
continue;
|
||||
}
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
continue;
|
||||
}
|
||||
if (!Q_stricmp(token, "lib")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddItem(token, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIListBox, UIMapListBox, NULL) {
|
||||
{&EV_MapListBox_RefreshMapList, &UIMapListBox::RefreshMapList},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIMapListBox::UIMapListBox() {}
|
||||
|
||||
void UIMapListBox::RefreshMapList(Event *ev)
|
||||
{
|
||||
DeleteAllItems();
|
||||
PopulateMapList();
|
||||
}
|
||||
|
||||
void UIMapListBox::PopulateMapList()
|
||||
{
|
||||
cvar_t *filter;
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
str path;
|
||||
int i;
|
||||
bool bTugOfWar = false;
|
||||
bool bObjective = false;
|
||||
bool bLiberation = false;
|
||||
|
||||
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
|
||||
if (!Q_stricmp(filter->string, "lib")) {
|
||||
path = "maps/lib/";
|
||||
bLiberation = true;
|
||||
} else if (!Q_stricmp(filter->string, "obj") || !Q_stricmp(filter->string, "tow")) {
|
||||
path = "maps/obj/";
|
||||
if (!Q_stricmp(filter->string, "tow")) {
|
||||
bTugOfWar = true;
|
||||
} else {
|
||||
bObjective = true;
|
||||
}
|
||||
} else {
|
||||
path = "maps/dm/";
|
||||
}
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
const char *token;
|
||||
char mapName[256];
|
||||
char tokenized[256];
|
||||
bool bHasMP = false;
|
||||
bool bHasTOW = false;
|
||||
bool bHasLib = false;
|
||||
|
||||
strcpy(mapName, filename);
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bTugOfWar || bLiberation) {
|
||||
strcpy(tokenized, mapName);
|
||||
|
||||
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (bLiberation) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "LIB")) {
|
||||
bHasLib = true;
|
||||
}
|
||||
if (bHasMP && bHasLib) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bTugOfWar) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
}
|
||||
if (bHasMP && bHasTOW) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bObjective) {
|
||||
strcpy(tokenized, mapName);
|
||||
|
||||
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Q_stricmp(mapName, "mp_ship_lib")) {
|
||||
AddItem(mapName, NULL);
|
||||
}
|
||||
} else {
|
||||
AddItem(mapName, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (bObjective) {
|
||||
path = "maps/lib/";
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
const char *token;
|
||||
char mapName[256];
|
||||
char tokenized[256];
|
||||
|
||||
strcpy(mapName, filename);
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
strcpy(tokenized, mapName);
|
||||
|
||||
token = strtok(tokenized, "_");
|
||||
if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bTugOfWar && !bObjective && !bLiberation) {
|
||||
int type;
|
||||
|
||||
for (type = 0; type < 2; type++) {
|
||||
if (type == 0) {
|
||||
path = "maps/obj/";
|
||||
} else {
|
||||
path = "maps/lib/";
|
||||
}
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
char mapName[256];
|
||||
|
||||
strcpy(mapName, filename);
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(mapName, "obj_team2") || !Q_stricmp(mapName, "obj_team4")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddItem(mapName, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIAddToRotationButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIAddToRotationButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIAddToRotationButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *mapList;
|
||||
UIListBox *rotationList;
|
||||
size_t prefixLength;
|
||||
int i;
|
||||
|
||||
mapList = static_cast<UIListBox *>(uWinMan.FindWidget("Map List"));
|
||||
rotationList = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
|
||||
if (Cvar_Get("g_maprotation_filter", "ffa", 0)) {
|
||||
prefixLength = strlen("obj/") + 1;
|
||||
} else {
|
||||
prefixLength = 1;
|
||||
}
|
||||
|
||||
if (mapList && rotationList) {
|
||||
size_t mapLength = 0;
|
||||
int item = mapList->getCurrentItem();
|
||||
|
||||
for (i = 1; i <= rotationList->getNumItems(); i++) {
|
||||
str text = rotationList->getItemText(i);
|
||||
|
||||
mapLength += text.length();
|
||||
}
|
||||
|
||||
if (item) {
|
||||
str text = mapList->getItemText(item);
|
||||
|
||||
if (prefixLength + mapLength + text.length() < 256) {
|
||||
rotationList->AddItem(text, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRemoveFromRotationButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRemoveFromRotationButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRemoveFromRotationButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
if (list) {
|
||||
list->DeleteItem(list->getCurrentItem());
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRotationApplyButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRotationApplyButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRotationApplyButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
cvar_t *filter;
|
||||
str cvarName;
|
||||
str maplistStr;
|
||||
int i;
|
||||
bool bObjective = false;
|
||||
bool bLiberation = false;
|
||||
|
||||
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
|
||||
if (!Q_stricmp(filter->string, "obj")) {
|
||||
cvarName = "ui_maplist_obj";
|
||||
bObjective = true;
|
||||
} else if (!Q_stricmp(filter->string, "tow")) {
|
||||
cvarName = "ui_maplist_obj";
|
||||
bObjective = true;
|
||||
} else if (!Q_stricmp(filter->string, "lib")) {
|
||||
cvarName = "ui_maplist_lib";
|
||||
bLiberation = true;
|
||||
} else if (!Q_stricmp(filter->string, "team")) {
|
||||
cvarName = "ui_maplist_team";
|
||||
} else if (!Q_stricmp(filter->string, "round")) {
|
||||
cvarName = "ui_maplist_round";
|
||||
} else {
|
||||
cvarName = "ui_maplist_ffa";
|
||||
}
|
||||
Cvar_Set(cvarName, "");
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
if (list) {
|
||||
for (i = 1; i <= list->getNumItems(); i++) {
|
||||
const char *token;
|
||||
str text = list->getItemText(i);
|
||||
char map[256];
|
||||
bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false;
|
||||
|
||||
strcpy(map, text);
|
||||
for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
break;
|
||||
}
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
bHasObj = true;
|
||||
break;
|
||||
}
|
||||
if (!Q_stricmp(token, "lib")) {
|
||||
bHasLib = true;
|
||||
break;
|
||||
}
|
||||
if (!Q_stricmp(token, "ship")) {
|
||||
bHasShip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bHasShip) {
|
||||
maplistStr += "lib/";
|
||||
} else if (bObjective || bHasTOW || bHasObj) {
|
||||
maplistStr += "obj/";
|
||||
} else if (bHasLib || bLiberation) {
|
||||
maplistStr += "lib/";
|
||||
} else {
|
||||
maplistStr += "dm/";
|
||||
}
|
||||
|
||||
maplistStr += text;
|
||||
maplistStr += " ";
|
||||
|
||||
if (i == 1) {
|
||||
Cvar_Set("ui_dmmap", maplistStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cvar_Set(cvarName, maplistStr);
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRotationMoveItemUpButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRotationMoveItemUpButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRotationMoveItemUpButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
int item;
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
item = list->getCurrentItem();
|
||||
|
||||
if (item < list->getNumItems() && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item + 1);
|
||||
|
||||
list->DeleteItem(list->getCurrentItem() - 1);
|
||||
list->InsertItem(text, item);
|
||||
list->setCurrentItem(item - 1);
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRotationMoveItemDownButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRotationMoveItemDownButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRotationMoveItemDownButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
int item;
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
item = list->getCurrentItem();
|
||||
|
||||
if (item < list->getNumItems() && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item + 1);
|
||||
|
||||
list->DeleteItem(list->getCurrentItem() + 1);
|
||||
list->InsertItem(text, item);
|
||||
list->setCurrentItem(item + 1);
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../uilib/uilistbox.h"
|
||||
|
||||
class UIMapRotationListBox : public UIListBox
|
||||
{
|
||||
CLASS_PROTOTYPE(UIMapRotationListBox);
|
||||
|
||||
public:
|
||||
UIMapRotationListBox();
|
||||
|
||||
void RefreshRotationList(Event *ev);
|
||||
void PopulateRotationList();
|
||||
};
|
||||
|
||||
class UIMapListBox : public UIListBox
|
||||
{
|
||||
CLASS_PROTOTYPE(UIMapListBox);
|
||||
|
||||
public:
|
||||
UIMapListBox();
|
||||
|
||||
void RefreshMapList(Event *ev);
|
||||
void PopulateMapList();
|
||||
};
|
||||
|
||||
class UIAddToRotationButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIAddToRotationButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRemoveFromRotationButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRemoveFromRotationButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRotationApplyButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRotationApplyButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRotationMoveItemUpButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRotationMoveItemUpButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRotationMoveItemDownButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRotationMoveItemDownButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,47 +22,107 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, MapRunnerClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, MapRunnerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void MapRunnerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void MapRunnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
str newName;
|
||||
|
||||
newName = "spmap " + str(fullname, 5, fullname.length() - 4) + "\n";
|
||||
// insert the command
|
||||
Cbuf_AddText(newName);
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, ViewSpawnerClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, UIPickFileClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void ViewSpawnerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
UIPickFileClass::UIPickFileClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
retobj = NULL;
|
||||
retevent = NULL;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, LODSpawnerClass, NULL )
|
||||
UIPickFileClass::~UIPickFileClass()
|
||||
{
|
||||
{ NULL, NULL }
|
||||
if (retevent) {
|
||||
delete retevent;
|
||||
}
|
||||
}
|
||||
|
||||
void UIPickFileClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
if (!retobj || !retevent) {
|
||||
CloseWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
retevent->AddString(fullname);
|
||||
retobj->ProcessEvent(retevent);
|
||||
|
||||
retevent = NULL;
|
||||
retobj = NULL;
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void PickFile(const char *name, Listener *obj, Event& event)
|
||||
{
|
||||
UIPickFileClass *picker;
|
||||
str currentpath;
|
||||
int i;
|
||||
|
||||
picker = new UIPickFileClass();
|
||||
picker->retevent = new Event(event);
|
||||
picker->retobj = obj;
|
||||
|
||||
if (name && *name && strchr(name, '/')) {
|
||||
currentpath = name;
|
||||
|
||||
for (i = currentpath.length(); i > 0; i--) {
|
||||
if (currentpath[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentpath = str(currentpath, 0, i + 1);
|
||||
} else {
|
||||
currentpath = "";
|
||||
}
|
||||
|
||||
picker->Setup("", currentpath, ".*", "");
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void LODSpawnerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void ViewSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
str newName;
|
||||
|
||||
newName = "viewspawn " + fullname + "\n";
|
||||
// insert the command
|
||||
Cbuf_AddText(newName);
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, UIPickFileClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, LODSpawnerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void UIPickFileClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void LODSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
str newName;
|
||||
|
||||
void PickFile( const char *name, Listener *obj, Event& event )
|
||||
{
|
||||
// FIXME: stub
|
||||
newName = "lod_spawn " + fullname + "\n";
|
||||
// insert the command
|
||||
Cbuf_AddText(newName);
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,40 +20,44 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIMAPRUNNER_H__
|
||||
#define __CL_UIMAPRUNNER_H__
|
||||
#pragma once
|
||||
|
||||
class MapRunnerClass : public FilePickerClass {
|
||||
class MapRunnerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( MapRunnerClass );
|
||||
CLASS_PROTOTYPE(MapRunnerClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
class ViewSpawnerClass : public FilePickerClass {
|
||||
class ViewSpawnerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( ViewSpawnerClass );
|
||||
CLASS_PROTOTYPE(ViewSpawnerClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
class LODSpawnerClass : public FilePickerClass {
|
||||
class LODSpawnerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( LODSpawnerClass );
|
||||
CLASS_PROTOTYPE(LODSpawnerClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
class UIPickFileClass : public FilePickerClass {
|
||||
class UIPickFileClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
Listener *retobj;
|
||||
Event *retevent;
|
||||
Listener *retobj;
|
||||
Event *retevent;
|
||||
|
||||
CLASS_PROTOTYPE( UIPickFileClass );
|
||||
CLASS_PROTOTYPE(UIPickFileClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
UIPickFileClass();
|
||||
~UIPickFileClass();
|
||||
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
void PickFile( const char *name, Listener *obj, Event& event );
|
||||
|
||||
#endif /* __CL_UIMAPRUNNER_H__ */
|
||||
void PickFile(const char *name, Listener *obj, Event& event);
|
||||
+138
-27
@@ -22,68 +22,179 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( UIWidget, FakkMiniconsole, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
Event EV_Minicon_Goin("_minicon_goin", EV_DEFAULT, NULL, NULL, "Event to make the miniconsole disappear");
|
||||
|
||||
CLASS_DECLARATION(UIWidget, FakkMiniconsole, NULL) {
|
||||
{&W_SizeChanged, &FakkMiniconsole::OnSizeChanged},
|
||||
{&EV_Minicon_Goin, &FakkMiniconsole::MoveInEvent },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
FakkMiniconsole::FakkMiniconsole()
|
||||
{
|
||||
// FIXME: stub
|
||||
m_maxlines = 0;
|
||||
m_reallyshown = true;
|
||||
m_boxstate = boxstate_t::box_in;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
}
|
||||
|
||||
|
||||
void FakkMiniconsole::VerifyBoxOut( void )
|
||||
void FakkMiniconsole::setShowState(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_reallyshown) {
|
||||
setShow(m_boxstate != boxstate_t::box_in);
|
||||
} else {
|
||||
setShow(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FakkMiniconsole::ChangeBoxState( boxstate_t state )
|
||||
void FakkMiniconsole::setRealShow(bool b)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_reallyshown = b;
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void FakkMiniconsole::HandleBoxMoving( void )
|
||||
void FakkMiniconsole::VerifyBoxOut(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostMoveinEvent();
|
||||
|
||||
if (m_boxstate && m_boxstate != boxstate_t::box_out) {
|
||||
ChangeBoxState(box_moving_out);
|
||||
}
|
||||
}
|
||||
|
||||
void FakkMiniconsole::PostMoveinEvent( void )
|
||||
void FakkMiniconsole::Print(const char *text)
|
||||
{
|
||||
// FIXME: stub
|
||||
str *lastline;
|
||||
const char *p;
|
||||
|
||||
if (!m_lines.NumObjects()) {
|
||||
m_lines.AddObject({});
|
||||
}
|
||||
|
||||
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
|
||||
|
||||
if (*text) {
|
||||
for (p = text; *p; p++) {
|
||||
if (*p != '\n') {
|
||||
*lastline += *p;
|
||||
} else {
|
||||
m_lines.AddObject({});
|
||||
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastline && lastline->length() > 128) {
|
||||
Print("\n");
|
||||
}
|
||||
|
||||
if (m_maxlines < 0) {
|
||||
m_maxlines = 1;
|
||||
}
|
||||
|
||||
while (m_lines.NumObjects() > this->m_maxlines) {
|
||||
m_lines.RemoveObjectAt(1);
|
||||
}
|
||||
|
||||
VerifyBoxOut();
|
||||
}
|
||||
|
||||
void FakkMiniconsole::setShowState( void )
|
||||
void FakkMiniconsole::PostMoveinEvent(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_boxstate != boxstate_t::box_out) {
|
||||
return;
|
||||
}
|
||||
|
||||
CancelEventsOfType(EV_Minicon_Goin);
|
||||
PostEvent(new Event(EV_Minicon_Goin), 5.f);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::OnSizeChanged( Event *ev )
|
||||
void FakkMiniconsole::OnSizeChanged(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_maxlines = m_frame.size.height / m_font->getHeight(false);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::Print( const char *text )
|
||||
void FakkMiniconsole::MoveInEvent(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
ChangeBoxState(boxstate_t::box_moving_in);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha )
|
||||
void FakkMiniconsole::HandleBoxMoving(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int delta;
|
||||
UIRect2D newRect;
|
||||
|
||||
if (m_boxstate == boxstate_t::box_out || m_boxstate == boxstate_t::box_in) {
|
||||
return;
|
||||
}
|
||||
|
||||
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
|
||||
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
|
||||
|
||||
switch (m_boxstate) {
|
||||
case boxstate_t::box_moving_in:
|
||||
newRect = UIRect2D(delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
|
||||
if (newRect.pos.x >= uid.vidWidth) {
|
||||
newRect.pos.x = uid.vidWidth;
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
}
|
||||
break;
|
||||
case boxstate_t::box_moving_out:
|
||||
newRect = UIRect2D(-delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
|
||||
if (newRect.pos.x <= uid.vidWidth - newRect.size.width) {
|
||||
newRect.pos.x = uid.vidWidth - newRect.size.width;
|
||||
ChangeBoxState(boxstate_t::box_out);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
break;
|
||||
}
|
||||
|
||||
setFrame(newRect);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::MoveInEvent( Event *ev )
|
||||
void FakkMiniconsole::Draw(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float aty;
|
||||
int i;
|
||||
|
||||
HandleBoxMoving();
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
aty = m_frame.size.height - m_font->getHeight(false);
|
||||
for (i = m_lines.NumObjects(); i > 0; i--) {
|
||||
if (-m_font->getHeight(false) >= aty) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_font->Print(0, aty, m_lines.ObjectAt(i), -1, false);
|
||||
aty -= m_font->getHeight(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FakkMiniconsole::Draw( void )
|
||||
void FakkMiniconsole::Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha)
|
||||
{
|
||||
// FIXME: stub
|
||||
InitFrame(NULL, uid.vidWidth, 0, size.width, size.height, 0);
|
||||
|
||||
setBackgroundColor(back, true);
|
||||
setForegroundColor(fore);
|
||||
setBackgroundAlpha(alpha);
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
OnSizeChanged(NULL);
|
||||
|
||||
m_movespeed = size.width * 3;
|
||||
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void FakkMiniconsole::setRealShow( bool b )
|
||||
void FakkMiniconsole::ChangeBoxState(boxstate_t state)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_boxstate = state;
|
||||
m_boxtime = uid.time;
|
||||
setShowState();
|
||||
if (state == boxstate_t::box_out) {
|
||||
PostMoveinEvent();
|
||||
}
|
||||
}
|
||||
+23
-25
@@ -20,38 +20,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIMINICON_H__
|
||||
#define __CL_UIMINICON_H__
|
||||
#pragma once
|
||||
|
||||
class FakkMiniconsole : public UIWidget {
|
||||
class FakkMiniconsole : public UIWidget
|
||||
{
|
||||
protected:
|
||||
Container<str> m_lines;
|
||||
int m_maxlines;
|
||||
bool m_reallyshown;
|
||||
bool m_boxmovingout;
|
||||
boxstate_t m_boxstate;
|
||||
int m_boxtime;
|
||||
int m_movespeed;
|
||||
Container<str> m_lines;
|
||||
int m_maxlines;
|
||||
bool m_reallyshown;
|
||||
bool m_boxmovingout;
|
||||
boxstate_t m_boxstate;
|
||||
int m_boxtime;
|
||||
int m_movespeed;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FakkMiniconsole );
|
||||
CLASS_PROTOTYPE(FakkMiniconsole);
|
||||
|
||||
protected:
|
||||
void VerifyBoxOut( void );
|
||||
void ChangeBoxState( boxstate_t state );
|
||||
void HandleBoxMoving( void );
|
||||
void PostMoveinEvent( void );
|
||||
void setShowState( void );
|
||||
void VerifyBoxOut(void);
|
||||
void ChangeBoxState(boxstate_t state);
|
||||
void HandleBoxMoving(void);
|
||||
void PostMoveinEvent(void);
|
||||
void setShowState(void);
|
||||
|
||||
public:
|
||||
FakkMiniconsole();
|
||||
FakkMiniconsole();
|
||||
|
||||
void OnSizeChanged( Event *ev );
|
||||
void Print( const char *text );
|
||||
void Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha );
|
||||
void MoveInEvent( Event *ev );
|
||||
void Draw( void ) override;
|
||||
void setRealShow( bool b );
|
||||
void OnSizeChanged(Event *ev);
|
||||
void Print(const char *text);
|
||||
void Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha);
|
||||
void MoveInEvent(Event *ev);
|
||||
void Draw(void) override;
|
||||
void setRealShow(bool b);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -21,73 +21,339 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( USignal, MpMapPickerClass, NULL )
|
||||
class MpMapPickerItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str m_string;
|
||||
// Added in 2.0
|
||||
str m_directory;
|
||||
|
||||
public:
|
||||
MpMapPickerItem(const str& string, const str& directory);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
CLASS_DECLARATION(USignal, MpMapPickerClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &MpMapPickerClass::FileSelected },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &MpMapPickerClass::FileChosen },
|
||||
{&W_Deactivated, &MpMapPickerClass::OnDeactivated},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
MpMapPickerClass::MpMapPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 300) / 2, (cls.glconfig.vidHeight - 200) / 2, 300, 200),
|
||||
"Select a Map",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
);
|
||||
window->setFont("facfont-20");
|
||||
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
|
||||
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
|
||||
window->Connect(this, W_Deactivated, W_Deactivated);
|
||||
|
||||
listbox = new UIListCtrl();
|
||||
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
|
||||
listbox->SetDrawHeader(false);
|
||||
listbox->setFont("facfont-20");
|
||||
listbox->FrameInitialized();
|
||||
listbox->AddColumn(Sys_LV_CL_ConvertString("Select a Map"), 0, 400, false, false);
|
||||
|
||||
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
listbox->AllowActivate(true);
|
||||
|
||||
// Added in 2.0
|
||||
// Don't localize elements
|
||||
listbox->SetDontLocalize();
|
||||
}
|
||||
|
||||
MpMapPickerClass::~MpMapPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
if (listbox) {
|
||||
delete listbox;
|
||||
listbox = NULL;
|
||||
}
|
||||
|
||||
if (window) {
|
||||
delete window;
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MpMapPickerClass::SetupFiles( void )
|
||||
void MpMapPickerClass::Setup(const char *root_directory, const char *current_directory, const char *game_type)
|
||||
{
|
||||
// FIXME: stub
|
||||
Initialize(root_directory, current_directory, game_type);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::GotoParentDirectory( void )
|
||||
void MpMapPickerClass::Initialize(const char *root_directory, const char *current_directory, const char *game_type)
|
||||
{
|
||||
// FIXME: stub
|
||||
rootDirectory = root_directory;
|
||||
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
|
||||
rootDirectory += "/";
|
||||
}
|
||||
|
||||
currentDirectory = current_directory;
|
||||
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
if (game_type) {
|
||||
gameType = game_type;
|
||||
}
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::GotoSubDirectory( str subdir )
|
||||
void MpMapPickerClass::GotoParentDirectory(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
uintptr_t i;
|
||||
|
||||
if (currentDirectory == rootDirectory) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = currentDirectory.length() - 2; i > 0; i--) {
|
||||
if (currentDirectory[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentDirectory[i] == '/') {
|
||||
i++;
|
||||
}
|
||||
|
||||
currentDirectory = str(currentDirectory, 0, i);
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::Initialize( const char *root_directory, const char *current_directory )
|
||||
void MpMapPickerClass::GotoSubDirectory(str subdir)
|
||||
{
|
||||
// FIXME: stub
|
||||
currentDirectory += subdir + "/";
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::CloseWindow( void )
|
||||
void MpMapPickerClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
char mapname[128];
|
||||
bool bTugOfWar = false, bObjective = false, bLiberation = false;
|
||||
|
||||
listbox->DeleteAllItems();
|
||||
|
||||
if (gameType == "tow") {
|
||||
bTugOfWar = true;
|
||||
} else if (gameType == "obj") {
|
||||
bObjective = true;
|
||||
} else if (gameType == "lib") {
|
||||
bLiberation = true;
|
||||
} else {
|
||||
// retrieve directories
|
||||
filenames = FS_ListFiles(rootDirectory, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
|
||||
strcpy(mapname, filename);
|
||||
mapname[strlen(mapname) - 4] = 0;
|
||||
|
||||
if (COM_IsMapValid(mapname)) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, rootDirectory));
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
}
|
||||
|
||||
if (com_target_game->integer > target_game_e::TG_MOH) {
|
||||
if (currentDirectory.length()) {
|
||||
if (currentDirectory == "maps/-/") {
|
||||
SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation);
|
||||
} else {
|
||||
SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation);
|
||||
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listbox->SortByColumn(0);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileSelected( Event *ev )
|
||||
void MpMapPickerClass::SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation)
|
||||
{
|
||||
// FIXME: stub
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
char mapname[128];
|
||||
char string[1024];
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
const char *token;
|
||||
|
||||
strcpy(mapname, filename);
|
||||
mapname[strlen(mapname) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapname)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bTugOfWar || bObjective || bLiberation) {
|
||||
bool bHasMP = false, bHasTOW = false, bHasLib = false;
|
||||
|
||||
strcpy(string, mapname);
|
||||
|
||||
for (token = strtok(string, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (bObjective) {
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
} else if (!Q_stricmp(token, "ship")) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
|
||||
if (bTugOfWar) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
}
|
||||
|
||||
if (bHasMP && bHasTOW) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
|
||||
if (bLiberation) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "LIB")) {
|
||||
bHasLib = true;
|
||||
}
|
||||
|
||||
if (bHasMP && bHasLib) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!Q_stricmp(mapname, "obj_team2") || !Q_stricmp(mapname, "obj_team4")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
|
||||
void MpMapPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
FileChosen(currentDirectory, partialName, fullname);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileChosen( Event *ev )
|
||||
void MpMapPickerClass::FileSelected(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (!listbox->getCurrentItem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uii.Snd_PlaySound("sound/menu/apply.wav");
|
||||
|
||||
UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
|
||||
str name = item->getListItemString(0);
|
||||
str directory = item->getListItemString(1);
|
||||
|
||||
FileSelected(directory, name, directory + name);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
|
||||
void MpMapPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
const char *pszFilename;
|
||||
str sCommand;
|
||||
|
||||
pszFilename = fullname.c_str();
|
||||
sCommand = va("ui_dmmap %s\n", pszFilename + 5);
|
||||
|
||||
Cbuf_AddText(sCommand);
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::OnDeactivated( Event *ev )
|
||||
void MpMapPickerClass::FileChosen(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (!listbox->getCurrentItem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uii.Snd_PlaySound("sound/menu/apply.wav");
|
||||
|
||||
UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
|
||||
str name = item->getListItemString(0);
|
||||
str directory = item->getListItemString(1);
|
||||
|
||||
FileSelected(directory, name, directory + name);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::Setup( const char *root_directory, const char *current_directory )
|
||||
void MpMapPickerClass::CloseWindow(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::OnDeactivated(Event *ev)
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
MpMapPickerItem::MpMapPickerItem(const str& string, const str& directory)
|
||||
{
|
||||
m_string = string;
|
||||
m_directory = directory;
|
||||
}
|
||||
|
||||
int MpMapPickerItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(m_string);
|
||||
}
|
||||
|
||||
griditemtype_t MpMapPickerItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str MpMapPickerItem::getListItemString(int which) const
|
||||
{
|
||||
switch (which) {
|
||||
default:
|
||||
case 0:
|
||||
return m_string;
|
||||
case 1:
|
||||
return m_directory;
|
||||
}
|
||||
}
|
||||
|
||||
void MpMapPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean MpMapPickerItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,39 +20,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIMPMAPPICKER_H__
|
||||
#define __CL_UIMPMAPPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class UIFloatingWindow;
|
||||
|
||||
class MpMapPickerClass : public USignal {
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
class MpMapPickerClass : public USignal
|
||||
{
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
str gameType;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( MpMapPickerClass );
|
||||
CLASS_PROTOTYPE(MpMapPickerClass);
|
||||
|
||||
private:
|
||||
void SetupFiles( void );
|
||||
void GotoParentDirectory( void );
|
||||
void GotoSubDirectory( str subdir );
|
||||
void Initialize( const char *root_directory, const char *current_directory );
|
||||
void SetupFiles(void);
|
||||
void SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation);
|
||||
void GotoParentDirectory(void);
|
||||
void GotoSubDirectory(str subdir);
|
||||
void Initialize(const char *root_directory, const char *current_directory, const char *game_type);
|
||||
|
||||
protected:
|
||||
void CloseWindow( void );
|
||||
void FileSelected( Event *ev );
|
||||
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
|
||||
void FileChosen( Event *ev );
|
||||
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
|
||||
void OnDeactivated( Event *ev );
|
||||
void CloseWindow(void);
|
||||
void FileSelected(Event *ev);
|
||||
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void FileChosen(Event *ev);
|
||||
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void OnDeactivated(Event *ev);
|
||||
|
||||
public:
|
||||
MpMapPickerClass();
|
||||
~MpMapPickerClass();
|
||||
MpMapPickerClass();
|
||||
~MpMapPickerClass();
|
||||
|
||||
void Setup( const char *root_directory, const char *current_directory );
|
||||
// game_type was added in 2.0
|
||||
void Setup(const char *root_directory, const char *current_directory, const char *game_type = NULL);
|
||||
};
|
||||
|
||||
#endif /* __CL_UIMPMAPPICKER_H__ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,62 +22,361 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( USignal, PlayerModelPickerClass, NULL )
|
||||
class PMPickerItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str m_string;
|
||||
|
||||
public:
|
||||
PMPickerItem(const str& string);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *fileName;
|
||||
const char *displayName;
|
||||
} PMPickerModel_t;
|
||||
|
||||
static const PMPickerModel_t pickerModels[] = {
|
||||
// 2.0 skins
|
||||
{"allied_101st_captain", "US - 101st Airborne Captain" },
|
||||
{"allied_101st_infantry", "US - 101st Airborne Private 1" },
|
||||
{"allied_101st_scout", "US - 101st Airborne Private 2" },
|
||||
{"allied_501st_pir_scout", "US - 501st Paratrooper 1" },
|
||||
{"allied_501st_pir_soldier", "US - 501st Paratrooper 2" },
|
||||
// 1.0 skins
|
||||
{"allied_airborne", "US - 501st Paratrooper 3" },
|
||||
// Readded in OPM (was removed in 2.0)
|
||||
{"allied_manon", "US - Manon" },
|
||||
// 2.0 skins
|
||||
{"allied_british_6th_airborne_captain", "UK - 6th Airborne Captain" },
|
||||
{"allied_british_6th_airborne_paratrooper", "UK - 6th Airborne Paratrooper" },
|
||||
// 1.0 skins
|
||||
{"allied_pilot", "US - Army Pilot" },
|
||||
// 2.0 skins
|
||||
{"allied_russian_corporal", "RA - Corporal" },
|
||||
{"allied_russian_crazy_boris", "RA - Crazy Boris" },
|
||||
{"allied_russian_recon_scout", "RA - Junior Lieutenant" },
|
||||
{"allied_russian_recon_soldier", "RA - Black Sea Petty Officer" },
|
||||
// 1.0 skins
|
||||
{"allied_sas", "UK - SAS Officer" },
|
||||
{"american_army", "US - Soldier" },
|
||||
{"american_ranger", "US - Ranger" },
|
||||
// 1.0 skins
|
||||
{"german_afrika_officer", "DE - Afrika Officer" },
|
||||
{"german_afrika_private", "DE - Afrika Private" },
|
||||
// 2.0 skins
|
||||
{"german_ardennes_artillery_commander", "DE - Artillery Commander" },
|
||||
{"german_dday_colonel", "DE - Normandy Colonel" },
|
||||
// 1.0 skins
|
||||
{"german_elite_officer", "DE - Elite Officer" },
|
||||
{"german_elite_sentry", "DE - Elite Sentry" },
|
||||
{"german_kradshutzen", "DE - Kradshutzen" },
|
||||
{"german_panzer_grenadier", "DE - Panzer Grenadier" },
|
||||
{"german_panzer_obershutze", "DE - Panzer Obershutze" },
|
||||
{"german_panzer_shutze", "DE - Panzer Shutze" },
|
||||
{"german_panzer_tankcommander", "DE - Panzer Tank Commander" },
|
||||
{"german_scientist", "DE - German Scientist" },
|
||||
// Those skins were superseded by german_waffenss
|
||||
{"german_waffen_officer", "DE - Waffen Officer" },
|
||||
{"german_waffen_shutze", "DE - Waffen Shutze" },
|
||||
// 1.0 skins
|
||||
{"german_waffenss_officer", "DE - Waffen Officer" },
|
||||
{"german_waffenss_shutze", "DE - Waffen Shutze" },
|
||||
{"german_wehrmacht_officer", "DE - Wehrmacht Officer" },
|
||||
{"german_wehrmacht_soldier", "DE - Wehrmacht Soldier" },
|
||||
{"german_winter_1", "DE - Winter Infantry 1" },
|
||||
{"german_winter_2", "DE - Winter Infantry 2" },
|
||||
{"german_worker", "DE - German Mechanic" },
|
||||
// 2.11 skins
|
||||
{"allied_british_tank_corporal", "UK - 6th Royal Tank Regiment" },
|
||||
{"allied_russian_seaman", "RA - Red Navy Seaman" },
|
||||
{"german_Panzer_Corporal", "DE - 1st Panzer Regiment" },
|
||||
{"allied_technician", "US - Air Force Technician" },
|
||||
{"german_stukageschwader", "DE - Stukageschwader" },
|
||||
// 2.30 skins
|
||||
{"It_AX_Ital_Vol", "IT - 10th Army XXI Corps" },
|
||||
{"SC_AX_Ital_Inf", "IT - 6th Army 202nd Coastal Div"},
|
||||
{"SC_AX_Ital_Inf2", "IT - 114th Inf Regiment" },
|
||||
{"SC_AX_ITAL_PARA", "IT - Paracadutista Militare" },
|
||||
// 2.40 skins
|
||||
{"allied_Wheathers", "US - General Wheathers" },
|
||||
{"allied_US_Tank", "US - II Corps Tank Commander" },
|
||||
{"allied_US_Mask", "US - II Corps Infantry" },
|
||||
{"allied_british_Cmd", "UK - 10th Corps" },
|
||||
{"allied_british_Tank", "UK - 8th Army" },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
const char *PM_FilenameToDisplayname(const char *fileName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; pickerModels[i].fileName; i++) {
|
||||
const PMPickerModel_t& model = pickerModels[i];
|
||||
|
||||
if (!Q_stricmp(model.fileName, fileName)) {
|
||||
return model.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
const char *PM_DisplaynameToFilename(const char *displayName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; pickerModels[i].fileName; i++) {
|
||||
const PMPickerModel_t& model = pickerModels[i];
|
||||
|
||||
if (!Q_stricmp(model.displayName, displayName)) {
|
||||
return model.fileName;
|
||||
}
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(USignal, PlayerModelPickerClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &PlayerModelPickerClass::FileSelected },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &PlayerModelPickerClass::FileChosen },
|
||||
{&UIFloatingWindow::W_ClosePressed, &PlayerModelPickerClass::OnDeactivated},
|
||||
{&W_Deactivated, &PlayerModelPickerClass::OnDeactivated},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
PlayerModelPickerClass::PlayerModelPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
|
||||
"Player Model Select...",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
);
|
||||
window->setFont("facfont-20");
|
||||
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
|
||||
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
|
||||
window->Connect(this, W_Deactivated, W_Deactivated);
|
||||
|
||||
listbox = new UIListCtrl();
|
||||
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
|
||||
listbox->SetDrawHeader(false);
|
||||
listbox->setFont("facfont-20");
|
||||
listbox->FrameInitialized();
|
||||
listbox->AddColumn("Player Model", 0, 400, false, false);
|
||||
|
||||
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
listbox->AllowActivate(true);
|
||||
|
||||
// Added in 2.0
|
||||
// Don't localize elements
|
||||
listbox->SetDontLocalize();
|
||||
|
||||
m_bGermanModels = false;
|
||||
}
|
||||
|
||||
PlayerModelPickerClass::~PlayerModelPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
if (listbox) {
|
||||
delete listbox;
|
||||
listbox = NULL;
|
||||
}
|
||||
|
||||
if (window) {
|
||||
delete window;
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::SetupFiles( void )
|
||||
void PlayerModelPickerClass::Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels)
|
||||
{
|
||||
// FIXME: stub
|
||||
Initialize(root_directory, current_directory, bGermanModels);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels )
|
||||
void PlayerModelPickerClass::Initialize(
|
||||
const char *root_directory, const char *current_directory, qboolean bGermanModels
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
rootDirectory = root_directory;
|
||||
m_bGermanModels = bGermanModels;
|
||||
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
|
||||
rootDirectory += "/";
|
||||
}
|
||||
|
||||
currentDirectory = current_directory;
|
||||
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::CloseWindow( void )
|
||||
void PlayerModelPickerClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
str mappath;
|
||||
char work[128];
|
||||
char **filenames;
|
||||
const char *displayName;
|
||||
int numfiles;
|
||||
int i;
|
||||
int iLen;
|
||||
qboolean bIsGerman;
|
||||
|
||||
// cleanup
|
||||
listbox->DeleteAllItems();
|
||||
|
||||
if (m_bGermanModels) {
|
||||
window->setTitle("Select Your Axis Player Model");
|
||||
} else {
|
||||
window->setTitle("Select Your Allied Player Model");
|
||||
}
|
||||
|
||||
filenames = FS_ListFiles(currentDirectory, ".tik", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
Q_strncpyz(work, filenames[i], sizeof(work));
|
||||
|
||||
if (strstr(work, "_fps")) {
|
||||
// ignore view models
|
||||
continue;
|
||||
}
|
||||
|
||||
if (work[0] == '_') {
|
||||
// ignore hidden models
|
||||
continue;
|
||||
}
|
||||
|
||||
// allied_manon readded in OPM
|
||||
//if (!Q_stricmpn(work, "allied_manon")) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
bIsGerman = !Q_stricmpn(work, "german", 6u) || !Q_stricmpn(work, "axis", 4u) || !Q_stricmpn(work, "it", 2u)
|
||||
|| !Q_stricmpn(work, "sc", 2u);
|
||||
|
||||
if (m_bGermanModels != bIsGerman) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// strip the extension
|
||||
work[strlen(work) - 4] = 0;
|
||||
displayName = PM_FilenameToDisplayname(work);
|
||||
|
||||
listbox->AddItem(new PMPickerItem(displayName));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
listbox->SortByColumn(0);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileSelected( Event *ev )
|
||||
void PlayerModelPickerClass::FileSelected(
|
||||
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
FileChosen(name, currentDirectory, partialName, fullname);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
|
||||
void PlayerModelPickerClass::FileSelected(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str name;
|
||||
char donotshowssindeorfr[64];
|
||||
str fullname;
|
||||
|
||||
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
fullname = PM_DisplaynameToFilename(name);
|
||||
|
||||
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
|
||||
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
|
||||
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
|
||||
} else {
|
||||
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
|
||||
}
|
||||
|
||||
FileSelected(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileChosen( Event *ev )
|
||||
void PlayerModelPickerClass::FileChosen(
|
||||
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
str sCommand;
|
||||
|
||||
if (m_bGermanModels) {
|
||||
sCommand += "ui_dm_playergermanmodel \"" + name;
|
||||
sCommand += "\" ; ui_dm_playergermanmodel_set " + partialName;
|
||||
sCommand += " ; ui_disp_playergermanmodel " + fullname + ".tik";
|
||||
} else {
|
||||
sCommand += "ui_dm_playermodel \"" + name;
|
||||
sCommand += "\" ; ui_dm_playermodel_set " + partialName;
|
||||
sCommand += " ; ui_disp_playermodel " + fullname + ".tik";
|
||||
}
|
||||
sCommand += "\n";
|
||||
|
||||
Cbuf_AddText(sCommand);
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
|
||||
void PlayerModelPickerClass::FileChosen(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str name;
|
||||
char donotshowssindeorfr[64];
|
||||
str fullname;
|
||||
|
||||
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
fullname = PM_DisplaynameToFilename(name);
|
||||
|
||||
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
|
||||
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
|
||||
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
|
||||
} else {
|
||||
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
|
||||
}
|
||||
|
||||
FileChosen(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::OnDeactivated( Event *ev )
|
||||
void PlayerModelPickerClass::CloseWindow(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels )
|
||||
void PlayerModelPickerClass::OnDeactivated(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
PMPickerItem::PMPickerItem(const str& string)
|
||||
{
|
||||
m_string = string;
|
||||
}
|
||||
|
||||
int PMPickerItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(m_string);
|
||||
}
|
||||
|
||||
griditemtype_t PMPickerItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str PMPickerItem::getListItemString(int which) const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
void PMPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean PMPickerItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,37 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIPLAYERMODELPICKER_H__
|
||||
#define __CL_UIPLAYERMODELPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class UIFloatingWindow;
|
||||
|
||||
class PlayerModelPickerClass : public USignal {
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
qboolean m_bGermanModels;
|
||||
class PlayerModelPickerClass : public USignal
|
||||
{
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
qboolean m_bGermanModels;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( PlayerModelPickerClass );
|
||||
CLASS_PROTOTYPE(PlayerModelPickerClass);
|
||||
|
||||
private:
|
||||
void SetupFiles( void );
|
||||
void Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels );
|
||||
void SetupFiles(void);
|
||||
void Initialize(const char *root_directory, const char *current_directory, qboolean bGermanModels);
|
||||
|
||||
protected:
|
||||
void CloseWindow( void );
|
||||
void FileSelected( Event *ev );
|
||||
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
|
||||
void FileChosen( Event *ev );
|
||||
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
|
||||
void OnDeactivated( Event *ev );
|
||||
void CloseWindow(void);
|
||||
void FileSelected(Event *ev);
|
||||
// The name parameter was added in 2.0.
|
||||
virtual void FileSelected(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void FileChosen(Event *ev);
|
||||
// The name parameter was added in 2.0.
|
||||
virtual void FileChosen(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void OnDeactivated(Event *ev);
|
||||
|
||||
public:
|
||||
PlayerModelPickerClass();
|
||||
~PlayerModelPickerClass();
|
||||
PlayerModelPickerClass();
|
||||
~PlayerModelPickerClass();
|
||||
|
||||
void Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels );
|
||||
void Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels);
|
||||
};
|
||||
|
||||
#endif /* __CL_UIPLAYERMODELPICKER_H__ */
|
||||
const char* PM_FilenameToDisplayname(const char* fileName);
|
||||
const char* PM_DisplaynameToFilename(const char* displayName);
|
||||
@@ -79,6 +79,7 @@ struct ServerListInstance {
|
||||
};
|
||||
|
||||
class FAKKServerListItem : public UIListCtrlItem {
|
||||
UIFAKKServerList* m_parent; // Added in OPM
|
||||
str m_strings[6];
|
||||
str m_sVersion;
|
||||
bool m_bDifferentVersion;
|
||||
@@ -94,7 +95,7 @@ public:
|
||||
int m_iGameSpyPort;
|
||||
|
||||
public:
|
||||
FAKKServerListItem(str string1, str string2, str string3, str string4, str string5, str string6, str ver);
|
||||
FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver);
|
||||
|
||||
griditemtype_t getListItemType(int index) const override;
|
||||
int getListItemValue(int i) const override;
|
||||
@@ -125,8 +126,9 @@ ServerListInstance g_ServerListInst[2];
|
||||
void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, void* param1, void* param2);
|
||||
static void AddFilter(char* filter, const char* value);
|
||||
|
||||
FAKKServerListItem::FAKKServerListItem(str string1, str string2, str string3, str string4, str string5, str string6, str ver)
|
||||
FAKKServerListItem::FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver)
|
||||
{
|
||||
m_parent = parent;
|
||||
m_strings[0] = string1;
|
||||
m_strings[1] = string2;
|
||||
m_strings[2] = string3;
|
||||
@@ -164,84 +166,95 @@ void FAKKServerListItem::setListItemString(int i, str sNewString)
|
||||
void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont* pFont)
|
||||
{
|
||||
static cvar_t *pColoringType = Cvar_Get("cl_browserdetailedcolors", "0", CVAR_ARCHIVE);
|
||||
UIRect2D newRect = drawRect;
|
||||
vec2_t virtualScale = { 1.f, 1.f };
|
||||
|
||||
/*
|
||||
if (m_parent->isVirtual()) {
|
||||
virtualScale[0] = uid.vidWidth / 640.f;
|
||||
virtualScale[1] = uid.vidHeight / 480.f;
|
||||
newRect.size.width *= uid.vidWidth / 1024;
|
||||
newRect.size.height *= uid.vidHeight / 768;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!pColoringType->integer) {
|
||||
if (IfQueryFailed() || (IsDifferentVersion() && IsQueried())) {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.2f, 0.0f, 0.0f), 1.0);
|
||||
DrawBox(newRect, UColor(0.2f, 0.0f, 0.0f), 1.0);
|
||||
pFont->setColor(UColor(0.9f, 0.0f, 0.0f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.1f, 0.0f, 0.0f), 1.0);
|
||||
DrawBox(newRect, UColor(0.1f, 0.0f, 0.0f), 1.0);
|
||||
pFont->setColor(UColor(0.55f, 0.0f, 0.0f));
|
||||
}
|
||||
} else if (IsQueried()) {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
|
||||
DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
|
||||
pFont->setColor(UColor(0.9f, 0.8f, 0.6f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.02f, 0.07f, 0.004f), 1.0);
|
||||
DrawBox(newRect, UColor(0.02f, 0.07f, 0.004f), 1.0);
|
||||
pFont->setColor(UHudColor);
|
||||
}
|
||||
} else {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
|
||||
DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
|
||||
pFont->setColor(UColor(0.6f, 0.7f, 0.8f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
|
||||
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
|
||||
pFont->setColor(UColor(0.05f, 0.5f, 0.6f));
|
||||
}
|
||||
}
|
||||
|
||||
pFont->Print(
|
||||
drawRect.pos.x + 1.0,
|
||||
drawRect.pos.y,
|
||||
newRect.pos.x / virtualScale[0] + 1.0,
|
||||
newRect.pos.y / virtualScale[1],
|
||||
getListItemString(iColumn).c_str(),
|
||||
-1,
|
||||
qfalse
|
||||
false //m_parent->isVirtual()
|
||||
);
|
||||
} else {
|
||||
if (IsDifferentVersion()) {
|
||||
if (IsQueried()) {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
|
||||
DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
|
||||
pFont->setColor(UColor(0.0f, 0.5f, 0.0f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
|
||||
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
|
||||
pFont->setColor(UColor(0.0f, 0.35f, 0.0f));
|
||||
}
|
||||
} else {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
|
||||
DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
|
||||
pFont->setColor(UColor(0.5f, 0.6f, 0.7f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.15f, 0.0f, 0.0f), 1.0);
|
||||
DrawBox(newRect, UColor(0.15f, 0.0f, 0.0f), 1.0);
|
||||
pFont->setColor(UColor(0.05f, 0.4f, 0.5f));
|
||||
}
|
||||
}
|
||||
} else if (IsQueried()) {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
|
||||
DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
|
||||
pFont->setColor(UColor(0.9f, 0.8f, 0.6f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.02f, 0.07f, 0.005f), 1.0);
|
||||
DrawBox(newRect, UColor(0.02f, 0.07f, 0.005f), 1.0);
|
||||
pFont->setColor(UHudColor);
|
||||
}
|
||||
} else {
|
||||
if (bSelected) {
|
||||
DrawBox(drawRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
|
||||
DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
|
||||
pFont->setColor(UColor(0.6f, 0.7f, 0.8f));
|
||||
} else {
|
||||
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
|
||||
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
|
||||
pFont->setColor(UColor(0.05f, 0.5f, 0.6f));
|
||||
}
|
||||
|
||||
if (IfQueryFailed()) {
|
||||
DrawBox(
|
||||
UIRect2D(
|
||||
drawRect.pos.x,
|
||||
drawRect.pos.y + drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y,
|
||||
drawRect.size.width,
|
||||
drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y
|
||||
newRect.pos.x,
|
||||
newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y,
|
||||
newRect.size.width,
|
||||
newRect.size.height * 0.5 - 1.0 + newRect.pos.y
|
||||
),
|
||||
URed,
|
||||
0.3f
|
||||
@@ -249,19 +262,19 @@ void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
|
||||
}
|
||||
|
||||
pFont->Print(
|
||||
drawRect.pos.x + 1.0,
|
||||
drawRect.pos.y,
|
||||
newRect.pos.x / virtualScale[0] + 1.0,
|
||||
newRect.pos.y / virtualScale[1],
|
||||
getListItemString(iColumn).c_str(),
|
||||
-1,
|
||||
qfalse
|
||||
false //m_parent->isVirtual()
|
||||
);
|
||||
|
||||
if (IsDifferentVersion()) {
|
||||
DrawBox(
|
||||
UIRect2D(
|
||||
drawRect.pos.x,
|
||||
drawRect.pos.y + drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y,
|
||||
drawRect.size.width,
|
||||
newRect.pos.x,
|
||||
newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y,
|
||||
newRect.size.width,
|
||||
1.0
|
||||
),
|
||||
URed,
|
||||
@@ -730,6 +743,14 @@ void UIFAKKServerList::UpdateServer( Event *ev )
|
||||
|
||||
FAKKServerListItem* item = (FAKKServerListItem*)GetItem(getCurrentItem());
|
||||
ServerListAuxUpdate(m_serverList[0], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status);
|
||||
|
||||
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
|
||||
const cvar_t* dm_omit_spearhead = Cvar_Get("dm_omit_spearhead", "0", CVAR_ARCHIVE);
|
||||
// check for Spearhead
|
||||
if (!dm_omit_spearhead->integer) {
|
||||
ServerListAuxUpdate(m_serverList[1], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UIFAKKServerList::ServerCompareFunction( const UIListCtrlItem *i1, const UIListCtrlItem *i2, int columnname )
|
||||
@@ -1019,23 +1040,36 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
str sServerName;
|
||||
str sPlayers;
|
||||
const char* pszGameVer;
|
||||
const char* pszGameVerNumber;
|
||||
|
||||
pszHostName = ServerGetStringValue(server, "hostname", "(NONE)");
|
||||
bDiffVersion = false;
|
||||
pszGameVer = ServerGetStringValue(server, "gamever", "1.00");
|
||||
pszGameVerNumber = pszGameVer;
|
||||
|
||||
if (pszGameVerNumber[0] == 'd') {
|
||||
// demo server
|
||||
pszGameVerNumber++;
|
||||
}
|
||||
|
||||
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
|
||||
if (iServerType == target_game_e::TG_MOHTT) {
|
||||
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.1f) {
|
||||
//if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) {
|
||||
// bDiffVersion = true;
|
||||
//}
|
||||
if (fabs(atof(pszGameVerNumber)) < 2.3f) {
|
||||
bDiffVersion = true;
|
||||
}
|
||||
} else {
|
||||
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.3f) {
|
||||
//if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.3f) {
|
||||
// bDiffVersion = true;
|
||||
//}
|
||||
if (fabs(atof(pszGameVerNumber)) < 2.1f) {
|
||||
bDiffVersion = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.1f) {
|
||||
if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) {
|
||||
bDiffVersion = true;
|
||||
}
|
||||
}
|
||||
@@ -1056,7 +1090,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
}
|
||||
|
||||
if (i > uiServerList->getNumItems() || !pNewServerItem) {
|
||||
pNewServerItem = new FAKKServerListItem("?", sAddress, "?", "?/?", "?", "?", "?");
|
||||
pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?");
|
||||
pNewServerItem->m_sIP = ServerGetAddress(server);
|
||||
pNewServerItem->m_uiRealIP = iRealIP;
|
||||
pNewServerItem->m_iGameSpyPort = iGameSpyPort;
|
||||
@@ -1154,7 +1188,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
continue;
|
||||
}
|
||||
|
||||
pNewServerItem = new FAKKServerListItem("?", sAddress, "?", "?/?", "?", "?", "?");
|
||||
pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?");
|
||||
pNewServerItem->m_sIP = ServerGetAddress(arrayServer);
|
||||
pNewServerItem->m_uiRealIP = iRealIP;
|
||||
pNewServerItem->m_iPort = PORT_SERVER;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,22 +22,42 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, SoundPickerClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, SoundPickerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
SoundPickerClass::SoundPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
str soundpath;
|
||||
str currentpath;
|
||||
const char *varValue;
|
||||
int i;
|
||||
|
||||
soundpath = "sound";
|
||||
|
||||
varValue = UI_GetCvarString("ui_pickedsound", NULL);
|
||||
if (varValue && *varValue) {
|
||||
currentpath = varValue;
|
||||
|
||||
for (i = currentpath.length(); i > 0; i--) {
|
||||
if (currentpath[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentpath = str(currentpath, 0, i + 1);
|
||||
} else {
|
||||
currentpath = soundpath;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundPickerClass::FileSelected( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void SoundPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
|
||||
uii.Snd_PlaySound(fullname);
|
||||
}
|
||||
|
||||
void SoundPickerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void SoundPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
|
||||
uii.Cvar_Set("ui_pickedsound", fullname);
|
||||
CloseWindow();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,17 +20,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISOUNDPICKER_H__
|
||||
#define __CL_UISOUNDPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class SoundPickerClass : public FilePickerClass {
|
||||
class SoundPickerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( SoundPickerClass );
|
||||
CLASS_PROTOTYPE(SoundPickerClass);
|
||||
|
||||
SoundPickerClass();
|
||||
SoundPickerClass();
|
||||
|
||||
void FileSelected( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
#endif /* __CL_UISOUNDPICKER_H__ */
|
||||
+174
-229
@@ -490,12 +490,10 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
float width = frac * m_frame.size.width;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
break;
|
||||
@@ -507,12 +505,10 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
float y = m_frame.size.height * (1.0 - frac);
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTilePic(
|
||||
0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
|
||||
);
|
||||
@@ -528,14 +524,12 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
float width = frac * m_frame.size.width;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawStretchPic(
|
||||
0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial()
|
||||
);
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawStretchPic(
|
||||
0.0,
|
||||
0.0,
|
||||
@@ -557,14 +551,12 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
float y = m_frame.size.height * (1.0 - frac);
|
||||
float height = m_frame.size.height * frac;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawStretchPic(
|
||||
0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial()
|
||||
);
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawStretchPic(
|
||||
0.0,
|
||||
y,
|
||||
@@ -583,14 +575,12 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
float height = m_frame.size.height * frac;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawStretchPic(
|
||||
0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial()
|
||||
);
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawStretchPic(
|
||||
0.0,
|
||||
0.0,
|
||||
@@ -686,12 +676,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
} else {
|
||||
@@ -709,12 +697,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
@@ -739,12 +725,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
} else {
|
||||
@@ -766,12 +750,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
@@ -846,12 +828,10 @@ void UIFakkLabel::DrawStatNeedle(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.f && m_statbar_material_flash) {
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
@@ -867,11 +847,9 @@ void UIFakkLabel::DrawStatNeedle(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.f && m_statbar_material_flash) {
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
}
|
||||
@@ -937,11 +915,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.f && m_statbar_material_flash) {
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
@@ -959,11 +935,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.f && m_statbar_material_flash) {
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
}
|
||||
@@ -1137,7 +1111,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
|
||||
vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0];
|
||||
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
vVerts[0][0] = vVerts[2][0];
|
||||
@@ -1150,7 +1123,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
|
||||
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
|
||||
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
}
|
||||
|
||||
@@ -1227,11 +1199,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.f && m_statbar_material_flash) {
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
@@ -1249,11 +1219,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
|
||||
re.SetColor(m_foreground_color);
|
||||
}
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.f && m_statbar_material_flash) {
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
}
|
||||
@@ -1294,40 +1262,16 @@ void UIFakkLabel::Draw(void)
|
||||
{
|
||||
if (m_stat_alpha != -1) {
|
||||
float frac;
|
||||
|
||||
|
||||
frac = (cl.snap.ps.stats[m_stat_alpha] + 1) / 100.0;
|
||||
frac = Q_clamp_float(frac, 0, 1);
|
||||
|
||||
|
||||
m_alpha = frac;
|
||||
}
|
||||
|
||||
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1) {
|
||||
if (m_stat_configstring != -1) {
|
||||
m_font->setColor(m_foreground_color);
|
||||
|
||||
if (m_bOutlinedText) {
|
||||
m_font->PrintOutlinedJustified(
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
} else {
|
||||
m_font->PrintJustified(
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_rendermodel && m_statbar_or == L_STATBAR_NONE && !m_sDrawModelName.length()) {
|
||||
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1 && m_stat_configstring == -1
|
||||
&& !m_rendermodel && m_statbar_or == L_STATBAR_NONE) {
|
||||
if (!m_sDrawModelName.length()) {
|
||||
UILabel::Draw();
|
||||
return;
|
||||
}
|
||||
@@ -1354,28 +1298,13 @@ void UIFakkLabel::Draw(void)
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_stat == -1) {
|
||||
float scale;
|
||||
qhandle_t handle;
|
||||
vec3_t origin;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t angles;
|
||||
vec3_t offset;
|
||||
vec3_t rotateoffset;
|
||||
vec4_t color;
|
||||
str sAnimName;
|
||||
float height;
|
||||
|
||||
if (m_itemindex != -1) {
|
||||
if (m_itemindex < 0) {
|
||||
return;
|
||||
}
|
||||
if (m_stat != -1) {
|
||||
int delta = cl.snap.ps.stats[m_stat];
|
||||
|
||||
if (m_statbar_or == L_STATBAR_NONE) {
|
||||
m_font->setColor(m_foreground_color);
|
||||
|
||||
if (m_bOutlinedText) {
|
||||
@@ -1383,7 +1312,7 @@ void UIFakkLabel::Draw(void)
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
|
||||
va("%d", delta),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
@@ -1392,143 +1321,13 @@ void UIFakkLabel::Draw(void)
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
|
||||
va("%d", delta),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() || !m_rendermodel) {
|
||||
float frac = 0.0;
|
||||
|
||||
if (m_statbar_or == L_STATBAR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_cvarname.length()) {
|
||||
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
|
||||
}
|
||||
|
||||
if (frac > 1.0) {
|
||||
frac = 1.0;
|
||||
}
|
||||
if (frac < 0.0) {
|
||||
frac = 0.0;
|
||||
}
|
||||
|
||||
DrawStatbar(frac);
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSet4(color, 255, 255, 255, 255);
|
||||
|
||||
if (m_rendermodel) {
|
||||
if (!m_cvarname.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
|
||||
if (!handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy(m_angles, angles);
|
||||
VectorCopy(m_rotateoffset, rotateoffset);
|
||||
VectorCopy(m_offset, offset);
|
||||
scale = m_scale;
|
||||
sAnimName = m_anim;
|
||||
} else if (m_sDrawModelName.length()) {
|
||||
if (m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
|
||||
if (!m_lastitem) {
|
||||
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
|
||||
}
|
||||
}
|
||||
|
||||
_shitlabel01:
|
||||
if (!m_lastitem) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
|
||||
VectorCopy(m_lastitem->hudprops.offset, offset);
|
||||
|
||||
handle = re.RegisterModel(m_lastitem->hudprops.model);
|
||||
|
||||
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
|
||||
|
||||
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
|
||||
float frac = uid.time / 600.0;
|
||||
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
|
||||
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
|
||||
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
|
||||
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
|
||||
float frac = uid.time / 600.0;
|
||||
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
|
||||
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
|
||||
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
|
||||
}
|
||||
|
||||
if (m_rendermodel) {
|
||||
VectorSet(mins, -16, -16, 0);
|
||||
VectorSet(maxs, 16, 16, 96);
|
||||
} else {
|
||||
re.ModelBounds(handle, mins, maxs);
|
||||
}
|
||||
|
||||
origin[1] = (mins[1] + maxs[1]) * 0.5;
|
||||
origin[2] = (mins[1] + maxs[1]) * -0.5;
|
||||
|
||||
height = maxs[2] - mins[2];
|
||||
|
||||
if (height < maxs[1] - mins[1]) {
|
||||
height = maxs[1] - mins[1];
|
||||
}
|
||||
|
||||
if (height <= maxs[0] - mins[0]) {
|
||||
height = maxs[0] - mins[0];
|
||||
}
|
||||
|
||||
origin[0] = height * scale * 0.5 / 0.268f;
|
||||
|
||||
CL_Draw3DModel(
|
||||
m_screenframe.pos.x,
|
||||
m_screenframe.pos.y,
|
||||
m_screenframe.size.width,
|
||||
m_screenframe.size.height,
|
||||
handle,
|
||||
origin,
|
||||
rotateoffset,
|
||||
offset,
|
||||
angles,
|
||||
color,
|
||||
sAnimName
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_lastitemindex == cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
|
||||
goto _shitlabel01;
|
||||
}
|
||||
|
||||
if (m_lastitem
|
||||
== CL_GetInvItemByName(
|
||||
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
|
||||
)) {
|
||||
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
|
||||
goto _shitlabel01;
|
||||
}
|
||||
|
||||
m_lastitem = CL_GetInvItemByName(
|
||||
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
|
||||
);
|
||||
goto _shitlabel01;
|
||||
}
|
||||
|
||||
int delta = cl.snap.ps.stats[m_stat];
|
||||
|
||||
if (m_statbar_or) {
|
||||
if (m_statbar_or == L_STATBAR_VERTICAL_STAGGER_EVEN || m_statbar_or == L_STATBAR_VERTICAL_STAGGER_ODD) {
|
||||
int stat;
|
||||
|
||||
@@ -1574,28 +1373,174 @@ void UIFakkLabel::Draw(void)
|
||||
}
|
||||
|
||||
DrawStatbar(frac);
|
||||
return;
|
||||
}
|
||||
|
||||
float scale;
|
||||
qhandle_t handle;
|
||||
vec3_t origin;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t angles;
|
||||
vec3_t offset;
|
||||
vec3_t rotateoffset;
|
||||
vec4_t color;
|
||||
str sAnimName;
|
||||
float height;
|
||||
|
||||
if (m_itemindex != -1) {
|
||||
if (m_itemindex < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
|
||||
if (m_bOutlinedText) {
|
||||
m_font->PrintOutlinedJustified(
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
} else {
|
||||
m_font->PrintJustified(
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() && !m_rendermodel) {
|
||||
float frac = 0.0;
|
||||
|
||||
if (m_bOutlinedText) {
|
||||
m_font->PrintOutlinedJustified(
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
va("%d", delta),
|
||||
UBlack,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
} else {
|
||||
m_font->PrintJustified(
|
||||
getClientFrame(),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
va("%d", delta),
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
if (m_statbar_or == L_STATBAR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_cvarname.length()) {
|
||||
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
|
||||
}
|
||||
|
||||
if (frac > 1.0) {
|
||||
frac = 1.0;
|
||||
}
|
||||
if (frac < 0.0) {
|
||||
frac = 0.0;
|
||||
}
|
||||
|
||||
DrawStatbar(frac);
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSet4(color, 255, 255, 255, 255);
|
||||
|
||||
if (m_rendermodel) {
|
||||
if (!m_cvarname.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
|
||||
if (!handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy(m_angles, angles);
|
||||
VectorCopy(m_rotateoffset, rotateoffset);
|
||||
VectorCopy(m_offset, offset);
|
||||
scale = m_scale;
|
||||
sAnimName = m_anim;
|
||||
|
||||
// Added in 2.11
|
||||
// Tunak easter egg
|
||||
if (Cvar_Get("tunak", "0", 0)->integer) {
|
||||
// Since 2.15, those animations start has 'zz' prefix
|
||||
if (strstr(m_anim, "american")) {
|
||||
sAnimName = "zzamericanspecialidle";
|
||||
} else {
|
||||
// Added in 2.15
|
||||
sAnimName = "zzgermanspecialidle";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_sDrawModelName.length()) {
|
||||
if (!m_lastitem) {
|
||||
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
|
||||
}
|
||||
} else {
|
||||
if (m_inventoryrendermodelindex >= 0
|
||||
&& m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
|
||||
m_lastitem = CL_GetInvItemByName(
|
||||
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
|
||||
);
|
||||
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_lastitem) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
|
||||
VectorCopy(m_lastitem->hudprops.offset, offset);
|
||||
scale = m_lastitem->hudprops.scale;
|
||||
handle = re.RegisterModel(m_lastitem->hudprops.model);
|
||||
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
|
||||
|
||||
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
|
||||
float frac = uid.time / 600.0;
|
||||
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
|
||||
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
|
||||
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
|
||||
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
|
||||
float frac = uid.time / 600.0;
|
||||
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
|
||||
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
|
||||
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_rendermodel) {
|
||||
VectorSet(mins, -16, -16, 0);
|
||||
VectorSet(maxs, 16, 16, 96);
|
||||
} else {
|
||||
re.ModelBounds(handle, mins, maxs);
|
||||
}
|
||||
|
||||
origin[1] = (mins[1] + maxs[1]) * 0.5;
|
||||
origin[2] = (mins[2] + maxs[2]) * -0.5;
|
||||
|
||||
height = maxs[2] - mins[2];
|
||||
|
||||
if (height < maxs[1] - mins[1]) {
|
||||
height = maxs[1] - mins[1];
|
||||
}
|
||||
|
||||
if (height < maxs[0] - mins[0]) {
|
||||
height = maxs[0] - mins[0];
|
||||
}
|
||||
|
||||
origin[0] = height * scale * 0.5 / 0.268f;
|
||||
|
||||
CL_Draw3DModel(
|
||||
m_screenframe.pos.x,
|
||||
m_screenframe.pos.y,
|
||||
m_screenframe.size.width,
|
||||
m_screenframe.size.height,
|
||||
handle,
|
||||
origin,
|
||||
rotateoffset,
|
||||
offset,
|
||||
angles,
|
||||
color,
|
||||
sAnimName
|
||||
);
|
||||
|
||||
set2D();
|
||||
}
|
||||
@@ -37,6 +37,8 @@ typedef enum {
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
} statbar_orientation_t;
|
||||
|
||||
extern Event EV_ClearInvItemReference;
|
||||
|
||||
class UIFakkLabel : public UILabel
|
||||
{
|
||||
protected:
|
||||
|
||||
+513
-364
@@ -21,424 +21,573 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( UIWidget, View3D, NULL )
|
||||
{
|
||||
{ &W_Activated, &View3D::OnActivate },
|
||||
{ &W_Deactivated, &View3D::OnDeactivate },
|
||||
{ &W_LeftMouseDown, &View3D::Pressed },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, View3D, NULL) {
|
||||
{&W_Activated, &View3D::OnActivate },
|
||||
{&W_Deactivated, &View3D::OnDeactivate},
|
||||
{&W_LeftMouseDown, &View3D::Pressed },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
#define MAX_SUBTITLES 4
|
||||
|
||||
cvar_t* subs[MAX_SUBTITLES];
|
||||
cvar_t* teams[MAX_SUBTITLES];
|
||||
float fadeTime[MAX_SUBTITLES];
|
||||
float subLife[MAX_SUBTITLES];
|
||||
float alpha[MAX_SUBTITLES];
|
||||
char oldStrings[MAX_SUBTITLES][2048];
|
||||
cvar_t *subs[MAX_SUBTITLES];
|
||||
cvar_t *teams[MAX_SUBTITLES];
|
||||
float fadeTime[MAX_SUBTITLES];
|
||||
float subLife[MAX_SUBTITLES];
|
||||
float alpha[MAX_SUBTITLES];
|
||||
char oldStrings[MAX_SUBTITLES][2048];
|
||||
|
||||
View3D::View3D()
|
||||
{
|
||||
// set as transparent
|
||||
setBackgroundColor(UClear, true);
|
||||
// no border
|
||||
setBorderStyle(border_none);
|
||||
AllowActivate(true);
|
||||
// set as transparent
|
||||
setBackgroundColor(UClear, true);
|
||||
// no border
|
||||
setBorderStyle(border_none);
|
||||
AllowActivate(true);
|
||||
|
||||
m_printfadetime = 0.0;
|
||||
m_print_mat = NULL;
|
||||
m_locationprint = qfalse;
|
||||
m_printfadetime = 0.0;
|
||||
m_print_mat = NULL;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::UpdateLocationPrint(int x, int y, const char *s, float alpha)
|
||||
{
|
||||
if (clc.state != CA_DISCONNECTED) {
|
||||
SCR_DrawScreenField();
|
||||
}
|
||||
|
||||
set2D();
|
||||
|
||||
re.SavePerformanceCounters();
|
||||
|
||||
Draw2D();
|
||||
m_printstring = s;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_x_coord = x;
|
||||
m_y_coord = y;
|
||||
m_locationprint = qtrue;
|
||||
}
|
||||
|
||||
void View3D::DrawLetterbox
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::UpdateCenterPrint(const char *s, float alpha)
|
||||
{
|
||||
float frac;
|
||||
vec4_t col;
|
||||
m_printstring = s;
|
||||
|
||||
col[0] = col[1] = col[2] = 0;
|
||||
col[3] = 1;
|
||||
if (s[0] == '@') {
|
||||
m_print_mat = uWinMan.RegisterShader(s + 1);
|
||||
} else {
|
||||
m_print_mat = NULL;
|
||||
}
|
||||
|
||||
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
|
||||
if (frac > 0.0) {
|
||||
m_letterbox_active = true;
|
||||
re.SetColor(col);
|
||||
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
re.DrawBox(0.0, m_screenframe.size.height - m_screenframe.size.height * frac, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
m_letterbox_active = false;
|
||||
}
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::DrawFades
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line)
|
||||
{
|
||||
if (cl.snap.ps.blend[3] > 0) {
|
||||
re.SetColor(cl.snap.ps.blend);
|
||||
if (cl.snap.ps.stats[STAT_ADDFADE]) {
|
||||
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
}
|
||||
}
|
||||
char buf[255];
|
||||
float x;
|
||||
float xStep;
|
||||
float height;
|
||||
|
||||
height = m_font->getHeight(false);
|
||||
xStep = height;
|
||||
|
||||
x = 0;
|
||||
sprintf(buf, "%d", channel);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep + xStep;
|
||||
sprintf(buf, "%s", name);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 30.0;
|
||||
sprintf(buf, "vol:%.2f", vol);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 8;
|
||||
sprintf(buf, "rvol:%.2f", (float)(rvol / 128.f));
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 5;
|
||||
sprintf(buf, "pit:%.2f", pitch);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 5;
|
||||
sprintf(buf, "base:%d", (int)base);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
void View3D::Draw2D
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::Pressed(Event *ev)
|
||||
{
|
||||
if (!cls.no_menus) {
|
||||
DrawFades();
|
||||
}
|
||||
|
||||
DrawLetterbox();
|
||||
|
||||
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus)
|
||||
{
|
||||
SCR_DrawDebugGraph();
|
||||
}
|
||||
else if (!cls.no_menus)
|
||||
{
|
||||
if (cge) {
|
||||
cge->CG_Draw2D();
|
||||
}
|
||||
|
||||
if (m_locationprint) {
|
||||
LocationPrint();
|
||||
} else {
|
||||
CenterPrint();
|
||||
}
|
||||
|
||||
if (!cls.no_menus)
|
||||
{
|
||||
DrawSoundOverlay();
|
||||
DrawSubtitleOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
if (fps->integer && !cls.no_menus)
|
||||
{
|
||||
DrawFPS();
|
||||
DrawProf();
|
||||
}
|
||||
IN_MouseOff();
|
||||
OnActivate(ev);
|
||||
}
|
||||
|
||||
void View3D::DrawFPS
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::OnDeactivate(Event *ev)
|
||||
{
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2)
|
||||
{
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
}
|
||||
else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
}
|
||||
|
||||
void View3D::DrawProf
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::OnActivate(Event *ev)
|
||||
{
|
||||
// Normal empty function
|
||||
}
|
||||
|
||||
void View3D::PrintSound
|
||||
(
|
||||
int channel,
|
||||
const char *name,
|
||||
float vol,
|
||||
int rvol,
|
||||
float pitch,
|
||||
float base,
|
||||
int& line
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::DrawSoundOverlay
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
if (sound_overlay->integer) {
|
||||
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
|
||||
Cvar_Set("sound_overlay", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::CenterPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::LocationPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::OnActivate
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
{
|
||||
UIWidget* wid;
|
||||
UList<UIWidget*> widgets;
|
||||
UIWidget *wid;
|
||||
UList<UIWidget *> widgets;
|
||||
|
||||
UI_CloseInventory();
|
||||
cls.keyCatchers &= ~KEYCATCH_UI;
|
||||
|
||||
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid))
|
||||
{
|
||||
if (wid->getAlwaysOnBottom() && wid != this) {
|
||||
widgets.AddTail(wid);
|
||||
}
|
||||
}
|
||||
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid)) {
|
||||
if (wid->getAlwaysOnBottom() && wid != this) {
|
||||
widgets.AddTail(wid);
|
||||
}
|
||||
}
|
||||
|
||||
widgets.IterateFromHead();
|
||||
while (widgets.IsCurrentValid())
|
||||
{
|
||||
widgets.getCurrent()->BringToFrontPropogated();
|
||||
widgets.IterateNext();
|
||||
}
|
||||
widgets.IterateFromHead();
|
||||
while (widgets.IsCurrentValid()) {
|
||||
widgets.getCurrent()->BringToFrontPropogated();
|
||||
widgets.IterateNext();
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::OnDeactivate
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::LocationPrint(void)
|
||||
{
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
fonthorzjustify_t horiz;
|
||||
fontvertjustify_t vert;
|
||||
int x, y;
|
||||
const char *p;
|
||||
float alpha;
|
||||
UIRect2D frame;
|
||||
|
||||
if (!m_printfadetime) {
|
||||
m_locationprint = false;
|
||||
return;
|
||||
}
|
||||
|
||||
horiz = FONT_JUSTHORZ_LEFT;
|
||||
vert = FONT_JUSTVERT_TOP;
|
||||
|
||||
p = Sys_LV_CL_ConvertString(m_printstring);
|
||||
if (m_printfadetime > 3250) {
|
||||
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
|
||||
} else if (m_printfadetime >= 750) {
|
||||
alpha = 1.f;
|
||||
} else {
|
||||
alpha = m_printfadetime / 750.f * m_printalpha;
|
||||
}
|
||||
|
||||
alpha = Q_clamp_float(alpha, 0, 1);
|
||||
|
||||
x = m_x_coord / 640.f * m_screenframe.size.width;
|
||||
y = (480 - m_font->getHeight(false) - m_y_coord) / 480.f * m_screenframe.size.height;
|
||||
|
||||
if (m_x_coord == -1) {
|
||||
horiz = FONT_JUSTHORZ_CENTER;
|
||||
x = 0;
|
||||
}
|
||||
if (m_y_coord == -1) {
|
||||
vert = FONT_JUSTVERT_CENTER;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha));
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
UIRect2D(frame.pos.x + x + 1, frame.pos.y + y + 1, frame.size.width, frame.size.height),
|
||||
horiz,
|
||||
vert,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha));
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
UIRect2D(frame.pos.x + x, frame.pos.y + y, frame.size.width, frame.size.height),
|
||||
horiz,
|
||||
vert,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
m_printfadetime -= cls.frametime;
|
||||
|
||||
if (m_printfadetime < 0) {
|
||||
m_printfadetime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawSubtitleOverlay
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
qboolean View3D::LetterboxActive(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::ClearCenterPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
m_printfadetime = 0.0;
|
||||
}
|
||||
|
||||
void View3D::UpdateCenterPrint
|
||||
(
|
||||
const char *s,
|
||||
float alpha
|
||||
)
|
||||
|
||||
{
|
||||
m_printstring = s;
|
||||
|
||||
if (s[0] == '@') {
|
||||
m_print_mat = uWinMan.RegisterShader(s + 1);
|
||||
} else {
|
||||
m_print_mat = NULL;
|
||||
}
|
||||
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::UpdateLocationPrint
|
||||
(
|
||||
int x,
|
||||
int y,
|
||||
const char *s,
|
||||
float alpha
|
||||
)
|
||||
|
||||
{
|
||||
m_printstring = s;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_x_coord = x;
|
||||
m_y_coord = y;
|
||||
m_locationprint = qtrue;
|
||||
}
|
||||
|
||||
qboolean View3D::LetterboxActive
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
return m_letterbox_active;
|
||||
return m_letterbox_active;
|
||||
}
|
||||
|
||||
float avWidth = 0.0;
|
||||
|
||||
void View3D::InitSubtitle
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::InitSubtitle(void)
|
||||
{
|
||||
float totalWidth;
|
||||
float totalWidth;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
|
||||
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
|
||||
strcpy(oldStrings[i], subs[i]->string);
|
||||
fadeTime[i] = 4000.0;
|
||||
subLife[i] = 4000.0;
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
|
||||
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
|
||||
strcpy(oldStrings[i], subs[i]->string);
|
||||
fadeTime[i] = 4000.0;
|
||||
subLife[i] = 4000.0;
|
||||
}
|
||||
|
||||
totalWidth = 0.0;
|
||||
for (char j = 'A'; j <= 'Z'; j++) {
|
||||
totalWidth += m_font->getCharWidth(j);
|
||||
}
|
||||
totalWidth = 0.0;
|
||||
for (char j = 'A'; j <= 'Z'; j++) {
|
||||
totalWidth += m_font->getCharWidth(j);
|
||||
}
|
||||
|
||||
avWidth = totalWidth / 26.0;
|
||||
avWidth = totalWidth / 26.0;
|
||||
}
|
||||
|
||||
void View3D::FrameInitialized
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::FrameInitialized(void)
|
||||
{
|
||||
Connect(this, W_Activated, W_Activated);
|
||||
Connect(this, W_Deactivated, W_Deactivated);
|
||||
Connect(this, W_Activated, W_Activated);
|
||||
Connect(this, W_Deactivated, W_Deactivated);
|
||||
}
|
||||
|
||||
void View3D::Pressed
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::DrawSubtitleOverlay(void)
|
||||
{
|
||||
IN_MouseOff();
|
||||
OnActivate(ev);
|
||||
cvar_t *subAlpha;
|
||||
int i;
|
||||
float minX, maxY;
|
||||
int line;
|
||||
|
||||
subAlpha = Cvar_Get("subAlpha", "0.5", 0);
|
||||
|
||||
setFont("facfont-20");
|
||||
m_font->setColor(URed);
|
||||
|
||||
for (i = 0; i < MAX_SUBTITLES; i++) {
|
||||
if (strcmp(oldStrings[i], subs[i]->string)) {
|
||||
fadeTime[i] = 2500 * ((strlen(subs[i]->string) / 68) + 1.f) + 1500;
|
||||
subLife[i] = fadeTime[i];
|
||||
Q_strncpyz(oldStrings[i], subs[i]->string, sizeof(oldStrings[i]));
|
||||
}
|
||||
|
||||
if (fadeTime[i] > subLife[i] - 750.f) {
|
||||
alpha[i] = 1.f - (fadeTime[i] - (subLife[i] - 750.f)) / 750.f;
|
||||
} else if (fadeTime[i] < 750) {
|
||||
alpha[i] = fadeTime[i] / 750.f;
|
||||
} else {
|
||||
alpha[i] = 1.f;
|
||||
}
|
||||
|
||||
fadeTime[i] -= cls.frametime;
|
||||
if (fadeTime[i] < 0) {
|
||||
// Clear the subtitle
|
||||
fadeTime[i] = 0;
|
||||
oldStrings[i][0] = 0;
|
||||
Cvar_Set(va("subtitle%d", i), "");
|
||||
}
|
||||
}
|
||||
|
||||
minX = m_screenframe.size.height - m_font->getHeight(false) * 10;
|
||||
maxY = (m_frame.pos.x + m_frame.size.width) - (m_frame.pos.x + m_frame.size.width) * 0.2f;
|
||||
line = 0;
|
||||
|
||||
for (i = 0; i < MAX_SUBTITLES; i++) {
|
||||
if (m_font->getWidth(subs[i]->string, sizeof(oldStrings[i])) > maxY) {
|
||||
char buf[2048];
|
||||
char *c;
|
||||
char *end;
|
||||
char *start;
|
||||
float total;
|
||||
int blockcount;
|
||||
|
||||
c = buf;
|
||||
strcpy(buf, subs[i]->string);
|
||||
|
||||
total = 0;
|
||||
end = NULL;
|
||||
start = buf;
|
||||
while (*c) {
|
||||
blockcount = m_font->DBCSGetWordBlockCount(c, -1);
|
||||
if (!blockcount) {
|
||||
break;
|
||||
}
|
||||
|
||||
total += m_font->getWidth(c, blockcount);
|
||||
c += blockcount;
|
||||
|
||||
if (total > maxY) {
|
||||
total = 0;
|
||||
if (end < start) {
|
||||
Com_DPrintf("ERROR - word longer than possible line\n");
|
||||
break;
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, false);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, false);
|
||||
|
||||
start = end + 1;
|
||||
c = end + 1;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, qfalse);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, qfalse);
|
||||
line++;
|
||||
} else {
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, subs[i]->string, -1, qfalse);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, subs[i]->string, -1, qfalse);
|
||||
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( UIWidget, ConsoleView, NULL )
|
||||
void View3D::DrawSoundOverlay(void)
|
||||
{
|
||||
{ NULL, NULL }
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
// FIXME: TODO
|
||||
if (sound_overlay->integer) {
|
||||
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
|
||||
Cvar_Set("sound_overlay", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawProf(void)
|
||||
{
|
||||
// Normal empty function
|
||||
}
|
||||
|
||||
void View3D::DrawLetterbox(void)
|
||||
{
|
||||
float frac;
|
||||
vec4_t col;
|
||||
|
||||
col[0] = col[1] = col[2] = 0;
|
||||
col[3] = 1;
|
||||
|
||||
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
|
||||
if (frac > 0.0) {
|
||||
m_letterbox_active = true;
|
||||
re.SetColor(col);
|
||||
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_screenframe.size.height - m_screenframe.size.height * frac,
|
||||
m_screenframe.size.width,
|
||||
m_screenframe.size.height
|
||||
);
|
||||
} else {
|
||||
m_letterbox_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawFades(void)
|
||||
{
|
||||
if (cl.snap.ps.blend[3] > 0) {
|
||||
re.SetColor(cl.snap.ps.blend);
|
||||
if (cl.snap.ps.stats[STAT_ADDFADE]) {
|
||||
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawFPS(void)
|
||||
{
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2) {
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
}
|
||||
|
||||
void View3D::Draw2D(void)
|
||||
{
|
||||
if (!cls.no_menus) {
|
||||
DrawFades();
|
||||
}
|
||||
|
||||
DrawLetterbox();
|
||||
|
||||
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus) {
|
||||
SCR_DrawDebugGraph();
|
||||
} else if (!cls.no_menus) {
|
||||
if (cge) {
|
||||
cge->CG_Draw2D();
|
||||
}
|
||||
|
||||
if (m_locationprint) {
|
||||
LocationPrint();
|
||||
} else {
|
||||
CenterPrint();
|
||||
}
|
||||
|
||||
if (!cls.no_menus) {
|
||||
DrawSoundOverlay();
|
||||
DrawSubtitleOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
if (fps->integer && !cls.no_menus) {
|
||||
DrawFPS();
|
||||
DrawProf();
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::Draw(void)
|
||||
{
|
||||
if (clc.state != CA_DISCONNECTED) {
|
||||
SCR_DrawScreenField();
|
||||
}
|
||||
|
||||
set2D();
|
||||
|
||||
re.SavePerformanceCounters();
|
||||
|
||||
Draw2D();
|
||||
}
|
||||
|
||||
void View3D::ClearCenterPrint(void)
|
||||
{
|
||||
m_printfadetime = 0.0;
|
||||
}
|
||||
|
||||
void View3D::CenterPrint(void)
|
||||
{
|
||||
float alpha;
|
||||
const char *p;
|
||||
qhandle_t mat;
|
||||
float x, y;
|
||||
float w, h;
|
||||
|
||||
if (!m_printfadetime) {
|
||||
return;
|
||||
}
|
||||
|
||||
p = Sys_LV_CL_ConvertString(m_printstring);
|
||||
if (m_printfadetime > 3250) {
|
||||
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
|
||||
} else if (m_printfadetime >= 750) {
|
||||
alpha = 1.f;
|
||||
} else {
|
||||
alpha = m_printfadetime / 750.f * m_printalpha;
|
||||
}
|
||||
|
||||
alpha = Q_clamp_float(alpha, 0, 1);
|
||||
|
||||
if (!m_print_mat) {
|
||||
UIRect2D frame;
|
||||
m_font->setColor(UColor(0, 0, 0, alpha));
|
||||
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
UIRect2D(frame.pos.x + 1, frame.pos.y + 1, frame.size.width, frame.size.height),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha));
|
||||
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
frame, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, p, m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
} else if ((mat = m_print_mat->GetMaterial())) {
|
||||
vec4_t col {alpha, alpha, alpha, alpha};
|
||||
|
||||
re.SetColor(col);
|
||||
|
||||
w = re.GetShaderWidth(mat);
|
||||
h = re.GetShaderHeight(mat);
|
||||
x = (m_frame.pos.x + m_frame.size.width - w) * 0.5f;
|
||||
y = (m_frame.pos.y + m_frame.size.height - h) * 0.5f;
|
||||
|
||||
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, mat);
|
||||
}
|
||||
|
||||
m_printfadetime -= cls.frametime;
|
||||
|
||||
if (m_printfadetime < 0) {
|
||||
m_printfadetime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIWidget, ConsoleView, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void ConsoleView::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void ConsoleView::Draw(void) {}
|
||||
+37
-38
@@ -20,55 +20,54 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIVIEW3D__
|
||||
#define __CL_UIVIEW3D__
|
||||
#pragma once
|
||||
|
||||
class View3D : public UIWidget {
|
||||
float m_printfadetime;
|
||||
float m_printalpha;
|
||||
str m_printstring;
|
||||
UIReggedMaterial *m_print_mat;
|
||||
qboolean m_locationprint;
|
||||
int m_x_coord;
|
||||
int m_y_coord;
|
||||
qboolean m_letterbox_active;
|
||||
class View3D : public UIWidget
|
||||
{
|
||||
float m_printfadetime;
|
||||
float m_printalpha;
|
||||
str m_printstring;
|
||||
UIReggedMaterial *m_print_mat;
|
||||
qboolean m_locationprint;
|
||||
int m_x_coord;
|
||||
int m_y_coord;
|
||||
qboolean m_letterbox_active;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( View3D );
|
||||
CLASS_PROTOTYPE(View3D);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void DrawLetterbox( void );
|
||||
void DrawFades( void );
|
||||
void Draw2D( void );
|
||||
void DrawFPS( void );
|
||||
void DrawProf( void );
|
||||
void PrintSound( int channel, const char *name, float vol, int rvol, float pitch, float base, int& line );
|
||||
void DrawSoundOverlay( void );
|
||||
void CenterPrint( void );
|
||||
void LocationPrint( void );
|
||||
void OnActivate( Event *ev );
|
||||
void OnDeactivate( Event *ev );
|
||||
void DrawSubtitleOverlay( void );
|
||||
void Draw(void) override;
|
||||
void DrawLetterbox(void);
|
||||
void DrawFades(void);
|
||||
void Draw2D(void);
|
||||
void DrawFPS(void);
|
||||
void DrawProf(void);
|
||||
void PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line);
|
||||
void DrawSoundOverlay(void);
|
||||
void CenterPrint(void);
|
||||
void LocationPrint(void);
|
||||
void OnActivate(Event *ev);
|
||||
void OnDeactivate(Event *ev);
|
||||
void DrawSubtitleOverlay(void);
|
||||
|
||||
public:
|
||||
View3D();
|
||||
View3D();
|
||||
|
||||
void ClearCenterPrint( void );
|
||||
void UpdateCenterPrint( const char *s, float alpha );
|
||||
void UpdateLocationPrint( int x, int y, const char *s, float alpha );
|
||||
qboolean LetterboxActive( void );
|
||||
void InitSubtitle( void );
|
||||
void FrameInitialized( void ) override;
|
||||
virtual void Pressed( Event *ev );
|
||||
void ClearCenterPrint(void);
|
||||
void UpdateCenterPrint(const char *s, float alpha);
|
||||
void UpdateLocationPrint(int x, int y, const char *s, float alpha);
|
||||
qboolean LetterboxActive(void);
|
||||
void InitSubtitle(void);
|
||||
void FrameInitialized(void) override;
|
||||
virtual void Pressed(Event *ev);
|
||||
};
|
||||
|
||||
class ConsoleView : public UIWidget {
|
||||
class ConsoleView : public UIWidget
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( ConsoleView );
|
||||
CLASS_PROTOTYPE(ConsoleView);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void Draw(void) override;
|
||||
};
|
||||
|
||||
#endif /* __CL_UIVIEW3D__ */
|
||||
@@ -320,7 +320,7 @@ typedef struct {
|
||||
serverInfo_t globalServers[MAX_GLOBAL_SERVERS];
|
||||
// additional global servers
|
||||
int numGlobalServerAddresses;
|
||||
serverAddress_t globalServerAddresses[MAX_GLOBAL_SERVERS];
|
||||
netadr_t globalServerAddresses[MAX_GLOBAL_SERVERS];
|
||||
|
||||
int numfavoriteservers;
|
||||
serverInfo_t favoriteServers[MAX_OTHER_SERVERS];
|
||||
|
||||
@@ -59,6 +59,9 @@ typedef struct {
|
||||
void S_ChannelFree_Callback(channel_t* v);
|
||||
void S_LoadData(soundsystemsavegame_t* pSave);
|
||||
void S_SaveData(soundsystemsavegame_t* pSave);
|
||||
void S_ReLoad(soundsystemsavegame_t* pSave);
|
||||
|
||||
extern qboolean s_bSoundPaused;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -21,11 +21,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "../snd_local.h"
|
||||
#include "../client.h"
|
||||
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
|
||||
qboolean s_bSoundPaused = qfalse;
|
||||
|
||||
void S_Init2()
|
||||
{
|
||||
S_Init();
|
||||
SND_setup();
|
||||
|
||||
// HACK: S_RegisterSound returns 0 when unsuccessful, or it returns the the sfx handle
|
||||
// But the first sfx handle is also 0...
|
||||
S_RegisterSound("sound/null.wav", qfalse);
|
||||
|
||||
Cmd_AddCommand("tmstart", S_TriggeredMusic_Start);
|
||||
Cmd_AddCommand("tmstartloop", S_TriggeredMusic_StartLoop);
|
||||
Cmd_AddCommand("tmstop", S_TriggeredMusic_Stop);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -46,7 +59,18 @@ S_AddLoopingSound
|
||||
*/
|
||||
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags)
|
||||
{
|
||||
if (!sfxHandle) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: unimplemented
|
||||
|
||||
if (VectorCompare(origin, vec3_origin)) {
|
||||
// Consider it to be a local sound, uses the player origin
|
||||
S_AddLoopingSound(cl.snap.ps.clientNum, cl.snap.ps.origin, velocity, sfxHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
S_AddLoopingSound(ENTITYNUM_WORLD, origin, velocity, sfxHandle);
|
||||
}
|
||||
|
||||
@@ -91,7 +115,13 @@ S_StartLocalSoundChannel
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
sfxHandle_t h;
|
||||
|
||||
h = S_RegisterSound(sound_name, qfalse);
|
||||
|
||||
if (h) {
|
||||
S_StartLocalSound(h, CHAN_LOCAL_SOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -351,6 +381,16 @@ void MUSIC_CheckForStoppedSongs(void)
|
||||
STUB();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_CurrentSoundtrack
|
||||
==============
|
||||
*/
|
||||
const char* S_CurrentSoundtrack()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_IsSoundRegistered
|
||||
@@ -415,26 +455,141 @@ void S_FadeSound(float fTime)
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_TriggeredMusic_Start
|
||||
==============
|
||||
*/
|
||||
void S_TriggeredMusic_Start()
|
||||
{
|
||||
if (Cmd_Argc() != 2) {
|
||||
Com_Printf("tmstart <sound file>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
S_StartBackgroundTrack(Cmd_Argv(1), "");
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_TriggeredMusic_StartLoop
|
||||
==============
|
||||
*/
|
||||
void S_TriggeredMusic_StartLoop()
|
||||
{
|
||||
if (Cmd_Argc() != 2) {
|
||||
Com_Printf("tmstartloop <sound file>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
S_StartBackgroundTrack(Cmd_Argv(1), Cmd_Argv(1));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_TriggeredMusic_Stop
|
||||
==============
|
||||
*/
|
||||
void S_TriggeredMusic_Stop()
|
||||
{
|
||||
S_StopBackgroundTrack();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_TriggeredMusic_PlayIntroMusic
|
||||
==============
|
||||
*/
|
||||
void S_TriggeredMusic_PlayIntroMusic() {
|
||||
S_StartBackgroundTrack("sound/music/mus_MainTheme.mp3", "");
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_TriggeredMusic_SetupHandle
|
||||
==============
|
||||
*/
|
||||
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetMusicFilename
|
||||
==============
|
||||
*/
|
||||
const char* S_GetMusicFilename() {
|
||||
// FIXME: unimplemented
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetMusicLoopCount
|
||||
==============
|
||||
*/
|
||||
int S_GetMusicLoopCount() {
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetMusicOffset
|
||||
==============
|
||||
*/
|
||||
unsigned int S_GetMusicOffset() {
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
callbackServer
|
||||
==============
|
||||
*/
|
||||
void callbackServer(int entnum, int channel_number, const char* name) {
|
||||
if (com_sv_running->integer) {
|
||||
SV_SoundCallback(entnum, channel_number, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_ChannelFree_Callback
|
||||
==============
|
||||
*/
|
||||
void S_ChannelFree_Callback(channel_t* v) {
|
||||
if (v->entnum & S_FLAG_DO_CALLBACK) {
|
||||
callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_LoadData
|
||||
==============
|
||||
*/
|
||||
void S_LoadData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SaveData
|
||||
==============
|
||||
*/
|
||||
void S_SaveData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_ReLoad
|
||||
==============
|
||||
*/
|
||||
void S_ReLoad(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -64,6 +64,12 @@ qboolean MUSIC_PlaySong(const char* alias);
|
||||
void MUSIC_UpdateMusicVolumes(void);
|
||||
void MUSIC_CheckForStoppedSongs(void);
|
||||
|
||||
void S_TriggeredMusic_Start();
|
||||
void S_TriggeredMusic_StartLoop();
|
||||
void S_TriggeredMusic_Stop();
|
||||
|
||||
const char* S_CurrentSoundtrack();
|
||||
|
||||
void S_StopSound(int entnum, int channel);
|
||||
void S_StopAllSounds2(qboolean stop_music);
|
||||
float S_GetSoundTime(sfxHandle_t handle);
|
||||
@@ -74,6 +80,11 @@ qboolean S_IsSoundPlaying(int channelNumber, const char* name);
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener);
|
||||
void S_FadeSound(float fTime);
|
||||
void S_TriggeredMusic_PlayIntroMusic();
|
||||
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
|
||||
|
||||
const char* S_GetMusicFilename();
|
||||
int S_GetMusicLoopCount();
|
||||
unsigned int S_GetMusicOffset();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ LPALGETSOURCEF qalGetSourcef;
|
||||
LPALGETSOURCE3F qalGetSource3f;
|
||||
LPALGETSOURCEFV qalGetSourcefv;
|
||||
LPALGETSOURCEI qalGetSourcei;
|
||||
LPALGETSOURCEIV qalGetSourceiv;
|
||||
LPALSOURCEPLAYV qalSourcePlayv;
|
||||
LPALSOURCESTOPV qalSourceStopv;
|
||||
LPALSOURCEREWINDV qalSourceRewindv;
|
||||
@@ -81,6 +82,7 @@ LPALDELETEBUFFERS qalDeleteBuffers;
|
||||
LPALISBUFFER qalIsBuffer;
|
||||
LPALBUFFERDATA qalBufferData;
|
||||
LPALGETBUFFERF qalGetBufferf;
|
||||
LPALGETBUFFERFV qalGetBufferfv;
|
||||
LPALGETBUFFERI qalGetBufferi;
|
||||
LPALDOPPLERFACTOR qalDopplerFactor;
|
||||
LPALSPEEDOFSOUND qalSpeedOfSound;
|
||||
@@ -184,6 +186,7 @@ qboolean QAL_Init(const char *libname)
|
||||
qalGetSource3f = GPA("alGetSource3f");
|
||||
qalGetSourcefv = GPA("alGetSourcefv");
|
||||
qalGetSourcei = GPA("alGetSourcei");
|
||||
qalGetSourceiv = GPA("alGetSourceiv");
|
||||
qalSourcePlayv = GPA("alSourcePlayv");
|
||||
qalSourceStopv = GPA("alSourceStopv");
|
||||
qalSourceRewindv = GPA("alSourceRewindv");
|
||||
@@ -199,6 +202,7 @@ qboolean QAL_Init(const char *libname)
|
||||
qalIsBuffer = GPA("alIsBuffer");
|
||||
qalBufferData = GPA("alBufferData");
|
||||
qalGetBufferf = GPA("alGetBufferf");
|
||||
qalGetBufferfv = GPA("alGetBufferfv");
|
||||
qalGetBufferi = GPA("alGetBufferi");
|
||||
qalDopplerFactor = GPA("alDopplerFactor");
|
||||
qalSpeedOfSound = GPA("alSpeedOfSound");
|
||||
@@ -283,6 +287,7 @@ void QAL_Shutdown( void )
|
||||
qalGetSource3f = NULL;
|
||||
qalGetSourcefv = NULL;
|
||||
qalGetSourcei = NULL;
|
||||
qalGetSourceiv = NULL;
|
||||
qalSourcePlayv = NULL;
|
||||
qalSourceStopv = NULL;
|
||||
qalSourceRewindv = NULL;
|
||||
@@ -298,6 +303,7 @@ void QAL_Shutdown( void )
|
||||
qalIsBuffer = NULL;
|
||||
qalBufferData = NULL;
|
||||
qalGetBufferf = NULL;
|
||||
qalGetBufferfv = NULL;
|
||||
qalGetBufferi = NULL;
|
||||
qalDopplerFactor = NULL;
|
||||
qalSpeedOfSound = NULL;
|
||||
|
||||
@@ -55,6 +55,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENAL_DLOPEN
|
||||
extern LPALENABLE qalEnable;
|
||||
extern LPALDISABLE qalDisable;
|
||||
@@ -248,4 +252,8 @@ extern LPALCCAPTURESAMPLES qalcCaptureSamples;
|
||||
qboolean QAL_Init(const char *libname);
|
||||
void QAL_Shutdown( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __QAL_H__
|
||||
@@ -27,6 +27,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct snd_info_s
|
||||
{
|
||||
int rate;
|
||||
@@ -113,4 +117,8 @@ void S_OggOpus_CodecCloseStream(snd_stream_t *stream);
|
||||
int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
|
||||
#endif // USE_CODEC_OPUS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !_SND_CODEC_H_
|
||||
@@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "snd_codec.h"
|
||||
|
||||
// includes for the MP3 codec
|
||||
#include "../libmad-0.15.1b/synth.h"
|
||||
#include "mad.h"
|
||||
|
||||
#define MP3_SAMPLE_WIDTH 2
|
||||
#define MP3_PCMSAMPLES_PERSLICE 32
|
||||
|
||||
+13
-3
@@ -785,7 +785,11 @@ void S_Base_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t ve
|
||||
}
|
||||
|
||||
if ( !sfx->soundLength ) {
|
||||
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
|
||||
// Fixed in OPM
|
||||
// Why should it crash???
|
||||
//Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
|
||||
Com_Printf( "%s has length 0\n", sfx->soundName );
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy( origin, loopSounds[entityNum].origin );
|
||||
@@ -848,7 +852,11 @@ void S_Base_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_
|
||||
}
|
||||
|
||||
if ( !sfx->soundLength ) {
|
||||
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
|
||||
// Fixed in OPM
|
||||
// Why should it crash???
|
||||
//Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
|
||||
Com_Printf( "%s has length 0", sfx->soundName );
|
||||
return;
|
||||
}
|
||||
VectorCopy( origin, loopSounds[entityNum].origin );
|
||||
VectorCopy( velocity, loopSounds[entityNum].velocity );
|
||||
@@ -1581,7 +1589,9 @@ qboolean S_Base_Init( soundInterface_t *si ) {
|
||||
|
||||
if ( r ) {
|
||||
s_soundStarted = 1;
|
||||
s_soundMuted = 1;
|
||||
// Fixed in OPM
|
||||
// The UI must be able to play sounds
|
||||
// s_soundMuted = 1;
|
||||
// s_numSfx = 0;
|
||||
|
||||
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
|
||||
|
||||
@@ -0,0 +1,816 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "snd_local.h"
|
||||
#include "snd_openal_new.h"
|
||||
#include "client.h"
|
||||
#include "cl_ui.h"
|
||||
|
||||
typedef struct {
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
sfx_t *sfx;
|
||||
int mergeFrame;
|
||||
} loopSound_t;
|
||||
|
||||
qboolean s_bLastInitSound = qfalse;
|
||||
qboolean s_bSoundStarted = qfalse;
|
||||
qboolean s_bSoundPaused = qfalse;
|
||||
qboolean s_bTryUnpause = qfalse;
|
||||
int s_iListenerNumber = 0;
|
||||
float s_fAmbientVolume = 1.f;
|
||||
|
||||
int number_of_sfx_infos = 0;
|
||||
|
||||
cvar_t *s_volume;
|
||||
cvar_t *s_loadas8bit;
|
||||
cvar_t *s_khz;
|
||||
cvar_t *s_show;
|
||||
cvar_t *s_testsound;
|
||||
cvar_t *s_separation;
|
||||
cvar_t *s_musicVolume;
|
||||
cvar_t *s_ambientVolume;
|
||||
|
||||
sfx_info_t sfx_infos[MAX_SFX_INFOS];
|
||||
|
||||
sfx_t s_knownSfx[MAX_SFX];
|
||||
int s_numSfx;
|
||||
|
||||
s_entity_t s_entity[MAX_GENTITIES];
|
||||
|
||||
static int s_registrationSequence;
|
||||
static qboolean s_inRegistration;
|
||||
|
||||
cvar_t *s_mixPreStep;
|
||||
cvar_t *s_dialogscale;
|
||||
|
||||
int numLoopSounds;
|
||||
loopSound_t loopSounds[MAX_LOOP_SOUNDS];
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SoundInfo_f
|
||||
==============
|
||||
*/
|
||||
void S_SoundInfo_f()
|
||||
{
|
||||
S_PrintInfo();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SoundDump_f
|
||||
==============
|
||||
*/
|
||||
void S_SoundDump_f()
|
||||
{
|
||||
S_DumpInfo();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_Init
|
||||
==============
|
||||
*/
|
||||
void S_Init(qboolean full_startup)
|
||||
{
|
||||
int iStart, iEnd;
|
||||
cvar_t *cv;
|
||||
|
||||
Com_Printf("------- Sound Initialization (%s) -------\n", full_startup ? "full" : "partial");
|
||||
|
||||
iStart = Sys_Milliseconds();
|
||||
|
||||
s_volume = Cvar_Get("s_volume", "0.9", CVAR_ARCHIVE);
|
||||
s_musicVolume = Cvar_Get("s_musicvolume", "0.9", CVAR_ARCHIVE);
|
||||
s_ambientVolume = Cvar_Get("s_ambientvolume", "1.00", CVAR_ARCHIVE);
|
||||
s_separation = Cvar_Get("s_separation", "0.5", CVAR_ARCHIVE);
|
||||
s_khz = Cvar_Get("s_khz", "11", CVAR_ARCHIVE | CVAR_SOUND_LATCH);
|
||||
s_loadas8bit = Cvar_Get("s_loadas8bit", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
s_mixPreStep = Cvar_Get("s_mixPreStep", "0.05", CVAR_ARCHIVE);
|
||||
s_show = Cvar_Get("s_show", "0", CVAR_CHEAT);
|
||||
s_testsound = Cvar_Get("s_testsound", "0", CVAR_CHEAT);
|
||||
s_dialogscale = Cvar_Get("s_dialogscale", "1", CVAR_ARCHIVE);
|
||||
s_bLastInitSound = false;
|
||||
|
||||
cv = Cvar_Get("s_initsound", "1", 0);
|
||||
|
||||
if (cv->integer) {
|
||||
Cmd_AddCommand("play", S_Play);
|
||||
Cmd_AddCommand("soundlist", S_SoundList);
|
||||
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
||||
Cmd_AddCommand("sounddump", S_SoundDump_f);
|
||||
|
||||
if (S_Driver_Init()) {
|
||||
s_bLastInitSound = true;
|
||||
s_bSoundStarted = true;
|
||||
|
||||
if (full_startup) {
|
||||
s_numSfx = 0;
|
||||
S_StopAllSounds(true);
|
||||
}
|
||||
|
||||
S_FindName("***DEFAULT***", -1);
|
||||
S_SoundInfo_f();
|
||||
}
|
||||
} else {
|
||||
Com_Printf("Sound Not Initializing.\n");
|
||||
s_bSoundStarted = 0;
|
||||
}
|
||||
|
||||
iEnd = Sys_Milliseconds();
|
||||
Com_Printf("------- Sound Initialization Complete ------- %i ms\n", iEnd - iStart);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_Shutdown
|
||||
==============
|
||||
*/
|
||||
void S_Shutdown(qboolean full_shutdown)
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("------- Sound Shutdown (%s) -------\n", full_shutdown ? "full" : "partial");
|
||||
|
||||
S_Driver_Shutdown();
|
||||
s_bSoundStarted = false;
|
||||
|
||||
Cmd_RemoveCommand("play");
|
||||
Cmd_RemoveCommand("music");
|
||||
Cmd_RemoveCommand("stopsound");
|
||||
Cmd_RemoveCommand("soundlist");
|
||||
Cmd_RemoveCommand("soundinfo");
|
||||
|
||||
if (full_shutdown) {
|
||||
for (i = 0; i < s_numSfx; i++) {
|
||||
sfx = &s_knownSfx[i];
|
||||
|
||||
if (sfx->name[0]) {
|
||||
if (sfx->data) {
|
||||
Z_Free(sfx->data);
|
||||
}
|
||||
|
||||
*sfx = {};
|
||||
}
|
||||
}
|
||||
|
||||
s_numSfx = 0;
|
||||
}
|
||||
|
||||
Com_Printf("------- Sound Shutdown Complete -------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_NameExists
|
||||
==============
|
||||
*/
|
||||
qboolean S_NameExists(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strlen(name) >= MAX_RES_NAME) {
|
||||
Com_DPrintf("Sound name too long: %s", name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
for (i = 0; i < s_numSfx; i++) {
|
||||
if (!strcmp(s_knownSfx[i].name, name)) {
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_FindName
|
||||
==============
|
||||
*/
|
||||
sfx_t *S_FindName(const char *name, int sequenceNumber)
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
|
||||
if (!name) {
|
||||
Com_DPrintf("S_FindName: NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!name[0]) {
|
||||
Com_DPrintf("S_FindName: empty name\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strlen(name) >= MAX_RES_NAME) {
|
||||
Com_DPrintf("Sound name too long: %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < s_numSfx; i++) {
|
||||
sfx = &s_knownSfx[i];
|
||||
|
||||
if (!strcmp(sfx->name, name)) {
|
||||
if (sfx->registration_sequence != -1) {
|
||||
sfx->registration_sequence = sequenceNumber;
|
||||
}
|
||||
|
||||
return sfx;
|
||||
}
|
||||
}
|
||||
|
||||
sfx = &s_knownSfx[0];
|
||||
|
||||
for (i = 0; i < s_numSfx; i++) {
|
||||
sfx = &s_knownSfx[i];
|
||||
if (!sfx->name[0]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == s_numSfx) {
|
||||
if (i == MAX_SFX) {
|
||||
Com_Error(ERR_FATAL, "S_FindName: out of sfx_t");
|
||||
}
|
||||
|
||||
sfx = &s_knownSfx[s_numSfx];
|
||||
s_numSfx++;
|
||||
}
|
||||
|
||||
*sfx = {};
|
||||
// Fixed in OPM
|
||||
// strcpy was used before
|
||||
//strcpy(sfx->name, name);
|
||||
Q_strncpyz(sfx->name, name, sizeof(sfx->name));
|
||||
sfx->registration_sequence = sequenceNumber;
|
||||
|
||||
return sfx;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_BeginRegistration
|
||||
==============
|
||||
*/
|
||||
void S_BeginRegistration()
|
||||
{
|
||||
Com_Printf("------- Sound Begin Registration -------\n");
|
||||
|
||||
S_StopAllSounds(true);
|
||||
|
||||
++s_registrationSequence;
|
||||
s_inRegistration = true;
|
||||
s_knownSfx[0].registration_sequence = s_registrationSequence;
|
||||
|
||||
Com_Printf("------- Sound Begin Registration Complete -------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_DefaultSound
|
||||
==============
|
||||
*/
|
||||
void S_DefaultSound(sfx_t *sfx)
|
||||
{
|
||||
sfx->data = NULL;
|
||||
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_IsSoundRegistered
|
||||
==============
|
||||
*/
|
||||
qboolean S_IsSoundRegistered(const char *name)
|
||||
{
|
||||
char szCacheName[MAX_QPATH];
|
||||
int i;
|
||||
|
||||
if (!s_bSoundStarted) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
for (i = 0; name[i] && i < MAX_QPATH; i++) {
|
||||
szCacheName[i] = tolower(name[i]);
|
||||
}
|
||||
szCacheName[i] = 0;
|
||||
|
||||
if (i >= MAX_QPATH) {
|
||||
Com_Printf("Sound name exceeds MAX_QPATH\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
return S_NameExists(szCacheName);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_RegisterSound
|
||||
==============
|
||||
*/
|
||||
sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load)
|
||||
{
|
||||
char szCacheName[MAX_QPATH];
|
||||
sfx_t *sfx;
|
||||
int i;
|
||||
|
||||
if (!s_bSoundStarted) {
|
||||
Com_Printf("ERROR: Trying to register sound %s when soundsystem hasn't started.\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; name[i] && i < MAX_QPATH; i++) {
|
||||
szCacheName[i] = tolower(name[i]);
|
||||
}
|
||||
szCacheName[i] = 0;
|
||||
|
||||
if (i >= MAX_QPATH) {
|
||||
Com_Printf("Sound name exceeds MAX_QPATH\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sfx = S_FindName(szCacheName, s_registrationSequence);
|
||||
if (!sfx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sfx->data) {
|
||||
if (!S_LoadSound(sfx->name, sfx, streamed, force_load)) {
|
||||
Com_DPrintf("Couldn't load sound: %s\n", sfx->name);
|
||||
if (!S_LoadSound("sound/default.wav", sfx, streamed, 0)) {
|
||||
Com_DPrintf("Couldn't load sound: sound/default.wav\n");
|
||||
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sfx->iFlags &= ~SFX_FLAG_DEFAULT_SOUND;
|
||||
sfx->sfx_info_index = 0;
|
||||
|
||||
for (i = 0; i < number_of_sfx_infos; i++) {
|
||||
if (!Q_stricmp(sfx->name, sfx_infos[i].name)) {
|
||||
sfx->sfx_info_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sfx - s_knownSfx;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetSoundTime
|
||||
==============
|
||||
*/
|
||||
float S_GetSoundTime(sfxHandle_t handle)
|
||||
{
|
||||
return s_knownSfx[handle].time_length;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_EndRegistration
|
||||
==============
|
||||
*/
|
||||
void S_EndRegistration()
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
|
||||
Com_Printf("------- Sound End Registration -------\n");
|
||||
s_inRegistration = qfalse;
|
||||
|
||||
for (i = 0; i < s_numSfx; i++) {
|
||||
sfx = &s_knownSfx[i];
|
||||
|
||||
if (!sfx->name[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sfx->registration_sequence && sfx->registration_sequence != s_registrationSequence) {
|
||||
if (sfx->data) {
|
||||
Z_Free(sfx->data);
|
||||
}
|
||||
|
||||
*sfx = {};
|
||||
}
|
||||
}
|
||||
|
||||
Com_Printf("------- Sound End Registration Complete -------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_UpdateEntity
|
||||
==============
|
||||
*/
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener)
|
||||
{
|
||||
if (entityNum > MAX_GENTITIES) {
|
||||
Com_Error(ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum);
|
||||
}
|
||||
|
||||
VectorCopy(origin, s_entity[entityNum].position);
|
||||
VectorCopy(vel, s_entity[entityNum].velocity);
|
||||
s_entity[entityNum].use_listener = use_listener;
|
||||
s_entity[entityNum].time = cl.serverTime;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SetGlobalAmbientVolumeLevel
|
||||
==============
|
||||
*/
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume)
|
||||
{
|
||||
s_fAmbientVolume = volume;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StartSound
|
||||
==============
|
||||
*/
|
||||
void S_StartSound(
|
||||
const vec3_t origin,
|
||||
int entnum,
|
||||
int entchannel,
|
||||
sfxHandle_t sfxHandle,
|
||||
float volume,
|
||||
float min_dist,
|
||||
float pitch,
|
||||
float maxDist,
|
||||
int streamed
|
||||
)
|
||||
{
|
||||
if (s_show_sounds->integer > 0 && sfxHandle > 0 && sfxHandle < s_numSfx) {
|
||||
Com_DPrintf("S_StartSound: %s\n", s_knownSfx[sfxHandle].name);
|
||||
}
|
||||
|
||||
if (!s_bSoundStarted) {
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("^~^~^ sound system not yet started\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (server_loading) {
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("^~^~^ cannot start sounds while loading a server\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
|
||||
Com_Error(ERR_DROP, "S_StartSound: handle %i out of range", sfxHandle);
|
||||
}
|
||||
|
||||
if (!sfxHandle) {
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("^~^~^ null handle\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (entnum && (entchannel == CHAN_DIALOG || entchannel == CHAN_DIALOG_SECONDARY) && s_dialogscale->value > 0) {
|
||||
volume *= s_dialogscale->value;
|
||||
}
|
||||
|
||||
S_Driver_StartSound(origin, entnum, entchannel, sfxHandle, volume, min_dist, pitch, maxDist, streamed);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StartLocalSound
|
||||
==============
|
||||
*/
|
||||
void S_StartLocalSound(const char *sound_name, qboolean force_load)
|
||||
{
|
||||
sfxHandle_t sfxHandle;
|
||||
const char *name;
|
||||
AliasListNode_t *pSoundAlias = NULL;
|
||||
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sound_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = Alias_FindRandom(sound_name, &pSoundAlias);
|
||||
if (!name) {
|
||||
name = sound_name;
|
||||
}
|
||||
|
||||
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
|
||||
|
||||
if (!pSoundAlias) {
|
||||
S_StartSound(NULL, s_iListenerNumber, CHAN_MENU, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
|
||||
return;
|
||||
}
|
||||
|
||||
S_StartSound(
|
||||
0,
|
||||
s_iListenerNumber,
|
||||
CHAN_MENU,
|
||||
sfxHandle,
|
||||
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
|
||||
-1.0,
|
||||
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
|
||||
pSoundAlias->maxDist,
|
||||
pSoundAlias->streamed
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StartLocalSoundChannel
|
||||
|
||||
Added in 2.0
|
||||
Starts a local sound, with the specified channel
|
||||
==============
|
||||
*/
|
||||
void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel)
|
||||
{
|
||||
sfxHandle_t sfxHandle;
|
||||
const char *name;
|
||||
AliasListNode_t *pSoundAlias = NULL;
|
||||
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sound_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = Alias_FindRandom(sound_name, &pSoundAlias);
|
||||
if (!name) {
|
||||
name = sound_name;
|
||||
}
|
||||
|
||||
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
|
||||
|
||||
if (!pSoundAlias) {
|
||||
S_StartSound(NULL, s_iListenerNumber, channel, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
|
||||
return;
|
||||
}
|
||||
|
||||
S_StartSound(
|
||||
0,
|
||||
s_iListenerNumber,
|
||||
channel,
|
||||
sfxHandle,
|
||||
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
|
||||
-1.0,
|
||||
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
|
||||
pSoundAlias->maxDist,
|
||||
pSoundAlias->streamed
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StopAllSounds
|
||||
==============
|
||||
*/
|
||||
void S_StopAllSounds(qboolean stop_music)
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("------- S_StopAllSounds (%s) -------\n", stop_music ? "stop music" : "don't stop music");
|
||||
|
||||
// Tell the driver to stop all sounds
|
||||
S_Driver_StopAllSounds(stop_music);
|
||||
|
||||
Com_Printf("------- S_StopAllSounds Complete-------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_ClearLoopingSounds
|
||||
==============
|
||||
*/
|
||||
void S_ClearLoopingSounds()
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_Driver_ClearLoopingSounds();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_AddLoopingSound
|
||||
==============
|
||||
*/
|
||||
void S_AddLoopingSound(
|
||||
const vec3_t origin,
|
||||
const vec3_t velocity,
|
||||
sfxHandle_t sfxHandle,
|
||||
float volume,
|
||||
float min_dist,
|
||||
float max_dist,
|
||||
float pitch,
|
||||
int flags
|
||||
)
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
|
||||
Com_Error(ERR_DROP, "S_AddLoopingSound: handle %i out of range", sfxHandle);
|
||||
}
|
||||
|
||||
if (!sfxHandle) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_Driver_AddLoopingSound(origin, velocity, sfxHandle, volume, min_dist, max_dist, pitch, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_Respatialize
|
||||
==============
|
||||
*/
|
||||
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3])
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_Driver_Respatialize(entityNum, head, axis);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_Update
|
||||
==============
|
||||
*/
|
||||
void S_Update()
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (server_loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_Driver_Update();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StopSound
|
||||
==============
|
||||
*/
|
||||
void S_StopSound(int entnum, int channel)
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (channel == CHAN_AUTO) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_Driver_StopSound(entnum, channel);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SetReverb
|
||||
==============
|
||||
*/
|
||||
void S_SetReverb(int reverb_type, float reverb_level)
|
||||
{
|
||||
if (!s_bSoundStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_Driver_SetReverb(reverb_type, reverb_level);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_Play
|
||||
==============
|
||||
*/
|
||||
void S_Play()
|
||||
{
|
||||
int i;
|
||||
char name[MAX_QPATH];
|
||||
|
||||
for (i = 1; i < Cmd_Argc(); i++) {
|
||||
if (strrchr(Cmd_Argv(i), '.')) {
|
||||
Q_strncpyz(name, Cmd_Argv(i), sizeof(name));
|
||||
} else {
|
||||
Com_sprintf(name, sizeof(name), "%s.wav", Cmd_Argv(1));
|
||||
}
|
||||
}
|
||||
|
||||
S_StartLocalSound(name, qfalse);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SoundList
|
||||
==============
|
||||
*/
|
||||
void S_SoundList()
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
int size;
|
||||
int total = 0;
|
||||
|
||||
for (i = 0; i < s_numSfx; i++) {
|
||||
sfx = &s_knownSfx[i];
|
||||
|
||||
if (sfx->registration_sequence) {
|
||||
size = sfx->length * sfx->width;
|
||||
total += size;
|
||||
Com_Printf("(%2db) %6i : %s\n", sfx->width * 8, size, sfx->name);
|
||||
}
|
||||
}
|
||||
|
||||
Com_Printf("Total resident: %i\n", total);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_ClearSoundBuffer
|
||||
==============
|
||||
*/
|
||||
void S_ClearSoundBuffer()
|
||||
{
|
||||
// TODO: Remove once AL is fully implemented
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetMusicFilename
|
||||
==============
|
||||
*/
|
||||
const char* S_GetMusicFilename()
|
||||
{
|
||||
return S_Driver_GetMusicFilename();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetMusicLoopCount
|
||||
==============
|
||||
*/
|
||||
int S_GetMusicLoopCount()
|
||||
{
|
||||
return S_Driver_GetMusicLoopCount();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_GetMusicOffset
|
||||
==============
|
||||
*/
|
||||
unsigned int S_GetMusicOffset()
|
||||
{
|
||||
return S_Driver_GetMusicOffset();
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "snd_local.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
|
||||
void load_sfx_info()
|
||||
{
|
||||
TikiScript tiki;
|
||||
const char *token;
|
||||
int current_sound_file;
|
||||
char file_name[MAX_QPATH];
|
||||
|
||||
sfx_infos[0].name[0] = 0;
|
||||
sfx_infos[0].max_factor = -1.0;
|
||||
sfx_infos[0].loop_start = -1;
|
||||
sfx_infos[0].loop_end = -1;
|
||||
sfx_infos[0].max_number_playing = 5;
|
||||
number_of_sfx_infos = 1;
|
||||
|
||||
for (current_sound_file = 0; current_sound_file < 10; current_sound_file++) {
|
||||
Com_sprintf(file_name, sizeof(file_name), "global/sound%d.txt", current_sound_file);
|
||||
|
||||
if (!tiki.LoadFile(file_name, qtrue)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Com_Printf("Loading %s\n", file_name);
|
||||
|
||||
while (tiki.TokenAvailable(qtrue)) {
|
||||
token = tiki.GetToken(qtrue);
|
||||
|
||||
if (!Q_stricmp(token, "sound")) {
|
||||
if (tiki.TokenAvailable(qtrue)) {
|
||||
token = tiki.GetToken(qtrue);
|
||||
|
||||
if (number_of_sfx_infos == 1000) {
|
||||
Com_DPrintf("Too many sound infos specified\n");
|
||||
break;
|
||||
}
|
||||
|
||||
Q_strncpyz(sfx_infos[number_of_sfx_infos].name, token, sizeof(sfx_infos[number_of_sfx_infos].name));
|
||||
sfx_infos[number_of_sfx_infos].max_factor = -1.f;
|
||||
sfx_infos[number_of_sfx_infos].loop_start = -1;
|
||||
sfx_infos[number_of_sfx_infos].loop_end = -1;
|
||||
sfx_infos[number_of_sfx_infos].max_number_playing = 5;
|
||||
number_of_sfx_infos++;
|
||||
}
|
||||
} else if (!Q_stricmp(token, "loopstart")) {
|
||||
if (!tiki.TokenAvailable(qtrue)) {
|
||||
token = tiki.GetToken(qtrue);
|
||||
sfx_infos[number_of_sfx_infos - 1].loop_start = atoi(token);
|
||||
}
|
||||
} else if (!Q_stricmp(token, "loopend")) {
|
||||
if (!tiki.TokenAvailable(qtrue)) {
|
||||
token = tiki.GetToken(qtrue);
|
||||
sfx_infos[number_of_sfx_infos - 1].loop_end = atoi(token);
|
||||
}
|
||||
} else if (!Q_stricmp(token, "maxnumber")) {
|
||||
if (!tiki.TokenAvailable(qtrue)) {
|
||||
token = tiki.GetToken(qtrue);
|
||||
sfx_infos[number_of_sfx_infos - 1].max_number_playing = atoi(token);
|
||||
}
|
||||
} else if (!Q_stricmp(token, "maxfactor")) {
|
||||
if (!tiki.TokenAvailable(qtrue)) {
|
||||
token = tiki.GetToken(qtrue);
|
||||
sfx_infos[number_of_sfx_infos - 1].max_factor = atoi(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tiki.Close();
|
||||
|
||||
sfx_infos[0].name[0] = 0;
|
||||
}
|
||||
@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "snd_public.h"
|
||||
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
|
||||
#define PAINTBUFFER_SIZE 4096 // this is in samples
|
||||
|
||||
#define SND_CHUNK_SIZE 1024 // samples
|
||||
@@ -281,3 +283,7 @@ void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
# include "snd_local_new.h"
|
||||
#endif
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern cvar_t *s_volume;
|
||||
extern cvar_t *s_khz;
|
||||
extern cvar_t *s_loadas8bit;
|
||||
extern cvar_t *s_separation;
|
||||
extern cvar_t *s_musicVolume;
|
||||
extern cvar_t *s_ambientVolume;
|
||||
|
||||
typedef struct {
|
||||
int format;
|
||||
float rate;
|
||||
|
||||
float width;
|
||||
int channels;
|
||||
int samples;
|
||||
|
||||
int dataofs;
|
||||
int datasize;
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct sfx_s {
|
||||
int iFlags;
|
||||
|
||||
int length;
|
||||
int width;
|
||||
byte *data;
|
||||
char name[64];
|
||||
|
||||
int registration_sequence;
|
||||
int sfx_info_index;
|
||||
float time_length;
|
||||
|
||||
wavinfo_t info;
|
||||
unsigned int buffer;
|
||||
} sfx_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short wFormatTag;
|
||||
unsigned short nChannels;
|
||||
unsigned int nSamplesPerSec;
|
||||
unsigned int nAvgBytesPerSec;
|
||||
unsigned short nBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
unsigned short cbSize;
|
||||
} wavinfo_x_t;
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
|
||||
int loop_start;
|
||||
int loop_end;
|
||||
|
||||
int max_number_playing;
|
||||
float max_factor;
|
||||
} sfx_info_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t position;
|
||||
vec3_t velocity;
|
||||
int time;
|
||||
qboolean use_listener;
|
||||
} s_entity_t;
|
||||
|
||||
typedef struct {
|
||||
char alias[32];
|
||||
char path[64];
|
||||
|
||||
int mood_num;
|
||||
int flags;
|
||||
float volume;
|
||||
float fadetime;
|
||||
|
||||
int current_pos;
|
||||
int current_state;
|
||||
} song_t;
|
||||
|
||||
typedef struct {
|
||||
int iFlags;
|
||||
char szName[64];
|
||||
} sfxsavegame_t;
|
||||
|
||||
typedef struct {
|
||||
qboolean bPlaying;
|
||||
int iStatus;
|
||||
sfxsavegame_t sfx;
|
||||
|
||||
int iEntNum;
|
||||
int iEntChannel;
|
||||
vec3_t vOrigin;
|
||||
float fVolume;
|
||||
int iBaseRate;
|
||||
float fNewPitchMult;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
|
||||
int iStartTime;
|
||||
int iTime;
|
||||
int iNextCheckObstructionTime;
|
||||
int iEndTime;
|
||||
|
||||
int iFlags;
|
||||
int iOffset;
|
||||
int iLoopCount;
|
||||
} channelbasesavegame_t;
|
||||
|
||||
typedef struct {
|
||||
channelbasesavegame_t Channels[96];
|
||||
} soundsystemsavegame_t;
|
||||
|
||||
enum channel_flags_t {
|
||||
CHANNEL_FLAG_PLAY_DEFERRED = 1,
|
||||
CHANNEL_FLAG_LOCAL_LISTENER = 16,
|
||||
CHANNEL_FLAG_NO_ENTITY = 32,
|
||||
CHANNEL_FLAG_PAUSED = 64,
|
||||
CHANNEL_FLAG_LOOPING = 128,
|
||||
// Added in OPM
|
||||
CHANNEL_FLAG_MISSING_ENT = 256,
|
||||
};
|
||||
|
||||
enum sfx_flags_t {
|
||||
SFX_FLAG_DEFAULT_SOUND = 1,
|
||||
SFX_FLAG_MP3 = 2,
|
||||
SFX_FLAG_STREAMED = 4,
|
||||
SFX_FLAG_NO_OFFSET = 8,
|
||||
SFX_FLAG_NULL = 16,
|
||||
};
|
||||
|
||||
enum loopsound_flags_t {
|
||||
LOOPSOUND_FLAG_NO_PAN = 1
|
||||
};
|
||||
|
||||
#define MAX_SFX 1400
|
||||
#define MAX_SFX_INFOS 1000
|
||||
#define MAX_LOOP_SOUNDS 64
|
||||
|
||||
extern qboolean s_bLastInitSound;
|
||||
extern qboolean s_bSoundStarted;
|
||||
extern qboolean s_bSoundPaused;
|
||||
extern qboolean s_bTryUnpause;
|
||||
extern int s_iListenerNumber;
|
||||
extern float s_fAmbientVolume;
|
||||
extern int number_of_sfx_infos;
|
||||
extern sfx_info_t sfx_infos[];
|
||||
extern sfx_t s_knownSfx[];
|
||||
extern int s_numSfx;
|
||||
extern s_entity_t s_entity[];
|
||||
|
||||
// The current sound driver.
|
||||
// Currently OPENAL
|
||||
#define SOUND_DRIVER OPENAL
|
||||
|
||||
//
|
||||
// snd_info.cpp
|
||||
//
|
||||
void load_sfx_info();
|
||||
|
||||
//
|
||||
// snd_dma_new.cpp
|
||||
//
|
||||
|
||||
sfx_t *S_FindName(const char *name, int sequenceNumber);
|
||||
void S_DefaultSound(sfx_t *sfx);
|
||||
|
||||
void S_LoadData(soundsystemsavegame_t *pSave);
|
||||
void S_SaveData(soundsystemsavegame_t *pSave);
|
||||
void S_ClearSoundBuffer();
|
||||
|
||||
//
|
||||
// snd_mem.c
|
||||
//
|
||||
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load);
|
||||
|
||||
#define S_StopAllSounds2 S_StopAllSounds
|
||||
|
||||
//
|
||||
// Driver-specific functions
|
||||
//
|
||||
#define S_Call_SndDriver(driver, func) S_##driver##_##func
|
||||
#define S_Call_SndDriverX(driver, func) S_Call_SndDriver(driver, func)
|
||||
|
||||
#define S_Driver_Init S_Call_SndDriverX(SOUND_DRIVER, Init)
|
||||
#define S_Driver_Shutdown S_Call_SndDriverX(SOUND_DRIVER, Shutdown)
|
||||
#define S_Driver_StartSound S_Call_SndDriverX(SOUND_DRIVER, StartSound)
|
||||
#define S_Driver_AddLoopingSound S_Call_SndDriverX(SOUND_DRIVER, AddLoopingSound)
|
||||
#define S_Driver_ClearLoopingSounds S_Call_SndDriverX(SOUND_DRIVER, ClearLoopingSounds)
|
||||
#define S_Driver_StopSound S_Call_SndDriverX(SOUND_DRIVER, StopSound)
|
||||
#define S_Driver_StopAllSounds S_Call_SndDriverX(SOUND_DRIVER, StopAllSounds)
|
||||
#define S_Driver_Respatialize S_Call_SndDriverX(SOUND_DRIVER, Respatialize)
|
||||
#define S_Driver_SetReverb S_Call_SndDriverX(SOUND_DRIVER, SetReverb)
|
||||
#define S_Driver_Update S_Call_SndDriverX(SOUND_DRIVER, Update)
|
||||
#define S_Driver_GetMusicFilename S_Call_SndDriverX(SOUND_DRIVER, GetMusicFilename)
|
||||
#define S_Driver_GetMusicLoopCount S_Call_SndDriverX(SOUND_DRIVER, GetMusicLoopCount)
|
||||
#define S_Driver_GetMusicOffset S_Call_SndDriverX(SOUND_DRIVER, GetMusicOffset)
|
||||
|
||||
void S_PrintInfo();
|
||||
void S_DumpInfo();
|
||||
qboolean S_NeedFullRestart();
|
||||
void S_ReLoad(soundsystemsavegame_t* pSave);
|
||||
|
||||
extern cvar_t *s_show_sounds;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "snd_local.h"
|
||||
#include "cl_ui.h"
|
||||
|
||||
byte *data_p;
|
||||
byte *iff_end;
|
||||
byte *last_chunk;
|
||||
byte *iff_data;
|
||||
int iff_chunk_len;
|
||||
|
||||
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx);
|
||||
|
||||
/*
|
||||
==============
|
||||
GetLittleShort
|
||||
==============
|
||||
*/
|
||||
short int GetLittleShort()
|
||||
{
|
||||
union {
|
||||
short value;
|
||||
byte bytes[2];
|
||||
} val;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
val.bytes[0] = data_p[0];
|
||||
val.bytes[1] = data_p[1];
|
||||
# else
|
||||
val.bytes[0] = data_p[1];
|
||||
val.bytes[1] = data_p[0];
|
||||
# endif
|
||||
|
||||
data_p += sizeof(short);
|
||||
return val.value;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
GetLittleLong
|
||||
==============
|
||||
*/
|
||||
int GetLittleLong()
|
||||
{
|
||||
union {
|
||||
int value;
|
||||
byte bytes[4];
|
||||
} val;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
val.bytes[0] = data_p[0];
|
||||
val.bytes[1] = data_p[1];
|
||||
val.bytes[2] = data_p[2];
|
||||
val.bytes[3] = data_p[3];
|
||||
# else
|
||||
val.bytes[0] = data_p[3];
|
||||
val.bytes[1] = data_p[2];
|
||||
val.bytes[2] = data_p[1];
|
||||
val.bytes[3] = data_p[0];
|
||||
# endif
|
||||
|
||||
data_p += sizeof(int);
|
||||
return val.value;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SetLittleShort
|
||||
==============
|
||||
*/
|
||||
void SetLittleShort(int i)
|
||||
{
|
||||
union {
|
||||
short value;
|
||||
byte bytes[2];
|
||||
} val;
|
||||
|
||||
val.value = i;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
data_p[0] = val.bytes[0];
|
||||
data_p[1] = val.bytes[1];
|
||||
# else
|
||||
data_p[0] = val.bytes[1];
|
||||
data_p[1] = val.bytes[0];
|
||||
# endif
|
||||
|
||||
data_p += sizeof(short);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SetLittleLong
|
||||
==============
|
||||
*/
|
||||
void SetLittleLong(int i)
|
||||
{
|
||||
union {
|
||||
int value;
|
||||
byte bytes[4];
|
||||
} val;
|
||||
|
||||
val.value = i;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
data_p[0] = val.bytes[0];
|
||||
data_p[1] = val.bytes[1];
|
||||
data_p[2] = val.bytes[2];
|
||||
data_p[3] = val.bytes[3];
|
||||
# else
|
||||
data_p[0] = val.bytes[3];
|
||||
data_p[1] = val.bytes[2];
|
||||
data_p[2] = val.bytes[1];
|
||||
data_p[3] = val.bytes[0];
|
||||
# endif
|
||||
|
||||
data_p += sizeof(int);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
FindNextChunk
|
||||
==============
|
||||
*/
|
||||
void FindNextChunk(const char *name)
|
||||
{
|
||||
int value;
|
||||
|
||||
while (1) {
|
||||
data_p = last_chunk;
|
||||
|
||||
if (last_chunk >= (byte *)iff_end) {
|
||||
break;
|
||||
}
|
||||
|
||||
data_p = last_chunk + 4;
|
||||
value = GetLittleLong();
|
||||
|
||||
iff_chunk_len = value;
|
||||
if (value < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
data_p -= 8;
|
||||
value++;
|
||||
value &= ~1;
|
||||
|
||||
last_chunk = data_p + value + 8;
|
||||
if (!strncmp((const char *)data_p, name, 4u)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
data_p = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
FindChunk
|
||||
==============
|
||||
*/
|
||||
void FindChunk(const char *name)
|
||||
{
|
||||
last_chunk = iff_data;
|
||||
FindNextChunk(name);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
DumpChunks
|
||||
==============
|
||||
*/
|
||||
void DumpChunks()
|
||||
{
|
||||
char str[5];
|
||||
|
||||
str[4] = 0;
|
||||
|
||||
data_p = iff_data;
|
||||
do {
|
||||
memcpy(str, data_p, 4);
|
||||
data_p += 4;
|
||||
|
||||
iff_chunk_len = GetLittleLong();
|
||||
|
||||
Com_Printf("0x%x : %s (%d)\n", data_p - 4, str, iff_chunk_len);
|
||||
|
||||
data_p += (iff_chunk_len + 1) & ~1;
|
||||
} while (data_p < (byte *)iff_end);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
GetWavinfo
|
||||
==============
|
||||
*/
|
||||
wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
||||
{
|
||||
wavinfo_t info;
|
||||
int samples;
|
||||
|
||||
memset(&info, 0, sizeof(wavinfo_t));
|
||||
|
||||
if (!wav) {
|
||||
return info;
|
||||
}
|
||||
|
||||
iff_data = wav;
|
||||
iff_end = &wav[wavlength];
|
||||
FindChunk("RIFF");
|
||||
|
||||
if (!data_p || strncmp((const char *)data_p + 8, "WAVE", 4u)) {
|
||||
Com_Printf("Missing RIFF/WAVE chunks\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
iff_data = data_p + 12;
|
||||
FindChunk("fmt ");
|
||||
if (!data_p) {
|
||||
Com_Printf("Missing fmt chunk\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
data_p += 8;
|
||||
|
||||
info.format = GetLittleShort();
|
||||
if (info.format == 17) {
|
||||
info.channels = GetLittleShort();
|
||||
info.rate = (float)GetLittleLong();
|
||||
data_p += 6;
|
||||
info.width = (float)GetLittleShort() / 8.f;
|
||||
data_p += 2;
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p) {
|
||||
Com_Printf("Missing data chunk\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
data_p += 4;
|
||||
if (info.width >= 1.0) {
|
||||
samples = (int)((float)GetLittleLong() / info.width);
|
||||
} else {
|
||||
samples = (int)((float)GetLittleLong() * info.width);
|
||||
}
|
||||
|
||||
if (!info.samples) {
|
||||
info.samples = samples;
|
||||
} else if (samples < info.samples) {
|
||||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
|
||||
info.dataofs = 0;
|
||||
} else if (info.format == 1) {
|
||||
info.channels = GetLittleShort();
|
||||
info.rate = (float)GetLittleLong();
|
||||
data_p += 6;
|
||||
info.width = (float)(GetLittleShort() / 8);
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p) {
|
||||
Com_Printf("Missing data chunk\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
data_p += 4;
|
||||
samples = (float)GetLittleLong() / info.width;
|
||||
|
||||
if (!info.samples) {
|
||||
info.samples = samples;
|
||||
} else if (samples < info.samples) {
|
||||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
|
||||
info.dataofs = data_p - wav;
|
||||
} else {
|
||||
Com_Printf("Microsoft PCM format only\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
info.datasize = iff_chunk_len;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
DownSampleWav
|
||||
==============
|
||||
*/
|
||||
qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
|
||||
{
|
||||
int newdatasize;
|
||||
byte* datap;
|
||||
int i;
|
||||
int ii;
|
||||
int error;
|
||||
int width;
|
||||
int oldsamples;
|
||||
int oldrate;
|
||||
|
||||
newdatasize = 0;
|
||||
datap = &wav[info->dataofs];
|
||||
|
||||
if (info->channels > 1)
|
||||
{
|
||||
Com_DPrintf("Could not downsample WAV file. Stereo WAVs not supported!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info->format != 1 || !info->dataofs)
|
||||
{
|
||||
Com_DPrintf("Could not downsample WAV file. Not PCM format!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info->rate <= newkhz) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
width = info->width;
|
||||
for (i = 0; i < info->samples; i++) {
|
||||
error += newkhz;
|
||||
while (error > info->rate) {
|
||||
error -= info->rate;
|
||||
newdatasize += width;
|
||||
}
|
||||
}
|
||||
|
||||
oldsamples = info->samples;
|
||||
oldrate = info->rate;
|
||||
info->samples = newdatasize / width;
|
||||
info->rate = (float)newkhz;
|
||||
newdatasize += info->dataofs;
|
||||
|
||||
*newdata = (byte*)Z_TagMalloc(newdatasize, TAG_SOUND);
|
||||
memcpy(*newdata, wav, info->dataofs);
|
||||
|
||||
iff_data = *newdata;
|
||||
iff_end = *newdata + newdatasize;
|
||||
FindChunk("RIFF");
|
||||
|
||||
if (!data_p || strncmp((const char*)data_p + 8, "WAVE", 4u))
|
||||
{
|
||||
Com_DPrintf("Missing RIFF/WAVE chunks\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
iff_data = data_p + 12;
|
||||
FindChunk("fmt ");
|
||||
if (!data_p)
|
||||
{
|
||||
Com_DPrintf("Missing fmt chunk\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data_p += 12;
|
||||
SetLittleShort((int)info->rate);
|
||||
data_p += 8;
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p)
|
||||
{
|
||||
Com_DPrintf("Missing data chunk\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data_p += 4;
|
||||
SetLittleLong((int)(info->samples * info->width));
|
||||
|
||||
error = 0;
|
||||
for (i = 0; i < oldsamples; i++) {
|
||||
error += newkhz;
|
||||
while (error > oldrate) {
|
||||
error -= oldrate;
|
||||
for (ii = 0; ii < width; ii++) {
|
||||
data_p[ii] = datap[ii];
|
||||
}
|
||||
|
||||
data_p += width;
|
||||
}
|
||||
|
||||
datap += width;
|
||||
}
|
||||
|
||||
return newdatasize;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
DownSampleWav_MILES
|
||||
==============
|
||||
*/
|
||||
int DownSampleWav_MILES(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
|
||||
{
|
||||
//STUB_DESC("sound stuff");
|
||||
//return 0;
|
||||
// FIXME: unimplemented
|
||||
// Fallback to software downsampling
|
||||
return DownSampleWav(info, wav, wavlength, newkhz, newdata);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_LoadSound
|
||||
==============
|
||||
*/
|
||||
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load)
|
||||
{
|
||||
int size;
|
||||
fileHandle_t file_handle;
|
||||
char tempName[MAX_RES_NAME + 1];
|
||||
int realKhz;
|
||||
|
||||
sfx->buffer = 0;
|
||||
|
||||
if (fileName[0] == '*') {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (streamed) {
|
||||
//
|
||||
// Added in 2.0
|
||||
// Will be loaded next time
|
||||
sfx->length = 5000;
|
||||
sfx->width = 1;
|
||||
sfx->iFlags |= SFX_FLAG_STREAMED;
|
||||
sfx->time_length = 5000.0;
|
||||
sfx->data = NULL;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if (clc.state != CA_LOADING && !force_load) {
|
||||
Com_Printf("**************S_LoadSound: %s\n", fileName);
|
||||
}
|
||||
|
||||
if (strstr(fileName, ".mp3")) {
|
||||
return S_LoadMP3(fileName, sfx);
|
||||
}
|
||||
|
||||
size = FS_FOpenFileRead(fileName, &file_handle, qfalse, qtrue);
|
||||
if (size <= 0)
|
||||
{
|
||||
if (file_handle) {
|
||||
FS_FCloseFile(file_handle);
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
sfx->data = (byte*)Z_TagMalloc(size, TAG_SOUND);
|
||||
|
||||
FS_Read(sfx->data, size, file_handle);
|
||||
FS_FCloseFile(file_handle);
|
||||
sfx->info = GetWavinfo(fileName, sfx->data, size);
|
||||
|
||||
if (sfx->info.channels != 1 && !streamed)
|
||||
{
|
||||
Com_Printf("%s is a stereo wav file\n", fileName);
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = NULL;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!sfx->info.dataofs) {
|
||||
sfx->iFlags |= SFX_FLAG_NO_OFFSET;
|
||||
}
|
||||
|
||||
switch (s_khz->integer) {
|
||||
case 11:
|
||||
realKhz = 11025;
|
||||
break;
|
||||
case 22:
|
||||
default:
|
||||
realKhz = 22050;
|
||||
break;
|
||||
case 44:
|
||||
realKhz = 44100;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(sfx->iFlags & SFX_FLAG_STREAMED) && realKhz < sfx->info.rate) {
|
||||
byte* newdata;
|
||||
int newdatasize;
|
||||
|
||||
newdata = NULL;
|
||||
if (sfx->iFlags & SFX_FLAG_NO_OFFSET) {
|
||||
newdatasize = DownSampleWav_MILES(&sfx->info, sfx->data, size, realKhz, &newdata);
|
||||
} else {
|
||||
newdatasize = DownSampleWav(&sfx->info, sfx->data, size, realKhz, &newdata);
|
||||
}
|
||||
|
||||
if (newdatasize) {
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = newdata;
|
||||
}
|
||||
}
|
||||
|
||||
sfx->length = sfx->info.samples;
|
||||
sfx->width = sfx->info.width;
|
||||
sfx->time_length = sfx->info.samples / sfx->info.rate * 1000.f;
|
||||
|
||||
if (sfx->iFlags & SFX_FLAG_STREAMED) {
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = NULL;
|
||||
}
|
||||
|
||||
sprintf(tempName, "k%s", fileName);
|
||||
UI_LoadResource(tempName);
|
||||
|
||||
if (strstr(fileName, "sound/null.wav")) {
|
||||
sfx->iFlags |= SFX_FLAG_NULL;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_LoadMP3
|
||||
==============
|
||||
*/
|
||||
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
|
||||
{
|
||||
int length;
|
||||
fileHandle_t file_handle;
|
||||
|
||||
length = FS_FOpenFileRead(fileName, &file_handle, 0, 1);
|
||||
if (length <= 0) {
|
||||
if (file_handle) {
|
||||
FS_FCloseFile(file_handle);
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
memset(&sfx->info, 0, sizeof(sfx->info));
|
||||
sfx->data = (byte*)Z_TagMalloc(length, TAG_SOUND);
|
||||
sfx->length = length;
|
||||
sfx->width = 1;
|
||||
FS_Read(sfx->data, length, file_handle);
|
||||
FS_FCloseFile(file_handle);
|
||||
|
||||
sfx->iFlags |= SFX_FLAG_MP3;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// See the header file for information
|
||||
|
||||
#include "snd_miles_new.h"
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// This file exists in the original source code.
|
||||
// But this driver won't be implemented, as OpenAL is a better sound system!
|
||||
//
|
||||
|
||||
#pragma once
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code 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.
|
||||
|
||||
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qal.h"
|
||||
|
||||
#undef OPENAL
|
||||
|
||||
typedef int S32;
|
||||
typedef unsigned int U32;
|
||||
|
||||
#define MAX_OPENAL_CHANNELS_3D 32
|
||||
#define MAX_OPENAL_CHANNELS_2D 32
|
||||
#define MAX_OPENAL_CHANNELS_2D_STREAM 32
|
||||
#define MAX_OPENAL_POSITION_CHANNELS (MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM)
|
||||
#define MAX_OPENAL_SONGS 2
|
||||
#define MAX_OPENAL_MISC_CHANNELS 3
|
||||
#define MAX_OPENAL_CHANNELS \
|
||||
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS \
|
||||
+ MAX_OPENAL_MISC_CHANNELS)
|
||||
#define MAX_OPENAL_LOOP_SOUNDS 64
|
||||
|
||||
#define OPENAL_CHANNEL_MP3_ID \
|
||||
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS)
|
||||
#define OPENAL_CHANNEL_TRIGGER_MUSIC_ID (OPENAL_CHANNEL_MP3_ID + 1)
|
||||
#define OPENAL_CHANNEL_MOVIE_ID (OPENAL_CHANNEL_TRIGGER_MUSIC_ID + 1)
|
||||
|
||||
#define MAX_STREAM_BUFFERS 16
|
||||
#define MAX_BUFFER_SAMPLES 16384
|
||||
|
||||
typedef enum {
|
||||
FADE_NONE,
|
||||
FADE_IN,
|
||||
FADE_OUT
|
||||
} fade_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t vOrigin;
|
||||
vec3_t vRelativeOrigin;
|
||||
vec3_t vVelocity;
|
||||
|
||||
sfx_t *pSfx;
|
||||
qboolean bPlaying;
|
||||
|
||||
int iChannel;
|
||||
float fVolume;
|
||||
float fPitch;
|
||||
|
||||
int iStartTime;
|
||||
qboolean bInUse;
|
||||
qboolean bCombine;
|
||||
|
||||
float fBaseVolume;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
int iFlags;
|
||||
} openal_loop_sound_t;
|
||||
|
||||
struct openal_channel {
|
||||
sfx_t *pSfx;
|
||||
int iEntNum;
|
||||
int iEntChannel;
|
||||
vec3_t vOrigin;
|
||||
|
||||
float fVolume;
|
||||
int iBaseRate;
|
||||
float fNewPitchMult;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
|
||||
int iStartTime;
|
||||
int iTime;
|
||||
int iEndTime;
|
||||
int iFlags;
|
||||
int iPausedOffset;
|
||||
|
||||
int song_number;
|
||||
|
||||
fade_t fading;
|
||||
int fade_time;
|
||||
int fade_start_time;
|
||||
|
||||
ALuint source;
|
||||
ALuint buffer;
|
||||
ALubyte *bufferdata;
|
||||
|
||||
public:
|
||||
void play();
|
||||
virtual void stop();
|
||||
void pause();
|
||||
|
||||
void set_no_3d();
|
||||
void set_3d();
|
||||
|
||||
void set_gain(float gain);
|
||||
void set_velocity(float v0, float v1, float v2);
|
||||
void set_position(float v0, float v1, float v2);
|
||||
|
||||
bool is_free();
|
||||
bool is_paused();
|
||||
bool is_playing();
|
||||
|
||||
void force_free();
|
||||
virtual bool set_sfx(sfx_t *pSfx);
|
||||
|
||||
void start_sample();
|
||||
void stop_sample();
|
||||
void resume_sample();
|
||||
void end_sample();
|
||||
|
||||
void set_sample_pan(S32 pan);
|
||||
void set_sample_playback_rate(S32 pan);
|
||||
S32 sample_playback_rate();
|
||||
|
||||
S32 sample_volume();
|
||||
virtual U32 sample_offset();
|
||||
U32 sample_ms_offset();
|
||||
U32 sample_loop_count();
|
||||
virtual void set_sample_offset(U32 offset);
|
||||
void set_sample_ms_offset(U32 offset);
|
||||
virtual void set_sample_loop_count(S32 count);
|
||||
void set_sample_loop_block(S32 start_offset, S32 end_offset);
|
||||
|
||||
U32 sample_status();
|
||||
|
||||
public:
|
||||
virtual void update();
|
||||
|
||||
virtual U32 buffer_frequency() const;
|
||||
};
|
||||
|
||||
struct openal_channel_two_d_stream : public openal_channel {
|
||||
private:
|
||||
char fileName[64];
|
||||
void *streamHandle;
|
||||
unsigned int buffers[MAX_STREAM_BUFFERS];
|
||||
unsigned int currentBuf;
|
||||
unsigned int sampleLoopCount;
|
||||
unsigned int sampleLooped;
|
||||
unsigned int streamNextOffset;
|
||||
bool streaming;
|
||||
|
||||
public:
|
||||
openal_channel_two_d_stream();
|
||||
~openal_channel_two_d_stream();
|
||||
|
||||
void stop() override;
|
||||
bool set_sfx(sfx_t *pSfx) override;
|
||||
void set_sample_loop_count(S32 count) override;
|
||||
void update() override;
|
||||
U32 sample_offset() override;
|
||||
void set_sample_offset(U32 offset) override;
|
||||
|
||||
bool queue_stream(const char *fileName);
|
||||
|
||||
protected:
|
||||
U32 buffer_frequency() const override;
|
||||
|
||||
private:
|
||||
void clear_stream();
|
||||
|
||||
unsigned int getQueueLength() const;
|
||||
unsigned int getCurrentStreamPosition() const;
|
||||
unsigned int getBytesPerSample() const;
|
||||
};
|
||||
|
||||
struct openal_internal_t {
|
||||
openal_channel chan_3D[MAX_OPENAL_CHANNELS_3D];
|
||||
openal_channel chan_2D[MAX_OPENAL_CHANNELS_2D];
|
||||
openal_channel_two_d_stream chan_2D_stream[MAX_OPENAL_CHANNELS_2D_STREAM];
|
||||
openal_channel_two_d_stream chan_song[MAX_OPENAL_SONGS];
|
||||
openal_channel_two_d_stream chan_mp3;
|
||||
openal_channel_two_d_stream chan_trig_music;
|
||||
openal_channel_two_d_stream chan_movie;
|
||||
|
||||
// Pointers to channels
|
||||
openal_channel *channel[MAX_OPENAL_CHANNELS];
|
||||
|
||||
openal_loop_sound_t loop_sounds[MAX_OPENAL_LOOP_SOUNDS];
|
||||
|
||||
openal_channel movieChannel;
|
||||
sfx_t movieSFX;
|
||||
|
||||
char tm_filename[MAX_RES_NAME];
|
||||
int tm_loopcount;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
qboolean S_OPENAL_Init();
|
||||
void S_OPENAL_Shutdown();
|
||||
void S_OPENAL_StartSound(
|
||||
const vec3_t vOrigin,
|
||||
int iEntNum,
|
||||
int iEntChannel,
|
||||
sfxHandle_t sfxHandle,
|
||||
float fVolume,
|
||||
float fMinDist,
|
||||
float fPitch,
|
||||
float fMaxDist,
|
||||
qboolean bStreamed
|
||||
);
|
||||
void S_OPENAL_AddLoopingSound(
|
||||
const vec3_t vOrigin,
|
||||
const vec3_t vVelocity,
|
||||
sfxHandle_t sfxHandle,
|
||||
float fVolume,
|
||||
float fMinDist,
|
||||
float fMaxDist,
|
||||
float fPitch,
|
||||
int iFlags
|
||||
);
|
||||
void S_OPENAL_ClearLoopingSounds();
|
||||
void S_OPENAL_StopSound(int iEntNum, int iEntChannel);
|
||||
void S_OPENAL_StopAllSounds(qboolean bStopMusic);
|
||||
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3]);
|
||||
void S_OPENAL_SetReverb(int iType, float fLevel);
|
||||
void S_OPENAL_Update();
|
||||
|
||||
const char *S_OPENAL_GetMusicFilename();
|
||||
int S_OPENAL_GetMusicLoopCount();
|
||||
unsigned int S_OPENAL_GetMusicOffset();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -89,3 +91,78 @@ void S_MasterGain(float gain);
|
||||
#endif
|
||||
|
||||
#include "new/snd_public_new.h"
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void S_SoundInfo_f();
|
||||
void S_SoundDump_f();
|
||||
void S_Init(qboolean full_startup);
|
||||
void S_Shutdown(qboolean full_shutdown);
|
||||
qboolean S_NameExists(const char* name);
|
||||
void S_BeginRegistration();
|
||||
qboolean S_IsSoundRegistered(const char* name);
|
||||
sfxHandle_t S_RegisterSound(const char* name, int streamed, qboolean force_load);
|
||||
float S_GetSoundTime(sfxHandle_t handle);
|
||||
void S_EndRegistration();
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener);
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume);
|
||||
void S_StartSound(const vec3_t origin, int entnum, int entchannel, sfxHandle_t sfxHandle, float volume, float min_dist, float pitch, float maxDist, int streamed);
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load);
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, soundChannel_t channel);
|
||||
void S_StopAllSounds(qboolean stop_music);
|
||||
void S_ClearLoopingSounds();
|
||||
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float min_dist, float max_dist, float pitch, int flags);
|
||||
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3]);
|
||||
void S_Update();
|
||||
void S_StopSound(int entnum, int channel);
|
||||
void S_SetReverb(int reverb_type, float reverb_level);
|
||||
void S_Play();
|
||||
void S_SoundList();
|
||||
|
||||
qboolean S_IsSoundPlaying(int channel_number, const char* sfxName);
|
||||
void S_FadeSound(float fTime);
|
||||
|
||||
qboolean MUSIC_LoadSoundtrackFile(const char* filename);
|
||||
qboolean MUSIC_SongValid(const char* mood);
|
||||
qboolean MUSIC_Loaded();
|
||||
void Music_Update();
|
||||
void MUSIC_SongEnded();
|
||||
void MUSIC_NewSoundtrack(const char* name);
|
||||
void MUSIC_UpdateMood(int current, int fallback);
|
||||
void MUSIC_UpdateVolume(float volume, float fade_time);
|
||||
void MUSIC_StopAllSongs();
|
||||
void MUSIC_FreeAllSongs();
|
||||
qboolean MUSIC_Playing();
|
||||
int MUSIC_FindSong(const char* name);
|
||||
void S_loadsoundtrack();
|
||||
const char* S_CurrentSoundtrack();
|
||||
void S_PlaySong();
|
||||
int MUSIC_CurrentSongChannel();
|
||||
void MUSIC_StopChannel(int channel_number);
|
||||
qboolean MUSIC_PlaySong(const char* alias);
|
||||
void MUSIC_UpdateMusicVolumes();
|
||||
void MUSIC_CheckForStoppedSongs();
|
||||
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
|
||||
void S_TriggeredMusic_Start();
|
||||
void S_TriggeredMusic_StartLoop();
|
||||
void S_TriggeredMusic_Stop();
|
||||
void S_TriggeredMusic_Pause();
|
||||
void S_TriggeredMusic_Unpause();
|
||||
void S_TriggeredMusic_PlayIntroMusic();
|
||||
void S_StopMovieAudio();
|
||||
void S_SetupMovieAudio(const char* pszMovieName);
|
||||
int S_CurrentMoviePosition();
|
||||
|
||||
const char* S_GetMusicFilename();
|
||||
int S_GetMusicLoopCount();
|
||||
unsigned int S_GetMusicOffset();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+138
-13
@@ -80,7 +80,8 @@ Event EV_PG_MaxDuration
|
||||
"Sets the maximum duration of bursts(in seconds)\nDefault=3",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_PG_MinNumShots(
|
||||
Event EV_PG_MinNumShots
|
||||
(
|
||||
"MinNumShots",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
@@ -88,7 +89,8 @@ Event EV_PG_MinNumShots(
|
||||
"Sets the minimum # of shots to fire in a cycle\nDefault=1",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_PG_MaxNumShots(
|
||||
Event EV_PG_MaxNumShots
|
||||
(
|
||||
"MaxNumShots",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
@@ -275,7 +277,8 @@ Event EV_PG_SetPreImpactSoundTime
|
||||
"Set the time before impact to play the preimpact sound.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_PG_SetPreImpactSoundProbability(
|
||||
Event EV_PG_SetPreImpactSoundProbability
|
||||
(
|
||||
"preimpactsoundprob",
|
||||
EV_DEFAULT,
|
||||
"f",
|
||||
@@ -492,6 +495,7 @@ void ProjectileGenerator::TurnOn(Event *ev)
|
||||
if (!m_bIsTurnedOn) {
|
||||
CancelEventsOfType(EV_PG_BeginCycle);
|
||||
CancelEventsOfType(EV_TickCycle);
|
||||
SetupNextCycle();
|
||||
m_bIsTurnedOn = true;
|
||||
}
|
||||
}
|
||||
@@ -519,6 +523,7 @@ void ProjectileGenerator::SetupNextCycle()
|
||||
|
||||
// get a random delay
|
||||
m_fShotsPerSec = numShots / m_fCycleTime;
|
||||
delay = 0.01f;
|
||||
if (m_bIsTurnedOn || !m_bFireOnStartUp) {
|
||||
delay = G_Random(m_fMaxDelay - m_fMinDelay) + m_fMinDelay;
|
||||
}
|
||||
@@ -1571,8 +1576,8 @@ Event EV_SetTriggered
|
||||
"triggered",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"0 or 1",
|
||||
"Set the triggered status",
|
||||
"triggered",
|
||||
"Set the triggered status (0 or 1)",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_SetExplosionEffect
|
||||
@@ -1580,7 +1585,7 @@ Event EV_SetExplosionEffect
|
||||
"explosioneffect",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"effect model",
|
||||
"effectModel",
|
||||
"Set the explosion effect model",
|
||||
EV_NORMAL
|
||||
);
|
||||
@@ -1589,7 +1594,7 @@ Event EV_SetExplosionOffset
|
||||
"explosionoffset",
|
||||
EV_DEFAULT,
|
||||
"v",
|
||||
"offset vector",
|
||||
"offset",
|
||||
"Set the explosion offset",
|
||||
EV_NORMAL
|
||||
);
|
||||
@@ -1986,6 +1991,26 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_Stickybomb, "ThrobbingBox
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
ThrobbingBox_Stickybomb::ThrobbingBox_Stickybomb()
|
||||
{
|
||||
if (LoadingSavegame) {
|
||||
return;
|
||||
}
|
||||
|
||||
setModel("items/pulse_stickybomb.tik");
|
||||
m_sUsedModel = "items/stickybomb.tik";
|
||||
m_sSound = "explode_flak88";
|
||||
m_sActivateSound = "stickybomb_plant";
|
||||
m_sTickSound = "stickybomb_fuse";
|
||||
|
||||
health = 10;
|
||||
m_fStopwatchStartTime = 0;
|
||||
|
||||
setSolidType(SOLID_BBOX);
|
||||
takedamage = DAMAGE_NO;
|
||||
setContents(CONTENTS_WEAPONCLIP);
|
||||
}
|
||||
|
||||
void ThrobbingBox_Stickybomb::OnStickyBombWet(Event *ev)
|
||||
{
|
||||
Player *player;
|
||||
@@ -2193,10 +2218,110 @@ int Objective::GetObjectiveIndex() const
|
||||
*/
|
||||
|
||||
CLASS_DECLARATION(Entity, FencePost, "func_fencepost") {
|
||||
{&EV_Killed, NULL},
|
||||
{NULL, NULL}
|
||||
{&EV_Killed, &FencePost::Killed},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
FencePost::FencePost()
|
||||
{
|
||||
max_health = 20;
|
||||
health = 20;
|
||||
damage_type = MOD_AAGUN;
|
||||
|
||||
if (!LoadingSavegame) {
|
||||
PostEvent(EV_BecomeSolid, EV_POSTSPAWN);
|
||||
}
|
||||
|
||||
takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
void FencePost::Killed(Event *ev)
|
||||
{
|
||||
Vector vMins, vMaxs;
|
||||
Vector vStart, vEnd;
|
||||
Vector vCenter;
|
||||
float fHalf;
|
||||
|
||||
vCenter = mins - maxs;
|
||||
vCenter *= 0.5;
|
||||
|
||||
if (size.x > size.y) {
|
||||
if (size.x > size.z) {
|
||||
if (size.y > size.z) {
|
||||
fHalf = size.y / 2.f;
|
||||
} else {
|
||||
fHalf = size.z / 2.f;
|
||||
}
|
||||
|
||||
vMins[0] = mins[0];
|
||||
vMaxs[0] = maxs[0];
|
||||
vMins[1] = vCenter[1];
|
||||
vMaxs[1] = vCenter[1];
|
||||
vMins[2] = vCenter[2];
|
||||
vMaxs[2] = vCenter[2];
|
||||
} else {
|
||||
fHalf = size.x / 2.f;
|
||||
|
||||
vMins[2] = mins[2];
|
||||
vMaxs[2] = maxs[2];
|
||||
vMins[1] = vCenter[1];
|
||||
vMaxs[1] = vCenter[1];
|
||||
vMins[0] = vCenter[0];
|
||||
vMaxs[0] = vCenter[0];
|
||||
}
|
||||
} else {
|
||||
if (size.y > size.z) {
|
||||
if (size.x > size.z) {
|
||||
fHalf = size.x / 2.f;
|
||||
} else {
|
||||
fHalf = size.z / 2.f;
|
||||
}
|
||||
|
||||
vMins[1] = mins[1];
|
||||
vMaxs[1] = maxs[1];
|
||||
vMins[0] = vCenter[0];
|
||||
vMaxs[0] = vCenter[0];
|
||||
vMins[2] = vCenter[2];
|
||||
vMaxs[2] = vCenter[2];
|
||||
} else {
|
||||
fHalf = size.y / 2.f;
|
||||
|
||||
vMins[2] = mins[2];
|
||||
vMaxs[2] = maxs[2];
|
||||
vMins[1] = vCenter[1];
|
||||
vMaxs[1] = vCenter[1];
|
||||
vMins[0] = vCenter[0];
|
||||
vMaxs[0] = vCenter[0];
|
||||
}
|
||||
}
|
||||
|
||||
MatrixTransformVector(vMins, orientation, vStart);
|
||||
MatrixTransformVector(vMaxs, orientation, vEnd);
|
||||
|
||||
vStart += origin;
|
||||
vEnd += origin;
|
||||
|
||||
if (fHalf > 255) {
|
||||
fHalf = 255;
|
||||
}
|
||||
|
||||
gi.SetBroadcastVisible(vStart, vEnd);
|
||||
gi.MSG_StartCGM(CGM_FENCEPOST);
|
||||
gi.MSG_WriteCoord(vStart[0]);
|
||||
gi.MSG_WriteCoord(vStart[1]);
|
||||
gi.MSG_WriteCoord(vStart[2]);
|
||||
gi.MSG_WriteCoord(vEnd[0]);
|
||||
gi.MSG_WriteCoord(vEnd[1]);
|
||||
gi.MSG_WriteCoord(vEnd[2]);
|
||||
gi.MSG_WriteByte((int)fHalf);
|
||||
gi.MSG_WriteByte(0);
|
||||
gi.MSG_EndCGM();
|
||||
|
||||
deadflag = DEAD_DEAD;
|
||||
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
Event EV_SetEnemyName
|
||||
(
|
||||
"enemyname",
|
||||
@@ -2213,7 +2338,7 @@ Event EV_SetEnemyName2
|
||||
"s",
|
||||
"enemyname",
|
||||
"",
|
||||
EV_GETTER
|
||||
EV_SETTER
|
||||
);
|
||||
Event EV_GetEnemyName
|
||||
(
|
||||
@@ -2222,7 +2347,7 @@ Event EV_GetEnemyName
|
||||
"s",
|
||||
"enemyname",
|
||||
"",
|
||||
EV_SETTER
|
||||
EV_GETTER
|
||||
);
|
||||
Event EV_Sentient_GetDontDropWeapons
|
||||
(
|
||||
@@ -2538,12 +2663,12 @@ void AISpawnPoint::SetFov(Event *ev)
|
||||
|
||||
void AISpawnPoint::SetSight(Event *ev)
|
||||
{
|
||||
ev->AddFloat(m_fSight);
|
||||
m_fSight = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
void AISpawnPoint::GetSight(Event *ev)
|
||||
{
|
||||
m_fSight = ev->GetFloat(1);
|
||||
ev->AddFloat(m_fSight);
|
||||
}
|
||||
|
||||
void AISpawnPoint::GetHearing(Event *ev)
|
||||
|
||||
+36
-30
@@ -26,19 +26,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "animate.h"
|
||||
|
||||
typedef enum {
|
||||
CONTROLLER_ALLIES,
|
||||
CONTROLLER_AXIS,
|
||||
CONTROLLER_ALLIES,
|
||||
CONTROLLER_AXIS,
|
||||
CONTROLLER_DRAW
|
||||
} eController;
|
||||
|
||||
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
|
||||
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
|
||||
#define PT_SPAWNFLAG_TARGET_RANDOM 4
|
||||
#define PT_SPAWNFLAG_TURN_ON 8
|
||||
#define PT_SPAWNFLAG_ROTATE_YAW 16
|
||||
#define PT_SPAWNFLAG_ROTATE_ROLL 32
|
||||
#define PT_SPAWNFLAG_TARGET_PLAYER 64
|
||||
#define PT_SPAWNFLAG_HIDDEN 128
|
||||
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
|
||||
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
|
||||
#define PT_SPAWNFLAG_TARGET_RANDOM 4
|
||||
#define PT_SPAWNFLAG_TURN_ON 8
|
||||
#define PT_SPAWNFLAG_ROTATE_YAW 16
|
||||
#define PT_SPAWNFLAG_ROTATE_ROLL 32
|
||||
#define PT_SPAWNFLAG_TARGET_PLAYER 64
|
||||
#define PT_SPAWNFLAG_HIDDEN 128
|
||||
|
||||
void ClearProjectileTargets();
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
ProjectileTarget();
|
||||
|
||||
void EventSetId(Event *ev);
|
||||
int GetTarget() const;
|
||||
int GetTarget() const;
|
||||
};
|
||||
|
||||
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
|
||||
@@ -106,16 +106,16 @@ public:
|
||||
bool ShouldRotateYaw() const;
|
||||
bool ShouldRotateRoll() const;
|
||||
|
||||
void EventIsTurnedOn(Event *ev);
|
||||
void EventGetTargetEntity(Event *ev);
|
||||
void EventLaunchSound(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void SetTarget(Entity* ent);
|
||||
void OnInitialize(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void TurnOn(Event *ev);
|
||||
bool ShouldTargetRandom() const;
|
||||
Entity* ChooseTarget();
|
||||
void EventIsTurnedOn(Event *ev);
|
||||
void EventGetTargetEntity(Event *ev);
|
||||
void EventLaunchSound(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void SetTarget(Entity *ent);
|
||||
void OnInitialize(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void TurnOn(Event *ev);
|
||||
bool ShouldTargetRandom() const;
|
||||
Entity *ChooseTarget();
|
||||
|
||||
void GetLocalTargets();
|
||||
bool ShouldTargetPlayer() const;
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
void GetMuzzlePos(Vector& pos);
|
||||
void Fire();
|
||||
void TryLaunchSound();
|
||||
void SetWeaponAnim(const char* name, Event* ev);
|
||||
void SetWeaponAnim(const char *name, Event *ev);
|
||||
void EventAccuracy(Event *ev);
|
||||
void EventMaxDelay(Event *ev);
|
||||
void EventMinDelay(Event *ev);
|
||||
@@ -134,11 +134,11 @@ public:
|
||||
void EventMaxDuration(Event *ev);
|
||||
void EventMinDuration(Event *ev);
|
||||
void SetWeaponModel(Event *ev);
|
||||
void EventSetId(Event* ev);
|
||||
void EventmaxDonut(Event* ev);
|
||||
void EventminDonut(Event* ev);
|
||||
void EventarcDonut(Event* ev);
|
||||
void EventisDonut(Event* ev);
|
||||
void EventSetId(Event *ev);
|
||||
void EventmaxDonut(Event *ev);
|
||||
void EventminDonut(Event *ev);
|
||||
void EventarcDonut(Event *ev);
|
||||
void EventisDonut(Event *ev);
|
||||
virtual bool Attack(int count);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
@@ -164,8 +164,8 @@ public:
|
||||
void SetProjectileModel(Event *ev);
|
||||
|
||||
float EstimateImpactTime(const Vector& targetOrigin, const Vector& fromOrigin, float speed) const;
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Gun : public ProjectileGenerator
|
||||
@@ -306,6 +306,8 @@ private:
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_Stickybomb);
|
||||
|
||||
ThrobbingBox_Stickybomb();
|
||||
|
||||
void OnStickyBombWet(Event *ev);
|
||||
void OnStickyBombUse(Event *ev);
|
||||
|
||||
@@ -325,7 +327,7 @@ public:
|
||||
|
||||
Objective();
|
||||
|
||||
void Archive(Archiver &arc) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
void TurnOn(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void Complete(Event *ev);
|
||||
@@ -340,6 +342,10 @@ class FencePost : public Entity
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(FencePost);
|
||||
|
||||
FencePost();
|
||||
|
||||
void Killed(Event* ev) override;
|
||||
};
|
||||
|
||||
class AISpawnPoint : public SimpleArchivedEntity
|
||||
|
||||
@@ -24,69 +24,77 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "VehicleCollisionEntity.h"
|
||||
#include "g_phys.h"
|
||||
|
||||
CLASS_DECLARATION( Entity, VehicleCollisionEntity, NULL )
|
||||
{
|
||||
{ &EV_Damage, &VehicleCollisionEntity::EventDamage },
|
||||
{ NULL, NULL }
|
||||
Event EV_Owner
|
||||
(
|
||||
"owner",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"owner",
|
||||
EV_GETTER
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(Entity, VehicleCollisionEntity, NULL) {
|
||||
{&EV_Damage, &VehicleCollisionEntity::EventDamage},
|
||||
{&EV_Owner, &VehicleCollisionEntity::GetOwner },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleCollisionEntity::VehicleCollisionEntity
|
||||
(
|
||||
Entity *ent
|
||||
)
|
||||
VehicleCollisionEntity::VehicleCollisionEntity(Entity *ent)
|
||||
{
|
||||
if( LoadingSavegame )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (LoadingSavegame) {
|
||||
return;
|
||||
}
|
||||
|
||||
edict->s.eType = ET_GENERAL;
|
||||
edict->s.eType = ET_GENERAL;
|
||||
|
||||
m_pOwner = ent;
|
||||
takedamage = DAMAGE_YES;
|
||||
m_pOwner = ent;
|
||||
takedamage = DAMAGE_YES;
|
||||
|
||||
showModel();
|
||||
setMoveType( MOVETYPE_PUSH );
|
||||
setSolidType(SOLID_NOT);
|
||||
showModel();
|
||||
setMoveType(MOVETYPE_PUSH);
|
||||
setSolidType(SOLID_NOT);
|
||||
|
||||
edict->clipmask |= MASK_VEHICLE;
|
||||
edict->s.eFlags |= EF_LINKANGLES;
|
||||
edict->clipmask |= MASK_VEHICLE;
|
||||
edict->s.eFlags |= EF_LINKANGLES;
|
||||
}
|
||||
|
||||
VehicleCollisionEntity::VehicleCollisionEntity
|
||||
(
|
||||
void
|
||||
)
|
||||
VehicleCollisionEntity::VehicleCollisionEntity(void)
|
||||
{
|
||||
if( LoadingSavegame )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (LoadingSavegame) {
|
||||
return;
|
||||
}
|
||||
|
||||
gi.Error( ERR_DROP, "VehicleCollisionEntity Created with no parameters!\n" );
|
||||
gi.Error(ERR_DROP, "VehicleCollisionEntity Created with no parameters!\n");
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::EventDamage
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void VehicleCollisionEntity::GetOwner(Event *ev)
|
||||
{
|
||||
m_pOwner->ProcessEvent(*ev);
|
||||
ev->AddListener(m_pOwner);
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::Solid
|
||||
(
|
||||
void
|
||||
)
|
||||
void VehicleCollisionEntity::Solid(void)
|
||||
{
|
||||
setContents( CONTENTS_SOLID );
|
||||
setSolidType( SOLID_BSP );
|
||||
setContents(CONTENTS_SOLID);
|
||||
setSolidType(SOLID_BSP);
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::NotSolid
|
||||
(
|
||||
void
|
||||
)
|
||||
void VehicleCollisionEntity::NotSolid(void)
|
||||
{
|
||||
setSolidType( SOLID_NOT );
|
||||
setSolidType(SOLID_NOT);
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::EventDamage(Event *ev)
|
||||
{
|
||||
m_pOwner->ProcessEvent(*ev);
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::Used(Event *ev)
|
||||
{
|
||||
m_pOwner->ProcessEvent(*ev);
|
||||
}
|
||||
|
||||
Entity *VehicleCollisionEntity::GetOwner() const
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
@@ -21,40 +21,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// VehicleCollisionEntity.h : MOHAA vehicle collision
|
||||
|
||||
#ifndef __VEHICLECOLLISIONENTITY_H__
|
||||
#define __VEHICLECOLLISIONENTITY_H__
|
||||
#pragma once
|
||||
|
||||
#include "entity.h"
|
||||
|
||||
class VehicleCollisionEntity : public Entity
|
||||
{
|
||||
private:
|
||||
EntityPtr m_pOwner;
|
||||
EntityPtr m_pOwner;
|
||||
|
||||
private:
|
||||
void EventDamage( Event *ev );
|
||||
void EventDamage(Event *ev);
|
||||
void GetOwner(Event *ev);
|
||||
void Used(Event *ev);
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( VehicleCollisionEntity );
|
||||
CLASS_PROTOTYPE(VehicleCollisionEntity);
|
||||
|
||||
VehicleCollisionEntity( Entity *ent );
|
||||
VehicleCollisionEntity();
|
||||
VehicleCollisionEntity(Entity *ent);
|
||||
VehicleCollisionEntity();
|
||||
|
||||
void Archive( Archiver& arc ) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
|
||||
void Solid( void );
|
||||
void NotSolid( void );
|
||||
void Solid(void);
|
||||
void NotSolid(void);
|
||||
Entity *GetOwner() const;
|
||||
};
|
||||
|
||||
inline
|
||||
void VehicleCollisionEntity::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void VehicleCollisionEntity::Archive(Archiver& arc)
|
||||
{
|
||||
Entity::Archive( arc );
|
||||
Entity::Archive(arc);
|
||||
|
||||
arc.ArchiveSafePointer( &m_pOwner );
|
||||
arc.ArchiveSafePointer(&m_pOwner);
|
||||
}
|
||||
|
||||
#endif // __VEHICLECOLLISIONENTITY_H__
|
||||
@@ -26,159 +26,128 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "vehicle.h"
|
||||
|
||||
Event EV_VehicleSoundEntity_PostSpawn
|
||||
(
|
||||
"vehiclesoundentity_post",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"PostSpawn of a Vehicle Sound Entity"
|
||||
);
|
||||
(
|
||||
"vehiclesoundentity_post",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"PostSpawn of a Vehicle Sound Entity"
|
||||
);
|
||||
|
||||
Event EV_VehicleSoundEntity_UpdateTraces
|
||||
(
|
||||
"vehiclesoudnentity_updatetraces",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Updates the traces of a Vehicle Sound Entity"
|
||||
);
|
||||
(
|
||||
"vehiclesoudnentity_updatetraces",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Updates the traces of a Vehicle Sound Entity"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION( Entity, VehicleSoundEntity, NULL )
|
||||
{
|
||||
{ &EV_VehicleSoundEntity_PostSpawn, &VehicleSoundEntity::EventPostSpawn },
|
||||
{ &EV_VehicleSoundEntity_UpdateTraces, &VehicleSoundEntity::EventUpdateTraces },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(Entity, VehicleSoundEntity, NULL) {
|
||||
{&EV_VehicleSoundEntity_PostSpawn, &VehicleSoundEntity::EventPostSpawn },
|
||||
{&EV_VehicleSoundEntity_UpdateTraces, &VehicleSoundEntity::EventUpdateTraces},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleSoundEntity::VehicleSoundEntity()
|
||||
{
|
||||
if( LoadingSavegame )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (LoadingSavegame) {
|
||||
return;
|
||||
}
|
||||
|
||||
gi.Error( ERR_DROP, "VehicleSoundEntity Created with no parameters!\n" );
|
||||
gi.Error(ERR_DROP, "VehicleSoundEntity Created with no parameters!\n");
|
||||
}
|
||||
|
||||
VehicleSoundEntity::VehicleSoundEntity( Vehicle *owner )
|
||||
VehicleSoundEntity::VehicleSoundEntity(Vehicle *owner)
|
||||
{
|
||||
m_pVehicle = owner;
|
||||
m_bDoSoundStuff = false;
|
||||
m_iTraceSurfaceFlags = 0;
|
||||
m_pVehicle = owner;
|
||||
m_bDoSoundStuff = false;
|
||||
m_iTraceSurfaceFlags = 0;
|
||||
|
||||
PostEvent( EV_VehicleSoundEntity_PostSpawn, EV_POSTSPAWN );
|
||||
PostEvent(EV_VehicleSoundEntity_PostSpawn, EV_POSTSPAWN);
|
||||
}
|
||||
|
||||
void VehicleSoundEntity::Start
|
||||
(
|
||||
void
|
||||
)
|
||||
void VehicleSoundEntity::Start(void)
|
||||
{
|
||||
m_bDoSoundStuff = true;
|
||||
m_bDoSoundStuff = true;
|
||||
}
|
||||
|
||||
void VehicleSoundEntity::Stop
|
||||
(
|
||||
void
|
||||
)
|
||||
void VehicleSoundEntity::Stop(void)
|
||||
{
|
||||
m_bDoSoundStuff = false;
|
||||
m_bDoSoundStuff = false;
|
||||
}
|
||||
|
||||
void VehicleSoundEntity::Think
|
||||
(
|
||||
void
|
||||
)
|
||||
void VehicleSoundEntity::Think(void)
|
||||
{
|
||||
DoSoundStuff();
|
||||
DoSoundStuff();
|
||||
}
|
||||
|
||||
void VehicleSoundEntity::EventPostSpawn
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void VehicleSoundEntity::EventPostSpawn(Event *ev)
|
||||
{
|
||||
setModel( "models/vehicles/vehiclesoundentity.tik" );
|
||||
setModel("models/vehicles/vehiclesoundentity.tik");
|
||||
|
||||
PostEvent( EV_VehicleSoundEntity_UpdateTraces, 1.0f );
|
||||
flags |= FL_THINK;
|
||||
PostEvent(EV_VehicleSoundEntity_UpdateTraces, 1.0f);
|
||||
flags |= FL_THINK;
|
||||
}
|
||||
|
||||
void VehicleSoundEntity::EventUpdateTraces
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void VehicleSoundEntity::EventUpdateTraces(Event *ev)
|
||||
{
|
||||
if( m_bDoSoundStuff )
|
||||
{
|
||||
m_pVehicle->SetSlotsNonSolid();
|
||||
if (m_bDoSoundStuff) {
|
||||
m_pVehicle->SetSlotsNonSolid();
|
||||
|
||||
trace_t trace = G_Trace(
|
||||
origin,
|
||||
vec3_origin,
|
||||
vec3_origin,
|
||||
Vector( origin[ 0 ], origin[ 1 ], origin[ 2 ] - 256.0f ),
|
||||
m_pVehicle->edict,
|
||||
MASK_SOUND,
|
||||
qfalse,
|
||||
"VehicleSoundEntity::DoSoundStuff"
|
||||
);
|
||||
trace_t trace = G_Trace(
|
||||
origin,
|
||||
vec3_origin,
|
||||
vec3_origin,
|
||||
Vector(origin[0], origin[1], origin[2] - 256.0f),
|
||||
m_pVehicle->edict,
|
||||
MASK_SOUND,
|
||||
qfalse,
|
||||
"VehicleSoundEntity::DoSoundStuff"
|
||||
);
|
||||
|
||||
if( trace.fraction >= 1.0f )
|
||||
m_iTraceSurfaceFlags = 0;
|
||||
else
|
||||
m_iTraceSurfaceFlags = trace.surfaceFlags;
|
||||
if (trace.fraction >= 1.0f) {
|
||||
m_iTraceSurfaceFlags = 0;
|
||||
} else {
|
||||
m_iTraceSurfaceFlags = trace.surfaceFlags;
|
||||
}
|
||||
|
||||
m_pVehicle->SetSlotsSolid();
|
||||
}
|
||||
m_pVehicle->SetSlotsSolid();
|
||||
}
|
||||
|
||||
PostEvent( EV_VehicleSoundEntity_UpdateTraces, 1.0f );
|
||||
PostEvent(EV_VehicleSoundEntity_UpdateTraces, 1.0f);
|
||||
}
|
||||
|
||||
void VehicleSoundEntity::DoSoundStuff
|
||||
(
|
||||
void
|
||||
)
|
||||
void VehicleSoundEntity::DoSoundStuff(void)
|
||||
{
|
||||
float pitch;
|
||||
float pitch;
|
||||
|
||||
if( !m_bDoSoundStuff )
|
||||
{
|
||||
StopLoopSound();
|
||||
return;
|
||||
}
|
||||
if (!m_bDoSoundStuff) {
|
||||
StopLoopSound();
|
||||
return;
|
||||
}
|
||||
|
||||
pitch = ( velocity.length() - m_pVehicle->m_fSoundMinSpeed ) / ( m_pVehicle->m_fSoundMaxSpeed - m_pVehicle->m_fSoundMinSpeed );
|
||||
if( pitch > 1.0f ) {
|
||||
pitch = 1.0f;
|
||||
} else if( pitch < 0.0f ) {
|
||||
pitch = 0.0f;
|
||||
}
|
||||
pitch = (velocity.length() - m_pVehicle->m_fSoundMinSpeed)
|
||||
/ (m_pVehicle->m_fSoundMaxSpeed - m_pVehicle->m_fSoundMinSpeed);
|
||||
if (pitch > 1.0f) {
|
||||
pitch = 1.0f;
|
||||
} else if (pitch < 0.0f) {
|
||||
pitch = 0.0f;
|
||||
}
|
||||
|
||||
pitch *= m_pVehicle->m_fSoundMinPitch + ( m_pVehicle->m_fSoundMaxPitch - m_pVehicle->m_fSoundMinPitch );
|
||||
pitch *= m_pVehicle->m_fSoundMinPitch + (m_pVehicle->m_fSoundMaxPitch - m_pVehicle->m_fSoundMinPitch);
|
||||
|
||||
if( m_iTraceSurfaceFlags & SURF_DIRT )
|
||||
{
|
||||
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_dirt", -1.0f, -1.0f, -1.0f, pitch );
|
||||
}
|
||||
else if( m_iTraceSurfaceFlags & SURF_GRASS )
|
||||
{
|
||||
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_grass", -1.0f, -1.0f, -1.0f, pitch );
|
||||
}
|
||||
else if( m_iTraceSurfaceFlags & SURF_WOOD )
|
||||
{
|
||||
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_wood", -1.0f, -1.0f, -1.0f, pitch );
|
||||
}
|
||||
else if( m_iTraceSurfaceFlags & SURF_MUD )
|
||||
{
|
||||
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_mud", -1.0f, -1.0f, -1.0f, pitch );
|
||||
}
|
||||
else if( m_iTraceSurfaceFlags & ( SURF_GRAVEL | SURF_ROCK ) )
|
||||
{
|
||||
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_stone", -1.0f, -1.0f, -1.0f, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
StopLoopSound();
|
||||
}
|
||||
if (m_iTraceSurfaceFlags & SURF_DIRT) {
|
||||
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_dirt", -1.0f, -1.0f, -1.0f, pitch);
|
||||
} else if (m_iTraceSurfaceFlags & SURF_GRASS) {
|
||||
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_grass", -1.0f, -1.0f, -1.0f, pitch);
|
||||
} else if (m_iTraceSurfaceFlags & SURF_WOOD) {
|
||||
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_wood", -1.0f, -1.0f, -1.0f, pitch);
|
||||
} else if (m_iTraceSurfaceFlags & SURF_MUD) {
|
||||
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_mud", -1.0f, -1.0f, -1.0f, pitch);
|
||||
} else if (m_iTraceSurfaceFlags & (SURF_GRAVEL | SURF_ROCK) || m_iTraceSurfaceFlags == 0) {
|
||||
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_stone", -1.0f, -1.0f, -1.0f, pitch);
|
||||
} else {
|
||||
StopLoopSound();
|
||||
}
|
||||
}
|
||||
@@ -21,47 +21,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// VehicleSoundEntity.h : Sound helper for vehicles
|
||||
|
||||
#ifndef __VEHICLESOUNDENTITY_H__
|
||||
#define __VEHICLESOUNDENTITY_H__
|
||||
#pragma once
|
||||
|
||||
#include "entity.h"
|
||||
|
||||
class Vehicle;
|
||||
|
||||
class VehicleSoundEntity : public Entity {
|
||||
class VehicleSoundEntity : public Entity
|
||||
{
|
||||
private:
|
||||
SafePtr<Vehicle> m_pVehicle;
|
||||
bool m_bDoSoundStuff;
|
||||
int m_iTraceSurfaceFlags;
|
||||
SafePtr<Vehicle> m_pVehicle;
|
||||
bool m_bDoSoundStuff;
|
||||
int m_iTraceSurfaceFlags;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( VehicleSoundEntity );
|
||||
CLASS_PROTOTYPE(VehicleSoundEntity);
|
||||
|
||||
VehicleSoundEntity();
|
||||
VehicleSoundEntity( Vehicle *owner );
|
||||
VehicleSoundEntity();
|
||||
VehicleSoundEntity(Vehicle *owner);
|
||||
|
||||
void Start( void );
|
||||
void Stop( void );
|
||||
void Think( void ) override;
|
||||
void Archive( Archiver& arc ) override;
|
||||
void Start(void);
|
||||
void Stop(void);
|
||||
void Think(void) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
|
||||
private:
|
||||
void EventPostSpawn( Event *ev );
|
||||
void EventUpdateTraces( Event *ev );
|
||||
void DoSoundStuff( void );
|
||||
void EventPostSpawn(Event *ev);
|
||||
void EventUpdateTraces(Event *ev);
|
||||
void DoSoundStuff(void);
|
||||
};
|
||||
|
||||
inline
|
||||
void VehicleSoundEntity::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void VehicleSoundEntity::Archive(Archiver& arc)
|
||||
{
|
||||
Entity::Archive( arc );
|
||||
Entity::Archive(arc);
|
||||
|
||||
arc.ArchiveSafePointer( &m_pVehicle );
|
||||
arc.ArchiveBool( &m_bDoSoundStuff );
|
||||
arc.ArchiveInteger( &m_iTraceSurfaceFlags );
|
||||
arc.ArchiveSafePointer(&m_pVehicle);
|
||||
arc.ArchiveBool(&m_bDoSoundStuff);
|
||||
arc.ArchiveInteger(&m_iTraceSurfaceFlags);
|
||||
}
|
||||
|
||||
#endif // __VEHICLECOLLISIONENTITY_H__
|
||||
+969
-56
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -1714,7 +1714,7 @@ inline bool Actor::CanSeeFOV(Entity *ent)
|
||||
|
||||
bCanSee = false;
|
||||
|
||||
if (InFOV(ent->centroid) && gi.AreasConnected(edict->r.areanum, ent->edict->r.areanum)) {
|
||||
if (InFOV(ent) && AreasConnected(ent)) {
|
||||
bCanSee = CanSee(ent, 0, 0, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ void Actor::Think_Alarm(void)
|
||||
Com_Printf("Actor::Think_Alarm: invalid think state %i\n", m_State);
|
||||
break;
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Alarm(void)
|
||||
|
||||
@@ -264,7 +264,7 @@ bool Actor::CalcFallPath(void)
|
||||
loop = currentPos;
|
||||
|
||||
mm.desired_speed = 0;
|
||||
mm.groundPlane = NULL;
|
||||
mm.groundPlane = qfalse;
|
||||
mm.walking = false;
|
||||
VectorSet(mm.velocity, 0, 0, -171);
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ bool Actor::Cover_SetPath(PathNode *node)
|
||||
fPathDist = PathDist();
|
||||
fMinDistSquared = Square(fPathDist);
|
||||
|
||||
if ((node->origin - origin).lengthSquared() <= fMinDistSquared * 4.0f && fPathDist > 128.0f) {
|
||||
if ((node->origin - origin).lengthSquared() * 4 <= fMinDistSquared && fPathDist > 128.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ void Actor::State_Cover_Hide(void)
|
||||
bool bCanShoot, bCanSee;
|
||||
|
||||
if (m_Enemy) {
|
||||
SetEnemyPos(origin);
|
||||
SetEnemyPos(m_Enemy->origin);
|
||||
}
|
||||
|
||||
if (!m_pCoverNode) {
|
||||
@@ -380,7 +380,7 @@ void Actor::State_Cover_Hide(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (bCanShoot || bCanShoot) {
|
||||
if (bCanSee || bCanShoot) {
|
||||
m_pCoverNode->Relinquish();
|
||||
m_pCoverNode->MarkTemporarilyBad();
|
||||
m_pCoverNode = NULL;
|
||||
|
||||
@@ -31,7 +31,7 @@ void Actor::InitCurious(GlobalFuncs_t *func)
|
||||
func->EndState = &Actor::End_Curious;
|
||||
func->ResumeState = &Actor::Resume_Curious;
|
||||
func->SuspendState = &Actor::Suspend_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Cover;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Curious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
}
|
||||
@@ -246,8 +246,8 @@ void Actor::LookAtCuriosity(void)
|
||||
|
||||
iSeed = 0x19660D * (m_iCuriousTime - 0x2EB71B09 * ((level.inttime - m_iCuriousTime) & 0xFFFFFF00)) + 0x3C6EF35F;
|
||||
|
||||
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / 0x4444444 * fLookScale;
|
||||
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / 0x2222222 * fLookScale;
|
||||
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / (float)0x4444444 * fLookScale;
|
||||
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / (float)0x2222222 * fLookScale;
|
||||
vAngles[2] = m_DesiredLookAngles[2];
|
||||
// clamp
|
||||
vAngles[0] = Q_clamp_float(vAngles[0], -90, 90);
|
||||
|
||||
@@ -31,6 +31,7 @@ void Actor::InitDisguiseSalute(GlobalFuncs_t *func)
|
||||
func->EndState = &Actor::End_DisguiseSalute;
|
||||
func->ResumeState = &Actor::Resume_DisguiseSalute;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseSalute;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_DisguiseSalute;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
@@ -51,7 +52,7 @@ void Actor::Begin_DisguiseSalute(void)
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_SALUTE_SCR);
|
||||
} else {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
@@ -85,7 +86,12 @@ void Actor::Think_DisguiseSalute(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) || level.m_bAlarm != qtrue) {
|
||||
if (!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.m_bAlarm == qtrue) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -89,8 +89,11 @@ void Actor::End_MachineGunner(void)
|
||||
}
|
||||
|
||||
Unholster();
|
||||
if (m_pTurret && m_pTurret->GetOwner() == this) {
|
||||
m_pTurret->TurretEndUsed();
|
||||
if (m_pTurret) {
|
||||
m_pTurret->m_bHadOwner = true;
|
||||
if (m_pTurret->GetOwner() == this) {
|
||||
m_pTurret->TurretEndUsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +157,7 @@ void Actor::ThinkHoldGun_TurretGun(void)
|
||||
}
|
||||
}
|
||||
|
||||
VectorScale2D(orientation[0], m_fCrouchWeight * -9.3f + 23.4f, offset);
|
||||
VectorScale2D(orientation[0], -(m_fCrouchWeight * -9.3f + 23.4f), offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
VectorScale2D(orientation[1], m_fCrouchWeight * 2.6f + 10.3f, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
@@ -164,7 +167,7 @@ void Actor::ThinkHoldGun_TurretGun(void)
|
||||
m_fCrouchWeight = 1.0;
|
||||
}
|
||||
|
||||
VectorScale2D(orientation[0], m_fCrouchWeight * -3.f + 23.4f, offset);
|
||||
VectorScale2D(orientation[0], -(m_fCrouchWeight * -3.f + 23.4f), offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
VectorScale2D(orientation[1], m_fCrouchWeight * -1.6f + 10.3f, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
@@ -179,6 +182,8 @@ void Actor::ThinkHoldGun_TurretGun(void)
|
||||
UpdateAimMotion();
|
||||
UpdateAnim();
|
||||
|
||||
newOrigin[2] += 18;
|
||||
|
||||
end[0] = newOrigin[0];
|
||||
end[1] = newOrigin[1];
|
||||
end[2] = newOrigin[2] - 94;
|
||||
@@ -207,6 +212,12 @@ void Actor::Think_MachineGunner_TurretGun(void)
|
||||
|
||||
UpdateEnemyInternal();
|
||||
|
||||
if (m_Team == TEAM_AMERICAN) {
|
||||
// Added in 2.30
|
||||
ThinkHoldGun_TurretGun();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pTurret->AI_CanTarget(G_GetEntity(0)->centroid)) {
|
||||
ThinkHoldGun_TurretGun();
|
||||
return;
|
||||
|
||||
Loaded 100 of 406 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user