mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-25 09:00:30 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
586da44c30 | ||
|
|
3956e03557 | ||
|
|
8d0b7b77c6 | ||
|
|
23ad991743 | ||
|
|
4493b2c42e | ||
|
|
8b6b1597d7 | ||
|
|
dddedba721 | ||
|
|
be34870a18 | ||
|
|
4d4b9288c6 | ||
|
|
fc9be91124 | ||
|
|
0d24c620fb | ||
|
|
89140f775e | ||
|
|
de6718b511 | ||
|
|
5c094f9c8a | ||
|
|
e2f4d8cd6b | ||
|
|
04da76167c | ||
|
|
90639cee36 | ||
|
|
ecfdcca4d5 | ||
|
|
3790f057e1 | ||
|
|
44d8adcfb0 | ||
|
|
64f877ae80 | ||
|
|
2ce8450a7e | ||
|
|
7e7b3ab280 | ||
|
|
48c2d026e6 | ||
|
|
ad825f5114 | ||
|
|
120a486aea | ||
|
|
864cdf1fc6 | ||
|
|
f1c12e0649 | ||
|
|
58d8a73269 | ||
|
|
c788d57c52 | ||
|
|
50eda4156a | ||
|
|
1e609a4b2f | ||
|
|
a0e2162dd7 | ||
|
|
01dfbcdbfe | ||
|
|
862af012cb | ||
|
|
d83374d38c | ||
|
|
05e14f6364 | ||
|
|
6bc621462c | ||
|
|
acb08b89f7 | ||
|
|
2107523eda | ||
|
|
2662174eba | ||
|
|
59d03ff6f0 | ||
|
|
05d304dfc3 | ||
|
|
614ed6e632 | ||
|
|
eb938c872d | ||
|
|
46e1aa979b | ||
|
|
ec5acb4d98 | ||
|
|
b237222761 | ||
|
|
652df1a5af | ||
|
|
69621335db | ||
|
|
7b58fbec8a | ||
|
|
aeb8aa8e55 | ||
|
|
e74e113199 | ||
|
|
953091cdc8 | ||
|
|
5819145af8 | ||
|
|
154464cda1 | ||
|
|
2342f08a79 | ||
|
|
16711a33ef | ||
|
|
cea0d95fee | ||
|
|
989ec9574c | ||
|
|
b0b82f0252 | ||
|
|
80ddba1013 | ||
|
|
23f776d3c7 | ||
|
|
880acf9120 | ||
|
|
598110477e | ||
|
|
ffdfbc3c7d | ||
|
|
a7dc8b3493 | ||
|
|
67d8cad64d | ||
|
|
b007842fb4 | ||
|
|
2c4b5fc9ba | ||
|
|
e96a3f4f59 | ||
|
|
8eded28efc | ||
|
|
b68bb4cee7 | ||
|
|
824cfd789c | ||
|
|
a0b80a9096 | ||
|
|
857d25825b | ||
|
|
735832829d | ||
|
|
5703161166 | ||
|
|
d85455e9ec | ||
|
|
f6c9de4286 | ||
|
|
a598cbf0dc | ||
|
|
67b285924c | ||
|
|
0c206beb45 | ||
|
|
9a6472210c | ||
|
|
7576d1241d | ||
|
|
fb2f3bddaa | ||
|
|
96ca9c20e4 | ||
|
|
d01fa33e46 | ||
|
|
ab84a6ea58 | ||
|
|
b0a683c188 | ||
|
|
e5ef61c5d2 | ||
|
|
02af9a763d | ||
|
|
132903a843 | ||
|
|
fe862badf6 | ||
|
|
1ad5964c2f | ||
|
|
851a16e18c | ||
|
|
763a79cb74 | ||
|
|
c9ccb0efaf | ||
|
|
9e060d11b6 | ||
|
|
50fdbaf152 | ||
|
|
ccca958ec5 | ||
|
|
dd37ba2741 | ||
|
|
81b49236a5 | ||
|
|
894e1d7d66 | ||
|
|
9d83d58756 | ||
|
|
54b9a0c340 | ||
|
|
2cf380c15d | ||
|
|
d400d8927d | ||
|
|
fef30ff3d5 | ||
|
|
4023c9d863 | ||
|
|
7bcb91bbb5 | ||
|
|
5edee7d12e | ||
|
|
51c7e27bc1 | ||
|
|
f400190531 | ||
|
|
8732e368b6 | ||
|
|
7e4da514f6 | ||
|
|
9a55939b42 | ||
|
|
cd89d2c0b4 | ||
|
|
661b08a7fa | ||
|
|
d27f928e2d | ||
|
|
079555e43a | ||
|
|
fcc4e94655 | ||
|
|
c5721f8a2c | ||
|
|
e5acee55ea | ||
|
|
d3f3b9b51c | ||
|
|
48e9db8966 | ||
|
|
67486f1e49 | ||
|
|
923a6de394 | ||
|
|
de0e4954f8 | ||
|
|
1ef1bad9ae | ||
|
|
23a035e2ca | ||
|
|
ec73268f94 | ||
|
|
2b06cc690e | ||
|
|
7afc2427ac | ||
|
|
f3bbcba4f0 | ||
|
|
0dca08a66a | ||
|
|
f646151ce2 | ||
|
|
2e0e5db260 | ||
|
|
f34aad03cd | ||
|
|
332d209f62 | ||
|
|
888e35466b | ||
|
|
1f69fce10e | ||
|
|
ac3eb58671 | ||
|
|
14f3e2faf9 | ||
|
|
a528e916c2 | ||
|
|
e6f83bc1d6 | ||
|
|
841a8d2b4a | ||
|
|
a51c250a31 | ||
|
|
c2291e92c4 | ||
|
|
b8cc3313b1 | ||
|
|
d1fca3e499 | ||
|
|
66b882346f | ||
|
|
b38fedb18c | ||
|
|
e6559c6ae6 | ||
|
|
772aad79d7 | ||
|
|
3e84dbe6ac | ||
|
|
381f2b02f5 | ||
|
|
f347102ecb | ||
|
|
f5d2fdbcad | ||
|
|
ab037f1890 | ||
|
|
a933c78d93 | ||
|
|
d08f539e6d | ||
|
|
caea6e6bba | ||
|
|
6970e2d00c | ||
|
|
af084542c4 | ||
|
|
9f728580b6 | ||
|
|
c25d0b668a | ||
|
|
1e29fd7d2b | ||
|
|
67f822d492 | ||
|
|
effbbd6c62 | ||
|
|
db802d1a4c | ||
|
|
fba40370af | ||
|
|
fc0ca18632 | ||
|
|
059b0ba34f | ||
|
|
e833b08a8e | ||
|
|
afc431c413 | ||
|
|
81e407a924 | ||
|
|
1f232efdf3 | ||
|
|
94e1830895 | ||
|
|
406f804ef8 | ||
|
|
437f20dfb9 | ||
|
|
ff4438bce9 | ||
|
|
5cb343730b | ||
|
|
dacaaa2cef | ||
|
|
2e6e20cf09 | ||
|
|
2da379bade | ||
|
|
cf8f755f6c | ||
|
|
8114003c84 | ||
|
|
bb47ba468c | ||
|
|
b97c47ab32 | ||
|
|
9042ea320c | ||
|
|
98e725ef7b | ||
|
|
05b2d3529e | ||
|
|
00dbc74269 | ||
|
|
8addeedf5e | ||
|
|
bc834b021c | ||
|
|
6bac4bd57a | ||
|
|
51324aa8e9 | ||
|
|
7d1d92980a | ||
|
|
3d42197f50 | ||
|
|
8a774c02dc | ||
|
|
a644e8a09c | ||
|
|
6f51427c7c | ||
|
|
62bcf58d83 | ||
|
|
f40f206161 | ||
|
|
1235f42143 | ||
|
|
1016bfa1ad | ||
|
|
f9ce111784 | ||
|
|
4c057faf73 | ||
|
|
4f16179c09 | ||
|
|
6991c9f9f7 | ||
|
|
6e6dac0b74 | ||
|
|
23f9c1a1e6 | ||
|
|
e4b2c863d8 | ||
|
|
ae16994289 | ||
|
|
b8b17bb0c9 | ||
|
|
3098fc98d3 | ||
|
|
f3ecfd04da | ||
|
|
0796fab24b | ||
|
|
0fda31b430 | ||
|
|
84a2b4be76 | ||
|
|
5269fbb1fa | ||
|
|
f23dfa091e | ||
|
|
32c3964474 | ||
|
|
6ff92f0a7e | ||
|
|
c795b2390e | ||
|
|
ce7005103c | ||
|
|
1a18878f26 | ||
|
|
1e036a7689 | ||
|
|
858b27b809 | ||
|
|
b4841a878b | ||
|
|
4565b6a9a8 | ||
|
|
9ffb407d11 | ||
|
|
0f3ffa267a | ||
|
|
74c8aa95f5 | ||
|
|
4853235d86 | ||
|
|
0d01ea939d | ||
|
|
5ba6c006c2 | ||
|
|
22e7d1e2e4 | ||
|
|
c650af7b55 | ||
|
|
2ce5e498ab | ||
|
|
d3212c55a0 | ||
|
|
becf9f5d8c | ||
|
|
9cd8133068 | ||
|
|
48fa5c0ce6 | ||
|
|
6fc7199719 | ||
|
|
9e04f94625 | ||
|
|
c9b844b9ea | ||
|
|
497058d7f4 | ||
|
|
a509dd4692 | ||
|
|
8fdfffab36 | ||
|
|
aa118bceb3 | ||
|
|
4da50a78d5 | ||
|
|
4d27a6daa3 | ||
|
|
b6f8997a01 | ||
|
|
568efd4742 | ||
|
|
bf68808eae | ||
|
|
5cbd2dd988 | ||
|
|
92b4ae2702 | ||
|
|
a8cdf0b5ad | ||
|
|
e8dfa0206b | ||
|
|
afe1ba47cf | ||
|
|
2afa9adceb | ||
|
|
ef32200c8d | ||
|
|
dae7795478 | ||
|
|
7c96b68623 | ||
|
|
558e69dba8 | ||
|
|
da7cd03f09 | ||
|
|
6934e5cff8 | ||
|
|
c7cdde7bc2 | ||
|
|
940ac789b9 | ||
|
|
3d46bae1d0 | ||
|
|
16bedf7e86 | ||
|
|
2ee531511b | ||
|
|
0ad5222946 | ||
|
|
2b4aef4ea6 | ||
|
|
679cf4b7ec | ||
|
|
a993b8d352 | ||
|
|
b7403347bb | ||
|
|
bf978256e9 | ||
|
|
9bd25e9734 | ||
|
|
e7499cca04 | ||
|
|
e2d6156b5a | ||
|
|
31cb6216c9 | ||
|
|
e75f5bbbfc | ||
|
|
69cc87212a | ||
|
|
3c1500002b | ||
|
|
b2287f3d83 | ||
|
|
005a278210 | ||
|
|
976e2ae022 | ||
|
|
8fe87e1067 | ||
|
|
d142ded9ad | ||
|
|
090f362bb6 | ||
|
|
ff3c25cc07 | ||
|
|
ed22a51a72 | ||
|
|
9e0c11a970 | ||
|
|
edb52a8448 | ||
|
|
afb08e0ea9 | ||
|
|
8758ba6cb1 | ||
|
|
e6a9968d23 | ||
|
|
fcd2d2e668 | ||
|
|
991c8869d1 | ||
|
|
aef9dc1704 | ||
|
|
848cf7ac01 | ||
|
|
de1d3b6ef4 | ||
|
|
29f8ff8d71 | ||
|
|
b641a1040c | ||
|
|
83acdeb16e | ||
|
|
aa2d73a1c8 | ||
|
|
b7a643aa59 | ||
|
|
3d454c90cb | ||
|
|
590b3f5cbb | ||
|
|
f87e6d5938 | ||
|
|
901e81cdf5 | ||
|
|
d2ed2f5e95 | ||
|
|
c580ccdee1 | ||
|
|
8ecbe1dd79 | ||
|
|
64696c7645 | ||
|
|
ff0dcbd786 | ||
|
|
a3e5d62c96 | ||
|
|
267e2f4b15 | ||
|
|
d52bf52e6a | ||
|
|
f5391bbfa0 | ||
|
|
a218106c8b | ||
|
|
8f54f4b806 | ||
|
|
78b2637c66 | ||
|
|
4b25e24a13 | ||
|
|
aa0c704655 | ||
|
|
4da099d15c | ||
|
|
0bb11d76bd | ||
|
|
c146452570 | ||
|
|
ed05983a57 | ||
|
|
909dc96c2f | ||
|
|
863a6293e7 | ||
|
|
7a49f6fc8b | ||
|
|
c1433a6d9e | ||
|
|
374b8b9ae7 | ||
|
|
e2f5c80afc | ||
|
|
29911380d1 | ||
|
|
405a4bfe28 | ||
|
|
87e41f0c21 | ||
|
|
dce2bcca7c | ||
|
|
00421a7666 | ||
|
|
fd426926e9 | ||
|
|
d83634f8a2 | ||
|
|
6efac1c0f7 | ||
|
|
3a68ca7f4b | ||
|
|
8898919fd3 | ||
|
|
40834380cf | ||
|
|
18abf3854d | ||
|
|
6d0b4f8cb7 | ||
|
|
fc1f795e83 | ||
|
|
ef09f136d4 | ||
|
|
6136bbd019 | ||
|
|
5136aa4886 | ||
|
|
1a3122bef3 | ||
|
|
23d7db814c | ||
|
|
3174ca5da9 | ||
|
|
6a107419e3 | ||
|
|
6d69a8033f | ||
|
|
bb9ccdd3b9 | ||
|
|
5b3ce85695 | ||
|
|
84c5bfa777 | ||
|
|
d9166478e5 | ||
|
|
373fe45b50 | ||
|
|
cd83091101 | ||
|
|
631abd2b0f | ||
|
|
02df233205 | ||
|
|
11e9d0f9ba | ||
|
|
35fea91268 | ||
|
|
6f3d79ae1b | ||
|
|
32da07ea80 | ||
|
|
e9a76f933b | ||
|
|
6b6adf1147 | ||
|
|
6413e770e1 | ||
|
|
7d1067108b | ||
|
|
e00ebda641 | ||
|
|
2b6fc0602a | ||
|
|
53c09b5342 | ||
|
|
d78d8abb9f | ||
|
|
f6b459b408 | ||
|
|
581585a47c | ||
|
|
ddbdcc91dd | ||
|
|
8f8b75e0aa | ||
|
|
2e673a6bc9 | ||
|
|
8c2b92d151 | ||
|
|
032fb9b5ba | ||
|
|
b1c5d6c62a | ||
|
|
037af5d728 | ||
|
|
61a2b6a837 | ||
|
|
13698a9590 | ||
|
|
4f2907ef77 | ||
|
|
8667d11c52 | ||
|
|
24309095ff | ||
|
|
d5a90ded17 | ||
|
|
9d744367ac | ||
|
|
46a46a9536 | ||
|
|
224c1df553 | ||
|
|
bcea5af30f | ||
|
|
211ce09c0b | ||
|
|
1e41a2595d | ||
|
|
36a080b3a9 | ||
|
|
a3050f6c64 | ||
|
|
be5deddc1d | ||
|
|
36f9bdb88c | ||
|
|
1a33e9a15b | ||
|
|
4157a49c7e | ||
|
|
f27be7314e | ||
|
|
a425038fa6 | ||
|
|
0b07858bfc | ||
|
|
7dbf1d7bf5 | ||
|
|
34c44ab2cf | ||
|
|
5ec106642d | ||
|
|
dcd9ce91a8 | ||
|
|
a05fbfe69b | ||
|
|
feb76f4fb4 | ||
|
|
d467b68187 | ||
|
|
de18fa2860 | ||
|
|
58f6c719a9 | ||
|
|
b2fa21a111 | ||
|
|
f94099e350 | ||
|
|
e2f11879d5 | ||
|
|
aa15b3ea7f | ||
|
|
1624d10a01 | ||
|
|
0d53adf9bd | ||
|
|
295c267c31 | ||
|
|
d4b3f7378e | ||
|
|
a503e18966 | ||
|
|
b1f7d641fc | ||
|
|
5019d1e4f9 | ||
|
|
2aa0205872 | ||
|
|
a7befa8882 | ||
|
|
a5058c7bab | ||
|
|
f5558d106e | ||
|
|
d19328230c | ||
|
|
b77464386c | ||
|
|
9119319429 | ||
|
|
d3d85fded0 | ||
|
|
9b9642df8f | ||
|
|
e564a97b05 | ||
|
|
a150cb5c6e | ||
|
|
afd7943b62 | ||
|
|
09eb130b6d | ||
|
|
5869ba06bc | ||
|
|
b6c2638c1b | ||
|
|
16b0f0d625 | ||
|
|
9293930628 | ||
|
|
46935b165c | ||
|
|
c0dd08f6e0 | ||
|
|
1fde1647e8 | ||
|
|
7ef006ccca | ||
|
|
fd69d6b42c | ||
|
|
627f66fb5b | ||
|
|
8451c11916 | ||
|
|
6bbbbcfb05 | ||
|
|
63465278a5 | ||
|
|
2980771deb | ||
|
|
1169b84c2f | ||
|
|
355491a950 | ||
|
|
7caa0adbab | ||
|
|
8acc51c489 | ||
|
|
732fd98593 | ||
|
|
21a610d22c | ||
|
|
a379e6efbf | ||
|
|
b1e1b6cc68 | ||
|
|
da86e0ce34 | ||
|
|
6ca12eb0de | ||
|
|
a25442368b | ||
|
|
e7e95d47a5 | ||
|
|
292fe8eab4 | ||
|
|
272a401189 | ||
|
|
592e3f47e9 | ||
|
|
cabf1a9043 | ||
|
|
e623541861 | ||
|
|
b74b6f8c1d | ||
|
|
11abdd451f | ||
|
|
1c3596b1f9 | ||
|
|
1e73333fbe | ||
|
|
6eb49f567a | ||
|
|
0120e7e4a5 | ||
|
|
10e4d3db11 | ||
|
|
0b34d2dbb8 | ||
|
|
be1ef1de0e | ||
|
|
ef45c988c6 | ||
|
|
3ecdee1b89 | ||
|
|
c7561b1f6d | ||
|
|
50a3df8dff | ||
|
|
dfde4a58de | ||
|
|
090ba308d8 | ||
|
|
e01e989c22 | ||
|
|
a9b4af98fc | ||
|
|
30f5442728 | ||
|
|
123ca2812a | ||
|
|
95435ea512 | ||
|
|
db625baadd | ||
|
|
200a80aa02 | ||
|
|
0472a93c3f | ||
|
|
9b70e646dc | ||
|
|
388ab210a7 | ||
|
|
15e8a71249 | ||
|
|
dfd04f0d41 | ||
|
|
88ac49c0c9 | ||
|
|
7d6ff3e6a4 | ||
|
|
c68fbfacb9 | ||
|
|
8e51c7ca3b | ||
|
|
33064f8392 | ||
|
|
40141465b5 | ||
|
|
13d855c2e7 | ||
|
|
2f8b6a2009 | ||
|
|
23e56e767f | ||
|
|
ce5b954c4d | ||
|
|
a0c20663a0 | ||
|
|
56f850b59d | ||
|
|
253d4e2c4d | ||
|
|
6fef42d6e0 | ||
|
|
d6a00a5984 | ||
|
|
26a1e24e3a | ||
|
|
6103efa8cc | ||
|
|
9a7ba0786c | ||
|
|
935efaeb3a | ||
|
|
020a6d8b66 | ||
|
|
9dea8fc41e | ||
|
|
3a7e249edf | ||
|
|
c406aaf74f | ||
|
|
83938471ca | ||
|
|
db6ff8901b | ||
|
|
737ee3af64 | ||
|
|
9ea40f31e4 | ||
|
|
27bd6f4b1c | ||
|
|
b9e9137f90 | ||
|
|
bee0bbbe90 | ||
|
|
277ca0c951 | ||
|
|
8aa059dd21 | ||
|
|
c39bdd246a | ||
|
|
9823af9159 | ||
|
|
9ee0e0a3c9 | ||
|
|
bf184fb719 | ||
|
|
94f308c50f | ||
|
|
bfa0ef64ec | ||
|
|
98fc0a8cb9 | ||
|
|
facabc09f5 | ||
|
|
51afcd7b96 | ||
|
|
340f1bb287 | ||
|
|
40c8479448 | ||
|
|
27e2063bf9 | ||
|
|
e43f0a9285 | ||
|
|
a977cbdd26 | ||
|
|
dbc536c6c2 | ||
|
|
97c9075503 | ||
|
|
290e45062d | ||
|
|
fc6bffe683 | ||
|
|
1fb8327ca9 | ||
|
|
36208de902 | ||
|
|
5403577642 | ||
|
|
c76dda1523 | ||
|
|
b5034e5b12 | ||
|
|
b039333922 | ||
|
|
b504e0d109 | ||
|
|
0692b9dcdb | ||
|
|
085b72154f | ||
|
|
4f99c0fa98 | ||
|
|
b38b71eb44 | ||
|
|
639da1a4b8 | ||
|
|
f2d27aae3f | ||
|
|
931876ac77 | ||
|
|
e5f62a9188 | ||
|
|
3fb699979c | ||
|
|
85f15a1f28 | ||
|
|
758017b638 | ||
|
|
724d1db9b8 | ||
|
|
00421fbee6 | ||
|
|
2510bab41f | ||
|
|
c6675f2013 | ||
|
|
1fd6c2bd52 | ||
|
|
8f355fe188 | ||
|
|
dbd10a281b | ||
|
|
d57ea3695b | ||
|
|
8dd74b7789 | ||
|
|
36c00f146d | ||
|
|
aba9f25744 | ||
|
|
dacfa6ae55 | ||
|
|
f53fba082a | ||
|
|
764b95f617 | ||
|
|
3237b3564e | ||
|
|
985731f543 | ||
|
|
7c28efe9cd | ||
|
|
5b567f4cba | ||
|
|
78918eb59d | ||
|
|
1848506f09 | ||
|
|
ce0004a296 | ||
|
|
e85d3f2a19 | ||
|
|
4e5a0a30bf | ||
|
|
9ab37e54b4 | ||
|
|
0bd15172b1 | ||
|
|
fe0e5c1d9c | ||
|
|
5128d88722 | ||
|
|
173ca3e58e | ||
|
|
2a13fca737 | ||
|
|
b3a9f4423b | ||
|
|
62c24826e6 | ||
|
|
a3d2c2c044 | ||
|
|
72409622ef | ||
|
|
c8a2de8235 | ||
|
|
6b91846b0c | ||
|
|
92190220aa | ||
|
|
705d30d125 | ||
|
|
c316dc7b00 | ||
|
|
529dc29d08 | ||
|
|
91e760bf5f | ||
|
|
61e24499bf | ||
|
|
75621651e5 | ||
|
|
3973b95746 | ||
|
|
f9d264058b | ||
|
|
a69d9d4483 | ||
|
|
8b19d00086 | ||
|
|
1156d4f881 | ||
|
|
08c5186426 | ||
|
|
61b4a817f3 | ||
|
|
13710904ba | ||
|
|
015ebb650e | ||
|
|
17d623bf85 | ||
|
|
0049348de5 | ||
|
|
20d11f5f97 | ||
|
|
047a7bb949 | ||
|
|
52c79f7f77 | ||
|
|
c97bc2e977 | ||
|
|
78d564cc04 | ||
|
|
e27c0716c4 | ||
|
|
35d037daff | ||
|
|
f055162ac0 | ||
|
|
f2e32c737b | ||
|
|
205709271b | ||
|
|
3e70a9fab8 | ||
|
|
733c6c96f0 | ||
|
|
a010e648ee | ||
|
|
1c7b561aa9 | ||
|
|
75a71d35ec | ||
|
|
7c0f0672bd | ||
|
|
8fc6b6e3c3 | ||
|
|
6c2c8ca2b7 | ||
|
|
1b6bdd07e7 | ||
|
|
539688dd3d | ||
|
|
08e09c3b4c | ||
|
|
4259053c7e | ||
|
|
c221cfd493 | ||
|
|
41298b53d4 | ||
|
|
ddcd05adc6 | ||
|
|
a28cd64c7a | ||
|
|
38e62fef18 | ||
|
|
3f139f463b | ||
|
|
0597191319 | ||
|
|
f4c8b0c21f | ||
|
|
bba7031f3d | ||
|
|
4785913e02 | ||
|
|
a6808d1f6a | ||
|
|
7188e9832a | ||
|
|
0cce0c81fb | ||
|
|
a60baa03e0 | ||
|
|
b0c8dafb33 | ||
|
|
b672fc8b29 | ||
|
|
eac69f659f | ||
|
|
d9ab65154c | ||
|
|
c120aed8bb | ||
|
|
ecdbe3d959 | ||
|
|
96d10fb8b0 | ||
|
|
2ab826268d | ||
|
|
c3e3f368e0 | ||
|
|
f35582489d | ||
|
|
9acea3484d | ||
|
|
a72da9b73e | ||
|
|
df53d35967 | ||
|
|
e5e7421d3c | ||
|
|
6ff25d00fc | ||
|
|
4a5b0b3105 | ||
|
|
d05d964432 | ||
|
|
daa4a67b49 | ||
|
|
9c0224911c | ||
|
|
ef5759cff5 | ||
|
|
77292fb9ab | ||
|
|
6fb9ab078e | ||
|
|
844a72e0f3 | ||
|
|
46e9046629 | ||
|
|
e5af60787e | ||
|
|
4b0696a187 | ||
|
|
a6377fedab | ||
|
|
2f884e6d55 | ||
|
|
28f8c65771 | ||
|
|
b509ef5ab4 | ||
|
|
9f48dabaec | ||
|
|
5b0224ae3c | ||
|
|
c3ef267d6d | ||
|
|
fe9b298705 | ||
|
|
0b106cf47e | ||
|
|
9b417c9b26 | ||
|
|
37d5458c4c | ||
|
|
77d48cb104 | ||
|
|
a25200741a | ||
|
|
d04a32920a | ||
|
|
792b676c11 | ||
|
|
690a7a7557 | ||
|
|
e128c93ad9 | ||
|
|
39add5ccec | ||
|
|
a1a89cba34 | ||
|
|
2d696cf500 | ||
|
|
45fe0bc8b7 | ||
|
|
9fc4c67187 | ||
|
|
34aeab5f77 | ||
|
|
b510452260 | ||
|
|
89b8d5a67b | ||
|
|
500e3a3b2c | ||
|
|
47e575ed9a | ||
|
|
10b30d74e7 | ||
|
|
1ba4c6b7ad | ||
|
|
eb899be95e | ||
|
|
6d993af419 | ||
|
|
a136cccbe1 | ||
|
|
2b43ebfca4 | ||
|
|
06f4980ee1 | ||
|
|
6cdf5b7b7e | ||
|
|
117b9a5579 | ||
|
|
9475be8f6f | ||
|
|
41ca1797f9 | ||
|
|
e56ae3d266 | ||
|
|
735ffaf80b | ||
|
|
ed52d1c648 | ||
|
|
78fa90c59b | ||
|
|
548a3efe5a | ||
|
|
18a12eeba3 | ||
|
|
83d486ceeb | ||
|
|
d898c0f995 | ||
|
|
02faf6f8c1 | ||
|
|
3478bbddf2 | ||
|
|
fd1ee31e1e | ||
|
|
4a565f0985 | ||
|
|
c68f23cdaf | ||
|
|
e386eb00ef | ||
|
|
662d048bf4 | ||
|
|
d9e3cc2188 | ||
|
|
a586f13af8 | ||
|
|
37820c1673 | ||
|
|
8a2e4ca470 | ||
|
|
3a5da64c6f | ||
|
|
9c018a2330 | ||
|
|
0840cdd83a | ||
|
|
e972747969 | ||
|
|
e151c6eb15 | ||
|
|
603444a69f | ||
|
|
999e0fd721 | ||
|
|
47131dec44 | ||
|
|
6adad053d9 | ||
|
|
725561b655 | ||
|
|
b84fbf452e | ||
|
|
eb7af2bce9 | ||
|
|
7c57c4b131 | ||
|
|
4460466cb3 | ||
|
|
eea19d733d | ||
|
|
abc97dcab3 | ||
|
|
065c791a10 | ||
|
|
6b902e7f5d | ||
|
|
df0cb87b35 | ||
|
|
0b9687fea4 | ||
|
|
99fbe092bc | ||
|
|
7a7849ae83 | ||
|
|
47830bb330 | ||
|
|
0dfb1a3a2a | ||
|
|
e2e1ab0275 | ||
|
|
4249cacf2f | ||
|
|
4e3ec52673 | ||
|
|
98991a4a7a | ||
|
|
bca6d656b6 | ||
|
|
ffc3580d43 | ||
|
|
c18cdc78ea | ||
|
|
77ecc73631 | ||
|
|
3834f51d74 | ||
|
|
86ddec3f76 | ||
|
|
4d12bcb184 | ||
|
|
7d93723382 | ||
|
|
8e1a52bbb7 | ||
|
|
cd9b1a741f | ||
|
|
cefe331e0c | ||
|
|
14d1fae54a | ||
|
|
a1601be7a6 | ||
|
|
a2ebeb11e3 | ||
|
|
b7f0f32878 | ||
|
|
58e39add5b | ||
|
|
61725c95df | ||
|
|
71a1df661a | ||
|
|
9eed0eab5f | ||
|
|
e42b6fe0a9 | ||
|
|
b1e640ad1d | ||
|
|
2fc091fdf7 | ||
|
|
47ba241e7d | ||
|
|
c0d37c504a | ||
|
|
1e0195f6e3 | ||
|
|
e806c1ddf1 | ||
|
|
78f0072c59 | ||
|
|
1022ce531a | ||
|
|
7f08a7bca8 | ||
|
|
4123bef60d | ||
|
|
c6464efa07 | ||
|
|
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 | ||
|
|
60faa9dd9b | ||
|
|
75f8f86f86 | ||
|
|
0ee1307e75 | ||
|
|
f0c38305b5 | ||
|
|
e07dda6991 | ||
|
|
b10ce9a426 | ||
|
|
2ac2800ecb | ||
|
|
e59200a7de | ||
|
|
a7902a8837 | ||
|
|
615726cc75 | ||
|
|
839abf6076 | ||
|
|
c7c8d4580d | ||
|
|
2cc47e10f9 | ||
|
|
8fc5dacebf | ||
|
|
cb23f3bb70 | ||
|
|
d7350d8629 | ||
|
|
ac6b5ef1f7 | ||
|
|
7fdd26c59e | ||
|
|
fad555308b | ||
|
|
969255c48e | ||
|
|
433305617c | ||
|
|
5418d84c7e | ||
|
|
cca37e3dfe | ||
|
|
0e9d83ee14 | ||
|
|
ecbf7f6caa | ||
|
|
5a3638fa68 | ||
|
|
111088b540 | ||
|
|
ba1703ebf0 | ||
|
|
825df20a72 | ||
|
|
0a42fd79d2 | ||
|
|
e50a041c12 | ||
|
|
ce0e9fe77e | ||
|
|
5105dcce04 | ||
|
|
58b4a9a676 | ||
|
|
1146c834fb | ||
|
|
9068264132 | ||
|
|
59ac8ea437 | ||
|
|
afafacaeec | ||
|
|
baf451d2a2 | ||
|
|
d588012168 | ||
|
|
a3ed25cb2e | ||
|
|
c399f45841 | ||
|
|
6a6eeae4ee | ||
|
|
65f36505d1 | ||
|
|
b852980842 | ||
|
|
d351ced78b | ||
|
|
4cd45c63c4 | ||
|
|
de16a72aed | ||
|
|
4b29c63fc9 | ||
|
|
770e832592 | ||
|
|
14f9acdb57 | ||
|
|
573a6f5bd5 | ||
|
|
8c64b7aa89 | ||
|
|
8d49f8935c | ||
|
|
ff8ec63e95 | ||
|
|
771ee1b5a9 | ||
|
|
096692fec8 | ||
|
|
d29454b44d | ||
|
|
30a1ccb2e2 | ||
|
|
ea1b411cc0 | ||
|
|
7794ee8aea | ||
|
|
99a9022b53 | ||
|
|
1255964e6b | ||
|
|
37de859bee | ||
|
|
990aa5cdb2 | ||
|
|
befcedcf58 | ||
|
|
eeb697570d | ||
|
|
6410567e9a | ||
|
|
bde7242cc7 | ||
|
|
e8aad97975 | ||
|
|
0662359776 | ||
|
|
5568d160ab | ||
|
|
defa297a56 | ||
|
|
782c37c4fe | ||
|
|
6f03c88ad5 | ||
|
|
3ec980c8ec | ||
|
|
c0a50eb2ff | ||
|
|
f73e4b6f22 | ||
|
|
096972827e | ||
|
|
08c040d4ea | ||
|
|
6d8b6b5f29 | ||
|
|
410f1c0ed8 | ||
|
|
cb73cfd57b | ||
|
|
8cb8a7f370 | ||
|
|
8c893acfff | ||
|
|
e453d1fa17 | ||
|
|
a7301ed7b6 | ||
|
|
42ebfd5394 | ||
|
|
cdf2f84b14 | ||
|
|
2592aeab8b | ||
|
|
34d4225ea0 | ||
|
|
17dcb4b00e | ||
|
|
eb1d096539 | ||
|
|
05c74655be | ||
|
|
3e0e0ba3b1 | ||
|
|
f90b6cd18c | ||
|
|
f0ecfcb708 | ||
|
|
177702d027 | ||
|
|
64429232f8 | ||
|
|
d6b7fecb69 | ||
|
|
51a0ee56aa | ||
|
|
2ed369568c | ||
|
|
e5b7e16d1a | ||
|
|
4a9f676d5d | ||
|
|
0e0da3d767 | ||
|
|
343ce4a6a7 | ||
|
|
df8b854cb7 | ||
|
|
831dc770d8 | ||
|
|
8a9285c64f | ||
|
|
7e4e06b09d | ||
|
|
96748b3fbc | ||
|
|
f1325048e9 | ||
|
|
deee21eb68 | ||
|
|
2f43e5c5ea | ||
|
|
4766067edb | ||
|
|
bc54f22639 | ||
|
|
20c8c87e79 | ||
|
|
3a5dcd6a3c | ||
|
|
a5ba02c2bb | ||
|
|
e1554efc08 | ||
|
|
9d652dd41b | ||
|
|
22eadf2c08 | ||
|
|
d3f1b62208 | ||
|
|
affc28ab79 | ||
|
|
41be7f44ab | ||
|
|
646c1f0f16 | ||
|
|
3cea097b48 | ||
|
|
786d72575e | ||
|
|
6d9a794aaf | ||
|
|
9e69df1e94 | ||
|
|
72d4bb0206 | ||
|
|
f68e06a949 | ||
|
|
f4da539d95 | ||
|
|
17af75a9bb | ||
|
|
dcbb39d640 | ||
|
|
d0ba1df4e0 | ||
|
|
2b92869683 | ||
|
|
379a4b0ce4 | ||
|
|
d4c7d4a7e1 | ||
|
|
dcac24c9e2 | ||
|
|
753589d840 | ||
|
|
382903c9e1 | ||
|
|
f29fec0b31 | ||
|
|
f9dc37d60a | ||
|
|
c5e48c67bb | ||
|
|
cc62ebcffc | ||
|
|
0f36504959 | ||
|
|
1fb8e25209 | ||
|
|
260876b1a2 | ||
|
|
e4fc074f09 | ||
|
|
7899e5161e | ||
|
|
95603b1142 | ||
|
|
bf8e0eb812 | ||
|
|
0c04ffc1e8 | ||
|
|
bd86acf118 | ||
|
|
6caa16444e | ||
|
|
94d4cbeb82 | ||
|
|
b31f4bc00c | ||
|
|
cf0808e119 | ||
|
|
92333909fd | ||
|
|
9c68af92be | ||
|
|
bc5d7f5e93 | ||
|
|
f2ba9a88be | ||
|
|
81b711364e | ||
|
|
554e0c7fac | ||
|
|
bd2c1c387b | ||
|
|
f19edac9ca | ||
|
|
1698f6d1bf | ||
|
|
2c3180813a | ||
|
|
a262fe5d9d | ||
|
|
a69249ee22 | ||
|
|
393c2a81d1 | ||
|
|
3a6be342ce | ||
|
|
6616bfe53e | ||
|
|
bafe60f48f | ||
|
|
e306c415f0 | ||
|
|
56a8c8d48d | ||
|
|
421f1d39a4 | ||
|
|
7c655944a5 | ||
|
|
0a27f37dc0 | ||
|
|
4695932ea1 | ||
|
|
7fe7a12167 | ||
|
|
f9487b0ba3 | ||
|
|
7c5c34741c | ||
|
|
d09459f4bf | ||
|
|
c0c6598151 | ||
|
|
f52fcc6f0e | ||
|
|
2e9ef64bd2 | ||
|
|
ff3ee39830 | ||
|
|
abd757f3bc | ||
|
|
c741591a36 | ||
|
|
78c481d725 | ||
|
|
b2ece37819 | ||
|
|
a557b29ecf | ||
|
|
1184843318 | ||
|
|
dd1f8bd92a | ||
|
|
220c82954c | ||
|
|
8879bacb1d | ||
|
|
5824022745 | ||
|
|
3ecb5bd06a | ||
|
|
7de31a776b | ||
|
|
503320d13f | ||
|
|
bd263c5d22 | ||
|
|
b0201aef5d | ||
|
|
31014808c8 | ||
|
|
0906124867 | ||
|
|
43bb5ce653 | ||
|
|
7e66483b1a | ||
|
|
f96b606a1a | ||
|
|
30d26c3e44 | ||
|
|
57e450a745 | ||
|
|
24297bf396 | ||
|
|
481cd760a9 | ||
|
|
6d6043775e | ||
|
|
bb97ec8933 | ||
|
|
dc028b87e4 | ||
|
|
0d1b7a9c8a | ||
|
|
a6e602af1d | ||
|
|
04a6012e5d | ||
|
|
0f7691c722 | ||
|
|
f01a0a17c1 | ||
|
|
b291ab92b6 | ||
|
|
fb4bf4fcaa | ||
|
|
98816156d7 | ||
|
|
92bfb4c426 | ||
|
|
cac883c4a0 | ||
|
|
5a4fb90c96 | ||
|
|
c4f9eb65ae | ||
|
|
9f5557b33c | ||
|
|
4d876fdf5d | ||
|
|
978666c946 | ||
|
|
9b9fa696e8 | ||
|
|
088b22073c | ||
|
|
4f9831faa4 | ||
|
|
3373caa939 | ||
|
|
dc1be17b2a | ||
|
|
64a3b04181 | ||
|
|
57e1920b9c | ||
|
|
ddb6236eb9 | ||
|
|
4e4af590e5 | ||
|
|
a249f6b29b | ||
|
|
7787729b24 | ||
|
|
45c8c704af | ||
|
|
31fde1ad94 | ||
|
|
bfb0fbd656 | ||
|
|
8afb7457c2 | ||
|
|
0ae1c8f771 | ||
|
|
6ff046ae29 | ||
|
|
6f9f845bb2 | ||
|
|
00033c3a70 | ||
|
|
acf71610df | ||
|
|
86e9ae343a | ||
|
|
9bbd546d4c | ||
|
|
31f2573b28 | ||
|
|
4d7fcb77c2 | ||
|
|
da02a8c73a | ||
|
|
dd0b4505a6 | ||
|
|
eaff26216a | ||
|
|
e850dd1963 | ||
|
|
cf61ae0332 | ||
|
|
5cffe3fb05 | ||
|
|
b996918d3b | ||
|
|
4a9f9a45c2 | ||
|
|
3a75772005 | ||
|
|
c196e31c6c | ||
|
|
60ceff5ae0 | ||
|
|
34a4a0c892 | ||
|
|
2a3c42d47b | ||
|
|
0b1f796e0a | ||
|
|
766d4d23bf | ||
|
|
6860a1e992 | ||
|
|
70c628d759 | ||
|
|
6eff8bc273 | ||
|
|
0b1e8cdbf3 | ||
|
|
6f58b34f87 | ||
|
|
adf081ba3c | ||
|
|
6d4a9fde3f | ||
|
|
5a5cc4ea17 | ||
|
|
69df583508 | ||
|
|
18506d9932 | ||
|
|
f076e7609e | ||
|
|
0b0d053044 | ||
|
|
ce7dfdd986 | ||
|
|
50e589f27c | ||
|
|
e904dafa38 | ||
|
|
6a210fa212 | ||
|
|
ae33155ed3 | ||
|
|
d3d44001ef | ||
|
|
c2aec1ff57 | ||
|
|
d5f08fe950 | ||
|
|
bdf4df9fd0 | ||
|
|
7481b0939e | ||
|
|
346e59f18a | ||
|
|
4725aad3e9 | ||
|
|
59fd1bfdb2 | ||
|
|
7546d91580 | ||
|
|
c81df27470 | ||
|
|
bd6232d913 | ||
|
|
7f6b73e60f | ||
|
|
e3562f9e56 | ||
|
|
40141c55de | ||
|
|
a6f6cbd9b5 | ||
|
|
e9ffb4b9b5 | ||
|
|
1f0418a9cd | ||
|
|
e76837b42c | ||
|
|
87be7068c9 | ||
|
|
49cb5af265 | ||
|
|
f0fe93429f | ||
|
|
c2461f1219 | ||
|
|
f82b6b75ff | ||
|
|
3486b590eb | ||
|
|
5730af672c | ||
|
|
4daff05142 | ||
|
|
e930768c67 | ||
|
|
6f03e388bf | ||
|
|
9b340e03c5 | ||
|
|
d5b61fe5cc | ||
|
|
5b46e48a17 | ||
|
|
585221f7cc | ||
|
|
77eb7a5259 | ||
|
|
77bfc4b599 | ||
|
|
95bbfba1b8 | ||
|
|
844a50dfd8 | ||
|
|
cd2fea5262 | ||
|
|
79d8b4bb0b | ||
|
|
531825545d | ||
|
|
daab5b9238 | ||
|
|
ce59e5e6a7 | ||
|
|
ea0c4b5060 | ||
|
|
9b9908b660 | ||
|
|
101894be37 | ||
|
|
3e314251f2 | ||
|
|
1995c75006 | ||
|
|
ff85986c44 | ||
|
|
9131297d43 | ||
|
|
301f3091d1 | ||
|
|
b59bd449d4 | ||
|
|
5e510ef0e2 | ||
|
|
c7c3fcd0e0 | ||
|
|
a5532ad67b | ||
|
|
290cd5501c | ||
|
|
8d1b1410cd | ||
|
|
df9aead324 | ||
|
|
851fd240d3 | ||
|
|
2da03c89d1 | ||
|
|
89cd12d2c1 | ||
|
|
e21d2a0adb | ||
|
|
2fad64b08a | ||
|
|
97fd147fbe | ||
|
|
0f01f6af11 | ||
|
|
a9892c88be | ||
|
|
f1d76a042d | ||
|
|
77d4e5d051 | ||
|
|
7041acfd51 | ||
|
|
b27bfbe189 | ||
|
|
1c10e7a63d | ||
|
|
0a7c324d48 | ||
|
|
c81d247fbb | ||
|
|
82294b7b2e | ||
|
|
d80f55d5bf | ||
|
|
7930cda277 | ||
|
|
7870db7202 | ||
|
|
407538fd85 | ||
|
|
1a293420c0 | ||
|
|
1e94cdd8ca | ||
|
|
7a2311d6e6 | ||
|
|
e686937ae9 | ||
|
|
8dca8988fe | ||
|
|
c890ac5944 | ||
|
|
56e52fda80 | ||
|
|
e7786b3192 | ||
|
|
4cc3a84e98 | ||
|
|
6e0b048ae7 | ||
|
|
115786798d | ||
|
|
376db9e9e6 | ||
|
|
8abdb80e85 | ||
|
|
656f212608 | ||
|
|
60e07cc4ff | ||
|
|
e132c0a015 | ||
|
|
8e63526f2a | ||
|
|
a5b7c774c1 | ||
|
|
130a5bb8c4 | ||
|
|
3802dd9984 | ||
|
|
7d37397222 | ||
|
|
932454d7b2 | ||
|
|
5d2e6c46aa | ||
|
|
38089195be | ||
|
|
85a6c1d145 | ||
|
|
85d034b7fb | ||
|
|
82b5468fb4 | ||
|
|
89759c44af | ||
|
|
6f66a1d1c3 | ||
|
|
d4bac185f6 | ||
|
|
658bba576e | ||
|
|
31f3c25b18 | ||
|
|
4a1f149051 | ||
|
|
c55a78b8b4 | ||
|
|
3dbf957304 | ||
|
|
8f98f49f1b | ||
|
|
0a8322960b | ||
|
|
63d73c6f86 | ||
|
|
f8cbbe78a2 | ||
|
|
2bb09503c6 | ||
|
|
ba313decd1 | ||
|
|
0d6847c76c | ||
|
|
7b721c7849 | ||
|
|
1fb073fd6a | ||
|
|
484272aed4 | ||
|
|
57422ce793 | ||
|
|
ba855cd064 | ||
|
|
39ac9f7de6 | ||
|
|
4368035da4 | ||
|
|
4391912ee3 | ||
|
|
fc17536f55 | ||
|
|
3bae4338c3 | ||
|
|
f59bdd6b9f | ||
|
|
03f3676b00 | ||
|
|
e0d7079745 | ||
|
|
b7f421481f | ||
|
|
3506cb3f94 | ||
|
|
7280acee42 | ||
|
|
d757fa6306 | ||
|
|
475fc92629 | ||
|
|
f24303dd78 | ||
|
|
180a20f561 | ||
|
|
2e5ca5b9dc | ||
|
|
decee20fd8 | ||
|
|
3d9a60c415 | ||
|
|
a4a7002867 | ||
|
|
96c9a014e6 | ||
|
|
11b4471be9 | ||
|
|
17aea205f7 | ||
|
|
739f54ed87 | ||
|
|
01be5bee72 | ||
|
|
dfcf0da710 | ||
|
|
f47fb87d1b | ||
|
|
bd639ba936 | ||
|
|
e784e62a4e | ||
|
|
e4425dcbf8 | ||
|
|
0dcffe8771 | ||
|
|
2b27f6c452 | ||
|
|
3ba3c728bc | ||
|
|
7193198af2 | ||
|
|
6691afd160 | ||
|
|
59fb220197 | ||
|
|
ff7651d4c8 | ||
|
|
b02abb1f18 | ||
|
|
9f42da4686 | ||
|
|
58e3056374 | ||
|
|
3142865fef | ||
|
|
06e3497a57 | ||
|
|
e49833737d | ||
|
|
7eedc5fef8 | ||
|
|
c442942022 | ||
|
|
2c2652ed1d | ||
|
|
97bcc07aab | ||
|
|
001704b22e | ||
|
|
f1d9cd93ce | ||
|
|
49aa2aa858 | ||
|
|
6274d9a1e9 | ||
|
|
5fa9d91401 | ||
|
|
9acb803ffe | ||
|
|
105924bca3 | ||
|
|
5f12be2037 | ||
|
|
13931c40cb | ||
|
|
ada5d614c5 | ||
|
|
7323d51219 | ||
|
|
f5071f2667 | ||
|
|
0ca0a81644 | ||
|
|
e1bd69b467 | ||
|
|
b17494519e | ||
|
|
13555f505c | ||
|
|
2a65f53084 | ||
|
|
71fe83083e | ||
|
|
0ddb5c859f | ||
|
|
f7b12d5108 | ||
|
|
baa8f4334b | ||
|
|
24a211b190 | ||
|
|
6e82f254b7 | ||
|
|
fbfedcf8d6 | ||
|
|
5b06a0c2a4 | ||
|
|
f3204b0845 | ||
|
|
334314a137 | ||
|
|
8ecc8122b8 | ||
|
|
eb9a119dfe | ||
|
|
313ece62f7 | ||
|
|
5799bcceb2 | ||
|
|
61e7571388 | ||
|
|
6cfd99e40a | ||
|
|
b3bdd9d563 | ||
|
|
5bec3d8471 | ||
|
|
711e46ecfb | ||
|
|
ddd127352f | ||
|
|
784fd825bb | ||
|
|
673a42242d | ||
|
|
3317345d92 | ||
|
|
7958ba38d8 | ||
|
|
2dd7e0c03f | ||
|
|
b94f021567 | ||
|
|
cf50c5b535 | ||
|
|
1b71169565 | ||
|
|
30f2b9d5ed | ||
|
|
999d6a449b | ||
|
|
a65aa2a0d0 | ||
|
|
36fc0b6e8a | ||
|
|
f97362cdb1 | ||
|
|
6398484459 | ||
|
|
07e8c6feaa | ||
|
|
faf351a496 | ||
|
|
cd9315852e | ||
|
|
8c8487231a | ||
|
|
65ebdf0862 | ||
|
|
9704362501 | ||
|
|
f0e87cd85a | ||
|
|
f6e6bf1d6b | ||
|
|
4b4e8f806b | ||
|
|
4141cee13f | ||
|
|
b2ee346f68 | ||
|
|
2220f1ff05 | ||
|
|
7ba48dd666 | ||
|
|
2a48e2fd27 | ||
|
|
63a24c4448 | ||
|
|
787df3362b | ||
|
|
5ad0f60ee3 | ||
|
|
d42f92361a | ||
|
|
0693db3ef5 | ||
|
|
fafb0e2793 | ||
|
|
0a4819d172 | ||
|
|
ee03f32a3e | ||
|
|
f4e01917a2 | ||
|
|
eed9b36c9f | ||
|
|
055192c2a8 | ||
|
|
cca39108dc | ||
|
|
b1bbd5e366 | ||
|
|
afb718f01f | ||
|
|
653b4e0ab7 | ||
|
|
c3d228a9f5 | ||
|
|
15e10caca0 | ||
|
|
46efa85441 | ||
|
|
bb42456653 | ||
|
|
38bf80aa52 | ||
|
|
c5c2aa5348 | ||
|
|
1e67aeb667 | ||
|
|
9ac7bccba5 | ||
|
|
610b82cfb7 | ||
|
|
c8144539d0 | ||
|
|
60f83597ee | ||
|
|
46c0c6085d | ||
|
|
36d4c4af61 | ||
|
|
7406c3dc23 | ||
|
|
24bb15ce29 | ||
|
|
f3ad05dc85 | ||
|
|
bbae3223cb | ||
|
|
8cedb24d31 | ||
|
|
528414dfef | ||
|
|
6e1c58e343 | ||
|
|
002e935193 | ||
|
|
e26d7d346a | ||
|
|
5d917f2578 | ||
|
|
8aecff1879 | ||
|
|
718672119e | ||
|
|
6ec7482662 | ||
|
|
5f3ea7c634 | ||
|
|
1c813a59d0 | ||
|
|
a66236fc3d | ||
|
|
ef9b7022df | ||
|
|
ad7efce855 | ||
|
|
78a9990c3a | ||
|
|
422b9eb6c0 | ||
|
|
703eb271f9 | ||
|
|
2aca32c44a | ||
|
|
56c30bddb1 | ||
|
|
1179b50ad1 | ||
|
|
6ad44441a6 | ||
|
|
2455c09475 | ||
|
|
7a1e07e72a | ||
|
|
aa8e95885a | ||
|
|
54bae94ad9 | ||
|
|
98b7e01069 | ||
|
|
12c7707bc3 | ||
|
|
a8a2c7e345 | ||
|
|
6c7542ec0c | ||
|
|
5ec56cbe77 | ||
|
|
6b79770783 | ||
|
|
e125a83625 | ||
|
|
d05b47e996 | ||
|
|
e1093d0c0c | ||
|
|
25690648d6 | ||
|
|
5c3c4f6288 | ||
|
|
9dec5e9e54 | ||
|
|
ae1fa808da | ||
|
|
ed6839dc99 | ||
|
|
e95d71da0d | ||
|
|
128c8f3c06 | ||
|
|
04f61a1af7 | ||
|
|
974e86b698 | ||
|
|
12c03384b2 | ||
|
|
99ba912d7b | ||
|
|
7607932216 | ||
|
|
acc9c241a3 | ||
|
|
5f5055f4fc | ||
|
|
fc3749e008 | ||
|
|
155734370c | ||
|
|
1095e3d509 | ||
|
|
f7bfa47f2e | ||
|
|
9f6ef14ea1 | ||
|
|
15de08556e | ||
|
|
e7dfa8fcfe | ||
|
|
7a67dc5dfd | ||
|
|
7eb8ef42b7 | ||
|
|
c9c7a4beed | ||
|
|
bcf3aad1b2 | ||
|
|
ad75363028 | ||
|
|
f4ec3939a5 | ||
|
|
aead97d29d | ||
|
|
f468305a2c | ||
|
|
a962f469eb | ||
|
|
63e025cc02 | ||
|
|
b2d332f152 | ||
|
|
e160cf240c | ||
|
|
19a4f70c44 | ||
|
|
dcca3901d5 | ||
|
|
0ee4ffbfbc | ||
|
|
776bc781cd | ||
|
|
b1bb79e19f | ||
|
|
76c69b7bd1 | ||
|
|
15a25a412f | ||
|
|
b511d89dcc | ||
|
|
9512ae7aeb | ||
|
|
5db086e470 | ||
|
|
d63f668291 | ||
|
|
35c72a9570 | ||
|
|
b29f62ddd4 | ||
|
|
525dc17573 | ||
|
|
4d8ed24833 | ||
|
|
aa15d996e0 | ||
|
|
0ec846945d | ||
|
|
03ff158e76 | ||
|
|
b3371b2d63 | ||
|
|
ed64d03bf5 | ||
|
|
3d936dede1 | ||
|
|
33e9c5b1ea | ||
|
|
078c90bbc9 | ||
|
|
2caf2cad5a | ||
|
|
5dec21dd43 | ||
|
|
36aa9bd802 | ||
|
|
bed2f15a72 | ||
|
|
f949f1e88d | ||
|
|
8af202bd5f | ||
|
|
67556a88f1 | ||
|
|
4f8573784d | ||
|
|
c5a46be23e | ||
|
|
47a3c0bf55 | ||
|
|
e8d2a2a461 | ||
|
|
7b72a3fba4 | ||
|
|
dda79e7f27 | ||
|
|
9a104566ba | ||
|
|
b4d8982341 | ||
|
|
5ea3fc28f7 | ||
|
|
0bbf39660e | ||
|
|
791f38762b | ||
|
|
c296b909c7 | ||
|
|
9c7a54f8fc | ||
|
|
4289eab72b | ||
|
|
7b0dbc7445 | ||
|
|
02db904336 | ||
|
|
55140fee3a | ||
|
|
96d881a1f1 | ||
|
|
260a95c05e | ||
|
|
99d633587f | ||
|
|
cf2f0256a2 | ||
|
|
dae8e8dfbd | ||
|
|
6d2d35e82d | ||
|
|
5e23a6b640 | ||
|
|
f2ec502dc2 | ||
|
|
be04f31256 | ||
|
|
85dd881c97 | ||
|
|
0ef2dccd90 | ||
|
|
000ec39c81 | ||
|
|
3160c6ee0b | ||
|
|
9da403e534 | ||
|
|
f19c3408e1 | ||
|
|
38c0e09e8a | ||
|
|
2be4f7cdaf | ||
|
|
cd48272fbb | ||
|
|
a5a146bb02 | ||
|
|
c901bcf321 | ||
|
|
8f3142e532 | ||
|
|
88438d6db4 | ||
|
|
7348734070 | ||
|
|
a99a4a3a2b | ||
|
|
7bc8c3ab5b | ||
|
|
2a58fbdd22 | ||
|
|
d102f5a88a | ||
|
|
8227f7125b | ||
|
|
673535dc08 | ||
|
|
9750489d07 | ||
|
|
53c6224ed0 | ||
|
|
f84794acbe | ||
|
|
9e535e509a | ||
|
|
489210424f | ||
|
|
394abbdb6f | ||
|
|
5fdeb92429 | ||
|
|
11cc39e41b | ||
|
|
b3d5851fdc | ||
|
|
5c25839bab | ||
|
|
fbd314b447 | ||
|
|
86888a32d4 | ||
|
|
37c2d22b10 | ||
|
|
19758ef75d | ||
|
|
519ccc90f7 | ||
|
|
b592d15d1f | ||
|
|
78d70a892c | ||
|
|
dbcf4c1800 | ||
|
|
cbd4630b3c | ||
|
|
92fdfe3f35 | ||
|
|
8b563e5232 | ||
|
|
aeb4875fa5 | ||
|
|
5ebb9c61f9 | ||
|
|
c0e5b8fe15 | ||
|
|
f852efea7d | ||
|
|
664ae905bb | ||
|
|
243b0fd109 | ||
|
|
43b0944403 | ||
|
|
ecc3c9f7b4 | ||
|
|
296249b203 | ||
|
|
8c1145bb9f | ||
|
|
7ad18a68f8 | ||
|
|
99ba396c24 | ||
|
|
f88e9960f2 | ||
|
|
b53466ea0d | ||
|
|
2afda6a470 | ||
|
|
acc8081ef2 | ||
|
|
7433677ead | ||
|
|
4132f7efe6 | ||
|
|
56e0f5797e | ||
|
|
54c142ce78 | ||
|
|
c106aeef2b | ||
|
|
66bde85807 | ||
|
|
08363511a7 | ||
|
|
d6b93b712c | ||
|
|
a85d6d0f4c | ||
|
|
2c1f341099 | ||
|
|
52bb709ca5 | ||
|
|
24ea958748 | ||
|
|
b6143ce54c | ||
|
|
463ea7d34b | ||
|
|
1015302a7f | ||
|
|
c73f5917f8 | ||
|
|
9315cfa488 | ||
|
|
0f58b5780a | ||
|
|
edd5f07d48 | ||
|
|
a7f258f2b1 | ||
|
|
65dcb72cba | ||
|
|
4885c536c8 | ||
|
|
b6204dab78 | ||
|
|
5b5951483a | ||
|
|
194d53569f | ||
|
|
5e8b54be7e | ||
|
|
8dc91e413e | ||
|
|
57cf513b39 | ||
|
|
bb1326860b | ||
|
|
136838e40b | ||
|
|
30d9483504 | ||
|
|
05d3c50866 | ||
|
|
d5e93d863a | ||
|
|
d3f93aae15 | ||
|
|
963e4aa7ec | ||
|
|
5a250ea247 | ||
|
|
bc8d8aafc0 | ||
|
|
f67ab4ec7f | ||
|
|
cf9af20fbd | ||
|
|
3be2a3eb79 | ||
|
|
7dfd18f4fb | ||
|
|
05fc960338 | ||
|
|
21d41ce14b | ||
|
|
1562ba3f97 | ||
|
|
2798e73707 | ||
|
|
89aeee4269 | ||
|
|
d50302fa41 | ||
|
|
8efae54450 | ||
|
|
2785a72789 | ||
|
|
ac55a44761 | ||
|
|
42f1a286a8 | ||
|
|
241fa5d485 | ||
|
|
e87f9c5710 | ||
|
|
c95a6ee3fd | ||
|
|
10b954cb1a | ||
|
|
cf7914b6f8 | ||
|
|
e58e048f00 | ||
|
|
b92cd8a64f | ||
|
|
317aead26d | ||
|
|
e93780c66c | ||
|
|
af8990acf0 | ||
|
|
e41dcf03ad | ||
|
|
0209e8f782 | ||
|
|
50d935171e | ||
|
|
86ee9089e9 | ||
|
|
ba6fe112bb | ||
|
|
15860a7795 | ||
|
|
78b3ad8075 | ||
|
|
f61bda330e | ||
|
|
5c9fceea2c | ||
|
|
32cceebc47 | ||
|
|
9d921df733 | ||
|
|
428f8c183d | ||
|
|
45aae54b32 | ||
|
|
d9ca73bc4c | ||
|
|
c2e24da9bd | ||
|
|
c6ae5ed551 | ||
|
|
0f86a5ee8a | ||
|
|
803e53869b | ||
|
|
a4fc25cca8 | ||
|
|
28fbcf5628 | ||
|
|
3ea73febe4 | ||
|
|
9eb3b3e1c3 | ||
|
|
48e1c39320 | ||
|
|
fe38c7650f | ||
|
|
5e2f5010f8 | ||
|
|
efce4703ca | ||
|
|
94ab4a5ac5 | ||
|
|
58321be1ce |
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.
|
||||
@@ -0,0 +1,17 @@
|
||||
name: Build branch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-all:
|
||||
uses: ./.github/workflows/shared-build.yml
|
||||
with:
|
||||
environment: "testing"
|
||||
@@ -1,192 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
|
||||
jobs:
|
||||
build-platform-linux:
|
||||
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: "Building for platform linux-${{matrix.architecture.name}}"
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(($(nproc) * 16))" >> $GITHUB_ENV
|
||||
# echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV
|
||||
|
||||
- name: Install required packages
|
||||
run: |
|
||||
sudo apt update && sudo apt install -y flex bison
|
||||
|
||||
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
if: matrix.architecture.name != 'amd64'
|
||||
run: sudo apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-DCMAKE_C_COMPILER=clang
|
||||
-DCMAKE_CXX_COMPILER=clang++
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# 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'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: out-linux-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path:
|
||||
${{github.workspace}}/install
|
||||
|
||||
build-platform-windows:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x64', config: 'x64' },
|
||||
{name: 'x86', config: 'Win32' },
|
||||
{name: 'arm64', config: 'ARM64' }
|
||||
]
|
||||
|
||||
name: "Building for platform windows-${{matrix.architecture.name}}"
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-A ${{ matrix.architecture.config }}"
|
||||
|
||||
- name: Install Flex/Bison
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
mkdir thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
|
||||
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
|
||||
cmake --build winflexbison-build --config Release --parallel
|
||||
cmake --install winflexbison-build
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=-A ${{ matrix.architecture.config }} `
|
||||
--log-level=VERBOSE `
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
|
||||
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/install
|
||||
!${{github.workspace}}/install/**/*.pdb
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}-pdb
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/install
|
||||
@@ -20,6 +20,10 @@ on:
|
||||
schedule:
|
||||
- cron: '42 8 * * 1'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
@@ -41,7 +45,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
@@ -52,7 +56,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 +70,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 +83,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}}"
|
||||
@@ -0,0 +1,477 @@
|
||||
name: Shared build workflow
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
environment:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
|
||||
|
||||
jobs:
|
||||
##########################
|
||||
#
|
||||
# Linux
|
||||
# Ubuntu 22.04
|
||||
#
|
||||
# Using this version instead of 24.04 to use a lower GLIBC version (2.34)
|
||||
##########################
|
||||
build-platform-linux:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{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}}"
|
||||
runs-on: "ubuntu-22.04"
|
||||
environment: ${{ inputs.environment }}
|
||||
|
||||
steps:
|
||||
###
|
||||
# Packages
|
||||
###
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
name: Install required packages
|
||||
with:
|
||||
packages: flex bison ninja-build cmake clang libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
|
||||
version: "0.1"
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
if: matrix.architecture.name != 'amd64'
|
||||
with:
|
||||
packages: gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
version: "0.1"
|
||||
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
|
||||
echo "CC=clang" >> $GITHUB_ENV
|
||||
echo "CXX=clang++" >> $GITHUB_ENV
|
||||
echo "CFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
|
||||
# Temporary workaround for PowerPC as the 1.24.0 version doesn't check for altivec
|
||||
# Will use older versions until a new tag is created with this issue resolved
|
||||
if [ ${{ matrix.architecture.name }} != 'powerpc' ] && [ ${{ matrix.architecture.name }} != 'ppc64' ] && [ ${{ matrix.architecture.name }} != 'ppc64el' ]; then
|
||||
echo "OPENAL_REF=1.24.0" >> $GITHUB_ENV
|
||||
else
|
||||
echo "OPENAL_REF=1.23.1" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
###
|
||||
# SDL
|
||||
###
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
# Workaround for when changing the runner OS version
|
||||
cmake-arguments: "-DCACHE_OS_VERSION=Ubuntu_22.04"
|
||||
|
||||
###
|
||||
# OpenAL
|
||||
###
|
||||
|
||||
# soft-oal setup
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: ${{ env.OPENAL_REF }}
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install'
|
||||
cmake --build ./build --config Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
|
||||
###
|
||||
# Project
|
||||
###
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
# Copy libraries
|
||||
mkdir ${{github.workspace}}/package
|
||||
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/package/'
|
||||
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/package/'
|
||||
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
|
||||
###
|
||||
# Artifacts
|
||||
###
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-linux-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path:
|
||||
${{github.workspace}}/package
|
||||
|
||||
##########################
|
||||
#
|
||||
# Microsoft Windows
|
||||
# Windows Server 2022
|
||||
#
|
||||
##########################
|
||||
build-platform-windows:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x64', config: 'x64', toolset: 'x64' },
|
||||
{name: 'x86', config: 'Win32', toolset: 'x64_x86' },
|
||||
{name: 'arm64', config: 'ARM64', toolset: 'x64_arm64' }
|
||||
]
|
||||
|
||||
name: "Building for platform windows-${{matrix.architecture.name}}"
|
||||
runs-on: "windows-2022"
|
||||
environment: ${{ inputs.environment }}
|
||||
|
||||
steps:
|
||||
###
|
||||
# Packages
|
||||
###
|
||||
|
||||
#
|
||||
# Commented out for now, chocolatey servers started complaining about too many requests
|
||||
#
|
||||
#- name: Install required packages
|
||||
# run: |
|
||||
# choco install -y ninja
|
||||
|
||||
- name: Install required packages
|
||||
run: |
|
||||
$DownloadPath="$($env:USERPROFILE)\Downloads"
|
||||
Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-win.zip" -OutFile "$DownloadPath\ninja-win.zip"
|
||||
Expand-Archive -Path "$DownloadPath\ninja-win.zip" -DestinationPath "$($env:PROGRAMFILES)\ninja"
|
||||
echo "$($env:PROGRAMFILES)\ninja" >> $GITHUB_PATH
|
||||
|
||||
- name: Install Flex/Bison
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
mkdir thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
|
||||
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
|
||||
cmake --build winflexbison-build --config Release --parallel
|
||||
cmake --install winflexbison-build --config Release
|
||||
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $env:GITHUB_ENV
|
||||
echo "CC=cl.exe" >> $env:GITHUB_ENV
|
||||
echo "CXX=cl.exe" >> $env:GITHUB_ENV
|
||||
pushd "$($env:PROGRAMFILES)\Microsoft Visual Studio\*\*\VC\Auxiliary\Build"
|
||||
cmd /c "vcvarsall.bat ${{ matrix.architecture.toolset }} & set" | ForEach-Object {
|
||||
if ($_ -match "=") {
|
||||
# Split into key=value
|
||||
$var = $_.split("=", 2);
|
||||
echo "$($var[0])=$($var[1])" >> $env:GITHUB_ENV
|
||||
}
|
||||
}
|
||||
popd
|
||||
|
||||
###
|
||||
# SDL
|
||||
###
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: ""
|
||||
|
||||
###
|
||||
# OpenAL
|
||||
###
|
||||
|
||||
# soft-oal setup
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.24.0'
|
||||
|
||||
# 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 `
|
||||
-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 Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
# 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' }
|
||||
|
||||
###
|
||||
# Project
|
||||
###
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM= `
|
||||
--log-level=VERBOSE `
|
||||
-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' `
|
||||
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
New-Item -ItemType Directory '${{github.workspace}}/package'
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/package'
|
||||
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/package'
|
||||
if (Test-Path ${{github.workspace}}/install/bin) { Copy-Item '${{github.workspace}}/install/bin/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
|
||||
if (Test-Path ${{github.workspace}}/install/lib) { Copy-Item '${{github.workspace}}/install/lib/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
|
||||
|
||||
###
|
||||
# Artifact
|
||||
###
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/package
|
||||
!${{github.workspace}}/package/**/*.pdb
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}-pdb
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/package
|
||||
|
||||
##########################
|
||||
#
|
||||
# Apple macOS
|
||||
# macOS 14
|
||||
#
|
||||
# This version is used as the OS, as older versions are slower.
|
||||
##########################
|
||||
build-platform-macos:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x86_64', triple: 'x86_64-apple-macos10.8'},
|
||||
{name: 'arm64', triple: 'arm64-apple-macos11'}
|
||||
]
|
||||
|
||||
name: "Building for platform macos-${{matrix.architecture.name}}"
|
||||
runs-on: "macos-14"
|
||||
environment: ${{inputs.environment}}
|
||||
|
||||
steps:
|
||||
###
|
||||
# Packages
|
||||
###
|
||||
|
||||
# Install required packages
|
||||
# Paths on x86_64 and ARM64 are different for homebrew
|
||||
- name: Install required packages
|
||||
run: |
|
||||
brew update && brew install git flex bison ninja cmake llvm ninja
|
||||
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
|
||||
echo "CC=clang" >> $GITHUB_ENV
|
||||
echo "CXX=clang++" >> $GITHUB_ENV
|
||||
echo "MACOSX_DEPLOYMENT_TARGET=10.15" >> $GITHUB_ENV
|
||||
|
||||
###
|
||||
# SDL
|
||||
###
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }}
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on"
|
||||
###
|
||||
# OpenAL
|
||||
###
|
||||
|
||||
# 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.24.0'
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on
|
||||
cmake --build ./build --config Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
|
||||
###
|
||||
# Project
|
||||
###
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include/AL' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
# Create hard-link and copy symbolic links
|
||||
mkdir ${{github.workspace}}/package
|
||||
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.0.dylib '${{github.workspace}}/package/'
|
||||
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.1.dylib '${{github.workspace}}/package/'
|
||||
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
|
||||
###
|
||||
# Artifacts
|
||||
###
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-macos-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path:
|
||||
${{github.workspace}}/package
|
||||
+17
-10
@@ -6,7 +6,7 @@ on:
|
||||
- "v*.*.*"
|
||||
|
||||
env:
|
||||
RELEASE_TYPE: ${{ vars.RELEASE_TYPE || 'test' }}
|
||||
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
|
||||
RELEASE_IS_PRERELEASE: ${{ vars.RELEASE_IS_PRELEASE }}
|
||||
|
||||
permissions:
|
||||
@@ -14,7 +14,9 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build-all:
|
||||
uses: ./.github/workflows/build-cmake.yml
|
||||
uses: ./.github/workflows/shared-build.yml
|
||||
with:
|
||||
environment: "release"
|
||||
|
||||
deploy_all:
|
||||
strategy:
|
||||
@@ -25,25 +27,30 @@ 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',
|
||||
'windows-x86',
|
||||
'windows-x86-pdb',
|
||||
'windows-arm64',
|
||||
'windows-arm64-pdb'
|
||||
'windows-arm64-pdb',
|
||||
'macos-x86_64',
|
||||
'macos-arm64'
|
||||
]
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
environment: release
|
||||
runs-on: ubuntu-24.04
|
||||
environment: "release"
|
||||
needs: [build-all]
|
||||
|
||||
env:
|
||||
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,8 +60,8 @@ 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}}'
|
||||
name: '${{github.ref_name}}-${{env.RELEASE_STAGE}}'
|
||||
prerelease: ${{env.RELEASE_IS_PRERELEASE}}
|
||||
files: ${{github.workspace}}/${{ env.RELEASE_NAME }}.zip
|
||||
+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/*
|
||||
+160
-26
@@ -5,23 +5,59 @@ include(TargetArch.cmake)
|
||||
|
||||
target_architecture(TARGET_ARCH)
|
||||
|
||||
set(USE_INTERNAL_LIBS ON)
|
||||
if(USE_SYSTEM_LIBS)
|
||||
set(USE_INTERNAL_LIBS OFF)
|
||||
endif()
|
||||
|
||||
option(USE_INTERNAL_JPEG "If set, use bundled libjpeg." ${USE_INTERNAL_LIBS})
|
||||
option(USE_INTERNAL_MAD "If set, use bundled libmad." ${USE_INTERNAL_LIBS})
|
||||
option(USE_INTERNAL_ZLIB "If set, use bundled zlib." ${USE_INTERNAL_LIBS})
|
||||
|
||||
if(TARGET_GAME_TYPE)
|
||||
message(SEND_ERROR "TARGET_GAME_TYPE is now unsupported, it is now done at runtime.")
|
||||
endif()
|
||||
|
||||
|
||||
set(TARGET_BASE_GAME "main")
|
||||
set(TARGET_BASE_GAME "./")
|
||||
set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
#
|
||||
# Microsoft compiler specific parameters
|
||||
#
|
||||
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()
|
||||
|
||||
#
|
||||
# Clang and GCC specific parameters
|
||||
#
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU" 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()
|
||||
|
||||
#
|
||||
# Clang specific parameters
|
||||
#
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Ignore warnings for code like 'assert("Assert string")'
|
||||
add_compile_options(-Wno-pointer-bool-conversion)
|
||||
endif()
|
||||
|
||||
#
|
||||
# GCC specific parameters
|
||||
#
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# Add this option on gcc to prevent functions from having the STB_GNU_UNIQUE binding
|
||||
# Otherwise, it would prevent libraries from being unloaded
|
||||
# which will cause undefined behavior and crashes due to memory corruption
|
||||
add_compile_options(-fno-gnu-unique)
|
||||
endif()
|
||||
|
||||
if(DEBUG_MEMORY)
|
||||
add_definitions(-D_DEBUG_MEM)
|
||||
endif()
|
||||
@@ -32,6 +68,8 @@ ELSE()
|
||||
set(TARGET_ARCH_SUFFIX ${TARGET_ARCH})
|
||||
ENDIF()
|
||||
|
||||
set(TARGET_BIN_SUFFIX ".${TARGET_ARCH}")
|
||||
|
||||
message(STATUS "Architecture detected: ${TARGET_ARCH}, suffix set to ${TARGET_ARCH_SUFFIX}.")
|
||||
|
||||
IF(WIN32)
|
||||
@@ -45,25 +83,68 @@ ELSE()
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
add_definitions(-D_DEBUG)
|
||||
add_compile_definitions(_DEBUG)
|
||||
|
||||
# NOTE: The following may mess up function importation
|
||||
#if(UNIX)
|
||||
# # Enable all exports so all functions name can be seen during executable crash
|
||||
# set(CMAKE_ENABLE_EXPORTS ON)
|
||||
# message(STATUS "Enabling exports on Unix for backtrace")
|
||||
#endif()
|
||||
ELSE()
|
||||
# Non-debug builds
|
||||
add_compile_definitions(NDEBUG)
|
||||
ENDIF()
|
||||
|
||||
# Common stuff
|
||||
if(APPLE)
|
||||
# macOS doesn't search the executable path by default
|
||||
# so, locate libraries like SDL in the executable path
|
||||
set(CMAKE_INSTALL_RPATH "@executable_path")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Set the visibility to hidden on macOS to prevent shared libraries from
|
||||
# using functions in the executable
|
||||
# it's ok to hide them because the backtrace on macOS will still print the name of the functions
|
||||
add_compile_options(-fvisibility=hidden)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Setup the installation directory
|
||||
#
|
||||
if(WIN32)
|
||||
# By default, both DLLs and EXEs are in the same directory
|
||||
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR bin)
|
||||
set(BIN_INSTALL_SUBDIR ".")
|
||||
set(LIB_INSTALL_SUBDIR ".")
|
||||
else()
|
||||
# Unix
|
||||
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR lib)
|
||||
set(BIN_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
|
||||
set(LIB_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
# By default, put both binaries and shared libraries in the same directory
|
||||
# the game uses internal shared libraries that must be in the same folder as the binaries
|
||||
set(CMAKE_INSTALL_BINDIR ${CMAKE_DEFAULT_INSTALL_RUNTIME_DIR} CACHE PATH "Binary dir")
|
||||
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Library dir")
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#
|
||||
# Common stuff
|
||||
#
|
||||
add_subdirectory("code/qcommon")
|
||||
add_subdirectory("code/gamespy")
|
||||
|
||||
#
|
||||
# Application
|
||||
|
||||
#
|
||||
add_subdirectory("code/sys")
|
||||
|
||||
##
|
||||
## Server app
|
||||
##
|
||||
add_subdirectory("code/server")
|
||||
|
||||
add_executable(omohaaded "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c")
|
||||
@@ -73,24 +154,27 @@ target_compile_features(omohaaded PUBLIC c_variadic_macros)
|
||||
target_link_libraries(omohaaded PRIVATE omohserver)
|
||||
target_link_libraries(omohaaded PRIVATE syslib)
|
||||
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
|
||||
# Gamespy dependency
|
||||
|
||||
# Add the gamespy dependency
|
||||
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BIN_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
INSTALL(TARGETS omohaaded DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION "./" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
|
||||
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")
|
||||
@@ -103,27 +187,77 @@ if (NOT BUILD_NO_CLIENT)
|
||||
target_link_libraries(openmohaa PRIVATE omohclient)
|
||||
target_link_libraries(openmohaa PRIVATE omohrenderer omohsdl)
|
||||
target_link_libraries(openmohaa PRIVATE qcommon qcommon_standalone)
|
||||
|
||||
### Gamespy dependency
|
||||
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/jpeg-8c")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
|
||||
# Add the gamespy dependency
|
||||
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BIN_SUFFIX}")
|
||||
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()
|
||||
if(USE_INTERNAL_JPEG)
|
||||
target_include_directories(openmohaa PUBLIC "code/jpeg-8c")
|
||||
target_link_libraries(openmohaa PRIVATE jpeg8)
|
||||
else()
|
||||
find_package(JPEG REQUIRED)
|
||||
target_include_directories(openmohaa PUBLIC ${JPEG_INCLUDE_DIRS})
|
||||
target_link_libraries(openmohaa PRIVATE ${JPEG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS openmohaa DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION "./" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS openmohaa DESTINATION "./")
|
||||
if(UNIX AND NOT APPLE)
|
||||
#
|
||||
# Desktop entries installation on Unix
|
||||
#
|
||||
set(TARGET_ARCH ${TARGET_BIN_SUFFIX})
|
||||
|
||||
# Configure the .desktop entries with the arch suffix
|
||||
configure_file(
|
||||
misc/linux/org.openmoh.openmohaa.desktop.in
|
||||
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
misc/linux/org.openmoh.openmohaab.desktop.in
|
||||
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
misc/linux/org.openmoh.openmohaas.desktop.in
|
||||
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop
|
||||
@ONLY
|
||||
)
|
||||
|
||||
# Install .desktop entries
|
||||
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
|
||||
install(FILES misc/linux/org.openmoh.openmohaa.metainfo.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo)
|
||||
|
||||
install(FILES misc/openmohaa.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/symbolic/apps/ RENAME org.openmoh.openmohaa.svg)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Launcher
|
||||
#
|
||||
add_subdirectory(code/Launcher)
|
||||
|
||||
#
|
||||
# uninstall target
|
||||
#
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
||||
@@ -1,130 +1,55 @@
|
||||
# OpenMoHAA
|
||||
|
||||
 [](https://github.com/openmoh/openmohaa/releases) [](https://github.com/openmoh/openmohaa/releases)
|
||||
[](https://github.com/openmoh/openmohaa/actions/workflows/branches-build.yml) [](https://github.com/openmoh/openmohaa/releases) [](https://github.com/openmoh/openmohaa/releases)
|
||||
|
||||
 
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```
|
||||
/ _ \ _ __ ___ _ __ | \/ |/ _ \| | | | / \ / \
|
||||
| | | | '_ \ / _ \ '_ \| |\/| | | | | |_| | / _ \ / _ \
|
||||
| |_| | |_) | __/ | | | | | | |_| | _ |/ ___ \ / ___ \
|
||||
\___/| .__/ \___|_| |_|_| |_|\___/|_| |_/_/ \_\/_/ \_\
|
||||
|_|
|
||||
```
|
||||
## Intro
|
||||
|
||||
## Current State
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault** on all platforms/architectures by providing new patches/features. Thanks to the ioquake3 project and the F.A.K.K SDK, OpenMoHAA has already reached more than half of its goal: 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).
|
||||
|
||||
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully implemented, and due to the script engine having a few issues. But the `training` map can be played from start to end. The current focus is on multiplayer.
|
||||
## Getting started
|
||||
|
||||
## Running
|
||||
- [Downloading and installing OpenMoHAA](docs/getting_started_installation.md)
|
||||
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
|
||||
- [Dedicated server configuration](docs/configuration/server.md)
|
||||
|
||||
Backup existing mohaa files, **cgamex86.dll** and **gamex86.dll** (set their extension to **.bak**)
|
||||
## Current state
|
||||
|
||||
a) extract archive to your MOHAA installation directory.
|
||||
### Single-player
|
||||
|
||||
-or-
|
||||
The entire single-player campaign should work (Allied Assault, Spearhead and Breakthrough). If you encounter any bug, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
|
||||
|
||||
b) Copy all pak*.pk3 files and the sound/ directory from your **MOHAA/main** directory into openmohaa's 'main' directory.
|
||||
### Multiplayer
|
||||
|
||||
If you have problems running the game :
|
||||
The Multiplayer part is almost fully stable.
|
||||
|
||||
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from
|
||||
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.
|
||||
|
||||
https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
|
||||
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.
|
||||
|
||||
You can now start a local OpenMOHAA server or play on a server.
|
||||
## Features
|
||||
|
||||
**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.
|
||||
|
||||
With `com_target_game`, OpenMoHAA will support the network protocol accordingly
|
||||
|
||||
### 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 and Vehicle systems are almost fully implemented, but they are not yet stable. This means that they 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, vehicle, and few gameplay bugs |
|
||||
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
|
||||
- [List of 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 and Bison
|
||||
- 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 build can be excluded 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.1
|
||||
|
||||
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04). Use the latest possible version of those compilers.
|
||||
|
||||
SDL2 library is required (libsdl2-dev).
|
||||
|
||||
1 line install command with latest clang version : `sudo apt-get install -y ninja-build cmake make clang-15 lld-15 flex bison libsdl2-dev`
|
||||
|
||||
Example with **CMake**, **clang-15** and **ninja-build** installed:
|
||||
```sh
|
||||
mkdir .cmake && cd .cmake
|
||||
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -G Ninja
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
| | |
|
||||
|-------------------------------------------------------------------------------|----------------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
| | |
|
||||
|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
*More screenshots [here](docs/images)*
|
||||
|
||||
## Third party
|
||||
|
||||
|
||||
+23
-9
@@ -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__
|
||||
@@ -63,12 +71,14 @@ function(target_architecture output_var)
|
||||
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
|
||||
set(osx_arch_ppc TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||
set(osx_arch_ppc64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "i386")
|
||||
set(osx_arch_i386 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "x86_64")
|
||||
set(osx_arch_x86_64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||
set(osx_arch_ppc64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "arm64")
|
||||
set(osx_arch_arm64 TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
|
||||
endif()
|
||||
@@ -79,6 +89,10 @@ function(target_architecture output_var)
|
||||
list(APPEND ARCH ppc)
|
||||
endif()
|
||||
|
||||
if(osx_arch_ppc64)
|
||||
list(APPEND ARCH ppc64)
|
||||
endif()
|
||||
|
||||
if(osx_arch_i386)
|
||||
list(APPEND ARCH i386)
|
||||
endif()
|
||||
@@ -87,8 +101,8 @@ function(target_architecture output_var)
|
||||
list(APPEND ARCH x86_64)
|
||||
endif()
|
||||
|
||||
if(osx_arch_ppc64)
|
||||
list(APPEND ARCH ppc64)
|
||||
if(osx_arch_arm64)
|
||||
list(APPEND ARCH arm64)
|
||||
endif()
|
||||
else()
|
||||
# figure out extension for the source file
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
execute_process(
|
||||
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RESULT_VARIABLE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -0,0 +1,36 @@
|
||||
project(Launcher)
|
||||
|
||||
set(LAUNCHER_SOURCES "${CMAKE_SOURCE_DIR}/code/Launcher/launch_main.cpp")
|
||||
|
||||
if (WIN32)
|
||||
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_win32.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/sys/win_resource.rc")
|
||||
else()
|
||||
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_linux.cpp")
|
||||
endif()
|
||||
|
||||
function (create_launcher name type)
|
||||
if (NOT BUILD_NO_CLIENT)
|
||||
add_executable(openmohaa_launcher_${name} ${LAUNCHER_SOURCES})
|
||||
target_include_directories(openmohaa_launcher_${name} PUBLIC "../qcommon")
|
||||
target_compile_definitions(openmohaa_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type})
|
||||
target_compile_features(openmohaa_launcher_${name} PRIVATE cxx_std_17)
|
||||
set_target_properties(openmohaa_launcher_${name} PROPERTIES OUTPUT_NAME "launch_openmohaa_${name}${TARGET_BIN_SUFFIX}")
|
||||
|
||||
INSTALL(TARGETS openmohaa_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
|
||||
endif()
|
||||
|
||||
#add_executable(omohaaded_launcher_${name} ${LAUNCHER_SOURCES})
|
||||
#target_include_directories(omohaaded_launcher_${name} PUBLIC "../qcommon")
|
||||
#target_compile_definitions(omohaaded_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type} DEDICATED=1)
|
||||
#target_compile_features(omohaaded_launcher_${name} PRIVATE cxx_std_17)
|
||||
#set_target_properties(omohaaded_launcher_${name} PROPERTIES OUTPUT_NAME "launch_omohaaded_${name}${TARGET_BIN_SUFFIX}")
|
||||
#
|
||||
#INSTALL(TARGETS omohaaded_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_INSTALL_SUBDIR})
|
||||
endfunction()
|
||||
|
||||
create_launcher(base 0)
|
||||
create_launcher(spearhead 1)
|
||||
create_launcher(breakthrough 2)
|
||||
@@ -1,38 +1,32 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
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.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
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 Foobar; if not, write to the Free Software
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
#if !( defined __linux__ || defined __FreeBSD__ )
|
||||
#error You should include this file only on Linux/FreeBSD platforms
|
||||
#endif
|
||||
|
||||
#ifndef __GLW_LINUX_H__
|
||||
#define __GLW_LINUX_H__
|
||||
// launch.h: Base interface for starting programs
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *OpenGLLib; // instance of OpenGL library
|
||||
#include "q_platform.h"
|
||||
|
||||
FILE *log_fp;
|
||||
} glwstate_t;
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern glwstate_t glw_state;
|
||||
|
||||
#endif
|
||||
std::filesystem::path GetProgramLocation();
|
||||
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList);
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// main.cpp: Windows implementation of the launcher
|
||||
|
||||
#include "launch.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
extern "C" char** environ;
|
||||
|
||||
std::filesystem::path GetProgramLocation()
|
||||
{
|
||||
char path[FILENAME_MAX];
|
||||
ssize_t count = readlink("/proc/self/exe", path, FILENAME_MAX);
|
||||
|
||||
return std::filesystem::path(std::string(path, (count > 0) ? count : 0)).parent_path();
|
||||
}
|
||||
|
||||
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
|
||||
{
|
||||
pid_t pid;
|
||||
std::string pathString = path.string();
|
||||
size_t argCount = argumentList.size();
|
||||
char** argv;
|
||||
int status;
|
||||
|
||||
argv = new char*[argCount + 2];
|
||||
argv[0] = (char*)pathString.c_str();
|
||||
|
||||
for (size_t i = 0; i < argCount; i++) {
|
||||
argv[i + 1] = (char*)argumentList[i].c_str();
|
||||
}
|
||||
argv[argCount + 1] = NULL;
|
||||
|
||||
//status = posix_spawn(&pid, pathString.c_str(), NULL, NULL, argv, environ);
|
||||
//delete[] argv;
|
||||
//if (status != 0) {
|
||||
// std::cout << "posix_spawn returned error: " << status << std::endl;
|
||||
// return;
|
||||
//}
|
||||
|
||||
//
|
||||
// Using execve rather than posix_spawn
|
||||
// This replaces the current process that is not needed anyway
|
||||
//
|
||||
status = execve(pathString.c_str(), argv, environ);
|
||||
delete[] argv;
|
||||
if (status == -1) {
|
||||
std::cout << "posix_spawn returned error: " << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
waitpid(pid, NULL, 0);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// main.cpp: The launcher
|
||||
|
||||
#include "launch.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
const char* targetGameList[] =
|
||||
{
|
||||
"Base",
|
||||
"Spearhead",
|
||||
"Breakthrough"
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::vector<std::string> argumentList;
|
||||
#if !defined(DEDICATED) || !DEDICATED
|
||||
const char* programName = "openmohaa" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
|
||||
#else
|
||||
const char* programName = "omohaaded" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
|
||||
#endif
|
||||
|
||||
argumentList.push_back("+set");
|
||||
argumentList.push_back("com_target_game");
|
||||
argumentList.push_back(std::to_string(TARGET_GAME));
|
||||
|
||||
for (size_t i = 1; i < argc; i++) {
|
||||
argumentList.push_back(argv[i]);
|
||||
}
|
||||
|
||||
std::cout << "Using the target game: " << targetGameList[TARGET_GAME] << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Expected program name: " << programName << std::endl;
|
||||
|
||||
const std::filesystem::path programLocation = GetProgramLocation();
|
||||
const std::filesystem::path programPath = programLocation / programName;
|
||||
|
||||
std::cout << "Program location: " << programLocation << std::endl;
|
||||
std::cout << "Expected path: " << programPath << std::endl;
|
||||
|
||||
LaunchProgram(programPath, argumentList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// main.cpp: Windows implementation of the launcher
|
||||
|
||||
#include "launch.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
std::filesystem::path GetProgramLocation()
|
||||
{
|
||||
wchar_t path[FILENAME_MAX] = { 0 };
|
||||
GetModuleFileNameW(nullptr, path, FILENAME_MAX);
|
||||
|
||||
return std::filesystem::path(path).parent_path();
|
||||
}
|
||||
|
||||
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
|
||||
{
|
||||
PROCESS_INFORMATION processInfo;
|
||||
STARTUPINFOW startupInfo;
|
||||
BOOL returnValue;
|
||||
std::wstring osCommandLine;
|
||||
std::wstring commandLine;
|
||||
size_t argCount = argumentList.size();
|
||||
|
||||
memset(&processInfo, 0, sizeof(processInfo));
|
||||
memset(&startupInfo, 0, sizeof(startupInfo));
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
for (size_t i = 0; i < argCount; i++) {
|
||||
commandLine += L"\"";
|
||||
commandLine += std::wstring(argumentList[i].begin(), argumentList[i].end());
|
||||
commandLine += L"\"";
|
||||
if (i != argCount - 1) {
|
||||
commandLine += L" ";
|
||||
}
|
||||
}
|
||||
|
||||
osCommandLine = path.wstring();
|
||||
osCommandLine += L" ";
|
||||
osCommandLine += commandLine;
|
||||
|
||||
returnValue = CreateProcessW(
|
||||
path.wstring().c_str(),
|
||||
(LPWSTR)osCommandLine.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
std::filesystem::current_path().wstring().c_str(),
|
||||
&startupInfo,
|
||||
&processInfo
|
||||
);
|
||||
|
||||
if (!returnValue) {
|
||||
std::cout << "Error in CreateProcess: " << GetLastError() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
|
||||
CloseHandle(processInfo.hProcess);
|
||||
CloseHandle(processInfo.hThread);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ set(SOURCES_SHARED
|
||||
"../script/scriptvariable.cpp"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES_BG "../fgame/bg_misc.cpp" "../fgame/bg_pmove.cpp" "../fgame/bg_slidemove.cpp")
|
||||
file(GLOB_RECURSE SOURCES_BG "../fgame/bg_misc.cpp" "../fgame/bg_pmove.cpp" "../fgame/bg_slidemove.cpp" "../fgame/bg_voteoptions.cpp")
|
||||
file(GLOB_RECURSE SOURCES_CGAME "./*.c" "./*.cpp")
|
||||
|
||||
add_library(cgame SHARED ${SOURCES_CGAME} ${SOURCES_BG})
|
||||
@@ -27,16 +27,11 @@ target_compile_features(cgame PUBLIC cxx_nullptr)
|
||||
target_compile_features(cgame PUBLIC c_variadic_macros)
|
||||
target_link_libraries(cgame PUBLIC qcommon)
|
||||
|
||||
set_target_properties(cgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
set_target_properties(cgame PROPERTIES PREFIX "")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_BIN_SUFFIX}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS cgame
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
INSTALL(TARGETS cgame DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR})
|
||||
|
||||
if(MSVC)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION "${TARGET_BASE_GAME}" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
+142
-10
@@ -22,43 +22,175 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_archive.h"
|
||||
#include "cg_commands.h"
|
||||
#include "memarchiver.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
archiver.SetBaseTime(svsTime);
|
||||
commandManager.ArchiveToMemory(archiver);
|
||||
CG_ArchiveVSSGlobals(archiver);
|
||||
}
|
||||
|
||||
void CG_SaveStateToBuffer(void** out, int svsTime)
|
||||
size_t CG_SaveStateToBuffer(void** out, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
MemArchiver archiver;
|
||||
size_t size;
|
||||
|
||||
archiver.SetupForWriting(0x200000);
|
||||
CG_ArchiveStuff(archiver, svsTime);
|
||||
size = archiver.BufferSize();
|
||||
if (size && out) {
|
||||
*out = archiver.ConfiscateBuffer();
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void CG_LoadStateToBuffer(void* state, int size, int svsTime)
|
||||
qboolean CG_LoadStateToBuffer(void* state, size_t size, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
MemArchiver archiver;
|
||||
|
||||
archiver.SetupForReading((byte*)state, size);
|
||||
CG_ArchiveStuff(archiver, svsTime);
|
||||
|
||||
return archiver.FinishedReading();
|
||||
}
|
||||
|
||||
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
int num;
|
||||
int i;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
str tmp;
|
||||
|
||||
archiver.ArchiveInteger(&num);
|
||||
container->ClearObjectList();
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
container->AddObject(tmp);
|
||||
}
|
||||
} else {
|
||||
num = container->NumObjects();
|
||||
archiver.ArchiveInteger(&num);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
str& tmp = container->ObjectAt(i + 1);
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*pTiki = cgi.R_Model_GetHandle(cgi.R_RegisterModel(tmp.c_str()));
|
||||
} else {
|
||||
*pTiki = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*pTiki) {
|
||||
tmp = (*pTiki)->name;
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterModel(tmp.c_str());
|
||||
} else {
|
||||
*handle = (qhandle_t)0;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
tmp = cgi.R_GetModelName(*handle);
|
||||
} else {
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterShader(tmp.c_str());
|
||||
} else {
|
||||
*handle = (qhandle_t)0;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
tmp = cgi.R_GetShaderName(*handle);
|
||||
} else {
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
archiver.ArchiveRaw(&ref->reType, sizeof(ref->reType));
|
||||
archiver.ArchiveInteger(&ref->renderfx);
|
||||
|
||||
CG_ArchiveModelHandle(archiver, &ref->hModel);
|
||||
CG_ArchiveModelHandle(archiver, &ref->hOldModel);
|
||||
|
||||
archiver.ArchiveVec3(ref->lightingOrigin);
|
||||
archiver.ArchiveInteger(&ref->parentEntity);
|
||||
archiver.ArchiveVec3(ref->axis[0]);
|
||||
archiver.ArchiveVec3(ref->axis[1]);
|
||||
archiver.ArchiveVec3(ref->axis[2]);
|
||||
archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
|
||||
archiver.ArchiveVec3(ref->origin);
|
||||
archiver.ArchiveRaw(ref->frameInfo, sizeof(ref->frameInfo));
|
||||
archiver.ArchiveFloat(&ref->actionWeight);
|
||||
archiver.ArchiveShort(&ref->wasframe);
|
||||
archiver.ArchiveFloat(&ref->scale);
|
||||
archiver.ArchiveVec3(ref->oldorigin);
|
||||
archiver.ArchiveInteger(&ref->skinNum);
|
||||
|
||||
CG_ArchiveShaderHandle(archiver, &ref->customShader);
|
||||
archiver.ArchiveRaw(ref->shaderRGBA, sizeof(ref->shaderRGBA));
|
||||
archiver.ArchiveFloat(ref->shaderTexCoord);
|
||||
archiver.ArchiveFloat(&ref->shaderTexCoord[1]);
|
||||
archiver.ArchiveFloat(&ref->shaderTime);
|
||||
|
||||
archiver.ArchiveInteger(&ref->entityNumber);
|
||||
archiver.ArchiveRaw(ref->surfaces, 32);
|
||||
archiver.ArchiveFloat(ref->shader_data);
|
||||
archiver.ArchiveFloat(&ref->shader_data[1]);
|
||||
|
||||
ref->bone_tag = NULL;
|
||||
ref->bone_quat = NULL;
|
||||
ref->of = NULL;
|
||||
ref->nf = NULL;
|
||||
|
||||
CG_ArchiveTikiPointer(archiver, &ref->tiki);
|
||||
|
||||
archiver.ArchiveInteger(&ref->bonestart);
|
||||
archiver.ArchiveInteger(&ref->morphstart);
|
||||
archiver.ArchiveBoolean(&ref->hasMorph);
|
||||
archiver.ArchiveFloat(&ref->radius);
|
||||
archiver.ArchiveFloat(&ref->rotation);
|
||||
}
|
||||
@@ -30,15 +30,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/container.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
class MemArchiver {
|
||||
|
||||
};
|
||||
class MemArchiver;
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CG_SaveStateToBuffer(void** out, int svsTime);
|
||||
void CG_LoadStateToBuffer(void* state, int size, int svsTime);
|
||||
size_t CG_SaveStateToBuffer(void** out, int svsTime);
|
||||
qboolean CG_LoadStateToBuffer(void* state, size_t size, int svsTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime);
|
||||
|
||||
+1348
-361
File diff suppressed because it is too large.
Load diff
+98
-19
@@ -113,9 +113,11 @@ 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;
|
||||
class MemArchiver;
|
||||
|
||||
typedef enum {
|
||||
NOT_RANDOM,
|
||||
@@ -181,6 +183,9 @@ public:
|
||||
float decal_orientation;
|
||||
float decal_radius;
|
||||
float spin_rotation;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline cg_common_data::cg_common_data()
|
||||
@@ -249,6 +254,9 @@ public:
|
||||
spawnthing_t *m_spawnthing;
|
||||
|
||||
void (*touchfcn)(ctempmodel_t *ct, trace_t *trace);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline ctempmodel_t::ctempmodel_t()
|
||||
@@ -315,8 +323,44 @@ public:
|
||||
int lastPhysicsTime;
|
||||
int lastLightingTime;
|
||||
qboolean lastValid;
|
||||
|
||||
public:
|
||||
cvssource_t();
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline cvssource_t::cvssource_t()
|
||||
: next(NULL)
|
||||
, prev(NULL)
|
||||
, stnext(NULL)
|
||||
, stindex(0)
|
||||
, lastRadius(0)
|
||||
, lastDensity(0)
|
||||
, lastColor {0}
|
||||
, lastLighting {0}
|
||||
, newRadius(0)
|
||||
, newDensity(0)
|
||||
, newColor {0}
|
||||
, newLighting {0}
|
||||
, ooRadius(0)
|
||||
, startAlpha(0)
|
||||
, roll(0)
|
||||
, lifeTime(0)
|
||||
, collisionmask(0)
|
||||
, parent(0)
|
||||
, flags(0)
|
||||
, flags2(0)
|
||||
, smokeType(0)
|
||||
, typeInfo(0)
|
||||
, fadeMult(0)
|
||||
, scaleMult(0)
|
||||
, lastPhysicsTime(0)
|
||||
, lastLightingTime(0)
|
||||
, lastValid(qfalse)
|
||||
{}
|
||||
|
||||
class cvssourcestate_t
|
||||
{
|
||||
public:
|
||||
@@ -387,6 +431,9 @@ public:
|
||||
protected:
|
||||
qboolean usedNumbers[256];
|
||||
virtual void RemoveEntity(int entnum);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline enttracker_t::enttracker_t()
|
||||
@@ -437,6 +484,9 @@ public:
|
||||
Vector oldorigin;
|
||||
qboolean active;
|
||||
qboolean lerp_emitter;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
// emitterthing_t is used to keep track of the last time and emitter was updated
|
||||
@@ -452,6 +502,9 @@ public:
|
||||
emittertime_t *GetEmitTime(int entnum);
|
||||
virtual void RemoveEntity(int entnum);
|
||||
qboolean startoff;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void emitterthing_t::RemoveEntity(int entnum)
|
||||
@@ -510,18 +563,23 @@ public:
|
||||
int entity_number;
|
||||
int command_number;
|
||||
int last_command_time;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
// This class is used for keeping track of the last time an entity executed a
|
||||
// particular command. A command number must be assigned externally by the user
|
||||
class commandthing_t : public enttracker_t
|
||||
{
|
||||
Container<commandtime_t *> m_commandtimes; // A list of entity numbers and the last time they
|
||||
// executed a command
|
||||
Container<commandtime_t> m_commandtimes; // A list of entity numbers and the last time they
|
||||
// executed a command
|
||||
|
||||
public:
|
||||
commandtime_t *GetLastCommandTime(int entnum, int commandnum);
|
||||
virtual void RemoveEntity(int entnum);
|
||||
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void commandthing_t::RemoveEntity(int entnum)
|
||||
@@ -532,7 +590,7 @@ inline void commandthing_t::RemoveEntity(int entnum)
|
||||
count = m_commandtimes.NumObjects();
|
||||
|
||||
for (num = count; num >= 1; num--) {
|
||||
ct = m_commandtimes.ObjectAt(num);
|
||||
ct = &m_commandtimes.ObjectAt(num);
|
||||
if (ct->entity_number == entnum) {
|
||||
m_commandtimes.RemoveObjectAt(num);
|
||||
}
|
||||
@@ -543,28 +601,27 @@ inline void commandthing_t::RemoveEntity(int entnum)
|
||||
|
||||
inline commandtime_t *commandthing_t::GetLastCommandTime(int entnum, int commandnum)
|
||||
{
|
||||
int num, count;
|
||||
commandtime_t *ct;
|
||||
int num, count;
|
||||
|
||||
// Search for this entity number
|
||||
count = m_commandtimes.NumObjects();
|
||||
|
||||
for (num = 1; num <= count; num++) {
|
||||
ct = m_commandtimes.ObjectAt(num);
|
||||
commandtime_t *ct = &m_commandtimes.ObjectAt(num);
|
||||
if ((ct->entity_number == entnum) && (ct->command_number == commandnum)) {
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new entry if we didn't find it
|
||||
ct = new commandtime_t;
|
||||
ct->entity_number = entnum;
|
||||
ct->command_number = commandnum;
|
||||
ct->last_command_time = 0;
|
||||
commandtime_t ct;
|
||||
ct.entity_number = entnum;
|
||||
ct.command_number = commandnum;
|
||||
ct.last_command_time = 0;
|
||||
|
||||
m_commandtimes.AddObject(ct);
|
||||
|
||||
return ct;
|
||||
return &m_commandtimes.ObjectAt(m_commandtimes.NumObjects());
|
||||
}
|
||||
|
||||
class spawnthing_t : public emitterthing_t
|
||||
@@ -625,6 +682,9 @@ public:
|
||||
void (*touchfcn)(ctempmodel_t *ct, trace_t *trace);
|
||||
str GetModel(void);
|
||||
void SetModel(str model);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void spawnthing_t::SetModel(str model)
|
||||
@@ -704,6 +764,7 @@ private:
|
||||
void SpawnVSSSource(int count, int timealive);
|
||||
void EventViewKick(Event *ev);
|
||||
void Print(Event *ev);
|
||||
void PrintDeathMsg(Event *ev); // Added in 2.0
|
||||
void StartBlock(Event *ev);
|
||||
void EndBlock(Event *ev);
|
||||
void UpdateSpawnThing(spawnthing_t *ep);
|
||||
@@ -729,6 +790,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);
|
||||
@@ -790,6 +852,7 @@ private:
|
||||
void StopSound(Event *ev);
|
||||
void StopAliasChannel(Event *ev);
|
||||
void LoopSound(Event *ev);
|
||||
void StopLoopSound(Event *ev); // Added in 2.0
|
||||
void Cache(Event *ev);
|
||||
void CacheImage(Event *ev);
|
||||
void CacheFont(Event *ev);
|
||||
@@ -824,8 +887,8 @@ private:
|
||||
void SetClampVel(Event *ev);
|
||||
void SetClampVelAxis(Event *ev);
|
||||
ctempmodel_t *AllocateTempModel(void);
|
||||
qboolean TempModelPhysics(ctempmodel_t *p, float ftime, float time2, float scale);
|
||||
qboolean TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float time2, float scale);
|
||||
qboolean TempModelPhysics(ctempmodel_t *p, float ftime, float scale);
|
||||
qboolean TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float scale);
|
||||
qboolean LerpTempModel(refEntity_t *newEnt, ctempmodel_t *p, float frac);
|
||||
void SpawnEffect(int count, int timealive);
|
||||
void SpawnTempModel(int count);
|
||||
@@ -871,13 +934,13 @@ public:
|
||||
void UpdateEmitter(dtiki_t *tiki, vec3_t axis[3], int entity_number, int parent_number, Vector entity_origin);
|
||||
void UpdateBeam(dtiki_t *tiki, int entity_number, spawnthing_t *beamthing);
|
||||
void PlaySound(
|
||||
str sound_name,
|
||||
str sound_name,
|
||||
const vec3_t origin = NULL,
|
||||
int channel = CHAN_AUTO,
|
||||
float volume = -1,
|
||||
float min_distance = -1,
|
||||
float pitch = -1,
|
||||
int argstype = 0
|
||||
int channel = CHAN_AUTO,
|
||||
float volume = -1,
|
||||
float min_distance = -1,
|
||||
float pitch = -1,
|
||||
int argstype = 0
|
||||
);
|
||||
|
||||
spawnthing_t *InitializeSpawnthing(spawnthing_t *ep);
|
||||
@@ -891,6 +954,7 @@ public:
|
||||
void InitializeEmitters(void);
|
||||
void RemoveClientEntity(int number, dtiki_t *tiki, centity_t *cent, ctempmodel_t *p = NULL);
|
||||
void ClearSwipes(void);
|
||||
void FreeSpawnthing(spawnthing_t *sp);
|
||||
void ResetTempModels(void);
|
||||
void SpawnTempModel(int count, spawnthing_t *sp);
|
||||
|
||||
@@ -921,6 +985,21 @@ public:
|
||||
void ResetTreadMarkSources(Event *ev);
|
||||
void InitializeRainCvars();
|
||||
void InitializeBeams();
|
||||
|
||||
//
|
||||
// archive stuff
|
||||
//
|
||||
int IdForTempModel(const ctempmodel_t *model);
|
||||
ctempmodel_t *TempModelForId(int id);
|
||||
int IdForSpawnThing(const spawnthing_t *sp);
|
||||
spawnthing_t *SpawnThingForId(int id);
|
||||
int IdForVssSource(const cvssource_t *source);
|
||||
cvssource_t *VssSourceForId(int id);
|
||||
|
||||
void ArchiveTempModelPointerToMemory(MemArchiver& archiver, ctempmodel_t **model);
|
||||
void ArchiveSpawnThingPointerToMemory(MemArchiver& archiver, spawnthing_t **sp);
|
||||
void ArchiveVssSourcePointerToMemory(MemArchiver& archiver, cvssource_t **source);
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
class EmitterLoader : public Listener
|
||||
|
||||
+207
-57
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2008-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -159,17 +160,157 @@ baseshader_t *CG_GetShaderUnderCrosshair(qboolean bVerbose, trace_t *pRetTrace)
|
||||
|
||||
static void CG_PrintContentTypes(int iContentFlags)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
if (iContentFlags & CONTENTS_SOLID) {
|
||||
cgi.Printf(" solid");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_LAVA) {
|
||||
cgi.Printf(" lava");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_SLIME) {
|
||||
cgi.Printf(" slime");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_WATER) {
|
||||
cgi.Printf(" water");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_FOG) {
|
||||
cgi.Printf(" fog");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_FENCE) {
|
||||
cgi.Printf(" fence");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_AREAPORTAL) {
|
||||
cgi.Printf(" areaportal");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_PLAYERCLIP) {
|
||||
cgi.Printf(" playerclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_VEHICLECLIP) {
|
||||
cgi.Printf(" vehicleclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_MONSTERCLIP) {
|
||||
cgi.Printf(" monsterclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_WEAPONCLIP) {
|
||||
cgi.Printf(" weaponclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_SHOOTONLY) {
|
||||
cgi.Printf(" shootableonly");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_ORIGIN) {
|
||||
cgi.Printf(" origin");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_TRANSLUCENT) {
|
||||
cgi.Printf(" trans");
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_PrintSurfaceProperties(int iSurfaceFlags)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
if (iSurfaceFlags & SURF_NODAMAGE) {
|
||||
cgi.Printf(" nodamage");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_SLICK) {
|
||||
cgi.Printf(" slick");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_SKY) {
|
||||
cgi.Printf(" sky");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_LADDER) {
|
||||
cgi.Printf(" ladder");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOIMPACT) {
|
||||
cgi.Printf(" noimpact");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOMARKS) {
|
||||
cgi.Printf(" nomarks");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_CASTSHADOW) {
|
||||
cgi.Printf(" castshadow");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NODRAW) {
|
||||
cgi.Printf(" nodraw");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOLIGHTMAP) {
|
||||
cgi.Printf(" nolightmap");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_ALPHASHADOW) {
|
||||
cgi.Printf(" alphashadow");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOSTEPS) {
|
||||
cgi.Printf(" nofootsteps");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NONSOLID) {
|
||||
cgi.Printf(" nonsolid");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_OVERBRIGHT) {
|
||||
cgi.Printf(" overbright");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_BACKSIDE) {
|
||||
cgi.Printf(" backside");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NODLIGHT) {
|
||||
cgi.Printf(" nodlight");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_HINT) {
|
||||
cgi.Printf(" hint");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_PATCH) {
|
||||
cgi.Printf(" patch");
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_PrintSurfaceType(int iSurfType)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
switch (iSurfType & MASK_SURF_TYPE) {
|
||||
case SURF_FOLIAGE:
|
||||
cgi.Printf("foliage");
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
cgi.Printf("snow");
|
||||
break;
|
||||
case SURF_CARPET:
|
||||
cgi.Printf("carpet");
|
||||
break;
|
||||
case SURF_SAND:
|
||||
cgi.Printf("sand");
|
||||
break;
|
||||
case SURF_PUDDLE:
|
||||
cgi.Printf("puddle");
|
||||
break;
|
||||
case SURF_GLASS:
|
||||
cgi.Printf("glass");
|
||||
break;
|
||||
case SURF_GRAVEL:
|
||||
cgi.Printf("gravel");
|
||||
break;
|
||||
case SURF_MUD:
|
||||
cgi.Printf("mud");
|
||||
break;
|
||||
case SURF_DIRT:
|
||||
cgi.Printf("dirt");
|
||||
break;
|
||||
case SURF_GRILL:
|
||||
cgi.Printf("metal grill");
|
||||
break;
|
||||
case SURF_GRASS:
|
||||
cgi.Printf("grass");
|
||||
break;
|
||||
case SURF_ROCK:
|
||||
cgi.Printf("rock");
|
||||
break;
|
||||
case SURF_PAPER:
|
||||
cgi.Printf("paper");
|
||||
break;
|
||||
case SURF_WOOD:
|
||||
cgi.Printf("wood");
|
||||
break;
|
||||
case SURF_METAL:
|
||||
cgi.Printf("metal");
|
||||
break;
|
||||
default:
|
||||
cgi.Printf("!!*none specified*!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CG_GetCHShader(void)
|
||||
@@ -215,9 +356,9 @@ void CG_EditCHShader(void)
|
||||
|
||||
pShader = CG_GetShaderUnderCrosshair(qfalse, NULL);
|
||||
if (pShader) {
|
||||
strcpy(name, "editspecificshader ");
|
||||
strcat(name, pShader->shader);
|
||||
strcat(name, "\n");
|
||||
Q_strncpyz(name, "editspecificshader ", sizeof(name));
|
||||
Q_strcat(name, sizeof(name), pShader->shader);
|
||||
Q_strcat(name, sizeof(name), "\n");
|
||||
cgi.AddCommand(name);
|
||||
} else {
|
||||
cgi.Printf("No surface selected\n");
|
||||
@@ -339,56 +480,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 },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+238
-41
@@ -323,8 +323,12 @@ static void CG_DrawPauseIcon()
|
||||
}
|
||||
w = cgi.R_GetShaderWidth(handle);
|
||||
h = cgi.R_GetShaderHeight(handle);
|
||||
x = w / 4;
|
||||
y = cgs.glconfig.vidHeight - (1.25f * h);
|
||||
if (cg.snap && cg.snap->ps.blend[3] > 0) {
|
||||
y = cgs.glconfig.vidHeight * 0.45f - h / 2.f;
|
||||
} else {
|
||||
y = cgs.glconfig.vidHeight * 0.75f - h / 2.f;
|
||||
}
|
||||
x = (cgs.glconfig.vidWidth - w) / 2.f;
|
||||
|
||||
cgi.R_SetColor(colorWhite);
|
||||
cgi.R_DrawStretchPic(x, y, w, h, 0, 0, 1, 1, handle);
|
||||
@@ -671,22 +675,25 @@ void CG_DrawObjectives()
|
||||
{
|
||||
float vColor[4];
|
||||
float fX, fY;
|
||||
int iNumObjectives;
|
||||
float fObjectivesTop;
|
||||
static float fWidth;
|
||||
float fHeight;
|
||||
int iNumLines[20];
|
||||
int iTotalNumLines;
|
||||
int i;
|
||||
int ii;
|
||||
int iCurrentObjective;
|
||||
float fTimeDelta;
|
||||
const char *pszLocalizedText;
|
||||
const char *pszLine;
|
||||
|
||||
iTotalNumLines = 0;
|
||||
for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) {
|
||||
CG_ProcessConfigString(i);
|
||||
CG_ProcessConfigString(i, qfalse);
|
||||
}
|
||||
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
cg.ObjectivesCurrentAlpha = cg.ObjectivesDesiredAlpha;
|
||||
if (fTimeDelta > 0) {
|
||||
cg.ObjectivesCurrentAlpha =
|
||||
@@ -698,26 +705,30 @@ void CG_DrawObjectives()
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_OBJECTIVES; i++) {
|
||||
if ((cg.Objectives[i].flags & 0xFFFFFFFE)) {
|
||||
iNumLines[i] = 0;
|
||||
// Added in 2.0
|
||||
// Get the minimum Y value, it should be below the compass
|
||||
fObjectivesTop = cgi.UI_GetObjectivesTop();
|
||||
iNumObjectives = 0;
|
||||
|
||||
for (ii = 0; ii < MAX_STRING_CHARS; ii++) {
|
||||
if (cg.Objectives[i].text[ii] == '\n') {
|
||||
iTotalNumLines++;
|
||||
iNumLines[i]++;
|
||||
} else if (!cg.Objectives[i].text[ii]) {
|
||||
iTotalNumLines++;
|
||||
iNumLines[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_OBJECTIVES; i++) {
|
||||
if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iNumObjectives++;
|
||||
iNumLines[i] = 0;
|
||||
pszLocalizedText = cgi.LV_ConvertString(cg.Objectives[i].text);
|
||||
|
||||
for (pszLine = strchr(pszLocalizedText, '\n'); pszLine; pszLine = strchr(pszLine + 1, '\n')) {
|
||||
iNumLines[i]++;
|
||||
}
|
||||
|
||||
iTotalNumLines += iNumLines[i];
|
||||
}
|
||||
|
||||
fX = 25.0;
|
||||
fY = 125.0;
|
||||
fWidth = (float)(25 * iTotalNumLines + 155) + 5.0 - 130.0;
|
||||
fY = fObjectivesTop + 5;
|
||||
fWidth = (float)(iTotalNumLines * 12 + fObjectivesTop + iNumObjectives * 25 + 32) - fY;
|
||||
vColor[2] = 0.2f;
|
||||
vColor[1] = 0.2f;
|
||||
vColor[0] = 0.2f;
|
||||
@@ -726,7 +737,7 @@ void CG_DrawObjectives()
|
||||
cgi.R_DrawStretchPic(fX, fY, 450.0, fWidth, 0.0, 0.0, 1.0, 1.0, cgs.media.objectivesBackShader);
|
||||
|
||||
fX = 30.0;
|
||||
fY = 130.0;
|
||||
fY = fObjectivesTop + 10;
|
||||
vColor[0] = 1.0;
|
||||
vColor[1] = 1.0;
|
||||
vColor[2] = 1.0;
|
||||
@@ -736,12 +747,12 @@ void CG_DrawObjectives()
|
||||
fY = fY + 5.0;
|
||||
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, "_______________________________________________________", fX, fY, -1, 0);
|
||||
fHeight = 155.0;
|
||||
fHeight = fObjectivesTop + 35;
|
||||
|
||||
for (i = 0; i < MAX_OBJECTIVES; ++i) {
|
||||
qhandle_t hBoxShader;
|
||||
|
||||
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) {
|
||||
|
||||
if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -785,7 +796,7 @@ void CG_DrawObjectives()
|
||||
cgi.R_SetColor(vColor);
|
||||
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hBoxShader);
|
||||
|
||||
fHeight += 25 * iNumLines[i];
|
||||
fHeight += iNumLines[i] * 12 + 25;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,6 +934,8 @@ void CG_UpdateAttackerDisplay()
|
||||
|
||||
void CG_UpdateCountdown()
|
||||
{
|
||||
const char* message = "";
|
||||
|
||||
if (!cg.snap) {
|
||||
return;
|
||||
}
|
||||
@@ -933,16 +946,24 @@ void CG_UpdateCountdown()
|
||||
iSecondsLeft = (cgs.matchEndTime - cg.time) / 1000;
|
||||
if (iSecondsLeft >= 0) {
|
||||
iMinutesLeft = iSecondsLeft / 60;
|
||||
cgi.Cvar_Set(
|
||||
"ui_timemessage", va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60)
|
||||
);
|
||||
message = va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60);
|
||||
} else if (!cgs.matchEndTime) {
|
||||
cgi.Cvar_Set("ui_timemessage", "");
|
||||
message = "";
|
||||
}
|
||||
} else {
|
||||
// The match has not started yet
|
||||
cgi.Cvar_Set("ui_timemessage", "Waiting For Players");
|
||||
message = "Waiting For Players";
|
||||
}
|
||||
|
||||
if (strcmp(ui_timemessage->string, message)) {
|
||||
cgi.Cvar_Set("ui_timemessage", message);
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_RemoveStopwatch() {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse_wet\n");
|
||||
}
|
||||
|
||||
void CG_DrawStopwatch()
|
||||
@@ -950,38 +971,55 @@ void CG_DrawStopwatch()
|
||||
int iFraction;
|
||||
|
||||
if (!cg_hud->integer) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cgi.stopWatch->iStartTime) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgi.stopWatch->iStartTime >= cgi.stopWatch->iEndTime) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgi.stopWatch->iEndTime <= cg.time) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cg.ObjectivesCurrentAlpha >= 0.02) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cg.snap && cg.snap->ps.stats[STAT_HEALTH] <= 0) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
if (cgi.stopWatch->eType >= SWT_FUSE_WET) {
|
||||
iFraction = cgi.stopWatch->iEndTime - cgi.stopWatch->iStartTime;
|
||||
} else {
|
||||
iFraction = cgi.stopWatch->iEndTime - cg.time;
|
||||
}
|
||||
|
||||
iFraction = cgi.stopWatch->iEndTime - cg.time;
|
||||
cgi.Cvar_Set("ui_stopwatch", va("%i", iFraction));
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
|
||||
|
||||
switch (cgi.stopWatch->eType) {
|
||||
case SWT_NORMAL:
|
||||
default:
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
|
||||
break;
|
||||
case SWT_FUSE:
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse\n");
|
||||
break;
|
||||
case SWT_FUSE_WET:
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse_wet\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawInstantMessageMenu()
|
||||
@@ -1081,9 +1119,9 @@ void CG_DrawSpectatorView_ver_15()
|
||||
char buf[128];
|
||||
|
||||
iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT];
|
||||
sprintf(buf, "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
|
||||
Com_sprintf(buf, sizeof(buf), "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
|
||||
|
||||
hShader = 0;
|
||||
hShader = 0;
|
||||
color[0] = 0.5;
|
||||
color[1] = 1.0;
|
||||
color[2] = 0.5;
|
||||
@@ -1165,6 +1203,163 @@ void CG_DrawSpectatorView()
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawCrosshair()
|
||||
{
|
||||
centity_t *friendEnt;
|
||||
qhandle_t shader;
|
||||
vec3_t forward;
|
||||
vec3_t end;
|
||||
vec3_t mins, maxs;
|
||||
trace_t trace;
|
||||
float x, y;
|
||||
float width, height;
|
||||
|
||||
shader = (qhandle_t)0;
|
||||
|
||||
if (!cg_hud->integer || !ui_crosshair->integer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cg.snap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cg.snap->ps.pm_flags & PMF_NO_HUD) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cg.snap->ps.stats[STAT_CROSSHAIR]
|
||||
&& (!cg.snap->ps.stats[STAT_INZOOM] || cg.snap->ps.stats[STAT_INZOOM] > 30)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgs.gametype != GT_FFA) {
|
||||
AngleVectorsLeft(cg.refdefViewAngles, forward, NULL, NULL);
|
||||
|
||||
VectorMA(cg.refdef.vieworg, 8192, forward, end);
|
||||
VectorClear(mins);
|
||||
VectorClear(maxs);
|
||||
|
||||
CG_Trace(&trace, cg.refdef.vieworg, mins, maxs, end, 9999, MASK_SOLID, qfalse, qtrue, "CG_DrawCrosshair");
|
||||
|
||||
// ENTITYNUM_WORLD check added in OPM
|
||||
if ((trace.entityNum != ENTITYNUM_NONE && trace.entityNum != ENTITYNUM_WORLD)
|
||||
&& trace.entityNum != cg.snap->ps.clientNum) {
|
||||
int myFlags;
|
||||
|
||||
friendEnt = &cg_entities[trace.entityNum];
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
myFlags = cg_entities[cg.snap->ps.clientNum].currentState.eFlags & EF_ANY_TEAM;
|
||||
} else {
|
||||
// the player will always be considered as an allied
|
||||
// in single-player
|
||||
myFlags = EF_ALLIES;
|
||||
}
|
||||
|
||||
if (((myFlags & EF_ALLIES) && (friendEnt->currentState.eFlags & EF_ALLIES))
|
||||
|| ((myFlags & EF_AXIS) && (friendEnt->currentState.eFlags & EF_AXIS))) {
|
||||
// friend
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair_friend->string);
|
||||
}
|
||||
} else {
|
||||
// enemy
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FFA
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
|
||||
if (shader) {
|
||||
width = cgi.R_GetShaderWidth(shader);
|
||||
height = cgi.R_GetShaderHeight(shader);
|
||||
x = (cgs.glconfig.vidWidth - width) * 0.5f;
|
||||
y = (cgs.glconfig.vidHeight - height) * 0.5f;
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, shader);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawVote()
|
||||
{
|
||||
const char *text;
|
||||
int seconds;
|
||||
int percentYes;
|
||||
int percentNo;
|
||||
int percentUndecided;
|
||||
float x, y;
|
||||
vec4_t col;
|
||||
|
||||
if (!cgs.voteTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgs.voteRefreshed) {
|
||||
cgs.voteRefreshed = qfalse;
|
||||
}
|
||||
|
||||
seconds = (30000 - (cg.time - cgs.voteTime)) / 1000 + 1;
|
||||
if (seconds < 0) {
|
||||
seconds = 0;
|
||||
}
|
||||
|
||||
percentYes = cgs.numVotesYes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
percentNo = cgs.numVotesNo * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
percentUndecided = cgs.numUndecidedVotes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
|
||||
x = 8;
|
||||
y = (cgs.glconfig.vidHeight > 480) ? (cgs.glconfig.vidHeight * 0.725f) : (cgs.glconfig.vidHeight * 0.75f);
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
|
||||
text = va("%s: %s", cgi.LV_ConvertString("Vote Running"), cgs.voteString);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
y += 12;
|
||||
|
||||
text =
|
||||
va("%s: %isec %s: %i%% %s: %i%% %s: %i%%",
|
||||
cgi.LV_ConvertString("Time"),
|
||||
seconds,
|
||||
cgi.LV_ConvertString("Yes"),
|
||||
percentYes,
|
||||
cgi.LV_ConvertString("No"),
|
||||
percentNo,
|
||||
cgi.LV_ConvertString("Undecided"),
|
||||
percentUndecided);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
if (cg.snap && !cg.snap->ps.voted) {
|
||||
col[0] = 0.5;
|
||||
col[1] = 1.0;
|
||||
col[2] = 0.5;
|
||||
col[3] = 1.0;
|
||||
cgi.R_SetColor(col);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("Vote now, it's your patriotic duty!");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("To vote Yes, press F1. To vote No, press F2.");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_SetColor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CG_Draw2D
|
||||
@@ -1183,5 +1378,7 @@ void CG_Draw2D(void)
|
||||
CG_DrawPlayerTeam();
|
||||
CG_DrawPlayerEntInfo();
|
||||
CG_UpdateAttackerDisplay();
|
||||
CG_DrawVote();
|
||||
CG_DrawInstantMessageMenu();
|
||||
CG_DrawCrosshair();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
+30
-4
@@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cg_public.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
class MemArchiver;
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -185,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;
|
||||
|
||||
@@ -338,6 +341,7 @@ extern "C" {
|
||||
float ObjectivesBaseAlpha;
|
||||
float ObjectivesDesiredAlpha;
|
||||
float ObjectivesCurrentAlpha;
|
||||
int ObjectivesCurrentIndex;
|
||||
|
||||
// misc
|
||||
crain_t rain;
|
||||
@@ -394,8 +398,19 @@ extern "C" {
|
||||
int maxclients;
|
||||
int cinematic;
|
||||
int mapChecksum;
|
||||
qboolean useMapChecksum;
|
||||
char mapname[MAX_QPATH];
|
||||
|
||||
//
|
||||
// vote
|
||||
//
|
||||
int voteTime;
|
||||
int numVotesYes;
|
||||
int numVotesNo;
|
||||
int numUndecidedVotes;
|
||||
qboolean voteRefreshed;
|
||||
char voteString[1024];
|
||||
|
||||
//
|
||||
// locally derived information from gamestate
|
||||
//
|
||||
@@ -416,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;
|
||||
@@ -458,6 +474,9 @@ extern "C" {
|
||||
extern cvar_t *cg_hud;
|
||||
extern cvar_t *cg_huddraw_force;
|
||||
extern cvar_t *cg_drawsvlag;
|
||||
extern cvar_t *cg_crosshair;
|
||||
extern cvar_t *cg_crosshair_friend;
|
||||
extern cvar_t *ui_crosshair;
|
||||
extern cvar_t *vm_offset_max;
|
||||
extern cvar_t *vm_offset_speed;
|
||||
extern cvar_t *vm_sway_front;
|
||||
@@ -484,11 +503,12 @@ extern "C" {
|
||||
extern cvar_t *voiceChat;
|
||||
extern cvar_t *cg_shadowscount;
|
||||
extern cvar_t *cg_shadowdebug;
|
||||
extern cvar_t *ui_timemessage;
|
||||
|
||||
//
|
||||
// cg_main.c
|
||||
//
|
||||
void CG_ProcessConfigString(int num);
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly);
|
||||
const char *CG_ConfigString(int index);
|
||||
void CG_AddToTeamChat(const char *str);
|
||||
void CG_NewClientinfo(int clientNum);
|
||||
@@ -530,6 +550,8 @@ extern "C" {
|
||||
// cg_tempmodels.cpp
|
||||
//
|
||||
extern cvar_t *cg_showtempmodels;
|
||||
extern cvar_t *cg_max_tempmodels;
|
||||
extern cvar_t *cg_reserve_tempmodels;
|
||||
extern cvar_t *cg_detail;
|
||||
extern cvar_t *cg_effectdetail;
|
||||
extern cvar_t *cg_effect_physicsrate;
|
||||
@@ -708,8 +730,8 @@ extern "C" {
|
||||
void CG_InitTestTreadMark();
|
||||
void CG_AddTreadMarks();
|
||||
int CG_PermanentMark(
|
||||
const vec3_t origin,
|
||||
const vec3_t dir,
|
||||
vec3_t origin,
|
||||
vec3_t dir,
|
||||
float orientation,
|
||||
float fSScale,
|
||||
float fTScale,
|
||||
@@ -902,7 +924,8 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
|
||||
void CG_InstaMessageGroupD_f(void);
|
||||
void CG_InstaMessageGroupE_f(void);
|
||||
void CG_HudPrint_f(void);
|
||||
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
|
||||
|
||||
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
|
||||
|
||||
//
|
||||
// cg_vehicle.cpp
|
||||
@@ -911,6 +934,9 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
|
||||
//
|
||||
// cg_volumetricsmoke.cpp
|
||||
void CG_ResetVSSSources(void);
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveVSSGlobals(MemArchiver& archiver);
|
||||
#endif
|
||||
void CG_AddVSSSources(void);
|
||||
|
||||
extern cvar_t *vss_draw;
|
||||
|
||||
+283
-160
@@ -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;
|
||||
@@ -80,6 +81,9 @@ cvar_t *cg_acidtrip;
|
||||
cvar_t *cg_hud;
|
||||
cvar_t *cg_huddraw_force;
|
||||
cvar_t *cg_drawsvlag;
|
||||
cvar_t *cg_crosshair;
|
||||
cvar_t *cg_crosshair_friend;
|
||||
cvar_t *ui_crosshair;
|
||||
cvar_t *vm_offset_max;
|
||||
cvar_t *vm_offset_speed;
|
||||
cvar_t *vm_sway_front;
|
||||
@@ -106,6 +110,7 @@ cvar_t *vm_lean_lower;
|
||||
cvar_t *voiceChat;
|
||||
cvar_t *cg_shadowscount;
|
||||
cvar_t *cg_shadowdebug;
|
||||
cvar_t *ui_timemessage;
|
||||
|
||||
/*
|
||||
=================
|
||||
@@ -151,14 +156,23 @@ 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);
|
||||
cg_huddraw_force = cgi.Cvar_Get("cg_huddraw_force", "0", CVAR_SAVEGAME);
|
||||
cg_drawsvlag = cgi.Cvar_Get("cg_drawsvlag", "1", CVAR_ARCHIVE);
|
||||
cg_crosshair = cgi.Cvar_Get("cg_crosshair", "textures/hud/crosshair", CVAR_ARCHIVE);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cg_crosshair_friend = cgi.Cvar_Get("cg_crosshair_friend", "textures/hud/crosshair_friend", CVAR_ARCHIVE);
|
||||
} else {
|
||||
// on 1.11 and below, fallback to standard crosshair
|
||||
// as it doesn't have crosshair_friend texture
|
||||
cg_crosshair_friend = cgi.Cvar_Get("cg_crosshair_friend", "textures/hud/crosshair", CVAR_ARCHIVE);
|
||||
}
|
||||
ui_crosshair = cgi.Cvar_Get("ui_crosshair", "1", CVAR_ARCHIVE);
|
||||
vm_offset_max = cgi.Cvar_Get("vm_offset_max", "8.0", 0);
|
||||
vm_offset_speed = cgi.Cvar_Get("vm_offset_speed", "8.0", 0);
|
||||
vm_sway_front = cgi.Cvar_Get("vm_sway_front", "0.1", 0);
|
||||
@@ -184,53 +198,111 @@ void CG_RegisterCvars(void)
|
||||
vm_lean_lower = cgi.Cvar_Get("vm_lean_lower", "0.1", 0);
|
||||
voiceChat = cgi.Cvar_Get("cg_voicechat", "1", 0);
|
||||
|
||||
ui_timemessage = cgi.Cvar_Get("ui_timemessage", "", 0);
|
||||
|
||||
// see if we are also running the server on this machine
|
||||
temp = cgi.Cvar_Get("sv_running", "0", 0);
|
||||
cgs.localServer = temp->integer;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_RegisterSoundsForFile
|
||||
|
||||
Register the specified ubersound source file
|
||||
================
|
||||
*/
|
||||
void CG_RegisterSoundsForFile(const char *name)
|
||||
{
|
||||
int startTime;
|
||||
int endTime;
|
||||
|
||||
Com_Printf("\n\n-----------PARSING '%s'------------\n", name);
|
||||
Com_Printf(
|
||||
"Any SetCurrentTiki errors means that tiki wasn't prefetched and tiki-specific sounds for it won't work. To "
|
||||
"fix prefetch the tiki. Ignore if you don't use that tiki on this level.\n"
|
||||
);
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(name, qfalse, NULL);
|
||||
endTime = cgi.Milliseconds();
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", (float)(endTime - startTime) / 1000.0);
|
||||
Com_Printf("-------------PARSING '%s' DONE---------------\n\n", name);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
qsort_compare_strings
|
||||
|
||||
perform case-insensitive sorting
|
||||
=================
|
||||
*/
|
||||
int qsort_compare_strings(const void *s1, const void *s2)
|
||||
{
|
||||
return Q_stricmp(*(const char **)s1, *(const char **)s2);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_RegisterSounds
|
||||
|
||||
called during a precache command
|
||||
Called during a precache command
|
||||
=================
|
||||
*/
|
||||
void CG_RegisterSounds(void)
|
||||
{
|
||||
int startTime;
|
||||
int endTime;
|
||||
char filename[MAX_QPATH];
|
||||
char **fileList;
|
||||
int numFiles;
|
||||
int i;
|
||||
|
||||
Com_Printf("\n\n-----------PARSING UBERSOUND------------\n");
|
||||
Com_Printf(
|
||||
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
|
||||
"tiki-specific sounds for it won't work. To fix prefe"
|
||||
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
|
||||
);
|
||||
Com_sprintf(filename, sizeof(filename), "ubersound/ubersound.scr");
|
||||
fileList = cgi.FS_ListFilteredFiles("ubersound/", "scr", "*.scr", qfalse, &numFiles, qtrue);
|
||||
if (cg_target_game >= TG_MOHTA) {
|
||||
// Fixed in 2.0
|
||||
// The behavior has changed, all aliases get cleared
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cgi.Alias_Clear();
|
||||
}
|
||||
} else {
|
||||
if (!cgs.localServer) {
|
||||
cgi.Alias_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
qsort(fileList, numFiles, sizeof(char *), &qsort_compare_strings);
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(filename, 0, 0);
|
||||
endTime = cgi.Milliseconds();
|
||||
for (i = 0; i < numFiles; i++) {
|
||||
// Added in 2.0
|
||||
// Since 2.0, all files in the ubersound folder
|
||||
// are parsed
|
||||
CG_RegisterSoundsForFile(va("ubersound/%s", fileList[i]));
|
||||
}
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", (endTime - startTime) / 1000.0f);
|
||||
cgi.FS_FreeFileList(fileList);
|
||||
}
|
||||
|
||||
Com_Printf("-------------UBERSOUND DONE---------------\n\n");
|
||||
Com_Printf("\n\n-----------PARSING UBERDIALOG------------\n");
|
||||
Com_Printf(
|
||||
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
|
||||
"tiki-specific sounds for it won't work. To fix prefe"
|
||||
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
|
||||
);
|
||||
Com_sprintf(filename, sizeof(filename), "ubersound/uberdialog.scr");
|
||||
/*
|
||||
================
|
||||
CG_IsHandleUnique
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(filename, 0, 0);
|
||||
endTime = cgi.Milliseconds() - startTime;
|
||||
Check if the model handle is unique
|
||||
================
|
||||
*/
|
||||
static qboolean CG_IsHandleUnique(qhandle_t handle) {
|
||||
int i;
|
||||
int numRef;
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", endTime / 1000.0f);
|
||||
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
|
||||
numRef = 0;
|
||||
for (i = 0; i < MAX_MODELS; i++) {
|
||||
if (cgs.model_draw[i] == handle) {
|
||||
numRef++;
|
||||
if (numRef >= 2) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -238,86 +310,17 @@ void CG_RegisterSounds(void)
|
||||
CG_ProcessConfigString
|
||||
================
|
||||
*/
|
||||
void CG_ProcessConfigString(int num)
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
{
|
||||
const char *str = CG_ConfigString(num);
|
||||
int i;
|
||||
const char* str;
|
||||
int i;
|
||||
|
||||
switch (num) {
|
||||
case CS_RAIN_DENSITY:
|
||||
cg.rain.density = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEED:
|
||||
cg.rain.speed = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEEDVARY:
|
||||
cg.rain.speed_vary = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_SLANT:
|
||||
cg.rain.slant = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_LENGTH:
|
||||
cg.rain.length = atof(str);
|
||||
return;
|
||||
case CS_RAIN_MINDIST:
|
||||
cg.rain.min_dist = atof(str);
|
||||
return;
|
||||
case CS_RAIN_WIDTH:
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
} else {
|
||||
strcpy(cg.rain.shader[0], str);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
|
||||
objective->flags = atoi(Info_ValueForKey(str, "flags"));
|
||||
strcpy(objective->text, Info_ValueForKey(str, "text"));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case CS_MUSIC:
|
||||
cgi.MUSIC_NewSoundtrack(str);
|
||||
return;
|
||||
case CS_WARMUP:
|
||||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf(str, "%f %d", &cg.sky_alpha, &cg.sky_portal);
|
||||
return;
|
||||
case CS_SERVERINFO:
|
||||
CG_ParseServerinfo();
|
||||
return;
|
||||
case CS_LEVEL_START_TIME:
|
||||
cgs.levelStartTime = atoi(str);
|
||||
return;
|
||||
case CS_MATCHEND:
|
||||
cgs.matchEndTime = atoi(str);
|
||||
return;
|
||||
}
|
||||
str = CG_ConfigString(num);
|
||||
|
||||
if (num >= CS_MODELS && num < CS_MODELS + MAX_MODELS) {
|
||||
qhandle_t hOldModel = cgs.model_draw[num - CS_MODELS];
|
||||
|
||||
if (str && str[0]) {
|
||||
if (str && str[0] && !modelOnly) {
|
||||
qhandle_t hModel = cgi.R_RegisterServerModel(str);
|
||||
dtiki_t *tiki;
|
||||
|
||||
@@ -334,43 +337,153 @@ void CG_ProcessConfigString(int num)
|
||||
}
|
||||
} else {
|
||||
// clear out the model
|
||||
if (hOldModel) {
|
||||
if (hOldModel && CG_IsHandleUnique(hOldModel)) {
|
||||
// Handle uniqueness added in OPM
|
||||
cgi.R_UnregisterServerModel(hOldModel);
|
||||
}
|
||||
cgs.model_draw[num - CS_MODELS] = 0;
|
||||
}
|
||||
} else if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS) {
|
||||
size_t len = strlen(str);
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
strcpy(buf, str);
|
||||
}
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
if (buf[0] != '*') {
|
||||
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
|
||||
if (!modelOnly) {
|
||||
switch (num) {
|
||||
case CS_RAIN_DENSITY:
|
||||
cg.rain.density = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEED:
|
||||
cg.rain.speed = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEEDVARY:
|
||||
cg.rain.speed_vary = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_SLANT:
|
||||
cg.rain.slant = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_LENGTH:
|
||||
cg.rain.length = atof(str);
|
||||
return;
|
||||
case CS_RAIN_MINDIST:
|
||||
cg.rain.min_dist = atof(str);
|
||||
return;
|
||||
case CS_RAIN_WIDTH:
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
Q_strncpyz(cg.rain.currentShader, str, sizeof(cg.rain.currentShader));
|
||||
if (cg.rain.numshaders) {
|
||||
// Fixed in OPM
|
||||
// not sure why some maps set a digit at the end...
|
||||
size_t len = strlen(cg.rain.currentShader);
|
||||
if (isdigit(cg.rain.currentShader[len - 1])) {
|
||||
cg.rain.currentShader[len - 1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES) {
|
||||
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
|
||||
} else if (num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS) {
|
||||
const char *value;
|
||||
|
||||
value = Info_ValueForKey(str, "name");
|
||||
if (value) {
|
||||
strncpy(cg.clientinfo[num - CS_PLAYERS].name, value, sizeof(cg.clientinfo[num - CS_PLAYERS].name));
|
||||
} else {
|
||||
strncpy(
|
||||
cg.clientinfo[num - CS_PLAYERS].name, "UnnamedSoldier", sizeof(cg.clientinfo[num - CS_PLAYERS].name)
|
||||
);
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
|
||||
value = Info_ValueForKey(str, "team");
|
||||
if (value) {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = atoi(value);
|
||||
} else {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = TEAM_NONE;
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
|
||||
objective->flags = atoi(Info_ValueForKey(str, "flags"));
|
||||
Q_strncpyz(objective->text, Info_ValueForKey(str, "text"), sizeof(objective->text));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case CS_MUSIC:
|
||||
cgi.MUSIC_NewSoundtrack(str);
|
||||
return;
|
||||
case CS_WARMUP:
|
||||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
cg.farclipOverride = 0;
|
||||
cg.farplaneColorOverride[0] = -1;
|
||||
cg.farplaneColorOverride[1] = -1;
|
||||
cg.farplaneColorOverride[2] = -1;
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf(str, "%f %d", &cg.sky_alpha, &cg.sky_portal);
|
||||
return;
|
||||
case CS_SERVERINFO:
|
||||
CG_ParseServerinfo();
|
||||
return;
|
||||
case CS_LEVEL_START_TIME:
|
||||
cgs.levelStartTime = atoi(str);
|
||||
return;
|
||||
case CS_VOTE_TIME:
|
||||
cgs.voteTime = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_STRING:
|
||||
Q_strncpyz(cgs.voteString, str, sizeof(cgs.voteString));
|
||||
break;
|
||||
case CS_VOTE_YES:
|
||||
cgs.numVotesYes = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_NO:
|
||||
cgs.numVotesNo = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_UNDECIDED:
|
||||
cgs.numUndecidedVotes = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_MATCHEND:
|
||||
cgs.matchEndTime = atoi(str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS) {
|
||||
size_t len = strlen(str);
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
Q_strncpyz(buf, str, sizeof(buf));
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
if (buf[0] != '*') {
|
||||
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
|
||||
}
|
||||
}
|
||||
} else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES) {
|
||||
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
|
||||
} else if (num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS) {
|
||||
const char *value;
|
||||
|
||||
value = Info_ValueForKey(str, "name");
|
||||
if (value) {
|
||||
strncpy(cg.clientinfo[num - CS_PLAYERS].name, value, sizeof(cg.clientinfo[num - CS_PLAYERS].name));
|
||||
} else {
|
||||
strncpy(
|
||||
cg.clientinfo[num - CS_PLAYERS].name, "UnnamedSoldier", sizeof(cg.clientinfo[num - CS_PLAYERS].name)
|
||||
);
|
||||
}
|
||||
|
||||
value = Info_ValueForKey(str, "team");
|
||||
if (value) {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = atoi(value);
|
||||
} else {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = TEAM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,14 +536,14 @@ void CG_PrepRefresh(void)
|
||||
cgs.media.binocularsOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/binocularsoverlay");
|
||||
cgs.media.hudDrawFont = cgi.R_LoadFont("verdana-14");
|
||||
cgs.media.attackerFont = cgi.R_LoadFont("facfont-20");
|
||||
cgs.media.objectiveFont = cgi.R_LoadFont("courier-16");
|
||||
cgs.media.objectiveFont = cgi.R_LoadFont("facfont-20"); // was courier-16 before 2.0
|
||||
cgs.media.objectivesBackShader = cgi.R_RegisterShaderNoMip("textures/hud/objectives_backdrop");
|
||||
cgs.media.checkedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/filledbox");
|
||||
cgs.media.uncheckedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/emptybox");
|
||||
|
||||
// go through all the configstrings and process them
|
||||
for (i = CS_SYSTEMINFO + 1; i < MAX_CONFIGSTRINGS; i++) {
|
||||
CG_ProcessConfigString(i);
|
||||
CG_ProcessConfigString(i, qfalse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,6 +582,7 @@ Displays the info screen while loading media
|
||||
void CG_GameStateReceived(void)
|
||||
{
|
||||
const char *s;
|
||||
int checksum;
|
||||
|
||||
// clear everything
|
||||
memset(&cg, 0, sizeof(cg));
|
||||
@@ -495,7 +609,10 @@ void CG_GameStateReceived(void)
|
||||
CG_ParseServerinfo();
|
||||
|
||||
// load the new map
|
||||
cgi.CM_LoadMap(cgs.mapname);
|
||||
cgi.CM_LoadMap(cgs.mapname, &checksum);
|
||||
if (cgs.useMapChecksum && checksum != cgs.mapChecksum && cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cgi.Error(ERR_DROP, "Client/Server map checksum mismatch: %x/%x", checksum, cgs.mapChecksum);
|
||||
}
|
||||
|
||||
CG_InitMarks();
|
||||
|
||||
@@ -539,16 +656,6 @@ void CG_ServerRestarted(void)
|
||||
CG_InitializeObjectives();
|
||||
}
|
||||
|
||||
void *CG_Malloc(int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void CG_Free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_Init
|
||||
@@ -559,17 +666,20 @@ Called after every level change or subsystem restart
|
||||
void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverCommandSequence, int clientNum)
|
||||
{
|
||||
cgi = *imported;
|
||||
#if _DEBUG
|
||||
cgi.Malloc = &CG_Malloc;
|
||||
cgi.Free = &CG_Free;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
memset(&cg, 0, sizeof(cg));
|
||||
memset(&cgs, 0, sizeof(cgs));
|
||||
// clear fog values
|
||||
cg.farclipOverride = 0;
|
||||
cg.farplaneColorOverride[0] = -1;
|
||||
cg.farplaneColorOverride[1] = -1;
|
||||
cg.farplaneColorOverride[2] = -1;
|
||||
|
||||
cg.clientNum = clientNum;
|
||||
cgs.processedSnapshotNum = serverMessageNum;
|
||||
@@ -626,11 +736,14 @@ Called before every level change or subsystem restart
|
||||
void CG_Shutdown(void)
|
||||
{
|
||||
L_ShutdownEvents();
|
||||
// Shutdown radar
|
||||
cgi.CL_InitRadar(NULL, NULL, -1);
|
||||
|
||||
// some mods may need to do cleanup work here,
|
||||
// like closing files or archiving session data
|
||||
|
||||
// hide the stats screen
|
||||
cgi.UI_HideMenu("StatsScreen", 1);
|
||||
cgi.UI_HideMenu("StatsScreen", qtrue);
|
||||
|
||||
// reset the scoreboard
|
||||
CG_PrepScoreBoardInfo();
|
||||
@@ -745,7 +858,7 @@ void Com_Error(int level, const char *error, ...)
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, error);
|
||||
vsprintf(text, error, argptr);
|
||||
Q_vsnprintf(text, sizeof(text), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
cgi.Error(level, "%s", text);
|
||||
@@ -757,7 +870,7 @@ void Com_Printf(const char *msg, ...)
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, msg);
|
||||
vsprintf(text, msg, argptr);
|
||||
Q_vsnprintf(text, sizeof(text), msg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
cgi.Printf("%s", text);
|
||||
@@ -788,10 +901,20 @@ void CG_ParseFogInfo_ver_15(const char *str)
|
||||
|
||||
void CG_ParseFogInfo_ver_6(const char *str)
|
||||
{
|
||||
cg.farclipOverride = 0.0;
|
||||
//
|
||||
// clear all unsupported fields in protocol below version 15
|
||||
//
|
||||
|
||||
// don't set the farplane_bias 0, otherwise the renderer will set a minimum value
|
||||
cg.farplane_bias = 0.001f;
|
||||
cg.skyboxFarplane = 0;
|
||||
cg.skyboxSpeed = 0;
|
||||
cg.renderTerrain = qtrue;
|
||||
cg.farclipOverride = -1.0;
|
||||
cg.farplaneColorOverride[0] = -1.0;
|
||||
cg.farplaneColorOverride[1] = -1.0;
|
||||
cg.farplaneColorOverride[2] = -1.0;
|
||||
|
||||
sscanf(
|
||||
str,
|
||||
"%d %f %f %f %f",
|
||||
|
||||
+1173
-283
File diff suppressed because it is too large.
Load diff
+408
-126
@@ -180,6 +180,337 @@ void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_InterpolateAnimParms
|
||||
|
||||
Interpolate between current and next entity
|
||||
===============
|
||||
*/
|
||||
void CG_InterpolateAnimParms(entityState_t* state, entityState_t* sNext, refEntity_t* model)
|
||||
{
|
||||
static cvar_t *vmEntity = NULL;
|
||||
int i;
|
||||
float t;
|
||||
float animLength;
|
||||
float t1, t2;
|
||||
|
||||
if (!vmEntity) {
|
||||
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
|
||||
}
|
||||
|
||||
if (sNext && sNext->usageIndex == state->usageIndex) {
|
||||
t1 = cg.time - cg.snap->serverTime;
|
||||
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
|
||||
t = t1 / t2;
|
||||
|
||||
model->actionWeight = (sNext->actionWeight - state->actionWeight) * t + state->actionWeight;
|
||||
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (sNext->frameInfo[i].weight) {
|
||||
model->frameInfo[i].index = sNext->frameInfo[i].index;
|
||||
if (sNext->frameInfo[i].index == state->frameInfo[i].index && state->frameInfo[i].weight) {
|
||||
model->frameInfo[i].weight =
|
||||
(sNext->frameInfo[i].weight - state->frameInfo[i].weight) * t + state->frameInfo[i].weight;
|
||||
|
||||
if (sNext->frameInfo[i].time >= state->frameInfo[i].time) {
|
||||
model->frameInfo[i].time = (sNext->frameInfo[i].time - state->frameInfo[i].time) * t + state->frameInfo[i].time;
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (animLength + sNext->frameInfo[i].time - state->frameInfo[i].time) * t
|
||||
+ state->frameInfo[i].time;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
while (t2 > animLength) {
|
||||
t2 -= animLength;
|
||||
|
||||
if (t2 == t1) {
|
||||
t2 = 1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = t2;
|
||||
}
|
||||
|
||||
model->frameInfo[i].time = t2;
|
||||
}
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
|
||||
}
|
||||
|
||||
model->frameInfo[i].time = Q_max(0, t1);
|
||||
model->frameInfo[i].weight = sNext->frameInfo[i].weight;
|
||||
}
|
||||
} else if (sNext->frameInfo[i].index == state->frameInfo[i].index) {
|
||||
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + state->frameInfo[i].time;
|
||||
}
|
||||
|
||||
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
|
||||
model->frameInfo[i].time = Q_min(animLength, t1);
|
||||
model->frameInfo[i].weight = (1.0 - t) * state->frameInfo[i].weight;
|
||||
} else {
|
||||
model->frameInfo[i].index = -1;
|
||||
model->frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no next state, don't blend anims
|
||||
|
||||
model->actionWeight = state->actionWeight;
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (state->frameInfo[i].weight) {
|
||||
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
|
||||
model->frameInfo[i].time = state->frameInfo[i].time;
|
||||
model->frameInfo[i].weight = state->frameInfo[i].weight;
|
||||
} else {
|
||||
model->frameInfo[i].index = -1;
|
||||
model->frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vmEntity->integer == state->number) {
|
||||
static cvar_t *curanim;
|
||||
if (!curanim) {
|
||||
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
|
||||
}
|
||||
|
||||
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model->frameInfo[curanim->integer].time));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastFootShadow
|
||||
|
||||
Cast complex foot shadow using lights
|
||||
===============
|
||||
*/
|
||||
void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag, refEntity_t* model)
|
||||
{
|
||||
int i;
|
||||
float fAlpha;
|
||||
float fLength;
|
||||
float fWidth;
|
||||
float fAlphaOfs;
|
||||
float fOfs;
|
||||
float fPitchCos;
|
||||
vec3_t vPos;
|
||||
vec3_t vEnd;
|
||||
vec3_t vDelta;
|
||||
vec3_t vLightAngles;
|
||||
trace_t trace;
|
||||
orientation_t oFoot;
|
||||
|
||||
VectorCopy(model->origin, vPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iTag);
|
||||
VectorMA(oFoot.origin, 2, oFoot.axis[1], vEnd);
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vPos, vEnd[i], model->axis[i], vPos);
|
||||
}
|
||||
|
||||
if (cg_shadowdebug->integer)
|
||||
{
|
||||
vec3_t vDir;
|
||||
|
||||
//
|
||||
// show debug lines
|
||||
//
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[0][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[1][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 0.0, 1.0, 0.0, 1.0);
|
||||
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[2][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 0.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
// calculate the direction
|
||||
VectorSubtract(vLightPos, vPos, vDelta);
|
||||
VectorNormalizeFast(vDelta);
|
||||
vectoangles(vDelta, vLightAngles);
|
||||
|
||||
// normalize to 180 degrees
|
||||
if (vLightAngles[0] > 180) {
|
||||
vLightAngles[0] -= 360;
|
||||
}
|
||||
|
||||
if (vLightAngles[0] > -5.7319679) {
|
||||
// FIXME: what is -5.7319679?
|
||||
return;
|
||||
}
|
||||
|
||||
fPitchCos = cos(DEG2RAD(vLightAngles[0]));
|
||||
if (fPitchCos > 0.955) {
|
||||
fAlpha = 1.0 - (fPitchCos - 0.955) * 25;
|
||||
} else {
|
||||
fAlpha = 1.0;
|
||||
}
|
||||
|
||||
fLength = fPitchCos * fPitchCos * 32.0 + fPitchCos * 8.0 + 10.0;
|
||||
fOfs = 0.5 - (-4.1 / tan(DEG2RAD(vLightAngles[0])) + 4.0 - fLength) / fLength * 0.5;
|
||||
VectorMA(vPos, -96.0, vDelta, vEnd);
|
||||
CG_Trace(&trace, vPos, vec3_origin, vec3_origin, vEnd, 0, MASK_FOOTSHADOW, qfalse, qtrue, "CG_CastFootShadow");
|
||||
|
||||
if (cg_shadowdebug->integer)
|
||||
{
|
||||
cgi.R_DebugLine(vPos, vLightPos, 0.75, 0.75, 0.5, 1.0);
|
||||
cgi.R_DebugLine(vPos, vEnd, 1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if (trace.fraction == 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
trace.fraction -= 0.0427f;
|
||||
if (trace.fraction < 0) {
|
||||
trace.fraction = 0;
|
||||
}
|
||||
|
||||
fWidth = 10.f - (1.f - trace.fraction) * 6.f;
|
||||
fAlphaOfs = (1.f - trace.fraction) * fAlpha;
|
||||
|
||||
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
|
||||
|
||||
if (fAlpha < 0.1) {
|
||||
vLightIntensity[0] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
vLightIntensity[1] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
vLightIntensity[2] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
} else {
|
||||
vLightIntensity[0] *= fAlphaOfs;
|
||||
vLightIntensity[1] *= fAlphaOfs;
|
||||
vLightIntensity[2] *= fAlphaOfs;
|
||||
}
|
||||
|
||||
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
|
||||
if (fAlpha > 0.6) {
|
||||
vLightIntensity[0] *= 0.6 / fAlpha;
|
||||
vLightIntensity[1] *= 0.6 / fAlpha;
|
||||
vLightIntensity[2] *= 0.6 / fAlpha;
|
||||
}
|
||||
|
||||
if (vLightIntensity[0] <= 0.01 && vLightIntensity[1] <= 0.01 && vLightIntensity[2] <= 0.01) {
|
||||
return;
|
||||
}
|
||||
|
||||
CG_ImpactMark(
|
||||
cgs.media.footShadowMarkShader,
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
vLightAngles[1],
|
||||
fWidth,
|
||||
fLength,
|
||||
vLightIntensity[0],
|
||||
vLightIntensity[1],
|
||||
vLightIntensity[2],
|
||||
1.0,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5,
|
||||
fOfs
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastSimpleFeetShadow
|
||||
|
||||
Cast basic feet shadow
|
||||
===============
|
||||
*/
|
||||
void CG_CastSimpleFeetShadow(const trace_t* pTrace, float fWidth, float fAlpha, int iRightTag, int iLeftTag, const dtiki_t* tiki, refEntity_t* model)
|
||||
{
|
||||
int i;
|
||||
float fShadowYaw;
|
||||
float fLength;
|
||||
vec3_t vPos, vRightPos, vLeftPos;
|
||||
vec3_t vDelta;
|
||||
orientation_t oFoot;
|
||||
|
||||
//
|
||||
// right foot
|
||||
//
|
||||
VectorCopy(pTrace->endpos, vRightPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iRightTag);
|
||||
VectorMA(oFoot.origin, 3, oFoot.axis[1], vPos);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vRightPos, vPos[i], model->axis[i], vRightPos);
|
||||
}
|
||||
|
||||
VectorMA(vRightPos, -2, oFoot.axis[1], vRightPos);
|
||||
|
||||
//
|
||||
// left foot
|
||||
//
|
||||
VectorCopy(pTrace->endpos, vLeftPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iLeftTag);
|
||||
VectorMA(oFoot.origin, 3, oFoot.axis[1], vPos);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vLeftPos, vPos[i], model->axis[i], vLeftPos);
|
||||
}
|
||||
|
||||
VectorAdd(vRightPos, vLeftPos, vPos);
|
||||
VectorScale(vPos, 0.5, vPos);
|
||||
VectorSubtract(vRightPos, vLeftPos, vDelta);
|
||||
VectorMA(vLeftPos, 0.5, vDelta, vPos);
|
||||
|
||||
// get the facing yaw
|
||||
fShadowYaw = vectoyaw(vDelta);
|
||||
fLength = VectorNormalize(vDelta) * 0.5 + 12;
|
||||
if (fLength < fWidth * 0.7) {
|
||||
fLength = fWidth * 0.7;
|
||||
}
|
||||
|
||||
// add the mark
|
||||
CG_ImpactMark(
|
||||
cgs.media.shadowMarkShader,
|
||||
vPos,
|
||||
pTrace->plane.normal,
|
||||
fShadowYaw,
|
||||
fWidth * 0.7,
|
||||
fLength,
|
||||
fAlpha,
|
||||
fAlpha,
|
||||
fAlpha,
|
||||
1.0,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5,
|
||||
0.5
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_EntityShadow
|
||||
@@ -193,9 +524,15 @@ Returns the Z component of the surface being shadowed
|
||||
|
||||
qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
{
|
||||
int iTagL, iTagR;
|
||||
float alpha;
|
||||
float fWidth;
|
||||
vec3_t end;
|
||||
vec3_t vMins, vMaxs;
|
||||
vec3_t vSize;
|
||||
trace_t trace;
|
||||
float alpha, radius;
|
||||
|
||||
iTagR = -1;
|
||||
|
||||
if (cg_shadows->integer == 0) {
|
||||
return qfalse;
|
||||
@@ -206,10 +543,31 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// no shadows when invisible
|
||||
// if ( cent->currentState.powerups & ( 1 << PW_INVIS ) ) {
|
||||
// return qfalse;
|
||||
// }
|
||||
if (cg_shadows->integer == 2 && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
iTagL = cgi.Tag_NumForName(model->tiki, "Bip01 L Foot");
|
||||
if (iTagL != -1) {
|
||||
iTagR = cgi.Tag_NumForName(model->tiki, "Bip01 R Foot");
|
||||
}
|
||||
|
||||
if (iTagR != -1) {
|
||||
int iNumLights, iCurrLight;
|
||||
vec3_t avLightPos[16], avLightIntensity[16];
|
||||
|
||||
iNumLights = Q_clamp(cg_shadowscount->integer, 1, 8);
|
||||
iNumLights = cgi.R_GatherLightSources(model->origin, avLightPos, avLightIntensity, iNumLights);
|
||||
if (iNumLights)
|
||||
{
|
||||
for (iCurrLight = 0; iCurrLight < iNumLights; iCurrLight++)
|
||||
{
|
||||
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagL, model);
|
||||
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagR, model);
|
||||
}
|
||||
|
||||
// shadow was casted properly
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send a trace down from the player to the ground
|
||||
VectorCopy(model->origin, end);
|
||||
@@ -222,29 +580,46 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ((cg_shadows->integer == 2) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
// since 2.0: no shadow if solid
|
||||
if (trace.startsolid || trace.allsolid) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ((cg_shadows->integer == 3) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
//
|
||||
// get the bounds of the current frame
|
||||
//
|
||||
radius = model->scale * cgi.R_ModelRadius(model->hModel);
|
||||
|
||||
if (radius < 1) {
|
||||
fWidth = model->scale * cgi.R_ModelRadius(model->hModel);
|
||||
if (fWidth < 1) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// fade the shadow out with height
|
||||
alpha = (1.0 - trace.fraction) * 0.8f;
|
||||
alpha = (1.0 - trace.fraction) * 0.65f;
|
||||
|
||||
if ((cg_shadows->integer == 3) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
if (model->shaderRGBA[3] == 255) {
|
||||
model->shaderRGBA[3] = alpha * 255;
|
||||
if (model->renderfx & RF_SHADOW_PRECISE) {
|
||||
iTagL = cgi.Tag_NumForName(model->tiki, "Bip01 L Foot");
|
||||
if (iTagL != -1) {
|
||||
iTagR = cgi.Tag_NumForName(model->tiki, "Bip01 R Foot");
|
||||
}
|
||||
|
||||
if (iTagR != -1) {
|
||||
if (cg_shadows->integer == 2) {
|
||||
alpha *= 0.6f;
|
||||
}
|
||||
|
||||
CG_CastSimpleFeetShadow(&trace, fWidth, alpha, iTagR, iTagL, model->tiki, model);
|
||||
return qtrue;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
cgi.R_ModelBounds(model->hModel, vMins, vMaxs);
|
||||
VectorSubtract(vMaxs, vMins, vSize);
|
||||
VectorScale(vSize, 0.6f, vSize);
|
||||
|
||||
// add the mark as a temporary, so it goes directly to the renderer
|
||||
// without taking a spot in the cg_marks array
|
||||
CG_ImpactMark(
|
||||
@@ -252,15 +627,15 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
cent->lerpAngles[YAW],
|
||||
radius,
|
||||
radius,
|
||||
vSize[1],
|
||||
vSize[0],
|
||||
alpha,
|
||||
alpha,
|
||||
alpha,
|
||||
1,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5f,
|
||||
0.5f
|
||||
@@ -286,7 +661,7 @@ void CG_AnimationDebugMessage(int number, const char *fmt, ...)
|
||||
char msg[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(msg, fmt, argptr);
|
||||
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == number)) {
|
||||
@@ -316,10 +691,12 @@ void CG_AttachEntity(
|
||||
orientation_t or ;
|
||||
vec3_t tempAxis[3];
|
||||
vec3_t vOrigin;
|
||||
vec3_t vDeltaLightOrg;
|
||||
|
||||
or = cgi.TIKI_Orientation(parent, tagnum);
|
||||
//cgi.Printf( "th = %d %.2f %.2f %.2f\n", tikihandle, or.origin[ 0 ], or.origin[ 1 ], or.origin[ 2 ] );
|
||||
|
||||
VectorSubtract(entity->lightingOrigin, entity->origin, vDeltaLightOrg);
|
||||
VectorCopy(parent->origin, entity->origin);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -337,14 +714,14 @@ void CG_AttachEntity(
|
||||
VectorCopy(entity->origin, entity->oldorigin);
|
||||
|
||||
if (use_angles) {
|
||||
MatrixMultiply(entity->axis, parent->axis, tempAxis);
|
||||
MatrixMultiply(or.axis, tempAxis, entity->axis);
|
||||
MatrixMultiply(entity->axis, or.axis, tempAxis);
|
||||
MatrixMultiply(tempAxis, parent->axis, entity->axis);
|
||||
}
|
||||
|
||||
entity->scale *= parent->scale;
|
||||
entity->renderfx |= (parent->renderfx & ~(RF_FLAGS_NOT_INHERITED | RF_LIGHTING_ORIGIN));
|
||||
|
||||
MatrixTransformVectorRight(entity->axis, entity->lightingOrigin, vOrigin);
|
||||
MatrixTransformVectorRight(entity->axis, vDeltaLightOrg, vOrigin);
|
||||
VectorAdd(entity->origin, vOrigin, entity->lightingOrigin);
|
||||
}
|
||||
|
||||
@@ -388,8 +765,8 @@ void CG_UpdateForceModels()
|
||||
pszAlliesPartial = dm_playermodel->string;
|
||||
pszAxisPartial = dm_playergermanmodel->string;
|
||||
|
||||
sprintf(szAlliesModel, "models/player/%s.tik", pszAlliesPartial);
|
||||
sprintf(szAxisModel, "models/player/%s.tik", pszAxisPartial);
|
||||
Com_sprintf(szAlliesModel, sizeof(szAlliesModel), "models/player/%s.tik", pszAlliesPartial);
|
||||
Com_sprintf(szAxisModel, sizeof(szAxisModel), "models/player/%s.tik", pszAxisPartial);
|
||||
hModel = cgi.R_RegisterModel(szAlliesModel);
|
||||
if (!hModel) hModel = cgi.R_RegisterModel("models/player/american_army.tik");
|
||||
|
||||
@@ -431,7 +808,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
int i;
|
||||
vec3_t vMins, vMaxs, vTmp;
|
||||
const char *szTagName;
|
||||
static cvar_t *vmEntity = NULL;
|
||||
int iAnimFlags;
|
||||
|
||||
s1 = ¢->currentState;
|
||||
@@ -443,10 +819,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
|
||||
memset(&model, 0, sizeof(model));
|
||||
|
||||
if (!vmEntity) {
|
||||
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
|
||||
}
|
||||
|
||||
if (cent->interpolate) {
|
||||
sNext = ¢->nextState;
|
||||
}
|
||||
@@ -614,103 +986,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
model.renderfx |= s1->renderfx;
|
||||
cgi.TIKI_SetEyeTargetPos(model.tiki, model.entityNumber, s1->eyeVector);
|
||||
|
||||
if (sNext && sNext->usageIndex == s1->usageIndex) {
|
||||
float t;
|
||||
float animLength;
|
||||
float t1, t2;
|
||||
|
||||
t1 = cg.time - cg.snap->serverTime;
|
||||
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
|
||||
t = t1 / t2;
|
||||
model.actionWeight = (sNext->actionWeight - s1->actionWeight) * t + s1->actionWeight;
|
||||
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (sNext->frameInfo[i].weight) {
|
||||
model.frameInfo[i].index = sNext->frameInfo[i].index;
|
||||
if (sNext->frameInfo[i].index == s1->frameInfo[i].index && s1->frameInfo[i].weight) {
|
||||
model.frameInfo[i].weight =
|
||||
(sNext->frameInfo[i].weight - s1->frameInfo[i].weight) * t + s1->frameInfo[i].weight;
|
||||
|
||||
if (sNext->frameInfo[i].time >= s1->frameInfo[i].time) {
|
||||
model.frameInfo[i].time =
|
||||
(sNext->frameInfo[i].time - s1->frameInfo[i].time) * t + s1->frameInfo[i].time;
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (animLength + sNext->frameInfo[i].time - s1->frameInfo[i].time) * t
|
||||
+ s1->frameInfo[i].time;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
while (t2 > animLength) {
|
||||
t2 -= animLength;
|
||||
}
|
||||
|
||||
model.frameInfo[i].time = t2;
|
||||
}
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
if (t2 < 0.0) {
|
||||
t2 = 0.0;
|
||||
}
|
||||
|
||||
model.frameInfo[i].time = t2;
|
||||
model.frameInfo[i].weight = sNext->frameInfo[i].weight;
|
||||
}
|
||||
} else if (sNext->frameInfo[i].index == s1->frameInfo[i].index) {
|
||||
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + s1->frameInfo[i].time;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
if (t2 < animLength) {
|
||||
t2 = animLength;
|
||||
}
|
||||
|
||||
model.frameInfo[i].index = s1->frameInfo[i].index;
|
||||
model.frameInfo[i].time = t2;
|
||||
model.frameInfo[i].weight = (1.0 - t) * s1->frameInfo[i].weight;
|
||||
} else {
|
||||
model.frameInfo[i].index = -1;
|
||||
model.frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no next state, don't blend anims
|
||||
|
||||
model.actionWeight = s1->actionWeight;
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (s1->frameInfo[i].weight) {
|
||||
model.frameInfo[i].index = s1->frameInfo[i].index;
|
||||
model.frameInfo[i].time = s1->frameInfo[i].time;
|
||||
model.frameInfo[i].weight = s1->frameInfo[i].weight;
|
||||
} else {
|
||||
model.frameInfo[i].index = -1;
|
||||
model.frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vmEntity->integer == s1->number) {
|
||||
static cvar_t *curanim;
|
||||
if (!curanim) {
|
||||
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
|
||||
}
|
||||
|
||||
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model.frameInfo[curanim->integer].time));
|
||||
}
|
||||
CG_InterpolateAnimParms(s1, sNext, &model);
|
||||
|
||||
if (cent->currentState.parent != ENTITYNUM_NONE) {
|
||||
int iTagNum;
|
||||
@@ -961,6 +1237,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
memset(model.surfaces, 0, sizeof(model.surfaces));
|
||||
|
||||
CG_ViewModelAnimation(&model);
|
||||
model.renderfx |= RF_FRAMELERP;
|
||||
cgi.ForceUpdatePose(&model);
|
||||
|
||||
if ((cent->currentState.eFlags & EF_UNARMED) || cg_drawviewmodel->integer <= 1
|
||||
@@ -1057,7 +1334,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);
|
||||
|
||||
@@ -51,16 +51,16 @@ void RainTouch(ctempmodel_t *ct, trace_t *trace)
|
||||
|
||||
void ClientGameCommandManager::RainTouch(Event *ev)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
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);
|
||||
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_RESETSTRING | CVAR_SYSTEMINFO);
|
||||
|
||||
cg.rain.density = 0.0;
|
||||
cg.rain.speed = 2048.0f;
|
||||
|
||||
+493
-420
File diff suppressed because it is too large.
Load diff
+26
-3
@@ -25,6 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// interpolating between snapshots from the server or locally predicting
|
||||
// ahead the client's movement. It also handles local physics interaction,
|
||||
// like fragments bouncing off walls
|
||||
//
|
||||
// ADDITIONS:
|
||||
// - CG_InterpolatePlayerState() footer: Interpolate the lean angles
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
@@ -187,8 +190,9 @@ void CG_ShowTrace(trace_t *trace, int passent, const char *reason)
|
||||
assert(reason);
|
||||
assert(trace);
|
||||
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
text,
|
||||
sizeof(text),
|
||||
"%0.2f : Pass (%d) Frac %f Hit (%d): '%s'\n",
|
||||
(float)cg.time / 1000.0f,
|
||||
passent,
|
||||
@@ -346,6 +350,13 @@ static void CG_InterpolatePlayerStateCamera(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Added in 2.0
|
||||
if (cg.predicted_player_state.camera_flags & CF_CAMERA_ANGLES_TURRETMODE) {
|
||||
VectorCopy(cg.nextSnap->ps.camera_origin, cg.camera_origin);
|
||||
VectorCopy(cg.nextSnap->ps.camera_angles, cg.camera_angles);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
cg.camera_origin[i] = prev->ps.camera_origin[i] + f * (next->ps.camera_origin[i] - prev->ps.camera_origin[i]);
|
||||
cg.camera_angles[i] = LerpAngle(prev->ps.camera_angles[i], next->ps.camera_angles[i], f);
|
||||
@@ -405,6 +416,9 @@ static void CG_InterpolatePlayerState(qboolean grabAngles)
|
||||
}
|
||||
out->velocity[i] = prev->ps.velocity[i] + f * (next->ps.velocity[i] - prev->ps.velocity[i]);
|
||||
}
|
||||
|
||||
// interpolate the lean angle
|
||||
out->fLeanAngle = LerpAngle(prev->ps.fLeanAngle, next->ps.fLeanAngle, f);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -487,8 +501,13 @@ void CG_PredictPlayerState(void)
|
||||
cg_pmove.leanSpeed = 2.f;
|
||||
} else {
|
||||
cg_pmove.alwaysAllowLean = qtrue;
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cg_pmove.leanMax = 40.f;
|
||||
} else {
|
||||
// Don't allow lean in single-player, like in the original game
|
||||
cg_pmove.leanMax = 0;
|
||||
}
|
||||
|
||||
cg_pmove.leanMax = 40.f;
|
||||
cg_pmove.leanAdd = 10.f;
|
||||
cg_pmove.leanRecoverSpeed = 15.f;
|
||||
cg_pmove.leanSpeed = 4.f;
|
||||
@@ -509,7 +528,11 @@ void CG_PredictPlayerState(void)
|
||||
// the server time is beyond our current cg.time,
|
||||
// because predicted player positions are going to
|
||||
// be ahead of everything else anyway
|
||||
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport) {
|
||||
// Added in OPM: prediction check
|
||||
// Don't use the next snapshot if the prediction is about to be disabled
|
||||
// this prevent "blinking" issues like when entering a vehicle turret gun
|
||||
// where arms would be seen shortly
|
||||
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport && !(cg.nextSnap->ps.pm_flags & PMF_NO_PREDICTION)) {
|
||||
cg.predicted_player_state = cg.nextSnap->ps;
|
||||
cg.physicsTime = cg.nextSnap->serverTime;
|
||||
} else {
|
||||
|
||||
+14
-5
@@ -120,6 +120,7 @@ functions exported to the main executable
|
||||
|
||||
// console variable interaction
|
||||
cvar_t *(*Cvar_Get)(const char *var_name, const char *value, int flags);
|
||||
cvar_t *(*Cvar_Find)(const char *var_name);
|
||||
void (*Cvar_Set)(const char *var_name, const char *value);
|
||||
|
||||
// ClientCommand and ConsoleCommand parameter access
|
||||
@@ -137,6 +138,8 @@ functions exported to the main executable
|
||||
void (*FS_FreeFile)(void *buf);
|
||||
int (*FS_WriteFile)(const char *qpath, const void *buffer, int size);
|
||||
void (*FS_WriteTextFile)(const char *qpath, const void *buffer, int size);
|
||||
char** (*FS_ListFilteredFiles)(const char* path, const char* extension, const char* filter, qboolean wantSubs, int* numfiles, qboolean allowNonPureFilesOnDisk);
|
||||
void (*FS_FreeFileList)(char **list);
|
||||
// add commands to the local console as if they were typed in
|
||||
// for map changing, etc. The command is not executed immediately,
|
||||
// but will be executed in order the next time console commands
|
||||
@@ -163,7 +166,7 @@ functions exported to the main executable
|
||||
void (*SendClientCommand)(const char *s);
|
||||
|
||||
// CM functions
|
||||
void (*CM_LoadMap)(const char *name);
|
||||
void (*CM_LoadMap)(const char *name, int* checksum);
|
||||
clipHandle_t (*CM_InlineModel)(int index); // 0 = world, 1+ = bmodels
|
||||
int (*CM_NumInlineModels)(void);
|
||||
int (*CM_PointContents)(const vec3_t p, int headnode);
|
||||
@@ -283,9 +286,11 @@ functions exported to the main executable
|
||||
qhandle_t (*R_RegisterModel)(const char *name);
|
||||
qhandle_t (*R_SpawnEffectModel)(const char *name, vec3_t pos, vec3_t axis[3]);
|
||||
qhandle_t (*R_RegisterServerModel)(const char *name);
|
||||
const char * (*R_GetModelName)(qhandle_t hModel);
|
||||
void (*R_UnregisterServerModel)(qhandle_t hModel);
|
||||
qhandle_t (*R_RegisterShader)(const char *name);
|
||||
qhandle_t (*R_RegisterShaderNoMip)(const char *name);
|
||||
const char* (*R_GetShaderName)(qhandle_t hShader);
|
||||
void (*R_AddRefEntityToScene)(const refEntity_t *ent, int parentEntityNumber);
|
||||
void (*R_AddRefSpriteToScene)(const refEntity_t *ent);
|
||||
void (*R_AddLightToScene)(const vec3_t origin, float intensity, float r, float g, float b, int type);
|
||||
@@ -356,6 +361,8 @@ functions exported to the main executable
|
||||
void (*UI_ShowMenu)(const char *name, qboolean bForce);
|
||||
void (*UI_HideMenu)(const char *name, qboolean bForce);
|
||||
int (*UI_FontStringWidth)(fontheader_t *font, const char *string, int maxLen);
|
||||
// Added in 2.0
|
||||
float (*UI_GetObjectivesTop)(void);
|
||||
|
||||
int (*Key_StringToKeynum)(const char *str);
|
||||
const char *(*Key_KeynumToBindString)(int keyNum);
|
||||
@@ -426,6 +433,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;
|
||||
@@ -459,8 +468,8 @@ functions exported to the main executable
|
||||
int (*CG_GetParent)(int entNum);
|
||||
float (*CG_GetObjectiveAlpha)();
|
||||
int (*CG_PermanentMark)(
|
||||
const vec3_t origin,
|
||||
const vec3_t dir,
|
||||
vec3_t origin,
|
||||
vec3_t dir,
|
||||
float orientation,
|
||||
float sScale,
|
||||
float tScale,
|
||||
@@ -499,8 +508,8 @@ functions exported to the main executable
|
||||
//
|
||||
void (*CG_ReadNonPVSClient)(radarUnpacked_t* radarUnpacked);
|
||||
void (*CG_UpdateRadar)();
|
||||
void (*CG_SaveStateToBuffer)(void** out, int svsTime);
|
||||
void (*CG_LoadStateToBuffer)(void** state, int size, int svsTime);
|
||||
size_t (*CG_SaveStateToBuffer)(void** out, int svsTime);
|
||||
qboolean (*CG_LoadStateToBuffer)(void* state, size_t size, int svsTime);
|
||||
void (*CG_CleanUpTempModels)();
|
||||
|
||||
// FIXME
|
||||
|
||||
@@ -58,19 +58,19 @@ void CG_PrepScoreBoardInfo()
|
||||
{
|
||||
switch (cgs.gametype) {
|
||||
case GT_TEAM_ROUNDS:
|
||||
strcpy(cg.scoresMenuName, "DM_Round_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "DM_Round_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
case GT_OBJECTIVE:
|
||||
strcpy(cg.scoresMenuName, "Obj_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "Obj_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
case GT_TOW:
|
||||
strcpy(cg.scoresMenuName, "Tow_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "Tow_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
case GT_LIBERATION:
|
||||
strcpy(cg.scoresMenuName, "Lib_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "Lib_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
default:
|
||||
strcpy(cg.scoresMenuName, "DM_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "DM_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -296,14 +296,15 @@ void CG_ParseScores_ver_15()
|
||||
|
||||
switch (iClientTeam) {
|
||||
case 1:
|
||||
strcpy(szString3, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString3, cgi.LV_ConvertString("Spectators"), sizeof(szString3));
|
||||
break;
|
||||
case 2:
|
||||
strcpy(szString3, cgi.LV_ConvertString("Free-For-Allers"));
|
||||
Q_strncpyz(szString3, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString3));
|
||||
break;
|
||||
case 3:
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
szString3,
|
||||
sizeof(szString3),
|
||||
"%s - %d %s",
|
||||
cgi.LV_ConvertString("Allies"),
|
||||
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
|
||||
@@ -312,8 +313,9 @@ void CG_ParseScores_ver_15()
|
||||
iCurrentEntry++;
|
||||
break;
|
||||
case 4:
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
szString3,
|
||||
sizeof(szString3),
|
||||
"%s - %d %s",
|
||||
cgi.LV_ConvertString("Axis"),
|
||||
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
|
||||
@@ -322,7 +324,7 @@ void CG_ParseScores_ver_15()
|
||||
iCurrentEntry++;
|
||||
break;
|
||||
default:
|
||||
strcpy(szString3, cgi.LV_ConvertString("No Team"));
|
||||
Q_strncpyz(szString3, cgi.LV_ConvertString("No Team"), sizeof(szString3));
|
||||
break;
|
||||
}
|
||||
} else if (iClientNum == -2) {
|
||||
@@ -330,14 +332,14 @@ void CG_ParseScores_ver_15()
|
||||
szString2[0] = 0;
|
||||
szString3[0] = 0;
|
||||
} else {
|
||||
strcpy(szString2, va("%i", iClientNum));
|
||||
strcpy(szString3, cg.clientinfo[iClientNum].name);
|
||||
Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
|
||||
Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
|
||||
}
|
||||
|
||||
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
Q_strncpyz(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
|
||||
|
||||
if (cgs.gametype >= GT_TEAM_ROUNDS && iClientNum == -1
|
||||
&& (iClientTeam == TEAM_ALLIES || iClientTeam == TEAM_AXIS)) {
|
||||
@@ -370,19 +372,19 @@ void CG_ParseScores_ver_15()
|
||||
} else {
|
||||
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
|
||||
if (iClientNum >= 0) {
|
||||
strcpy(szString2, va("%i", iClientNum));
|
||||
strcpy(szString3, cg.clientinfo[iClientNum].name);
|
||||
strcpy(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
|
||||
Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
|
||||
Q_strncpyz(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
Q_strncpyz(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
|
||||
} else {
|
||||
szString2[0] = 0;
|
||||
if (iClientNum == -3) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Players"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else if (iClientNum == -2) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else {
|
||||
// unknown
|
||||
@@ -535,32 +537,32 @@ void CG_ParseScores_ver_6()
|
||||
|
||||
switch (iClientTeam) {
|
||||
case 1:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
|
||||
break;
|
||||
case 2:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Free-For-Allers"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString2));
|
||||
break;
|
||||
case 3:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Allies"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Allies"), sizeof(szString2));
|
||||
break;
|
||||
case 4:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Axis"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Axis"), sizeof(szString2));
|
||||
break;
|
||||
default:
|
||||
strcpy(szString2, cgi.LV_ConvertString("No Team"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("No Team"), sizeof(szString2));
|
||||
break;
|
||||
}
|
||||
} else if (iClientNum == -2) {
|
||||
// spectating
|
||||
szString2[0] = 0;
|
||||
} else {
|
||||
strcpy(szString2, cg.clientinfo[iClientNum].name);
|
||||
Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
|
||||
}
|
||||
|
||||
strcpy(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
|
||||
Q_strncpyz(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
|
||||
if (iClientNum == cg.snap->ps.clientNum) {
|
||||
pItemTextColor = vThisClientTextColor;
|
||||
@@ -587,17 +589,17 @@ void CG_ParseScores_ver_6()
|
||||
} else {
|
||||
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
|
||||
if (iClientNum >= 0) {
|
||||
strcpy(szString2, cg.clientinfo[iClientNum].name);
|
||||
strcpy(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
|
||||
Q_strncpyz(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
|
||||
Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
} else {
|
||||
if (iClientNum == -3) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Players"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else if (iClientNum == -2) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else {
|
||||
// unknown
|
||||
|
||||
+320
-19
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2008-2024 the OpenMoHAA team
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,12 +25,29 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// cg_servercmds.c -- text commands sent by the server
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../fgame/bg_voteoptions.h"
|
||||
|
||||
static qboolean CG_IsStatementFiltered(char *cmd);
|
||||
|
||||
/*
|
||||
================
|
||||
IsWeaponAllowed
|
||||
|
||||
Returns true if the weapon is allowed
|
||||
================
|
||||
*/
|
||||
static const char *IsWeaponAllowed(int dmFlags, int flags)
|
||||
{
|
||||
return (dmFlags & flags) ? "0" : "1";
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
QueryLandminesAllowed2
|
||||
|
||||
Returns true if landmines is allowed by the map or by a dm flag
|
||||
================
|
||||
*/
|
||||
static qboolean QueryLandminesAllowed2(const char *mapname, int dmflags)
|
||||
{
|
||||
if (dmflags & DF_WEAPON_NO_LANDMINE) {
|
||||
@@ -112,6 +130,7 @@ void CG_ParseServerinfo(void)
|
||||
char map[MAX_QPATH];
|
||||
char *spawnpos;
|
||||
const char *version;
|
||||
const char *mapChecksumStr;
|
||||
|
||||
info = CG_ConfigString(CS_SERVERINFO);
|
||||
cgs.gametype = atoi(Info_ValueForKey(info, "g_gametype"));
|
||||
@@ -132,15 +151,27 @@ void CG_ParseServerinfo(void)
|
||||
cgi.Cvar_Set("cg_fraglimit", Info_ValueForKey(info, "fraglimit"));
|
||||
cgi.Cvar_Set("cg_timelimit", Info_ValueForKey(info, "timelimit"));
|
||||
cgi.Cvar_Set("cg_maxclients", Info_ValueForKey(info, "sv_gametype"));
|
||||
cgi.Cvar_Set("cg_allowvote", Info_ValueForKey(info, "g_allowvote"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext1", Info_ValueForKey(info, "g_obj_alliedtext1"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext2", Info_ValueForKey(info, "g_obj_alliedtext2"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext3", Info_ValueForKey(info, "g_obj_alliedtext3"));
|
||||
cgi.Cvar_Set("cg_obj_axistext1", Info_ValueForKey(info, "cg_obj_axistext1"));
|
||||
cgi.Cvar_Set("cg_obj_axistext2", Info_ValueForKey(info, "cg_obj_axistext2"));
|
||||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "cg_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext4", Info_ValueForKey(info, "g_obj_alliedtext4"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext5", Info_ValueForKey(info, "g_obj_alliedtext5"));
|
||||
cgi.Cvar_Set("cg_obj_axistext1", Info_ValueForKey(info, "g_obj_axistext1"));
|
||||
cgi.Cvar_Set("cg_obj_axistext2", Info_ValueForKey(info, "g_obj_axistext2"));
|
||||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "g_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_obj_axistext4", Info_ValueForKey(info, "g_obj_axistext4"));
|
||||
cgi.Cvar_Set("cg_obj_axistext5", Info_ValueForKey(info, "g_obj_axistext5"));
|
||||
cgi.Cvar_Set("cg_scoreboardpic", Info_ValueForKey(info, "g_scoreboardpic"));
|
||||
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
|
||||
cgs.mapChecksum = atoi(Info_ValueForKey(info, "sv_mapChecksum"));
|
||||
mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum");
|
||||
if (mapChecksumStr && mapChecksumStr[0]) {
|
||||
cgs.mapChecksum = atoi(mapChecksumStr);
|
||||
cgs.useMapChecksum = qtrue;
|
||||
} else {
|
||||
cgs.mapChecksum = 0;
|
||||
cgs.useMapChecksum = qfalse;
|
||||
}
|
||||
|
||||
mapname = Info_ValueForKey(info, "mapname");
|
||||
|
||||
@@ -156,7 +187,7 @@ void CG_ParseServerinfo(void)
|
||||
if (spawnpos) {
|
||||
Q_strncpyz(map, mapname, spawnpos - mapname + 1);
|
||||
} else {
|
||||
strcpy(map, mapname);
|
||||
Q_strncpyz(map, mapname, sizeof(map));
|
||||
}
|
||||
|
||||
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map);
|
||||
@@ -184,17 +215,13 @@ CG_ConfigStringModified
|
||||
|
||||
================
|
||||
*/
|
||||
static void CG_ConfigStringModified(void)
|
||||
static void CG_ConfigStringModified(int num, qboolean modelOnly)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = atoi(cgi.Argv(1));
|
||||
|
||||
// get the gamestate from the client system, which will have the
|
||||
// new configstring already integrated
|
||||
cgi.GetGameState(&cgs.gameState);
|
||||
|
||||
CG_ProcessConfigString(num);
|
||||
CG_ProcessConfigString(num, modelOnly);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -275,7 +302,7 @@ The string has been tokenized and can be retrieved with
|
||||
Cmd_Argc() / Cmd_Argv()
|
||||
=================
|
||||
*/
|
||||
static void CG_ServerCommand(void)
|
||||
static void CG_ServerCommand(qboolean modelOnly)
|
||||
{
|
||||
const char *cmd;
|
||||
|
||||
@@ -287,7 +314,11 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "cs")) {
|
||||
CG_ConfigStringModified();
|
||||
CG_ConfigStringModified(cgi.getConfigStringIdNormalized(atoi(cgi.Argv(1))), modelOnly);
|
||||
return;
|
||||
}
|
||||
|
||||
if (modelOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -298,12 +329,12 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
return;
|
||||
} else if (!strcmp(cmd, "printdeathmsg")) {
|
||||
const char *s1, *s2, * attackerName, * victimName, *type;
|
||||
const char *s1, *s2, *attackerName, *victimName, *type;
|
||||
const char *result1, *result2;
|
||||
int hudColor;
|
||||
|
||||
result1 = NULL;
|
||||
result2 = NULL;
|
||||
result1 = NULL;
|
||||
result2 = NULL;
|
||||
s1 = cgi.Argv(1);
|
||||
s2 = cgi.Argv(2);
|
||||
attackerName = cgi.Argv(3);
|
||||
@@ -339,7 +370,14 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "stufftext")) {
|
||||
cgi.Cmd_Stuff(cgi.Argv(1));
|
||||
char *cmd = cgi.Argv(1);
|
||||
if (CG_IsStatementFiltered(cmd)) {
|
||||
// Added in OPM
|
||||
// Don't execute filtered commands
|
||||
return;
|
||||
}
|
||||
|
||||
cgi.Cmd_Stuff(cmd);
|
||||
cgi.Cmd_Stuff("\n");
|
||||
return;
|
||||
}
|
||||
@@ -364,6 +402,28 @@ static void CG_ServerCommand(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "voteresult")) {
|
||||
cmd = cgi.Argv(1);
|
||||
if (*cmd) {
|
||||
strcmp(cmd, "passed");
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo0")) {
|
||||
CG_VoteOptions_StartReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo1")) {
|
||||
CG_VoteOptions_ContinueReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo2")) {
|
||||
CG_VoteOptions_FinishReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
cgi.Printf("Unknown client game command: %s\n", cmd);
|
||||
}
|
||||
|
||||
@@ -377,9 +437,250 @@ with this this snapshot.
|
||||
*/
|
||||
void CG_ExecuteNewServerCommands(int latestSequence, qboolean differentServer)
|
||||
{
|
||||
int lastServerCommandSequence;
|
||||
|
||||
lastServerCommandSequence = cgs.serverCommandSequence;
|
||||
|
||||
while (cgs.serverCommandSequence < latestSequence) {
|
||||
if (cgi.GetServerCommand(++cgs.serverCommandSequence, differentServer)) {
|
||||
CG_ServerCommand();
|
||||
CG_ServerCommand(qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
cgs.serverCommandSequence = lastServerCommandSequence;
|
||||
while (cgs.serverCommandSequence < latestSequence) {
|
||||
if (cgi.GetServerCommand(++cgs.serverCommandSequence, differentServer)) {
|
||||
CG_ServerCommand(qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// List of client variables allowed to be changed by the server
|
||||
//
|
||||
static const char *whiteListedVariables[] = {
|
||||
"r_fastsky", // some mods set this variable to make the sky uniform
|
||||
"ui_hud",
|
||||
};
|
||||
|
||||
//
|
||||
// List of client variables allowed to be changed by the server
|
||||
//
|
||||
static const char *whiteListedLocalServerVariables[] = {"ui_hidemouse", "ui_showmouse", "cg_marks_add"};
|
||||
|
||||
//
|
||||
// List of commands allowed to be executed by the server
|
||||
//
|
||||
static const char *whiteListedCommands[] = {
|
||||
"primarydmweapon",
|
||||
"pushmenu",
|
||||
"pushmenu_teamselect",
|
||||
"pushmenu_weaponselect",
|
||||
"popmenu",
|
||||
"wait",
|
||||
"globalwidgetcommand", // used for mods adding custom HUDs
|
||||
"ui_addhud",
|
||||
"ui_removehud",
|
||||
"tmstart",
|
||||
"tmstartloop",
|
||||
"tmstop",
|
||||
"tmvolume",
|
||||
"`stufftext",
|
||||
"+moveup", // workaround for mods that want to prevent inactivity when handling the spectate
|
||||
"-moveup",
|
||||
"screenshot",
|
||||
"screenshotJPEG",
|
||||
"levelshot"
|
||||
};
|
||||
|
||||
//
|
||||
// List of commands allowed to be executed by the server
|
||||
//
|
||||
static const char *whiteListedLocalServerCommands[] = {
|
||||
"spmap", // Used by briefings
|
||||
"map",
|
||||
"disconnect",
|
||||
"cinematic",
|
||||
"showmenu",
|
||||
"hidemenu"
|
||||
};
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsVariableFiltered
|
||||
|
||||
Returns whether or not the variable should be filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsVariableFiltered(const char *name)
|
||||
{
|
||||
cvar_t *var;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedVariables); i++) {
|
||||
if (!Q_stricmp(name, whiteListedVariables[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
if (cgs.localServer) {
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerVariables); i++) {
|
||||
if (!Q_stricmp(name, whiteListedLocalServerVariables[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filtered
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsSetVariableFiltered
|
||||
|
||||
Returns whether or not the variable should be filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsSetVariableFiltered(const char *name, char type)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
if (!CG_IsVariableFiltered(name)) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (type != 'u' && type != 's') {
|
||||
// Don't allow custom info variables to avoid flooding
|
||||
// the client with many serverinfo and userinfo variables
|
||||
|
||||
var = cgi.Cvar_Find(name);
|
||||
if (!var) {
|
||||
// Allow as it doesn't exist
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (var->flags & CVAR_USER_CREATED) {
|
||||
// Allow, it's user-created, wouldn't cause issues
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
// Filtered
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsCommandFiltered
|
||||
|
||||
Returns whether or not the variable should be filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsCommandFiltered(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedCommands); i++) {
|
||||
if (!Q_stricmp(name, whiteListedCommands[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
if (cgs.localServer) {
|
||||
// Allow more commands when the client is hosting the server
|
||||
// Mostly used on single-player mode, like when briefings switch to the next map
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerCommands); i++) {
|
||||
if (!Q_stricmp(name, whiteListedLocalServerCommands[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test variables
|
||||
//
|
||||
return CG_IsVariableFiltered(name);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
RemoveEndToken
|
||||
====================
|
||||
*/
|
||||
static qboolean RemoveEndToken(char* com_token) {
|
||||
char* p;
|
||||
|
||||
for (p = com_token; p[0]; p++) {
|
||||
if (*p == ';') {
|
||||
*p = 0;
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsStatementFiltered
|
||||
|
||||
Returns whether or not the statement is filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsStatementFiltered(char *cmd)
|
||||
{
|
||||
char* parsed;
|
||||
char* p;
|
||||
char com_token[256];
|
||||
qboolean bNextStatement = qfalse;
|
||||
|
||||
parsed = cmd;
|
||||
|
||||
for (Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token)); com_token[0]; Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token))) {
|
||||
bNextStatement = RemoveEndToken(com_token);
|
||||
|
||||
if (com_token[0] == ';') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(com_token, "set") || !Q_stricmp(com_token, "setu") || !Q_stricmp(com_token, "seta")
|
||||
|| !Q_stricmp(com_token, "sets")) {
|
||||
char type = com_token[3];
|
||||
|
||||
//
|
||||
// variable
|
||||
//
|
||||
Q_strncpyz(com_token, COM_ParseExt(&parsed, qfalse), sizeof(com_token));
|
||||
bNextStatement |= RemoveEndToken(com_token);
|
||||
if (com_token[0] == ';') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CG_IsSetVariableFiltered(com_token, type)) {
|
||||
return qtrue;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// normal command
|
||||
//
|
||||
if (CG_IsCommandFiltered(com_token)) {
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bNextStatement) {
|
||||
// Skip up to the next statement
|
||||
while (parsed && parsed[0]) {
|
||||
char c = parsed[0];
|
||||
|
||||
parsed++;
|
||||
if (c == '\n' || c == ';') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
@@ -23,8 +23,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// DESCRIPTION:
|
||||
// things that happen on snapshot transition, not necessarily every
|
||||
// single frame
|
||||
//
|
||||
// ADDITIONS:
|
||||
// - CG_TransitionSnapshot() footer: set ps.walking to true if the ps has a ground entity
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
#include "tiki.h"
|
||||
|
||||
/*
|
||||
@@ -69,10 +73,10 @@ static void CG_ResetEntity(centity_t *cent)
|
||||
CG_RemoveClientEntity(cent->currentState.number, tiki, cent);
|
||||
|
||||
// reset the animation for the entities
|
||||
if (tiki && tiki->a->bIsCharacter) {
|
||||
if (tiki) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
cent->animLast[i] = cent->currentState.frameInfo[i].index;
|
||||
cent->animLastTimes[i] = cent->currentState.frameInfo[i].time;
|
||||
cent->animLast[i] = -1;
|
||||
cent->animLastTimes[i] = -1;
|
||||
if (cent->currentState.frameInfo[i].weight) {
|
||||
cent->animLastWeight |= 1 << i;
|
||||
} else {
|
||||
@@ -83,7 +87,8 @@ static void CG_ResetEntity(centity_t *cent)
|
||||
} else {
|
||||
// clear all the last animations
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
cent->animLast[i] = -1;
|
||||
cent->animLast[i] = -1;
|
||||
cent->animLastTimes[i] = 0.0;
|
||||
}
|
||||
|
||||
cent->animLastWeight = 0;
|
||||
@@ -206,6 +211,9 @@ static void CG_TransitionSnapshot(qboolean differentServer)
|
||||
cent->teleported = qfalse;
|
||||
}
|
||||
CG_TransitionEntity(cent);
|
||||
|
||||
// remember time of snapshot this entity was last updated in
|
||||
cent->snapShotTime = cg.snap->serverTime;
|
||||
}
|
||||
|
||||
for (i = 0; i < cg.snap->number_of_sounds; i++) {
|
||||
@@ -243,6 +251,15 @@ static void CG_TransitionSnapshot(qboolean differentServer)
|
||||
CG_TransitionPlayerState(ps, ops);
|
||||
}
|
||||
}
|
||||
|
||||
if (differentServer) {
|
||||
cgi.CL_RestoreSavedCgameState();
|
||||
} else {
|
||||
cgi.CL_ClearSavedCgameState();
|
||||
}
|
||||
|
||||
// this allows the view model to still look normal when the player is on ground
|
||||
cg.snap->ps.walking = cg.snap->ps.groundEntityNum != ENTITYNUM_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -330,8 +347,10 @@ static snapshot_t *CG_ReadNextSnapshot(void)
|
||||
snapshot_t *dest;
|
||||
|
||||
if (cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000) {
|
||||
cgi.Error(
|
||||
ERR_DROP, "CG_ReadNextSnapshot: way out of range, %i > %i", cg.latestSnapshotNum, cgs.processedSnapshotNum
|
||||
cgi.Printf(
|
||||
"WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n",
|
||||
cg.latestSnapshotNum,
|
||||
cgs.processedSnapshotNum
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+178
-7
@@ -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",
|
||||
@@ -94,7 +95,7 @@ void ClientSpecialEffectsManager::LoadEffects()
|
||||
cgi.DPrintf("Loading Special Effects...\n");
|
||||
AxisClear(axis);
|
||||
|
||||
for (i = 0; i < MAX_SPECIAL_EFFECTS; i++) {
|
||||
for (i = 0; i < SFX_COUNT; i++) {
|
||||
switch (i) {
|
||||
case SFX_BHIT_PAPER_LITE:
|
||||
szEffectModel = "models/fx/bh_paper_lite.tik";
|
||||
@@ -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:
|
||||
@@ -478,7 +512,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
|
||||
current_tiki = NULL;
|
||||
|
||||
pCommand->emitter->cgd.origin = vPos;
|
||||
if (pCommand->emitter->cgd.flags & T_ANGLES) {
|
||||
if (!(pCommand->emitter->cgd.flags & T_ANGLES)) {
|
||||
pCommand->emitter->cgd.angles = vAngles;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1023,5 +1194,5 @@ qboolean ClientSpecialEffectsManager::EffectsPending()
|
||||
|
||||
specialeffect_t *ClientSpecialEffectsManager::GetTestEffectPointer()
|
||||
{
|
||||
return &m_effects[SPECIAL_EFFECT_TEST];
|
||||
return &m_effects[SFX_TEST_EFFECT];
|
||||
}
|
||||
@@ -170,12 +170,9 @@ public:
|
||||
specialeffectcommand_t *AddNewCommand();
|
||||
};
|
||||
|
||||
#define MAX_SPECIAL_EFFECTS 99
|
||||
#define SPECIAL_EFFECT_TEST MAX_SPECIAL_EFFECTS - 1
|
||||
|
||||
class ClientSpecialEffectsManager : public Listener
|
||||
{
|
||||
specialeffect_t m_effects[99];
|
||||
specialeffect_t m_effects[SFX_COUNT];
|
||||
qboolean m_bEffectsLoaded;
|
||||
int m_iNumPendingEvents;
|
||||
|
||||
|
||||
+308
-133
@@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "tiki.h"
|
||||
|
||||
cvar_t *cg_showtempmodels;
|
||||
cvar_t *cg_max_tempmodels;
|
||||
cvar_t *cg_reserve_tempmodels;
|
||||
cvar_t *cg_detail;
|
||||
cvar_t *cg_effectdetail;
|
||||
cvar_t *cg_effect_physicsrate;
|
||||
@@ -77,6 +79,11 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
|
||||
|
||||
RemoveClientEntity(p->number, p->cgd.tiki, NULL, p);
|
||||
|
||||
if (m_active_tempmodels.next == p) {
|
||||
// use the next active temp model
|
||||
m_active_tempmodels.next = p->next;
|
||||
}
|
||||
|
||||
// remove from the doubly linked active list
|
||||
p->prev->next = p->next;
|
||||
p->next->prev = p->prev;
|
||||
@@ -84,8 +91,101 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
|
||||
// the free list is only singly linked
|
||||
p->next = m_free_tempmodels;
|
||||
m_free_tempmodels = p;
|
||||
|
||||
if (p->m_spawnthing) {
|
||||
p->m_spawnthing->numtempmodels--;
|
||||
// delete unused spawnthings
|
||||
if (!p->m_spawnthing->numtempmodels) {
|
||||
m_emitters.RemoveObject(p->m_spawnthing);
|
||||
|
||||
if (p->m_spawnthing == m_spawnthing) {
|
||||
m_spawnthing = NULL;
|
||||
}
|
||||
|
||||
delete p->m_spawnthing;
|
||||
}
|
||||
|
||||
p->m_spawnthing = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeAllTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeAllTempModels(void)
|
||||
{
|
||||
ctempmodel_t *p, *next;
|
||||
|
||||
// Go through all the temp models and run the physics if necessary,
|
||||
// then add them to the ref
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
// grab next now, so if the local entity is freed we still have it
|
||||
next = p->prev;
|
||||
FreeTempModel(p);
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeSomeTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeSomeTempModels(void)
|
||||
{
|
||||
ctempmodel_t* model;
|
||||
int count = 0;
|
||||
unsigned int i;
|
||||
unsigned int numToFree;
|
||||
|
||||
if (!m_free_tempmodels) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = model->prev) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (cg_reserve_tempmodels->integer <= (cg_max_tempmodels->integer - count)) {
|
||||
// nothing to free
|
||||
return;
|
||||
}
|
||||
|
||||
numToFree = cg_reserve_tempmodels->integer - (cg_max_tempmodels->integer - count);
|
||||
|
||||
for (i = 0; i < numToFree; i++) {
|
||||
FreeTempModel(m_active_tempmodels.prev);
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeSpawnthing
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeSpawnthing(spawnthing_t* sp)
|
||||
{
|
||||
ctempmodel_t* model;
|
||||
ctempmodel_t* prev;
|
||||
|
||||
if (sp->numtempmodels) {
|
||||
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = prev) {
|
||||
prev = model->prev;
|
||||
|
||||
if (model->m_spawnthing == sp) {
|
||||
FreeTempModel(model);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_emitters.RemoveObject(sp);
|
||||
|
||||
if (sp == m_spawnthing) {
|
||||
m_spawnthing = NULL;
|
||||
}
|
||||
|
||||
delete sp;
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// ResetTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::ResetTempModels(void)
|
||||
{
|
||||
// Go through all the active tempmodels and free them
|
||||
@@ -99,6 +199,7 @@ void ClientGameCommandManager::ResetTempModels(void)
|
||||
}
|
||||
|
||||
static int lastTempModelFrameTime = 0;
|
||||
int next_tempmodel_warning = 0;
|
||||
|
||||
void CG_ResetTempModels(void)
|
||||
{
|
||||
@@ -128,9 +229,23 @@ void ClientGameCommandManager::InitializeTempModels(void)
|
||||
void ClientGameCommandManager::InitializeTempModelCvars(void)
|
||||
{
|
||||
cg_showtempmodels = cgi.Cvar_Get("cg_showtempmodels", "0", 0);
|
||||
cg_detail = cgi.Cvar_Get("detail", "1", 1);
|
||||
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", 1);
|
||||
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", 1);
|
||||
cg_detail = cgi.Cvar_Get("detail", "1", CVAR_ARCHIVE);
|
||||
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", CVAR_ARCHIVE);
|
||||
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", CVAR_ARCHIVE);
|
||||
cg_max_tempmodels = cgi.Cvar_Get("cg_max_tempmodels", "1100", CVAR_ARCHIVE);
|
||||
cg_reserve_tempmodels = cgi.Cvar_Get("cg_reserve_tempmodels", "200", CVAR_ARCHIVE);
|
||||
|
||||
if (cg_max_tempmodels->integer > MAX_TEMPMODELS) {
|
||||
// 2.40 sets the integer value directly rather than calling Cvar_Set()
|
||||
//cg_max_tempmodels->integer = MAX_TEMPMODELS
|
||||
cgi.Cvar_Set("cg_max_tempmodels", va("%i", MAX_TEMPMODELS));
|
||||
}
|
||||
|
||||
if (cg_reserve_tempmodels->integer * 5 > cg_max_tempmodels->integer) {
|
||||
// 2.40 sets the integer value directly rather than calling Cvar_Set()
|
||||
//cg_reserve_tempmodels->integer = cg_max_tempmodels->integer / 5;
|
||||
cgi.Cvar_Set("cg_reserve_tempmodels", va("%i", cg_max_tempmodels->integer / 5));
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -141,6 +256,7 @@ void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin,
|
||||
int numframes;
|
||||
int deltatime;
|
||||
int frametime;
|
||||
float prev;
|
||||
|
||||
// This code is for animating tempmodels that are spawned from the client
|
||||
// side
|
||||
@@ -165,10 +281,18 @@ void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin,
|
||||
|
||||
// Go through all the frames, and process any commands associated with the
|
||||
// tempmodel as well
|
||||
prev = deltatime;
|
||||
while (deltatime >= frametime) {
|
||||
deltatime -= frametime;
|
||||
p->lastAnimTime += frametime;
|
||||
p->ent.wasframe = (p->ent.wasframe + 1) % numframes;
|
||||
CG_ProcessEntityCommands(p->ent.wasframe, p->ent.frameInfo[0].index, -1, &p->ent, NULL);
|
||||
|
||||
if (deltatime == prev) {
|
||||
break;
|
||||
}
|
||||
|
||||
prev = deltatime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,9 +332,10 @@ void ClientGameCommandManager::UpdateSwarm(ctempmodel_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float dtime, float scale)
|
||||
qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float scale)
|
||||
{
|
||||
float fade, fadein;
|
||||
float dtime;
|
||||
byte tempColor[4];
|
||||
|
||||
if (p->cgd.flags & (T_FADE | T_SCALEUPDOWN)) {
|
||||
@@ -314,9 +439,11 @@ qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, flo
|
||||
|
||||
p->ent.shaderRGBA[0] = (int)((float)tempColor[0] * vLighting[0]);
|
||||
p->ent.shaderRGBA[1] = (int)((float)tempColor[1] * vLighting[1]);
|
||||
p->ent.shaderRGBA[2] = (int)((float)tempColor[2] * vLighting[2]);
|
||||
} else {
|
||||
p->ent.shaderRGBA[0] = tempColor[0];
|
||||
p->ent.shaderRGBA[1] = tempColor[1];
|
||||
p->ent.shaderRGBA[2] = tempColor[2];
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_FADEIN && (fadein < 1)) // Do the fadein effect
|
||||
@@ -362,9 +489,19 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
|
||||
vec3_t axis[3];
|
||||
|
||||
if (p->number != -1) {
|
||||
refEntity_t *old_entity;
|
||||
dtiki_t *old_tiki;
|
||||
int oldnum;
|
||||
float oldscale;
|
||||
|
||||
// Set the axis
|
||||
AnglesToAxis(p->cgd.angles, axis);
|
||||
|
||||
old_entity = current_entity;
|
||||
old_tiki = current_tiki;
|
||||
oldnum = current_entity_number;
|
||||
oldscale = current_scale;
|
||||
|
||||
current_scale = newEnt->scale;
|
||||
current_entity = newEnt;
|
||||
current_tiki = p->cgd.tiki;
|
||||
@@ -380,14 +517,23 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
|
||||
commandManager.ProcessEvent(ev);
|
||||
}
|
||||
|
||||
current_entity_number = -1;
|
||||
current_tiki = NULL;
|
||||
current_entity = NULL;
|
||||
current_scale = -1;
|
||||
current_entity_number = oldnum;
|
||||
current_tiki = old_tiki;
|
||||
current_entity = old_entity;
|
||||
current_scale = oldscale;
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_ALIGNSTRETCH) {
|
||||
Vector vDelta;
|
||||
float fScale;
|
||||
|
||||
vDelta = p->cgd.origin - p->cgd.oldorigin;
|
||||
fScale = vDelta.length() * p->cgd.scale2;
|
||||
VectorScale(newEnt->axis[0], fScale, newEnt->axis[0]);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime, float time2, float scale)
|
||||
qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime, float scale)
|
||||
{
|
||||
int dtime;
|
||||
Vector parentOrigin(0, 0, 0);
|
||||
@@ -395,6 +541,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
Vector tempangles;
|
||||
trace_t trace;
|
||||
float dot;
|
||||
int i;
|
||||
|
||||
VectorCopy(p->ent.origin, p->lastEnt.origin);
|
||||
AxisCopy(p->ent.axis, p->lastEnt.axis);
|
||||
@@ -406,37 +553,41 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
|
||||
// Update based on swarm
|
||||
if (p->cgd.flags & T_SWARM) {
|
||||
p->cgd.origin += ftime * p->cgd.velocity * scale;
|
||||
p->cgd.origin += p->cgd.velocity * ftime * scale;
|
||||
}
|
||||
|
||||
// Update the orign and the angles based on velocities first
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ftime * scale) + (time2 * p->cgd.accel);
|
||||
else if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
p->cgd.origin += p->cgd.velocity * ftime * scale;
|
||||
}
|
||||
|
||||
// If linked to the parent or hardlinked, get the parent's origin
|
||||
if ((p->cgd.flags & (T_PARENTLINK | T_HARDLINK)) && (p->cgd.parent != ENTITYNUM_NONE)) {
|
||||
centity_t *pc;
|
||||
centity_t* pc;
|
||||
refEntity_t* e;
|
||||
|
||||
pc = &cg_entities[p->cgd.parent];
|
||||
|
||||
if (pc->currentValid) {
|
||||
refEntity_t *e;
|
||||
|
||||
e = cgi.R_GetRenderEntity(p->cgd.parent);
|
||||
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentOrigin = e->origin;
|
||||
vectoangles(e->axis[0], parentAngles);
|
||||
} else {
|
||||
if (!pc->currentValid) {
|
||||
return false;
|
||||
}
|
||||
} else if (p->cgd.flags & T_SWARM) {
|
||||
|
||||
e = cgi.R_GetRenderEntity(p->cgd.parent);
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentOrigin = e->origin;
|
||||
vectoangles(e->axis[0], parentAngles);
|
||||
}
|
||||
else if (p->cgd.flags & T_SWARM) {
|
||||
p->cgd.parentOrigin = p->cgd.velocity + p->cgd.accel * ftime * scale;
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_WATERONLY) {
|
||||
if (!(cgi.CM_PointContents(p->cgd.origin, 0) & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Align the object along it's traveling vector
|
||||
if (p->cgd.flags & T_ALIGN) {
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
@@ -457,12 +608,12 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
p->cgd.angles[1] = AngleMod(p->cgd.angles[1]);
|
||||
p->cgd.angles[2] = AngleMod(p->cgd.angles[2]);
|
||||
|
||||
// Add in parent angles
|
||||
tempangles = p->cgd.angles + parentAngles;
|
||||
|
||||
// Convert to axis
|
||||
if ((p->cgd.flags & (T_ALIGN | T_RANDOMROLL | T_PARENTLINK | T_HARDLINK | T_ANGLES))
|
||||
|| (p->cgd.flags2 & T2_AMOVE)) {
|
||||
// Add in parent angles
|
||||
tempangles = p->cgd.angles + parentAngles;
|
||||
|
||||
AnglesToAxis(tempangles, p->ent.axis);
|
||||
}
|
||||
|
||||
@@ -503,70 +654,68 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_CLAMP_VEL) {
|
||||
if (p->cgd.velocity.x < p->cgd.minVel.x) {
|
||||
p->cgd.velocity.x = p->cgd.minVel.x;
|
||||
}
|
||||
if (p->cgd.velocity.y < p->cgd.minVel.y) {
|
||||
p->cgd.velocity.y = p->cgd.minVel.y;
|
||||
}
|
||||
if (p->cgd.velocity.z < p->cgd.minVel.z) {
|
||||
p->cgd.velocity.z = p->cgd.minVel.z;
|
||||
}
|
||||
|
||||
if (p->cgd.velocity.x > p->cgd.maxVel.x) {
|
||||
p->cgd.velocity.x = p->cgd.maxVel.x;
|
||||
}
|
||||
if (p->cgd.velocity.y > p->cgd.maxVel.y) {
|
||||
p->cgd.velocity.y = p->cgd.maxVel.y;
|
||||
}
|
||||
if (p->cgd.velocity.z > p->cgd.maxVel.z) {
|
||||
p->cgd.velocity.z = p->cgd.maxVel.z;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
|
||||
p->cgd.velocity.x = Q_clamp_float(p->cgd.velocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
|
||||
p->cgd.velocity.y = Q_clamp_float(p->cgd.velocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
|
||||
p->cgd.velocity.z = Q_clamp_float(p->cgd.velocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
|
||||
} else if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
|
||||
Vector localVelocity;
|
||||
localVelocity.x = DotProduct(p->cgd.velocity, p->ent.axis[0]);
|
||||
localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]);
|
||||
localVelocity.z = DotProduct(p->cgd.velocity, p->ent.axis[2]);
|
||||
|
||||
if (localVelocity.x < p->cgd.minVel.x) {
|
||||
localVelocity.x = p->cgd.minVel.x;
|
||||
}
|
||||
if (localVelocity.y < p->cgd.minVel.y) {
|
||||
localVelocity.y = p->cgd.minVel.y;
|
||||
}
|
||||
if (localVelocity.z < p->cgd.minVel.z) {
|
||||
localVelocity.z = p->cgd.minVel.z;
|
||||
}
|
||||
|
||||
if (localVelocity.x > p->cgd.maxVel.x) {
|
||||
localVelocity.x = p->cgd.maxVel.x;
|
||||
}
|
||||
if (localVelocity.y > p->cgd.maxVel.y) {
|
||||
localVelocity.y = p->cgd.maxVel.y;
|
||||
}
|
||||
if (localVelocity.z > p->cgd.maxVel.z) {
|
||||
localVelocity.z = p->cgd.maxVel.z;
|
||||
}
|
||||
localVelocity.x = Q_clamp_float(localVelocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
|
||||
localVelocity.y = Q_clamp_float(localVelocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
|
||||
localVelocity.z = Q_clamp_float(localVelocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
|
||||
|
||||
p->cgd.velocity.x = DotProduct(localVelocity, p->ent.axis[0]);
|
||||
p->cgd.velocity.y = DotProduct(localVelocity, p->ent.axis[1]);
|
||||
p->cgd.velocity.z = DotProduct(localVelocity, p->ent.axis[2]);
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T_ALIGN) {
|
||||
// FIXME: vss wind
|
||||
if (p->cgd.flags2 & T2_WIND_AFFECT) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
float fWind;
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
fWind = vss_wind_x->value;
|
||||
break;
|
||||
case 1:
|
||||
fWind = vss_wind_y->value;
|
||||
break;
|
||||
case 2:
|
||||
fWind = vss_wind_z->value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fWind < 0) {
|
||||
if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
|
||||
if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
} else if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] += ftime * vss_movement_dampen->value;
|
||||
if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] += ftime * vss_wind_strength->value;
|
||||
if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
} else if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
|
||||
if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p->touchfcn) {
|
||||
p->touchfcn(p, &trace);
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_DIETOUCH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector normal;
|
||||
|
||||
// Set the origin
|
||||
@@ -581,14 +730,14 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
p->cgd.decal_orientation,
|
||||
p->cgd.decal_radius,
|
||||
p->cgd.color[0],
|
||||
p->cgd.color[1],
|
||||
p->cgd.color[2],
|
||||
p->cgd.alpha,
|
||||
p->cgd.flags & T_FADE,
|
||||
p->cgd.decal_radius,
|
||||
p->cgd.flags2 & T2_TEMPORARY_DECAL,
|
||||
p->cgd.lightstyle,
|
||||
qtrue,
|
||||
p->cgd.flags & T_FADEIN
|
||||
);
|
||||
|
||||
@@ -610,9 +759,10 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
dot = p->cgd.velocity * normal;
|
||||
p->cgd.velocity = p->cgd.velocity + ((-2 * dot) * normal);
|
||||
p->cgd.velocity *= p->cgd.bouncefactor;
|
||||
p->cgd.avelocity *= -p->cgd.bouncefactor;
|
||||
|
||||
// check for stop
|
||||
if (trace.plane.normal[2] > 0 && p->cgd.velocity[2] < 40) {
|
||||
if (trace.plane.normal[2] > 0 && p->cgd.velocity[2] < 45) {
|
||||
p->cgd.velocity = Vector(0, 0, 0);
|
||||
p->cgd.avelocity = Vector(0, 0, 0);
|
||||
p->cgd.flags &= ~T_WAVE;
|
||||
@@ -685,7 +835,7 @@ qboolean ClientGameCommandManager::LerpTempModel(refEntity_t *newEnt, ctempmodel
|
||||
// Add the parent ent's origin to the local origin
|
||||
VectorAdd(newEnt->origin, parentOrigin, newEnt->origin);
|
||||
} else {
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL) || (p->cgd.flags & T_SWARM)) {
|
||||
// Lerp the ent's origin
|
||||
for (i = 0; i < 3; i++) {
|
||||
newEnt->origin[i] = p->lastEnt.origin[i] + frac * (p->ent.origin[i] - p->lastEnt.origin[i]);
|
||||
@@ -741,16 +891,17 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
refEntity_t *old_ent;
|
||||
|
||||
// To counteract cg.time going backwards
|
||||
if (lastTempModelFrameTime) {
|
||||
if ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED)) {
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
next = p->prev;
|
||||
p->lastPhysicsTime = cg.time;
|
||||
}
|
||||
lastTempModelFrameTime = cg.time;
|
||||
return;
|
||||
if (lastTempModelFrameTime && ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED))) {
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
next = p->prev;
|
||||
p->lastPhysicsTime = cg.time;
|
||||
}
|
||||
lastTempModelFrameTime = cg.time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTempModelFrameTime) {
|
||||
frameTime = cg.time - lastTempModelFrameTime;
|
||||
} else {
|
||||
frameTime = 0;
|
||||
@@ -763,6 +914,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
}
|
||||
|
||||
memset(&newEnt, 0, sizeof(newEnt));
|
||||
newEnt.parentEntity = ENTITYNUM_NONE;
|
||||
// Set this frame time for the next one
|
||||
effectTime = (float)frameTime / 1000.0f;
|
||||
effectTime2 = effectTime * effectTime;
|
||||
@@ -793,7 +945,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
current_tiki = p->cgd.tiki;
|
||||
current_entity_number = p->number;
|
||||
|
||||
TempModelRealtimeEffects(p, effectTime, effectTime2, scale);
|
||||
TempModelRealtimeEffects(p, effectTime, scale);
|
||||
|
||||
if (p->lastPhysicsTime) {
|
||||
mstime = cg.time - p->lastPhysicsTime;
|
||||
@@ -808,8 +960,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
if ((mstime >= physics_rate) || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
|
||||
ftime = mstime / 1000.0f;
|
||||
time2 = ftime * ftime;
|
||||
ret = TempModelPhysics(p, ftime, time2, scale);
|
||||
ret = TempModelPhysics(p, ftime, scale);
|
||||
|
||||
if (!ret) {
|
||||
FreeTempModel(p);
|
||||
@@ -823,9 +974,8 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
// Calculate the lerp value based on the time passed since last physics
|
||||
// time of this tempmodel
|
||||
lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate;
|
||||
|
||||
// Clamp
|
||||
if (lerpfrac > 1) {
|
||||
if (lerpfrac > 1 || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
|
||||
lerpfrac = 1;
|
||||
}
|
||||
if (lerpfrac < 0) {
|
||||
@@ -843,11 +993,10 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
// Run physics if the lastEnt is not valid to get a valid lerp
|
||||
if (!p->lastEntValid) {
|
||||
float t, t2;
|
||||
float t;
|
||||
t = physics_rate / 1000.0f;
|
||||
t2 = t * t;
|
||||
|
||||
ret = TempModelPhysics(p, t, t2, scale);
|
||||
ret = TempModelPhysics(p, t, scale);
|
||||
if (!ret) {
|
||||
FreeTempModel(p);
|
||||
continue;
|
||||
@@ -872,12 +1021,12 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_WAVE) {
|
||||
Vector origin;
|
||||
vec3_t origin;
|
||||
float axis[3][3];
|
||||
|
||||
origin = Vector(p->m_spawnthing->linked_origin) + Vector(p->m_spawnthing->linked_axis[0]) * newEnt.origin[0]
|
||||
+ Vector(p->m_spawnthing->linked_axis[1]) * newEnt.origin[1]
|
||||
+ Vector(p->m_spawnthing->linked_axis[2]) * newEnt.origin[2];
|
||||
VectorMA(p->m_spawnthing->linked_origin, newEnt.origin[0], p->m_spawnthing->linked_axis[0], origin);
|
||||
VectorMA(origin, newEnt.origin[1], p->m_spawnthing->linked_axis[1], origin);
|
||||
VectorMA(origin, newEnt.origin[2], p->m_spawnthing->linked_axis[2], origin);
|
||||
|
||||
VectorCopy(origin, newEnt.origin);
|
||||
|
||||
@@ -891,7 +1040,10 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
newEnt.reType = p->ent.reType;
|
||||
newEnt.shaderTime = p->ent.shaderTime;
|
||||
|
||||
newEnt.frameInfo[0] = p->ent.frameInfo[0];
|
||||
newEnt.frameInfo[0].index = p->ent.frameInfo[0].index;
|
||||
newEnt.frameInfo[0].weight = 1.0;
|
||||
newEnt.frameInfo[0].time = 0.0;
|
||||
|
||||
newEnt.wasframe = p->ent.wasframe;
|
||||
newEnt.actionWeight = 1.0;
|
||||
newEnt.entityNumber = ENTITYNUM_NONE;
|
||||
@@ -901,6 +1053,9 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
OtherTempModelEffects(p, newEnt.origin, &newEnt);
|
||||
|
||||
VectorCopy(newEnt.origin, newEnt.lightingOrigin);
|
||||
newEnt.radius = 4.0;
|
||||
|
||||
// Add to the ref
|
||||
if (p->cgd.flags & T_DLIGHT) {
|
||||
// Tempmodel is a Dynamic Light
|
||||
@@ -960,6 +1115,14 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
Vector delta;
|
||||
Vector start;
|
||||
Vector vForward, vLeft, vUp;
|
||||
float fDist;
|
||||
|
||||
delta = m_spawnthing->cgd.origin - cg.refdef.vieworg;
|
||||
fDist = delta * delta * (cg.refdef.fov_x * cg.refdef.fov_x / 6400.0);
|
||||
if (fDist >= m_spawnthing->fMaxRangeSquared || fDist < m_spawnthing->fMinRangeSquared) {
|
||||
// don't draw above the distance
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_entity) {
|
||||
current_entity_scale = current_entity->scale;
|
||||
@@ -1003,7 +1166,11 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
p = AllocateTempModel();
|
||||
|
||||
if (!p) {
|
||||
cgi.DPrintf("Out of tempmodels\n");
|
||||
if (cgi.Milliseconds() >= next_tempmodel_warning) {
|
||||
// make sure to not spam the console with this message
|
||||
cgi.DPrintf("Out of tempmodels\n");
|
||||
next_tempmodel_warning = cgi.Milliseconds() + 1000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1027,15 +1194,23 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
|
||||
// Set up the origin of the tempmodel
|
||||
if (m_spawnthing->cgd.flags & T_SPHERE) {
|
||||
// Create a random forward vector so the particles burst out in a
|
||||
// sphere
|
||||
newForward = Vector(crandom(), crandom(), crandom());
|
||||
do {
|
||||
// Create a random forward vector so the particles burst out in a
|
||||
// sphere
|
||||
newForward = Vector(crandom(), crandom(), crandom());
|
||||
} while (newForward * newForward > 1.0);
|
||||
} else if (m_spawnthing->cgd.flags & T_CIRCLE) {
|
||||
if (m_spawnthing->sphereRadius != 0) // Offset by the radius
|
||||
{
|
||||
Vector dst;
|
||||
// Create a circular shaped burst around the up vector
|
||||
float angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
|
||||
float angle;
|
||||
|
||||
if (mcount == 1) {
|
||||
angle = random() * 360;
|
||||
} else {
|
||||
angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
|
||||
}
|
||||
|
||||
Vector end = Vector(vLeft) * m_spawnthing->sphereRadius * current_entity_scale;
|
||||
RotatePointAroundVector(dst, Vector(vForward), end, angle);
|
||||
@@ -1044,12 +1219,14 @@ 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;
|
||||
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
} while (dir * dir > 1.0);
|
||||
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius * current_entity_scale;
|
||||
VectorCopy(end, p->cgd.origin);
|
||||
@@ -1078,10 +1255,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());
|
||||
@@ -1092,7 +1268,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
VectorCopy(end, p->cgd.origin);
|
||||
newForward = dir;
|
||||
} else {
|
||||
VectorCopy(m_spawnthing->cgd.origin, p->cgd.origin);
|
||||
VectorCopy(start, p->cgd.origin);
|
||||
}
|
||||
|
||||
if (m_spawnthing->cgd.flags & T_SWARM && !(m_spawnthing->cgd.flags & (T_HARDLINK | T_PARENTLINK))) {
|
||||
@@ -1287,7 +1463,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
p->cgd.avelocity[i] = m_spawnthing->avelocity_amplitude[i] * random() + m_spawnthing->avelocity_base[i];
|
||||
|
||||
// Randomize angles or set absolute
|
||||
p->cgd.angles[i] += random() * m_spawnthing->angles_amplitude[i];
|
||||
p->cgd.angles[i] = m_spawnthing->angles_amplitude[i] * random() + m_spawnthing->cgd.angles[i];
|
||||
}
|
||||
|
||||
// If forward velocity is set, just use that otherwise use random
|
||||
@@ -1321,18 +1497,15 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate one tick of velocity based on time alive ( passed in )
|
||||
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ((float)p->aliveTime / 1000.0f) * current_entity_scale);
|
||||
|
||||
if (p->cgd.flags2 & T2_ACCEL) {
|
||||
if (m_spawnthing->cgd.flags2 & T2_RADIALVELOCITY) {
|
||||
float fLength;
|
||||
|
||||
p->cgd.velocity = p->cgd.origin - start;
|
||||
|
||||
fLength = p->cgd.velocity.length();
|
||||
if (fLength) {
|
||||
float fVel = m_spawnthing->cgd.velocity.x
|
||||
+ (m_spawnthing->cgd.velocity.y + m_spawnthing->cgd.velocity.z * crandom()) / fLength;
|
||||
float fVel = m_spawnthing->cgd.velocity[0]
|
||||
+ (m_spawnthing->cgd.velocity[1] + m_spawnthing->cgd.velocity[2] * random()) / fLength;
|
||||
|
||||
p->cgd.velocity *= fVel;
|
||||
}
|
||||
@@ -1343,20 +1516,22 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
(m_spawnthing->randvel_base[i] + m_spawnthing->randvel_amplitude[i] * random()) * current_entity_scale;
|
||||
|
||||
if (m_spawnthing->cgd.flags & T_RANDVELAXIS) {
|
||||
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
|
||||
if (p->cgd.flags2 & T2_NOTAGAXIS) {
|
||||
p->cgd.velocity += fVel * Vector(m_spawnthing->axis[i]);
|
||||
} else {
|
||||
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
|
||||
}
|
||||
} else {
|
||||
p->cgd.velocity[i] += fVel;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->cgd.flags & (T_ALIGN | T_DETAIL)) {
|
||||
if (p->cgd.velocity.x && p->cgd.velocity.y) {
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
}
|
||||
|
||||
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
}
|
||||
|
||||
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
|
||||
|
||||
if (p->cgd.flags & T_AUTOCALCLIFE) {
|
||||
Vector end, delta;
|
||||
float length, speed;
|
||||
|
||||
+1647
-37
File diff suppressed because it is too large.
Load diff
+35
-6
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "str.h"
|
||||
#include "../client/keycodes.h"
|
||||
|
||||
void CG_MessageMode_f(void)
|
||||
{
|
||||
@@ -61,8 +62,8 @@ void CG_MessageMode_Private_f(void)
|
||||
return;
|
||||
}
|
||||
|
||||
clientNum = atoi(cgi.Argv(1)) - 1;
|
||||
if (clientNum < 0 || clientNum >= MAX_CLIENTS) {
|
||||
clientNum = atoi(cgi.Argv(1));
|
||||
if (clientNum < 1 || clientNum >= MAX_CLIENTS) {
|
||||
cgi.Printf(HUD_MESSAGE_CHAT_WHITE "Message Error: %s is a bad client number\n", cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
@@ -189,11 +190,39 @@ void CG_InstaMessageGroupE_f(void)
|
||||
|
||||
void CG_HudPrint_f(void)
|
||||
{
|
||||
cgi.Printf("\x1%s", cgi.Argv(0));
|
||||
cgi.Printf("\x1%s", cgi.Argv(1));
|
||||
}
|
||||
|
||||
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
|
||||
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
char minKey = '1', maxKey = '9';
|
||||
|
||||
if (!cg.iInstaMessageMenu || !down) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
maxKey = '8';
|
||||
}
|
||||
|
||||
if (key < minKey || key > maxKey) {
|
||||
if (key == K_ESCAPE || key == '0') {
|
||||
cg.iInstaMessageMenu = 0;
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (cg.iInstaMessageMenu == -1) {
|
||||
if (key > '6') {
|
||||
cg.iInstaMessageMenu = 0;
|
||||
} else {
|
||||
cg.iInstaMessageMenu = key - '0';
|
||||
}
|
||||
} else if (cg.iInstaMessageMenu > 0) {
|
||||
cgi.SendClientCommand(va("dmmessage 0 *%i%i\n", cg.iInstaMessageMenu, key - '0'));
|
||||
cg.iInstaMessageMenu = 0;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
+170
-21
@@ -242,6 +242,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
float mat[3][3];
|
||||
vec3_t vOldOrigin;
|
||||
vec3_t vStart, vEnd, vMins, vMaxs;
|
||||
vec3_t vVelocity;
|
||||
trace_t trace;
|
||||
|
||||
VectorSet(vMins, -6, -6, -6);
|
||||
@@ -297,6 +298,15 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
|
||||
VectorCopy(origin, vOldOrigin);
|
||||
|
||||
if (!cg.predicted_player_state.walking || !(cg.predicted_player_state.pm_flags & PMF_FROZEN)) {
|
||||
VectorCopy(cg.predicted_player_state.velocity, vVelocity);
|
||||
} else {
|
||||
//
|
||||
// Added in OPM
|
||||
// When frozen, there must be no movement at all
|
||||
VectorClear(vVelocity);
|
||||
}
|
||||
|
||||
if (bUseWorldPosition) {
|
||||
iMask = MASK_VIEWSOLID;
|
||||
} else {
|
||||
@@ -367,7 +377,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
}
|
||||
|
||||
if (cg.predicted_player_state.walking) {
|
||||
fVel = VectorLength(cg.predicted_player_state.velocity);
|
||||
fVel = VectorLength(vVelocity);
|
||||
fPhase = fVel * 0.0015 + 0.9;
|
||||
cg.fCurrentViewBobPhase += (cg.frametime / 1000.0 + cg.frametime / 1000.0) * M_PI * fPhase;
|
||||
|
||||
@@ -446,7 +456,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
AngleVectorsLeft(vDelta, mat[0], mat[1], mat[2]);
|
||||
|
||||
CG_CalcViewModelMovement(
|
||||
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, cg.predicted_player_state.velocity, vDelta
|
||||
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, vVelocity, vDelta
|
||||
);
|
||||
|
||||
VectorMA(pREnt->origin, vDelta[0], mat[0], pREnt->origin);
|
||||
@@ -504,6 +514,44 @@ static int CG_CalcFov(void)
|
||||
return inwater;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_SetupFog
|
||||
|
||||
Prepares fog values for rendering
|
||||
===============
|
||||
*/
|
||||
void CG_SetupFog() {
|
||||
cg.refdef.farplane_distance = cg.farplane_distance;
|
||||
cg.refdef.farplane_bias = cg.farplane_bias;
|
||||
cg.refdef.farplane_color[0] = cg.farplane_color[0];
|
||||
cg.refdef.farplane_color[1] = cg.farplane_color[1];
|
||||
cg.refdef.farplane_color[2] = cg.farplane_color[2];
|
||||
cg.refdef.farplane_cull = cg.farplane_cull;
|
||||
cg.refdef.skybox_farplane = cg.skyboxFarplane;
|
||||
cg.refdef.renderTerrain = cg.renderTerrain;
|
||||
cg.refdef.farclipOverride = cg.farclipOverride;
|
||||
cg.refdef.farplaneColorOverride[0] = cg.farplaneColorOverride[0];
|
||||
cg.refdef.farplaneColorOverride[1] = cg.farplaneColorOverride[1];
|
||||
cg.refdef.farplaneColorOverride[2] = cg.farplaneColorOverride[2];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_SetupPortalSky
|
||||
|
||||
Sets portalsky values for rendering
|
||||
===============
|
||||
*/
|
||||
void CG_SetupPortalSky() {
|
||||
cg.refdef.sky_alpha = cg.sky_alpha;
|
||||
cg.refdef.sky_portal = cg.sky_portal;
|
||||
VectorCopy(cg.sky_axis[0], cg.refdef.sky_axis[0]);
|
||||
VectorCopy(cg.sky_axis[1], cg.refdef.sky_axis[1]);
|
||||
VectorCopy(cg.sky_axis[2], cg.refdef.sky_axis[2]);
|
||||
VectorMA(cg.sky_origin, cg.skyboxSpeed, cg.refdef.vieworg, cg.refdef.sky_origin);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CalcViewValues
|
||||
@@ -520,17 +568,7 @@ static int CG_CalcViewValues(void)
|
||||
|
||||
// calculate size of 3D view
|
||||
CG_CalcVrect();
|
||||
|
||||
// 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);
|
||||
CG_SetupFog();
|
||||
|
||||
ps = &cg.predicted_player_state;
|
||||
|
||||
@@ -604,7 +642,9 @@ static int CG_CalcViewValues(void)
|
||||
// Set the aural axis of the player
|
||||
VectorCopy(cg.refdefViewAngles, SoundAngles);
|
||||
// yaw is purposely inverted because of the miles sound system
|
||||
SoundAngles[YAW] = -SoundAngles[YAW];
|
||||
// Commented out in OPM
|
||||
// Useless as SDL audio/AL is used
|
||||
//SoundAngles[YAW] = -SoundAngles[YAW];
|
||||
AnglesToAxis(SoundAngles, cg.SoundAxis);
|
||||
|
||||
// decide on third person view
|
||||
@@ -623,6 +663,11 @@ static int CG_CalcViewValues(void)
|
||||
// Set the aural axis to the camera's angles
|
||||
VectorCopy(cg.camera_angles, cg.refdefViewAngles);
|
||||
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN && (ps->pm_flags & PMF_DAMAGE_ANGLES)) {
|
||||
// Handle camera shake
|
||||
VectorSubtract(cg.refdefViewAngles, cg.predicted_player_state.damage_angles, cg.refdefViewAngles);
|
||||
}
|
||||
|
||||
if (ps->camera_posofs[0] || ps->camera_posofs[1] || ps->camera_posofs[2]) {
|
||||
vec3_t vAxis[3], vOrg;
|
||||
AnglesToAxis(cg.refdefViewAngles, vAxis);
|
||||
@@ -633,6 +678,9 @@ static int CG_CalcViewValues(void)
|
||||
// copy view values
|
||||
VectorCopy(cg.refdef.vieworg, cg.currentViewPos);
|
||||
VectorCopy(cg.refdefViewAngles, cg.currentViewAngles);
|
||||
// since 2.0: also copy location data for sound
|
||||
VectorCopy(cg.refdef.vieworg, cg.SoundOrg);
|
||||
AnglesToAxis(cg.refdefViewAngles, cg.SoundAxis);
|
||||
}
|
||||
|
||||
// position eye reletive to origin
|
||||
@@ -674,7 +722,37 @@ float CG_SensitivityScale()
|
||||
|
||||
void CG_AddLightShow()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
int i;
|
||||
float fSlopeY, fSlopeZ;
|
||||
float x, y, z;
|
||||
vec3_t vOrg;
|
||||
float r, g, b;
|
||||
float fMax;
|
||||
|
||||
fSlopeY = tan(cg.refdef.fov_x * 0.5);
|
||||
fSlopeZ = tan(cg.refdef.fov_y * 0.5);
|
||||
|
||||
for (i = 0; i < cg_acidtrip->integer; i++) {
|
||||
x = pow(random(), 1.0 / 3.0) * 2048.0;
|
||||
y = crandom() * x * fSlopeY;
|
||||
z = crandom() * x * fSlopeZ;
|
||||
|
||||
VectorCopy(cg.refdef.vieworg, vOrg);
|
||||
VectorMA(vOrg, x, cg.refdef.viewaxis[0], vOrg);
|
||||
VectorMA(vOrg, y, cg.refdef.viewaxis[1], vOrg);
|
||||
VectorMA(vOrg, z, cg.refdef.viewaxis[2], vOrg);
|
||||
|
||||
r = random();
|
||||
g = random();
|
||||
b = random();
|
||||
|
||||
fMax = Q_max(r, Q_max(g, b));
|
||||
r /= fMax;
|
||||
g /= fMax;
|
||||
b /= fMax;
|
||||
|
||||
cgi.R_AddLightToScene(vOrg, (rand() & 0x1FF) + 0x80, r, g, b, 0);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean CG_FrustumCullSphere(const vec3_t vPos, float fRadius) {
|
||||
@@ -774,10 +852,46 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
CG_ScoresDown_f();
|
||||
} else if (cg.bIntermissionDisplay) {
|
||||
if (cg.nextSnap) {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cvar_t* pMission = cgi.Cvar_Get("g_mission", "", CVAR_ARCHIVE);
|
||||
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_ShowMenu("mission_success_1", 0);
|
||||
cgi.Cvar_Set("g_t2l1", "1");
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_ShowMenu("mission_success_2", 0);
|
||||
cgi.Cvar_Set("g_t3l1", "1");
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_ShowMenu("mission_success_3", 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_ShowMenu("mission_failed_1", 0);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_ShowMenu("mission_failed_2", 0);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_ShowMenu("mission_failed_3", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -789,10 +903,44 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
CG_ScoresUp_f();
|
||||
} else {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cvar_t* pMission = cgi.Cvar_Get("g_mission", "", CVAR_ARCHIVE);
|
||||
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_success_1", qtrue);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_success_2", qtrue);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_success_3", qtrue);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_failed_1", qtrue);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_failed_2", qtrue);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_failed_3", qtrue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_HideMenu("StatsScreen_Success", qtrue);
|
||||
} else {
|
||||
cgi.UI_HideMenu("StatsScreen_Failed", qtrue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,6 +954,7 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
}
|
||||
|
||||
// finish up the rest of the refdef
|
||||
CG_SetupPortalSky();
|
||||
|
||||
cg.refdef.time = cg.time;
|
||||
memcpy(cg.refdef.areamask, cg.snap->areamask, sizeof(cg.refdef.areamask));
|
||||
|
||||
@@ -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]
|
||||
@@ -346,13 +351,15 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
} else {
|
||||
iAnimPrefixIndex = CG_GetVMAnimPrefixIndex();
|
||||
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]));
|
||||
Q_strncpyz(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]), sizeof(cgi.anim->g_szLastActiveItem));
|
||||
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
|
||||
bAnimChanged = qtrue;
|
||||
|
||||
bAnimChanged = qtrue;
|
||||
bWeaponChanged = qtrue;
|
||||
}
|
||||
|
||||
if (cgi.anim->g_iLastVMAnim == -1) {
|
||||
sprintf(szAnimName, "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
|
||||
Com_sprintf(szAnimName, sizeof(szAnimName), "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
|
||||
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index = cgi.Anim_NumForName(pTiki, szAnimName);
|
||||
|
||||
if (cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index == -1) {
|
||||
@@ -421,21 +428,28 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
Com_sprintf(szAnimName, sizeof(szAnimName), "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+319
-320
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_commands.h"
|
||||
#include "memarchiver.h"
|
||||
|
||||
const char *cg_vsstypes[] = {
|
||||
"default",
|
||||
@@ -41,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;
|
||||
@@ -77,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +209,7 @@ void ClientGameCommandManager::ResetVSSSources()
|
||||
|
||||
void ClientGameCommandManager::ResetVSSSources(Event *ev)
|
||||
{
|
||||
// FIXME: stub??
|
||||
ResetVSSSources();
|
||||
}
|
||||
|
||||
void CG_ResetVSSSources()
|
||||
@@ -214,6 +218,11 @@ void CG_ResetVSSSources()
|
||||
lastVSSFrameTime = cg.time;
|
||||
}
|
||||
|
||||
void CG_ArchiveVSSGlobals(MemArchiver& archiver)
|
||||
{
|
||||
archiver.ArchiveTime(&lastVSSFrameTime);
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::InitializeVSSSources()
|
||||
{
|
||||
int i;
|
||||
@@ -280,13 +289,13 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
|
||||
fWind = 0.0;
|
||||
|
||||
if ((pSource->flags2 & 5) != 0) {
|
||||
if ((pSource->flags2 & (T2_ACCEL | T2_MOVE)) != 0) {
|
||||
VectorMA(pSource->velocity, ftime, pSource->repulsion, pSource->velocity);
|
||||
}
|
||||
|
||||
pSource->lastOrigin = pSource->newOrigin;
|
||||
|
||||
if (pSource->flags & 0x800) {
|
||||
if (pSource->flags & T_COLLISION) {
|
||||
trace.allsolid = qfalse;
|
||||
CG_ClipMoveToEntities(
|
||||
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
|
||||
@@ -306,11 +315,11 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
}
|
||||
}
|
||||
|
||||
if (pSource->flags2 & 5) {
|
||||
if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
|
||||
VectorMA(pSource->newOrigin, ftime, pSource->velocity, pSource->newOrigin);
|
||||
}
|
||||
|
||||
if (pSource->flags & 0x800) {
|
||||
if (pSource->flags & T_COLLISION) {
|
||||
CG_Trace(
|
||||
&trace,
|
||||
pSource->lastOrigin,
|
||||
@@ -328,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);
|
||||
@@ -352,7 +363,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
}
|
||||
|
||||
iSmokeType = abs(pSource->smokeType);
|
||||
if (pSource->flags2 & 5) {
|
||||
if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
|
||||
VectorCopy(pSource->velocity, vVel);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -613,7 +624,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pCurrent->flags & 0xA0000) {
|
||||
if (pCurrent->flags & (T_HARDLINK | T_PARENTLINK)) {
|
||||
Vector parentOrigin;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -632,7 +643,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
|
||||
|
||||
parentOrigin = e->origin;
|
||||
VectorAdd(pState->origin, parentOrigin, pState->origin);
|
||||
} else if (pCurrent->flags2 & 5) {
|
||||
} else if (pCurrent->flags2 & (T2_ACCEL | T2_MOVE)) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
pState->origin[i] =
|
||||
(pCurrent->newOrigin[i] - pCurrent->lastOrigin[i]) * fLerpFrac + pCurrent->lastOrigin[i];
|
||||
@@ -735,9 +746,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
|
||||
pSource->startAlpha = (random() * 0.15 + 0.85) * fDensity;
|
||||
pSource->newDensity = 0.0;
|
||||
if (m_spawnthing->cgd.flags & 1) {
|
||||
if (m_spawnthing->cgd.flags & T_RANDSCALE) {
|
||||
pSource->newRadius = RandomizeRange(m_spawnthing->cgd.scalemin, m_spawnthing->cgd.scalemax);
|
||||
;
|
||||
if (pSource->newRadius > 32.0) {
|
||||
pSource->newRadius = 32.0;
|
||||
}
|
||||
@@ -766,16 +776,16 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
pSource->roll = anglemod(fAngle);
|
||||
|
||||
if (random() < 0.5) {
|
||||
pSource->flags |= 0x40000;
|
||||
pSource->flags |= T_RANDOMROLL;
|
||||
}
|
||||
|
||||
VectorCopy(m_spawnthing->axis[0], vNewForward);
|
||||
if (m_spawnthing->cgd.flags & 4) {
|
||||
if (m_spawnthing->cgd.flags & T_SPHERE) {
|
||||
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
|
||||
do {
|
||||
vNewForward = Vector(crandom(), crandom(), crandom());
|
||||
} while (Vector::Dot(vNewForward, vNewForward) < 1.0);
|
||||
} else if (m_spawnthing->cgd.flags & 0x10) {
|
||||
} else if (m_spawnthing->cgd.flags & T_CIRCLE) {
|
||||
if (m_spawnthing->sphereRadius != 0.0) {
|
||||
Vector dst, end;
|
||||
|
||||
@@ -788,7 +798,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
|
||||
fAngle += fAngleStep;
|
||||
}
|
||||
} else if (m_spawnthing->cgd.flags & 8) {
|
||||
} else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
|
||||
Vector dir, end;
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
@@ -797,7 +807,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
|
||||
VectorCopy(end, pSource->newOrigin);
|
||||
vNewForward = dir * -1.0;
|
||||
} else if (m_spawnthing->cgd.flags2 & 0x20000) {
|
||||
} else if (m_spawnthing->cgd.flags2 & T2_CONE) {
|
||||
float fHeight, fRadius;
|
||||
float fAngle;
|
||||
float sina, cosa;
|
||||
@@ -819,8 +829,6 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
VectorMA(m_spawnthing->cgd.origin, fRadius * cosa, m_spawnthing->axis[1], pSource->newOrigin);
|
||||
VectorMA(m_spawnthing->cgd.origin, fRadius * sina, m_spawnthing->axis[2], pSource->newOrigin);
|
||||
} else if (m_spawnthing->sphereRadius) {
|
||||
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
|
||||
} else {
|
||||
Vector dir, end;
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
@@ -830,6 +838,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
|
||||
VectorCopy(end, pSource->newOrigin);
|
||||
vNewForward = dir;
|
||||
} else {
|
||||
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -863,15 +873,14 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
for (i = 0; i < 3; ++i) {
|
||||
float fDist = m_spawnthing->axis_offset_base[i] + random() * m_spawnthing->axis_offset_amplitude[i];
|
||||
|
||||
if (pSource->flags2 & 0x80) {
|
||||
if (pSource->flags2 & T2_PARALLEL) {
|
||||
pSource->newOrigin += Vector(m_spawnthing->axis[i]) * fDist;
|
||||
} else {
|
||||
pSource->newOrigin += Vector(m_spawnthing->tag_axis[i]) * fDist;
|
||||
}
|
||||
}
|
||||
|
||||
pSource->velocity *= pSource->lifeTime / 1000.0;
|
||||
pSource->newOrigin += pSource->velocity;
|
||||
pSource->newOrigin += pSource->velocity * (pSource->lifeTime / 1000.0);
|
||||
if (vss_lighting_fps->integer) {
|
||||
cgi.R_GetLightingForSmoke(pSource->newLighting, pSource->newOrigin);
|
||||
}
|
||||
@@ -884,251 +893,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1216,13 +1223,13 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
pComp = pCurrent->prev;
|
||||
|
||||
newEnt.renderfx = 0;
|
||||
if (pCurrent->flags < 0 && !cg_detail->integer) {
|
||||
if ((pCurrent->flags & T_DETAIL) && !cg_detail->integer) {
|
||||
FreeVSSSource(pCurrent);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pCurrent->flags2 & 0x4000) != 0) {
|
||||
newEnt.renderfx = 0x4000000;
|
||||
if ((pCurrent->flags2 & T2_ALWAYSDRAW) != 0) {
|
||||
newEnt.renderfx = RF_ALWAYSDRAW;
|
||||
}
|
||||
|
||||
if (pCurrent->lastPhysicsTime) {
|
||||
@@ -1231,8 +1238,8 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
mstime = physics_rate;
|
||||
}
|
||||
|
||||
if (mstime >= physics_rate || (pCurrent->flags2 & 0x10) != 0) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)mstime * 0.001)) {
|
||||
if (mstime >= physics_rate || (pCurrent->flags2 & T2_PHYSICS_EVERYFRAME) != 0) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)mstime / 1000.0)) {
|
||||
FreeVSSSource(pCurrent);
|
||||
continue;
|
||||
}
|
||||
@@ -1256,26 +1263,18 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
}
|
||||
}
|
||||
|
||||
fLerpFrac = (cg.time - pCurrent->lastPhysicsTime) / physics_rate;
|
||||
if (fLerpFrac > 1.0) {
|
||||
fLerpFrac = 1.0;
|
||||
} else if (fLerpFrac < 0.0) {
|
||||
fLerpFrac = 0.0;
|
||||
}
|
||||
fLerpFrac = (float)(cg.time - pCurrent->lastPhysicsTime) / (float)physics_rate;
|
||||
fLerpFrac = Q_clamp_float(fLerpFrac, 0, 1);
|
||||
|
||||
fLightingFrac = (cg.time - pCurrent->lastLightingTime) / lighting_rate;
|
||||
if (fLightingFrac > 1.0) {
|
||||
fLightingFrac = 1.0;
|
||||
} else if (fLightingFrac < 0.0) {
|
||||
fLightingFrac = 0.0;
|
||||
}
|
||||
fLightingFrac = (float)(cg.time - pCurrent->lastLightingTime) / (float)lighting_rate;
|
||||
fLightingFrac = Q_clamp_float(fLightingFrac, 0, 1);
|
||||
|
||||
if (lastVSSFrameTime) {
|
||||
pCurrent->lifeTime += frameTime;
|
||||
}
|
||||
|
||||
if (!pCurrent->lastValid) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate * 0.001)) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate / 1000)) {
|
||||
ClientGameCommandManager::FreeVSSSource(pCurrent);
|
||||
continue;
|
||||
}
|
||||
@@ -1329,12 +1328,12 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
pCurrent->roll -= j;
|
||||
}
|
||||
|
||||
if ((pCurrent->flags & 0x40000) != 0) {
|
||||
if ((pCurrent->flags & T_RANDOMROLL) != 0) {
|
||||
newEnt.hModel = hModel;
|
||||
} else {
|
||||
newEnt.hModel = hModel2;
|
||||
}
|
||||
} else if ((pCurrent->flags & 0x40000) != 0) {
|
||||
} else if ((pCurrent->flags & T_RANDOMROLL) != 0) {
|
||||
newEnt.hModel = hModel;
|
||||
} else {
|
||||
newEnt.hModel = hModel2;
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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 "cg_local.h"
|
||||
#include "memarchiver.h"
|
||||
#include "../qcommon/vector.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
MemArchiver::MemArchiver()
|
||||
{
|
||||
state = MEMARC_WRITING;
|
||||
buffer = 0;
|
||||
allocatedSize = 0;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
MemArchiver::~MemArchiver()
|
||||
{
|
||||
if (state == MEMARC_WRITING && buffer) {
|
||||
cgi.Free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForWriting(size_t initialSize)
|
||||
{
|
||||
this->state = MEMARC_WRITING;
|
||||
this->buffer = (byte*)cgi.Malloc(initialSize);
|
||||
this->allocatedSize = initialSize;
|
||||
this->bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForReading(byte* buffer, size_t size)
|
||||
{
|
||||
this->state = MEMARC_READING;
|
||||
this->buffer = buffer;
|
||||
this->allocatedSize = size;
|
||||
this->bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetBaseTime(unsigned int time)
|
||||
{
|
||||
this->svsTime = time;
|
||||
}
|
||||
|
||||
size_t MemArchiver::BufferSize() const
|
||||
{
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
byte* MemArchiver::ConfiscateBuffer()
|
||||
{
|
||||
byte* confiscatedBuffer = buffer;
|
||||
|
||||
buffer = NULL;
|
||||
allocatedSize = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
return confiscatedBuffer;
|
||||
}
|
||||
|
||||
bool MemArchiver::IsReading() const
|
||||
{
|
||||
return !IsWriting();
|
||||
}
|
||||
|
||||
bool MemArchiver::IsWriting() const
|
||||
{
|
||||
return state == MEMARC_WRITING;
|
||||
}
|
||||
|
||||
bool MemArchiver::FinishedReading() const
|
||||
{
|
||||
return bufferSize == allocatedSize;
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveByte(byte* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(byte));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveBoolean(qboolean* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(qboolean));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveChar(char* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(char));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveUChar(unsigned char* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveShort(short* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(short));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveInteger(int* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(int));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveSize(size_t* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(size_t));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveFloat(float* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(float));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveVec3(vec3_t value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(vec3_t));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveVector(Vector* value)
|
||||
{
|
||||
ArchiveFloat(&value->x);
|
||||
ArchiveFloat(&value->y);
|
||||
ArchiveFloat(&value->z);
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveString(str* value)
|
||||
{
|
||||
char tmp[4096];
|
||||
int current = 0;
|
||||
|
||||
if (IsReading()) {
|
||||
for (current = 0; current < 4096; current++) {
|
||||
ArchiveReadRaw(&tmp[current], sizeof(char));
|
||||
if (!tmp[current]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current == 4096) {
|
||||
tmp[current - 1] = 0;
|
||||
}
|
||||
|
||||
*value = tmp;
|
||||
} else {
|
||||
ArchiveWriteRaw(value->c_str(), value->length() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveTime(int* value)
|
||||
{
|
||||
int time;
|
||||
|
||||
if (IsReading()) {
|
||||
ArchiveReadRaw(&time, sizeof(time));
|
||||
|
||||
if (time) {
|
||||
time += svsTime;
|
||||
}
|
||||
|
||||
*value = time;
|
||||
} else {
|
||||
time = *value;
|
||||
if (time) {
|
||||
time -= svsTime;
|
||||
}
|
||||
|
||||
ArchiveWriteRaw(&time, sizeof(time));
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveRaw(void* buffer, size_t size)
|
||||
{
|
||||
if (IsReading()) {
|
||||
ArchiveReadRaw(buffer, size);
|
||||
} else {
|
||||
ArchiveWriteRaw(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveReadRaw(void* buffer, size_t size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size + this->bufferSize > this->allocatedSize) {
|
||||
Com_Error(ERR_DROP, "MemArchiver: tried to read past end of buffer");
|
||||
}
|
||||
|
||||
memcpy(buffer, this->buffer + this->bufferSize, size);
|
||||
this->bufferSize += size;
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveWriteRaw(const void* buffer, size_t size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size + this->bufferSize > this->allocatedSize) {
|
||||
if (!this->allocatedSize) {
|
||||
this->allocatedSize = 1024;
|
||||
this->buffer = (byte*)cgi.Malloc(this->allocatedSize);
|
||||
} else {
|
||||
byte* newBuffer;
|
||||
|
||||
do {
|
||||
this->allocatedSize *= 2;
|
||||
} while (size + this->bufferSize > this->allocatedSize);
|
||||
|
||||
newBuffer = (byte*)cgi.Malloc(this->allocatedSize);
|
||||
memcpy(newBuffer, this->buffer, this->bufferSize);
|
||||
cgi.Free(this->buffer);
|
||||
this->buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(this->buffer + this->bufferSize, buffer, size);
|
||||
this->bufferSize += size;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// DESCRIPTION:
|
||||
// In-memory archiver
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
class Vector;
|
||||
class str;
|
||||
|
||||
typedef enum {
|
||||
MEMARC_WRITING,
|
||||
MEMARC_READING
|
||||
} archiverState_e;
|
||||
|
||||
class MemArchiver {
|
||||
public:
|
||||
MemArchiver();
|
||||
~MemArchiver();
|
||||
|
||||
void SetupForWriting(size_t initialSize);
|
||||
void SetupForReading(byte* buffer, size_t size);
|
||||
void SetBaseTime(unsigned int time);
|
||||
size_t BufferSize() const;
|
||||
byte* ConfiscateBuffer();
|
||||
bool IsReading() const;
|
||||
bool IsWriting() const;
|
||||
bool FinishedReading() const;
|
||||
|
||||
void ArchiveByte(byte* value);
|
||||
void ArchiveBoolean(qboolean* value);
|
||||
void ArchiveChar(char* value);
|
||||
void ArchiveUChar(unsigned char* value);
|
||||
void ArchiveShort(short* value);
|
||||
void ArchiveInteger(int* value);
|
||||
void ArchiveSize(size_t* value);
|
||||
void ArchiveFloat(float* value);
|
||||
void ArchiveVec3(vec3_t value);
|
||||
void ArchiveVector(Vector* value);
|
||||
void ArchiveString(str* value);
|
||||
void ArchiveTime(int* value);
|
||||
void ArchiveRaw(void* buffer, size_t size);
|
||||
void ArchiveReadRaw(void* buffer, size_t size);
|
||||
void ArchiveWriteRaw(const void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
archiverState_e state;
|
||||
byte* buffer;
|
||||
size_t bufferSize;
|
||||
size_t allocatedSize;
|
||||
int svsTime;
|
||||
};
|
||||
@@ -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,56 @@ 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)
|
||||
|
||||
if(USE_INTERNAL_MAD)
|
||||
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(omohclient INTERFACE mad)
|
||||
else()
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_path(LIBMAD_INCLUDE_DIRS mad.h)
|
||||
find_library(LIBMAD_LIBRARIES mad)
|
||||
find_package_handle_standard_args(
|
||||
LibMad
|
||||
DEFAULT_MSG
|
||||
LIBMAD_LIBRARIES
|
||||
LIBMAD_INCLUDE_DIRS
|
||||
)
|
||||
target_include_directories(omohclient INTERFACE ${LIBMAD_INCLUDE_DIRS})
|
||||
target_link_libraries(omohclient INTERFACE ${LIBMAD_LIBRARIES})
|
||||
endif()
|
||||
|
||||
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+122
-36
@@ -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,33 +234,37 @@ 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)
|
||||
{
|
||||
for (i = count; i < snapshot->numEntities; i++)
|
||||
if (snapshot->numEntities != count) {
|
||||
Com_DPrintf("CL_GetSnapshot: Not all children could find their parents.\n");
|
||||
|
||||
for (i = snapshot->numEntities; i < count; i++)
|
||||
{
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
if (parents[s1->number] >= 0) {
|
||||
Com_DPrintf(
|
||||
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
|
||||
s1->number,
|
||||
s1->parent,
|
||||
CL_ConfigString(CS_MODELS + s1->modelindex),
|
||||
s1->origin[0],
|
||||
s1->origin[1],
|
||||
s1->origin[2]
|
||||
);
|
||||
for (pnum = 0; pnum < count; pnum++) {
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + pnum) & (MAX_PARSE_ENTITIES - 1)];
|
||||
if (parents[s1->number] >= 0) {
|
||||
Com_DPrintf(
|
||||
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
|
||||
s1->number,
|
||||
s1->parent,
|
||||
CL_ConfigString(CS_MODELS + s1->modelindex),
|
||||
s1->origin[0],
|
||||
s1->origin[1],
|
||||
s1->origin[2]
|
||||
);
|
||||
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,7 +362,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 +401,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 +427,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);
|
||||
}
|
||||
|
||||
@@ -435,10 +471,10 @@ CL_CM_LoadMap
|
||||
Just adds default parameters that cgame doesn't need to know about
|
||||
====================
|
||||
*/
|
||||
void CL_CM_LoadMap( const char *mapname ) {
|
||||
int checksum;
|
||||
|
||||
CM_LoadMap( mapname, qtrue, &checksum );
|
||||
void CL_CM_LoadMap( const char *mapname, int *checksum ) {
|
||||
CM_LoadMap( mapname, qtrue, checksum );
|
||||
// prepare world vis data
|
||||
re.SetWorldVisData(CM_VisibilityPointer());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -548,7 +584,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,6 +616,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
|
||||
cgi->Printf = Com_Printf;
|
||||
cgi->DPrintf = Com_DPrintf;
|
||||
cgi->DebugPrintf = Com_DebugPrintf;
|
||||
|
||||
cgi->Malloc = CL_CG_Malloc;
|
||||
cgi->Free = CL_CG_Free;
|
||||
@@ -590,6 +627,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->LV_ConvertString = Sys_LV_CL_ConvertString;
|
||||
|
||||
cgi->Cvar_Get = Cvar_Get;
|
||||
cgi->Cvar_Find = Cvar_FindVar;
|
||||
cgi->Cvar_Set = Cvar_Set;
|
||||
|
||||
cgi->Argc = Cmd_Argc;
|
||||
@@ -605,6 +643,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->FS_FreeFile = FS_FreeFile;
|
||||
cgi->FS_WriteFile = FS_WriteFile;
|
||||
cgi->FS_WriteTextFile = FS_WriteTextFile;
|
||||
cgi->FS_ListFilteredFiles = FS_ListFilteredFiles;
|
||||
cgi->FS_FreeFileList = FS_FreeFileList;
|
||||
|
||||
cgi->SendConsoleCommand = Cbuf_AddText;
|
||||
|
||||
@@ -676,9 +716,11 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->R_RegisterModel = re.RegisterModel;
|
||||
cgi->R_SpawnEffectModel = re.SpawnEffectModel;
|
||||
cgi->R_RegisterServerModel = re.RegisterServerModel;
|
||||
cgi->R_GetModelName = re.GetModelName;
|
||||
cgi->R_UnregisterServerModel = re.UnregisterServerModel;
|
||||
cgi->R_RegisterShader = re.RegisterShader;
|
||||
cgi->R_RegisterShaderNoMip = re.RegisterShaderNoMip;
|
||||
cgi->R_GetShaderName = re.GetShaderName;
|
||||
|
||||
cgi->R_AddRefEntityToScene = re.AddRefEntityToScene;
|
||||
cgi->R_AddRefSpriteToScene = re.AddRefSpriteToScene;
|
||||
@@ -730,7 +772,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
|
||||
cgi->UI_ShowMenu = UI_ShowMenu;
|
||||
cgi->UI_HideMenu = UI_HideMenu;
|
||||
cgi->UI_FontStringWidth = uie.FontStringWidth;
|
||||
cgi->UI_FontStringWidth = CL_FontStringWidth;
|
||||
cgi->UI_GetObjectivesTop = UI_GetObjectivesTop;
|
||||
cgi->Key_StringToKeynum = Key_StringToKeynum;
|
||||
cgi->Key_KeynumToBindString = Key_KeynumToBindString;
|
||||
cgi->Key_GetKeysForCommand = Key_GetKeysForCommand;
|
||||
@@ -778,6 +821,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;
|
||||
@@ -1070,6 +1115,42 @@ void CL_FirstSnapshot( void ) {
|
||||
Cbuf_AddText( cl_activeAction->string );
|
||||
Cvar_Set( "activeAction", "" );
|
||||
}
|
||||
|
||||
#ifdef USE_MUMBLE
|
||||
if ((cl_useMumble->integer) && !mumble_islinked()) {
|
||||
int ret = mumble_link(CLIENT_WINDOW_TITLE);
|
||||
Com_Printf("Mumble: Linking to Mumble application %s\n", ret==0?"ok":"failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOIP
|
||||
if (!clc.voipCodecInitialized) {
|
||||
int i;
|
||||
int error;
|
||||
|
||||
clc.opusEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, &error);
|
||||
|
||||
if ( error ) {
|
||||
Com_DPrintf("VoIP: Error opus_encoder_create %d\n", error);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
clc.opusDecoder[i] = opus_decoder_create(48000, 1, &error);
|
||||
if ( error ) {
|
||||
Com_DPrintf("VoIP: Error opus_decoder_create(%d) %d\n", i, error);
|
||||
return;
|
||||
}
|
||||
clc.voipIgnore[i] = qfalse;
|
||||
clc.voipGain[i] = 1.0f;
|
||||
}
|
||||
clc.voipCodecInitialized = qtrue;
|
||||
clc.voipMuteAll = qfalse;
|
||||
Cmd_AddCommand ("voip", CL_Voip_f);
|
||||
Cvar_Set("cl_voipSendTarget", "spatial");
|
||||
Com_Memset(clc.voipTargets, ~0, sizeof(clc.voipTargets));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int lastSnapFlags;
|
||||
@@ -1120,7 +1201,12 @@ void CL_SetCGameTime( void ) {
|
||||
// allow pause in single player
|
||||
if ( paused->integer && com_sv_running->integer ) {
|
||||
// paused
|
||||
CL_AdjustTimeDelta();
|
||||
//CL_AdjustTimeDelta();
|
||||
// Fixed in OPM
|
||||
// Keep in sync with the server time.
|
||||
// In OG, the game could lag for a short time
|
||||
// when pausing and unpausing frequently
|
||||
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+159
-44
@@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../uilib/ui_public.h"
|
||||
#include "snd_local.h"
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
#define MAXSIZE 8
|
||||
#define MINSIZE 4
|
||||
|
||||
@@ -55,6 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
static void RoQ_init( void );
|
||||
static void CL_FinishedCinematic();
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@@ -126,6 +129,10 @@ typedef struct {
|
||||
int playonwalls;
|
||||
byte* buf;
|
||||
long drawX, drawY;
|
||||
|
||||
long realTime;
|
||||
long currTime;
|
||||
long soundTime;
|
||||
} cin_cache;
|
||||
|
||||
static cinematics_t cin;
|
||||
@@ -133,6 +140,10 @@ static cin_cache cinTable[MAX_VIDEO_HANDLES];
|
||||
static int currentHandle = -1;
|
||||
static int CL_handle = -1;
|
||||
|
||||
static connstate_t oldClientState;
|
||||
|
||||
static int audioStartTime = 0;
|
||||
|
||||
extern "C" int s_soundtime; // sample PAIRS
|
||||
|
||||
|
||||
@@ -160,7 +171,7 @@ static int CIN_HandleForVideo(void) {
|
||||
}
|
||||
|
||||
|
||||
extern "C" int CL_ScaledMilliseconds(void);
|
||||
extern "C" int Com_Milliseconds(void);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RllSetupTable
|
||||
@@ -1142,24 +1153,20 @@ redump:
|
||||
case ZA_SOUND_MONO:
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
|
||||
S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
|
||||
// S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
|
||||
}
|
||||
break;
|
||||
case ZA_SOUND_STEREO:
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
if (cinTable[currentHandle].numQuads == -1) {
|
||||
S_Update();
|
||||
s_rawend[0] = s_soundtime;
|
||||
}
|
||||
ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
|
||||
S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
|
||||
// S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
|
||||
}
|
||||
break;
|
||||
case ROQ_QUAD_INFO:
|
||||
if (cinTable[currentHandle].numQuads == -1) {
|
||||
readQuadInfo( framedata );
|
||||
setupQuad( 0, 0 );
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds();
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
|
||||
}
|
||||
if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0;
|
||||
break;
|
||||
@@ -1226,7 +1233,10 @@ redump:
|
||||
|
||||
static void RoQ_init( void )
|
||||
{
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds();
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
|
||||
cinTable[currentHandle].realTime = Com_Milliseconds();
|
||||
cinTable[currentHandle].currTime = 0;
|
||||
cinTable[currentHandle].soundTime = 0;
|
||||
|
||||
cinTable[currentHandle].RoQPlayed = 24;
|
||||
|
||||
@@ -1273,8 +1283,10 @@ static void RoQShutdown( void ) {
|
||||
cinTable[currentHandle].iFile = 0;
|
||||
}
|
||||
|
||||
S_StopMovieAudio();
|
||||
|
||||
if (cinTable[currentHandle].alterGameState) {
|
||||
clc.state = CA_DISCONNECTED;
|
||||
clc.state = oldClientState;
|
||||
// we can't just do a vstr nextmap, because
|
||||
// if we are aborting the intro cinematic with
|
||||
// a devmap command, nextmap would be valid by
|
||||
@@ -1286,8 +1298,29 @@ static void RoQShutdown( void ) {
|
||||
}
|
||||
CL_handle = -1;
|
||||
}
|
||||
|
||||
cinTable[currentHandle].fileName[0] = 0;
|
||||
currentHandle = -1;
|
||||
|
||||
CL_FinishedCinematic();
|
||||
}
|
||||
|
||||
static void CL_FinishedCinematic()
|
||||
{
|
||||
const char* s;
|
||||
|
||||
if (!CL_FinishedIntro())
|
||||
{
|
||||
CL_FinishedStartStage();
|
||||
return;
|
||||
}
|
||||
|
||||
s = Cvar_VariableString("nextmap");
|
||||
if (*s)
|
||||
{
|
||||
Cbuf_ExecuteText(EXEC_APPEND, va("%s\n", s));
|
||||
Cvar_Set("nextmap", "");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1328,8 +1361,11 @@ Fetch and decompress the pending frame
|
||||
|
||||
e_status CIN_RunCinematic (int handle)
|
||||
{
|
||||
int start = 0;
|
||||
int thisTime = 0;
|
||||
int deltaTime;
|
||||
int frameTime;
|
||||
int soundTime;
|
||||
int newTime;
|
||||
long tfps;
|
||||
|
||||
if (handle < 0 || handle>= MAX_VIDEO_HANDLES || cinTable[handle].status == FMV_EOF) return FMV_EOF;
|
||||
|
||||
@@ -1357,24 +1393,46 @@ e_status CIN_RunCinematic (int handle)
|
||||
return cinTable[currentHandle].status;
|
||||
}
|
||||
|
||||
thisTime = CL_ScaledMilliseconds();
|
||||
if (cinTable[currentHandle].shader && (abs(thisTime - cinTable[currentHandle].lastTime))>100) {
|
||||
cinTable[currentHandle].startTime += thisTime - cinTable[currentHandle].lastTime;
|
||||
frameTime = Com_Milliseconds();
|
||||
deltaTime = frameTime - cinTable[currentHandle].realTime;
|
||||
if (deltaTime > 100) {
|
||||
deltaTime = 100;
|
||||
}
|
||||
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
|
||||
|
||||
start = cinTable[currentHandle].startTime;
|
||||
while( (cinTable[currentHandle].tfps != cinTable[currentHandle].numQuads)
|
||||
newTime = cinTable[currentHandle].currTime + deltaTime;
|
||||
if (cl_movieaudio->integer) {
|
||||
soundTime = S_CurrentMoviePosition();
|
||||
if (soundTime > cinTable[currentHandle].currTime || soundTime > cinTable[currentHandle].soundTime) {
|
||||
cinTable[currentHandle].currTime = newTime + (deltaTime * (soundTime - newTime)) / 100;
|
||||
}
|
||||
else {
|
||||
cinTable[currentHandle].currTime = newTime;
|
||||
}
|
||||
|
||||
cinTable[currentHandle].soundTime = soundTime;
|
||||
} else {
|
||||
//
|
||||
// Fixed in OPM
|
||||
//
|
||||
cinTable[currentHandle].currTime = newTime;
|
||||
}
|
||||
|
||||
cinTable[currentHandle].realTime = frameTime;
|
||||
|
||||
tfps = (cinTable[currentHandle].currTime * 3) / 100;
|
||||
|
||||
while( (tfps != cinTable[currentHandle].numQuads)
|
||||
&& (cinTable[currentHandle].status == FMV_PLAY) )
|
||||
{
|
||||
RoQInterrupt();
|
||||
if (start != cinTable[currentHandle].startTime) {
|
||||
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
|
||||
start = cinTable[currentHandle].startTime;
|
||||
|
||||
cinTable[currentHandle].realTime = Com_Milliseconds();
|
||||
if (cinTable[currentHandle].realTime > frameTime + 66) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cinTable[currentHandle].lastTime = thisTime;
|
||||
cinTable[currentHandle].lastTime = frameTime;
|
||||
|
||||
if (cinTable[currentHandle].status == FMV_LOOPED) {
|
||||
cinTable[currentHandle].status = FMV_PLAY;
|
||||
@@ -1422,7 +1480,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||
|
||||
cin.currentHandle = currentHandle;
|
||||
|
||||
strcpy(cinTable[currentHandle].fileName, name);
|
||||
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
|
||||
|
||||
cinTable[currentHandle].ROQSize = 0;
|
||||
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
|
||||
@@ -1468,10 +1526,6 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||
clc.state = CA_CINEMATIC;
|
||||
}
|
||||
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
s_rawend[0] = s_soundtime;
|
||||
}
|
||||
|
||||
return currentHandle;
|
||||
}
|
||||
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
|
||||
@@ -1593,33 +1647,96 @@ void CIN_DrawCinematic (int handle) {
|
||||
cinTable[handle].dirty = qfalse;
|
||||
}
|
||||
|
||||
static unsigned short CL_PlayRoQ(const char* name, const char* arg, const char* s) {
|
||||
unsigned short RoQID;
|
||||
|
||||
Com_Memset(&cin, 0, sizeof(cinematics_t) );
|
||||
currentHandle = CIN_HandleForVideo();
|
||||
|
||||
cin.currentHandle = currentHandle;
|
||||
|
||||
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
|
||||
|
||||
cinTable[currentHandle].ROQSize = 0;
|
||||
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
|
||||
|
||||
if (cinTable[currentHandle].ROQSize<=0) {
|
||||
Com_DPrintf("Can not find RoQ cinematic '%s'\n", name);
|
||||
CL_FinishedCinematic();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
|
||||
cinTable[currentHandle].holdAtEnd = qtrue;
|
||||
}
|
||||
|
||||
CIN_SetExtents(currentHandle, 0, 0, 640, 480);
|
||||
cinTable[currentHandle].alterGameState = qtrue;
|
||||
|
||||
initRoQ();
|
||||
|
||||
FS_Read (cin.file, 16, cinTable[currentHandle].iFile);
|
||||
|
||||
RoQID = (unsigned short)(cin.file[0]) + (unsigned short)(cin.file[1])*256;
|
||||
if (RoQID == 0x1084)
|
||||
{
|
||||
RoQ_init();
|
||||
// FS_Read (cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile);
|
||||
|
||||
cinTable[currentHandle].status = FMV_PLAY;
|
||||
Com_DPrintf("trFMV::play(), playing %s\n", arg);
|
||||
|
||||
if (cl_movieaudio->integer) {
|
||||
audioStartTime = Com_Milliseconds();
|
||||
S_SetupMovieAudio(name);
|
||||
}
|
||||
|
||||
oldClientState = clc.state;
|
||||
clc.state = CA_CINEMATIC;
|
||||
|
||||
if (cls.glconfig.maxTextureSize <= 256 || s && *s == '2') {
|
||||
//cinTable[currentHandle].interlaced = qtrue;
|
||||
}
|
||||
|
||||
CL_handle = currentHandle;
|
||||
|
||||
do {
|
||||
SCR_RunCinematic();
|
||||
} while (!cinTable[currentHandle].buf && cinTable[currentHandle].status == FMV_PLAY);
|
||||
|
||||
UI_CloseConsole();
|
||||
|
||||
return currentHandle;
|
||||
}
|
||||
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
|
||||
|
||||
RoQShutdown();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CL_PlayCinematic_f(void) {
|
||||
char *arg, *s;
|
||||
int bits = CIN_system;
|
||||
char name[256];
|
||||
|
||||
Com_DPrintf("CL_PlayCinematic_f\n");
|
||||
if (clc.state == CA_CINEMATIC) {
|
||||
SCR_StopCinematic();
|
||||
}
|
||||
|
||||
arg = Cmd_Argv( 1 );
|
||||
Com_DPrintf("CL_PlayCinematic( %s )\n", arg);
|
||||
s = Cmd_Argv(2);
|
||||
|
||||
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
|
||||
bits |= CIN_hold;
|
||||
}
|
||||
if (s && s[0] == '2') {
|
||||
bits |= CIN_loop;
|
||||
CL_StartHunkUsers(qfalse);
|
||||
S_StopAllSounds2(qtrue);
|
||||
|
||||
Com_sprintf(name, sizeof(name), "video/%s", arg);
|
||||
|
||||
if (Q_stricmp(&name[strlen(name) - 4], ".roq")) {
|
||||
Com_Printf("Bad or missing cinematic extension.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
S_StopAllSounds( qtrue );
|
||||
|
||||
CL_handle = CIN_PlayCinematic( arg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits );
|
||||
if (CL_handle >= 0) {
|
||||
do {
|
||||
SCR_RunCinematic();
|
||||
} while (cinTable[currentHandle].buf == NULL && cinTable[currentHandle].status == FMV_PLAY); // wait for first frame (load codebook and sound)
|
||||
}
|
||||
CL_PlayRoQ(name, arg, s);
|
||||
}
|
||||
|
||||
|
||||
@@ -1639,7 +1756,5 @@ void SCR_RunCinematic (void)
|
||||
void SCR_StopCinematic(void) {
|
||||
if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) {
|
||||
CIN_StopCinematic(CL_handle);
|
||||
S_StopAllSounds( qtrue );
|
||||
CL_handle = -1;
|
||||
}
|
||||
}
|
||||
+188
-19
@@ -56,6 +56,10 @@ qboolean in_guimouse;
|
||||
|
||||
kbutton_t in_up, in_down;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
kbutton_t in_voiprecord;
|
||||
#endif
|
||||
|
||||
kbutton_t in_buttons[16];
|
||||
|
||||
qboolean in_mlooking;
|
||||
@@ -258,6 +262,20 @@ void IN_SpeedUp(void) {IN_KeyUp(&in_speed);}
|
||||
void IN_StrafeDown(void) {IN_KeyDown(&in_strafe);}
|
||||
void IN_StrafeUp(void) {IN_KeyUp(&in_strafe);}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
void IN_VoipRecordDown(void)
|
||||
{
|
||||
IN_KeyDown(&in_voiprecord);
|
||||
Cvar_Set("cl_voipSend", "1");
|
||||
}
|
||||
|
||||
void IN_VoipRecordUp(void)
|
||||
{
|
||||
IN_KeyUp(&in_voiprecord);
|
||||
Cvar_Set("cl_voipSend", "0");
|
||||
}
|
||||
#endif
|
||||
|
||||
void IN_Button0Down(void) {IN_KeyDown(&in_buttons[0]);}
|
||||
void IN_Button0Up(void) {IN_KeyUp(&in_buttons[0]);}
|
||||
void IN_Button1Down(void) {IN_KeyDown(&in_buttons[1]);}
|
||||
@@ -432,7 +450,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;
|
||||
@@ -461,6 +479,16 @@ CL_JoystickMove
|
||||
void CL_JoystickMove( usercmd_t *cmd ) {
|
||||
float anglespeed;
|
||||
|
||||
float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
|
||||
float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
|
||||
float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
|
||||
float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
|
||||
float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
|
||||
|
||||
if ( in_speed.active ^ cl_run->integer ) {
|
||||
cmd->buttons |= BUTTON_RUN;
|
||||
}
|
||||
|
||||
if ( in_speed.active ) {
|
||||
anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value;
|
||||
} else {
|
||||
@@ -468,18 +496,22 @@ void CL_JoystickMove( usercmd_t *cmd ) {
|
||||
}
|
||||
|
||||
if ( !in_strafe.active ) {
|
||||
cl.viewangles[YAW] += anglespeed * cl_yawspeed->value * cl.joystickAxis[AXIS_SIDE];
|
||||
cl.viewangles[YAW] += anglespeed * yaw;
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
|
||||
} else {
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + cl.joystickAxis[AXIS_SIDE] );
|
||||
cl.viewangles[YAW] += anglespeed * right;
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
|
||||
}
|
||||
|
||||
if ( in_mlooking ) {
|
||||
cl.viewangles[PITCH] += anglespeed * cl_pitchspeed->value * cl.joystickAxis[AXIS_FORWARD];
|
||||
cl.viewangles[PITCH] += anglespeed * forward;
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
|
||||
} else {
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + cl.joystickAxis[AXIS_FORWARD] );
|
||||
cl.viewangles[PITCH] += anglespeed * pitch;
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
|
||||
}
|
||||
|
||||
cmd->upmove = ClampChar( cmd->upmove + cl.joystickAxis[AXIS_UP] );
|
||||
cmd->upmove = ClampChar( cmd->upmove + (int)up );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -565,6 +597,8 @@ void CL_MouseMove( usercmd_t *cmd ) {
|
||||
mx *= cgameSensitivity;
|
||||
my *= cgameSensitivity;
|
||||
|
||||
cmd->buttons |= BUTTON_ANY;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if(in_strafe.active)
|
||||
cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx);
|
||||
@@ -575,6 +609,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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -609,8 +651,8 @@ void CL_CmdButtons( usercmd_t *cmd ) {
|
||||
if (UI_MenuActive() || UI_ConsoleIsOpen()) {
|
||||
cmd->buttons |= BUTTON_TALK;
|
||||
}
|
||||
|
||||
if (in_speed.active == !cl_run->integer) {
|
||||
|
||||
if ( in_speed.active ^ cl_run->integer ) {
|
||||
cmd->buttons |= BUTTON_RUN;
|
||||
}
|
||||
|
||||
@@ -718,6 +760,12 @@ void CL_CreateNewCommands( void ) {
|
||||
|
||||
frame_msec = com_frameTime - old_com_frameTime;
|
||||
|
||||
// if running over 1000fps, act as if each frame is 1ms
|
||||
// prevents divisions by zero
|
||||
if ( frame_msec < 1 ) {
|
||||
frame_msec = 1;
|
||||
}
|
||||
|
||||
// if running less than 5fps, truncate the extra time to prevent
|
||||
// unexpected moves after a hitch
|
||||
if ( frame_msec > 200 ) {
|
||||
@@ -909,6 +957,58 @@ void CL_WritePacket( void ) {
|
||||
count = MAX_PACKET_USERCMDS;
|
||||
Com_Printf("MAX_PACKET_USERCMDS\n");
|
||||
}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
if (clc.voipOutgoingDataSize > 0)
|
||||
{
|
||||
if((clc.voipFlags & VOIP_SPATIAL) || Com_IsVoipTarget(clc.voipTargets, sizeof(clc.voipTargets), -1))
|
||||
{
|
||||
MSG_WriteByte (&buf, clc_voipOpus);
|
||||
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
|
||||
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
|
||||
MSG_WriteByte (&buf, clc.voipOutgoingDataFrames);
|
||||
MSG_WriteData (&buf, clc.voipTargets, sizeof(clc.voipTargets));
|
||||
MSG_WriteByte(&buf, clc.voipFlags);
|
||||
MSG_WriteShort (&buf, clc.voipOutgoingDataSize);
|
||||
MSG_WriteData (&buf, clc.voipOutgoingData, clc.voipOutgoingDataSize);
|
||||
|
||||
// If we're recording a demo, we have to fake a server packet with
|
||||
// this VoIP data so it gets to disk; the server doesn't send it
|
||||
// back to us, and we might as well eliminate concerns about dropped
|
||||
// and misordered packets here.
|
||||
if(clc.demorecording && !clc.demowaiting)
|
||||
{
|
||||
const int voipSize = clc.voipOutgoingDataSize;
|
||||
msg_t fakemsg;
|
||||
byte fakedata[MAX_MSGLEN];
|
||||
MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
|
||||
MSG_Bitstream (&fakemsg);
|
||||
MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
|
||||
MSG_WriteByte (&fakemsg, svc_voipOpus);
|
||||
MSG_WriteShort (&fakemsg, clc.clientNum);
|
||||
MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
|
||||
MSG_WriteLong (&fakemsg, clc.voipOutgoingSequence);
|
||||
MSG_WriteByte (&fakemsg, clc.voipOutgoingDataFrames);
|
||||
MSG_WriteShort (&fakemsg, clc.voipOutgoingDataSize );
|
||||
MSG_WriteBits (&fakemsg, clc.voipFlags, VOIP_FLAGCNT);
|
||||
MSG_WriteData (&fakemsg, clc.voipOutgoingData, voipSize);
|
||||
MSG_WriteByte (&fakemsg, svc_EOF);
|
||||
CL_WriteDemoMessage (&fakemsg, 0);
|
||||
}
|
||||
|
||||
clc.voipOutgoingSequence += clc.voipOutgoingDataFrames;
|
||||
clc.voipOutgoingDataSize = 0;
|
||||
clc.voipOutgoingDataFrames = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have data, but no targets. Silently discard all data
|
||||
clc.voipOutgoingDataSize = 0;
|
||||
clc.voipOutgoingDataFrames = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( count >= 1 ) {
|
||||
if ( cl_showSend->integer ) {
|
||||
Com_Printf( "(%i)", count );
|
||||
@@ -965,16 +1065,6 @@ void CL_WritePacket( void ) {
|
||||
}
|
||||
|
||||
CL_Netchan_Transmit (&clc.netchan, &buf);
|
||||
|
||||
// clients never really should have messages large enough
|
||||
// to fragment, but in case they do, fire them all off
|
||||
// at once
|
||||
// TTimo: this causes a packet burst, which is bad karma for winsock
|
||||
// added a WARNING message, we'll see if there are legit situations where this happens
|
||||
while ( clc.netchan.unsentFragments ) {
|
||||
Com_DPrintf( "WARNING: #462 unsent fragments (not supposed to happen!)\n" );
|
||||
CL_Netchan_TransmitNextFragment( &clc.netchan );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -991,7 +1081,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;
|
||||
}
|
||||
|
||||
@@ -1086,6 +1176,85 @@ void CL_InitInput( void ) {
|
||||
Cmd_AddCommand("+mlook", IN_MLookDown);
|
||||
Cmd_AddCommand("-mlook", IN_MLookUp);
|
||||
|
||||
#ifdef USE_VOIP
|
||||
Cmd_AddCommand ("+voiprecord", IN_VoipRecordDown);
|
||||
Cmd_AddCommand ("-voiprecord", IN_VoipRecordUp);
|
||||
#endif
|
||||
|
||||
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
|
||||
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_ShutdownInput
|
||||
============
|
||||
*/
|
||||
void CL_ShutdownInput(void)
|
||||
{
|
||||
Cmd_RemoveCommand("centerview");
|
||||
|
||||
Cmd_RemoveCommand("+moveup");
|
||||
Cmd_RemoveCommand("-moveup");
|
||||
Cmd_RemoveCommand("+movedown");
|
||||
Cmd_RemoveCommand("-movedown");
|
||||
Cmd_RemoveCommand("+left");
|
||||
Cmd_RemoveCommand("-left");
|
||||
Cmd_RemoveCommand("+right");
|
||||
Cmd_RemoveCommand("-right");
|
||||
Cmd_RemoveCommand("+forward");
|
||||
Cmd_RemoveCommand("-forward");
|
||||
Cmd_RemoveCommand("+back");
|
||||
Cmd_RemoveCommand("-back");
|
||||
Cmd_RemoveCommand("+lookup");
|
||||
Cmd_RemoveCommand("-lookup");
|
||||
Cmd_RemoveCommand("+lookdown");
|
||||
Cmd_RemoveCommand("-lookdown");
|
||||
Cmd_RemoveCommand("+strafe");
|
||||
Cmd_RemoveCommand("-strafe");
|
||||
Cmd_RemoveCommand("+moveleft");
|
||||
Cmd_RemoveCommand("-moveleft");
|
||||
Cmd_RemoveCommand("+moveright");
|
||||
Cmd_RemoveCommand("-moveright");
|
||||
Cmd_RemoveCommand("+speed");
|
||||
Cmd_RemoveCommand("-speed");
|
||||
Cmd_RemoveCommand("+attack");
|
||||
Cmd_RemoveCommand("-attack");
|
||||
Cmd_RemoveCommand("+button0");
|
||||
Cmd_RemoveCommand("-button0");
|
||||
Cmd_RemoveCommand("+button1");
|
||||
Cmd_RemoveCommand("-button1");
|
||||
Cmd_RemoveCommand("+button2");
|
||||
Cmd_RemoveCommand("-button2");
|
||||
Cmd_RemoveCommand("+button3");
|
||||
Cmd_RemoveCommand("-button3");
|
||||
Cmd_RemoveCommand("+button4");
|
||||
Cmd_RemoveCommand("-button4");
|
||||
Cmd_RemoveCommand("+button5");
|
||||
Cmd_RemoveCommand("-button5");
|
||||
Cmd_RemoveCommand("+button6");
|
||||
Cmd_RemoveCommand("-button6");
|
||||
Cmd_RemoveCommand("+button7");
|
||||
Cmd_RemoveCommand("-button7");
|
||||
Cmd_RemoveCommand("+button8");
|
||||
Cmd_RemoveCommand("-button8");
|
||||
Cmd_RemoveCommand("+button9");
|
||||
Cmd_RemoveCommand("-button9");
|
||||
Cmd_RemoveCommand("+button10");
|
||||
Cmd_RemoveCommand("-button10");
|
||||
Cmd_RemoveCommand("+button11");
|
||||
Cmd_RemoveCommand("-button11");
|
||||
Cmd_RemoveCommand("+button12");
|
||||
Cmd_RemoveCommand("-button12");
|
||||
Cmd_RemoveCommand("+button13");
|
||||
Cmd_RemoveCommand("-button13");
|
||||
Cmd_RemoveCommand("+button14");
|
||||
Cmd_RemoveCommand("-button14");
|
||||
Cmd_RemoveCommand("+mlook");
|
||||
Cmd_RemoveCommand("-mlook");
|
||||
|
||||
#ifdef USE_VOIP
|
||||
Cmd_RemoveCommand("+voiprecord");
|
||||
Cmd_RemoveCommand("-voiprecord");
|
||||
#endif
|
||||
}
|
||||
+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);
|
||||
+933
-915
File diff suppressed because it is too large.
Load diff
+652
-413
File diff suppressed because it is too large.
Load diff
@@ -132,7 +132,7 @@ CL_Netchan_TransmitNextFragment
|
||||
=================
|
||||
*/
|
||||
void CL_Netchan_TransmitNextFragment( netchan_t *chan ) {
|
||||
Netchan_TransmitNextFragment( chan );
|
||||
Netchan_TransmitNextFragment( chan, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,7 +144,7 @@ void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
|
||||
MSG_WriteByte( msg, clc_EOF );
|
||||
|
||||
CL_Netchan_Encode( msg );
|
||||
Netchan_Transmit( chan, msg->cursize, msg->data );
|
||||
Netchan_Transmit( chan, msg->cursize, msg->data, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
|
||||
}
|
||||
|
||||
extern int oldsize;
|
||||
@@ -158,10 +158,30 @@ CL_Netchan_Process
|
||||
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
||||
int ret;
|
||||
|
||||
ret = Netchan_Process( chan, msg );
|
||||
ret = Netchan_Process( chan, msg, cl_netprofile->integer ? &cls.netprofile.outPackets : NULL );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
CL_Netchan_Decode( msg );
|
||||
newsize += msg->cursize;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_NET_OutOfBandPrint
|
||||
=================
|
||||
*/
|
||||
void CL_NET_OutOfBandPrint(netadr_t adr, const char* format, ...) {
|
||||
va_list argptr;
|
||||
char string[MAX_MSGLEN];
|
||||
|
||||
va_start(argptr, format);
|
||||
Q_vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
NET_OutOfBandPrint(NS_CLIENT, adr, "%s", string);
|
||||
|
||||
if (cl_netprofile->integer) {
|
||||
NetProfileAddPacket(&cls.netprofile.inPackets, strlen(string), NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
}
|
||||
+201
-43
@@ -223,13 +223,13 @@ qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
|
||||
range = 0;
|
||||
}
|
||||
|
||||
unpacked->x = x * range / 63.f;
|
||||
unpacked->y = y * range / 63.f;
|
||||
unpacked->x = x * range / (MAX_CLIENTS - 1);
|
||||
unpacked->y = y * range / (MAX_CLIENTS - 1);
|
||||
|
||||
if (!bValid)
|
||||
{
|
||||
unpacked->x = x * range / 63.f * 1024;
|
||||
unpacked->y = y * range / 63.f * 1024;
|
||||
unpacked->x = x * range / (MAX_CLIENTS - 1) * 1024.0;
|
||||
unpacked->y = y * range / (MAX_CLIENTS - 1) * 1024.0;
|
||||
}
|
||||
|
||||
unpacked->yaw = yaw * 11.25f;
|
||||
@@ -429,12 +429,24 @@ void CL_SystemInfoChanged( void ) {
|
||||
// in some cases, outdated cp commands might get sent with this news serverId
|
||||
cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) );
|
||||
|
||||
#ifdef USE_VOIP
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(clc.compat)
|
||||
clc.voipEnabled = qfalse;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s = Info_ValueForKey( systemInfo, "sv_voipProtocol" );
|
||||
clc.voipEnabled = !Q_stricmp(s, "opus");
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't set any vars when playing a demo
|
||||
if ( clc.demoplaying ) {
|
||||
return;
|
||||
}
|
||||
|
||||
s = Info_ValueForKey( systemInfo, "sv_cheats" );
|
||||
s = Info_ValueForKey( systemInfo, "cheats" );
|
||||
cl_connectedToCheatServer = atoi( s );
|
||||
if ( !cl_connectedToCheatServer ) {
|
||||
Cvar_SetCheatState();
|
||||
@@ -514,40 +526,6 @@ static void CL_ParseServerInfo(void)
|
||||
sizeof(clc.sv_dlURL));
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar_ver_15(msg_t* msg) {
|
||||
return MSG_ReadScrambledBigString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime_ver_15(msg_t* msg) {
|
||||
return MSG_ReadFloat(msg);
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar_ver_6(msg_t* msg) {
|
||||
return MSG_ReadString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime_ver_6(msg_t* msg) {
|
||||
return 1.f / atof(Info_ValueForKey(cl.gameState.stringData + cl.gameState.stringOffsets[CS_SYSTEMINFO], "sv_fps"));
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar(msg_t* msg) {
|
||||
if (MSG_IsProtocolVersion15()) {
|
||||
return MSG_ReadGameStateChar_ver_15(msg);
|
||||
} else {
|
||||
// smaller below version 15
|
||||
return MSG_ReadGameStateChar_ver_6(msg);
|
||||
}
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime(msg_t* msg) {
|
||||
if (MSG_IsProtocolVersion15()) {
|
||||
return MSG_ReadServerFrameTime_ver_15(msg);
|
||||
} else {
|
||||
// smaller below version 15
|
||||
return MSG_ReadServerFrameTime_ver_6(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseGamestate
|
||||
@@ -591,7 +569,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
if (csNum < 0 || csNum >= MAX_CONFIGSTRINGS) {
|
||||
Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
|
||||
}
|
||||
s = MSG_ReadGameStateChar(msg);
|
||||
s = MSG_ReadScrambledBigString(msg);
|
||||
len = strlen(s);
|
||||
|
||||
if (len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS) {
|
||||
@@ -620,7 +598,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
clc.clientNum = MSG_ReadLong(msg);
|
||||
// read the checksum feed
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg);
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg, &cl.gameState);
|
||||
|
||||
// parse serverId and other cvars
|
||||
CL_SystemInfoChanged();
|
||||
@@ -818,6 +796,178 @@ void CL_ParseDownload ( msg_t *msg ) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
static
|
||||
qboolean CL_ShouldIgnoreVoipSender(int sender)
|
||||
{
|
||||
if (!cl_voip->integer)
|
||||
return qtrue; // VoIP is disabled.
|
||||
else if ((sender == clc.clientNum) && (!clc.demoplaying))
|
||||
return qtrue; // ignore own voice (unless playing back a demo).
|
||||
else if (clc.voipMuteAll)
|
||||
return qtrue; // all channels are muted with extreme prejudice.
|
||||
else if (clc.voipIgnore[sender])
|
||||
return qtrue; // just ignoring this guy.
|
||||
else if (clc.voipGain[sender] == 0.0f)
|
||||
return qtrue; // too quiet to play.
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_PlayVoip
|
||||
|
||||
Play raw data
|
||||
=====================
|
||||
*/
|
||||
|
||||
static void CL_PlayVoip(int sender, int samplecnt, const byte *data, int flags)
|
||||
{
|
||||
if(flags & VOIP_DIRECT)
|
||||
{
|
||||
S_RawSamples(sender + 1, samplecnt, 48000, 2, 1,
|
||||
data, clc.voipGain[sender], -1);
|
||||
}
|
||||
|
||||
if(flags & VOIP_SPATIAL)
|
||||
{
|
||||
S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, 48000, 2, 1,
|
||||
data, 1.0f, sender);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseVoip
|
||||
|
||||
A VoIP message has been received from the server
|
||||
=====================
|
||||
*/
|
||||
static
|
||||
void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) {
|
||||
static short decoded[VOIP_MAX_PACKET_SAMPLES*4]; // !!! FIXME: don't hard code
|
||||
|
||||
const int sender = MSG_ReadShort(msg);
|
||||
const int generation = MSG_ReadByte(msg);
|
||||
const int sequence = MSG_ReadLong(msg);
|
||||
const int frames = MSG_ReadByte(msg);
|
||||
const int packetsize = MSG_ReadShort(msg);
|
||||
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
|
||||
unsigned char encoded[4000];
|
||||
int numSamples;
|
||||
int seqdiff;
|
||||
int written = 0;
|
||||
int i;
|
||||
|
||||
Com_DPrintf("VoIP: %d-byte packet from client %d\n", packetsize, sender);
|
||||
|
||||
if (sender < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (generation < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (sequence < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (frames < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (packetsize < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
|
||||
if (packetsize > sizeof (encoded)) { // overlarge packet?
|
||||
int bytesleft = packetsize;
|
||||
while (bytesleft) {
|
||||
int br = bytesleft;
|
||||
if (br > sizeof (encoded))
|
||||
br = sizeof (encoded);
|
||||
MSG_ReadData(msg, encoded, br);
|
||||
bytesleft -= br;
|
||||
}
|
||||
return; // overlarge packet, bail.
|
||||
}
|
||||
|
||||
MSG_ReadData(msg, encoded, packetsize);
|
||||
|
||||
if (ignoreData) {
|
||||
return; // just ignore legacy speex voip data
|
||||
} else if (!clc.voipCodecInitialized) {
|
||||
return; // can't handle VoIP without libopus!
|
||||
} else if (sender >= MAX_CLIENTS) {
|
||||
return; // bogus sender.
|
||||
} else if (CL_ShouldIgnoreVoipSender(sender)) {
|
||||
return; // Channel is muted, bail.
|
||||
}
|
||||
|
||||
// !!! FIXME: make sure data is narrowband? Does decoder handle this?
|
||||
|
||||
Com_DPrintf("VoIP: packet accepted!\n");
|
||||
|
||||
seqdiff = sequence - clc.voipIncomingSequence[sender];
|
||||
|
||||
// This is a new "generation" ... a new recording started, reset the bits.
|
||||
if (generation != clc.voipIncomingGeneration[sender]) {
|
||||
Com_DPrintf("VoIP: new generation %d!\n", generation);
|
||||
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
|
||||
clc.voipIncomingGeneration[sender] = generation;
|
||||
seqdiff = 0;
|
||||
} else if (seqdiff < 0) { // we're ahead of the sequence?!
|
||||
// This shouldn't happen unless the packet is corrupted or something.
|
||||
Com_DPrintf("VoIP: misordered sequence! %d < %d!\n",
|
||||
sequence, clc.voipIncomingSequence[sender]);
|
||||
// reset the decoder just in case.
|
||||
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
|
||||
seqdiff = 0;
|
||||
} else if (seqdiff * VOIP_MAX_PACKET_SAMPLES*2 >= sizeof (decoded)) { // dropped more than we can handle?
|
||||
// just start over.
|
||||
Com_DPrintf("VoIP: Dropped way too many (%d) frames from client #%d\n",
|
||||
seqdiff, sender);
|
||||
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
|
||||
seqdiff = 0;
|
||||
}
|
||||
|
||||
if (seqdiff != 0) {
|
||||
Com_DPrintf("VoIP: Dropped %d frames from client #%d\n",
|
||||
seqdiff, sender);
|
||||
// tell opus that we're missing frames...
|
||||
for (i = 0; i < seqdiff; i++) {
|
||||
assert((written + VOIP_MAX_PACKET_SAMPLES) * 2 < sizeof (decoded));
|
||||
numSamples = opus_decode(clc.opusDecoder[sender], NULL, 0, decoded + written, VOIP_MAX_PACKET_SAMPLES, 0);
|
||||
if ( numSamples <= 0 ) {
|
||||
Com_DPrintf("VoIP: Error decoding frame %d from client #%d\n", i, sender);
|
||||
continue;
|
||||
}
|
||||
written += numSamples;
|
||||
}
|
||||
}
|
||||
|
||||
numSamples = opus_decode(clc.opusDecoder[sender], encoded, packetsize, decoded + written, ARRAY_LEN(decoded) - written, 0);
|
||||
|
||||
if ( numSamples <= 0 ) {
|
||||
Com_DPrintf("VoIP: Error decoding voip data from client #%d\n", sender);
|
||||
numSamples = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static FILE *encio = NULL;
|
||||
if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb");
|
||||
if (encio != NULL) { fwrite(encoded, packetsize, 1, encio); fflush(encio); }
|
||||
static FILE *decio = NULL;
|
||||
if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb");
|
||||
if (decio != NULL) { fwrite(decoded+written, numSamples*2, 1, decio); fflush(decio); }
|
||||
#endif
|
||||
|
||||
written += numSamples;
|
||||
|
||||
Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n",
|
||||
written * 2, written, frames);
|
||||
|
||||
if(written > 0)
|
||||
CL_PlayVoip(sender, written, (const byte *) decoded, flags);
|
||||
|
||||
clc.voipIncomingSequence[sender] = sequence + frames;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseCommandString
|
||||
@@ -966,8 +1116,16 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
||||
}
|
||||
CL_ParseCGMessage( msg );
|
||||
break;
|
||||
case svc_voipSpeex:
|
||||
#ifdef USE_VOIP
|
||||
CL_ParseVoip( msg, qtrue );
|
||||
#endif
|
||||
break;
|
||||
case svc_voipOpus:
|
||||
#ifdef USE_VOIP
|
||||
CL_ParseVoip( msg, !clc.voipEnabled );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ void SCR_DrawDemoRecording( void ) {
|
||||
}
|
||||
|
||||
pos = FS_FTell( clc.demofile );
|
||||
sprintf( string, "RECORDING %s: %ik", clc.demoName, pos / 1024 );
|
||||
Com_sprintf( string, sizeof( string ), "RECORDING %s: %ik", clc.demoName, pos / 1024 );
|
||||
|
||||
SCR_DrawStringExt( 320 - strlen( string ) * 4, 20, 8, string, g_color_table[7], qtrue, qfalse );
|
||||
}
|
||||
@@ -520,16 +520,18 @@ text to the screen.
|
||||
==================
|
||||
*/
|
||||
void SCR_UpdateScreen( void ) {
|
||||
static int recursive;
|
||||
static qboolean screen_recursive;
|
||||
|
||||
if ( !scr_initialized ) {
|
||||
return; // not initialized yet
|
||||
}
|
||||
|
||||
if ( ++recursive > 2 ) {
|
||||
Com_Error( ERR_FATAL, "SCR_UpdateScreen: recursively called" );
|
||||
if (screen_recursive) {
|
||||
// already called
|
||||
return;
|
||||
}
|
||||
recursive = 1;
|
||||
|
||||
screen_recursive = qtrue;
|
||||
|
||||
CL_StartHunkUsers(qfalse);
|
||||
SCR_SimpleUpdateScreen();
|
||||
@@ -553,6 +555,6 @@ void SCR_UpdateScreen( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
recursive = 0;
|
||||
screen_recursive = qfalse;
|
||||
}
|
||||
|
||||
+4097
-4134
File diff suppressed because it is too large.
Load diff
+89
-68
@@ -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.
|
||||
|
||||
@@ -20,112 +20,133 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UI_H__
|
||||
#define __CL_UI_H__
|
||||
#pragma once
|
||||
|
||||
#include "../uilib/ui_extern.h"
|
||||
#include "../uilib/uiwidget.h"
|
||||
|
||||
typedef struct {
|
||||
UIReggedMaterial *loading;
|
||||
UIReggedMaterial *loading;
|
||||
} static_media_t;
|
||||
|
||||
//
|
||||
// cvars
|
||||
//
|
||||
extern cvar_t* ui_health_start;
|
||||
extern cvar_t* ui_health_end;
|
||||
extern cvar_t* sound_overlay;
|
||||
extern cvar_t *ui_health_start;
|
||||
extern cvar_t *ui_health_end;
|
||||
extern cvar_t *sound_overlay;
|
||||
extern cvar_t *cl_movieaudio;
|
||||
|
||||
//
|
||||
// initialization
|
||||
//
|
||||
void CL_FillUIDef( void );
|
||||
void CL_InitializeUI( void );
|
||||
void CL_ShutdownUI( void );
|
||||
void CL_FillUIDef(void);
|
||||
void CL_InitializeUI(void);
|
||||
void CL_ShutdownUI(void);
|
||||
|
||||
//
|
||||
// general ui stuff
|
||||
//
|
||||
extern inventory_t client_inv;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t* cl_greenfps;
|
||||
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 );
|
||||
void CL_BeginRegistration( void );
|
||||
void CL_EndRegistration(void);
|
||||
const char *CvarGetForUI(const char *name, const char *defval);
|
||||
void UI_ClearState(void);
|
||||
void CL_BeginRegistration(void);
|
||||
void CL_EndRegistration(void);
|
||||
float UI_GetObjectivesTop(void);
|
||||
|
||||
//
|
||||
// menu
|
||||
//
|
||||
extern Menu *ui_pLoadingMenu;
|
||||
|
||||
void UI_ShowMenu( const char *name, qboolean bForce );
|
||||
void UI_HideMenu( const char *name, qboolean bForce );
|
||||
void UI_ForceMenuOff( bool force );
|
||||
void UI_PushMenu( const char *name );
|
||||
void UI_ForceMenu( const char *name );
|
||||
qboolean UI_BindActive( void );
|
||||
void UI_SetReturnMenuToCurrent(void);
|
||||
void UI_ActivateView3D( void );
|
||||
void UI_MenuEscape( const char *name );
|
||||
void UI_CreateScoreboard( void );
|
||||
qboolean UI_MenuActive( void );
|
||||
qboolean UI_MenuUp( void );
|
||||
void UI_FocusMenuIfExists(void);
|
||||
void UI_DrawConnect( void );
|
||||
void UI_CreateDialog( const char *title, char *cvarname, const char *command, const char *cancelCommand, int width, int height, const char *shader, const char *okshader, const char *cancelshader );
|
||||
void UI_ToggleDMConsole( int iMode );
|
||||
void UI_ShowScoreboard_f( const char *pszMenuName );
|
||||
void UI_HideScoreboard_f( void );
|
||||
void UI_SetScoreBoardItem( int iItemNumber,
|
||||
const char *pszData1, const char *pszData2, const char *pszData3, const char *pszData4,
|
||||
const char *pszData5, const char *pszData6, const char *pszData7, const char *pszData8,
|
||||
const vec4_t pTextColor, const vec4_t pBackColor, qboolean bIsHeader );
|
||||
void UI_DeleteScoreBoardItems( int iMaxIndex );
|
||||
void UI_ShowMenu(const char *name, qboolean bForce);
|
||||
void UI_HideMenu(const char *name, qboolean bForce);
|
||||
void UI_ForceMenuOff(bool force);
|
||||
void UI_PushMenu(const char *name);
|
||||
void UI_ForceMenu(const char *name);
|
||||
qboolean UI_BindActive(void);
|
||||
void UI_SetReturnMenuToCurrent(void);
|
||||
void UI_ActivateView3D(void);
|
||||
void UI_MenuEscape(const char *name);
|
||||
void UI_CreateScoreboard(void);
|
||||
qboolean UI_MenuActive(void);
|
||||
qboolean UI_MenuUp(void);
|
||||
void UI_FocusMenuIfExists(void);
|
||||
void UI_DrawConnect(void);
|
||||
void UI_CreateDialog(
|
||||
const char *title,
|
||||
char *cvarname,
|
||||
const char *command,
|
||||
const char *cancelCommand,
|
||||
int width,
|
||||
int height,
|
||||
const char *shader,
|
||||
const char *okshader,
|
||||
const char *cancelshader
|
||||
);
|
||||
void UI_ToggleDMConsole(int iMode);
|
||||
void UI_ShowScoreboard_f(const char *pszMenuName);
|
||||
void UI_HideScoreboard_f(void);
|
||||
void UI_SetScoreBoardItem(
|
||||
int iItemNumber,
|
||||
const char *pszData1,
|
||||
const char *pszData2,
|
||||
const char *pszData3,
|
||||
const char *pszData4,
|
||||
const char *pszData5,
|
||||
const char *pszData6,
|
||||
const char *pszData7,
|
||||
const char *pszData8,
|
||||
const vec4_t pTextColor,
|
||||
const vec4_t pBackColor,
|
||||
qboolean bIsHeader
|
||||
);
|
||||
void UI_DeleteScoreBoardItems(int iMaxIndex);
|
||||
|
||||
//
|
||||
// ressources
|
||||
//
|
||||
void UI_BeginLoad( const char *pszMapName );
|
||||
void UI_EndLoad( void );
|
||||
void UI_AbortLoad( void );
|
||||
void UI_BeginLoadResource( void );
|
||||
void UI_EndLoadResource( void );
|
||||
void UI_EndLoadResource( const char *name );
|
||||
qboolean UI_IsResourceLoaded( const char *name );
|
||||
void UI_RegisterLoadResource( const char *name );
|
||||
void UI_ClearResource( void );
|
||||
void UI_LoadResource( const char *name );
|
||||
void UI_BeginLoad(const char *pszMapName);
|
||||
void UI_EndLoad(void);
|
||||
void UI_AbortLoad(void);
|
||||
int CL_FontStringWidth(fontheader_t* pFont, const char* pszString, int iMaxLen);
|
||||
void UI_BeginLoadResource(void);
|
||||
void UI_EndLoadResource(void);
|
||||
void UI_EndLoadResource(const char *name);
|
||||
qboolean UI_IsResourceLoaded(const char *name);
|
||||
void UI_RegisterLoadResource(const char *name);
|
||||
void UI_ClearResource(void);
|
||||
void UI_LoadResource(const char *name);
|
||||
|
||||
//
|
||||
// windows
|
||||
//
|
||||
void UI_DeactiveFloatingWindows( void );
|
||||
void UI_DeactiveFloatingWindows(void);
|
||||
|
||||
//
|
||||
// console
|
||||
//
|
||||
void UI_OpenConsole( void );
|
||||
qboolean UI_ConsoleIsVisible( void );
|
||||
qboolean UI_ConsoleIsOpen( void );
|
||||
void UI_CloseConsole( void );
|
||||
void UI_ToggleConsole( void );
|
||||
void UI_OpenDMConsole( int iMode );
|
||||
void UI_CloseDMConsole( void );
|
||||
void UI_ToggleDMConsole( int iMode );
|
||||
void UI_OpenDeveloperConsole( void );
|
||||
void UI_CloseDeveloperConsole( void );
|
||||
void UI_PrintConsole(const char* msg);
|
||||
void UI_OpenConsole(void);
|
||||
qboolean UI_ConsoleIsVisible(void);
|
||||
qboolean UI_ConsoleIsOpen(void);
|
||||
void UI_CloseConsole(void);
|
||||
void UI_ToggleConsole(void);
|
||||
void UI_OpenDMConsole(int iMode);
|
||||
void UI_CloseDMConsole(void);
|
||||
void UI_ToggleDMConsole(int iMode);
|
||||
void UI_OpenDeveloperConsole(void);
|
||||
void UI_CloseDeveloperConsole(void);
|
||||
void UI_PrintConsole(const char *msg);
|
||||
|
||||
//
|
||||
// callbacks
|
||||
//
|
||||
void UI_Update( void );
|
||||
void UI_ServerLoaded( void );
|
||||
void UI_ResolutionChange( void );
|
||||
void UI_KeyEvent( int key, unsigned int time );
|
||||
void UI_CharEvent( int ch );
|
||||
|
||||
#endif /* __CL_UI_H__ */
|
||||
void UI_Update(void);
|
||||
void UI_ServerLoaded(void);
|
||||
void UI_ResolutionChange(void);
|
||||
void UI_KeyEvent(int key, unsigned int time);
|
||||
void UI_CharEvent(int ch);
|
||||
+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);
|
||||
@@ -61,6 +61,7 @@ UIDMBox::UIDMBox()
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
}
|
||||
|
||||
void UIDMBox::VerifyBoxOut( void )
|
||||
@@ -278,6 +279,28 @@ float UIDMBox::PrintWrap( UIFont *font, float x, float y, str text )
|
||||
|
||||
float UIDMBox::DrawItem( item_t *in, float x, float y, float alpha )
|
||||
{
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
@@ -316,7 +339,11 @@ void UIDMBox::Print( const char *text )
|
||||
}
|
||||
else if (*text == MESSAGE_CHAT_GREEN)
|
||||
{
|
||||
m_items[m_numitems].color = UGreen;
|
||||
if (com_target_game->integer >= TG_MOHTA) {
|
||||
m_items[m_numitems].color = ULightGreen;
|
||||
} else {
|
||||
m_items[m_numitems].color = UGreen;
|
||||
}
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2015-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIDMBOX_H__
|
||||
#define __CL_UIDMBOX_H__
|
||||
#pragma once
|
||||
|
||||
static constexpr unsigned int DMBOX_ITEM_FLAG_BOLD = 2u;
|
||||
static constexpr unsigned int DMBOX_ITEM_FLAG_DEATH = 4u;
|
||||
@@ -47,6 +46,8 @@ protected:
|
||||
int m_movespeed;
|
||||
int m_iBeginDecay;
|
||||
int m_iEndDecay;
|
||||
// Added in OPM
|
||||
bool m_drawoutline;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIDMBox );
|
||||
@@ -75,5 +76,3 @@ public:
|
||||
void setRealShow( bool b );
|
||||
void Clear( void );
|
||||
};
|
||||
|
||||
#endif /* __CL_UIDMBOX_H__ */
|
||||
+211
-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,256 @@ 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;
|
||||
if (ignore_files) {
|
||||
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__ */
|
||||
@@ -61,6 +61,7 @@ UIGMBox::UIGMBox()
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
}
|
||||
|
||||
void UIGMBox::VerifyBoxOut( void )
|
||||
@@ -272,6 +273,28 @@ float UIGMBox::PrintWrap( UIFont *font, float x, float y, str text )
|
||||
|
||||
float UIGMBox::DrawItem( item_t *in, float x, float y, float alpha )
|
||||
{
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2015-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIGMBOX_H__
|
||||
#define __CL_UIGMBOX_H__
|
||||
#pragma once
|
||||
|
||||
static constexpr unsigned int GMBOX_ITEM_FLAG_BOLD = 1u;
|
||||
|
||||
@@ -44,6 +43,8 @@ protected:
|
||||
int m_movespeed;
|
||||
int m_iBeginDecay;
|
||||
int m_iEndDecay;
|
||||
// Added in OPM
|
||||
bool m_drawoutline;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIGMBox );
|
||||
@@ -72,5 +73,3 @@ public:
|
||||
void setRealShow( bool b );
|
||||
void Clear( void );
|
||||
};
|
||||
|
||||
#endif
|
||||
+197
-17
@@ -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.
|
||||
|
||||
@@ -21,44 +21,224 @@ 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[6];
|
||||
|
||||
public:
|
||||
LANGameItem();
|
||||
LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping, const str& ipAddress
|
||||
);
|
||||
|
||||
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");
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
m_bVirtual = false;
|
||||
}
|
||||
|
||||
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.27f, false, false); // was 0.4
|
||||
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.12f, false, false); // was 0.15
|
||||
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.08f, true, true); // was 0.165
|
||||
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.118f, false, false); // was 0.22
|
||||
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.052f, true, false); // was 0.065
|
||||
AddColumn(Sys_LV_CL_ConvertString("IP"), 5, width * 0.36f, false, false); // Added in OPM
|
||||
|
||||
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),
|
||||
// Added in OPM
|
||||
NET_AdrToStringwPort(pServerInfo->adr)
|
||||
);
|
||||
}
|
||||
|
||||
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_AdrToStringwPort(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, const str& ipAddress
|
||||
)
|
||||
{
|
||||
strings[0] = hostName;
|
||||
strings[1] = mapName;
|
||||
strings[2] = players;
|
||||
strings[3] = gameTypeString;
|
||||
strings[4] = ping;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
|
||||
strings[5] = ipAddress;
|
||||
}
|
||||
|
||||
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(true);
|
||||
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 UIListCtrl::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
-28
@@ -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,38 +20,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UILOADSAVE_H__
|
||||
#define __CL_UILOADSAVE_H__
|
||||
#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;
|
||||
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();
|
||||
UIFAKKLoadGameClass();
|
||||
~UIFAKKLoadGameClass();
|
||||
|
||||
void SetupFiles( void );
|
||||
void SetupFiles(void);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void UI_SetupFiles( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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);
|
||||
}
|
||||
|
||||
Q_strncpyz(mapBuffer, maplistVar->string, sizeof(mapBuffer));
|
||||
|
||||
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;
|
||||
|
||||
Q_strncpyz(mapName, filename, sizeof(mapName));
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bTugOfWar || bLiberation) {
|
||||
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
|
||||
|
||||
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) {
|
||||
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
|
||||
|
||||
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];
|
||||
|
||||
Q_strncpyz(mapName, filename, sizeof(mapName));
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
|
||||
|
||||
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];
|
||||
|
||||
Q_strncpyz(mapName, filename, sizeof(mapName));
|
||||
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();
|
||||
str currentItemText;
|
||||
|
||||
if (item) {
|
||||
currentItemText = mapList->getItemText(item);
|
||||
}
|
||||
|
||||
for (i = 1; i <= rotationList->getNumItems(); i++) {
|
||||
str text = rotationList->getItemText(i);
|
||||
if (text == currentItemText) {
|
||||
// Added in OPM
|
||||
// Prevent adding duplicates
|
||||
item = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mapLength += text.length();
|
||||
}
|
||||
|
||||
if (item && prefixLength + mapLength + currentItemText.length() < 256) {
|
||||
rotationList->AddItem(currentItemText, 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;
|
||||
|
||||
Q_strncpyz(map, text, sizeof(map));
|
||||
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;
|
||||
|
||||
if (i == 1) {
|
||||
Cvar_Set("ui_dmmap", maplistStr);
|
||||
}
|
||||
|
||||
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 > 1 && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item - 1);
|
||||
|
||||
list->DeleteItem(item - 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(item + 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() - 1; 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);
|
||||
+14
-11
@@ -58,7 +58,7 @@ void UIRadar::Draw(void)
|
||||
float inv;
|
||||
float iconSize;
|
||||
int blinkTime, speakTime;
|
||||
float origin[2], axis[2];
|
||||
vec2_t origin, axis;
|
||||
float halfScale;
|
||||
int i;
|
||||
|
||||
@@ -105,17 +105,17 @@ void UIRadar::Draw(void)
|
||||
halfScale = iconSize * 0.5f;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
float delta[2];
|
||||
float newOrg[2];
|
||||
float screenOrg[2];
|
||||
float length;
|
||||
vec2_t delta;
|
||||
vec2_t newOrg;
|
||||
vec2_t screenOrg;
|
||||
float length;
|
||||
|
||||
radar = &g_radarClients[i];
|
||||
if (i == g_radarClientNum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_radarClients[i].time) {
|
||||
if (!radar->time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -128,10 +128,13 @@ void UIRadar::Draw(void)
|
||||
// make the icon blink
|
||||
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (delta < 0 || delta >= speakTime) {
|
||||
radar->lastSpeakTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
radar->lastSpeakTime = 0;
|
||||
delta[0] = radar->origin[0] - origin[0];
|
||||
delta[1] = radar->origin[1] - origin[1];
|
||||
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv;
|
||||
@@ -140,12 +143,12 @@ void UIRadar::Draw(void)
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv * (1.f / length);
|
||||
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv * (1.f / length);
|
||||
newOrg[0] *= 1.f / length;
|
||||
newOrg[1] *= 1.f / length;
|
||||
}
|
||||
|
||||
screenOrg[0] = -((halfScale * (1.141f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
|
||||
screenOrg[1] = -((halfScale * (1.141f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
|
||||
screenOrg[0] = -((halfScale * (1.414f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
|
||||
screenOrg[1] = -((halfScale * (1.414f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
|
||||
|
||||
uii.Rend_DrawPicStretched2(
|
||||
screenOrg[0],
|
||||
|
||||
@@ -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,
|
||||
@@ -638,6 +651,9 @@ static void AddFilter(char* filter, const char* value) {
|
||||
void UIFAKKServerList::CancelRefresh( Event *ev )
|
||||
{
|
||||
ServerListHalt(m_serverList[0]);
|
||||
if (m_serverList[1]) {
|
||||
ServerListHalt(m_serverList[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void UIFAKKServerList::NewServerList( void )
|
||||
@@ -730,6 +746,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 )
|
||||
@@ -1009,38 +1033,58 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_Set("dm_serverstatusbar", va("%i", param2));
|
||||
Cvar_Set("dm_serverstatusbar", va("%i", (int)(uintptr_t)param2));
|
||||
}
|
||||
|
||||
if (msg == LIST_PROGRESS)
|
||||
{
|
||||
const char* pszHostName;
|
||||
bool bDiffVersion;
|
||||
bool bIsDemo;
|
||||
str sServerName;
|
||||
str sPlayers;
|
||||
const char* pszGameVer;
|
||||
const char* pszGameVerNumber;
|
||||
|
||||
pszHostName = ServerGetStringValue(server, "hostname", "(NONE)");
|
||||
bDiffVersion = false;
|
||||
bIsDemo = false;
|
||||
pszGameVer = ServerGetStringValue(server, "gamever", "1.00");
|
||||
pszGameVerNumber = pszGameVer;
|
||||
|
||||
if (pszGameVerNumber[0] == 'd') {
|
||||
// demo server
|
||||
pszGameVerNumber++;
|
||||
bIsDemo = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// always show the version
|
||||
sServerName = va(" (%s) %s", pszGameVer, pszHostName);
|
||||
if (!bIsDemo) {
|
||||
sServerName = va(" (%s) %s", pszGameVerNumber, pszHostName);
|
||||
} else {
|
||||
sServerName = va(" (d%s) %s", pszGameVerNumber, pszHostName);
|
||||
}
|
||||
|
||||
iRealIP = inet_addr(ServerGetAddress(server));
|
||||
iPort = ServerGetIntValue(server, "hostport", PORT_SERVER);
|
||||
@@ -1056,7 +1100,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 +1198,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__ */
|
||||
+1250
-1158
File diff suppressed because it is too large.
Load diff
+73
-70
@@ -20,85 +20,88 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISTD_H__
|
||||
#define __CL_UISTD_H__
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
L_STATBAR_NONE,
|
||||
L_STATBAR_HORIZONTAL,
|
||||
L_STATBAR_VERTICAL,
|
||||
L_STATBAR_VERTICAL_REVERSE,
|
||||
L_STATBAR_VERTICAL_STAGGER_EVEN,
|
||||
L_STATBAR_VERTICAL_STAGGER_ODD,
|
||||
L_STATBAR_CIRCULAR,
|
||||
L_STATBAR_NEEDLE,
|
||||
L_STATBAR_ROTATOR,
|
||||
L_STATBAR_COMPASS,
|
||||
L_STATBAR_SPINNER,
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
L_STATBAR_NONE,
|
||||
L_STATBAR_HORIZONTAL,
|
||||
L_STATBAR_VERTICAL,
|
||||
L_STATBAR_VERTICAL_REVERSE,
|
||||
L_STATBAR_VERTICAL_STAGGER_EVEN,
|
||||
L_STATBAR_VERTICAL_STAGGER_ODD,
|
||||
L_STATBAR_CIRCULAR,
|
||||
L_STATBAR_NEEDLE,
|
||||
L_STATBAR_ROTATOR,
|
||||
L_STATBAR_COMPASS,
|
||||
L_STATBAR_SPINNER,
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
} statbar_orientation_t;
|
||||
|
||||
class UIFakkLabel : public UILabel {
|
||||
extern Event EV_ClearInvItemReference;
|
||||
|
||||
class UIFakkLabel : public UILabel
|
||||
{
|
||||
protected:
|
||||
SafePtr<inventory_item_t> m_lastitem;
|
||||
int m_lastitemindex;
|
||||
int m_stat;
|
||||
int m_stat_configstring;
|
||||
int m_maxstat;
|
||||
int m_itemindex;
|
||||
int m_inventoryrendermodelindex;
|
||||
str m_sDrawModelName;
|
||||
qboolean m_rendermodel;
|
||||
statbar_orientation_t m_statbar_or;
|
||||
float m_statbar_min;
|
||||
float m_statbar_max;
|
||||
float m_lastfrac;
|
||||
float m_flashtime;
|
||||
vec3_t m_offset;
|
||||
vec3_t m_rotateoffset;
|
||||
vec3_t m_angles;
|
||||
float m_scale;
|
||||
str m_anim;
|
||||
UIReggedMaterial *m_statbar_material;
|
||||
UIReggedMaterial *m_statbar_material_flash;
|
||||
SafePtr<inventory_item_t> m_lastitem;
|
||||
int m_lastitemindex;
|
||||
int m_stat;
|
||||
int m_stat_alpha;
|
||||
int m_stat_configstring;
|
||||
int m_maxstat;
|
||||
int m_itemindex;
|
||||
int m_inventoryrendermodelindex;
|
||||
str m_sDrawModelName;
|
||||
qboolean m_rendermodel;
|
||||
statbar_orientation_t m_statbar_or;
|
||||
float m_statbar_min;
|
||||
float m_statbar_max;
|
||||
float m_lastfrac;
|
||||
float m_flashtime;
|
||||
vec3_t m_offset;
|
||||
vec3_t m_rotateoffset;
|
||||
vec3_t m_angles;
|
||||
float m_scale;
|
||||
str m_anim;
|
||||
UIReggedMaterial *m_statbar_material;
|
||||
UIReggedMaterial *m_statbar_material_flash;
|
||||
UIReggedMaterial *m_statbar_material_marker;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFakkLabel );
|
||||
CLASS_PROTOTYPE(UIFakkLabel);
|
||||
|
||||
UIFakkLabel();
|
||||
UIFakkLabel();
|
||||
|
||||
void LayoutPlayerStat( Event *ev );
|
||||
void LayoutPlayerStatConfigstring( Event *ev );
|
||||
void LayoutMaxPlayerStat( Event *ev );
|
||||
void LayoutItemIndex( Event *ev );
|
||||
void InventoryRenderModelIndex( Event *ev );
|
||||
void LayoutModelName( Event *ev );
|
||||
void ClearInvItemReference( Event *ev );
|
||||
void LayoutStatbar( Event *ev );
|
||||
void LayoutStatbarShader( Event *ev );
|
||||
void LayoutStatbarTileShader( Event *ev );
|
||||
void LayoutStatbarShader_Flash( Event *ev );
|
||||
void LayoutStatbarEndAngles( Event *ev );
|
||||
void LayoutStatbarNeedleWidth( Event *ev );
|
||||
void LayoutStatbarRotatorSize( Event *ev );
|
||||
void LayoutStatbarTileShader_Flash( Event *ev );
|
||||
void LayoutRenderModel( Event *ev );
|
||||
void LayoutRenderModelOffset( Event *ev );
|
||||
void LayoutRenderModelRotateOffset( Event *ev );
|
||||
void LayoutRenderModelAngles( Event *ev );
|
||||
void LayoutRenderModelScale( Event *ev );
|
||||
void LayoutRenderModelAnim( Event *ev );
|
||||
void LayoutPlayerStat(Event *ev);
|
||||
void LayoutPlayerStatAlpha(Event *ev); // Added in 2.0
|
||||
void LayoutPlayerStatConfigstring(Event *ev);
|
||||
void LayoutMaxPlayerStat(Event *ev);
|
||||
void LayoutItemIndex(Event *ev);
|
||||
void InventoryRenderModelIndex(Event *ev);
|
||||
void LayoutModelName(Event *ev);
|
||||
void ClearInvItemReference(Event *ev);
|
||||
void LayoutStatbar(Event *ev);
|
||||
void LayoutStatbarShader(Event *ev);
|
||||
void LayoutStatbarTileShader(Event *ev);
|
||||
void LayoutStatbarShader_Flash(Event *ev);
|
||||
void LayoutStatbarShader_Marker(Event *ev); // Added in 2.0
|
||||
void LayoutStatbarEndAngles(Event *ev);
|
||||
void LayoutStatbarNeedleWidth(Event *ev);
|
||||
void LayoutStatbarRotatorSize(Event *ev);
|
||||
void LayoutStatbarTileShader_Flash(Event *ev);
|
||||
void LayoutRenderModel(Event *ev);
|
||||
void LayoutRenderModelOffset(Event *ev);
|
||||
void LayoutRenderModelRotateOffset(Event *ev);
|
||||
void LayoutRenderModelAngles(Event *ev);
|
||||
void LayoutRenderModelScale(Event *ev);
|
||||
void LayoutRenderModelAnim(Event *ev);
|
||||
|
||||
void DrawStatbar( float frac );
|
||||
void DrawStatCircle( float frac );
|
||||
void DrawStatNeedle( float frac );
|
||||
void DrawStatRotator( float frac );
|
||||
void DrawStatCompass( float frac );
|
||||
void DrawStatSpinner( float frac );
|
||||
void StatCircleTexCoord( float fAng, vec3_t vTexCoord );
|
||||
void DrawStatbar(float frac);
|
||||
void DrawStatCircle(float frac);
|
||||
void DrawStatNeedle(float frac);
|
||||
void DrawStatRotator(float frac);
|
||||
void DrawStatCompass(float frac);
|
||||
void DrawStatSpinner(float frac);
|
||||
void StatCircleTexCoord(float fAng, vec3_t vTexCoord);
|
||||
|
||||
void Draw( void ) override;
|
||||
void Draw(void) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+786
-355
File diff suppressed because it is too large.
Load diff
+40
-38
@@ -20,55 +20,57 @@ 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);
|
||||
|
||||
// Added in 2.0
|
||||
void DrawNetProfile(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__ */
|
||||
+76
-14
@@ -21,8 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// client.h -- primary header for client
|
||||
|
||||
#ifndef __CLIENT_H__
|
||||
#define __CLIENT_H__
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
@@ -37,6 +36,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cl_curl.h"
|
||||
#endif /* USE_CURL */
|
||||
|
||||
#ifdef USE_VOIP
|
||||
#include <opus.h>
|
||||
#endif
|
||||
|
||||
// file full of random crap that gets used to create cl_guid
|
||||
#define QKEY_FILE "qkey"
|
||||
#define QKEY_SIZE 2048
|
||||
@@ -175,6 +178,7 @@ typedef struct {
|
||||
int lastPacketSentTime; // for retransmits during connection
|
||||
int lastPacketTime; // for timeouts
|
||||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
|
||||
netadr_t serverAddress;
|
||||
int connectTime; // for connection retransmits
|
||||
int connectStartTime;
|
||||
@@ -240,15 +244,42 @@ typedef struct {
|
||||
int timeDemoMaxDuration; // maximum frame duration
|
||||
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
|
||||
|
||||
float aviVideoFrameRemainder;
|
||||
float aviSoundFrameRemainder;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
qboolean voipEnabled;
|
||||
qboolean voipCodecInitialized;
|
||||
|
||||
// incoming data...
|
||||
// !!! FIXME: convert from parallel arrays to array of a struct.
|
||||
OpusDecoder *opusDecoder[MAX_CLIENTS];
|
||||
byte voipIncomingGeneration[MAX_CLIENTS];
|
||||
int voipIncomingSequence[MAX_CLIENTS];
|
||||
float voipGain[MAX_CLIENTS];
|
||||
qboolean voipIgnore[MAX_CLIENTS];
|
||||
qboolean voipMuteAll;
|
||||
|
||||
// outgoing data...
|
||||
// if voipTargets[i / 8] & (1 << (i % 8)),
|
||||
// then we are sending to clientnum i.
|
||||
uint8_t voipTargets[(MAX_CLIENTS + 7) / 8];
|
||||
uint8_t voipFlags;
|
||||
OpusEncoder *opusEncoder;
|
||||
int voipOutgoingDataSize;
|
||||
int voipOutgoingDataFrames;
|
||||
int voipOutgoingSequence;
|
||||
byte voipOutgoingGeneration;
|
||||
byte voipOutgoingData[1024];
|
||||
float voipPower;
|
||||
#endif
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
#endif
|
||||
|
||||
// big stuff at end of structure so most offsets are 15 bits or less
|
||||
netchan_t netchan;
|
||||
|
||||
float aviVideoFrameRemainder;
|
||||
float aviSoundFrameRemainder;
|
||||
} clientConnection_t;
|
||||
|
||||
extern clientConnection_t clc;
|
||||
@@ -298,8 +329,6 @@ typedef struct {
|
||||
qboolean cddialog; // bring up the cd needed dialog next frame
|
||||
qboolean no_menus;
|
||||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
|
||||
|
||||
// when the server clears the hunk, all of these must be restarted
|
||||
qboolean rendererRegistered;
|
||||
qboolean cgameStarted;
|
||||
@@ -321,7 +350,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];
|
||||
@@ -352,10 +381,10 @@ typedef struct {
|
||||
clientAnim_t anim;
|
||||
stopWatch_t stopwatch;
|
||||
void* savedCgameState;
|
||||
int savedCgameStateSize;
|
||||
size_t savedCgameStateSize;
|
||||
char gcdResponse[73];
|
||||
int unknown3_0;
|
||||
int currentRate;
|
||||
// Added in 2.0
|
||||
netprofclient_t netprofile;
|
||||
qhandle_t charSetShader;
|
||||
qhandle_t whiteShader;
|
||||
qhandle_t consoleShader;
|
||||
@@ -386,6 +415,8 @@ extern cvar_t *cl_connect_timeout;
|
||||
extern cvar_t *cl_maxpackets;
|
||||
extern cvar_t *cl_packetdup;
|
||||
extern cvar_t *cl_shownet;
|
||||
extern cvar_t *cl_netprofile;
|
||||
extern cvar_t *cl_netprofileoverlay;
|
||||
extern cvar_t *cl_showSend;
|
||||
extern cvar_t *cl_timeNudge;
|
||||
extern cvar_t *cl_showTimeDelta;
|
||||
@@ -446,6 +477,32 @@ extern cvar_t *cl_r_fullscreen;
|
||||
|
||||
extern cvar_t *cl_consoleKeys;
|
||||
|
||||
#ifdef USE_MUMBLE
|
||||
extern cvar_t *cl_useMumble;
|
||||
extern cvar_t *cl_mumbleScale;
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOIP
|
||||
// cl_voipSendTarget is a string: "all" to broadcast to everyone, "none" to
|
||||
// send to no one, or a comma-separated list of client numbers:
|
||||
// "0,7,2,23" ... an empty string is treated like "all".
|
||||
extern cvar_t *cl_voipUseVAD;
|
||||
extern cvar_t *cl_voipVADThreshold;
|
||||
extern cvar_t *cl_voipSend;
|
||||
extern cvar_t *cl_voipSendTarget;
|
||||
extern cvar_t *cl_voipGainDuringCapture;
|
||||
extern cvar_t *cl_voipCaptureMult;
|
||||
extern cvar_t *cl_voipShowMeter;
|
||||
extern cvar_t *cl_voip;
|
||||
|
||||
// 20ms at 48k
|
||||
#define VOIP_MAX_FRAME_SAMPLES ( 20 * 48 )
|
||||
|
||||
// 3 frame is 60ms of audio, the max opus will encode at once
|
||||
#define VOIP_MAX_PACKET_FRAMES 3
|
||||
#define VOIP_MAX_PACKET_SAMPLES ( VOIP_MAX_FRAME_SAMPLES * VOIP_MAX_PACKET_FRAMES )
|
||||
#endif
|
||||
|
||||
extern cvar_t *cg_gametype;
|
||||
|
||||
extern cvar_t* j_pitch;
|
||||
@@ -471,7 +528,7 @@ void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd);
|
||||
|
||||
void CL_StartHunkUsers( qboolean rendererOnly );
|
||||
|
||||
void CL_Connect( const char *server );
|
||||
void CL_Connect( const char *server, netadrtype_t family );
|
||||
|
||||
void CL_Disconnect_f (void);
|
||||
void CL_GetChallengePacket (void);
|
||||
@@ -521,6 +578,7 @@ void IN_MouseOn( void );
|
||||
void IN_MouseOff( void );
|
||||
|
||||
void CL_InitInput (void);
|
||||
void CL_ShutdownInput(void);
|
||||
void CL_SendCmd (void);
|
||||
void CL_ClearState (void);
|
||||
void CL_ReadPackets (void);
|
||||
@@ -546,6 +604,10 @@ extern int cl_connectedToPureServer;
|
||||
extern int cl_connectedToCheatServer;
|
||||
extern msg_t *cl_currentMSG;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
void CL_Voip_f( void );
|
||||
#endif
|
||||
|
||||
void CL_SystemInfoChanged( void );
|
||||
void CL_ParseServerMessage( msg_t *msg );
|
||||
|
||||
@@ -584,6 +646,7 @@ void Con_DrawCharacter (int cx, int line, int num);
|
||||
|
||||
void Con_CheckResize (void);
|
||||
void Con_Init (void);
|
||||
void Con_Shutdown (void);
|
||||
void Con_Clear_f (void);
|
||||
void Con_ToggleConsole_f (void);
|
||||
void Con_DrawNotify (void);
|
||||
@@ -671,6 +734,7 @@ void LAN_SaveServersToCache( void );
|
||||
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg); //int length, const byte *data );
|
||||
void CL_Netchan_TransmitNextFragment( netchan_t *chan );
|
||||
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg );
|
||||
void CL_NET_OutOfBandPrint( netadr_t adr, const char* format, ... );
|
||||
|
||||
//
|
||||
// cl_avi.c
|
||||
@@ -690,5 +754,3 @@ void CL_InitConsoleCommands( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __CLIENT_H__
|
||||
@@ -58,6 +58,10 @@ 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);
|
||||
}
|
||||
|
||||
@@ -55,7 +79,7 @@ void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t s
|
||||
S_StopAllSounds
|
||||
=================
|
||||
*/
|
||||
void S_StopAllSounds(qboolean stop_music)
|
||||
void S_StopAllSounds2(qboolean stop_music)
|
||||
{
|
||||
// Call the original function
|
||||
S_StopAllSounds();
|
||||
@@ -83,12 +107,29 @@ void S_Respatialize(int entityNum, const vec3_t origin,
|
||||
{
|
||||
S_Respatialize(entityNum, origin, axis, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSoundChannel
|
||||
=================
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
{
|
||||
sfxHandle_t h;
|
||||
|
||||
h = S_RegisterSound(sound_name, qfalse);
|
||||
|
||||
if (h) {
|
||||
S_StartLocalSound(h, CHAN_LOCAL_SOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSound
|
||||
=================
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, int channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -340,6 +381,16 @@ void MUSIC_CheckForStoppedSongs(void)
|
||||
STUB();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_CurrentSoundtrack
|
||||
==============
|
||||
*/
|
||||
const char* S_CurrentSoundtrack()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_IsSoundRegistered
|
||||
@@ -404,22 +455,166 @@ 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
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StopMovieAudio
|
||||
==============
|
||||
*/
|
||||
void S_StopMovieAudio() {
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_CurrentMoviePosition
|
||||
==============
|
||||
*/
|
||||
int S_CurrentMoviePosition() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SetupMovieAudio
|
||||
==============
|
||||
*/
|
||||
void S_SetupMovieAudio(const char* pszMovieName) {
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -30,8 +30,8 @@ void S_Respatialize(int entityNum, const vec3_t origin, vec3_t axis[3]);
|
||||
sfxHandle_t S_RegisterSound(const char* sample, qboolean compressed, qboolean streamed);
|
||||
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags);
|
||||
void S_StartLocalSound(const char* name, qboolean force_load);
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, int channel);
|
||||
void S_StartSound(const vec3_t origin, int entNum, int entChannel, sfxHandle_t sfxHandle, float volume, float minDist, float pitch, float maxDist, qboolean streamed);
|
||||
void S_StopAllSounds(qboolean stop_music);
|
||||
void S_ClearLoopingSounds(void);
|
||||
qboolean S_IsSoundRegistered(const char* name);
|
||||
void S_Init2();
|
||||
@@ -64,7 +64,14 @@ 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);
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume);
|
||||
void S_SetReverb(int reverb_type, float reverb_level);
|
||||
@@ -73,6 +80,15 @@ 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();
|
||||
|
||||
void S_StopMovieAudio();
|
||||
int S_CurrentMoviePosition();
|
||||
void S_SetupMovieAudio(const char* pszMovieName);
|
||||
|
||||
#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
|
||||
|
||||
Loaded 100 of 798 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user