Compare commits
759
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ac0f2bae2 | ||
|
|
cee28c6166 | ||
|
|
a6be267325 | ||
|
|
426740e0ac | ||
|
|
78c0f64135 | ||
|
|
b6e766ee44 | ||
|
|
5437040b78 | ||
|
|
c786569981 | ||
|
|
7064b14539 | ||
|
|
f275ae98f5 | ||
|
|
ef07d89e29 | ||
|
|
b9bbd45e15 | ||
|
|
2bda27b80d | ||
|
|
6ebf90cc50 | ||
|
|
ea00bebb04 | ||
|
|
b862d835a5 | ||
|
|
d6602747ae | ||
|
|
9f79429d03 | ||
|
|
5ff0c09868 | ||
|
|
ad1c3e63a4 | ||
|
|
24dd6ba675 | ||
|
|
85f036a45b | ||
|
|
6f8342b9a8 | ||
|
|
c5c6f6b820 | ||
|
|
3d472c34a1 | ||
|
|
63ca366bd8 | ||
|
|
e9e888ab7f | ||
|
|
5ea55b3e3a | ||
|
|
8b1797927a | ||
|
|
05a98964fb | ||
|
|
8cbf798de8 | ||
|
|
9314a24cb2 | ||
|
|
19b1683e61 | ||
|
|
d029107e75 | ||
|
|
bc97e0b703 | ||
|
|
f47c663f79 | ||
|
|
6f9d41eadb | ||
|
|
1b512edc56 | ||
|
|
884a6da2bd | ||
|
|
7a3d958fc1 | ||
|
|
7223581539 | ||
|
|
664bd2de3f | ||
|
|
63568e3861 | ||
|
|
f149d058a1 | ||
|
|
970251ced3 | ||
|
|
dba7a7dc3c | ||
|
|
393c0be407 | ||
|
|
5e9ea2429b | ||
|
|
81a14995da | ||
|
|
4267ac9a8d | ||
|
|
bcf72cc0e8 | ||
|
|
54d9a98090 | ||
|
|
81d415c5ba | ||
|
|
de1b801bda | ||
|
|
2c665fef6f | ||
|
|
c6fbf405bf | ||
|
|
7076c35521 | ||
|
|
86ed1b709e | ||
|
|
d30c96e8cb | ||
|
|
0af52ba3ae | ||
|
|
fbe97556de | ||
|
|
7a6f43bece | ||
|
|
afca521fe5 | ||
|
|
d3e2875c94 | ||
|
|
1daac9a124 | ||
|
|
38f3e48aed | ||
|
|
4cf4d49f48 | ||
|
|
a19c4dc5e5 | ||
|
|
d37505ff06 | ||
|
|
7f6ce1f299 | ||
|
|
262a84aac6 | ||
|
|
3f12ebb2bd | ||
|
|
b58fcf331c | ||
|
|
fe51278295 | ||
|
|
c3fb84981e | ||
|
|
919aad4f30 | ||
|
|
818e6046b7 | ||
|
|
f01d2a0ba6 | ||
|
|
8df0a2d059 | ||
|
|
d7ed91af1d | ||
|
|
081dcc021b | ||
|
|
70ebd0d475 | ||
|
|
02bbb38606 | ||
|
|
d00014ea59 | ||
|
|
210d6ac8ac | ||
|
|
55248e7fcf | ||
|
|
23b36b5074 | ||
|
|
2e7f0721b9 | ||
|
|
4927e55c7e | ||
|
|
c51d33fa6e | ||
|
|
8630d8cd47 | ||
|
|
659243baa1 | ||
|
|
b6a84c1646 | ||
|
|
c33afa4a3b | ||
|
|
1428c3c2bf | ||
|
|
aa0cbfda74 | ||
|
|
9d13ff3c9f | ||
|
|
e47c13b7ac | ||
|
|
3f5b96bd45 | ||
|
|
63c1372c34 | ||
|
|
8b915f9ac1 | ||
|
|
f3a18a0655 | ||
|
|
e8351d44b6 | ||
|
|
297af069cb | ||
|
|
baa5d6630d | ||
|
|
0c30730ef6 | ||
|
|
c82148fafc | ||
|
|
d1346dee53 | ||
|
|
6722b43244 | ||
|
|
cfdbf1f4ad | ||
|
|
48a00ba911 | ||
|
|
4b1102357a | ||
|
|
e3b0204b2c | ||
|
|
a2799ddcca | ||
|
|
76198f61de | ||
|
|
ff2006ad74 | ||
|
|
55c9c7297f | ||
|
|
4b083ee72e | ||
|
|
6574ec2fb9 | ||
|
|
f54bb349b5 | ||
|
|
6f1252e27d | ||
|
|
7d65b5369f | ||
|
|
4877c81728 | ||
|
|
5cb207edfa | ||
|
|
fc39a0dedf | ||
|
|
0b3e7240a8 | ||
|
|
f32c346534 | ||
|
|
3165004d0e | ||
|
|
ec3b1cf130 | ||
|
|
a0437713bf | ||
|
|
96f7ff550c | ||
|
|
837216d78e | ||
|
|
dfb6006f9c | ||
|
|
fb0765a5f3 | ||
|
|
2e8769496f | ||
|
|
bdb39fcd8d | ||
|
|
31516c7987 | ||
|
|
b985ce06a2 | ||
|
|
12d6546062 | ||
|
|
fb71da3627 | ||
|
|
a90ffff320 | ||
|
|
9abf2bca75 | ||
|
|
3db6770dfd | ||
|
|
3a951576ee | ||
|
|
6b0d67ac36 | ||
|
|
d06b8ac398 | ||
|
|
67435ebf9e | ||
|
|
2ee29630fb | ||
|
|
7fa21e9aea | ||
|
|
b4b206f575 | ||
|
|
f363663b3e | ||
|
|
42d957e21b | ||
|
|
07f9756bc8 | ||
|
|
e958e43b49 | ||
|
|
0d150e4b08 | ||
|
|
0deff73a46 | ||
|
|
b24caf397a | ||
|
|
f051e33a0c | ||
|
|
ff2b28ac73 | ||
|
|
e2367d26d1 | ||
|
|
e1a65add5d | ||
|
|
913426bfdb | ||
|
|
d7b0726e42 | ||
|
|
cadb67e6c9 | ||
|
|
564838a439 | ||
|
|
4554bcc565 | ||
|
|
fd48335688 | ||
|
|
222f56d1b2 | ||
|
|
b71870f57b | ||
|
|
01c9632025 | ||
|
|
1533e13d68 | ||
|
|
89965ad718 | ||
|
|
eb74f3525a | ||
|
|
536f88dee0 | ||
|
|
2622ba286e | ||
|
|
a1d490cb49 | ||
|
|
b357c09171 | ||
|
|
48e71afec1 | ||
|
|
1c6fce9339 | ||
|
|
96551d3b75 | ||
|
|
7a832df4d3 | ||
|
|
c3b6121968 | ||
|
|
b3b2b65c5f | ||
|
|
7a3ccec38d | ||
|
|
d8da0a11a2 | ||
|
|
d5c3332635 | ||
|
|
0137f2254d | ||
|
|
da769ce524 | ||
|
|
2e99636bb0 | ||
|
|
ff7f68f5b4 | ||
|
|
14eec0c902 | ||
|
|
b064c534d8 | ||
|
|
e7c0f322ee | ||
|
|
725754c427 | ||
|
|
9a6c0a0280 | ||
|
|
26d8c05ce7 | ||
|
|
91a9f20af7 | ||
|
|
90745d91aa | ||
|
|
0dbae34998 | ||
|
|
eec93b8013 | ||
|
|
cfe3f01b32 | ||
|
|
43452e1af4 | ||
|
|
a4706e0785 | ||
|
|
c921ab463c | ||
|
|
892816dadf | ||
|
|
e7e1fd711e | ||
|
|
ba5459eeb6 | ||
|
|
0bd9c696df | ||
|
|
c14af4a136 | ||
|
|
8dfa841a7b | ||
|
|
a6de843c75 | ||
|
|
0bb1efcd50 | ||
|
|
26e8c2ca2b | ||
|
|
12ffca7374 | ||
|
|
6ecf65d83a | ||
|
|
231c173545 | ||
|
|
f12b7fd772 | ||
|
|
14ea041c72 | ||
|
|
6fb804292c | ||
|
|
f77f7361a9 | ||
|
|
d6d19d5dab | ||
|
|
8074bfacb6 | ||
|
|
f5f7b99479 | ||
|
|
f0a8c27829 | ||
|
|
30024f2341 | ||
|
|
ff0dcafeea | ||
|
|
8580451bce | ||
|
|
d867868854 | ||
|
|
b1644d4817 | ||
|
|
a9a3a04379 | ||
|
|
7ac9f0cbef | ||
|
|
5f7bf4164d | ||
|
|
43690c9b2c | ||
|
|
02c14bfa5c | ||
|
|
0544811c7d | ||
|
|
e079bac283 | ||
|
|
862f1fce2c | ||
|
|
5aeb78f2a5 | ||
|
|
cb42bc581b | ||
|
|
5fc9410b59 | ||
|
|
84d3ee7170 | ||
|
|
accef8f1e1 | ||
|
|
4a8edff694 | ||
|
|
aac3b8d025 | ||
|
|
4034658e44 | ||
|
|
7d4898dd8b | ||
|
|
71fe6ec9da | ||
|
|
075097c219 | ||
|
|
f70ec60ae4 | ||
|
|
aeafd46f24 | ||
|
|
5f57044118 | ||
|
|
65006c11d3 | ||
|
|
76bc184f6c | ||
|
|
dd39a444f2 | ||
|
|
1a16012a5c | ||
|
|
c49aae8d49 | ||
|
|
d5dc52d3d3 | ||
|
|
4f1f1ede97 | ||
|
|
c98b896fc8 | ||
|
|
3714735c2a | ||
|
|
025cc093db | ||
|
|
924d79c20d | ||
|
|
0926f68776 | ||
|
|
26f3806b3c | ||
|
|
d628320c8d | ||
|
|
41fc4c7cfd | ||
|
|
1c8ca2b110 | ||
|
|
241d107485 | ||
|
|
8d0601c2ad | ||
|
|
31118254a0 | ||
|
|
85a1636776 | ||
|
|
3b227932e9 | ||
|
|
ff591bce04 | ||
|
|
c3a03d89c4 | ||
|
|
dd405532af | ||
|
|
677cdc77e4 | ||
|
|
f9463d8efa | ||
|
|
77c9badeca | ||
|
|
926287eb97 | ||
|
|
7a91b19962 | ||
|
|
c148ff5a05 | ||
|
|
ef7e658f9d | ||
|
|
0e9b9d15ea | ||
|
|
dd2d437a21 | ||
|
|
b9779d4dba | ||
|
|
1d40d8c4ef | ||
|
|
847b1f5cb7 | ||
|
|
9448a98573 | ||
|
|
14bce36b95 | ||
|
|
ba4c54004a | ||
|
|
9fdfc09229 | ||
|
|
b19bc7d77e | ||
|
|
58815ae9c4 | ||
|
|
0b12c9b5a8 | ||
|
|
863abe86ca | ||
|
|
f54d2fb0fe | ||
|
|
8824ba3824 | ||
|
|
8a8db796be | ||
|
|
4f532b766f | ||
|
|
e175a4e00b | ||
|
|
473e843142 | ||
|
|
ef8e71cb11 | ||
|
|
ea985151dd | ||
|
|
62fae0ad8b | ||
|
|
f9210ee3bc | ||
|
|
d5101dd0b2 | ||
|
|
2a7940bfd1 | ||
|
|
047d38daab | ||
|
|
2d61f5c861 | ||
|
|
750f305c46 | ||
|
|
51b79e58d3 | ||
|
|
915b4e9d15 | ||
|
|
c9c0c06763 | ||
|
|
406037dabe | ||
|
|
d9affe2331 | ||
|
|
6df675523f | ||
|
|
65e66e8ace | ||
|
|
5efb0c7136 | ||
|
|
1793340474 | ||
|
|
d10db6d1d2 | ||
|
|
9eefbcea72 | ||
|
|
d56b70a8e7 | ||
|
|
54ebb9dfec | ||
|
|
43b6597ec0 | ||
|
|
b7d887d610 | ||
|
|
ff9b35ab45 | ||
|
|
20b5175180 | ||
|
|
596c8e2ecc | ||
|
|
94218a6549 | ||
|
|
2d36f798e7 | ||
|
|
853004dad9 | ||
|
|
0cc86430ca | ||
|
|
8760886f57 | ||
|
|
821669d03d | ||
|
|
17f8996afc | ||
|
|
7ef4eedd06 | ||
|
|
df6a31767e | ||
|
|
882a3b7824 | ||
|
|
94ddd01427 | ||
|
|
e614decae0 | ||
|
|
e0f46ea80d | ||
|
|
3391018606 | ||
|
|
61fd11f7cd | ||
|
|
4a469aebdc | ||
|
|
341815c0ed | ||
|
|
5830270bda | ||
|
|
8a1ff58dff | ||
|
|
0523d98a1c | ||
|
|
983af4e7a1 | ||
|
|
f8bec7296c | ||
|
|
2be4bd3d6a | ||
|
|
7d74296604 | ||
|
|
0504a355d2 | ||
|
|
036df817f1 | ||
|
|
ba331caff6 | ||
|
|
e2ac9708cb | ||
|
|
783ce7bada | ||
|
|
594931e07e | ||
|
|
3e245d49d8 | ||
|
|
76ed4aae12 | ||
|
|
565f36d4b7 | ||
|
|
75a94b050d | ||
|
|
91fac0880d | ||
|
|
42fa29f78b | ||
|
|
28d8e84d6b | ||
|
|
c11d925580 | ||
|
|
d7c1b12dbd | ||
|
|
e2c3d5b20d | ||
|
|
8581d87e41 | ||
|
|
fe853d4bee | ||
|
|
b8038130b8 | ||
|
|
31c5d8d67c | ||
|
|
a2f4430378 | ||
|
|
a8e4f6e2ea | ||
|
|
aac89f270b | ||
|
|
9022e02ccd | ||
|
|
5ddd2e4fbc | ||
|
|
3b500add73 | ||
|
|
4a6635f8a8 | ||
|
|
af6393af50 | ||
|
|
6a14543e9e | ||
|
|
3d827570e6 | ||
|
|
9f8eb07442 | ||
|
|
31c64b63de | ||
|
|
cf5c0ca5f7 | ||
|
|
f0d91a9708 | ||
|
|
0f94a26dc6 | ||
|
|
cded0af061 | ||
|
|
fffa7e44c5 | ||
|
|
a38aee7fe3 | ||
|
|
4d03fa06e1 | ||
|
|
dcd470b2e1 | ||
|
|
2259ef3f71 | ||
|
|
af18e2b7d1 | ||
|
|
9e8d79f246 | ||
|
|
5b480be6dc | ||
|
|
54d897fc33 | ||
|
|
cfebe422d3 | ||
|
|
fcc5c13274 | ||
|
|
707448193b | ||
|
|
84a1f86037 | ||
|
|
b2129011c2 | ||
|
|
9d359ef8c5 | ||
|
|
87a2b74a88 | ||
|
|
d5388e8dad | ||
|
|
fe7677c5c8 | ||
|
|
f36ac0bb4b | ||
|
|
d24bcc9fd7 | ||
|
|
daf8151a32 | ||
|
|
b432491d34 | ||
|
|
1313b4c112 | ||
|
|
164d7399d2 | ||
|
|
87176cfd0b | ||
|
|
bab96b73e0 | ||
|
|
f10db3900a | ||
|
|
7d4b1d0852 | ||
|
|
6ab99218f2 | ||
|
|
1959edf357 | ||
|
|
6fc2681b34 | ||
|
|
02dcf85c46 | ||
|
|
89f0521cce | ||
|
|
35029e826f | ||
|
|
f6c170b53c | ||
|
|
7991a5ce5e | ||
|
|
3973851dd2 | ||
|
|
f6361e29bd | ||
|
|
9f8db631f0 | ||
|
|
ada1de7ad6 | ||
|
|
ac55d473e7 | ||
|
|
2100f11af7 | ||
|
|
ea1b5cd1a9 | ||
|
|
e100fff230 | ||
|
|
5393ac526a | ||
|
|
808f7baf53 | ||
|
|
35f54822be | ||
|
|
94714fe571 | ||
|
|
5bdf8698bd | ||
|
|
2398e60e89 | ||
|
|
b4e563bfd6 | ||
|
|
a56ce09923 | ||
|
|
68c7a6bd93 | ||
|
|
b4612d6bd4 | ||
|
|
c2cfc96d87 | ||
|
|
8db99291ac | ||
|
|
c9aa764444 | ||
|
|
ee4869993d | ||
|
|
0758cf39c2 | ||
|
|
bb0c777cac | ||
|
|
0bd2c49dae | ||
|
|
d25c6fa0b2 | ||
|
|
8f2d36aab0 | ||
|
|
6c764a8487 | ||
|
|
dd6056a07a | ||
|
|
a83d364ba7 | ||
|
|
9c4b2b0abf | ||
|
|
4235801ae4 | ||
|
|
6791f2e883 | ||
|
|
caeec35c66 | ||
|
|
7b95df150a | ||
|
|
852651cefe | ||
|
|
22b9915ad7 | ||
|
|
0f994a0676 | ||
|
|
5d68fd690b | ||
|
|
c55bc6db4d | ||
|
|
a77d8b4762 | ||
|
|
23596d2516 | ||
|
|
352b958da1 | ||
|
|
e9f2ef1422 | ||
|
|
7baa711744 | ||
|
|
65e274a65f | ||
|
|
a874691bce | ||
|
|
d60d101e75 | ||
|
|
8d9a648dce | ||
|
|
2332cc76ee | ||
|
|
5c3a2bf5be | ||
|
|
5e2b50c49e | ||
|
|
3a56bf2bb5 | ||
|
|
3f4afb604a | ||
|
|
77a2976d05 | ||
|
|
0eda508cf6 | ||
|
|
4301e0f750 | ||
|
|
c5eb81c26a | ||
|
|
47d3cf3e62 | ||
|
|
41dc34efe8 | ||
|
|
4acbca4c8f | ||
|
|
11329d5794 | ||
|
|
b0880607d4 | ||
|
|
2afa18bbdd | ||
|
|
acad230daa | ||
|
|
49fcf3e486 | ||
|
|
acb0144742 | ||
|
|
6efc8fdad3 | ||
|
|
c75e6ba63c | ||
|
|
7bd1808c88 | ||
|
|
fe8e00895a | ||
|
|
9dc5e3d338 | ||
|
|
694c1ad808 | ||
|
|
754b028623 | ||
|
|
4423fb300f | ||
|
|
5c7d9327e3 | ||
|
|
cd72bce3cb | ||
|
|
64ef0465d5 | ||
|
|
fe6ad4f762 | ||
|
|
4b69b39d39 | ||
|
|
a6fc237c88 | ||
|
|
2448a0b735 | ||
|
|
685220140a | ||
|
|
99779629d0 | ||
|
|
9fceabed8f | ||
|
|
e11363db3a | ||
|
|
023cade51d | ||
|
|
d675b98330 | ||
|
|
b3f16e935d | ||
|
|
5b9e179017 | ||
|
|
6f53263107 | ||
|
|
fd797436fa | ||
|
|
96ee117657 | ||
|
|
8b60fb6b6c | ||
|
|
67542d3cf1 | ||
|
|
41e97ffa79 | ||
|
|
ffcff99a79 | ||
|
|
48bcaacada | ||
|
|
01b060b0fe | ||
|
|
51ce092a6a | ||
|
|
d09e02721b | ||
|
|
88b81aa28b | ||
|
|
84c4f4f428 | ||
|
|
ab5bc92a95 | ||
|
|
b44dd3edf0 | ||
|
|
80498a78ea | ||
|
|
40663eb2b5 | ||
|
|
dca2827154 | ||
|
|
eec069b4e8 | ||
|
|
26eedc3341 | ||
|
|
b19cefee3c | ||
|
|
fb54b969d1 | ||
|
|
034724b03e | ||
|
|
b80762eaf5 | ||
|
|
d5258786e5 | ||
|
|
9bfe2d3138 | ||
|
|
ae3b3f750d | ||
|
|
f83090e299 | ||
|
|
3e4f497cbc | ||
|
|
ce2398fdb7 | ||
|
|
f545cce6fe | ||
|
|
f614725fcb | ||
|
|
59e4f9ce4a | ||
|
|
dff6b15263 | ||
|
|
977ee8ccfc | ||
|
|
161815e6fb | ||
|
|
8dda864909 | ||
|
|
f6f9542d6e | ||
|
|
6655c0d881 | ||
|
|
98c8176d59 | ||
|
|
2e7f64458d | ||
|
|
d6a9cdc452 | ||
|
|
17dbe77cd3 | ||
|
|
4b71d9a48d | ||
|
|
1f41cb9a3f | ||
|
|
c6351c6c53 | ||
|
|
283218f2d6 | ||
|
|
4de22e9d66 | ||
|
|
b4a737d910 | ||
|
|
0f2c17324a | ||
|
|
6a1b10eaf9 | ||
|
|
824211c2f6 | ||
|
|
02d115f119 | ||
|
|
b44617413b | ||
|
|
c447f25e0a | ||
|
|
34ce92d9fa | ||
|
|
7ad5dc61ac | ||
|
|
7072332ab7 | ||
|
|
60e933eb00 | ||
|
|
43e3d07acb | ||
|
|
228252ee6f | ||
|
|
56a919eb60 | ||
|
|
bfcb906b12 | ||
|
|
b94776063f | ||
|
|
3f412373bc | ||
|
|
e7d1858052 | ||
|
|
bd106308fc | ||
|
|
6ec96b37bd | ||
|
|
3653786e14 | ||
|
|
5824d9e803 | ||
|
|
3ad3cdfa38 | ||
|
|
efcd1df365 | ||
|
|
aef62c45de | ||
|
|
94bd1cb37b | ||
|
|
f7bf3fe510 | ||
|
|
a771ebf0e8 | ||
|
|
6b4d02ae99 | ||
|
|
3e6cab1ec9 | ||
|
|
147c59c26b | ||
|
|
db6f76d12d | ||
|
|
86950c26d0 | ||
|
|
e1d4f10223 | ||
|
|
01c1ae42a1 | ||
|
|
550871f576 | ||
|
|
56fcca1f6b | ||
|
|
930bde785c | ||
|
|
13aadc41ff | ||
|
|
ea4998f666 | ||
|
|
6f0e92e0d1 | ||
|
|
a4085cb155 | ||
|
|
b7e77e10b6 | ||
|
|
8f195530b5 | ||
|
|
048ccf52b0 | ||
|
|
df9ad5a31f | ||
|
|
0b3284e23c | ||
|
|
36d598440a | ||
|
|
9cc42e6430 | ||
|
|
3f5c19bffd | ||
|
|
800dbf5e78 | ||
|
|
2b5db9ff3f | ||
|
|
b07c8848ca | ||
|
|
9bff8dd91f | ||
|
|
19eee66c39 | ||
|
|
fbf7be8808 | ||
|
|
fcda4c1188 | ||
|
|
deae234afa | ||
|
|
82e33fd4e4 | ||
|
|
15914c2f25 | ||
|
|
da64d3ccbf | ||
|
|
79a5d174a5 | ||
|
|
295d9768ce | ||
|
|
9490b1235d | ||
|
|
55eb984ccd | ||
|
|
4b1a82e14e | ||
|
|
3c224923e9 | ||
|
|
2c4f5a68b9 | ||
|
|
d324c917ad | ||
|
|
bd8ff77fe0 | ||
|
|
35d40e1d37 | ||
|
|
e9e281fd2a | ||
|
|
2437c5a19a | ||
|
|
b9b4de929d | ||
|
|
28fc55b653 | ||
|
|
8f4df0ceca | ||
|
|
ecde8a5e8b | ||
|
|
715b106c9e | ||
|
|
2114afa536 | ||
|
|
c78816a8d1 | ||
|
|
28516c4833 | ||
|
|
837ed3535d | ||
|
|
bcb332e88f | ||
|
|
f4be7a8034 | ||
|
|
e69413f1e8 | ||
|
|
ee6dcfc678 | ||
|
|
d4370a1811 | ||
|
|
babf4ca06a | ||
|
|
ccf0905469 | ||
|
|
970130e02b | ||
|
|
6088fa5134 | ||
|
|
33bc484d69 | ||
|
|
6bf113d0ff | ||
|
|
630d910a9e | ||
|
|
3c70963f56 | ||
|
|
4c4f6f6d80 | ||
|
|
f949fa54af | ||
|
|
17a5c6ed06 | ||
|
|
e6359663b1 | ||
|
|
405cef6a01 | ||
|
|
d4886f8923 | ||
|
|
c5ec61baa5 | ||
|
|
7a9ffa7ee8 | ||
|
|
5ff665a073 | ||
|
|
3d4e078a90 | ||
|
|
8ef613ef9b | ||
|
|
988a672dea | ||
|
|
cca9c51315 | ||
|
|
18aa3689d9 | ||
|
|
59ab6572b1 | ||
|
|
b6cf933159 | ||
|
|
48f36ca8f3 | ||
|
|
fea89de037 | ||
|
|
e2f1dd1ce8 | ||
|
|
48ac3353cb | ||
|
|
63015c3a93 | ||
|
|
c7bd402e54 | ||
|
|
0c6f9b6cc1 | ||
|
|
b5d7b84c1e | ||
|
|
cbbde8dea5 | ||
|
|
58dd0b7591 | ||
|
|
d9f2535402 | ||
|
|
66eb201466 | ||
|
|
edbf20d975 | ||
|
|
711d7dcfcc | ||
|
|
219979e20b | ||
|
|
27917a0e85 | ||
|
|
4b4b2d5cbc | ||
|
|
8d968d7f89 | ||
|
|
9090a5cd73 | ||
|
|
59a50994b8 | ||
|
|
ac99a6ac3c | ||
|
|
fa2257ad3b | ||
|
|
66ce0871bc | ||
|
|
c59564723c | ||
|
|
606717d253 | ||
|
|
f73e84e0ad | ||
|
|
fc01453544 | ||
|
|
d37a1c799f | ||
|
|
3456ef96a7 | ||
|
|
40143375fc | ||
|
|
7f34a1d83e | ||
|
|
2316c117b1 | ||
|
|
31b7482c3a | ||
|
|
0974625769 | ||
|
|
266f5149b5 | ||
|
|
008a9b9b3f | ||
|
|
ec2fd5b38f | ||
|
|
d449a1b714 | ||
|
|
0bd5ca5e3f | ||
|
|
06248e5388 | ||
|
|
9c5a0ed7ee | ||
|
|
b199354167 | ||
|
|
74ce725e3d | ||
|
|
3d5e033158 | ||
|
|
ca58c1dee2 | ||
|
|
d51a69b052 | ||
|
|
1a96d96837 | ||
|
|
2e7cd51ff8 | ||
|
|
112716dae5 | ||
|
|
c13e780f29 | ||
|
|
c35887f5ee | ||
|
|
2f55c10ce3 | ||
|
|
0068312ce3 | ||
|
|
ea49d92932 | ||
|
|
efe7dd23b6 | ||
|
|
3a1a58bcfc | ||
|
|
953862f133 | ||
|
|
41eb2ee969 | ||
|
|
225ecce676 | ||
|
|
335b10a694 | ||
|
|
967220178c | ||
|
|
be7461ad51 | ||
|
|
5af7cf850a | ||
|
|
86395d4d8b | ||
|
|
3412bb5380 | ||
|
|
d66e7e660d | ||
|
|
07d631e320 | ||
|
|
6ffb50530d | ||
|
|
bd7103d109 | ||
|
|
4abc2ab5bd | ||
|
|
f8a8b8ac6e | ||
|
|
cfe6e08168 | ||
|
|
5139259037 | ||
|
|
1503daf02b | ||
|
|
4246e42948 | ||
|
|
9b3eaa6fe8 | ||
|
|
716685d809 | ||
|
|
dd72871ba6 | ||
|
|
ea510f95b8 | ||
|
|
9de3db7c97 | ||
|
|
0e927ce4bd | ||
|
|
1747ebf481 | ||
|
|
da9d57a624 | ||
|
|
086d0113c5 | ||
|
|
8cf6050d10 | ||
|
|
b310168c12 |
No files matched your search
Executable
+346
@@ -0,0 +1,346 @@
|
||||
#!/bin/bash
|
||||
set -e # Enable auto-exit for debugging :))
|
||||
|
||||
# Make Linux AppImage program data
|
||||
# https://docs.appimage.org/reference/appdir.html
|
||||
|
||||
# PWD: {repo_root}/build
|
||||
# See deployer.sh for usage
|
||||
|
||||
# Terminal stuff
|
||||
RESET="$(tput sgr0)" #"\e[0m" # Resets terminal colors
|
||||
|
||||
# Colors for various information types
|
||||
FAILURE="$(tput setaf 1)" #"\e[91m"
|
||||
SUCCESS="$(tput setaf 2)" #"\e[92m"
|
||||
NOTICE="$(tput setaf 3)" #"\e[93m"
|
||||
VERBOSE="$(tput setaf 4)" #"\e[94m"
|
||||
|
||||
verbosity=0 # By default don't print anything unless it's *ultra* important.
|
||||
quiet=0 # Also don't print anything if they supplied the quiet argument
|
||||
|
||||
# URL from which to download appimagetool if there isn't one available in your $PATH
|
||||
# at time of writing only aarch64, armhf, i686, and x86_64 versions are available via this method
|
||||
# in those cases, and honestly even outside of those cases, it's better to just put a working one in your $PATH yourself..
|
||||
url="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$(uname -m).AppImage"
|
||||
|
||||
# A whitelist of libraries to include into SRB2's AppImage if SRB2 is dynamically linked.
|
||||
# please don't add a newline at the end of this or i will cry :(
|
||||
libraryWhitelist="
|
||||
libbacktrace
|
||||
libnsl
|
||||
libSDL2
|
||||
libSDL2_mixer
|
||||
libgme
|
||||
libopenmpt
|
||||
libpng
|
||||
libfluidsynth
|
||||
libpulse
|
||||
libmodplug
|
||||
libvorbisfile
|
||||
libopusfile
|
||||
libFLAC
|
||||
libmad
|
||||
libmpg123
|
||||
libvorbis
|
||||
libpulsecommon
|
||||
libsndfile
|
||||
libsndio
|
||||
libogg
|
||||
libvorbisenc
|
||||
libjson
|
||||
libreadline
|
||||
libwrap
|
||||
libtinfo
|
||||
libtirpc
|
||||
libpng16"
|
||||
|
||||
# these kinda look like macros don't they
|
||||
function print { (( "$quiet" == 0 )) && echo "$@" || :; } # echo if not quiet
|
||||
function coloredText { printf "$1"; print "${@:2}"; printf "$RESET"; } # use print to inherit quiet
|
||||
function success { coloredText "$SUCCESS" "$@"; } # use coloredText to inherit quiet
|
||||
function important { coloredText "$NOTICE" "$@"; } # use coloredText to inherit quiet
|
||||
function verboseOnly { (( "$verbosity" >= $1 )) && (coloredText "$VERBOSE" "${@:2}") || :; } # use coloredText to inherit quiet
|
||||
|
||||
# Parses an argument with a single dash
|
||||
function parseSingleDashArg() {
|
||||
while read -n 1 char; do
|
||||
if [[ "$char" == '-' || "$char" == '' ]]; then
|
||||
:
|
||||
elif [[ "$char" == 'h' ]]; then
|
||||
helppassed=1
|
||||
elif [[ "$char" == 'q' ]]; then
|
||||
quiet=1
|
||||
elif [[ "$char" == 'v' ]]; then
|
||||
verbosity="$((verbosity + 1))"
|
||||
elif [[ "$char" == 'd' ]]; then
|
||||
dry=1
|
||||
elif [[ "$char" == 's' ]]; then
|
||||
small=1
|
||||
else
|
||||
echo "$0: invalid option -- '$1'"
|
||||
echo "Try '$0 --help' for more information."
|
||||
return 1
|
||||
fi
|
||||
done <<<"$1"
|
||||
}
|
||||
|
||||
# Simple help argument checker.
|
||||
currentarg=1; # Which argument is --help...
|
||||
|
||||
# For $arg in the argument array...
|
||||
for arg in "$@"; do
|
||||
# Is it a help argument?
|
||||
if [[ "$arg" == "--help" ]]; then
|
||||
helppassed=1; # Help is passed, set $helppassed!
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
|
||||
elif [[ "$arg" == "--quiet" ]]; then
|
||||
quiet=1
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ "$arg" == "--verbose" ]]; then
|
||||
verbosity="$((verbosity + 1))" # Increase verbosity!
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ "$arg" == "--dry" ]]; then
|
||||
dry=1; # Show parameters instead of using them.
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ "$arg" == "--small" ]]; then
|
||||
small=1; # Don't copy assets to save on bandwidth.
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ ! "$arg" == *'--'* && "$arg" == *'-'* ]]; then
|
||||
parseSingleDashArg "$arg"
|
||||
|
||||
if [[ "$?" == 0 ]]; then
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
|
||||
fi
|
||||
elif [[ $arg == *'--'* ]]; then
|
||||
print "$0: invalid option -- '$1'"
|
||||
print "Try '$0 --help' for more information."
|
||||
return 1
|
||||
else
|
||||
currentarg="$((currentarg+1))" # Increment current argument number otherwise...
|
||||
fi
|
||||
done
|
||||
|
||||
important "SRB2Kart AppImage Packager v1.0 modified for kart by NepDisk."
|
||||
important "Orignal for SRB2 my mazmazz and Golden."
|
||||
|
||||
# Get root directory from the full path of this script.
|
||||
__ROOT_DIR="$3"
|
||||
|
||||
if [[ -z "$3" ]]; then
|
||||
# finds out where this script is and goes to that directory and goes up one for the root
|
||||
|
||||
scriptdir="$(dirname "${BASH_SOURCE[0]}")"
|
||||
scriptbase="$(basename "${BASH_SOURCE[0]}")"
|
||||
|
||||
__ROOT_DIR="$(cd "$scriptdir" && pwd -P)"
|
||||
fi
|
||||
|
||||
# If it starts with '.', put the current working directory behind it so things work.
|
||||
if [[ "$__ROOT_DIR" == '.' || "$__ROOT_DIR" == '..' ]]; then
|
||||
__ROOT_DIR="$PWD/$__ROOT_DIR"
|
||||
fi
|
||||
|
||||
# Set up defaults
|
||||
__PROGRAM_NAME="${PROGRAM_NAME:-"SRB2Kart Saturn"}"
|
||||
__PROGRAM_DESCRIPTION="${PROGRAM_DESCRIPTION:-"Modded version of SRB2kart with more features."}"
|
||||
__PROGRAM_FILENAME="${PROGRAM_FILENAME:-"lsdl2srb2kart"}"
|
||||
__PROGRAM_ASSETS="${PROGRAM_ASSETS:-"$__ROOT_DIR/assets/installer"}"
|
||||
|
||||
__BUILD_DIR="${1:-"$__ROOT_DIR/bin"}"
|
||||
__OUTPUT_FILENAME="${2:-"$__PROGRAM_FILENAME.AppImage"}"
|
||||
|
||||
__APPIMAGETOOL="${4:-"appimagetool"}"
|
||||
|
||||
if (! command -v "$__APPIMAGETOOL" &> /dev/null); then
|
||||
__APPIMAGETOOL=
|
||||
fi
|
||||
|
||||
# Stuff that prints and exits.
|
||||
|
||||
# Prints setup text using method given by arguments.
|
||||
# Example: printSetup "print" # print "Setup for AppImage...
|
||||
function printSetup {
|
||||
$@ "Setup for AppImage in BUILD_DIR: '$__BUILD_DIR'..."
|
||||
$@ "With the OUTPUT_FILENAME: '$__OUTPUT_FILENAME'"
|
||||
$@ "And SRB2 Repository Root ROOT_DIR: '$__ROOT_DIR'"
|
||||
$@ "Using APPIMAGETOOL: '$([ -z "$__APPIMAGETOOL" ] && echo '(download)' || echo $__APPIMAGETOOL)'"
|
||||
$@ ""
|
||||
$@ "This should be run from a Makefile or from the directory of the build. If it is not, then change to that directory or specify that directory as an argument."
|
||||
$@ "If ROOT_DIR isn't SRB2's repository root, specify that as an argument too."
|
||||
$@ "Make must have built the program before you run this script."
|
||||
$@ ""
|
||||
$@ "Make sure these Environment Variables are correct."
|
||||
$@ "If not, then enter: export PROGRAM_VARIABLE=value"
|
||||
$@ "PROGRAM_NAME: $__PROGRAM_NAME"
|
||||
$@ "PROGRAM_DESCRIPTION: $__PROGRAM_DESCRIPTION"
|
||||
$@ "PROGRAM_FILENAME: $__PROGRAM_FILENAME"
|
||||
$@ "PROGRAM_ASSETS: $__PROGRAM_ASSETS"
|
||||
}
|
||||
|
||||
if [[ "$helppassed" ]]; then
|
||||
print "Usage: $(basename "$0") [OPTION]... [BUILD_DIR] [OUTPUT_NAME] [ROOT_DIR] [APPIMAGETOOL]"
|
||||
print "Packages a SRB2 binary into an AppImage."
|
||||
print "OPTIONs may be included anywhere within the arguments."
|
||||
print ""
|
||||
print "Arguments:"
|
||||
print " -h, --help display this help and exit."
|
||||
print " -q, --quiet don't display any text."
|
||||
print " -v, --verbose make commands more verbose, will always print."
|
||||
print " -s, --small don't copy SRB2 assets to save on bandwidth."
|
||||
print " parameters regardless of --dry."
|
||||
print " -d, --dry print parameters and exit."
|
||||
print ""
|
||||
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
|
||||
printSetup "print"
|
||||
else
|
||||
print "This should be run from a Makefile or from the directory of the build."
|
||||
print "Make must have built the program before you run this script."
|
||||
fi
|
||||
exit;
|
||||
fi
|
||||
|
||||
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
|
||||
printSetup "verboseOnly" "0"
|
||||
verboseOnly 0 ""
|
||||
|
||||
if [[ "$dry" ]]; then
|
||||
set -n # Enable debug mode and verbose for dry run.
|
||||
fi
|
||||
fi
|
||||
|
||||
# End stuff that prints and exits.
|
||||
|
||||
if (( "$verbosity" >= 4 )); then
|
||||
set -v # Really verbose? Print *everything*!
|
||||
fi
|
||||
|
||||
# Define AppDir structure
|
||||
mkdir -p "$__BUILD_DIR/AppDir/usr/bin"
|
||||
mkdir -p "$__BUILD_DIR/AppDir/lib"
|
||||
mkdir -p "$__BUILD_DIR/AppDir/usr/share/applications"
|
||||
mkdir -p "$__BUILD_DIR/AppDir/usr/share/icons/hicolor/256x256/apps"
|
||||
|
||||
# Copy program data
|
||||
if [[ ! $small ]]; then
|
||||
verboseOnly 1 "Packaging program assets..."
|
||||
cp -r "$__PROGRAM_ASSETS"/* "$__BUILD_DIR/AppDir/usr/bin/"
|
||||
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
|
||||
else
|
||||
verboseOnly 1 "Skipping program asset packing, --small or -s passed..."
|
||||
fi
|
||||
|
||||
verboseOnly 1 "Packaging SRB2..."
|
||||
verboseOnly 1 "Assuming executable name $__PROGRAM_FILENAME"
|
||||
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
|
||||
|
||||
# Copy required dependencies, but only if the program is dynamically linked.
|
||||
verboseOnly 1 "Testing if this build is dynamically linked..."
|
||||
|
||||
set +e # Disable auto-exit for ldd.
|
||||
|
||||
srb2Libraries="$(ldd "$__BUILD_DIR/$__PROGRAM_FILENAME")"
|
||||
exitcode="$?"
|
||||
|
||||
set -e # Enable it again!
|
||||
|
||||
if (( $exitcode == 0 )); then
|
||||
verboseOnly 1 "This build *is* dynamically linked! Packaging dependencies."
|
||||
|
||||
# read the dynamic libraries of srb2, trim off beginning whitespace, and get the third field seperated by spaces
|
||||
# this gives us a newline-seperated list of libraries with their full paths.
|
||||
srb2Libraries="$(echo "$srb2Libraries" | cut -f 2 | cut -d ' ' -f 3)"
|
||||
|
||||
# remove any extraneous newlines around the string
|
||||
libraryWhitelist="$(echo $libraryWhitelist | head -c -1 | tr ' ' '\n')"
|
||||
|
||||
# replace e.g. 'abc' with '(/abc\b)', and replace newlines with '|'.
|
||||
# this converts it into a grep regular expression to check for any whitelisted library names.
|
||||
libraryWhitelist="$(printf "%s" "$libraryWhitelist" | sed 's|.*|(/\0\\b)|' | tr '\n' '|')"
|
||||
|
||||
# grab only the entries that match the regex
|
||||
__LDD_LIST="$(printf "%s" "$srb2Libraries" | grep -E "$libraryWhitelist")"
|
||||
|
||||
# use echo to convert the newline-seperated list into an argument list
|
||||
__LDD_LIST="$(echo $__LDD_LIST)"
|
||||
|
||||
# read into an array because i can't be bothered iterating the lines of a string today
|
||||
# there's so many other things in this file that'd need to be adjusted to be POSIX-compliant anyway
|
||||
IFS=' ' read -r -a paths <<< "$__LDD_LIST"
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
if [ -f "$path" ]; then
|
||||
verboseOnly 2 "Packaging dependency $(basename "$path")..."
|
||||
cp "$path" $__BUILD_DIR/AppDir/lib/
|
||||
else
|
||||
verboseOnly 2 "Dependency $(basename "$path") not found"
|
||||
fi
|
||||
done
|
||||
else
|
||||
verboseOnly 1 "This SRB2 build is statically linked, skipping dependency packing."
|
||||
fi
|
||||
|
||||
cd "$__BUILD_DIR/AppDir"
|
||||
|
||||
# Copy icons
|
||||
verboseOnly 1 "Packaging resources..."
|
||||
cp "$__ROOT_DIR/srb2.png" "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png"
|
||||
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./.DirIcon"
|
||||
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./$__PROGRAM_FILENAME.png"
|
||||
|
||||
# Make desktop descriptor
|
||||
cat > "./usr/share/applications/$__PROGRAM_FILENAME.desktop" <<EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=$__PROGRAM_NAME
|
||||
Comment=$__PROGRAM_DESCRIPTION
|
||||
Icon=$__PROGRAM_FILENAME
|
||||
Exec=AppRun %F
|
||||
Categories=Game;
|
||||
EOF
|
||||
|
||||
ln -sf "./usr/share/applications/$__PROGRAM_FILENAME.desktop" "./$__PROGRAM_FILENAME.desktop"
|
||||
|
||||
# Make entry point
|
||||
echo -e '#!'"$(dirname "$SHELL")/sh" > ./AppRun
|
||||
echo -e 'HERE="$(dirname "$(readlink -f "${0}")")"' >> ./AppRun
|
||||
echo -e 'SRB2WADDIR=$HERE/usr/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HERE/lib exec $HERE/usr/bin/'"$__PROGRAM_FILENAME"' "$@"' >> ./AppRun
|
||||
chmod +x ./AppRun
|
||||
|
||||
cd .. # now in $__BUILD_DIR
|
||||
|
||||
# Package AppImage
|
||||
if [ -z "$__APPIMAGETOOL" ]; then
|
||||
verboseOnly 1 "No valid appimagetool path given or detected, downloading appimagetool..."
|
||||
|
||||
# Print notice for internet connection.
|
||||
important "If the command hangs here, check your internet connection, or download appimagetool and add it to your \$PATH and try compiling again."
|
||||
|
||||
(( "$verbosity" >= 3 )) && wget "$url" || wget -q "$url"
|
||||
|
||||
APPIMAGETOOL="./$(basename "$url")"
|
||||
chmod a+x "$APPIMAGETOOL"
|
||||
else
|
||||
verboseOnly 1 "appimagetool path given or detected, no download required."
|
||||
APPIMAGETOOL="$__APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
verboseOnly 1 "Packing AppImage $__OUTPUT_FILENAME"
|
||||
|
||||
if (( verbosity >= 3 )); then
|
||||
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME"
|
||||
elif (( verbosity >= 2 )); then
|
||||
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null
|
||||
else
|
||||
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
success "AppImage ready!"
|
||||
verboseOnly 1 "Cleaning up files..."
|
||||
rm -r ./AppDir
|
||||
|
||||
if [ -z "$__APPIMAGETOOL" ]; then
|
||||
rm "$APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
cd "$__ROOT_DIR" # snap back to reality
|
||||
+33
@@ -130,3 +130,36 @@ if rawget(_G, "S_StopSoundByNum") ~= nil then
|
||||
... -- Can use it
|
||||
end
|
||||
```
|
||||
## addHook("ServerJoin", function())
|
||||
|
||||
ServerJoin hook called when client joins server (starting a listen server also calls it for host).
|
||||
Generally it was made to make loading custom config files less hacky, but can be used for anything else too.
|
||||
|
||||
## player.viewrollangle field
|
||||
|
||||
Returns player's current view roll angle for the Screen Tilting feature, useful for HUD elements.
|
||||
|
||||
## G_SetPlayerGamepadIndicatorColor(player, skincolor)
|
||||
|
||||
Set a custom color for Supported Gamepads with RGB LED functionality.
|
||||
To be used with Displayplayers.
|
||||
Only takes Skincolors.
|
||||
Best to be used in a Loop to ensure the color wont get overwritten by the game.
|
||||
|
||||
## G_PlayerDeviceRumble(player, low_strength, high_strength, -optional- duration)
|
||||
|
||||
Add Gamepad Rumble support for things.
|
||||
To be used with Displayplayers.
|
||||
Duration is in milliseconds and is optional to set, default value is 84ms.
|
||||
|
||||
# Other changes
|
||||
|
||||
## P_PlayRinglossSound(source, damager)
|
||||
|
||||
Add optional `damager` argument (should be `mobj_t`), which causes hurt sound also play for damager
|
||||
if `karthitemdialog` option is enabled
|
||||
|
||||
## K_PlayHitEmSound(mobj, victim)
|
||||
|
||||
Add optional `victim` argument (should be a player's `mobj_t`), which causes "hit em" sound to be
|
||||
delayed and played for victim too if `karthitemdialog` option is enabled
|
||||
@@ -1 +1 @@
|
||||
/lsdlsrb2
|
||||
/lsdl2srb2kart
|
||||
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := am_map.c \
|
||||
m_cheat.c \
|
||||
m_fixed.c \
|
||||
m_menu.c \
|
||||
m_textinput.c \
|
||||
m_misc.c \
|
||||
m_queue.c \
|
||||
m_random.c \
|
||||
|
||||
+553
-551
File diff suppressed because it is too large.
Load diff
+42
-2
@@ -106,6 +106,8 @@ ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
|
||||
|
||||
else # if you on the *nix
|
||||
|
||||
NOUPX=1
|
||||
|
||||
system:=$(shell uname -s)
|
||||
|
||||
ifeq ($(system),Linux)
|
||||
@@ -205,6 +207,18 @@ USE_FBO_OGL=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOSATURNSYNCH
|
||||
DOSATURNSYNCH=1
|
||||
ifndef NOSATURNJOIN
|
||||
DOSATURNJOIN=1
|
||||
endif
|
||||
ifndef NOSATURNPAK
|
||||
DOSATURNPAK=1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINGW
|
||||
include win32/Makefile.cfg
|
||||
endif #ifdef MINGW
|
||||
@@ -278,12 +292,12 @@ ifdef NOHW
|
||||
OPTS+=-DNOHW
|
||||
else
|
||||
OPTS+=-DHWRENDER
|
||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
|
||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o \
|
||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
|
||||
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o
|
||||
endif
|
||||
|
||||
OPTS += -DCOMPVERSION
|
||||
OPTS += -DCOMPVERSION -fwrapv
|
||||
|
||||
ifndef NONX86
|
||||
ifndef GCC29
|
||||
@@ -384,6 +398,18 @@ OPTS+=-DUSE_FBO_OGL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOSATURNSYNCH
|
||||
OPTS+=-DDOSATURNSYNCH
|
||||
ifndef NOSATURNJOIN
|
||||
OPTS+=-DDOSATURNJOIN
|
||||
endif
|
||||
ifndef NOSATURNPAK
|
||||
OPTS+=-DDOSATURNPAK
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_MINIUPNPC
|
||||
ifdef NONET
|
||||
HAVE_MINIUPNPC=''
|
||||
@@ -492,6 +518,7 @@ OBJS:=$(i_main_o) \
|
||||
$(OBJDIR)/hu_stuff.o \
|
||||
$(OBJDIR)/y_inter.o \
|
||||
$(OBJDIR)/st_stuff.o \
|
||||
$(OBJDIR)/k_director.o \
|
||||
$(OBJDIR)/k_kart.o \
|
||||
$(OBJDIR)/m_aatree.o \
|
||||
$(OBJDIR)/m_anigif.o \
|
||||
@@ -502,6 +529,7 @@ OBJS:=$(i_main_o) \
|
||||
$(OBJDIR)/m_fixed.o \
|
||||
$(OBJDIR)/m_menu.o \
|
||||
$(OBJDIR)/m_misc.o \
|
||||
$(OBJDIR)/m_textinput.o \
|
||||
$(OBJDIR)/m_perfstats.o \
|
||||
$(OBJDIR)/m_random.o \
|
||||
$(OBJDIR)/m_queue.o \
|
||||
@@ -535,6 +563,7 @@ OBJS:=$(i_main_o) \
|
||||
$(OBJDIR)/r_splats.o \
|
||||
$(OBJDIR)/r_patch.o \
|
||||
$(OBJDIR)/r_things.o \
|
||||
$(OBJDIR)/r_portal.o \
|
||||
$(OBJDIR)/screen.o \
|
||||
$(OBJDIR)/v_video.o \
|
||||
$(OBJDIR)/s_sound.o \
|
||||
@@ -630,6 +659,17 @@ ifndef NOUPX
|
||||
-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef APPIMAGE
|
||||
@echo Building AppImage...
|
||||
ifdef APPIMAGE_NOASSETS
|
||||
$(.)../AppImage_build.sh --small --quiet $(BIN)/
|
||||
else
|
||||
$(.)../AppImage_build.sh -q $(BIN)/
|
||||
endif
|
||||
@echo AppImage build complete, please look for $(EXENAME).AppImage in $(BIN)
|
||||
endif
|
||||
|
||||
@echo Build is done, please look for $(EXENAME) in $(BIN), \(checking for post steps\)
|
||||
|
||||
reobjdump:
|
||||
|
||||
+12
-7
@@ -12,7 +12,7 @@
|
||||
# to avoid a false positive with the version detection...
|
||||
|
||||
SUPPORTED_GCC_VERSIONS:=\
|
||||
141 14\
|
||||
142 141 140 14\
|
||||
132 131 130 13\
|
||||
123 122 121 120 12\
|
||||
114 113 112 111 110 11\
|
||||
@@ -24,7 +24,7 @@ SUPPORTED_GCC_VERSIONS:=\
|
||||
55 54 53 52 51 50\
|
||||
49 48 47 46 45 44 43 42 41 40
|
||||
|
||||
LATEST_GCC_VERSION=14.1
|
||||
LATEST_GCC_VERSION=14.2.1
|
||||
|
||||
# gcc or g++
|
||||
ifdef PREFIX
|
||||
@@ -78,12 +78,20 @@ ifeq (,$(filter GCC%,$(.VARIABLES)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef GCC141
|
||||
ifdef GCC142
|
||||
GCC141=1
|
||||
endif
|
||||
|
||||
ifdef GCC141
|
||||
GCC140=1
|
||||
endif
|
||||
|
||||
ifdef GCC14
|
||||
GCC14=1
|
||||
GCC140=1
|
||||
endif
|
||||
|
||||
ifdef GCC140
|
||||
GCC132=1
|
||||
endif
|
||||
|
||||
ifdef GCC132
|
||||
@@ -437,9 +445,6 @@ endif
|
||||
ifdef GCC44
|
||||
WFLAGS+=-Wno-error=array-bounds
|
||||
endif
|
||||
ifdef GCC45
|
||||
opts+=-fwrapv
|
||||
endif
|
||||
ifdef GCC46
|
||||
WFLAGS+=-Wno-error=suggest-attribute=noreturn
|
||||
endif
|
||||
|
||||
+10
-17
@@ -260,25 +260,15 @@ static inline void AM_restoreScaleAndLoc(void)
|
||||
*/
|
||||
static void AM_findMinMaxBoundaries(void)
|
||||
{
|
||||
size_t i;
|
||||
fixed_t a;
|
||||
fixed_t b;
|
||||
fixed_t a, b;
|
||||
|
||||
min_x = min_y = +INT32_MAX;
|
||||
max_x = max_y = -INT32_MAX;
|
||||
min_x = minimapinfo.min_x << MAPBITS;
|
||||
max_x = minimapinfo.max_x << MAPBITS;
|
||||
min_y = minimapinfo.min_y << MAPBITS;
|
||||
max_y = minimapinfo.max_y << MAPBITS;
|
||||
|
||||
for (i = 0; i < numvertexes; i++)
|
||||
{
|
||||
if (vertexes[i].x < min_x)
|
||||
min_x = vertexes[i].x;
|
||||
else if (vertexes[i].x > max_x)
|
||||
max_x = vertexes[i].x;
|
||||
|
||||
if (vertexes[i].y < min_y)
|
||||
min_y = vertexes[i].y;
|
||||
else if (vertexes[i].y > max_y)
|
||||
max_y = vertexes[i].y;
|
||||
}
|
||||
max_w = minimapinfo.map_w << MAPBITS;
|
||||
max_h = minimapinfo.map_h << MAPBITS;
|
||||
|
||||
max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS);
|
||||
max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS);
|
||||
@@ -1015,6 +1005,9 @@ static inline void AM_drawPlayers(void)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
|
||||
p = &players[i];
|
||||
if (p->skincolor > 0)
|
||||
|
||||
+54
-253
@@ -32,6 +32,7 @@
|
||||
#include "i_threads.h"
|
||||
#include "d_main.h"
|
||||
#include "m_menu.h"
|
||||
#include "m_textinput.h"
|
||||
#include "filesrch.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
@@ -43,8 +44,12 @@
|
||||
#ifdef HAVE_THREADS
|
||||
I_mutex con_mutex;
|
||||
|
||||
# define Lock_state() I_lock_mutex(&con_mutex)
|
||||
# define Unlock_state() I_unlock_mutex(con_mutex)
|
||||
// g_in_exiting_signal_handler is an evil hack
|
||||
// to avoid infinite SIGABRT recursion in the signal handler
|
||||
// due to poisoned locks or mach-o kernel not supporting locks in signals
|
||||
// or something like that. idk
|
||||
# define Lock_state() if (!g_in_exiting_signal_handler) { I_lock_mutex(&con_mutex); }
|
||||
# define Unlock_state() if (!g_in_exiting_signal_handler) { I_unlock_mutex(con_mutex); }
|
||||
#else/*HAVE_THREADS*/
|
||||
# define Lock_state()
|
||||
# define Unlock_state()
|
||||
@@ -93,9 +98,7 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines
|
||||
|
||||
static INT32 inputline; // current input line number
|
||||
static INT32 inputhist; // line number of history input line to restore
|
||||
static size_t input_cur; // position of cursor in line
|
||||
static size_t input_sel; // position of selection marker (I.E.: anything between this and input_cur is "selected")
|
||||
static size_t input_len; // length of current line, used to bound cursor and such
|
||||
static textinput_t input;
|
||||
// notice: input does NOT include the "$" at the start of the line. - 11/3/16
|
||||
|
||||
// protos.
|
||||
@@ -454,7 +457,8 @@ static void CON_InputInit(void)
|
||||
// prepare the first prompt line
|
||||
memset(inputlines, 0, sizeof (inputlines));
|
||||
inputline = 0;
|
||||
input_cur = input_sel = input_len = 0;
|
||||
|
||||
M_TextInputInit(&input, inputlines[inputline], CON_MAXPROMPTCHARS);
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
@@ -798,113 +802,6 @@ void CON_Ticker(void)
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
//
|
||||
// ----
|
||||
//
|
||||
// Shortcuts for adding and deleting characters, strings, and sections
|
||||
// Necessary due to moving cursor
|
||||
//
|
||||
|
||||
static void CON_InputClear(void)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
|
||||
input_cur = input_sel = input_len = 0;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputSetString(const char *c)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
|
||||
strcpy(inputlines[inputline], c);
|
||||
input_cur = input_sel = input_len = strlen(c);
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputAddString(const char *c)
|
||||
{
|
||||
size_t csize = strlen(c);
|
||||
|
||||
Lock_state();
|
||||
|
||||
if (input_len + csize > CON_MAXPROMPTCHARS-1)
|
||||
{
|
||||
Unlock_state();
|
||||
return;
|
||||
}
|
||||
if (input_cur != input_len)
|
||||
memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur);
|
||||
memcpy(&inputlines[inputline][input_cur], c, csize);
|
||||
input_len += csize;
|
||||
input_sel = (input_cur += csize);
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputDelSelection(void)
|
||||
{
|
||||
size_t start, end, len;
|
||||
|
||||
Lock_state();
|
||||
|
||||
if (input_cur > input_sel)
|
||||
{
|
||||
start = input_sel;
|
||||
end = input_cur;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = input_cur;
|
||||
end = input_sel;
|
||||
}
|
||||
len = (end - start);
|
||||
|
||||
if (end != input_len)
|
||||
memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end);
|
||||
memset(&inputlines[inputline][input_len - len], 0, len);
|
||||
|
||||
input_len -= len;
|
||||
input_sel = input_cur = start;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputAddChar(char c)
|
||||
{
|
||||
if (input_len >= CON_MAXPROMPTCHARS-1)
|
||||
return;
|
||||
|
||||
Lock_state();
|
||||
|
||||
if (input_cur != input_len)
|
||||
memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur);
|
||||
inputlines[inputline][input_cur++] = c;
|
||||
inputlines[inputline][++input_len] = 0;
|
||||
input_sel = input_cur;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputDelChar(void)
|
||||
{
|
||||
if (!input_cur)
|
||||
return;
|
||||
|
||||
Lock_state();
|
||||
|
||||
if (input_cur != input_len)
|
||||
memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur);
|
||||
inputlines[inputline][--input_len] = 0;
|
||||
input_sel = --input_cur;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
//
|
||||
// ----
|
||||
//
|
||||
@@ -985,6 +882,10 @@ boolean CON_Responder(event_t *ev)
|
||||
}
|
||||
}
|
||||
|
||||
Lock_state();
|
||||
M_TextInputHandle(&input, key);
|
||||
Unlock_state();
|
||||
|
||||
// Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas
|
||||
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|
||||
|| key == KEY_LCTRL || key == KEY_RCTRL
|
||||
@@ -997,12 +898,11 @@ boolean CON_Responder(event_t *ev)
|
||||
// show all cvars/commands that match what we have inputted
|
||||
if (key == KEY_TAB)
|
||||
{
|
||||
|
||||
if (!completion[0])
|
||||
{
|
||||
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
|
||||
if (!input.length || input.length >= 40 || strchr(input.buffer, ' '))
|
||||
return true;
|
||||
strcpy(completion, inputlines[inputline]);
|
||||
strcpy(completion, input.buffer);
|
||||
comskips = varskips = 0;
|
||||
}
|
||||
|
||||
@@ -1023,42 +923,9 @@ boolean CON_Responder(event_t *ev)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == 'x' || key == 'X')
|
||||
{
|
||||
if (input_sel > input_cur)
|
||||
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
|
||||
else
|
||||
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
|
||||
CON_InputDelSelection();
|
||||
// Those are already handled in M_TextInputHandle, but they do extra logic... Maybe textinput_t should have some sort of callbacks?
|
||||
if (key == 'x' || key == 'X' || key == 'v' || key == 'V')
|
||||
completion[0] = 0;
|
||||
return true;
|
||||
}
|
||||
else if (key == 'c' || key == 'C')
|
||||
{
|
||||
if (input_sel > input_cur)
|
||||
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
|
||||
else
|
||||
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
|
||||
return true;
|
||||
}
|
||||
else if (key == 'v' || key == 'V')
|
||||
{
|
||||
const char *paste = I_ClipboardPaste();
|
||||
if (input_sel != input_cur)
|
||||
CON_InputDelSelection();
|
||||
if (paste != NULL)
|
||||
CON_InputAddString(paste);
|
||||
completion[0] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Select all
|
||||
if (key == 'a' || key == 'A')
|
||||
{
|
||||
input_sel = 0;
|
||||
input_cur = input_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ...why shouldn't it eat the key? if it doesn't, it just means you
|
||||
// can control Sonic from the console, which is silly
|
||||
@@ -1073,9 +940,9 @@ boolean CON_Responder(event_t *ev)
|
||||
// remember typing for several completions (a-la-4dos)
|
||||
if (!completion[0])
|
||||
{
|
||||
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
|
||||
if (!input.length || input.length >= 40 || strchr(input.buffer, ' '))
|
||||
return true;
|
||||
strcpy(completion, inputlines[inputline]);
|
||||
strcpy(completion, input.buffer);
|
||||
comskips = varskips = 0;
|
||||
}
|
||||
else
|
||||
@@ -1106,7 +973,11 @@ boolean CON_Responder(event_t *ev)
|
||||
cmd = CV_CompleteVar(completion, varskips);
|
||||
|
||||
if (cmd)
|
||||
CON_InputSetString(va("%s ", cmd));
|
||||
{
|
||||
Lock_state();
|
||||
M_TextInputSetString(&input, va("%s ", cmd));
|
||||
Unlock_state();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (comskips > 0)
|
||||
@@ -1132,37 +1003,6 @@ boolean CON_Responder(event_t *ev)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == KEY_LEFTARROW)
|
||||
{
|
||||
if (input_cur != 0)
|
||||
--input_cur;
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
{
|
||||
if (input_cur < input_len)
|
||||
++input_cur;
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_HOME)
|
||||
{
|
||||
input_cur = 0;
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_END)
|
||||
{
|
||||
input_cur = input_len;
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
// At this point we're messing with input
|
||||
// Clear completion
|
||||
completion[0] = 0;
|
||||
@@ -1170,45 +1010,29 @@ boolean CON_Responder(event_t *ev)
|
||||
// command enter
|
||||
if (key == KEY_ENTER)
|
||||
{
|
||||
if (!input_len)
|
||||
if (!input.length)
|
||||
return true;
|
||||
|
||||
// push the command
|
||||
COM_BufAddText(inputlines[inputline]);
|
||||
COM_BufAddText(input.buffer);
|
||||
COM_BufAddText("\n");
|
||||
|
||||
CONS_Printf("\x86""%c""\x80""%s\n", CON_PROMPTCHAR, inputlines[inputline]);
|
||||
|
||||
Lock_state();
|
||||
|
||||
// Only add command to history if it differs from previous one
|
||||
if (strcmp(inputlines[inputline], inputlines[(inputline-1) & 31]))
|
||||
if (strcmp(input.buffer, inputlines[(inputline-1) & 31]))
|
||||
{
|
||||
inputline = (inputline+1) & 31;
|
||||
M_TextInputInit(&input, inputlines[inputline], CON_MAXPROMPTCHARS);
|
||||
}
|
||||
|
||||
inputhist = inputline;
|
||||
CON_InputClear();
|
||||
M_TextInputClear(&input);
|
||||
|
||||
return true;
|
||||
}
|
||||
Unlock_state();
|
||||
|
||||
// backspace and delete command prompt
|
||||
if (input_sel != input_cur)
|
||||
{
|
||||
if (key == KEY_BACKSPACE || key == KEY_DEL)
|
||||
{
|
||||
CON_InputDelSelection();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == KEY_BACKSPACE)
|
||||
{
|
||||
CON_InputDelChar();
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_DEL)
|
||||
{
|
||||
if (input_cur == input_len)
|
||||
return true;
|
||||
++input_cur;
|
||||
CON_InputDelChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1225,7 +1049,9 @@ boolean CON_Responder(event_t *ev)
|
||||
if (inputhist == inputline)
|
||||
inputhist = (inputline + 1) & 31;
|
||||
|
||||
CON_InputSetString(inputlines[inputhist]);
|
||||
Lock_state();
|
||||
M_TextInputSetString(&input, inputlines[inputhist]);
|
||||
Unlock_state();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1239,41 +1065,16 @@ boolean CON_Responder(event_t *ev)
|
||||
while (inputhist != inputline && !inputlines[inputhist][0]);
|
||||
|
||||
// back to currentline
|
||||
Lock_state();
|
||||
if (inputhist == inputline)
|
||||
CON_InputClear();
|
||||
M_TextInputClear(&input);
|
||||
else
|
||||
CON_InputSetString(inputlines[inputhist]);
|
||||
M_TextInputSetString(&input, inputlines[inputhist]);
|
||||
Unlock_state();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// allow people to use keypad in console (good for typing IP addresses) - Calum
|
||||
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
|
||||
{
|
||||
char keypad_translation[] = {'7','8','9','-',
|
||||
'4','5','6','+',
|
||||
'1','2','3',
|
||||
'0','.'};
|
||||
|
||||
key = keypad_translation[key - KEY_KEYPAD7];
|
||||
}
|
||||
else if (key == KEY_KPADSLASH)
|
||||
key = '/';
|
||||
|
||||
// same capslock code as hu_stuff.c's HU_responder. Check there for details.
|
||||
key = CON_ShiftChar(key);
|
||||
|
||||
// enter a char into the command prompt
|
||||
if (key < 32 || key > 127)
|
||||
return true;
|
||||
|
||||
// add key to cmd line here
|
||||
if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
|
||||
key = key + 'a' - 'A';
|
||||
|
||||
if (input_sel != input_cur)
|
||||
CON_InputDelSelection();
|
||||
CON_InputAddChar(key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1555,16 +1356,16 @@ static void CON_DrawInput(void)
|
||||
|
||||
clen = con_width-13;
|
||||
|
||||
if (input_len <= clen)
|
||||
if (input.length <= clen)
|
||||
{
|
||||
c = 0;
|
||||
clen = input_len;
|
||||
clen = input.length;
|
||||
}
|
||||
else // input line scrolls left if it gets too long
|
||||
{
|
||||
clen -= 2; // There will always be some extra truncation -- but where is what we'll find out
|
||||
|
||||
if (input_cur <= clen/2)
|
||||
if (input.cursor <= clen/2)
|
||||
{
|
||||
// Close enough to right edge to show all
|
||||
c = 0;
|
||||
@@ -1575,15 +1376,15 @@ static void CON_DrawInput(void)
|
||||
{
|
||||
// Cursor in the middle (or right side) of input
|
||||
// Move over for the ellipsis
|
||||
c = input_cur - (clen/2) + 2;
|
||||
c = input.cursor - (clen/2) + 2;
|
||||
x += charwidth*2;
|
||||
lellip = 1;
|
||||
|
||||
if (c + clen >= input_len)
|
||||
if (c + clen >= input.length)
|
||||
{
|
||||
// Cursor in the right side of input
|
||||
// We were too far over, so move back
|
||||
c = input_len - clen;
|
||||
c = input.length - clen;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1597,7 +1398,7 @@ static void CON_DrawInput(void)
|
||||
if (lellip)
|
||||
{
|
||||
x -= charwidth*3;
|
||||
if (input_sel < c)
|
||||
if (input.select < c)
|
||||
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART);
|
||||
for (i = 0; i < 3; ++i, x += charwidth)
|
||||
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
@@ -1607,7 +1408,7 @@ static void CON_DrawInput(void)
|
||||
|
||||
for (cend = c + clen; c < cend; ++c, x += charwidth)
|
||||
{
|
||||
if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c))
|
||||
if ((input.select > c && input.cursor <= c) || (input.select <= c && input.cursor > c))
|
||||
{
|
||||
V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART);
|
||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
@@ -1615,14 +1416,14 @@ static void CON_DrawInput(void)
|
||||
else
|
||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
|
||||
if (c == input_cur && con_tick >= 4)
|
||||
if (c == input.cursor && con_tick >= 4)
|
||||
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
}
|
||||
if (cend == input_cur && con_tick >= 4)
|
||||
if (cend == input.cursor && con_tick >= 4)
|
||||
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
if (rellip)
|
||||
{
|
||||
if (input_sel > cend)
|
||||
if (input.select > cend)
|
||||
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART);
|
||||
for (i = 0; i < 3; ++i, x += charwidth)
|
||||
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
|
||||
+486
-136
File diff suppressed because it is too large.
Load diff
+27
-3
@@ -98,6 +98,16 @@ typedef enum
|
||||
PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)"
|
||||
|
||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate!
|
||||
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
|
||||
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
|
||||
|
||||
// we will reserve this for now even if unused, so order wont get mangled
|
||||
PT_ISSATURN, // Saturn specific identifier packet
|
||||
#endif
|
||||
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
@@ -363,6 +373,9 @@ typedef struct
|
||||
UINT8 subversion; // Contains build version
|
||||
UINT8 localplayers; // number of splitscreen players
|
||||
UINT8 mode;
|
||||
#ifdef SATURNJOIN
|
||||
UINT8 issaturn;
|
||||
#endif
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
||||
@@ -567,14 +580,22 @@ extern consvar_t
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
cv_joinnextround,
|
||||
#endif
|
||||
cv_netticbuffer, cv_allownewplayer, cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
cv_netticbuffer, cv_allownewplayer,
|
||||
#ifdef SATURNJOIN
|
||||
cv_allownewsaturnplayer,
|
||||
#endif
|
||||
cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts,
|
||||
#ifdef SATURNSYNCH
|
||||
cv_resynchcooldown, cv_gamestateattempts,
|
||||
#endif
|
||||
cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
extern consvar_t cv_connectawaittime;
|
||||
|
||||
extern consvar_t cv_discordinvites;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
//tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
void D_ClientServerInit(void);
|
||||
|
||||
// Initialise the other field
|
||||
@@ -632,7 +653,10 @@ tic_t GetLag(INT32 node);
|
||||
UINT8 GetFreeXCmdSize(void);
|
||||
|
||||
extern UINT8 hu_resynching;
|
||||
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
|
||||
#ifdef SATURNSYNCH
|
||||
extern UINT8 hu_redownloadinggamestate;
|
||||
#endif
|
||||
extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
|
||||
|
||||
typedef struct rewind_s {
|
||||
UINT8 savebuffer[(768*1024)];
|
||||
|
||||
+181
-111
@@ -37,6 +37,7 @@
|
||||
#include "d_net.h"
|
||||
#include "f_finale.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_system.h"
|
||||
@@ -98,23 +99,22 @@ UINT8 window_notinfocus = false;
|
||||
// DEMO LOOP
|
||||
//
|
||||
//static INT32 demosequence;
|
||||
static const char *pagename = "MAP1PIC";
|
||||
static char *startupwadfiles[MAX_WADFILES];
|
||||
static char *startuppwads[MAX_WADFILES];
|
||||
|
||||
// autoloading
|
||||
static char *autoloadwadfiles[MAX_WADFILES];
|
||||
char *autoloadwadfiles[MAX_WADFILES];
|
||||
char *autoloadwadfilespost[MAX_WADFILES];
|
||||
boolean autoloading;
|
||||
boolean autoloaded;
|
||||
boolean postautoloaded;
|
||||
boolean postautoloaded = false;
|
||||
boolean wasautoloaded = false;
|
||||
|
||||
boolean devparm = false; // started game with -devparm
|
||||
|
||||
boolean singletics = false; // timedemo
|
||||
boolean lastdraw = false;
|
||||
|
||||
postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
|
||||
INT32 postimgparam[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
// These variables are only true if
|
||||
@@ -149,6 +149,8 @@ INT32 eventhead, eventtail;
|
||||
|
||||
boolean dedicated = false;
|
||||
|
||||
boolean loaded_config = false;
|
||||
|
||||
//
|
||||
// D_PostEvent
|
||||
// Called by the I/O functions when input is detected
|
||||
@@ -166,6 +168,32 @@ UINT8 ctrldown = 0; // 0x1 left, 0x2 right
|
||||
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
||||
boolean capslock = 0; // gee i wonder what this does.
|
||||
|
||||
static inline void D_DeviceLEDTick(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT16 color[MAXSPLITSCREENPLAYERS];
|
||||
UINT16 curcolor[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
if (I_NumJoys() == 0 || (cv_gamepadled[0].value == 0 && cv_gamepadled[1].value == 0 && cv_gamepadled[2].value == 0 && cv_gamepadled[3].value == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (G_GetDeviceForPlayer(i) == 0)
|
||||
continue;
|
||||
|
||||
color[i] = G_GetSkinColor(i);
|
||||
|
||||
if (curcolor[i] == color[i]) // dont update if same colour
|
||||
continue;
|
||||
|
||||
G_SetPlayerGamepadIndicatorColor(i, color[i]);
|
||||
curcolor[i] = color[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// D_ProcessEvents
|
||||
// Send all the events of the given timestamp down the responder chain
|
||||
@@ -242,8 +270,9 @@ void D_ProcessEvents(void)
|
||||
// added comment : there is a wipe eatch change of the gamestate
|
||||
gamestate_t wipegamestate = GS_LEVEL;
|
||||
|
||||
static void D_Display(void)
|
||||
static boolean D_Display(void)
|
||||
{
|
||||
boolean ranwipe = false;
|
||||
boolean forcerefresh = false;
|
||||
static boolean wipe = false;
|
||||
INT32 wipedefindex = 0;
|
||||
@@ -252,7 +281,7 @@ static void D_Display(void)
|
||||
if (!dedicated)
|
||||
{
|
||||
if (nodrawers)
|
||||
return; // for comparative timing/profiling
|
||||
return false; // for comparative timing/profiling
|
||||
|
||||
// check for change of screen size (video mode)
|
||||
if (setmodeneeded && !wipe)
|
||||
@@ -262,7 +291,10 @@ static void D_Display(void)
|
||||
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
|
||||
|
||||
if (rendermode == render_soft && !splitscreen)
|
||||
{
|
||||
R_InterpolateViewRollAngle(rendertimefrac);
|
||||
R_CheckViewMorph();
|
||||
}
|
||||
|
||||
// change the view size if needed
|
||||
if (setsizeneeded)
|
||||
@@ -302,6 +334,7 @@ static void D_Display(void)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
||||
ranwipe = true;
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL && rendermode != render_none)
|
||||
@@ -315,12 +348,13 @@ static void D_Display(void)
|
||||
else //dedicated servers
|
||||
{
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
||||
ranwipe = true;
|
||||
wipegamestate = gamestate;
|
||||
}
|
||||
}
|
||||
|
||||
if (dedicated) //bail out after wipe logic
|
||||
return;
|
||||
return false;
|
||||
|
||||
// do buffered drawing
|
||||
switch (gamestate)
|
||||
@@ -427,7 +461,7 @@ static void D_Display(void)
|
||||
viewssnum = i;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
if (rendermode == render_opengl)
|
||||
HWR_RenderPlayerView(i, &players[displayplayers[i]]);
|
||||
else
|
||||
#endif
|
||||
@@ -477,13 +511,12 @@ static void D_Display(void)
|
||||
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (!splitscreen)
|
||||
R_ApplyViewMorph();
|
||||
if (!splitscreen)
|
||||
R_ApplyViewMorph();
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (postimgtype[i])
|
||||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
||||
V_DoPostProcessor(i, &players[displayplayers[i]], postimgparam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,7 +530,6 @@ static void D_Display(void)
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
usebuffer = true;
|
||||
}
|
||||
lastdraw = false;
|
||||
}
|
||||
@@ -531,7 +563,7 @@ static void D_Display(void)
|
||||
V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, V_SNAPTOTOP, patch);
|
||||
}
|
||||
|
||||
if (demo.rewinding)
|
||||
if (rendermode == render_soft && demo.rewinding)
|
||||
V_DrawFadeScreen(TC_RAINBOW, (leveltime & 0x20) ? SKINCOLOR_PASTEL : SKINCOLOR_MOONSLAM);
|
||||
|
||||
// vid size change is now finished if it was on...
|
||||
@@ -561,11 +593,10 @@ static void D_Display(void)
|
||||
{
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
||||
ranwipe = true;
|
||||
}
|
||||
}
|
||||
|
||||
NetUpdate(); // send out any new accumulation
|
||||
|
||||
// It's safe to end the game now.
|
||||
if (G_GetExitGameFlag())
|
||||
{
|
||||
@@ -610,6 +641,7 @@ static void D_Display(void)
|
||||
PS_STOP_TIMING(ps_swaptime);
|
||||
}
|
||||
|
||||
return ranwipe;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
@@ -617,7 +649,7 @@ static void D_Display(void)
|
||||
// =========================================================================
|
||||
|
||||
tic_t rendergametic;
|
||||
static int menuInputDelayTimer = 0;
|
||||
static SINT8 menuInputDelayTimer = 0;
|
||||
|
||||
void D_SRB2Loop(void)
|
||||
{
|
||||
@@ -627,6 +659,7 @@ void D_SRB2Loop(void)
|
||||
|
||||
boolean interp = false;
|
||||
boolean doDisplay = false;
|
||||
int frameskip = 0;
|
||||
|
||||
if (dedicated)
|
||||
server = true;
|
||||
@@ -671,6 +704,8 @@ void D_SRB2Loop(void)
|
||||
capbudget = (precise_t) budget;
|
||||
}
|
||||
|
||||
boolean ranwipe = false;
|
||||
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
|
||||
if (lastwipetic)
|
||||
@@ -703,9 +738,11 @@ void D_SRB2Loop(void)
|
||||
HW3S_BeginFrameUpdate();
|
||||
#endif
|
||||
|
||||
renderisnewtic = (realtics > 0 || singletics);
|
||||
|
||||
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||
|
||||
if (realtics > 0 || singletics)
|
||||
if (renderisnewtic)
|
||||
{
|
||||
// don't skip more than 10 frames at a time
|
||||
// (fadein / fadeout cause massive frame skip!)
|
||||
@@ -724,14 +761,52 @@ void D_SRB2Loop(void)
|
||||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
{
|
||||
// Lagless camera! Yay!
|
||||
if (cv_laglesscam.value && gamestate == GS_LEVEL && netgame)
|
||||
{
|
||||
// Evaluate the chase cam once for every local realtic
|
||||
// This might actually be better suited inside G_Ticker or TryRunTics
|
||||
for (tic_t chasecamtics = 0; chasecamtics < realtics; chasecamtics++)
|
||||
{
|
||||
P_RunChaseCameras();
|
||||
}
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
doDisplay = true;
|
||||
}
|
||||
|
||||
renderisnewtic = true;
|
||||
#define DPADSCROLLINPUT(INPUT)\
|
||||
{\
|
||||
myev.data1 = INPUT;\
|
||||
M_Responder(&myev);\
|
||||
}
|
||||
else
|
||||
{
|
||||
renderisnewtic = false;
|
||||
// this is absolutely awful and i hate it lmao
|
||||
if (menuactive && (DPADUPSCROLL || DPADDOWNSCROLL || DPADLEFTSCROLL || DPADRIGHTSCROLL))
|
||||
{
|
||||
event_t myev;
|
||||
myev.type = ev_keydown;
|
||||
|
||||
if (menuInputDelayTimer < 19)
|
||||
menuInputDelayTimer++;
|
||||
|
||||
if (menuInputDelayTimer == 19) // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt
|
||||
{
|
||||
if (DPADUPSCROLL)
|
||||
DPADSCROLLINPUT(KEY_UPARROW)
|
||||
else if (DPADDOWNSCROLL)
|
||||
DPADSCROLLINPUT(KEY_DOWNARROW)
|
||||
else if (DPADLEFTSCROLL)
|
||||
DPADSCROLLINPUT(KEY_LEFTARROW)
|
||||
else if (DPADRIGHTSCROLL)
|
||||
DPADSCROLLINPUT(KEY_RIGHTARROW)
|
||||
}
|
||||
}
|
||||
else
|
||||
menuInputDelayTimer = 0;
|
||||
#undef DPADSCROLLINPUT
|
||||
|
||||
D_DeviceLEDTick();
|
||||
}
|
||||
|
||||
if (interp)
|
||||
@@ -746,16 +821,19 @@ void D_SRB2Loop(void)
|
||||
{
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
||||
rendertimefrac_unpaused = g_time.timefrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
rendertimefrac = FRACUNIT;
|
||||
rendertimefrac_unpaused = FRACUNIT;
|
||||
}
|
||||
|
||||
if (interp || doDisplay)
|
||||
if ((interp || doDisplay) && !frameskip)
|
||||
{
|
||||
D_Display();
|
||||
ranwipe = D_Display();
|
||||
}
|
||||
|
||||
// Only take screenshots after drawing.
|
||||
@@ -780,46 +858,31 @@ void D_SRB2Loop(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
// this is absolutely awful and i hate it lmao
|
||||
if (menuactive && (DPADUPSCROLL || DPADDOWNSCROLL || DPADLEFTSCROLL || DPADRIGHTSCROLL))
|
||||
{
|
||||
event_t myev;
|
||||
myev.type = ev_keydown;
|
||||
|
||||
if (renderisnewtic)
|
||||
{
|
||||
menuInputDelayTimer++;
|
||||
|
||||
if (menuInputDelayTimer >= 19) // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt
|
||||
{
|
||||
if (DPADUPSCROLL)
|
||||
{
|
||||
myev.data1 = KEY_UPARROW;
|
||||
M_Responder(&myev);
|
||||
}
|
||||
else if (DPADDOWNSCROLL)
|
||||
{
|
||||
myev.data1 = KEY_DOWNARROW;
|
||||
M_Responder(&myev);
|
||||
}
|
||||
else if (DPADLEFTSCROLL)
|
||||
{
|
||||
myev.data1 = KEY_LEFTARROW;
|
||||
M_Responder(&myev);
|
||||
}
|
||||
else if (DPADRIGHTSCROLL)
|
||||
{
|
||||
myev.data1 = KEY_RIGHTARROW;
|
||||
M_Responder(&myev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
menuInputDelayTimer = 0;
|
||||
|
||||
// Fully completed frame made.
|
||||
finishprecise = I_GetPreciseTime();
|
||||
|
||||
// Use the time before sleep for frameskip calculations:
|
||||
// post-sleep time is literally being intentionally wasted
|
||||
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
|
||||
deltatics = deltasecs * NEWTICRATE;
|
||||
|
||||
// If time spent this game loop exceeds a single tic,
|
||||
// it's probably because of rendering.
|
||||
//
|
||||
// Skip rendering the next frame, up to a limit of 3
|
||||
// frames before a frame is rendered no matter what.
|
||||
//
|
||||
// Wipes run an inner loop and artificially increase
|
||||
// the measured time.
|
||||
if (!ranwipe && frameskip < 3 && deltatics > 1.0)
|
||||
{
|
||||
frameskip++;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameskip = 0;
|
||||
}
|
||||
|
||||
if (!singletics)
|
||||
{
|
||||
INT64 elapsed = (INT64)(finishprecise - enterprecise);
|
||||
@@ -945,7 +1008,7 @@ static INT32 D_DetectFileType(const char* filename)
|
||||
return 5;
|
||||
else if (!stricmp(&filename[strlen(filename) - 4], ".soc"))
|
||||
return 6;
|
||||
|
||||
|
||||
else if (!stricmp(&filename[strlen(filename) - 4], ".cfg"))
|
||||
return 7;
|
||||
else if (!stricmp(&filename[strlen(filename) - 4], ".txt"))
|
||||
@@ -969,12 +1032,12 @@ static void D_AutoloadFile(const char *file, char **filearray)
|
||||
if (!newfile)
|
||||
I_Error("No more free memory to AutoloadFile %s",file);
|
||||
|
||||
if (!fileType)
|
||||
if (!fileType)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile: File %s is unknown or invalid\n", file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
strcpy(newfile, file);
|
||||
|
||||
if (fileType <= 6)
|
||||
@@ -1004,8 +1067,7 @@ static void D_FindAddonsToAutoload(void)
|
||||
const char *autoloadpath;
|
||||
boolean postload;
|
||||
|
||||
INT32 i, len;
|
||||
boolean hasprefix = false;
|
||||
INT32 i;
|
||||
char wadsToAutoload[256] = "";
|
||||
|
||||
// does it exist tho
|
||||
@@ -1014,7 +1076,10 @@ static void D_FindAddonsToAutoload(void)
|
||||
|
||||
// If the file is found, run our shit
|
||||
if (!autoloadconfigfile) // nope outta here
|
||||
{
|
||||
wasautoloaded = postautoloaded = true; // so D_AddAutoloadFiles can skip everything since nothings there to autoload
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(wadsToAutoload, sizeof wadsToAutoload, autoloadconfigfile) != NULL)
|
||||
{
|
||||
@@ -1024,7 +1089,8 @@ static void D_FindAddonsToAutoload(void)
|
||||
|| (wadsToAutoload[0] == '#'))
|
||||
continue;
|
||||
// this marks it so that it loads after loading server addons
|
||||
else if (fastncmp(wadsToAutoload, "postload ", 9)) {
|
||||
else if (fastncmp(wadsToAutoload, "postload ", 9))
|
||||
{
|
||||
strremove(wadsToAutoload, "postload ");
|
||||
postload = true;
|
||||
}
|
||||
@@ -1036,34 +1102,10 @@ static void D_FindAddonsToAutoload(void)
|
||||
wadsToAutoload[i] = '\0';
|
||||
}
|
||||
|
||||
len = strlen(wadsToAutoload);
|
||||
hasprefix = false;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
if (!postload && W_CheckPostLoadList(wadsToAutoload))
|
||||
{
|
||||
if (wadsToAutoload[i] == '_')
|
||||
{
|
||||
hasprefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Lets just hope no one adds bonuschars in autoload
|
||||
if (hasprefix)
|
||||
{
|
||||
// We searching for c in prefix, which stands for "character" and doesn't work well with
|
||||
// autoload atm, only fine for postload
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
if (wadsToAutoload[i] == '_') break; // Prefix end
|
||||
|
||||
if (wadsToAutoload[i] == 'c' || wadsToAutoload[i] == 'C')
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "forcing postload for %s as local skin\n", wadsToAutoload);
|
||||
postload = true;
|
||||
break; // Found it
|
||||
}
|
||||
}
|
||||
CONS_Printf("forcing postload for file %s\n", wadsToAutoload);
|
||||
postload = true;
|
||||
}
|
||||
|
||||
// LOAD IT
|
||||
@@ -1081,6 +1123,32 @@ static void D_FindAddonsToAutoload(void)
|
||||
fclose(autoloadconfigfile);
|
||||
}
|
||||
|
||||
static void D_AddAutoloadFiles(void)
|
||||
{
|
||||
if (wasautoloaded)
|
||||
return;
|
||||
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfiles);
|
||||
|
||||
wasautoloaded = true;
|
||||
}
|
||||
|
||||
void D_AddPostloadFiles(void)
|
||||
{
|
||||
if (postautoloaded || !netgame)
|
||||
return;
|
||||
|
||||
CONS_Printf("D_AddPostloadFiles(): Loading postloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
|
||||
CONS_Printf("D_AddPostloadFiles(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfilespost);
|
||||
|
||||
postautoloaded = true;
|
||||
}
|
||||
|
||||
void D_CleanFile(char **filearray)
|
||||
{
|
||||
size_t pnumwadfiles;
|
||||
@@ -1186,13 +1254,13 @@ static void IdentifyVersion(void)
|
||||
D_AddFile(va(pandf,srb2waddir,"extra.kart"), startupwadfiles);
|
||||
found_extra_kart = true;
|
||||
}
|
||||
|
||||
|
||||
// completely optional 2: Back with a vengence
|
||||
if (FIL_ReadFileOK(va(pandf,srb2waddir,"extra2.kart"))) {
|
||||
D_AddFile(va(pandf,srb2waddir,"extra2.kart"), startupwadfiles);
|
||||
found_extra2_kart = true;
|
||||
}
|
||||
|
||||
|
||||
if (FIL_ReadFileOK(va(pandf,srb2waddir,"extra3.kart"))) {
|
||||
D_AddFile(va(pandf,srb2waddir,"extra3.kart"), startupwadfiles);
|
||||
found_extra3_kart = true;
|
||||
@@ -1495,7 +1563,7 @@ void D_SRB2Main(void)
|
||||
if (found_extra_kart || found_extra2_kart || found_extra3_kart) // found the funny, add it in!
|
||||
{
|
||||
// HAYA: These are seperated for a reason lmao
|
||||
if (found_extra_kart)
|
||||
if (found_extra_kart)
|
||||
mainwads++;
|
||||
if (found_extra2_kart)
|
||||
mainwads++;
|
||||
@@ -1523,7 +1591,7 @@ void D_SRB2Main(void)
|
||||
achi_speedo_clr = true;
|
||||
|
||||
// check for bigger lap count
|
||||
if (W_CheckMultipleLumps("K_STLAPB", "K_STLA2B", NULL))
|
||||
if (W_CheckMultipleLumps("K_STLAPB", "K_STLA2B", NULL))
|
||||
big_lap = true;
|
||||
|
||||
// now check for colour hud stuff
|
||||
@@ -1532,7 +1600,7 @@ void D_SRB2Main(void)
|
||||
clr_hud = true;
|
||||
|
||||
// check for bigger lap count but color** its color bitch
|
||||
if (W_CheckMultipleLumps("K_SCLAPB", "K_SCLA2B", NULL))
|
||||
if (W_CheckMultipleLumps("K_SCLAPB", "K_SCLA2B", NULL))
|
||||
big_lap_color = true;
|
||||
|
||||
// kartzspeedo
|
||||
@@ -1547,16 +1615,16 @@ void D_SRB2Main(void)
|
||||
|
||||
// stat display for extended player setup
|
||||
if (W_CheckMultipleLumps("K_STATNB", "K_STATN1", "K_STATN2", "K_STATN3", "K_STATN4", \
|
||||
"K_STATN5", "K_STATN6", NULL))
|
||||
"K_STATN5", "K_STATN6", NULL))
|
||||
statdp = true;
|
||||
|
||||
// Nametag stuffs
|
||||
if (W_CheckMultipleLumps("NTLINE", "NTLINEV", "NTSP", "NTWH", NULL))
|
||||
if (W_CheckMultipleLumps("NTLINE", "NTLINEV", "NTSP", "NTWH", NULL))
|
||||
nametaggfx = true;
|
||||
|
||||
if (W_CheckMultipleLumps("K_DGAU","K_DCAU","K_DGSU","K_DCSU", NULL))
|
||||
if (W_CheckMultipleLumps("K_DGAU","K_DCAU","K_DGSU","K_DCSU", NULL))
|
||||
driftgaugegfx = true;
|
||||
|
||||
|
||||
if (found_extra3_kart)
|
||||
{
|
||||
// 80x11 speedometer crap
|
||||
@@ -1569,11 +1637,15 @@ void D_SRB2Main(void)
|
||||
if (W_LumpExists("SC_SM3TC"))
|
||||
xtra_speedo_clr3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef PUSHSPEEDO
|
||||
memcpy(speedo_cons_t, speedo_cons_temp, sizeof(speedo_cons_t));
|
||||
|
||||
// Do it before P_InitMapData because PNG patch
|
||||
// conversion sometimes needs the palette
|
||||
V_ReloadPalette();
|
||||
|
||||
//
|
||||
// search for maps
|
||||
//
|
||||
@@ -1683,6 +1755,8 @@ void D_SRB2Main(void)
|
||||
|
||||
savedata.lives = 0; // flag this as not-used
|
||||
|
||||
loaded_config = true; // so pallettechange doesent get called 500 times at startup lol
|
||||
|
||||
//------------------------------------------------ COMMAND LINE PARAMS
|
||||
|
||||
// this must be done after loading gamedata,
|
||||
@@ -1767,10 +1841,7 @@ void D_SRB2Main(void)
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfiles);
|
||||
D_AddAutoloadFiles();
|
||||
|
||||
// Set up splitscreen players before joining!
|
||||
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
|
||||
@@ -1973,10 +2044,9 @@ void D_SRB2Main(void)
|
||||
|
||||
if (dedicated && server)
|
||||
{
|
||||
pagename = "TITLESKY";
|
||||
levelstarttic = gametic;
|
||||
G_SetGamestate(GS_LEVEL);
|
||||
if (!P_SetupLevel(false))
|
||||
if (!P_SetupLevel(false, false))
|
||||
I_Quit(); // fail so reset game stuff
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -20,6 +20,8 @@
|
||||
// make sure not to write back the config until it's been correctly loaded
|
||||
extern tic_t rendergametic;
|
||||
|
||||
extern boolean loaded_config;
|
||||
|
||||
extern char srb2home[256]; //Alam: My Home
|
||||
extern boolean usehome; //Alam: which path?
|
||||
extern const char *pandf; //Alam: how to path?
|
||||
@@ -43,12 +45,15 @@ extern boolean statdp; // stat display for extended player setup
|
||||
extern boolean nametaggfx; // Nametag stuffs
|
||||
extern boolean driftgaugegfx;
|
||||
|
||||
|
||||
// autoload stuff
|
||||
extern boolean autoloading;
|
||||
extern boolean autoloaded;
|
||||
extern boolean postautoloaded;
|
||||
|
||||
void D_AddPostloadFiles(void);
|
||||
|
||||
extern char *autoloadwadfilespost[MAX_WADFILES];
|
||||
extern char *autoloadwadfiles[MAX_WADFILES];
|
||||
|
||||
// the infinite loop of D_SRB2Loop() called from win_main for windows version
|
||||
void D_SRB2Loop(void) FUNCNORETURN;
|
||||
|
||||
+26
-33
@@ -64,9 +64,6 @@ static doomdata_t reboundstore[MAXREBOUND];
|
||||
static INT16 reboundsize[MAXREBOUND];
|
||||
static INT32 rebound_head, rebound_tail;
|
||||
|
||||
/// \brief bandwith of netgame
|
||||
INT32 net_bandwidth;
|
||||
|
||||
/// \brief max length per packet
|
||||
INT16 hardware_MAXPACKETLENGTH;
|
||||
|
||||
@@ -793,7 +790,7 @@ static void fprintfstringnewline(char *s, size_t len)
|
||||
}
|
||||
|
||||
/// \warning Keep this up-to-date if you add/remove/rename packet types
|
||||
static const char *packettypename[NUMPACKETTYPE] =
|
||||
const char *packettypename[NUMPACKETTYPE] =
|
||||
{
|
||||
"NOTHING",
|
||||
"SERVERCFG",
|
||||
@@ -836,13 +833,31 @@ static const char *packettypename[NUMPACKETTYPE] =
|
||||
"MOREFILESNEEDED",
|
||||
|
||||
"PING"
|
||||
#ifdef SATURNSYNCH
|
||||
,
|
||||
|
||||
"WILLRESENDGAMESTATE",
|
||||
"CANRECEIVEGAMESTATE",
|
||||
"RECEIVEDGAMESTATE",
|
||||
|
||||
// we will reserve this for now even if unused, so order wont get mangled
|
||||
"ISSATURN"
|
||||
#endif
|
||||
};
|
||||
|
||||
const char *Net_GetPacketName(UINT8 packettype)
|
||||
{
|
||||
if (packettype >= NUMPACKETTYPE)
|
||||
return "UNKNOWN";
|
||||
|
||||
return packettypename[packettype];
|
||||
}
|
||||
|
||||
static void DebugPrintpacket(const char *header)
|
||||
{
|
||||
fprintf(debugfile, "%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n",
|
||||
header, doomcom->remotenode, netbuffer->ack, netbuffer->ackreturn, doomcom->datalength,
|
||||
netbuffer->packettype, packettypename[netbuffer->packettype]);
|
||||
netbuffer->packettype, Net_GetPacketName(netbuffer->packettype));
|
||||
|
||||
switch (netbuffer->packettype)
|
||||
{
|
||||
@@ -1208,7 +1223,7 @@ boolean HGetPacket(void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif // ndef NONET
|
||||
#endif // ifndef NONET
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1258,10 +1273,7 @@ void D_SetDoomcom(void)
|
||||
{
|
||||
if (doomcom) return;
|
||||
doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL);
|
||||
doomcom->id = DOOMCOM_ID;
|
||||
doomcom->numslots = doomcom->numnodes = 1;
|
||||
doomcom->gametype = 0;
|
||||
doomcom->consoleplayer = 0;
|
||||
doomcom->extratics = 0;
|
||||
}
|
||||
|
||||
@@ -1286,7 +1298,6 @@ boolean D_CheckNetGame(void)
|
||||
I_NetMakeNodewPort = NULL;
|
||||
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
net_bandwidth = 30000;
|
||||
// I_InitNetwork sets doomcom and netgame
|
||||
// check and initialize the network driver
|
||||
multiplayer = false;
|
||||
@@ -1306,7 +1317,6 @@ boolean D_CheckNetGame(void)
|
||||
server = true; // WTF? server always true???
|
||||
// no! The deault mode is server. Client is set elsewhere
|
||||
// when the client executes connect command.
|
||||
doomcom->ticdup = 1;
|
||||
|
||||
if (M_CheckParm("-extratic"))
|
||||
{
|
||||
@@ -1317,21 +1327,6 @@ boolean D_CheckNetGame(void)
|
||||
CONS_Printf(M_GetText("Set extratics to %d\n"), doomcom->extratics);
|
||||
}
|
||||
|
||||
if (M_CheckParm("-bandwidth"))
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
{
|
||||
net_bandwidth = atoi(M_GetNextParm());
|
||||
if (net_bandwidth < 1000)
|
||||
net_bandwidth = 1000;
|
||||
if (net_bandwidth > 100000)
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
CONS_Printf(M_GetText("Network bandwidth set to %d\n"), net_bandwidth);
|
||||
}
|
||||
else
|
||||
I_Error("usage: -bandwidth <byte_per_sec>");
|
||||
}
|
||||
|
||||
software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH;
|
||||
if (M_CheckParm("-packetsize"))
|
||||
{
|
||||
@@ -1351,8 +1346,6 @@ boolean D_CheckNetGame(void)
|
||||
if (netgame)
|
||||
multiplayer = true;
|
||||
|
||||
if (doomcom->id != DOOMCOM_ID)
|
||||
I_Error("Doomcom buffer invalid!");
|
||||
if (doomcom->numnodes > MAXNETNODES)
|
||||
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
|
||||
|
||||
@@ -1365,7 +1358,7 @@ boolean D_CheckNetGame(void)
|
||||
if (M_CheckParm("-debugfile"))
|
||||
{
|
||||
char filename[21];
|
||||
INT32 k = doomcom->consoleplayer - 1;
|
||||
INT32 k = consoleplayer - 1;
|
||||
if (M_IsNextParm())
|
||||
k = atoi(M_GetNextParm()) - 1;
|
||||
while (!debugfile && k < MAXPLAYERS)
|
||||
@@ -1453,13 +1446,13 @@ void Command_Ping_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (f_width < 10) f_width = 1;
|
||||
if (f_width < 10) f_width = 1;
|
||||
else if (f_width < 100) f_width = 2;
|
||||
else f_width = 3;
|
||||
else f_width = 3;
|
||||
|
||||
if (ms_width < 10) ms_width = 1;
|
||||
if (ms_width < 10) ms_width = 1;
|
||||
else if (ms_width < 100) ms_width = 2;
|
||||
else ms_width = 3;
|
||||
else ms_width = 3;
|
||||
|
||||
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
|
||||
|
||||
|
||||
@@ -65,5 +65,6 @@ void Net_ConnectionTimeout(INT32 node);
|
||||
void Net_AbortPacketType(UINT8 packettype);
|
||||
void Net_SendAcks(INT32 node);
|
||||
void Net_WaitAllAckReceived(UINT32 timeout);
|
||||
const char *Net_GetPacketName(UINT8 packettype);
|
||||
|
||||
#endif
|
||||
+130
-29
@@ -299,6 +299,9 @@ consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t,
|
||||
//WTF
|
||||
consvar_t cv_mouseturn = {"mouseturn", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Lagless camera! Yay!
|
||||
consvar_t cv_laglesscam = {"laglesscamera", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#if defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2
|
||||
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -394,6 +397,7 @@ static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometer
|
||||
consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
|
||||
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
||||
consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_karthitemdialog = {"karthitemdialog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -489,6 +493,8 @@ consvar_t cv_showlapemblem = {"showlapemblem", "On", CV_SAVE, CV_OnOff, NULL, 0,
|
||||
|
||||
consvar_t cv_showviewpointtext = {"showviewpointtext", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_showdownloadprompt = {"showdownloadprompt", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Intermission time Tails 04-19-2002
|
||||
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -561,6 +567,10 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
|
||||
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
|
||||
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_director = {"director", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebugdirector = {"debugdirector", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showdirectorhud = {"showdirectorhud", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_showtrackaddon = {"showtrackaddon", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t skinselectmenu_t[] = {{SKINMENUTYPE_SCROLL, "Scroll"}, {SKINMENUTYPE_2D, "2d"}, {SKINMENUTYPE_GRID, "Grid"}, {SKINMENUTYPE_EXTENDED, "Extended"}, {0, NULL}};
|
||||
@@ -577,7 +587,8 @@ static CV_PossibleValue_t skinselectgridsort_t[] ={
|
||||
};
|
||||
consvar_t cv_skinselectgridsort ={ "skinselectgridsort", "Real name", CV_SAVE|CV_CALL|CV_NOINIT, skinselectgridsort_t, sortSkinGrid, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
||||
consvar_t cv_betainterscreen = {"betaintermissionscreen", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t betainterscreen_t[] = {{0, "Off"}, {1, "On"}, {2, "NoBG"}, {0, NULL}};
|
||||
consvar_t cv_betainterscreen = {"betaintermissionscreen", "Off", CV_SAVE, betainterscreen_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT16 gametype = GT_RACE; // SRB2kart
|
||||
boolean forceresetplayers = false;
|
||||
@@ -779,6 +790,10 @@ void D_RegisterServerCommands(void)
|
||||
// d_clisrv
|
||||
CV_RegisterVar(&cv_maxplayers);
|
||||
CV_RegisterVar(&cv_resynchattempts);
|
||||
#ifdef SATURNSYNCH
|
||||
CV_RegisterVar(&cv_gamestateattempts);
|
||||
CV_RegisterVar(&cv_resynchcooldown);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_maxsend);
|
||||
CV_RegisterVar(&cv_noticedownload);
|
||||
CV_RegisterVar(&cv_downloadspeed);
|
||||
@@ -786,6 +801,9 @@ void D_RegisterServerCommands(void)
|
||||
CV_RegisterVar(&cv_httpsource);
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_allownewplayer);
|
||||
#ifdef SATURNJOIN
|
||||
CV_RegisterVar(&cv_allownewsaturnplayer);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_joinrefusemessage);
|
||||
CV_RegisterVar(&cv_chatlogsize);
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
@@ -823,9 +841,9 @@ void D_RegisterServerCommands(void)
|
||||
CV_RegisterVar(&cv_recordmultiplayerdemos);
|
||||
CV_RegisterVar(&cv_netdemosyncquality);
|
||||
CV_RegisterVar(&cv_maxdemosize);
|
||||
CV_RegisterVar(&cv_demochangemap);
|
||||
|
||||
CV_RegisterVar(&cv_keyboardlayout);
|
||||
|
||||
CV_RegisterVar(&cv_betainterscreen);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
@@ -960,7 +978,6 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_audbuffersize);
|
||||
|
||||
// m_menu.c
|
||||
//CV_RegisterVar(&cv_compactscoreboard);
|
||||
CV_RegisterVar(&cv_chatheight);
|
||||
CV_RegisterVar(&cv_chatwidth);
|
||||
CV_RegisterVar(&cv_chattime);
|
||||
@@ -978,6 +995,11 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_showtrackaddon);
|
||||
CV_RegisterVar(&cv_showviewpointtext);
|
||||
CV_RegisterVar(&cv_showdownloadprompt);
|
||||
|
||||
CV_RegisterVar(&cv_director);
|
||||
CV_RegisterVar(&cv_kartdebugdirector);
|
||||
CV_RegisterVar(&cv_showdirectorhud);
|
||||
|
||||
CV_RegisterVar(&cv_luaimmersion);
|
||||
CV_RegisterVar(&cv_fakelocalskin);
|
||||
@@ -992,6 +1014,7 @@ void D_RegisterClientCommands(void)
|
||||
//CV_RegisterVar(&cv_alwaysfreelook2);
|
||||
//CV_RegisterVar(&cv_chasefreelook);
|
||||
//CV_RegisterVar(&cv_chasefreelook2);
|
||||
CV_RegisterVar(&cv_replaysearchrate);
|
||||
CV_RegisterVar(&cv_showfocuslost);
|
||||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
@@ -1066,6 +1089,13 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_controlperkey);
|
||||
CV_RegisterVar(&cv_turnsmooth);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
CV_RegisterVar(&cv_rumble[i]);
|
||||
CV_RegisterVar(&cv_gamepadled[i]);
|
||||
CV_RegisterVar(&cv_ledpowerup[i]);
|
||||
}
|
||||
|
||||
CV_RegisterVar(&cv_usemouse);
|
||||
CV_RegisterVar(&cv_usemouse2);
|
||||
CV_RegisterVar(&cv_invertmouse);
|
||||
@@ -1158,32 +1188,26 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_showmusicfilename);
|
||||
|
||||
CV_RegisterVar(&cv_betainterscreen);
|
||||
|
||||
CV_RegisterVar(&cv_laglesscam);
|
||||
|
||||
// ingame object placing
|
||||
COM_AddCommand("objectplace", Command_ObjectPlace_f);
|
||||
COM_AddCommand("writethings", Command_Writethings_f);
|
||||
CV_RegisterVar(&cv_speed);
|
||||
CV_RegisterVar(&cv_opflags);
|
||||
CV_RegisterVar(&cv_mapthingnum);
|
||||
//CV_RegisterVar(&cv_grid);
|
||||
//CV_RegisterVar(&cv_snapto);
|
||||
|
||||
// add cheat commands
|
||||
COM_AddCommand("noclip", Command_CheatNoClip_f);
|
||||
COM_AddCommand("god", Command_CheatGod_f);
|
||||
COM_AddCommand("notarget", Command_CheatNoTarget_f);
|
||||
/*COM_AddCommand("getallemeralds", Command_Getallemeralds_f);
|
||||
COM_AddCommand("resetemeralds", Command_Resetemeralds_f);
|
||||
COM_AddCommand("setrings", Command_Setrings_f);
|
||||
COM_AddCommand("setlives", Command_Setlives_f);
|
||||
COM_AddCommand("setcontinues", Command_Setcontinues_f);*/
|
||||
COM_AddCommand("devmode", Command_Devmode_f);
|
||||
COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f);
|
||||
COM_AddCommand("scale", Command_Scale_f);
|
||||
COM_AddCommand("gravflip", Command_Gravflip_f);
|
||||
COM_AddCommand("hurtme", Command_Hurtme_f);
|
||||
/*COM_AddCommand("jumptoaxis", Command_JumpToAxis_f);
|
||||
COM_AddCommand("charability", Command_Charability_f);
|
||||
COM_AddCommand("charspeed", Command_Charspeed_f);*/
|
||||
COM_AddCommand("teleport", Command_Teleport_f);
|
||||
COM_AddCommand("rteleport", Command_RTeleport_f);
|
||||
COM_AddCommand("skynum", Command_Skynum_f);
|
||||
@@ -1215,19 +1239,69 @@ void D_RegisterClientCommands(void)
|
||||
*/
|
||||
static void Skin_FindRealNameSkin(consvar_t *cvar)
|
||||
{
|
||||
// Not the best way to implements this but it will do.
|
||||
INT32 matches[MAXSKINS] = {0}; // Skin numbers of matching skins
|
||||
INT32 matches_pos[MAXSKINS] = {0}; // Index of matching substring
|
||||
INT32 nummatches = 0;
|
||||
|
||||
int i;
|
||||
INT32 i;
|
||||
const char *value = cvar->string;
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
if (strncmp(value, skins[i].realname, sizeof skins[i].realname) == 0)
|
||||
{
|
||||
// Change the cvar to be the value of the name.
|
||||
CV_StealthSet(cvar, skins[i].name);
|
||||
// Perfect match with some skin name, no need to find matching realname
|
||||
if (strncasecmp(value, skins[i].name, sizeof skins[i].name) == 0)
|
||||
return;
|
||||
|
||||
const char *match = strcasestr(skins[i].realname, value);
|
||||
if (match != NULL)
|
||||
{
|
||||
matches[nummatches] = i;
|
||||
matches_pos[nummatches] = match - skins[i].realname;
|
||||
++nummatches;
|
||||
}
|
||||
}
|
||||
|
||||
if (nummatches == 1)
|
||||
{
|
||||
// Change the cvar to be the value of the name.
|
||||
CV_StealthSet(cvar, skins[matches[0]].name);
|
||||
}
|
||||
else if (nummatches > 1)
|
||||
{
|
||||
size_t query_length = strlen(value);
|
||||
|
||||
char start[SKINNAMESIZE+1] = {0}; // Start of name, printed with normal color
|
||||
char match[SKINNAMESIZE+1] = {0}; // Matching part of name, highlighted in red
|
||||
const char *end = NULL; // End of the name, printed with normal color. Can be just a pointer into realname part
|
||||
|
||||
CONS_Printf("\x86Multiple matches found:\n");
|
||||
|
||||
for (i = 0; i < nummatches; ++i)
|
||||
{
|
||||
const char *realname = skins[matches[i]].realname;
|
||||
|
||||
if (matches_pos[i] == 0)
|
||||
start[0] = 0;
|
||||
else
|
||||
{
|
||||
memcpy(start, realname, matches_pos[i]);
|
||||
start[matches_pos[i]] = 0;
|
||||
}
|
||||
|
||||
memcpy(match, realname+matches_pos[i], query_length);
|
||||
match[matches_pos[i] + query_length] = 0;
|
||||
|
||||
end = realname + matches_pos[i] + query_length;
|
||||
|
||||
CONS_Printf("%s\x85%s\x80%s (%s)\n", start, match, end, skins[matches[i]].name);
|
||||
}
|
||||
|
||||
CONS_Printf("\x86Try be more specific\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("\x86Skin not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1654,8 +1728,9 @@ static void SendNameAndColor(void)
|
||||
cv_skin.value = R_SkinAvailable(cv_skin.string);
|
||||
if (cv_skin.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin, DEFAULTSKIN);
|
||||
cv_skin.value = 0;
|
||||
INT32 skinnum = players[consoleplayer].skin;
|
||||
CV_StealthSet(&cv_skin, skins[skinnum].name);
|
||||
cv_skin.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -1783,8 +1858,9 @@ static void SendNameAndColor2(void)
|
||||
cv_skin2.value = R_SkinAvailable(cv_skin2.string);
|
||||
if (cv_skin2.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin2, DEFAULTSKIN);
|
||||
cv_skin2.value = 0;
|
||||
INT32 skinnum = players[displayplayers[1]].skin;
|
||||
CV_StealthSet(&cv_skin2, skins[skinnum].name);
|
||||
cv_skin2.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -1903,8 +1979,9 @@ static void SendNameAndColor3(void)
|
||||
cv_skin3.value = R_SkinAvailable(cv_skin3.string);
|
||||
if (cv_skin3.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin3, DEFAULTSKIN);
|
||||
cv_skin3.value = 0;
|
||||
INT32 skinnum = players[displayplayers[2]].skin;
|
||||
CV_StealthSet(&cv_skin3, skins[skinnum].name);
|
||||
cv_skin3.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -2031,8 +2108,9 @@ static void SendNameAndColor4(void)
|
||||
cv_skin4.value = R_SkinAvailable(cv_skin4.string);
|
||||
if (cv_skin4.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin4, DEFAULTSKIN);
|
||||
cv_skin4.value = 0;
|
||||
INT32 skinnum = players[displayplayers[3]].skin;
|
||||
CV_StealthSet(&cv_skin4, skins[skinnum].name);
|
||||
cv_skin4.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -2905,6 +2983,14 @@ static void Command_Map_f(void)
|
||||
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
|
||||
else
|
||||
{
|
||||
if (!mapheaderinfo[newmapnum-1] || mapheaderinfo[newmapnum-1] == NULL)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Invalid mapheaderinfo for Course %s (%s)\n"), realmapname, G_BuildMapName(newmapnum));
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Course %s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
|
||||
@@ -2937,6 +3023,10 @@ static void Command_Map_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
// spend atleast 35 seconds in one map
|
||||
if (cv_demochangemap.value && demo.recording && demo.savemode != DSM_NOTSAVING && (timeinmap > 1463) && ((cv_demochangemap.value == 2 && newmapnum == gamemap) || newmapnum != gamemap))
|
||||
G_SaveDemo();
|
||||
|
||||
fromlevelselect = false;
|
||||
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, false);
|
||||
|
||||
@@ -3127,6 +3217,8 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
|
||||
else
|
||||
S_ResumeAudio();
|
||||
}
|
||||
|
||||
G_ResetAllDeviceRumbles();
|
||||
}
|
||||
|
||||
static void Command_ReplayMarker(void)
|
||||
@@ -3144,7 +3236,10 @@ static void Command_ReplayMarker(void)
|
||||
demo.savemode = DSM_WILLAUTOSAVE;
|
||||
if (adjustedleveltime < 0)
|
||||
adjustedleveltime = 0;
|
||||
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", G_BuildMapTitle(gamemap), G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
|
||||
char *title = G_BuildMapTitle(gamemap);
|
||||
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
|
||||
if (title)
|
||||
Z_Free(title);
|
||||
CONS_Printf("Replay will be saved!\n");
|
||||
}
|
||||
}
|
||||
@@ -5665,6 +5760,12 @@ void Command_ExitGame_f(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (dedicated)
|
||||
{
|
||||
CONS_Printf("This command cannot be used on dedicated server\n");
|
||||
return;
|
||||
}
|
||||
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
CV_ClearChangedFlags();
|
||||
|
||||
@@ -128,6 +128,7 @@ extern consvar_t cv_kartvoterulechanges;
|
||||
extern consvar_t cv_kartgametypepreference;
|
||||
extern consvar_t cv_kartspeedometer;
|
||||
extern consvar_t cv_kartvoices;
|
||||
extern consvar_t cv_karthitemdialog;
|
||||
|
||||
extern consvar_t cv_karteliminatelast;
|
||||
|
||||
@@ -165,6 +166,7 @@ extern consvar_t cv_minihead;
|
||||
extern consvar_t cv_showlapemblem;
|
||||
|
||||
extern consvar_t cv_showviewpointtext;
|
||||
extern consvar_t cv_showdownloadprompt;
|
||||
extern consvar_t cv_luaimmersion;
|
||||
extern consvar_t cv_fakelocalskin;
|
||||
extern consvar_t cv_showlocalskinmenus;
|
||||
@@ -201,12 +203,16 @@ extern consvar_t cv_ps_thinkframe_page;
|
||||
extern consvar_t cv_ps_samplesize;
|
||||
extern consvar_t cv_ps_descriptor;
|
||||
|
||||
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
|
||||
|
||||
extern consvar_t cv_showtrackaddon;
|
||||
|
||||
extern consvar_t cv_showspecstuff;
|
||||
|
||||
extern consvar_t cv_betainterscreen;
|
||||
|
||||
extern consvar_t cv_laglesscam;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SKINMENUTYPE_SCROLL = 0,
|
||||
|
||||
+36
-8
@@ -65,10 +65,10 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
||||
#ifdef HAVE_CURL
|
||||
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 35, 0)
|
||||
int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
|
||||
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
|
||||
#define XFERINFOFUNCTION
|
||||
#else
|
||||
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
|
||||
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -833,7 +833,6 @@ void SV_FileSendTicker(void)
|
||||
|
||||
netbuffer->packettype = PT_FILEFRAGMENT;
|
||||
|
||||
// (((sendbytes-nowsentbyte)*TICRATE)/(I_GetTime()-starttime)<(UINT32)net_bandwidth)
|
||||
while (packetsent-- && filestosend != 0)
|
||||
{
|
||||
for (i = currentnode, j = 0; j < MAXNETNODES;
|
||||
@@ -1204,25 +1203,53 @@ size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
}
|
||||
|
||||
#ifdef XFERINFOFUNCTION
|
||||
int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
|
||||
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
|
||||
{
|
||||
time_t curtime;
|
||||
|
||||
(void)clientp;
|
||||
(void)ultotal;
|
||||
(void)ulnow; // Function prototype requires these but we won't use, so just discard
|
||||
|
||||
curtime = time(NULL);
|
||||
|
||||
curl_dlnow = dlnow;
|
||||
curl_dltotal = dltotal;
|
||||
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
|
||||
|
||||
if (curtime > curl_starttime)
|
||||
{
|
||||
getbytes = curl_dlnow / (curtime - curl_starttime); // To-do: Make this more accurate???
|
||||
}
|
||||
else
|
||||
{
|
||||
getbytes = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
|
||||
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
|
||||
{
|
||||
time_t curtime;
|
||||
|
||||
(void)clientp;
|
||||
(void)ultotal;
|
||||
(void)ulnow; // Function prototype requires these but we won't use, so just discard
|
||||
|
||||
curtime = time(NULL);
|
||||
|
||||
curl_dlnow = dlnow;
|
||||
curl_dltotal = dltotal;
|
||||
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
|
||||
|
||||
if (curtime > curl_starttime)
|
||||
{
|
||||
getbytes = curl_dlnow / (curtime - curl_starttime); // To-do: Make this more accurate???
|
||||
}
|
||||
else
|
||||
{
|
||||
getbytes = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1300,8 +1327,9 @@ void CURLPrepareFile(const char* url, int dfilenum)
|
||||
curl_starttime = time(NULL);
|
||||
|
||||
curl_running = true;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-5
@@ -347,6 +347,14 @@ typedef enum
|
||||
RW_RAIL = 32
|
||||
} ringweapons_t;
|
||||
|
||||
// enum for saved lap times
|
||||
typedef enum
|
||||
{
|
||||
LAP_CUR,
|
||||
LAP_LAST,
|
||||
LAP__MAX
|
||||
} laptime_e;
|
||||
|
||||
// ========================================================================
|
||||
// PLAYER STRUCTURE
|
||||
// ========================================================================
|
||||
@@ -405,6 +413,8 @@ typedef struct player_s
|
||||
// See pflags_t, above.
|
||||
pflags_t pflags;
|
||||
|
||||
UINT16 postimgflags;
|
||||
|
||||
// playing animation.
|
||||
panim_t panim;
|
||||
|
||||
@@ -465,6 +475,7 @@ typedef struct player_s
|
||||
INT16 numboxes; // Number of item boxes obtained for Race Mode
|
||||
INT16 totalring; // Total number of rings obtained for Race Mode
|
||||
tic_t realtime; // integer replacement for leveltime
|
||||
tic_t laptime[LAP__MAX];
|
||||
UINT8 laps; // Number of laps (optional)
|
||||
|
||||
////////////////////
|
||||
@@ -537,15 +548,13 @@ typedef struct player_s
|
||||
tic_t grieftime;
|
||||
UINT8 griefstrikes;
|
||||
|
||||
tic_t hitemtimer;
|
||||
UINT8 hitemvictim;
|
||||
|
||||
UINT8 splitscreenindex;
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
||||
struct {
|
||||
angle_t aiming, awayviewaiming, frameangle;
|
||||
angle_t viewrollangle;
|
||||
} lerp;
|
||||
} player_t;
|
||||
|
||||
#endif
|
||||
+28
-163
@@ -291,8 +291,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
INT32 i;
|
||||
boolean slotfound = false;
|
||||
|
||||
DEH_WriteUndoline("PLAYERTEXT", description[num].notes, UNDO_ENDTEXT);
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
@@ -362,7 +360,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
|
||||
PlayerMenu[num].status = IT_CALL;
|
||||
strncpy(description[num].picname, word2, 8);
|
||||
}
|
||||
@@ -386,7 +383,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
*/
|
||||
if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE);
|
||||
PlayerMenu[num].status = (INT16)i;
|
||||
}
|
||||
else if (fastcmp(word, "SKINNAME"))
|
||||
@@ -394,7 +390,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
// Send to free slot.
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
|
||||
PlayerMenu[num].status = IT_CALL;
|
||||
|
||||
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
|
||||
@@ -557,122 +552,98 @@ static void readthing(MYFILE *f, INT32 num)
|
||||
|
||||
if (fastcmp(word, "MAPTHINGNUM") || fastcmp(word, "DOOMEDNUM"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].doomednum), UNDO_NONE);
|
||||
mobjinfo[num].doomednum = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPAWNSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].spawnstate), UNDO_NONE);
|
||||
mobjinfo[num].spawnstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPAWNHEALTH"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].spawnhealth), UNDO_NONE);
|
||||
mobjinfo[num].spawnhealth = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SEESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].seestate), UNDO_NONE);
|
||||
mobjinfo[num].seestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SEESOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].seesound), UNDO_NONE);
|
||||
mobjinfo[num].seesound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "REACTIONTIME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].reactiontime), UNDO_NONE);
|
||||
mobjinfo[num].reactiontime = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ATTACKSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].attacksound), UNDO_NONE);
|
||||
mobjinfo[num].attacksound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "PAINSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].painstate), UNDO_NONE);
|
||||
mobjinfo[num].painstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "PAINCHANCE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].painchance), UNDO_NONE);
|
||||
mobjinfo[num].painchance = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "PAINSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].painsound), UNDO_NONE);
|
||||
mobjinfo[num].painsound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MELEESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].meleestate), UNDO_NONE);
|
||||
mobjinfo[num].meleestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MISSILESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].missilestate), UNDO_NONE);
|
||||
mobjinfo[num].missilestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEATHSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].deathstate), UNDO_NONE);
|
||||
mobjinfo[num].deathstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEATHSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].deathsound), UNDO_NONE);
|
||||
mobjinfo[num].deathsound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "XDEATHSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].xdeathstate), UNDO_NONE);
|
||||
mobjinfo[num].xdeathstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPEED"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].speed), UNDO_NONE);
|
||||
mobjinfo[num].speed = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "RADIUS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].radius), UNDO_NONE);
|
||||
mobjinfo[num].radius = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HEIGHT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].height), UNDO_NONE);
|
||||
mobjinfo[num].height = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DISPOFFSET"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].dispoffset), UNDO_NONE);
|
||||
mobjinfo[num].dispoffset = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MASS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].mass), UNDO_NONE);
|
||||
mobjinfo[num].mass = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DAMAGE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].damage), UNDO_NONE);
|
||||
mobjinfo[num].damage = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ACTIVESOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].activesound), UNDO_NONE);
|
||||
mobjinfo[num].activesound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "FLAGS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].flags), UNDO_NONE);
|
||||
mobjinfo[num].flags = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "RAISESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].raisestate), UNDO_NONE);
|
||||
mobjinfo[num].raisestate = get_number(word2);
|
||||
}
|
||||
else
|
||||
@@ -1110,8 +1081,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
UINT16 usi;
|
||||
UINT8 picid;
|
||||
|
||||
DEH_WriteUndoline("SCENETEXT", cutscenes[num]->scene[scenenum].text, UNDO_ENDTEXT);
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
@@ -1188,7 +1157,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
|
||||
if (fastcmp(word, "NUMBEROFPICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", cutscenes[num]->scene[scenenum].numpics), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].numpics = (UINT8)i;
|
||||
}
|
||||
else if (fastncmp(word, "PIC", 3))
|
||||
@@ -1203,27 +1171,22 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
|
||||
if (fastcmp(word+4, "NAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].picname[picid], UNDO_NONE);
|
||||
strncpy(cutscenes[num]->scene[scenenum].picname[picid], word2, 8);
|
||||
}
|
||||
else if (fastcmp(word+4, "HIRES"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", cutscenes[num]->scene[scenenum].pichires[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].pichires[picid] = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word+4, "DURATION"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].picduration[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].picduration[picid] = usi;
|
||||
}
|
||||
else if (fastcmp(word+4, "XCOORD"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].xcoord[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].xcoord[picid] = usi;
|
||||
}
|
||||
else if (fastcmp(word+4, "YCOORD"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].ycoord[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].ycoord[picid] = usi;
|
||||
}
|
||||
else
|
||||
@@ -1231,14 +1194,12 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
}
|
||||
else if (fastcmp(word, "MUSIC"))
|
||||
{
|
||||
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE);
|
||||
strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7);
|
||||
cutscenes[num]->scene[scenenum].musswitch[6] = 0;
|
||||
}
|
||||
#ifdef MUSICSLOT_COMPATIBILITY
|
||||
else if (fastcmp(word, "MUSICSLOT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE);
|
||||
i = get_mus(word2, true);
|
||||
if (i && i <= 1035)
|
||||
snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i));
|
||||
@@ -1251,42 +1212,34 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
#endif
|
||||
else if (fastcmp(word, "MUSICTRACK"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
|
||||
}
|
||||
else if (fastcmp(word, "MUSICPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchposition), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musswitchposition = (UINT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MUSICLOOP"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicloop), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "TEXTXPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].textxpos), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].textxpos = usi;
|
||||
}
|
||||
else if (fastcmp(word, "TEXTYPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].textypos), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].textypos = usi;
|
||||
}
|
||||
else if (fastcmp(word, "FADEINID"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].fadeinid = (UINT8)i;
|
||||
}
|
||||
else if (fastcmp(word, "FADEOUTID"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].fadeoutid = (UINT8)i;
|
||||
}
|
||||
else if (fastcmp(word, "FADECOLOR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].fadecolor = (UINT8)i;
|
||||
}
|
||||
else
|
||||
@@ -1346,8 +1299,6 @@ static void readcutscene(MYFILE *f, INT32 num)
|
||||
if (1 <= value && value <= 128)
|
||||
{
|
||||
readcutscenescene(f, num, value - 1);
|
||||
DEH_WriteUndoline(word, word2, UNDO_SPACE|UNDO_CUTLINE);
|
||||
DEH_WriteUndoline("NUMSCENES", va("%d", oldnumscenes), UNDO_SPACE);
|
||||
}
|
||||
else
|
||||
deh_warning("Scene number %d out of range (1 - 128)", value);
|
||||
@@ -1403,12 +1354,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
||||
|
||||
if (fastcmp(word, "X"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", hudinfo[num].x), UNDO_NONE);
|
||||
hudinfo[num].x = i;
|
||||
}
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", hudinfo[num].y), UNDO_NONE);
|
||||
hudinfo[num].y = i;
|
||||
}
|
||||
else
|
||||
@@ -1419,25 +1368,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
/*
|
||||
Sprite number = 10
|
||||
Sprite subnumber = 32968
|
||||
Duration = 200
|
||||
Next frame = 200
|
||||
*/
|
||||
|
||||
/** Action pointer for reading actions from Dehacked lumps.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
actionf_t action; ///< Function pointer corresponding to the actual action.
|
||||
const char *name; ///< Name of the action in ALL CAPS.
|
||||
} actionpointer_t;
|
||||
|
||||
/** Array mapping action names to action functions.
|
||||
* Names must be in ALL CAPS for case insensitive comparisons.
|
||||
*/
|
||||
static actionpointer_t actionpointers[] =
|
||||
// IMPORTANT!
|
||||
// DO NOT FORGET TO SYNC THIS LIST WITH THE ACTIONNUM ENUM IN INFO.H
|
||||
actionpointer_t actionpointers[] =
|
||||
{
|
||||
{{A_Explode}, "A_EXPLODE"},
|
||||
{{A_Pain}, "A_PAIN"},
|
||||
@@ -1592,6 +1526,7 @@ static actionpointer_t actionpointers[] =
|
||||
{{A_FZBoomSmoke}, "A_FZBOOMSMOKE"}, //SRB2kart
|
||||
{{A_RandomShadowFrame}, "A_RANDOMSHADOWFRAME"}, //SRB2kart
|
||||
{{A_RoamingShadowThinker}, "A_ROAMINGSHADOWTHINKER"}, //SRB2kart
|
||||
{{A_MayonakaArrow}, "A_MAYONAKAARROW"}, //SRB2kart
|
||||
{{A_ReaperThinker}, "A_REAPERTHINKER"}, //SRB2kart
|
||||
{{A_MementosTPParticles}, "A_MEMENTOSTPPARTICLES"}, //SRB2kart
|
||||
{{A_FlameParticle}, "A_FLAMEPARTICLE"}, // SRB2kart
|
||||
@@ -1684,32 +1619,26 @@ static void readframe(MYFILE *f, INT32 num)
|
||||
|
||||
if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%u", states[num].sprite), UNDO_NONE);
|
||||
states[num].sprite = get_sprite(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].frame), UNDO_NONE);
|
||||
states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated
|
||||
}
|
||||
else if (fastcmp(word1, "DURATION"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%u", states[num].tics), UNDO_NONE);
|
||||
states[num].tics = (INT32)get_number(word2); // So TICRATE can be used
|
||||
}
|
||||
else if (fastcmp(word1, "NEXT"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].nextstate), UNDO_NONE);
|
||||
states[num].nextstate = get_state(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "VAR1"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].var1), UNDO_NONE);
|
||||
states[num].var1 = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "VAR2"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].var2), UNDO_NONE);
|
||||
states[num].var2 = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "ACTION"))
|
||||
@@ -1735,7 +1664,6 @@ static void readframe(MYFILE *f, INT32 num)
|
||||
{
|
||||
if (actionpointers[z].action.acv == states[num].action.acv)
|
||||
{
|
||||
DEH_WriteUndoline(word1, actionpointers[z].name, UNDO_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1795,17 +1723,14 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||
|
||||
if (fastcmp(word, "SINGULAR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||
S_sfx[num].singularity = value;
|
||||
}
|
||||
else if (fastcmp(word, "PRIORITY"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].priority), UNDO_NONE);
|
||||
S_sfx[num].priority = value;
|
||||
}
|
||||
else if (fastcmp(word, "FLAGS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].pitch), UNDO_NONE);
|
||||
S_sfx[num].pitch = value;
|
||||
}
|
||||
else
|
||||
@@ -1865,16 +1790,6 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||
INT32 value;
|
||||
|
||||
// Reset all data initially
|
||||
DEH_WriteUndoline("TYPE", va("%d", emblemlocations[num-1].type), UNDO_NONE);
|
||||
DEH_WriteUndoline("X", va("%d", emblemlocations[num-1].x), UNDO_NONE);
|
||||
DEH_WriteUndoline("Y", va("%d", emblemlocations[num-1].y), UNDO_NONE);
|
||||
DEH_WriteUndoline("Z", va("%d", emblemlocations[num-1].z), UNDO_NONE);
|
||||
DEH_WriteUndoline("MAPNUM", va("%d", emblemlocations[num-1].level), UNDO_NONE);
|
||||
DEH_WriteUndoline("VAR", va("%d", emblemlocations[num-1].var), UNDO_NONE);
|
||||
DEH_WriteUndoline("SPRITE", va("%d", emblemlocations[num-1].sprite), UNDO_NONE);
|
||||
DEH_WriteUndoline("COLOR", va("%d", emblemlocations[num-1].color), UNDO_NONE);
|
||||
DEH_WriteUndoline("HINT", extraemblems[num-1].hint, UNDO_NONE);
|
||||
|
||||
memset(&emblemlocations[num-1], 0, sizeof(emblem_t));
|
||||
|
||||
do
|
||||
@@ -2002,12 +1917,6 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
||||
INT32 value;
|
||||
|
||||
// Reset all data initially
|
||||
DEH_WriteUndoline("NAME", extraemblems[num-1].name, UNDO_NONE);
|
||||
DEH_WriteUndoline("OBJECTIVE", extraemblems[num-1].description, UNDO_NONE);
|
||||
DEH_WriteUndoline("CONDITIONSET", va("%d", extraemblems[num-1].conditionset), UNDO_NONE);
|
||||
DEH_WriteUndoline("SPRITE", va("%d", extraemblems[num-1].sprite), UNDO_NONE);
|
||||
DEH_WriteUndoline("COLOR", va("%d", extraemblems[num-1].color), UNDO_NONE);
|
||||
|
||||
memset(&extraemblems[num-1], 0, sizeof(extraemblem_t));
|
||||
|
||||
do
|
||||
@@ -2086,15 +1995,6 @@ static void readunlockable(MYFILE *f, INT32 num)
|
||||
INT32 i;
|
||||
|
||||
// Same deal with unlockables, clear all first
|
||||
DEH_WriteUndoline("NAME", unlockables[num].name, UNDO_NONE);
|
||||
DEH_WriteUndoline("OBJECTIVE", unlockables[num].objective, UNDO_NONE);
|
||||
DEH_WriteUndoline("HEIGHT", va("%d", unlockables[num].height), UNDO_NONE);
|
||||
DEH_WriteUndoline("CONDITIONSET", va("%d", unlockables[num].conditionset), UNDO_NONE);
|
||||
DEH_WriteUndoline("TYPE", va("%d", unlockables[num].type), UNDO_NONE);
|
||||
DEH_WriteUndoline("NOCECHO", va("%d", unlockables[num].nocecho), UNDO_NONE);
|
||||
DEH_WriteUndoline("NOCHECKLIST", va("%d", unlockables[num].nochecklist), UNDO_NONE);
|
||||
DEH_WriteUndoline("VAR", va("%d", unlockables[num].variable), UNDO_NONE);
|
||||
|
||||
memset(&unlockables[num], 0, sizeof(unlockable_t));
|
||||
|
||||
do
|
||||
@@ -2473,13 +2373,11 @@ static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
||||
// X position of the patch in the texture.
|
||||
if (fastcmp(word, "X"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE);
|
||||
patch.originx = (INT16)value;
|
||||
}
|
||||
// Y position of the patch in the texture.
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE);
|
||||
patch.originy = (INT16)value;
|
||||
}
|
||||
else
|
||||
@@ -2548,7 +2446,6 @@ static void readmaincfg(MYFILE *f)
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
DEH_WriteUndoline(word, va("%d", spstage_start), UNDO_NONE);
|
||||
spstage_start = (INT16)value;
|
||||
}
|
||||
else if (fastcmp(word, "SSTAGE_START"))
|
||||
@@ -2562,79 +2459,64 @@ static void readmaincfg(MYFILE *f)
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
DEH_WriteUndoline(word, va("%d", sstage_start), UNDO_NONE);
|
||||
sstage_start = (INT16)value;
|
||||
sstage_end = (INT16)(sstage_start+6); // 7 special stages total
|
||||
}
|
||||
else if (fastcmp(word, "USENIGHTSSS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", useNightsSS), UNDO_NONE);
|
||||
useNightsSS = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "REDTEAM"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_redteam), UNDO_NONE);
|
||||
skincolor_redteam = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BLUETEAM"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_blueteam), UNDO_NONE);
|
||||
skincolor_blueteam = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "REDRING"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_redring), UNDO_NONE);
|
||||
skincolor_redring = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BLUERING"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_bluering), UNDO_NONE);
|
||||
skincolor_bluering = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "INVULNTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", invulntics), UNDO_NONE);
|
||||
invulntics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SNEAKERTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", sneakertics), UNDO_NONE);
|
||||
sneakertics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "FLASHINGTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", flashingtics), UNDO_NONE);
|
||||
flashingtics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "TAILSFLYTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", tailsflytics), UNDO_NONE);
|
||||
tailsflytics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "UNDERWATERTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", underwatertics), UNDO_NONE);
|
||||
underwatertics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPACETIMETICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", spacetimetics), UNDO_NONE);
|
||||
spacetimetics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "EXTRALIFETICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", extralifetics), UNDO_NONE);
|
||||
extralifetics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "GAMEOVERTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", gameovertics), UNDO_NONE);
|
||||
gameovertics = get_number(word2);
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "INTROTOPLAY"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", introtoplay), UNDO_NONE);
|
||||
introtoplay = (UINT8)get_number(word2);
|
||||
// range check, you morons.
|
||||
if (introtoplay > 128)
|
||||
@@ -2642,17 +2524,14 @@ static void readmaincfg(MYFILE *f)
|
||||
}
|
||||
else if (fastcmp(word, "LOOPTITLE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", looptitle), UNDO_NONE);
|
||||
looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "TITLESCROLLSPEED"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", titlescrollspeed), UNDO_NONE);
|
||||
titlescrollspeed = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "CREDITSCUTSCENE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", creditscutscene), UNDO_NONE);
|
||||
creditscutscene = (UINT8)get_number(word2);
|
||||
// range check, you morons.
|
||||
if (creditscutscene > 128)
|
||||
@@ -2660,27 +2539,22 @@ static void readmaincfg(MYFILE *f)
|
||||
}
|
||||
else if (fastcmp(word, "NUMDEMOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE);
|
||||
numDemos = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEMODELAYTIME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", demoDelayTime), UNDO_NONE);
|
||||
demoDelayTime = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEMOIDLETIME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", demoIdleTime), UNDO_NONE);
|
||||
demoIdleTime = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "USE1UPSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", use1upSound), UNDO_NONE);
|
||||
use1upSound = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "MAXXTRALIFE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", maxXtraLife), UNDO_NONE);
|
||||
maxXtraLife = (UINT8)get_number(word2);
|
||||
}
|
||||
|
||||
@@ -2694,7 +2568,6 @@ static void readmaincfg(MYFILE *f)
|
||||
I_Error("Maincfg: bad data file name '%s'\n", word2);
|
||||
|
||||
G_SaveGameData(false);
|
||||
DEH_WriteUndoline(word, gamedatafilename, UNDO_NONE);
|
||||
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
|
||||
strlwr(gamedatafilename);
|
||||
savemoddata = true;
|
||||
@@ -2715,12 +2588,10 @@ static void readmaincfg(MYFILE *f)
|
||||
}
|
||||
else if (fastcmp(word, "RESETDATA"))
|
||||
{
|
||||
DEH_WriteUndoline(word, "0", UNDO_TODO); /// \todo
|
||||
P_ResetData(value);
|
||||
}
|
||||
else if (fastcmp(word, "CUSTOMVERSION"))
|
||||
{
|
||||
DEH_WriteUndoline(word, customversionstring, UNDO_NONE);
|
||||
strlcpy(customversionstring, word2, sizeof (customversionstring));
|
||||
}
|
||||
else
|
||||
@@ -2980,13 +2851,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
{
|
||||
G_SetGameModified(multiplayer, true);
|
||||
readmaincfg(f);
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
continue;
|
||||
}
|
||||
else if (fastcmp(word, "WIPES"))
|
||||
{
|
||||
readwipes(f);
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
@@ -3007,7 +2876,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Character %d out of range (0 - 31)", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
@@ -3021,7 +2889,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
{
|
||||
// Read patch from spec file.
|
||||
readpatch(f, word2, wad);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
@@ -3039,13 +2906,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
/* else if (fastcmp(word, "ANIMTEX"))
|
||||
{
|
||||
readAnimTex(f, i);
|
||||
// This is not a major mod.
|
||||
}*/
|
||||
else if (fastcmp(word, "LEVEL"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
@@ -3066,7 +2927,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "CUTSCENE"))
|
||||
{
|
||||
@@ -3077,8 +2937,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Cutscene number %d out of range (1 - 128)", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
//G_SetGameModified(multiplayer, true); -- might have to reconsider in a future update
|
||||
}
|
||||
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
|
||||
{
|
||||
@@ -3095,7 +2953,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SOUND"))
|
||||
{
|
||||
@@ -3108,7 +2965,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Sound %d out of range (0 - %d)", i, NUMSFX-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "HUDITEM"))
|
||||
@@ -3122,7 +2978,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("HUD item number %d out of range (0 - %d)", i, NUMHUDITEMS-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "EMBLEM"))
|
||||
@@ -3143,7 +2998,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Emblem number %d out of range (1 - %d)", i, MAXEMBLEMS);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "EXTRAEMBLEM"))
|
||||
{
|
||||
@@ -3163,7 +3017,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Extra emblem number %d out of range (1 - %d)", i, MAXEXTRAEMBLEMS);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
@@ -3179,7 +3032,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Unlockable number %d out of range (1 - %d)", i, MAXUNLOCKABLES);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
{
|
||||
@@ -3195,15 +3047,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Condition set number %d out of range (1 - %d)", i, MAXCONDITIONSETS);
|
||||
ignorelines(f);
|
||||
}
|
||||
// no undo support for this insanity yet
|
||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2KART"))
|
||||
{
|
||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||
if (ver != PATCHVERSION)
|
||||
deh_warning("Patch is for SRB2Kart version %d,\nonly version %d is supported", ver, PATCHVERSION);
|
||||
//DEH_WriteUndoline(word, va("%d", ver), UNDO_NONE);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
{
|
||||
@@ -3282,7 +3131,6 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
||||
f.curpos = f.data;
|
||||
f.data[f.size] = 0;
|
||||
DEH_LoadDehackedFile(&f, wad);
|
||||
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
||||
Z_Free(f.data);
|
||||
}
|
||||
|
||||
@@ -9130,12 +8978,15 @@ int LUA_EnumLib(lua_State *L)
|
||||
char *str = NULL;
|
||||
int size = 0;
|
||||
|
||||
// Sound enum tables preallocated for sfx_freeslot0 elements because using NUMSFX may be too
|
||||
// much if number of skins increased a lot (because of skinsound freeslots)
|
||||
|
||||
/* SFX (SFX_) */
|
||||
lua_pushcfunction(L, lua_glib_new_enum);
|
||||
lua_createtable(L, 0, NUMSFX);
|
||||
lua_createtable(L, 0, sfx_freeslot0);
|
||||
for (int i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if (!S_sfx[i].name) continue;
|
||||
if (!S_sfx[i].name || !S_sfx[i].priority) continue;
|
||||
|
||||
if (lua_enumlib_sprintf_upper(&str, &size, "SFX_%s", S_sfx[i].name) == NULL)
|
||||
return luaL_error(L, "Ran out of memory.");
|
||||
@@ -9150,10 +9001,10 @@ int LUA_EnumLib(lua_State *L)
|
||||
|
||||
/* SFX (DS) */
|
||||
lua_pushcfunction(L, lua_glib_new_enum);
|
||||
lua_createtable(L, 0, NUMSFX);
|
||||
lua_createtable(L, 0, sfx_freeslot0);
|
||||
for (int i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if (!S_sfx[i].name) continue;
|
||||
if (!S_sfx[i].name || !S_sfx[i].priority) continue;
|
||||
|
||||
if (lua_enumlib_sprintf_upper(&str, &size, "DS%s", S_sfx[i].name) == NULL)
|
||||
return luaL_error(L, "Ran out of memory.");
|
||||
@@ -9188,10 +9039,10 @@ int LUA_EnumLib(lua_State *L)
|
||||
{
|
||||
/* SFX (sfx_) */
|
||||
lua_pushcfunction(L, lua_glib_new_enum);
|
||||
lua_createtable(L, 0, NUMSFX);
|
||||
lua_createtable(L, 0, sfx_freeslot0);
|
||||
for (int i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if (!S_sfx[i].name) continue;
|
||||
if (!S_sfx[i].name || !S_sfx[i].priority) continue;
|
||||
|
||||
lua_pushfstring(L, "sfx_%s", S_sfx[i].name);
|
||||
lua_pushinteger(L, i);
|
||||
@@ -9365,6 +9216,11 @@ int LUA_EnumLib(lua_State *L)
|
||||
lua_glib_push_bool_getter(L, &demo.playback);
|
||||
lua_call(L, 2, 0);
|
||||
|
||||
lua_pushcfunction(L, lua_glib_new_getter);
|
||||
lua_pushliteral(L, "replayfreecam");
|
||||
lua_glib_push_bool_getter(L, &demo.freecam);
|
||||
lua_call(L, 2, 0);
|
||||
|
||||
if (!mathlib)
|
||||
{
|
||||
lua_pushcfunction(L, lua_glib_new_getter);
|
||||
@@ -9422,4 +9278,13 @@ void LUA_SetActionByName(void *state, const char *actiontocompare)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum actionnum LUA_GetActionNumByName(const char *actiontocompare)
|
||||
{
|
||||
size_t z;
|
||||
for (z = 0; actionpointers[z].name; z++)
|
||||
if (fasticmp(actiontocompare, actionpointers[z].name))
|
||||
return z;
|
||||
return z;
|
||||
}
|
||||
+1
-14
@@ -15,20 +15,6 @@
|
||||
|
||||
#include "m_fixed.h" // for get_number
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNDO_NONE = 0x00,
|
||||
UNDO_NEWLINE = 0x01,
|
||||
UNDO_SPACE = 0x02,
|
||||
UNDO_CUTLINE = 0x04,
|
||||
UNDO_HEADER = 0x07,
|
||||
UNDO_ENDTEXT = 0x08,
|
||||
UNDO_TODO = 0,
|
||||
UNDO_DONE = 0,
|
||||
} undotype_f;
|
||||
|
||||
#define DEH_WriteUndoline(a,b,c)
|
||||
|
||||
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
|
||||
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
|
||||
|
||||
@@ -41,6 +27,7 @@ fixed_t get_number(const char *word);
|
||||
boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
|
||||
const char *LUA_GetActionName(void *action);
|
||||
void LUA_SetActionByName(void *state, const char *actiontocompare);
|
||||
enum actionnum LUA_GetActionNumByName(const char *actiontocompare);
|
||||
|
||||
extern boolean deh_loaded;
|
||||
|
||||
|
||||
+36
-8
@@ -127,13 +127,8 @@ extern char logfilename[1024];
|
||||
#else
|
||||
#define VERSION 1 // Game version
|
||||
#define SUBVERSION 6 // more precise version number
|
||||
#ifndef USE_FBO_OGL
|
||||
#define VERSIONSTRING "Saturn v6.2 "
|
||||
#define VERSIONSTRINGW L"Saturn v6.2"
|
||||
#else
|
||||
#define VERSIONSTRING "Saturn v6.2 - FBO "
|
||||
#define VERSIONSTRINGW L"Saturn v6.2 - FBO"
|
||||
#endif
|
||||
#define VERSIONSTRING "Saturn v7.1"
|
||||
#define VERSIONSTRINGW L"Saturn v7.1"
|
||||
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
|
||||
// And change CMakeLists.txt (not src/, but in root), for CMake users!
|
||||
// AND appveyor.yml, for the build bots!
|
||||
@@ -211,6 +206,7 @@ extern char logfilename[1024];
|
||||
|
||||
#define MAXPLAYERS 16
|
||||
#define MAXSKINS 255
|
||||
#define MAXLOCALSKINS 32
|
||||
#define PLAYERSMASK (MAXPLAYERS-1)
|
||||
#define MAXPLAYERNAME 21
|
||||
|
||||
@@ -473,7 +469,12 @@ void M_StartupLocale(void);
|
||||
// M_GetText function that just returns the string.
|
||||
#define M_GetText(x) (x)
|
||||
#endif
|
||||
void *M_Memcpy(void* dest, const void* src, size_t n);
|
||||
|
||||
FUNCINLINE static ATTRINLINE void *M_Memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
char *va(const char *format, ...) FUNCPRINTF;
|
||||
char *M_GetToken(const char *inputString);
|
||||
char *sizeu1(size_t num);
|
||||
@@ -528,6 +529,10 @@ INT32 I_GetKey(void);
|
||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x)))
|
||||
#endif
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
@@ -563,6 +568,29 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
||||
// Compile them at your own risk!
|
||||
|
||||
#ifndef NONET
|
||||
//-- SATURN __
|
||||
/// Enable gamestate resynching between Saturn servers and clients
|
||||
/// Like SRB2 and RR does
|
||||
/// Still highly experimental
|
||||
#ifdef DOSATURNSYNCH
|
||||
#define SATURNSYNCH
|
||||
|
||||
/// Detect if a client is on Saturn in the clientconfig.
|
||||
/// To seperately allow them to join or block joining from vanilla clients.
|
||||
#ifdef DOSATURNJOIN
|
||||
#define SATURNJOIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Server detection for if a connecting client is on Saturn.
|
||||
/// For stuff like extra synching, etc.
|
||||
#ifdef DOSATURNPAK
|
||||
#define SATURNPAK
|
||||
#endif
|
||||
//-- <( ̄︶ ̄)> __
|
||||
#endif
|
||||
|
||||
/// Undefine to use the new method of Gamma correction see colour cube in v_video.c
|
||||
#define BACKWARDSCOMPATCORRECTION
|
||||
|
||||
|
||||
+13
-2
@@ -112,7 +112,6 @@ extern UINT8 window_notinfocus; // are we in focus? (backend independant -- hand
|
||||
extern boolean nodrawers;
|
||||
extern boolean noblit;
|
||||
extern boolean lastdraw;
|
||||
extern postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 postimgparam[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern INT32 viewwindowx, viewwindowy;
|
||||
@@ -192,7 +191,7 @@ extern struct quake
|
||||
// camera offsets and duration
|
||||
fixed_t x,y,z;
|
||||
angle_t roll;
|
||||
UINT16 time;
|
||||
tic_t time;
|
||||
|
||||
// location, radius, and intensity...
|
||||
mappoint_t *epicenter;
|
||||
@@ -510,6 +509,18 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative
|
||||
extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF
|
||||
extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
|
||||
|
||||
#define WAYPOINTSEQUENCESIZE 256
|
||||
#define NUMWAYPOINTSEQUENCES 256
|
||||
extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
|
||||
extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
|
||||
|
||||
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint);
|
||||
mobj_t *P_GetFirstWaypoint(UINT8 sequence);
|
||||
mobj_t *P_GetLastWaypoint(UINT8 sequence);
|
||||
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
|
||||
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
|
||||
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
|
||||
|
||||
// =====================================
|
||||
// Internal parameters, used for engine.
|
||||
// =====================================
|
||||
|
||||
+6
-8
@@ -344,14 +344,12 @@ typedef union FColorRGBA RGBA_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
postimg_none,
|
||||
postimg_water,
|
||||
postimg_motion,
|
||||
postimg_flip,
|
||||
postimg_heat,
|
||||
postimg_mirror,
|
||||
postimg_mirrorflip
|
||||
} postimg_t;
|
||||
POSTIMG_WATER = 1, // Underwater screen effect.
|
||||
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
|
||||
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
|
||||
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
|
||||
POSTIMG_MIRROR = 1<<4, // encore screen effect.
|
||||
} postimgflag_t;
|
||||
|
||||
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
|
||||
#define LUMPERROR UINT32_MAX
|
||||
|
||||
+5
-5
@@ -170,8 +170,8 @@ static void F_SkyScroll(INT32 scrollspeed)
|
||||
w = (vid.width / vid.dupx)<<FRACBITS;
|
||||
|
||||
// The scroll offset MUST be clamped before shifting by FRACBITS, or else it'll overflow in about 3 minutes
|
||||
animtimer = ((((finalecount * scrollspeed) % (SHORT(pat->width)*16))<<FRACBITS) + (R_GetHudUncap() * scrollspeed))/16;
|
||||
anim2 = (SHORT(pat2->width)<<FRACBITS) - ((((finalecount * scrollspeed) % (SHORT(pat2->width)*16))<<FRACBITS) + (R_GetHudUncap() * scrollspeed))/16;
|
||||
animtimer = ((((finalecount * scrollspeed) % (SHORT(pat->width)*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
|
||||
anim2 = (SHORT(pat2->width)<<FRACBITS) - ((((finalecount * scrollspeed) % (SHORT(pat2->width)*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
|
||||
|
||||
// SRB2Kart: F_DrawPatchCol is over-engineered; recoded to be less shitty and error-prone
|
||||
if (rendermode != render_none)
|
||||
@@ -996,7 +996,7 @@ void F_TitleScreenDrawer(void)
|
||||
if (finalecount >= 20)
|
||||
V_DrawSmallScaledPatch(84, 87, 0, ttkart);
|
||||
else if (finalecount >= 10)
|
||||
V_DrawSciencePatch((84<<FRACBITS) - 18*(((20 - finalecount)<<FRACBITS) - R_GetHudUncap()), 87<<FRACBITS, 0, ttkart, FRACUNIT/2);
|
||||
V_DrawSciencePatch((84<<FRACBITS) - 18*(((20 - finalecount)<<FRACBITS) - R_GetMenuUncap()), 87<<FRACBITS, 0, ttkart, FRACUNIT/2);
|
||||
}
|
||||
else if (finalecount < 52)
|
||||
{
|
||||
@@ -1012,8 +1012,8 @@ void F_TitleScreenDrawer(void)
|
||||
|
||||
F_SkyScroll(titlescrollspeed);
|
||||
|
||||
V_DrawSciencePatch(0, -40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetHudUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTOLEFT, ttcheckers, FRACUNIT);
|
||||
V_DrawSciencePatch(280<<FRACBITS, -(40<<FRACBITS) + 40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetHudUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTORIGHT, ttcheckers, FRACUNIT);
|
||||
V_DrawSciencePatch(0, -40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetMenuUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTOLEFT, ttcheckers, FRACUNIT);
|
||||
V_DrawSciencePatch(280<<FRACBITS, -(40<<FRACBITS) + 40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetMenuUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTORIGHT, ttcheckers, FRACUNIT);
|
||||
|
||||
if (transval)
|
||||
V_DrawFadeScreen(120, 10 - transval);
|
||||
|
||||
+9
-11
@@ -37,7 +37,6 @@
|
||||
#include <tchar.h>
|
||||
|
||||
#define SUFFIX "*"
|
||||
#define SLASH "\\"
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
@@ -135,7 +134,7 @@ opendir (const CHAR *szPath)
|
||||
/* Allocate enough space to store DIR structure and the complete
|
||||
* directory path given. */
|
||||
nd = (DIR *) malloc (sizeof (DIR) + (strlen(szFullPath) + strlen (SLASH) +
|
||||
strlen(SUFFIX) + 1) * sizeof (CHAR));
|
||||
strlen(PATHSEP) + 1) * sizeof (CHAR));
|
||||
|
||||
if (!nd)
|
||||
{
|
||||
@@ -149,10 +148,9 @@ opendir (const CHAR *szPath)
|
||||
|
||||
/* Add on a slash if the path does not end with one. */
|
||||
if (nd->dd_name[0] != '\0' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != PATHSEP[0])
|
||||
{
|
||||
strcat (nd->dd_name, SLASH);
|
||||
strcat (nd->dd_name, PATHSEP);
|
||||
}
|
||||
|
||||
/* Add on the search pattern */
|
||||
@@ -382,9 +380,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
if (searchpath[searchpathindex[depthleft]-2] != '/')
|
||||
if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0])
|
||||
{
|
||||
searchpath[searchpathindex[depthleft]-1] = '/';
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else
|
||||
@@ -392,7 +390,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
|
||||
while ((!found) && (depthleft < maxsearchdepth))
|
||||
{
|
||||
searchpath[searchpathindex[depthleft]]=0;
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
dent = readdir(dirhandle[depthleft]);
|
||||
|
||||
if (!dent)
|
||||
@@ -419,7 +417,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
if (S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
else if (S_ISLNK(fsstat.st_mode))
|
||||
dent->d_type = DT_LNK;
|
||||
dent->d_type = DT_LNK;
|
||||
}
|
||||
|
||||
// Symlinks aren't always directory symlinks. Dunno if this would resolve recursive
|
||||
@@ -447,8 +445,8 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
depthleft++;
|
||||
}
|
||||
|
||||
searchpath[searchpathindex[depthleft]-1]='/';
|
||||
searchpath[searchpathindex[depthleft]]=0;
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else if (!strcasecmp(searchname, dent->d_name))
|
||||
{
|
||||
|
||||
+173
-247
@@ -50,6 +50,7 @@
|
||||
#include "b_bot.h"
|
||||
#include "m_cond.h" // condition sets
|
||||
#include "md5.h" // demo checksums
|
||||
#include "k_director.h" // SRB2kart
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
|
||||
@@ -335,6 +336,11 @@ boolean precache = true; // if true, load all graphics at start
|
||||
|
||||
INT16 prevmap, nextmap;
|
||||
|
||||
// save if director is enabled
|
||||
// so demos can disable it by default and restore it after
|
||||
static int directorstate = 0;
|
||||
tic_t directortoggletimer = 0;
|
||||
|
||||
static CV_PossibleValue_t recordmultiplayerdemos_cons_t[] = {{0, "Disabled"}, {1, "Manual Save"}, {2, "Auto Save"}, {0, NULL}};
|
||||
consvar_t cv_recordmultiplayerdemos = {"netdemo_record", "Manual Save", CV_SAVE, recordmultiplayerdemos_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -345,13 +351,12 @@ consvar_t cv_netdemosyncquality = {"netdemo_syncquality", "1", CV_SAVE, netdemos
|
||||
static CV_PossibleValue_t maxdemosize_cons_t[] = {{10, "MIN"}, {100, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxdemosize = {"maxdemosize", "10", CV_SAVE, maxdemosize_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t demochangemap_cons_t[] = {{0, "Disabled"}, {1, "Diff Map"}, {2, "Always"}, {0, NULL}};
|
||||
consvar_t cv_demochangemap = {"netdemo_savemapchange", "Disabled", CV_SAVE, demochangemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
// Analog Control
|
||||
static void UserAnalog_OnChange(void);
|
||||
static void UserAnalog2_OnChange(void);
|
||||
static void UserAnalog3_OnChange(void);
|
||||
static void UserAnalog4_OnChange(void);
|
||||
static void Analog_OnChange(void);
|
||||
static void Analog2_OnChange(void);
|
||||
static void Analog3_OnChange(void);
|
||||
@@ -417,8 +422,9 @@ consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NUL
|
||||
consvar_t cv_showfreeplay = { "showfreeplay", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// We can disable special tunes!
|
||||
consvar_t cv_growmusic = {"growmusic", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_supermusic = {"supermusic", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t powermusic_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "SFX"}, {0, NULL}};
|
||||
consvar_t cv_growmusic = {"growmusic", "On", CV_SAVE, powermusic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_supermusic = {"supermusic", "On", CV_SAVE, powermusic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
/*consvar_t cv_crosshair = {"crosshair", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_crosshair2 = {"crosshair2", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -436,10 +442,10 @@ consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, N
|
||||
consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_analog3 = {"analog3", "Off", CV_CALL, CV_OnOff, Analog3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_analog4 = {"analog4", "Off", CV_CALL, CV_OnOff, Analog4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_turnaxis = {"joyaxis_turn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -501,8 +507,8 @@ static CV_PossibleValue_t driftsparkpulse_t[] = {{0, "MIN"}, {FRACUNIT*3, "MAX"}
|
||||
consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, driftsparkpulse_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t stretchfactor_t[] = {
|
||||
{0, "Off"}, {FRACUNIT/8, "0.125"}, {FRACUNIT/4, "0.250"},
|
||||
{3*FRACUNIT/8, "0.375"}, {FRACUNIT/2, "0.500"}, {5*FRACUNIT/8, "0.625"},
|
||||
{0, "Off"}, {FRACUNIT/8, "0.125"}, {FRACUNIT/4, "0.250"},
|
||||
{3*FRACUNIT/8, "0.375"}, {FRACUNIT/2, "0.500"}, {5*FRACUNIT/8, "0.625"},
|
||||
{3*FRACUNIT/4, "0.750"}, {7*FRACUNIT/8, "0.875"}, {FRACUNIT, "Max"}, {0, NULL}};
|
||||
consvar_t cv_gravstretch = {"gravstretch", "0", CV_SAVE, stretchfactor_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -586,15 +592,6 @@ void G_ClearRecords(void)
|
||||
}
|
||||
}
|
||||
|
||||
// For easy retrieval of records
|
||||
/*UINT32 G_GetBestScore(INT16 map)
|
||||
{
|
||||
if (!mainrecords[map-1])
|
||||
return 0;
|
||||
|
||||
return mainrecords[map-1]->score;
|
||||
}*/
|
||||
|
||||
tic_t G_GetBestTime(INT16 map)
|
||||
{
|
||||
if (!mainrecords[map-1] || mainrecords[map-1]->time <= 0)
|
||||
@@ -970,7 +967,7 @@ static INT32 Joy3Axis(axis_input_e axissel)
|
||||
}
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -990,7 +987,7 @@ static INT32 Joy3Axis(axis_input_e axissel)
|
||||
}
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1065,7 +1062,7 @@ static INT32 Joy4Axis(axis_input_e axissel)
|
||||
}
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1085,7 +1082,7 @@ static INT32 Joy4Axis(axis_input_e axissel)
|
||||
}
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1499,61 +1496,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
|
||||
}
|
||||
|
||||
// User has designated that they want
|
||||
// analog ON, so tell the game to stop
|
||||
// fudging with it.
|
||||
static void UserAnalog_OnChange(void)
|
||||
{
|
||||
/*if (cv_useranalog.value)
|
||||
CV_SetValue(&cv_analog, 1);
|
||||
else
|
||||
CV_SetValue(&cv_analog, 0);*/
|
||||
}
|
||||
|
||||
static void UserAnalog2_OnChange(void)
|
||||
{
|
||||
if (botingame)
|
||||
return;
|
||||
/*if (cv_useranalog2.value)
|
||||
CV_SetValue(&cv_analog2, 1);
|
||||
else
|
||||
CV_SetValue(&cv_analog2, 0);*/
|
||||
}
|
||||
|
||||
static void UserAnalog3_OnChange(void)
|
||||
{
|
||||
if (botingame)
|
||||
return;
|
||||
/*if (cv_useranalog3.value)
|
||||
CV_SetValue(&cv_analog3, 1);
|
||||
else
|
||||
CV_SetValue(&cv_analog3, 0);*/
|
||||
}
|
||||
|
||||
static void UserAnalog4_OnChange(void)
|
||||
{
|
||||
if (botingame)
|
||||
return;
|
||||
/*if (cv_useranalog4.value)
|
||||
CV_SetValue(&cv_analog4, 1);
|
||||
else
|
||||
CV_SetValue(&cv_analog4, 0);*/
|
||||
}
|
||||
|
||||
static void Analog_OnChange(void)
|
||||
{
|
||||
if (!cv_cam_dist.string)
|
||||
return;
|
||||
|
||||
// cameras are not initialized at this point
|
||||
|
||||
/*
|
||||
if (!cv_chasecam.value && cv_analog.value) {
|
||||
CV_SetValue(&cv_analog, 0);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
SendWeaponPref();
|
||||
}
|
||||
|
||||
@@ -1562,15 +1509,6 @@ static void Analog2_OnChange(void)
|
||||
if (!(splitscreen || botingame) || !cv_cam2_dist.string)
|
||||
return;
|
||||
|
||||
// cameras are not initialized at this point
|
||||
|
||||
/*
|
||||
if (!cv_chasecam2.value && cv_analog2.value) {
|
||||
CV_SetValue(&cv_analog2, 0);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
SendWeaponPref2();
|
||||
}
|
||||
|
||||
@@ -1579,15 +1517,6 @@ static void Analog3_OnChange(void)
|
||||
if (splitscreen < 2 || !cv_cam3_dist.string)
|
||||
return;
|
||||
|
||||
// cameras are not initialized at this point
|
||||
|
||||
/*
|
||||
if (!cv_chasecam3.value && cv_analog3.value) {
|
||||
CV_SetValue(&cv_analog3, 0);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
SendWeaponPref3();
|
||||
}
|
||||
|
||||
@@ -1596,15 +1525,6 @@ static void Analog4_OnChange(void)
|
||||
if (splitscreen < 3 || !cv_cam4_dist.string)
|
||||
return;
|
||||
|
||||
// cameras are not initialized at this point
|
||||
|
||||
/*
|
||||
if (!cv_chasecam4.value && cv_analog4.value) {
|
||||
CV_SetValue(&cv_analog4, 0);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
SendWeaponPref4();
|
||||
}
|
||||
|
||||
@@ -1637,7 +1557,7 @@ void G_DoLoadLevel(boolean resetplayer)
|
||||
}
|
||||
|
||||
// Setup the level.
|
||||
if (!P_SetupLevel(false))
|
||||
if (!P_SetupLevel(false,false))
|
||||
{
|
||||
// fail so reset game stuff
|
||||
Command_ExitGame_f();
|
||||
@@ -1680,6 +1600,8 @@ void G_DoLoadLevel(boolean resetplayer)
|
||||
|
||||
// clear hud messages remains (usually from game startup)
|
||||
CON_ClearHUD();
|
||||
|
||||
G_ResetAllDeviceRumbles();
|
||||
}
|
||||
|
||||
static INT32 pausedelay = 0;
|
||||
@@ -1934,6 +1856,11 @@ boolean G_Responder(event_t *ev)
|
||||
COM_ImmedExecute("changeteam4 spectator");
|
||||
}
|
||||
}
|
||||
if (ev->data1 == gamecontrol[gc_director][0]
|
||||
|| ev->data1 == gamecontrol[gc_director][1])
|
||||
{
|
||||
K_ToggleDirector();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -2064,6 +1991,29 @@ INT32 G_CountPlayersPotentiallyViewable(boolean active)
|
||||
return total;
|
||||
}
|
||||
|
||||
//
|
||||
// G_FixCamera
|
||||
// Reset camera position, angle and interpolation on a view
|
||||
// after changing state.
|
||||
//
|
||||
static void G_FixCamera(UINT8 view)
|
||||
{
|
||||
player_t *player = &players[displayplayers[view - 1]];
|
||||
|
||||
// The order of displayplayers can change, which would
|
||||
// invalidate localangle.
|
||||
localangle[view - 1] = player->cmd.angleturn;
|
||||
|
||||
P_ResetCamera(player, &camera[view - 1]);
|
||||
|
||||
// Make sure the viewport doesn't interpolate at all into
|
||||
// its new position -- just snap instantly into place.
|
||||
|
||||
// Why does it need to be done twice?
|
||||
R_ResetViewInterpolation(view);
|
||||
R_ResetViewInterpolation(view);
|
||||
}
|
||||
|
||||
//
|
||||
// G_ResetView
|
||||
// Correct a viewpoint to playernum or the next available, wraps forward.
|
||||
@@ -2076,7 +2026,6 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
||||
UINT8 viewd;
|
||||
|
||||
INT32 *displayplayerp;
|
||||
camera_t *camerap;
|
||||
|
||||
INT32 olddisplayplayer;
|
||||
INT32 playersviewable;
|
||||
@@ -2108,29 +2057,25 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
||||
olddisplayplayer = (*displayplayerp);
|
||||
|
||||
/* Check if anyone is available to view. */
|
||||
if (( playernum = G_FindView(playernum, viewnum, onlyactive, playernum < olddisplayplayer) ) == -1)
|
||||
if ((playernum = G_FindView(playernum, viewnum, onlyactive, playernum < olddisplayplayer)) == -1)
|
||||
return;
|
||||
|
||||
/* Focus our target view first so that we don't take its player. */
|
||||
(*displayplayerp) = playernum;
|
||||
if ((*displayplayerp) != olddisplayplayer)
|
||||
{
|
||||
camerap = &camera[viewnum-1];
|
||||
P_ResetCamera(&players[(*displayplayerp)], camerap);
|
||||
|
||||
R_ResetViewInterpolation(viewnum);
|
||||
}
|
||||
|
||||
/* If a viewpoint changes, reset the camera to clear uninitialized memory. */
|
||||
if (viewnum > splits)
|
||||
{
|
||||
for (viewd = splits+1; viewd < viewnum; ++viewd)
|
||||
for (viewd = splits+1; viewd <= viewnum; ++viewd)
|
||||
{
|
||||
displayplayerp = (&displayplayers[viewd-1]);
|
||||
camerap = &camera[viewd];
|
||||
|
||||
(*displayplayerp) = G_FindView(0, viewd, onlyactive, false);
|
||||
|
||||
P_ResetCamera(&players[(*displayplayerp)], camerap);
|
||||
G_FixCamera(viewd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*displayplayerp) != olddisplayplayer)
|
||||
{
|
||||
G_FixCamera(viewnum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2212,13 +2157,6 @@ void G_Ticker(boolean run)
|
||||
if (!(netgame || multiplayer) && G_GetRetryFlag())
|
||||
{
|
||||
G_ClearRetryFlag();
|
||||
|
||||
// Costs a life to retry ... unless the player in question is dead already.
|
||||
/*if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE)
|
||||
players[consoleplayer].lives -= 1;
|
||||
|
||||
G_DoReborn(consoleplayer);*/
|
||||
|
||||
D_MapChange(gamemap, gametype, cv_kartencore.value, true, 1, false, false);
|
||||
}
|
||||
|
||||
@@ -2244,13 +2182,14 @@ void G_Ticker(boolean run)
|
||||
buf = gametic % TICQUEUE;
|
||||
|
||||
if (!demo.playback)
|
||||
// read/write demo and check turbo cheat
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
cmd = &players[i].cmd;
|
||||
|
||||
if (playeringame[i])
|
||||
for (i = 0; i < MAXPLAYERS; i++) // read/write demo and check turbo cheat
|
||||
{
|
||||
cmd = &players[i].cmd;
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
//@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat...
|
||||
// Remove for 1.1!
|
||||
|
||||
@@ -2485,6 +2424,10 @@ void G_PlayerReborn(INT32 player)
|
||||
boolean fade;
|
||||
boolean playing;
|
||||
|
||||
tic_t laptime[LAP__MAX];
|
||||
|
||||
INT32 i;
|
||||
|
||||
score = players[player].score;
|
||||
marescore = players[player].marescore;
|
||||
lives = players[player].lives;
|
||||
@@ -2546,6 +2489,11 @@ void G_PlayerReborn(INT32 player)
|
||||
starpostnum = 0;
|
||||
respawnflip = 0;
|
||||
starpostangle = 0;
|
||||
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
laptime[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2574,6 +2522,11 @@ void G_PlayerReborn(INT32 player)
|
||||
bumper = players[player].kartstuff[k_bumper];
|
||||
comebackpoints = players[player].kartstuff[k_comebackpoints];
|
||||
wanted = players[player].kartstuff[k_wanted];
|
||||
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
laptime[i] = players[player].laptime[i];
|
||||
}
|
||||
}
|
||||
|
||||
spectatorreentry = players[player].spectatorreentry;
|
||||
@@ -2617,6 +2570,11 @@ void G_PlayerReborn(INT32 player)
|
||||
p->laps = laps;
|
||||
p->totalring = totalring;
|
||||
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
p->laptime[i] = laptime[i];
|
||||
}
|
||||
|
||||
p->mare = mare;
|
||||
if (bot)
|
||||
p->bot = 1; // reset to AI-controlled
|
||||
@@ -2666,8 +2624,7 @@ void G_PlayerReborn(INT32 player)
|
||||
}
|
||||
|
||||
/* I'm putting this here because lol */
|
||||
|
||||
fade = (cv_fading.value && cv_birdmusic.value && P_IsLocalPlayer(p));
|
||||
fade = (cv_birdmusic.value && cv_fading.value && P_IsLocalPlayer(p));
|
||||
|
||||
if (fade)
|
||||
{
|
||||
@@ -2677,7 +2634,7 @@ void G_PlayerReborn(INT32 player)
|
||||
Fade it in with the same call to avoid
|
||||
max volume for a few milliseconds (?).
|
||||
*/
|
||||
if (! playing)
|
||||
if (!playing)
|
||||
S_SetRestoreMusicFadeInCvar(&cv_respawnfademusicback);
|
||||
}
|
||||
|
||||
@@ -3033,12 +2990,6 @@ void G_DoReborn(INT32 playernum)
|
||||
player_t *player = &players[playernum];
|
||||
boolean starpost = false;
|
||||
|
||||
/*if (modeattacking) // Not needed for SRB2Kart.
|
||||
{
|
||||
M_EndModeAttackRun();
|
||||
return;
|
||||
}*/
|
||||
|
||||
// Make sure objectplace is OFF when you first start the level!
|
||||
OP_ResetObjectplace();
|
||||
|
||||
@@ -3058,68 +3009,6 @@ void G_DoReborn(INT32 playernum)
|
||||
if (oldmo)
|
||||
G_ChangePlayerReferences(oldmo, players[playernum].mo);
|
||||
}
|
||||
/*else if (countdowntimeup || (!multiplayer && !modeattacking))
|
||||
{
|
||||
// reload the level from scratch
|
||||
if (countdowntimeup)
|
||||
{
|
||||
player->starpostangle = 0;
|
||||
player->starposttime = 0;
|
||||
player->starpostx = 0;
|
||||
player->starposty = 0;
|
||||
player->starpostz = 0;
|
||||
player->starpostnum = 0;
|
||||
}
|
||||
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD))
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
player->playerstate = PST_REBORN;
|
||||
|
||||
P_LoadThingsOnly();
|
||||
|
||||
// Do a wipe
|
||||
wipegamestate = -1;
|
||||
|
||||
if (player->starpostnum) // SRB2kart
|
||||
starpost = true;
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (camera[i].chase)
|
||||
P_ResetCamera(&players[displayplayers[i]], &camera[i]);
|
||||
}
|
||||
|
||||
// clear cmd building stuff
|
||||
memset(gamekeydown, 0, sizeof (gamekeydown));
|
||||
for (i = 0;i < JOYAXISSET; i++)
|
||||
{
|
||||
joyxmove[i] = joyymove[i] = 0;
|
||||
joy2xmove[i] = joy2ymove[i] = 0;
|
||||
joy3xmove[i] = joy3ymove[i] = 0;
|
||||
joy4xmove[i] = joy4ymove[i] = 0;
|
||||
}
|
||||
mousex = mousey = 0;
|
||||
mouse2x = mouse2y = 0;
|
||||
|
||||
// clear hud messages remains (usually from game startup)
|
||||
CON_ClearHUD();
|
||||
|
||||
// Starpost support
|
||||
G_SpawnPlayer(playernum, starpost);
|
||||
|
||||
if (botingame)
|
||||
{ // Bots respawn next to their master.
|
||||
players[displayplayers[1]].playerstate = PST_REBORN;
|
||||
G_SpawnPlayer(displayplayers[1], false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LUAh_MapChange(gamemap);
|
||||
G_DoLoadLevel(true);
|
||||
}
|
||||
}*/
|
||||
else
|
||||
{
|
||||
// respawn at the start
|
||||
@@ -3156,6 +3045,8 @@ void G_AddPlayer(INT32 playernum)
|
||||
|
||||
void G_ExitLevel(void)
|
||||
{
|
||||
G_ResetAllDeviceRumbles();
|
||||
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
gameaction = ga_completed;
|
||||
@@ -3184,13 +3075,6 @@ const char *Gametype_Names[NUMGAMETYPES] =
|
||||
{
|
||||
"Race", // GT_RACE
|
||||
"Battle" // GT_MATCH
|
||||
|
||||
/*"Co-op", // GT_COOP
|
||||
"Competition", // GT_COMPETITION
|
||||
"Team Match", // GT_TEAMMATCH
|
||||
"Tag", // GT_TAG
|
||||
"Hide and Seek", // GT_HIDEANDSEEK
|
||||
"CTF" // GT_CTF*/
|
||||
};
|
||||
|
||||
//
|
||||
@@ -3252,12 +3136,7 @@ boolean G_GametypeHasTeams(void)
|
||||
//
|
||||
boolean G_GametypeHasSpectators(void)
|
||||
{
|
||||
// SRB2Kart: We don't have any exceptions to not being able to spectate yet. Maybe when SP & bots roll around.
|
||||
#if 0
|
||||
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
|
||||
#else
|
||||
return (netgame || (multiplayer && demo.playback)); //true
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -4292,14 +4171,11 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
||||
// gameaction = ga_nothing;
|
||||
// G_SetGamestate(GS_LEVEL);
|
||||
displayplayers[0] = consoleplayer;
|
||||
multiplayer = false;
|
||||
splitscreen = 0;
|
||||
SplitScreen_OnChange(); // not needed?
|
||||
|
||||
// G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1);
|
||||
if (setsizeneeded)
|
||||
R_ExecuteSetViewSize();
|
||||
|
||||
@@ -4446,6 +4322,11 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
||||
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
|
||||
players[i].lives = 1; // SRB2Kart
|
||||
|
||||
// This should be cleared in P_SpawnPlayer but address sanitizer says "use-after-free"
|
||||
// when reloading map sometimes
|
||||
players[i].awayviewtics = 0;
|
||||
players[i].awayviewmobj = NULL;
|
||||
|
||||
// The latter two should clear by themselves, but just in case
|
||||
players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS);
|
||||
|
||||
@@ -4499,6 +4380,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
||||
else
|
||||
{
|
||||
LUAh_MapChange(gamemap);
|
||||
S_CheckMap();
|
||||
G_DoLoadLevel(resetplayer);
|
||||
}
|
||||
|
||||
@@ -4660,8 +4542,7 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (apromapnum == 0 || wanttable)
|
||||
else if (apromapnum == 0 || wanttable)
|
||||
{
|
||||
/* LEVEL 1--match keywords verbatim */
|
||||
if (( aprop = strcasestr(realmapname, mapname) ))
|
||||
@@ -4752,6 +4633,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
|
||||
{
|
||||
if (mapname[0] == '*') // current map
|
||||
return gamemap;
|
||||
else if (mapname[0] == '?' && mapheaderinfo[gamemap-1])
|
||||
return G_RandMap(G_TOLFlag(gametype), gamemap-1, false, 0, false, NULL)+1;
|
||||
else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map
|
||||
{
|
||||
newmapnum = mapheaderinfo[gamemap-1]->nextlevel;
|
||||
@@ -6503,8 +6386,18 @@ void G_BeginRecording(void)
|
||||
// Full replay title
|
||||
demo_p += 64;
|
||||
{
|
||||
char demotitlename[65];
|
||||
char *title = G_BuildMapTitle(gamemap);
|
||||
snprintf(demo.titlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
|
||||
|
||||
// Print to a separate temp buffer instead of demo.titlename, so we can use it in M_TextInputSetString
|
||||
snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
|
||||
|
||||
// Init just in case it isn't initialized already
|
||||
M_TextInputInit(&demo.titlenameinput, demo.titlename, sizeof(demo.titlename));
|
||||
|
||||
// This will indirectly assign to demo.titlename too
|
||||
M_TextInputSetString(&demo.titlenameinput, demotitlename);
|
||||
|
||||
Z_Free(title);
|
||||
}
|
||||
|
||||
@@ -7161,6 +7054,57 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
Z_Free(infobuffer);
|
||||
}
|
||||
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo)
|
||||
{
|
||||
UINT8 infobuffer[96], *info_p;
|
||||
UINT16 pdemoversion;
|
||||
size_t count;
|
||||
|
||||
FILE *handle = fopen(pdemo->filepath, "rb");
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
count = fread(infobuffer, 1, 96, handle);
|
||||
fclose(handle);
|
||||
info_p = infobuffer;
|
||||
|
||||
// First check isn't too accurate technically, but well, valid replays should be larger than that anyway
|
||||
if (count < 96 || memcmp(info_p, DEMOHEADER, 12))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
info_p += 12; // DEMOHEADER
|
||||
|
||||
READUINT8(info_p);
|
||||
READUINT8(info_p);
|
||||
pdemoversion = READUINT16(info_p);
|
||||
|
||||
switch(pdemoversion)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
// demo title
|
||||
M_Memcpy(pdemo->title, info_p, 64);
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
sprintf(pdemo->title, "Legacy Replay");
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// G_PlayDemo
|
||||
//
|
||||
@@ -7690,6 +7634,9 @@ post_compat:
|
||||
players[i].kartweight = kartweight[i];
|
||||
}
|
||||
|
||||
directorstate = cv_director.value;
|
||||
CV_SetValue(&cv_director, 0);
|
||||
|
||||
demo.deferstart = true;
|
||||
}
|
||||
#undef SKIPERRORS
|
||||
@@ -7820,9 +7767,6 @@ void G_AddGhost(char *defdemoname)
|
||||
case ATTACKING_RECORD: // 1
|
||||
p += 8; // demo time, lap
|
||||
break;
|
||||
/*case ATTACKING_NIGHTS: // 2
|
||||
p += 8; // demo time left, score
|
||||
break;*/
|
||||
default: // 3
|
||||
break;
|
||||
}
|
||||
@@ -8256,6 +8200,11 @@ void G_StopDemo(void)
|
||||
{
|
||||
Z_Free(demobuffer);
|
||||
demobuffer = NULL;
|
||||
if (demo.playback)
|
||||
{
|
||||
CV_SetValue(&cv_director, directorstate);
|
||||
directorstate = 0;
|
||||
}
|
||||
demo.playback = false;
|
||||
if (demo.title)
|
||||
modeattacking = false;
|
||||
@@ -8438,7 +8387,6 @@ void G_SaveDemo(void)
|
||||
|
||||
boolean G_DemoTitleResponder(event_t *ev)
|
||||
{
|
||||
size_t len;
|
||||
INT32 ch;
|
||||
|
||||
if (ev->type != ev_keydown)
|
||||
@@ -8459,28 +8407,7 @@ boolean G_DemoTitleResponder(event_t *ev)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|
||||
|| ch == ' ') // Allow spaces, of course
|
||||
{
|
||||
len = strlen(demo.titlename);
|
||||
if (len < 64)
|
||||
{
|
||||
demo.titlename[len+1] = 0;
|
||||
demo.titlename[len] = cv_keyboardlayout.value == 3 ? CON_ShitAndAltGrChar(ch) : CON_ShiftChar(ch);
|
||||
}
|
||||
}
|
||||
else if (ch == KEY_BACKSPACE)
|
||||
{
|
||||
if (shiftdown)
|
||||
memset(demo.titlename, 0, sizeof(demo.titlename));
|
||||
else
|
||||
{
|
||||
len = strlen(demo.titlename);
|
||||
|
||||
if (len > 0)
|
||||
demo.titlename[len-1] = 0;
|
||||
}
|
||||
}
|
||||
M_TextInputHandle(&demo.titlenameinput, ch);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -8565,4 +8492,3 @@ INT32 G_TicsToMilliseconds(tic_t tics)
|
||||
{
|
||||
return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
|
||||
}
|
||||
|
||||
+8
-11
@@ -17,6 +17,7 @@
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_event.h"
|
||||
#include "m_textinput.h"
|
||||
|
||||
extern char gamedatafilename[64];
|
||||
extern char timeattackfolder[64];
|
||||
@@ -39,11 +40,12 @@ extern UINT8 *demo_p;
|
||||
// ======================================
|
||||
|
||||
// demoplaying back and demo recording
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize;
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize, cv_demochangemap;
|
||||
|
||||
// Publicly-accessible demo vars
|
||||
struct demovars_s {
|
||||
char titlename[65];
|
||||
textinput_t titlenameinput;
|
||||
boolean recording, playback, timing;
|
||||
UINT16 version; // Current file format of the demo being played
|
||||
boolean title; // Title Screen demo can be cancelled by any key
|
||||
@@ -218,6 +220,8 @@ extern angle_t localangle[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
|
||||
extern boolean camspin[MAXSPLITSCREENPLAYERS]; // SRB2Kart
|
||||
|
||||
extern tic_t directortoggletimer;
|
||||
|
||||
//
|
||||
// GAME
|
||||
//
|
||||
@@ -265,6 +269,7 @@ void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar
|
||||
void G_DoLoadLevel(boolean resetplayer);
|
||||
|
||||
void G_LoadDemoInfo(menudemo_t *pdemo);
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
||||
@@ -414,19 +419,9 @@ void G_SetGamestate(gamestate_t newstate);
|
||||
|
||||
// Gamedata record shit
|
||||
void G_AllocMainRecordData(INT16 i);
|
||||
//void G_AllocNightsRecordData(INT16 i);
|
||||
void G_ClearRecords(void);
|
||||
|
||||
//UINT32 G_GetBestScore(INT16 map);
|
||||
tic_t G_GetBestTime(INT16 map);
|
||||
//tic_t G_GetBestLap(INT16 map);
|
||||
//UINT16 G_GetBestRings(INT16 map);
|
||||
//UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare);
|
||||
//tic_t G_GetBestNightsTime(INT16 map, UINT8 mare);
|
||||
//UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare);
|
||||
|
||||
//void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare);
|
||||
//void G_SetNightsRecords(void);
|
||||
|
||||
FUNCMATH INT32 G_TicsToHours(tic_t tics);
|
||||
FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full);
|
||||
@@ -434,6 +429,8 @@ FUNCMATH INT32 G_TicsToSeconds(tic_t tics);
|
||||
FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
|
||||
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
|
||||
|
||||
boolean K_DirectorIsPlayerAlone(void); // idk where else to put this lol
|
||||
|
||||
// Don't split up TOL handling
|
||||
INT16 G_TOLFlag(INT32 pgametype);
|
||||
|
||||
|
||||
+231
@@ -14,11 +14,17 @@
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "g_input.h"
|
||||
#include "g_game.h"
|
||||
#include "keys.h"
|
||||
#include "hu_stuff.h" // need HUFONT start & end
|
||||
#include "d_net.h"
|
||||
#include "console.h"
|
||||
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "r_draw.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
||||
|
||||
static CV_PossibleValue_t mousesens_cons_t[] = {{1, "MIN"}, {MAXMOUSESENSITIVITY, "MAX"}, {0, NULL}};
|
||||
@@ -33,6 +39,89 @@ consvar_t cv_mouseysens2 = {"mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL
|
||||
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_turnsmooth = {"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static void G_ResetPlayerDeviceRumble(INT32 player);
|
||||
static void rumble_off_handle(void);
|
||||
static void rumble_off_handle2(void);
|
||||
static void rumble_off_handle3(void);
|
||||
static void rumble_off_handle4(void);
|
||||
|
||||
static void G_ResetPlayerGamepadIndicatorColor(INT32 player);
|
||||
static void led_off_handle(void);
|
||||
static void led_off_handle2(void);
|
||||
static void led_off_handle3(void);
|
||||
static void led_off_handle4(void);
|
||||
|
||||
consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = {
|
||||
{"rumble", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumble2", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle2, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumble3", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle3, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumble4", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle4, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
|
||||
{"gamepadled", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"gamepadled2", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"gamepadled3", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"gamepadled4", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS] = {
|
||||
{"ledpowerup", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"ledpowerup2", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"ledpowerup3", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"ledpowerup4", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
static void rumble_off_handle(void)
|
||||
{
|
||||
if (cv_rumble[0].value == 0)
|
||||
G_ResetPlayerDeviceRumble(0);
|
||||
}
|
||||
|
||||
|
||||
static void rumble_off_handle2(void)
|
||||
{
|
||||
if (cv_rumble[1].value == 0)
|
||||
G_ResetPlayerDeviceRumble(1);
|
||||
}
|
||||
|
||||
|
||||
static void rumble_off_handle3(void)
|
||||
{
|
||||
if (cv_rumble[2].value == 0)
|
||||
G_ResetPlayerDeviceRumble(2);
|
||||
}
|
||||
|
||||
|
||||
static void rumble_off_handle4(void)
|
||||
{
|
||||
if (cv_rumble[3].value == 0)
|
||||
G_ResetPlayerDeviceRumble(3);
|
||||
}
|
||||
|
||||
static void led_off_handle(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(0);
|
||||
}
|
||||
|
||||
|
||||
static void led_off_handle2(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(1);
|
||||
}
|
||||
|
||||
|
||||
static void led_off_handle3(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(2);
|
||||
}
|
||||
|
||||
|
||||
static void led_off_handle4(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(3);
|
||||
}
|
||||
|
||||
INT32 mousex, mousey;
|
||||
INT32 mlooky; // like mousey but with a custom sensitivity for mlook
|
||||
|
||||
@@ -812,10 +901,152 @@ static const char *gamecontrolname[num_gamecontrols] =
|
||||
"custom1",
|
||||
"custom2",
|
||||
"custom3",
|
||||
"director",
|
||||
};
|
||||
|
||||
#define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t))
|
||||
|
||||
#include "k_kart.h"
|
||||
|
||||
INT32 G_GetDeviceForPlayer(INT32 player)
|
||||
{
|
||||
switch (player)
|
||||
{
|
||||
case 0:
|
||||
return cv_usejoystick.value;
|
||||
break;
|
||||
case 1:
|
||||
return cv_usejoystick2.value;
|
||||
break;
|
||||
case 2:
|
||||
return cv_usejoystick3.value;
|
||||
break;
|
||||
case 3:
|
||||
return cv_usejoystick4.value;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline UINT16 G_GetSkinColor(INT32 player)
|
||||
{
|
||||
// make rgb rainbow vomit when invul or flash blue when grow
|
||||
if (cv_ledpowerup[player].value && gamestate == GS_LEVEL && players[displayplayers[player]].mo && (players[displayplayers[player]].kartstuff[k_invincibilitytimer] || players[displayplayers[player]].powers[pw_invulnerability] || players[displayplayers[player]].kartstuff[k_growshrinktimer]))
|
||||
return players[displayplayers[player]].mo->color;
|
||||
|
||||
// take actual player skincolour when ingame
|
||||
if (gamestate == GS_LEVEL && players[displayplayers[player]].skincolor)
|
||||
return players[displayplayers[player]].skincolor;
|
||||
|
||||
// otherwise just fallback to whatever the cvar is
|
||||
switch (player)
|
||||
{
|
||||
case 0:
|
||||
return cv_playercolor.value;
|
||||
break;
|
||||
case 1:
|
||||
return cv_playercolor2.value;
|
||||
break;
|
||||
case 2:
|
||||
return cv_playercolor3.value;
|
||||
break;
|
||||
case 3:
|
||||
return cv_playercolor4.value;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color)
|
||||
{
|
||||
INT32 device;
|
||||
UINT16 skincolor;
|
||||
byteColor_t byte_color;
|
||||
|
||||
I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS);
|
||||
|
||||
if (cv_gamepadled[player].value == 0)
|
||||
return;
|
||||
|
||||
device = G_GetDeviceForPlayer(player);
|
||||
|
||||
if (device <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
skincolor = color ? color : G_GetSkinColor(player);
|
||||
byte_color = V_GetColor(colortranslations[skincolor][8]).s;
|
||||
|
||||
I_SetGamepadIndicatorColor(device, byte_color.red, byte_color.green, byte_color.blue);
|
||||
}
|
||||
|
||||
static void G_ResetPlayerGamepadIndicatorColor(INT32 player)
|
||||
{
|
||||
if (cv_gamepadled[player].value == 0)
|
||||
{
|
||||
INT32 device = G_GetDeviceForPlayer(player);
|
||||
if (device <= 0)
|
||||
return;
|
||||
|
||||
I_SetGamepadIndicatorColor(device, 0, 0, 255);
|
||||
}
|
||||
else
|
||||
G_SetPlayerGamepadIndicatorColor(player, 0);
|
||||
}
|
||||
|
||||
static void G_ResetPlayerDeviceRumble(INT32 player)
|
||||
{
|
||||
INT32 device_id;
|
||||
|
||||
device_id = G_GetDeviceForPlayer(player);
|
||||
|
||||
if (device_id < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
I_GamepadRumble(device_id, 0, 0, 0);
|
||||
}
|
||||
|
||||
void G_ResetAllDeviceRumbles(void)
|
||||
{
|
||||
int i;
|
||||
int devices;
|
||||
|
||||
devices = I_NumJoys();
|
||||
|
||||
for (i = 0; i < devices; i++)
|
||||
{
|
||||
INT32 device_id = G_GetDeviceForPlayer(i);
|
||||
|
||||
I_GamepadRumble(device_id, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
|
||||
{
|
||||
INT32 device_id;
|
||||
|
||||
if (cv_rumble[player].value == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
device_id = G_GetDeviceForPlayer(player);
|
||||
|
||||
if (device_id < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
I_GamepadRumble(device_id, low_strength, high_strength, duration);
|
||||
}
|
||||
|
||||
//
|
||||
// Detach any keys associated to the given game control
|
||||
// - pass the pointer to the gamecontrol table for the player being edited
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define __G_INPUT__
|
||||
|
||||
#include "d_event.h"
|
||||
#include "doomstat.h"
|
||||
#include "keys.h"
|
||||
#include "command.h"
|
||||
|
||||
@@ -98,6 +99,7 @@ typedef enum
|
||||
gc_custom1, // Lua scriptable
|
||||
gc_custom2, // Lua scriptable
|
||||
gc_custom3, // Lua scriptable
|
||||
gc_director,
|
||||
num_gamecontrols
|
||||
} gamecontrols_e;
|
||||
|
||||
@@ -105,6 +107,9 @@ typedef enum
|
||||
extern consvar_t cv_mousesens, cv_mouseysens;
|
||||
extern consvar_t cv_mousesens2, cv_mouseysens2;
|
||||
extern consvar_t cv_controlperkey, cv_turnsmooth;
|
||||
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern INT32 mousex, mousey;
|
||||
extern INT32 mlooky; //mousey with mlookSensitivity
|
||||
@@ -129,6 +134,12 @@ extern INT32 gamecontrol4[num_gamecontrols][2];
|
||||
// peace to my little coder fingers!
|
||||
// check a gamecontrol being active or not
|
||||
|
||||
UINT16 G_GetSkinColor(INT32 player);
|
||||
INT32 G_GetDeviceForPlayer(INT32 player);
|
||||
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color);
|
||||
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
|
||||
void G_ResetAllDeviceRumbles(void);
|
||||
|
||||
// remaps the input event to a game control.
|
||||
void G_MapEventsToControls(event_t *ev);
|
||||
|
||||
|
||||
+57
-57
@@ -35,7 +35,7 @@ int finalVertexArrayAllocSize = 65536;
|
||||
|
||||
PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed
|
||||
int polygonArraySize = 0;
|
||||
UINT32* polygonIndexArray = NULL;// contains sorting pointers for polygonArray
|
||||
PolygonArrayEntry **polygonArraySorted = NULL;// contains sorted pointers to polygonArray
|
||||
int polygonArrayAllocSize = 65536;
|
||||
|
||||
FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon
|
||||
@@ -47,7 +47,9 @@ int unsortedVertexArrayAllocSize = 65536;
|
||||
void HWR_StartBatching(void)
|
||||
{
|
||||
if (currently_batching)
|
||||
{
|
||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||
}
|
||||
|
||||
// init arrays if that has not been done yet
|
||||
if (!finalVertexArray)
|
||||
@@ -55,7 +57,7 @@ void HWR_StartBatching(void)
|
||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||
finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
|
||||
polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
|
||||
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||
}
|
||||
|
||||
@@ -96,8 +98,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||
free(polygonArray);
|
||||
polygonArray = new_array;
|
||||
// also need to redo the index array, dont need to copy it though
|
||||
free(polygonIndexArray);
|
||||
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
|
||||
free(polygonArraySorted);
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
}
|
||||
|
||||
while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize)
|
||||
@@ -134,10 +136,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||
|
||||
static int comparePolygons(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int index1 = *(const unsigned int*)p1;
|
||||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
UINT32 downloaded1 = 0;
|
||||
@@ -155,7 +155,7 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (shader1 == -1 && shader2 == -1)
|
||||
return index1 - index2;
|
||||
return poly1 - poly2;
|
||||
|
||||
if (poly1->texture)
|
||||
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
@@ -184,10 +184,8 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int index1 = *(const unsigned int*)p1;
|
||||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
|
||||
@@ -205,7 +203,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
downloaded2 = texture2->downloaded;
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (!texture1 && !texture2)
|
||||
return index1 - index2;
|
||||
return poly1 - poly2;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
@@ -225,7 +223,7 @@ void HWR_RenderBatches(void)
|
||||
int finalVertexWritePos = 0;// position in finalVertexArray
|
||||
int finalIndexWritePos = 0;// position in finalVertexIndexArray
|
||||
|
||||
int polygonReadPos = 0;// position in polygonIndexArray
|
||||
int polygonReadPos = 0;// position in polygonArraySorted
|
||||
|
||||
int currentShader;
|
||||
int nextShader = 0;
|
||||
@@ -258,18 +256,18 @@ void HWR_RenderBatches(void)
|
||||
ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0;
|
||||
ps_hw_numshaders.value.i = ps_hw_numtextures.value.i
|
||||
= ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1;
|
||||
// init polygonIndexArray
|
||||
// init polygonArraySorted
|
||||
for (i = 0; i < polygonArraySize; i++)
|
||||
{
|
||||
polygonIndexArray[i] = i;
|
||||
polygonArraySorted[i] = &polygonArray[i];
|
||||
}
|
||||
|
||||
// sort polygons
|
||||
PS_START_TIMING(ps_hw_batchsorttime);
|
||||
if (cv_grshaders.value && gr_shadersavailable)
|
||||
qs22j(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygons);
|
||||
else
|
||||
qs22j(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygonsNoShaders);
|
||||
PS_STOP_TIMING(ps_hw_batchsorttime);
|
||||
// sort order
|
||||
// 1. shader
|
||||
@@ -280,10 +278,10 @@ void HWR_RenderBatches(void)
|
||||
|
||||
PS_START_TIMING(ps_hw_batchdrawtime);
|
||||
|
||||
currentShader = polygonArray[polygonIndexArray[0]].shader;
|
||||
currentTexture = polygonArray[polygonIndexArray[0]].texture;
|
||||
currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags;
|
||||
currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf;
|
||||
currentShader = polygonArraySorted[0]->shader;
|
||||
currentTexture = polygonArraySorted[0]->texture;
|
||||
currentPolyFlags = polygonArraySorted[0]->polyFlags;
|
||||
currentSurfaceInfo = polygonArraySorted[0]->surf;
|
||||
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
|
||||
// and a color array could replace the color calls.
|
||||
|
||||
@@ -322,8 +320,8 @@ void HWR_RenderBatches(void)
|
||||
// reset write pos
|
||||
// repeat loop
|
||||
|
||||
int index = polygonIndexArray[polygonReadPos++];
|
||||
int numVerts = polygonArray[index].numVerts;
|
||||
PolygonArrayEntry *entry = polygonArraySorted[polygonReadPos++];
|
||||
int numVerts = entry->numVerts;
|
||||
// before writing, check if there is enough room
|
||||
// using 'while' instead of 'if' here makes sure that there will *always* be enough room.
|
||||
// probably never will this loop run more than once though
|
||||
@@ -344,7 +342,7 @@ void HWR_RenderBatches(void)
|
||||
finalVertexIndexArray = new_index_array;
|
||||
}
|
||||
// write the vertices of the polygon
|
||||
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex],
|
||||
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[entry->vertsIndex],
|
||||
numVerts * sizeof(FOutVector));
|
||||
// write the indexes, pointing to the fan vertexes but in triangles format
|
||||
firstIndex = finalVertexWritePos;
|
||||
@@ -364,11 +362,11 @@ void HWR_RenderBatches(void)
|
||||
else
|
||||
{
|
||||
// check if a state change is required, set the change bools and next vars
|
||||
int nextIndex = polygonIndexArray[polygonReadPos];
|
||||
nextShader = polygonArray[nextIndex].shader;
|
||||
nextTexture = polygonArray[nextIndex].texture;
|
||||
nextPolyFlags = polygonArray[nextIndex].polyFlags;
|
||||
nextSurfaceInfo = polygonArray[nextIndex].surf;
|
||||
PolygonArrayEntry *nextEntry = polygonArraySorted[polygonReadPos];
|
||||
nextShader = nextEntry->shader;
|
||||
nextTexture = nextEntry->texture;
|
||||
nextPolyFlags = nextEntry->polyFlags;
|
||||
nextSurfaceInfo = nextEntry->surf;
|
||||
if (nextPolyFlags & PF_NoTexture)
|
||||
nextTexture = 0;
|
||||
if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable)
|
||||
@@ -426,38 +424,40 @@ void HWR_RenderBatches(void)
|
||||
if (stopFlag) break;
|
||||
|
||||
// change state according to change bools and next vars, update current vars and reset bools
|
||||
if (changeShader)
|
||||
if (changeState)
|
||||
{
|
||||
HWD.pfnSetShader(nextShader);
|
||||
currentShader = nextShader;
|
||||
changeShader = false;
|
||||
if (changeShader)
|
||||
{
|
||||
HWD.pfnSetShader(nextShader);
|
||||
currentShader = nextShader;
|
||||
changeShader = false;
|
||||
|
||||
ps_hw_numshaders.value.i++;
|
||||
}
|
||||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
ps_hw_numshaders.value.i++;
|
||||
}
|
||||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
|
||||
ps_hw_numtextures.value.i++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
{
|
||||
currentPolyFlags = nextPolyFlags;
|
||||
changePolyFlags = false;
|
||||
ps_hw_numtextures.value.i++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
{
|
||||
currentPolyFlags = nextPolyFlags;
|
||||
changePolyFlags = false;
|
||||
|
||||
ps_hw_numpolyflags.value.i++;
|
||||
}
|
||||
if (changeSurfaceInfo)
|
||||
{
|
||||
currentSurfaceInfo = nextSurfaceInfo;
|
||||
changeSurfaceInfo = false;
|
||||
ps_hw_numpolyflags.value.i++;
|
||||
}
|
||||
if (changeSurfaceInfo)
|
||||
{
|
||||
currentSurfaceInfo = nextSurfaceInfo;
|
||||
changeSurfaceInfo = false;
|
||||
|
||||
ps_hw_numcolors.value.i++;
|
||||
ps_hw_numcolors.value.i++;
|
||||
}
|
||||
}
|
||||
// and that should be it?
|
||||
}
|
||||
// reset the arrays (set sizes to 0)
|
||||
polygonArraySize = 0;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "hw_data.h"
|
||||
#include "hw_drv.h"
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
|
||||
unsigned int vertsIndex;// location of verts in unsortedVertexArray
|
||||
|
||||
+18
-8
@@ -667,9 +667,15 @@ static boolean PointInSeg(polyvertex_t *a,polyvertex_t *v1,polyvertex_t *v2)
|
||||
// v1 = origine
|
||||
ax= v2->x-v1->x;
|
||||
ay= v2->y-v1->y;
|
||||
norm = (float)hypot(ax, ay);
|
||||
ax /= norm;
|
||||
ay /= norm;
|
||||
norm = hypotf(ax, ay);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
if (norm != 0) // yes, this can be exactly 0
|
||||
#pragma GCC diagnostic pop
|
||||
{
|
||||
ax /= norm;
|
||||
ay /= norm;
|
||||
}
|
||||
bx = a->x-v1->x;
|
||||
by = a->y-v1->y;
|
||||
//d = a.b
|
||||
@@ -772,9 +778,11 @@ static INT32 SolveTProblem(void)
|
||||
for (l = 0; l < addsubsector; l++)
|
||||
{
|
||||
p = extrasubsectors[l].planepoly;
|
||||
if (p)
|
||||
for (i = 0; i < p->numpts; i++)
|
||||
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < p->numpts; i++)
|
||||
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
|
||||
}
|
||||
//CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
|
||||
return numsplitpoly;
|
||||
@@ -802,8 +810,10 @@ static void AdjustSegs(void)
|
||||
count = subsectors[i].numlines;
|
||||
lseg = &segs[subsectors[i].firstline];
|
||||
p = extrasubsectors[i].planepoly;
|
||||
//if (!p)
|
||||
//continue;
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
for (; count--; lseg++)
|
||||
{
|
||||
float distv1,distv2,tmp;
|
||||
|
||||
+19
-14
@@ -379,18 +379,19 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe
|
||||
blockwidth, blockheight,
|
||||
texture, patch,
|
||||
realpatch);
|
||||
Z_Unlock(realpatch);
|
||||
Z_ChangeTag(realpatch, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
|
||||
if (format2bpp(grtex->mipmap.format)==4)
|
||||
{
|
||||
for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp
|
||||
{
|
||||
if (block[i] == 0)
|
||||
{
|
||||
grtex->mipmap.flags |= TF_TRANSPARENT;
|
||||
break;
|
||||
}
|
||||
if (block[i] != 0)
|
||||
continue;
|
||||
|
||||
grtex->mipmap.flags |= TF_TRANSPARENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +573,6 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grtex->mipmap.downloaded)
|
||||
HWD.pfnSetTexture(&grtex->mipmap);
|
||||
|
||||
HWR_SetCurrentTexture(&grtex->mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
@@ -629,8 +629,12 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
||||
#ifdef GLENCORE
|
||||
flat = grMipmap->data;
|
||||
for (steppy = 0; steppy < size; steppy++)
|
||||
if (flat[steppy] != HWR_PATCHES_CHROMAKEY_COLORINDEX)
|
||||
flat[steppy] = grMipmap->colormap[flat[steppy]];
|
||||
{
|
||||
if (flat[steppy] == HWR_PATCHES_CHROMAKEY_COLORINDEX)
|
||||
continue;
|
||||
|
||||
flat[steppy] = grMipmap->colormap[flat[steppy]];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -743,11 +747,12 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
|
||||
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
|
||||
{
|
||||
grmip = grmip->nextcolormap;
|
||||
if (grmip->colormap == colormap)
|
||||
{
|
||||
HWR_LoadMappedPatch(grmip, gpatch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (grmip->colormap != colormap)
|
||||
continue;
|
||||
|
||||
HWR_LoadMappedPatch(grmip, gpatch);
|
||||
return;
|
||||
}
|
||||
// not found, create it!
|
||||
// If we are here, the sprite with the current colormap is not already in hardware memory
|
||||
|
||||
@@ -337,16 +337,16 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
|
||||
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * clipfov / 90.0f;
|
||||
if (floatangle >= 180.0)
|
||||
return 0xffffffff;
|
||||
a1 = ANG1 * (int)floatangle;
|
||||
a1 = (angle_t)(ANG1 * (int)floatangle);
|
||||
return a1;
|
||||
}
|
||||
|
||||
|
||||
// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either
|
||||
// compiler complains about (p)glGetFloatv anyway, in case anyone wants this
|
||||
// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks
|
||||
// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h
|
||||
#ifdef HAVE_SPHEREFRUSTRUM
|
||||
|
||||
//
|
||||
// gld_FrustumSetup
|
||||
//
|
||||
|
||||
@@ -44,7 +44,6 @@ struct GLMipmap_s
|
||||
UINT16 width, height;
|
||||
UINT32 downloaded; // tex_downloaded
|
||||
|
||||
struct GLMipmap_s *nextmipmap;
|
||||
struct GLMipmap_s *nextcolormap;
|
||||
const UINT8 *colormap;
|
||||
};
|
||||
|
||||
@@ -156,7 +156,7 @@ typedef struct
|
||||
boolean mirrorflip; // Encore Mode with Flipcam
|
||||
#endif
|
||||
boolean shearing; // 14042019
|
||||
angle_t viewaiming; // 17052019
|
||||
float viewaiming; // 17052019
|
||||
} FTransform;
|
||||
|
||||
// Transformed vector, as passed to HWR API
|
||||
@@ -173,10 +173,10 @@ enum
|
||||
{
|
||||
SHADER_NONE = -1,
|
||||
SHADER_FLOOR = 0,
|
||||
SHADER_SHADOW,
|
||||
SHADER_WALL,
|
||||
SHADER_SPRITECLIPHACK,
|
||||
SHADER_MODEL,
|
||||
SHADER_SPRITE,
|
||||
SHADER_MODEL,
|
||||
SHADER_WATER,
|
||||
SHADER_FOG,
|
||||
SHADER_SKY,
|
||||
|
||||
@@ -28,11 +28,10 @@ typedef struct gr_vissprite_s
|
||||
float x1, x2;
|
||||
float z1, z2;
|
||||
float gz, gzt;
|
||||
float tz, ty;
|
||||
float tz;
|
||||
float scale;
|
||||
float spritexscale, spriteyscale;
|
||||
float spritexoffset, spriteyoffset;
|
||||
UINT32 renderflags;
|
||||
GLPatch_t *gpatch;
|
||||
boolean flip;
|
||||
UINT8 translucency; //alpha level 0-255
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
|
||||
#include "../doomdef.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hw_light.h"
|
||||
#include "hw_drv.h"
|
||||
#include "../i_video.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../m_random.h"
|
||||
#include "../m_bbox.h"
|
||||
#include "../w_wad.h"
|
||||
#include "../r_state.h"
|
||||
#include "../r_main.h"
|
||||
#include "../p_local.h"
|
||||
|
||||
#endif // HWRENDER
|
||||
@@ -1,20 +0,0 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief Dynamic lighting & coronas add on by Hurdler
|
||||
|
||||
#ifndef _HW_LIGHTS_
|
||||
#define _HW_LIGHTS_
|
||||
|
||||
#include "hw_glob.h"
|
||||
#include "hw_defs.h"
|
||||
|
||||
#endif
|
||||
+905
-1254
File diff suppressed because it is too large.
Load diff
+2
-14
@@ -116,11 +116,10 @@ void HWR_MakeScreenFinalTexture(void);
|
||||
void HWR_DrawScreenFinalTexture(INT32 width, INT32 height);
|
||||
|
||||
// hw_main.c: Planes
|
||||
void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
//void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
|
||||
|
||||
void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
void HWR_AddPolyObjectPlanes(void);
|
||||
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
|
||||
|
||||
// hw_main.c: Segs
|
||||
@@ -132,14 +131,6 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 t
|
||||
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
|
||||
void HWR_DrawSkyBackground(float fpov);
|
||||
|
||||
void HWR_AddPolyObjectSegs(void);
|
||||
|
||||
// hw_main.c: Sprites
|
||||
void HWR_AddSprites(sector_t *sec);
|
||||
void HWR_ProjectSprite(mobj_t *thing);
|
||||
void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
void HWR_DrawSprites(void);
|
||||
|
||||
// hw_bsp.c
|
||||
void HWR_CreatePlanePolygons(INT32 bspnum);
|
||||
extern boolean gr_maphasportals;
|
||||
@@ -155,10 +146,6 @@ extern consvar_t cv_grshaders;
|
||||
#ifdef USE_FBO_OGL
|
||||
extern consvar_t cv_grframebuffer;
|
||||
#endif
|
||||
extern consvar_t cv_grfofcut;
|
||||
extern consvar_t cv_fofzfightfix;
|
||||
extern consvar_t cv_splitwallfix;
|
||||
extern consvar_t cv_slopepegfix;
|
||||
extern consvar_t cv_grshearing;
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmdls;
|
||||
@@ -179,6 +166,7 @@ extern consvar_t cv_grrenderdistance;
|
||||
extern consvar_t cv_grpaletterendering;
|
||||
extern consvar_t cv_grpalettedepth;
|
||||
extern consvar_t cv_grflashpal;
|
||||
extern consvar_t cv_lightdither;
|
||||
extern consvar_t cv_grscreentextures;
|
||||
extern consvar_t cv_grportals;
|
||||
extern consvar_t cv_nostencil;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hw_drv.h"
|
||||
#include "hw_light.h"
|
||||
#include "hw_md2.h"
|
||||
#include "../d_main.h"
|
||||
#include "../r_bsp.h"
|
||||
@@ -75,7 +74,7 @@
|
||||
|
||||
md2_t md2_models[NUMSPRITES];
|
||||
md2_t md2_playermodels[MAXSKINS];
|
||||
md2_t md2_localplayermodels[MAXSKINS];
|
||||
md2_t md2_localplayermodels[MAXLOCALSKINS];
|
||||
|
||||
|
||||
/*
|
||||
@@ -494,7 +493,9 @@ void HWR_InitMD2(void)
|
||||
md2_playermodels[s].skin = -1;
|
||||
md2_playermodels[s].notfound = true;
|
||||
md2_playermodels[s].error = false;
|
||||
|
||||
}
|
||||
for (s = 0; s < MAXLOCALSKINS; s++)
|
||||
{
|
||||
md2_localplayermodels[s].scale = -1.0f;
|
||||
md2_localplayermodels[s].model = NULL;
|
||||
md2_localplayermodels[s].grpatch = NULL;
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct
|
||||
|
||||
extern md2_t md2_models[NUMSPRITES];
|
||||
extern md2_t md2_playermodels[MAXSKINS];
|
||||
extern md2_t md2_localplayermodels[MAXSKINS];
|
||||
extern md2_t md2_localplayermodels[MAXLOCALSKINS];
|
||||
|
||||
void HWR_InitMD2(void);
|
||||
void HWR_DrawMD2(gr_vissprite_t *spr);
|
||||
|
||||
+119
-5
@@ -29,15 +29,15 @@ static struct {
|
||||
// Floor shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER},
|
||||
|
||||
// Shadow shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SHADOW_FRAGMENT_SHADER},
|
||||
|
||||
// Wall shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Sprite shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Sprite clipping hack shader (for pulling things out of the floor)
|
||||
{GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Model shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
@@ -82,6 +82,7 @@ static shadertarget_t gl_shadertargets[NUMSHADERTARGETS];
|
||||
#define WHITESPACE_CHARS " \t"
|
||||
|
||||
#define PALETTE_RENDERING_DEFINE "#define SRB2_PALETTE_RENDERING"
|
||||
#define LIGHT_DITHERING_DEFINE "#define SRB2_LIGHT_DITHER"
|
||||
|
||||
// Initialize shader variables and the backend's shader system. Load the base shaders.
|
||||
// Returns false if shaders cannot be used.
|
||||
@@ -282,6 +283,9 @@ static char *HWR_PreprocessShader(char *original)
|
||||
if (cv_grpaletterendering.value)
|
||||
ADD_TO_LEN(PALETTE_RENDERING_DEFINE)
|
||||
|
||||
if (cv_lightdither.value)
|
||||
ADD_TO_LEN(LIGHT_DITHERING_DEFINE)
|
||||
|
||||
#undef ADD_TO_LEN
|
||||
|
||||
#define VERSION_PART "#version "
|
||||
@@ -323,6 +327,9 @@ static char *HWR_PreprocessShader(char *original)
|
||||
if (cv_grpaletterendering.value)
|
||||
WRITE_DEFINE(PALETTE_RENDERING_DEFINE)
|
||||
|
||||
if (cv_lightdither.value)
|
||||
WRITE_DEFINE(LIGHT_DITHERING_DEFINE)
|
||||
|
||||
#undef WRITE_DEFINE
|
||||
|
||||
// Write a #line directive, so compiler errors will report line numbers from the
|
||||
@@ -425,9 +432,9 @@ static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
|
||||
customshaderxlat_t shaderxlat[] =
|
||||
{
|
||||
{"Flat", SHADER_FLOOR},
|
||||
{"Shadow", SHADER_SHADOW},
|
||||
{"WallTexture", SHADER_WALL},
|
||||
{"Sprite", SHADER_SPRITE},
|
||||
{"SpriteClipHack", SHADER_SPRITECLIPHACK},
|
||||
{"Model", SHADER_MODEL},
|
||||
{"WaterRipple", SHADER_WATER},
|
||||
{"Fog", SHADER_FOG},
|
||||
@@ -446,6 +453,106 @@ void HWR_LoadAllCustomShaders(void)
|
||||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
static const char version_directives[][14] = {
|
||||
"#version 330\n",
|
||||
"#version 150\n",
|
||||
"#version 140\n",
|
||||
"#version 130\n",
|
||||
"#version 120\n",
|
||||
"#version 110\n",
|
||||
};
|
||||
|
||||
static boolean HWR_VersionDirectiveExists(const char* source)
|
||||
{
|
||||
return strncmp(source, "#version", 8) == 0;
|
||||
}
|
||||
|
||||
static char* HWR_PrependVersionDirective(const char* source, UINT32 version_index)
|
||||
{
|
||||
const UINT32 version_len = sizeof(version_directives[version_index]) - 1;
|
||||
const UINT32 source_len = strlen(source);
|
||||
|
||||
char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL);
|
||||
strcpy(result, version_directives[version_index]);
|
||||
strcpy(result + version_len, source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index)
|
||||
{
|
||||
shader[9] = version_directives[version_index][9];
|
||||
shader[10] = version_directives[version_index][10];
|
||||
shader[11] = version_directives[version_index][11];
|
||||
}
|
||||
|
||||
static boolean HWR_CheckVersionDirectives(const char* vert, const char* frag)
|
||||
{
|
||||
return HWR_VersionDirectiveExists(vert) && HWR_VersionDirectiveExists(frag);
|
||||
}
|
||||
|
||||
static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 shaderxlat_id)
|
||||
{
|
||||
char* vert_shader = gl_shaders[shader_index].vertex;
|
||||
char* frag_shader = gl_shaders[shader_index].fragment;
|
||||
|
||||
boolean vert_shader_version_exists = HWR_VersionDirectiveExists(vert_shader);
|
||||
boolean frag_shader_version_exists = HWR_VersionDirectiveExists(frag_shader);
|
||||
|
||||
if (!vert_shader_version_exists)
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: vertex shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
|
||||
if (!frag_shader_version_exists)
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: fragment shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
|
||||
// try to compile as is
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if (gl_shaders[shader_index].compiled)
|
||||
return;
|
||||
|
||||
// try each version directive
|
||||
for (UINT32 i = 0; i < sizeof(version_directives) / sizeof(version_directives[0]); ++i)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Trying %s\n", version_directives[i]);
|
||||
|
||||
if (!vert_shader_version_exists)
|
||||
{
|
||||
// first time reallocation would have to be made
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
void* old = (void*)gl_shaders[shader_index].vertex;
|
||||
vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i);
|
||||
Z_Free(old);
|
||||
}
|
||||
else
|
||||
HWR_ReplaceVersionInplace(vert_shader, i);
|
||||
}
|
||||
|
||||
if (!frag_shader_version_exists)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
void* old = (void*)gl_shaders[shader_index].fragment;
|
||||
frag_shader = gl_shaders[shader_index].fragment = HWR_PrependVersionDirective(frag_shader, i);
|
||||
Z_Free(old);
|
||||
}
|
||||
else
|
||||
HWR_ReplaceVersionInplace(frag_shader, i);
|
||||
}
|
||||
|
||||
HWR_CompileShader(shader_index);
|
||||
if (gl_shaders[shader_index].compiled)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Compiled with %s\n",
|
||||
version_directives[i]);
|
||||
CONS_Alert(CONS_WARNING, "Implicit GLSL version is used. Correct behavior is not guaranteed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
{
|
||||
UINT16 lump;
|
||||
@@ -602,13 +709,20 @@ skip_field:
|
||||
{
|
||||
int shader_index = i + NUMSHADERTARGETS; // index to gl_shaders
|
||||
gl_shadertargets[i].custom_shader = shader_index;
|
||||
|
||||
// if only one stage (vertex/fragment) is defined, the other one
|
||||
// is copied from the base shaders.
|
||||
if (!gl_shaders[shader_index].fragment)
|
||||
gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment);
|
||||
|
||||
if (!gl_shaders[shader_index].vertex)
|
||||
gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex);
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if (!HWR_CheckVersionDirectives(gl_shaders[shader_index].vertex, gl_shaders[shader_index].fragment))
|
||||
HWR_TryToCompileShaderWithImplicitVersion(shader_index, i);
|
||||
else
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if (!gl_shaders[shader_index].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename);
|
||||
}
|
||||
|
||||
+68
-15
@@ -31,17 +31,6 @@
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// Sprite clipping makes me want to McFucking Die
|
||||
|
||||
#define GLSL_SPRITECLIP_HACK_VERTEX_SHADER \
|
||||
"void main(void) {\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_Position.z -= 80.0 / gl_Position.z;\n" \
|
||||
"}\0"
|
||||
|
||||
// ==================
|
||||
// Fragment shaders
|
||||
// ==================
|
||||
@@ -62,15 +51,53 @@
|
||||
//
|
||||
|
||||
// Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro.
|
||||
#define GLSL_DOOM_COLORMAP_DITHER \
|
||||
"float baseValue = max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
"float endResolutionx = scr_resolution.x;\n" \
|
||||
"float endResolutiony = scr_resolution.y;\n" \
|
||||
"if (scr_resolution.x > 1280.0) {\n" \
|
||||
"endResolutionx = scr_resolution.x * 0.5;\n" \
|
||||
"}\n" \
|
||||
"if (scr_resolution.y > 720.0) {\n" \
|
||||
"endResolutiony = scr_resolution.y * 0.5;\n" \
|
||||
"}\n" \
|
||||
"float zFactor = clamp((z - 192.0) / (6144.0 - 192.0), 0.0, 1.0);\n" \
|
||||
"int scaleFactor = int(mix(1.0, 8.0, zFactor));\n" \
|
||||
"endResolutionx = endResolutionx * scaleFactor;\n" \
|
||||
"endResolutiony = endResolutiony * scaleFactor;\n" \
|
||||
"vec2 normalizedPosition = position * vec2(endResolutionx / scr_resolution.x, endResolutiony / scr_resolution.y);\n" \
|
||||
"int x = int(mod(normalizedPosition.x, 4.0));\n" \
|
||||
"int y = int(mod(normalizedPosition.y, 4.0));\n" \
|
||||
"float bayerMatrix[4*4] = float[4*4](\n" \
|
||||
"0.0, 8.0, 2.0, 10.0,\n" \
|
||||
"12.0, 4.0, 14.0, 6.0,\n" \
|
||||
"3.0, 11.0, 1.0, 9.0,\n" \
|
||||
"15.0, 7.0, 13.0, 5.0\n" \
|
||||
");\n" \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"float threshold = (1.0 - pow(zFactor, 2.0)) * (bayerMatrix[y*4 + x] / 11.0);\n" \
|
||||
"#else\n" \
|
||||
"float threshold = (1.0 - pow(zFactor, 2.0)) * (bayerMatrix[y*4 + x] / 16.0);\n" \
|
||||
"#endif\n" \
|
||||
"return mix(baseValue + threshold - 0.5 / 16.0, baseValue, zFactor);\n"
|
||||
|
||||
#define GLSL_DOOM_COLORMAP_NODITHER \
|
||||
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
|
||||
#define GLSL_DOOM_COLORMAP \
|
||||
"float R_DoomColormap(float light, float z)\n" \
|
||||
"uniform vec2 scr_resolution;\n" \
|
||||
"float R_DoomColormap(float light, float z, vec2 position)\n" \
|
||||
"{\n" \
|
||||
"float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \
|
||||
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
|
||||
"float startmap = (15.0 - lightnum) * 4.0;\n" \
|
||||
"float scale = 160.0 / (lightz + 1.0);\n" \
|
||||
"float cap = (155.0 - light) * 0.26;\n" \
|
||||
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
"#ifdef SRB2_LIGHT_DITHER\n" \
|
||||
GLSL_DOOM_COLORMAP_DITHER \
|
||||
"#else\n" \
|
||||
GLSL_DOOM_COLORMAP_NODITHER \
|
||||
"#endif\n" \
|
||||
"}\n"
|
||||
// lighting cap adjustment:
|
||||
// first num (155.0), increase to make it start to go dark sooner
|
||||
@@ -80,7 +107,7 @@
|
||||
"float R_DoomLightingEquation(float light)\n" \
|
||||
"{\n" \
|
||||
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||
"float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \
|
||||
"float colormap = floor(R_DoomColormap(light, z, gl_FragCoord.xy)) + 0.5;\n" \
|
||||
"return clamp(colormap, 0.0, 31.0) / 32.0;\n" \
|
||||
"}\n"
|
||||
|
||||
@@ -106,7 +133,7 @@
|
||||
#define GLSL_PALETTE_RENDERING \
|
||||
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
|
||||
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||
"float light_y = clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0);\n" \
|
||||
"float light_y = clamp(floor(R_DoomColormap(lighting, z, gl_FragCoord.xy)), 0.0, 31.0);\n" \
|
||||
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \
|
||||
"vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
@@ -144,13 +171,35 @@
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\n" \
|
||||
"#endif\0"
|
||||
|
||||
#define GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
GLSL_DOOM_LIGHT_EQUATION \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\n" \
|
||||
|
||||
// hand tuned adjustments for light level calculation
|
||||
#define GLSL_FLOOR_FUDGES \
|
||||
"#version 120\n" \
|
||||
"#define STARTMAP_FUDGE 1.06\n" \
|
||||
"#define SCALE_FUDGE 1.15\n"
|
||||
|
||||
#define GLSL_WALL_FUDGES \
|
||||
"#version 120\n" \
|
||||
"#define STARTMAP_FUDGE 1.05\n" \
|
||||
"#define SCALE_FUDGE 2.2\n"
|
||||
|
||||
@@ -161,6 +210,10 @@
|
||||
#define GLSL_WALL_FRAGMENT_SHADER \
|
||||
GLSL_WALL_FUDGES \
|
||||
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||
|
||||
#define GLSL_SHADOW_FRAGMENT_SHADER \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL
|
||||
|
||||
//
|
||||
// Water surface shader
|
||||
|
||||
@@ -120,8 +120,6 @@ GLfloat projMatrix[16];
|
||||
static GLint viewport[4];
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
static boolean GLFramebuffer_IsFuncAvailible(void);
|
||||
|
||||
GLuint FramebufferObject, FramebufferTexture, RenderbufferObject;
|
||||
GLboolean FrameBufferEnabled = GL_FALSE, RenderToFramebuffer = GL_FALSE;
|
||||
|
||||
@@ -608,6 +606,7 @@ typedef void (APIENTRY *PFNglDeleteProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint);
|
||||
typedef void (APIENTRY *PFNglLinkProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*);
|
||||
typedef void (APIENTRY *PFNglGetProgramInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*);
|
||||
typedef void (APIENTRY *PFNglUseProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglUniform1i) (GLint, GLint);
|
||||
typedef void (APIENTRY *PFNglUniform1f) (GLint, GLfloat);
|
||||
@@ -630,6 +629,7 @@ static PFNglDeleteProgram pglDeleteProgram;
|
||||
static PFNglAttachShader pglAttachShader;
|
||||
static PFNglLinkProgram pglLinkProgram;
|
||||
static PFNglGetProgramiv pglGetProgramiv;
|
||||
static PFNglGetProgramInfoLog pglGetProgramInfoLog;
|
||||
static PFNglUseProgram pglUseProgram;
|
||||
static PFNglUniform1i pglUniform1i;
|
||||
static PFNglUniform1f pglUniform1f;
|
||||
@@ -669,6 +669,8 @@ typedef enum
|
||||
|
||||
// misc.
|
||||
gluniform_leveltime,
|
||||
|
||||
gluniform_scr_resolution,
|
||||
|
||||
gluniform_max,
|
||||
} gluniform_t;
|
||||
@@ -703,6 +705,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
|
||||
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
static boolean GLFramebuffer_IsFuncAvailible(void);
|
||||
#endif
|
||||
|
||||
void SetupGLFunc4(void)
|
||||
{
|
||||
@@ -735,6 +740,7 @@ void SetupGLFunc4(void)
|
||||
pglAttachShader = GetGLFunc("glAttachShader");
|
||||
pglLinkProgram = GetGLFunc("glLinkProgram");
|
||||
pglGetProgramiv = GetGLFunc("glGetProgramiv");
|
||||
pglGetProgramInfoLog = GetGLFunc("glGetProgramInfoLog");
|
||||
pglUseProgram = GetGLFunc("glUseProgram");
|
||||
pglUniform1i = GetGLFunc("glUniform1i");
|
||||
pglUniform1f = GetGLFunc("glUniform1f");
|
||||
@@ -759,6 +765,8 @@ void SetupGLFunc4(void)
|
||||
pglDeleteRenderbuffers = GetGLFunc("glDeleteRenderbuffers");
|
||||
pglRenderbufferStorage = GetGLFunc("glRenderbufferStorage");
|
||||
pglFramebufferRenderbuffer = GetGLFunc("glFramebufferRenderbuffer");
|
||||
|
||||
supportFBO = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -770,9 +778,7 @@ static boolean GLFramebuffer_IsFuncAvailible(void)
|
||||
if (majorGL < 3)
|
||||
return false;
|
||||
|
||||
return((isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions)) &&
|
||||
(isExtAvailable("GL_ARB_framebuffer_object",gl_extensions)) &&
|
||||
(isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions)));
|
||||
return (isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_object",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -846,7 +852,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
|
||||
switch (info)
|
||||
{
|
||||
case HWD_SHADERINFO_LEVELTIME:
|
||||
shader_leveltime = value;
|
||||
shader_leveltime = (((float)(value-1)) + FIXED_TO_FLOAT(rendertimefrac)) / TICRATE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1038,37 +1044,9 @@ EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
|
||||
}
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
void GLFramebuffer_Generate(void)
|
||||
static void GLFramebuffer_GenerateAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Generate the framebuffer
|
||||
if (FramebufferObject == 0)
|
||||
pglGenFramebuffers(1, &FramebufferObject);
|
||||
|
||||
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
GLFramebuffer_GenerateAttachments();
|
||||
}
|
||||
|
||||
void GLFramebuffer_Delete(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (FramebufferObject)
|
||||
pglDeleteFramebuffers(1, &FramebufferObject);
|
||||
|
||||
GLFramebuffer_DeleteAttachments();
|
||||
FramebufferObject = 0;
|
||||
}
|
||||
|
||||
void GLFramebuffer_GenerateAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
// Bind the framebuffer
|
||||
@@ -1109,11 +1087,12 @@ void GLFramebuffer_GenerateAttachments(void)
|
||||
|
||||
void GLFramebuffer_DeleteAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
if (FramebufferTexture)
|
||||
pglDeleteTextures(1, &FramebufferTexture);
|
||||
@@ -1125,9 +1104,43 @@ void GLFramebuffer_DeleteAttachments(void)
|
||||
RenderbufferObject = 0;
|
||||
}
|
||||
|
||||
void GLFramebuffer_Enable(void)
|
||||
static void GLFramebuffer_Generate(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
// Generate the framebuffer
|
||||
if (FramebufferObject == 0)
|
||||
pglGenFramebuffers(1, &FramebufferObject);
|
||||
|
||||
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
GLFramebuffer_GenerateAttachments();
|
||||
}
|
||||
|
||||
static void GLFramebuffer_Delete(void)
|
||||
{
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
if (FramebufferObject)
|
||||
pglDeleteFramebuffers(1, &FramebufferObject);
|
||||
|
||||
GLFramebuffer_DeleteAttachments();
|
||||
FramebufferObject = 0;
|
||||
}
|
||||
|
||||
inline void GLFramebuffer_Unbind(void)
|
||||
{
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
inline void GLFramebuffer_Enable(void)
|
||||
{
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
if (FramebufferObject == 0)
|
||||
@@ -1141,11 +1154,13 @@ void GLFramebuffer_Enable(void)
|
||||
|
||||
void GLFramebuffer_Disable(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
GLFramebuffer_Delete();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1834,7 +1849,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
|
||||
}
|
||||
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
|
||||
|
||||
UNIFORM_2(shader->uniforms[gluniform_scr_resolution], vid.width, vid.height, pglUniform2f);
|
||||
|
||||
#undef UNIFORM_1
|
||||
#undef UNIFORM_2
|
||||
@@ -1850,6 +1867,7 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
GLint result;
|
||||
const GLchar *vert_shader = shader->vertex_shader;
|
||||
const GLchar *frag_shader = shader->fragment_shader;
|
||||
GLchar info_log[512];
|
||||
|
||||
if (shader->program)
|
||||
pglDeleteProgram(shader->program);
|
||||
@@ -1879,7 +1897,10 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
GL_MSG_Error("Error compiling vertex shader", gl_vertShader, i);
|
||||
pglGetShaderInfoLog(gl_vertShader, 512, NULL, info_log);
|
||||
|
||||
GL_MSG_Error("Error compiling vertex shader: %s\n", info_log);
|
||||
|
||||
pglDeleteShader(gl_vertShader);
|
||||
return false;
|
||||
}
|
||||
@@ -1906,7 +1927,9 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
GL_MSG_Error("Error compiling fragment shader", gl_fragShader, i);
|
||||
pglGetShaderInfoLog(gl_fragShader, 512, NULL, info_log);
|
||||
|
||||
GL_MSG_Error("Error compiling fragment shader: %s\n", info_log);
|
||||
pglDeleteShader(gl_vertShader);
|
||||
pglDeleteShader(gl_fragShader);
|
||||
return false;
|
||||
@@ -1932,7 +1955,8 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
// couldn't link?
|
||||
if (result != GL_TRUE)
|
||||
{
|
||||
GL_MSG_Error("Shader_CompileProgram: Error linking shader program %s\n", HWR_GetShaderName(i));
|
||||
pglGetProgramInfoLog(shader->program, 512, NULL, info_log);
|
||||
GL_MSG_Error("Shader_CompileProgram: Error linking shader program %s: %s\n", HWR_GetShaderName(i), info_log);
|
||||
pglDeleteProgram(shader->program);
|
||||
return false;
|
||||
}
|
||||
@@ -1953,6 +1977,8 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex");
|
||||
shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex");
|
||||
|
||||
shader->uniforms[gluniform_scr_resolution] = GETUNI("scr_resolution");
|
||||
|
||||
// misc.
|
||||
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
|
||||
#undef GETUNI
|
||||
@@ -2327,7 +2353,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||
#ifdef USE_FBO_OGL
|
||||
case HWD_SET_FRAMEBUFFER:
|
||||
FrameBufferEnabled = Value ? GL_TRUE : GL_FALSE;
|
||||
supportFBO = GLFramebuffer_IsFuncAvailible();
|
||||
|
||||
if (!supportFBO)
|
||||
{
|
||||
@@ -2959,8 +2984,8 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
||||
// https://zdoom.org/wiki/Y-shearing
|
||||
if (shearing)
|
||||
{
|
||||
float dy = FIXED_TO_FLOAT(AIMINGTODY((stransform->viewaiming)) * 2)* ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT); //screen_width/BASEVIDWIDTH;
|
||||
if (stransform->flip)
|
||||
float dy = stransform->viewaiming * 2;
|
||||
if (stransform->flip || stransform->mirrorflip)
|
||||
dy *= -1.0f;
|
||||
pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f);
|
||||
}
|
||||
|
||||
@@ -105,12 +105,9 @@ static PFNglEnableClientState pglEnableClientState;
|
||||
#endif
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
void GLFramebuffer_Generate(void);
|
||||
void GLFramebuffer_Delete(void);
|
||||
|
||||
void GLFramebuffer_GenerateAttachments(void);
|
||||
void GLFramebuffer_DeleteAttachments(void);
|
||||
|
||||
void GLFramebuffer_Unbind(void);
|
||||
void GLFramebuffer_Enable(void);
|
||||
void GLFramebuffer_Disable(void);
|
||||
|
||||
|
||||
+6
-1
@@ -532,7 +532,9 @@ HMS_fetch_rules (char *buffer, size_t buffer_size)
|
||||
if (! hms)
|
||||
return NULL;
|
||||
|
||||
if (HMS_do(hms))
|
||||
boolean ok = HMS_do(hms);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
char *p = strstr(hms->buffer, "\n\n");
|
||||
|
||||
@@ -550,6 +552,9 @@ HMS_fetch_rules (char *buffer, size_t buffer_size)
|
||||
|
||||
HMS_end(hms);
|
||||
|
||||
if (!ok)
|
||||
return NULL;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
+162
-278
@@ -49,6 +49,8 @@
|
||||
#include "s_sound.h" // song credits
|
||||
#include "k_kart.h"
|
||||
|
||||
#include "m_textinput.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
@@ -86,8 +88,8 @@ patch_t *frameslash; // framerate stuff. Used in screen.c
|
||||
|
||||
static player_t *plr;
|
||||
boolean chat_on; // entering a chat message?
|
||||
static char w_chat[HU_MAXMSGLEN + 1];
|
||||
static size_t c_input = 0; // let's try to make the chat input less shitty.
|
||||
static char w_chat_buf[HU_MAXMSGLEN + 1];
|
||||
static textinput_t w_chat;
|
||||
static boolean headsupactive = false;
|
||||
boolean hu_showscores; // draw rankings
|
||||
static char hu_tick;
|
||||
@@ -594,7 +596,10 @@ void HU_AddChatText(const char *text, boolean playsound)
|
||||
if (OLDCHAT) // if we're using oldchat, print directly in console
|
||||
CONS_Printf("%s\n", text);
|
||||
else // if we aren't, still save the message to log.txt
|
||||
CON_LogMessage(va("%s\n", text));
|
||||
{
|
||||
CON_LogMessage(text);
|
||||
CON_LogMessage("\n"); // Add newline. Don't use va for that, since `text` might be refering to va's buffer itself
|
||||
}
|
||||
#else
|
||||
(void)playsound;
|
||||
CONS_Printf("%s\n", text);
|
||||
@@ -1140,71 +1145,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Handles key input and string input
|
||||
//
|
||||
static inline boolean HU_keyInChatString(char *s, char ch)
|
||||
{
|
||||
size_t l;
|
||||
|
||||
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|
||||
|| ch == ' ') // Allow spaces, of course
|
||||
{
|
||||
l = strlen(s);
|
||||
if (l < HU_MAXMSGLEN - 1)
|
||||
{
|
||||
if (c_input >= strlen(s)) // don't do anything complicated
|
||||
{
|
||||
s[l++] = ch;
|
||||
s[l]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// move everything past c_input for new characters:
|
||||
size_t m = HU_MAXMSGLEN-1;
|
||||
while (m>=c_input)
|
||||
{
|
||||
if (s[m])
|
||||
s[m+1] = (s[m]);
|
||||
if (m == 0) // prevent overflow
|
||||
break;
|
||||
m--;
|
||||
}
|
||||
s[c_input] = ch; // and replace this.
|
||||
}
|
||||
c_input++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (ch == KEY_BACKSPACE)
|
||||
{
|
||||
size_t i = c_input;
|
||||
|
||||
if (c_input <= 0)
|
||||
return false;
|
||||
|
||||
if (!s[i-1])
|
||||
return false;
|
||||
|
||||
if (i >= strlen(s)-1)
|
||||
{
|
||||
s[strlen(s)-1] = 0;
|
||||
c_input--;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; (i < HU_MAXMSGLEN); i++)
|
||||
{
|
||||
s[i-1] = s[i];
|
||||
}
|
||||
c_input--;
|
||||
}
|
||||
else if (ch != KEY_ENTER)
|
||||
return false; // did not eat key
|
||||
|
||||
return true; // ate the key
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -1253,7 +1193,11 @@ void HU_Ticker(void)
|
||||
if (cechotimer > 0) --cechotimer;
|
||||
|
||||
// Animate the desynch dots
|
||||
if (hu_resynching)
|
||||
if (hu_resynching
|
||||
#ifdef SATURNSYNCH
|
||||
|| hu_redownloadinggamestate
|
||||
#endif
|
||||
)
|
||||
resynch_ticker++; //tic tic tic tic tic
|
||||
|
||||
HU_TickSongCredits();
|
||||
@@ -1273,9 +1217,9 @@ static boolean HU_clearChatSpaces(void)
|
||||
char c; // current character we're iterating.
|
||||
boolean nothingbutspaces = true;
|
||||
|
||||
for (; i < strlen(w_chat); i++) // iterate through message and eradicate all spaces that don't belong.
|
||||
for (; i < strlen(w_chat_buf); i++) // iterate through message and eradicate all spaces that don't belong.
|
||||
{
|
||||
c = w_chat[i];
|
||||
c = w_chat_buf[i];
|
||||
if (!c)
|
||||
break; // if there's nothing, it's safe to assume our message has ended, so let's not waste any more time here.
|
||||
|
||||
@@ -1287,128 +1231,110 @@ static boolean HU_clearChatSpaces(void)
|
||||
return nothingbutspaces;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
static void HU_queueChatChar(INT32 c)
|
||||
static void HU_SendChatMessage(void)
|
||||
{
|
||||
// send automaticly the message (no more chat char)
|
||||
if (c == KEY_ENTER)
|
||||
char buf[2 + HU_MAXMSGLEN + 1];
|
||||
char *msg = &buf[2];
|
||||
size_t ci = 2;
|
||||
INT32 target = 0;
|
||||
char c;
|
||||
|
||||
if (HU_clearChatSpaces()) // Avoids being able to send empty messages, or something.
|
||||
return; // If this returns true, that means our message was NOTHING but spaces, so don't send it period.
|
||||
|
||||
do {
|
||||
c = w_chat_buf[-2+ci++];
|
||||
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
|
||||
buf[ci-1]=c;
|
||||
} while (c);
|
||||
|
||||
M_TextInputClear(&w_chat);
|
||||
|
||||
// last minute mute check
|
||||
if (CHAT_MUTE)
|
||||
{
|
||||
char buf[2 + HU_MAXMSGLEN + 1];
|
||||
char *msg = &buf[2];
|
||||
size_t i;
|
||||
size_t ci = 2;
|
||||
INT32 target = 0;
|
||||
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HU_clearChatSpaces()) // Avoids being able to send empty messages, or something.
|
||||
return; // If this returns true, that means our message was NOTHING but spaces, so don't send it period.
|
||||
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
||||
{
|
||||
INT32 spc = 1; // used if nodenum[1] is a space.
|
||||
char *nodenum = (char*) malloc(3);
|
||||
const char *newmsg;
|
||||
|
||||
do {
|
||||
c = w_chat[-2+ci++];
|
||||
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
|
||||
buf[ci-1]=c;
|
||||
} while (c);
|
||||
i = 0;
|
||||
for (;(i<HU_MAXMSGLEN);i++)
|
||||
w_chat[i] = 0; // reset this.
|
||||
// what we're gonna do now is check if the node exists
|
||||
// with that logic, characters 4 and 5 are our numbers:
|
||||
|
||||
c_input = 0;
|
||||
|
||||
for (;(i<HU_MAXMSGLEN);i++)
|
||||
w_chat[i] = 0; // reset this.
|
||||
|
||||
c_input = 0;
|
||||
|
||||
// last minute mute check
|
||||
if (CHAT_MUTE)
|
||||
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
|
||||
if (teamtalk)
|
||||
{
|
||||
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
|
||||
HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
||||
memcpy(nodenum, msg+3, 2);
|
||||
nodenum[2] = '\0';
|
||||
|
||||
// check for undesirable characters in our "number"
|
||||
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
|
||||
{
|
||||
INT32 spc = 1; // used if nodenum[1] is a space.
|
||||
char *nodenum = (char*) malloc(3);
|
||||
const char *newmsg;
|
||||
|
||||
// what we're gonna do now is check if the node exists
|
||||
// with that logic, characters 4 and 5 are our numbers:
|
||||
|
||||
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
|
||||
if (teamtalk)
|
||||
{
|
||||
HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(nodenum, msg+3, 2);
|
||||
nodenum[2] = '\0';
|
||||
|
||||
// check for undesirable characters in our "number"
|
||||
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
|
||||
{
|
||||
// check if nodenum[1] is a space
|
||||
if (nodenum[1] == ' ')
|
||||
spc = 0;
|
||||
// let it slide
|
||||
else
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// I'm very bad at C, I swear I am, additional checks eww!
|
||||
if (spc != 0)
|
||||
{
|
||||
if (msg[5] != ' ')
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
//CONS_Printf("%d\n", target);
|
||||
|
||||
// check for target player, if it doesn't exist then we can't send the message!
|
||||
if (target < MAXPLAYERS && playeringame[target]) // player exists
|
||||
target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
|
||||
// check if nodenum[1] is a space
|
||||
if (nodenum[1] == ' ')
|
||||
spc = 0;
|
||||
// let it slide
|
||||
else
|
||||
{
|
||||
HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to get rid of the /pm<node>
|
||||
newmsg = msg+5+spc;
|
||||
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
|
||||
}
|
||||
if (ci > 3) // don't send target+flags+empty message.
|
||||
// I'm very bad at C, I swear I am, additional checks eww!
|
||||
if (spc != 0)
|
||||
{
|
||||
if (teamtalk)
|
||||
buf[0] = -1; // target
|
||||
else
|
||||
buf[0] = target;
|
||||
|
||||
buf[1] = 0; // flags
|
||||
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
|
||||
if (msg[5] != ' ')
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
target = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
//CONS_Printf("%d\n", target);
|
||||
|
||||
// check for target player, if it doesn't exist then we can't send the message!
|
||||
if (target < MAXPLAYERS && playeringame[target]) // player exists
|
||||
target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
|
||||
else
|
||||
{
|
||||
HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to get rid of the /pm<node>
|
||||
newmsg = msg+5+spc;
|
||||
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
|
||||
}
|
||||
if (ci > 3) // don't send target+flags+empty message.
|
||||
{
|
||||
if (teamtalk)
|
||||
buf[0] = -1; // target
|
||||
else
|
||||
buf[0] = target;
|
||||
|
||||
buf[1] = 0; // flags
|
||||
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void HU_clearChatChars(void)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (;i<HU_MAXMSGLEN;i++)
|
||||
w_chat[i] = 0; // reset this.
|
||||
M_TextInputClear(&w_chat);
|
||||
chat_on = false;
|
||||
c_input = 0;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
@@ -1456,7 +1382,8 @@ boolean HU_Responder(event_t *ev)
|
||||
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
|
||||
{
|
||||
chat_on = true;
|
||||
w_chat[0] = 0;
|
||||
w_chat_buf[0] = 0;
|
||||
M_TextInputInit(&w_chat, w_chat_buf, sizeof w_chat_buf);
|
||||
teamtalk = false;
|
||||
chat_scrollmedown = true;
|
||||
typelines = 1;
|
||||
@@ -1466,7 +1393,8 @@ boolean HU_Responder(event_t *ev)
|
||||
&& netgame && !OLD_MUTE)
|
||||
{
|
||||
chat_on = true;
|
||||
w_chat[0] = 0;
|
||||
w_chat_buf[0] = 0;
|
||||
M_TextInputInit(&w_chat, w_chat_buf, sizeof w_chat_buf);
|
||||
teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
|
||||
chat_scrollmedown = true;
|
||||
typelines = 1;
|
||||
@@ -1491,62 +1419,13 @@ boolean HU_Responder(event_t *ev)
|
||||
&& ev->data1 != gamecontrol[gc_talkkey][1]))
|
||||
return false;
|
||||
|
||||
c = cv_keyboardlayout.value == 3 ? CON_ShitAndAltGrChar(c) : CON_ShiftChar(c);
|
||||
M_TextInputHandle(&w_chat, c);
|
||||
|
||||
// pasting. pasting is cool. chat is a bit limited, though :(
|
||||
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)
|
||||
{
|
||||
const char *paste = I_ClipboardPaste();
|
||||
size_t chatlen;
|
||||
size_t pastelen;
|
||||
|
||||
// create a dummy string real quickly
|
||||
|
||||
if (paste == NULL)
|
||||
return true;
|
||||
|
||||
chatlen = strlen(w_chat);
|
||||
pastelen = strlen(paste);
|
||||
if (chatlen+pastelen > HU_MAXMSGLEN)
|
||||
return true; // we can't paste this!!
|
||||
|
||||
if (c_input >= strlen(w_chat)) // add it at the end of the string.
|
||||
{
|
||||
memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that.
|
||||
c_input += pastelen;
|
||||
/*size_t i = 0;
|
||||
for (;i<pastelen;i++)
|
||||
{
|
||||
HU_queueChatChar(paste[i]); // queue it so that it's actually sent. (this chat write thing is REALLY messy.)
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
else // otherwise, we need to shift everything and make space, etc etc
|
||||
{
|
||||
size_t i = HU_MAXMSGLEN-1;
|
||||
while (i >= c_input)
|
||||
{
|
||||
if (w_chat[i])
|
||||
w_chat[i+pastelen] = w_chat[i];
|
||||
if (i == 0) // prevent overflow
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
|
||||
c_input += pastelen;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CHAT_MUTE && HU_keyInChatString(w_chat,c))
|
||||
{
|
||||
HU_queueChatChar(c);
|
||||
}
|
||||
if (c == KEY_ENTER)
|
||||
{
|
||||
chat_on = false;
|
||||
c_input = 0; // reset input cursor
|
||||
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
|
||||
HU_SendChatMessage();
|
||||
}
|
||||
else if (c == KEY_ESCAPE
|
||||
|| ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1]
|
||||
@@ -1554,7 +1433,6 @@ boolean HU_Responder(event_t *ev)
|
||||
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
|
||||
{
|
||||
chat_on = false;
|
||||
c_input = 0; // reset input cursor
|
||||
}
|
||||
else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
|
||||
{
|
||||
@@ -1568,10 +1446,6 @@ boolean HU_Responder(event_t *ev)
|
||||
justscrolleddown = true;
|
||||
chat_scrolltime = 4;
|
||||
}
|
||||
else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
|
||||
c_input--;
|
||||
else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
|
||||
c_input++;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -1925,8 +1799,9 @@ static void HU_DrawChat(void)
|
||||
INT32 charwidth = 4, charheight = 6;
|
||||
INT32 boxw = cv_chatwidth.value;
|
||||
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
|
||||
UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
|
||||
UINT32 i = 0, saylen = strlen(w_chat_buf); // You learn new things everyday!
|
||||
INT32 cflag = 0;
|
||||
size_t select_start = 0, select_end = 0;
|
||||
const char *ntalk = "Say: ", *ttalk = "Team: ";
|
||||
const char *talk = ntalk;
|
||||
const char *mute = "Chat has been muted.";
|
||||
@@ -1988,13 +1863,19 @@ static void HU_DrawChat(void)
|
||||
i = 0;
|
||||
typelines = 1;
|
||||
|
||||
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
|
||||
V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
|
||||
V_DrawChatCharacter(chatx+2+c+charwidth*w_chat.cursor, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
|
||||
while (w_chat[i])
|
||||
if (w_chat.select != w_chat.cursor)
|
||||
{
|
||||
select_start = min(w_chat.select, w_chat.cursor);
|
||||
select_end = max(w_chat.select, w_chat.cursor);
|
||||
}
|
||||
|
||||
while (w_chat_buf[i])
|
||||
{
|
||||
boolean skippedline = false;
|
||||
if (c_input == (i+1))
|
||||
if (w_chat.cursor == (i+1))
|
||||
{
|
||||
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
|
||||
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
|
||||
@@ -2009,10 +1890,14 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
|
||||
//Hurdler: isn't it better like that?
|
||||
if (w_chat[i] < HU_FONTSTART)
|
||||
++i;
|
||||
else
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
if (w_chat_buf[i] >= HU_FONTSTART)
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(chatx + c + 2, y-1, charwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
|
||||
++i;
|
||||
|
||||
c += charwidth;
|
||||
if (c > boxw-(charwidth*2) && !skippedline)
|
||||
@@ -2024,7 +1909,7 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
|
||||
// handle /pm list. It's messy, horrible and I don't care.
|
||||
if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
|
||||
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
|
||||
{
|
||||
INT32 count = 0;
|
||||
INT32 p_dispy = chaty - charheight -1;
|
||||
@@ -2044,38 +1929,38 @@ static void HU_DrawChat(void)
|
||||
{
|
||||
|
||||
// filter: (code needs optimization pls help I'm bad with C)
|
||||
if (w_chat[3])
|
||||
if (w_chat_buf[3])
|
||||
{
|
||||
char *nodenum;
|
||||
UINT32 n;
|
||||
// right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!)
|
||||
if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' '))
|
||||
// right, that's half important: (w_chat_buf[4] may be a space since /pm0 msg is perfectly acceptable!)
|
||||
if ( ( ((w_chat_buf[3] != 0) && ((w_chat_buf[3] < '0') || (w_chat_buf[3] > '9'))) || ((w_chat_buf[4] != 0) && (((w_chat_buf[4] < '0') || (w_chat_buf[4] > '9'))))) && (w_chat_buf[4] != ' '))
|
||||
break;
|
||||
|
||||
|
||||
nodenum = (char*) malloc(3);
|
||||
memcpy(nodenum, w_chat+3, 2);
|
||||
memcpy(nodenum, w_chat_buf+3, 2);
|
||||
nodenum[2] = '\0';
|
||||
n = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
// special cases:
|
||||
|
||||
if ((n == 0) && !(w_chat[4] == '0'))
|
||||
if ((n == 0) && !(w_chat_buf[4] == '0'))
|
||||
{
|
||||
if (!(i<10))
|
||||
continue;
|
||||
}
|
||||
else if ((n == 1) && !(w_chat[3] == '0'))
|
||||
else if ((n == 1) && !(w_chat_buf[3] == '0'))
|
||||
{
|
||||
if (!((i == 1) || ((i >= 10) && (i <= 19))))
|
||||
continue;
|
||||
}
|
||||
else if ((n == 2) && !(w_chat[3] == '0'))
|
||||
else if ((n == 2) && !(w_chat_buf[3] == '0'))
|
||||
{
|
||||
if (!((i == 2) || ((i >= 20) && (i <= 29))))
|
||||
continue;
|
||||
}
|
||||
else if ((n == 3) && !(w_chat[3] == '0'))
|
||||
else if ((n == 3) && !(w_chat_buf[3] == '0'))
|
||||
{
|
||||
if (!((i == 3) || ((i >= 30) && (i <= 31))))
|
||||
continue;
|
||||
@@ -2114,6 +1999,7 @@ static void HU_DrawChat_Old(void)
|
||||
size_t i = 0;
|
||||
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
||||
const char *talk = ntalk;
|
||||
size_t select_start = 0, select_end = 0;
|
||||
INT32 charwidth = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
|
||||
INT32 charheight = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor;
|
||||
if (teamtalk)
|
||||
@@ -2142,14 +2028,19 @@ static void HU_DrawChat_Old(void)
|
||||
c += charwidth;
|
||||
}
|
||||
|
||||
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
|
||||
V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
|
||||
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
|
||||
V_DrawCharacter(HU_INPUTX+c+charwidth*w_chat.cursor, y+2*con_scalefactor, '_'|cv_constextsize.value|V_NOSCALESTART|t, !cv_allcaps.value);
|
||||
|
||||
if (w_chat.select != w_chat.cursor)
|
||||
{
|
||||
select_start = min(w_chat.select, w_chat.cursor);
|
||||
select_end = max(w_chat.select, w_chat.cursor);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (w_chat[i])
|
||||
while (w_chat_buf[i])
|
||||
{
|
||||
|
||||
if (c_input == (i+1) && hu_tick < 4)
|
||||
if (w_chat.cursor == (i+1) && hu_tick < 4)
|
||||
{
|
||||
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
|
||||
INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight);
|
||||
@@ -2157,17 +2048,18 @@ static void HU_DrawChat_Old(void)
|
||||
}
|
||||
|
||||
//Hurdler: isn't it better like that?
|
||||
if (w_chat[i] < HU_FONTSTART)
|
||||
{
|
||||
++i;
|
||||
//charwidth = 4 * con_scalefactor;
|
||||
}
|
||||
else
|
||||
if (w_chat_buf[i] >= HU_FONTSTART)
|
||||
{
|
||||
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat_buf[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(HU_INPUTX + c, y, charwidth, charheight, 103|V_TRANSLUCENT|cv_constextsize.value|V_NOSCALESTART|t);
|
||||
|
||||
++i;
|
||||
|
||||
c += charwidth;
|
||||
if (c >= vid.width)
|
||||
{
|
||||
@@ -2418,7 +2310,11 @@ void HU_Drawer(void)
|
||||
HU_DrawSongCredits();
|
||||
|
||||
// draw desynch text
|
||||
if (hu_resynching)
|
||||
if (hu_resynching
|
||||
#ifdef SATURNSYNCH
|
||||
|| hu_redownloadinggamestate
|
||||
#endif
|
||||
)
|
||||
{
|
||||
char resynch_text[14];
|
||||
UINT32 i;
|
||||
@@ -2721,7 +2617,8 @@ static void HU_DrawRankings(void)
|
||||
boolean completed[MAXPLAYERS];
|
||||
UINT32 whiteplayer = MAXPLAYERS;
|
||||
|
||||
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
|
||||
if (!automapactive)
|
||||
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
|
||||
|
||||
if (cons_menuhighlight.value)
|
||||
hilicol = cons_menuhighlight.value;
|
||||
@@ -2737,10 +2634,14 @@ static void HU_DrawRankings(void)
|
||||
//V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
|
||||
|
||||
// draw the current map in the lower right if theres none just say its unknown
|
||||
if (!G_BuildMapTitle(gamemap))
|
||||
char *maptitle = G_BuildMapTitle(gamemap);
|
||||
if (!maptitle)
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "UNKNOWN");
|
||||
else
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, G_BuildMapTitle(gamemap));
|
||||
{
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, maptitle);
|
||||
Z_Free(maptitle);
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
@@ -2790,18 +2691,6 @@ static void HU_DrawRankings(void)
|
||||
V_DrawCenteredString(256, 16, hilicol, va("%d", cv_pointlimit.value));
|
||||
}
|
||||
}
|
||||
/*else if (gametype == GT_COOP)
|
||||
{
|
||||
INT32 totalscore = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
totalscore += players[i].score;
|
||||
}
|
||||
|
||||
V_DrawCenteredString(256, 8, 0, "TOTAL SCORE");
|
||||
V_DrawCenteredString(256, 16, 0, va("%u", totalscore));
|
||||
}*/
|
||||
else
|
||||
{
|
||||
if (circuitmap)
|
||||
@@ -2874,12 +2763,7 @@ static void HU_DrawRankings(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*if (G_GametypeHasTeams())
|
||||
HU_DrawTeamTabRankings(tab, whiteplayer); //separate function for Spazzo's silly request -- gotta fix this up later
|
||||
else if (scorelines > 10)*/
|
||||
HU_DrawTabRankings(((scorelines > 8) ? 32 : 40), 33, tab, scorelines, whiteplayer, hilicol);
|
||||
/*else
|
||||
HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);*/
|
||||
|
||||
// draw spectators in a ticker across the bottom
|
||||
if (netgame && G_GametypeHasSpectators())
|
||||
|
||||
-20
@@ -34,7 +34,6 @@
|
||||
#define NO_BAN_TIME (time_t)(-1)
|
||||
|
||||
extern INT16 hardware_MAXPACKETLENGTH;
|
||||
extern INT32 net_bandwidth; // in byte/s
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
@@ -42,36 +41,17 @@ extern INT32 net_bandwidth; // in byte/s
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/// Supposed to be DOOMCOM_ID
|
||||
INT32 id;
|
||||
|
||||
/// SRB2 executes an INT32 to execute commands.
|
||||
INT16 intnum;
|
||||
/// Communication between SRB2 and the driver.
|
||||
/// Is CMD_SEND or CMD_GET.
|
||||
INT16 command;
|
||||
/// Is dest for send, set by get (-1 = no packet).
|
||||
INT16 remotenode;
|
||||
|
||||
/// Number of bytes in doomdata to be sent
|
||||
INT16 datalength;
|
||||
|
||||
/// Info common to all nodes.
|
||||
/// Console is always node 0.
|
||||
INT16 numnodes;
|
||||
/// Flag: 1 = no duplication, 2-5 = dup for slow nets.
|
||||
INT16 ticdup;
|
||||
/// Flag: 1 = send a backup tic in every packet.
|
||||
INT16 extratics;
|
||||
/// kind of game
|
||||
INT16 gametype;
|
||||
/// Flag: -1 = new game, 0-5 = load savegame
|
||||
INT16 savegame;
|
||||
/// currect map
|
||||
INT16 map;
|
||||
|
||||
/// Info specific to this node.
|
||||
INT16 consoleplayer;
|
||||
/// Number of "slots": the highest player number in use plus one.
|
||||
INT16 numslots;
|
||||
|
||||
|
||||
@@ -159,7 +159,6 @@ boolean I_SetSongPosition(UINT32 position);
|
||||
UINT32 I_GetSongPosition(void);
|
||||
|
||||
void I_UpdateSongLagThreshold (void);
|
||||
void I_UpdateSongLagConditions (void);
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
|
||||
@@ -34,6 +34,9 @@ extern UINT8 graphics_started;
|
||||
*/
|
||||
extern UINT8 keyboard_started;
|
||||
|
||||
/** \brief Set to true when inside a signal handler that will exit the program. */
|
||||
extern boolean g_in_exiting_signal_handler;
|
||||
|
||||
/** \brief The I_GetFreeMem function
|
||||
|
||||
\param total total memory in the system
|
||||
@@ -227,6 +230,9 @@ INT32 I_NumJoys(void);
|
||||
*/
|
||||
const char *I_GetJoyName(INT32 joyindex);
|
||||
|
||||
void I_GamepadRumble(INT32 device_id, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
|
||||
void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue);
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
#include "p_mobj.h" // mobj_t
|
||||
#include "s_sound.h" // listener_t
|
||||
|
||||
+22
-9
@@ -100,6 +100,14 @@
|
||||
#undef ETIMEDOUT
|
||||
#endif
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#ifdef EHOSTUNREACH
|
||||
#undef EHOSTUNREACH
|
||||
#endif
|
||||
#define EHOSTUNREACH WSAEHOSTUNREACH
|
||||
#ifdef ENETUNREACH
|
||||
#undef ENETUNREACH
|
||||
#endif
|
||||
#define ENETUNREACH WSAENETUNREACH
|
||||
#ifndef IOC_VENDOR
|
||||
#define IOC_VENDOR 0x18000000
|
||||
#endif
|
||||
@@ -816,6 +824,8 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
|
||||
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
|
||||
}
|
||||
|
||||
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH)
|
||||
|
||||
static void SOCK_Send(void)
|
||||
{
|
||||
ssize_t c = ERRSOCKET;
|
||||
@@ -831,7 +841,11 @@ static void SOCK_Send(void)
|
||||
for (j = 0; j < broadcastaddresses; j++)
|
||||
{
|
||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||
{
|
||||
c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -841,7 +855,11 @@ static void SOCK_Send(void)
|
||||
for (i = 0; i < mysocketses; i++)
|
||||
{
|
||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||
{
|
||||
c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -853,11 +871,12 @@ static void SOCK_Send(void)
|
||||
if (c == ERRSOCKET)
|
||||
{
|
||||
int e = errno; // save error code so it can't be modified later
|
||||
if (e != ECONNREFUSED && e != EWOULDBLOCK)
|
||||
if (!ALLOWEDERROR(e))
|
||||
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
|
||||
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
||||
}
|
||||
}
|
||||
#undef ALLOWEDERROR
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
@@ -1692,8 +1711,6 @@ boolean I_InitTcpNetwork(void)
|
||||
// FIXME: for dedicated server, numnodes needs to be set to 0 upon start
|
||||
if (dedicated)
|
||||
doomcom->numnodes = 0;
|
||||
/* else if (M_IsNextParm())
|
||||
doomcom->numnodes = (INT16)atoi(M_GetNextParm());*/
|
||||
else
|
||||
doomcom->numnodes = 1;
|
||||
|
||||
@@ -1707,7 +1724,6 @@ boolean I_InitTcpNetwork(void)
|
||||
// FIXME:
|
||||
// ??? and now ?
|
||||
// server on a big modem ??? 4*isdn
|
||||
net_bandwidth = 16000;
|
||||
hardware_MAXPACKETLENGTH = INETPACKETLENGTH;
|
||||
|
||||
ret = true;
|
||||
@@ -1738,7 +1754,6 @@ boolean I_InitTcpNetwork(void)
|
||||
// so we're on a LAN
|
||||
COM_BufAddText("connect any\n");
|
||||
|
||||
net_bandwidth = 800000;
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
}
|
||||
}
|
||||
@@ -1763,8 +1778,6 @@ boolean I_InitTcpNetwork(void)
|
||||
{
|
||||
// so we're on a LAN
|
||||
COM_BufAddText("connect any\n");
|
||||
|
||||
net_bandwidth = 800000;
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,10 @@ UINT32 I_GetRefreshRate(void);
|
||||
boolean I_UseNativeKeyboard(void);
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
#if defined (__unix__)
|
||||
extern boolean xwaylandcrap;
|
||||
#endif
|
||||
|
||||
void RefreshOGLSDLSurface(void);
|
||||
void I_DownSample(void);
|
||||
extern boolean downsample;
|
||||
|
||||
+10
-10
@@ -1822,7 +1822,7 @@ state_t states[NUMSTATES] =
|
||||
|
||||
// Rain
|
||||
{SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1
|
||||
{SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN
|
||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RAINRETURN
|
||||
|
||||
// Snowflake
|
||||
{SPR_SNO1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW1
|
||||
@@ -1841,9 +1841,9 @@ state_t states[NUMSTATES] =
|
||||
{SPR_SPLH, FF_TRANS50|8, 2, {NULL}, 0, 0, S_NULL}, // S_SPLISH9
|
||||
|
||||
// Water Splash
|
||||
{SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1
|
||||
{SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2
|
||||
{SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_RAINRETURN}, // S_SPLASH3
|
||||
{SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1
|
||||
{SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2
|
||||
{SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_NULL}, // S_SPLASH3
|
||||
|
||||
// Smoke
|
||||
{SPR_SMOK, FF_TRANS50 , 4, {NULL}, 0, 0, S_SMOKE2}, // S_SMOKE1
|
||||
@@ -11198,22 +11198,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
S_RAIN1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_rainin, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_SPLASH1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
-72*FRACUNIT, // speed -- -24*FRACUNIT originally, srb2kart x3 (nya)
|
||||
1*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
0, // display offset
|
||||
4, // mass
|
||||
80, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP, // flags
|
||||
@@ -11226,7 +11226,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
@@ -11240,7 +11240,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
4*FRACUNIT, // radius
|
||||
4*FRACUNIT, // height
|
||||
0, // display offset
|
||||
4, // mass
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP, // flags
|
||||
|
||||
+430
-203
@@ -22,211 +22,438 @@
|
||||
// dehacked.c now has lists for the more named enums! PLEASE keep them up to date!
|
||||
// For great modding!!
|
||||
|
||||
/** Action pointer for reading actions from Dehacked lumps.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
actionf_t action; ///< Function pointer corresponding to the actual action.
|
||||
const char *name; ///< Name of the action in ALL CAPS.
|
||||
} actionpointer_t;
|
||||
|
||||
/** Array mapping action names to action functions.
|
||||
* Names must be in ALL CAPS for case insensitive comparisons.
|
||||
*/
|
||||
extern actionpointer_t actionpointers[];
|
||||
|
||||
// IMPORTANT!
|
||||
// DO NOT FORGET TO SYNC THIS LIST WITH THE ACTIONPOINTERS ARRAY IN DEHACKED.C
|
||||
enum actionnum
|
||||
{
|
||||
A_EXPLODE = 0,
|
||||
A_PAIN,
|
||||
A_FALL,
|
||||
A_MONITORPOP,
|
||||
A_LOOK,
|
||||
A_CHASE,
|
||||
A_FACESTABCHASE,
|
||||
A_FACETARGET,
|
||||
A_FACETRACER,
|
||||
A_SCREAM,
|
||||
A_BOSSDEATH,
|
||||
A_CUSTOMPOWER,
|
||||
A_GIVEWEAPON,
|
||||
A_RINGSHIELD,
|
||||
A_RINGBOX,
|
||||
A_INVINCIBILITY,
|
||||
A_SUPERSNEAKERS,
|
||||
A_BUNNYHOP,
|
||||
A_BUBBLESPAWN,
|
||||
A_FANBUBBLESPAWN,
|
||||
A_BUBBLERISE,
|
||||
A_BUBBLECHECK,
|
||||
A_AWARDSCORE,
|
||||
A_EXTRALIFE,
|
||||
A_BOMBSHIELD,
|
||||
A_JUMPSHIELD,
|
||||
A_WATERSHIELD,
|
||||
A_FORCESHIELD,
|
||||
A_PITYSHIELD,
|
||||
A_GRAVITYBOX,
|
||||
A_SCORERISE,
|
||||
A_PARTICLESPAWN,
|
||||
A_ATTRACTCHASE,
|
||||
A_DROPMINE,
|
||||
A_FISHJUMP,
|
||||
A_THROWNRING,
|
||||
A_GRENADERING, // SRB2kart
|
||||
A_SETSOLIDSTEAM,
|
||||
A_UNSETSOLIDSTEAM,
|
||||
A_SIGNPLAYER,
|
||||
A_OVERLAYTHINK,
|
||||
A_JETCHASE,
|
||||
A_JETBTHINK,
|
||||
A_JETGTHINK,
|
||||
A_JETGSHOOT,
|
||||
A_SHOOTBULLET,
|
||||
A_MINUSDIGGING,
|
||||
A_MINUSPOPUP,
|
||||
A_MINUSCHECK,
|
||||
A_CHICKENCHECK,
|
||||
A_MOUSETHINK,
|
||||
A_DETONCHASE,
|
||||
A_CAPECHASE,
|
||||
A_ROTATESPIKEBALL,
|
||||
A_SLINGAPPEAR,
|
||||
A_MACEROTATE,
|
||||
A_UNIDUSBALL,
|
||||
A_ROCKSPAWN,
|
||||
A_SETFUSE,
|
||||
A_CRAWLACOMMANDERTHINK,
|
||||
A_SMOKETRAILER,
|
||||
A_RINGEXPLODE,
|
||||
A_OLDRINGEXPLODE,
|
||||
A_MIXUP,
|
||||
A_RECYCLEPOWERS,
|
||||
A_BOSS1CHASE,
|
||||
A_FOCUSTARGET,
|
||||
A_BOSS2CHASE,
|
||||
A_BOSS2POGO,
|
||||
A_BOSSZOOM,
|
||||
A_BOSSSCREAM,
|
||||
A_BOSS2TAKEDAMAGE,
|
||||
A_BOSS7CHASE,
|
||||
A_GOOPSPLAT,
|
||||
A_BOSS2POGOSFX,
|
||||
A_BOSS2POGOTARGET,
|
||||
A_BOSSJETFUME,
|
||||
A_EGGMANBOX,
|
||||
A_TURRETFIRE,
|
||||
A_SUPERTURRETFIRE,
|
||||
A_TURRETSTOP,
|
||||
A_JETJAWROAM,
|
||||
A_JETJAWCHOMP,
|
||||
A_POINTYTHINK,
|
||||
A_CHECKBUDDY,
|
||||
A_HOODTHINK,
|
||||
A_ARROWCHECK,
|
||||
A_SNAILERTHINK,
|
||||
A_SHARPCHASE,
|
||||
A_SHARPSPIN,
|
||||
A_VULTUREVTOL,
|
||||
A_VULTURECHECK,
|
||||
A_SKIMCHASE,
|
||||
A_1UPTHINKER,
|
||||
A_SKULLATTACK,
|
||||
A_LOBSHOT,
|
||||
A_FIRESHOT,
|
||||
A_SUPERFIRESHOT,
|
||||
A_BOSSFIRESHOT,
|
||||
A_BOSS7FIREMISSILES,
|
||||
A_BOSS1LASER,
|
||||
A_BOSS4REVERSE,
|
||||
A_BOSS4SPEEDUP,
|
||||
A_BOSS4RAISE,
|
||||
A_SPARKFOLLOW,
|
||||
A_BUZZFLY,
|
||||
A_GUARDCHASE,
|
||||
A_EGGSHIELD,
|
||||
A_SETREACTIONTIME,
|
||||
A_BOSS1SPIKEBALLS,
|
||||
A_BOSS3TAKEDAMAGE,
|
||||
A_BOSS3PATH,
|
||||
A_LINEDEFEXECUTE,
|
||||
A_PLAYSEESOUND,
|
||||
A_PLAYATTACKSOUND,
|
||||
A_PLAYACTIVESOUND,
|
||||
A_SPAWNOBJECTABSOLUTE,
|
||||
A_SPAWNOBJECTRELATIVE,
|
||||
A_CHANGEANGLERELATIVE,
|
||||
A_CHANGEANGLEABSOLUTE,
|
||||
A_ROLLANGLE,
|
||||
A_CHANGEROLLANGLERELATIVE,
|
||||
A_CHANGEROLLANGLEABSOLUTE,
|
||||
A_PLAYSOUND,
|
||||
A_FINDTARGET,
|
||||
A_FINDTRACER,
|
||||
A_SETTICS,
|
||||
A_SETRANDOMTICS,
|
||||
A_CHANGECOLORRELATIVE,
|
||||
A_CHANGECOLORABSOLUTE,
|
||||
A_MOVERELATIVE,
|
||||
A_MOVEABSOLUTE,
|
||||
A_THRUST,
|
||||
A_ZTHRUST,
|
||||
A_SETTARGETSTARGET,
|
||||
A_SETOBJECTFLAGS,
|
||||
A_SETOBJECTFLAGS2,
|
||||
A_RANDOMSTATE,
|
||||
A_RANDOMSTATERANGE,
|
||||
A_DUALACTION,
|
||||
A_REMOTEACTION,
|
||||
A_TOGGLEFLAMEJET,
|
||||
A_ITEMPOP, // SRB2kart
|
||||
A_JAWZCHASE, // SRB2kart
|
||||
A_JAWZEXPLODE, // SRB2kart
|
||||
A_SPBCHASE, // SRB2kart
|
||||
A_MINEEXPLODE, // SRB2kart
|
||||
A_BALLHOGEXPLODE, // SRB2kart
|
||||
A_LIGHTNINGFOLLOWPLAYER, //SRB2kart
|
||||
A_FZBOOMFLASH, //SRB2kart
|
||||
A_FZBOOMSMOKE, //SRB2kart
|
||||
A_RANDOMSHADOWFRAME, //SRB2kart
|
||||
A_ROAMINGSHADOWTHINKER, //SRB2kart
|
||||
A_MAYONAKAARROW, //SRB2kart
|
||||
A_REAPERTHINKER, //SRB2kart
|
||||
A_MEMENTOSTPPARTICLES, //SRB2kart
|
||||
A_FLAMEPARTICLE, // SRB2kart
|
||||
A_ORBITNIGHTS,
|
||||
A_GHOSTME,
|
||||
A_SETOBJECTSTATE,
|
||||
A_SETOBJECTTYPESTATE,
|
||||
A_KNOCKBACK,
|
||||
A_PUSHAWAY,
|
||||
A_RINGDRAIN,
|
||||
A_SPLITSHOT,
|
||||
A_MISSILESPLIT,
|
||||
A_MULTISHOT,
|
||||
A_INSTALOOP,
|
||||
A_CUSTOM3DROTATE,
|
||||
A_SEARCHFORPLAYERS,
|
||||
A_CHECKRANDOM,
|
||||
A_CHECKTARGETRINGS,
|
||||
A_CHECKRINGS,
|
||||
A_CHECKTOTALRINGS,
|
||||
A_CHECKHEALTH,
|
||||
A_CHECKRANGE,
|
||||
A_CHECKHEIGHT,
|
||||
A_CHECKTRUERANGE,
|
||||
A_CHECKTHINGCOUNT,
|
||||
A_CHECKAMBUSH,
|
||||
A_CHECKCUSTOMVALUE,
|
||||
A_CHECKCUSVALMEMO,
|
||||
A_SETCUSTOMVALUE,
|
||||
A_USECUSVALMEMO,
|
||||
A_RELAYCUSTOMVALUE,
|
||||
A_CUSVALACTION,
|
||||
A_FORCESTOP,
|
||||
A_FORCEWIN,
|
||||
A_SPIKERETRACT,
|
||||
A_INFOSTATE,
|
||||
A_REPEAT,
|
||||
A_SETSCALE,
|
||||
A_REMOTEDAMAGE,
|
||||
A_HOMINGCHASE,
|
||||
A_TRAPSHOT,
|
||||
A_VILETARGET,
|
||||
A_VILEATTACK,
|
||||
A_VILEFIRE,
|
||||
A_BRAKCHASE,
|
||||
A_BRAKFIRESHOT,
|
||||
A_BRAKLOBSHOT,
|
||||
A_NAPALMSCATTER,
|
||||
A_SPAWNFRESHCOPY,
|
||||
NUMACTIONS
|
||||
};
|
||||
|
||||
struct mobj_s;
|
||||
|
||||
// IMPORTANT NOTE: If you add/remove from this list of action
|
||||
// functions, don't forget to update them in dehacked.c!
|
||||
void A_Explode();
|
||||
void A_Pain();
|
||||
void A_Fall();
|
||||
void A_MonitorPop();
|
||||
void A_Look();
|
||||
void A_Chase();
|
||||
void A_FaceStabChase();
|
||||
void A_FaceTarget();
|
||||
void A_FaceTracer();
|
||||
void A_Scream();
|
||||
void A_BossDeath();
|
||||
void A_CustomPower(); // Use this for a custom power
|
||||
void A_GiveWeapon(); // Gives the player weapon(s)
|
||||
void A_JumpShield(); // Obtained Jump Shield
|
||||
void A_RingShield(); // Obtained Ring Shield
|
||||
void A_RingBox(); // Obtained Ring Box Tails
|
||||
void A_Invincibility(); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(); // have bunny hop tails
|
||||
void A_BubbleSpawn(); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn();
|
||||
void A_BubbleRise(); // Bubbles float to surface
|
||||
void A_BubbleCheck(); // Don't draw if not underwater
|
||||
void A_AwardScore();
|
||||
void A_ExtraLife(); // Extra Life
|
||||
void A_BombShield(); // Obtained Bomb Shield
|
||||
void A_WaterShield(); // Obtained Water Shield
|
||||
void A_ForceShield(); // Obtained Force Shield
|
||||
void A_PityShield(); // Obtained Pity Shield. We're... sorry.
|
||||
void A_GravityBox();
|
||||
void A_ScoreRise(); // Rise the score logo
|
||||
void A_ParticleSpawn();
|
||||
void A_AttractChase(); // Ring Chase
|
||||
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(); // Fish Jump
|
||||
void A_ThrownRing(); // Sparkle trail for red ring
|
||||
void A_GrenadeRing(); // SRB2kart
|
||||
void A_SetSolidSteam();
|
||||
void A_UnsetSolidSteam();
|
||||
void A_SignPlayer();
|
||||
void A_OverlayThink();
|
||||
void A_JetChase();
|
||||
void A_JetbThink(); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging();
|
||||
void A_MinusPopup();
|
||||
void A_MinusCheck();
|
||||
void A_ChickenCheck();
|
||||
void A_MouseThink(); // Mouse Thinker
|
||||
void A_DetonChase(); // Deton Chaser
|
||||
void A_CapeChase(); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(); // Spike ball rotation
|
||||
void A_SlingAppear();
|
||||
void A_MaceRotate();
|
||||
void A_UnidusBall();
|
||||
void A_RockSpawn();
|
||||
void A_SetFuse();
|
||||
void A_CrawlaCommanderThink(); // Crawla Commander
|
||||
void A_SmokeTrailer();
|
||||
void A_RingExplode();
|
||||
void A_OldRingExplode();
|
||||
void A_MixUp();
|
||||
void A_RecyclePowers();
|
||||
void A_BossScream();
|
||||
void A_Boss2TakeDamage();
|
||||
void A_GoopSplat();
|
||||
void A_Boss2PogoSFX();
|
||||
void A_Boss2PogoTarget();
|
||||
void A_EggmanBox();
|
||||
void A_TurretFire();
|
||||
void A_SuperTurretFire();
|
||||
void A_TurretStop();
|
||||
void A_JetJawRoam();
|
||||
void A_JetJawChomp();
|
||||
void A_PointyThink();
|
||||
void A_CheckBuddy();
|
||||
void A_HoodThink();
|
||||
void A_ArrowCheck();
|
||||
void A_SnailerThink();
|
||||
void A_SharpChase();
|
||||
void A_SharpSpin();
|
||||
void A_VultureVtol();
|
||||
void A_VultureCheck();
|
||||
void A_SkimChase();
|
||||
void A_SkullAttack();
|
||||
void A_LobShot();
|
||||
void A_FireShot();
|
||||
void A_SuperFireShot();
|
||||
void A_BossFireShot();
|
||||
void A_Boss7FireMissiles();
|
||||
void A_Boss1Laser();
|
||||
void A_FocusTarget();
|
||||
void A_Boss4Reverse();
|
||||
void A_Boss4SpeedUp();
|
||||
void A_Boss4Raise();
|
||||
void A_SparkFollow();
|
||||
void A_BuzzFly();
|
||||
void A_GuardChase();
|
||||
void A_EggShield();
|
||||
void A_SetReactionTime();
|
||||
void A_Boss1Spikeballs();
|
||||
void A_Boss3TakeDamage();
|
||||
void A_Boss3Path();
|
||||
void A_LinedefExecute();
|
||||
void A_PlaySeeSound();
|
||||
void A_PlayAttackSound();
|
||||
void A_PlayActiveSound();
|
||||
void A_1upThinker();
|
||||
void A_BossZoom(); //Unused
|
||||
void A_Boss1Chase();
|
||||
void A_Boss2Chase();
|
||||
void A_Boss2Pogo();
|
||||
void A_Boss7Chase();
|
||||
void A_BossJetFume();
|
||||
void A_SpawnObjectAbsolute();
|
||||
void A_SpawnObjectRelative();
|
||||
void A_ChangeAngleRelative();
|
||||
void A_ChangeAngleAbsolute();
|
||||
void A_RollAngle();
|
||||
void A_ChangeRollAngleRelative();
|
||||
void A_ChangeRollAngleAbsolute();
|
||||
void A_PlaySound();
|
||||
void A_FindTarget();
|
||||
void A_FindTracer();
|
||||
void A_SetTics();
|
||||
void A_SetRandomTics();
|
||||
void A_ChangeColorRelative();
|
||||
void A_ChangeColorAbsolute();
|
||||
void A_MoveRelative();
|
||||
void A_MoveAbsolute();
|
||||
void A_Thrust();
|
||||
void A_ZThrust();
|
||||
void A_SetTargetsTarget();
|
||||
void A_SetObjectFlags();
|
||||
void A_SetObjectFlags2();
|
||||
void A_RandomState();
|
||||
void A_RandomStateRange();
|
||||
void A_DualAction();
|
||||
void A_RemoteAction();
|
||||
void A_ToggleFlameJet();
|
||||
void A_ItemPop(); // SRB2kart
|
||||
void A_JawzChase(); // SRB2kart
|
||||
void A_JawzExplode(); // SRB2kart
|
||||
void A_SPBChase(); // SRB2kart
|
||||
void A_MineExplode(); // SRB2kart
|
||||
void A_BallhogExplode(); // SRB2kart
|
||||
void A_LightningFollowPlayer(); // SRB2kart: Lightning shield effect player chasing
|
||||
void A_FZBoomFlash(); // SRB2kart
|
||||
void A_FZBoomSmoke(); // SRB2kart
|
||||
void A_RandomShadowFrame(); //SRB2kart: Shadow spawner frame randomizer
|
||||
void A_RoamingShadowThinker(); // SRB2kart: Roaming Shadow moving + attacking players.
|
||||
void A_MayonakaArrow(); //SRB2kart: midnight channel arrow sign
|
||||
void A_ReaperThinker(); //SRB2kart: mementos reaper
|
||||
void A_MementosTPParticles(); //SRB2kart: mementos teleporter particles. Man that's a lot of actions for my shite.
|
||||
void A_FlameParticle(); // SRB2kart
|
||||
void A_OrbitNights();
|
||||
void A_GhostMe();
|
||||
void A_SetObjectState();
|
||||
void A_SetObjectTypeState();
|
||||
void A_KnockBack();
|
||||
void A_PushAway();
|
||||
void A_RingDrain();
|
||||
void A_SplitShot();
|
||||
void A_MissileSplit();
|
||||
void A_MultiShot();
|
||||
void A_InstaLoop();
|
||||
void A_Custom3DRotate();
|
||||
void A_SearchForPlayers();
|
||||
void A_CheckRandom();
|
||||
void A_CheckTargetRings();
|
||||
void A_CheckRings();
|
||||
void A_CheckTotalRings();
|
||||
void A_CheckHealth();
|
||||
void A_CheckRange();
|
||||
void A_CheckHeight();
|
||||
void A_CheckTrueRange();
|
||||
void A_CheckThingCount();
|
||||
void A_CheckAmbush();
|
||||
void A_CheckCustomValue();
|
||||
void A_CheckCusValMemo();
|
||||
void A_SetCustomValue();
|
||||
void A_UseCusValMemo();
|
||||
void A_RelayCustomValue();
|
||||
void A_CusValAction();
|
||||
void A_ForceStop();
|
||||
void A_ForceWin();
|
||||
void A_SpikeRetract();
|
||||
void A_InfoState();
|
||||
void A_Repeat();
|
||||
void A_SetScale();
|
||||
void A_RemoteDamage();
|
||||
void A_HomingChase();
|
||||
void A_TrapShot();
|
||||
void A_VileTarget();
|
||||
void A_VileAttack();
|
||||
void A_VileFire();
|
||||
void A_BrakChase();
|
||||
void A_BrakFireShot();
|
||||
void A_BrakLobShot();
|
||||
void A_NapalmScatter();
|
||||
void A_SpawnFreshCopy();
|
||||
void A_Explode(struct mobj_s *actor);
|
||||
void A_Pain(struct mobj_s *actor);
|
||||
void A_Fall(struct mobj_s *actor);
|
||||
void A_MonitorPop(struct mobj_s *actor);
|
||||
void A_Look(struct mobj_s *actor);
|
||||
void A_Chase(struct mobj_s *actor);
|
||||
void A_FaceStabChase(struct mobj_s *actor);
|
||||
void A_FaceTarget(struct mobj_s *actor);
|
||||
void A_FaceTracer(struct mobj_s *actor);
|
||||
void A_Scream(struct mobj_s *actor);
|
||||
void A_BossDeath(struct mobj_s *actor);
|
||||
void A_CustomPower(struct mobj_s *actor); // Use this for a custom power
|
||||
void A_GiveWeapon(struct mobj_s *actor); // Gives the player weapon(s)
|
||||
void A_JumpShield(struct mobj_s *actor); // Obtained Jump Shield
|
||||
void A_RingShield(struct mobj_s *actor); // Obtained Ring Shield
|
||||
void A_RingBox(struct mobj_s *actor); // Obtained Ring Box Tails
|
||||
void A_Invincibility(struct mobj_s *actor); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(struct mobj_s *actor); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(struct mobj_s *actor); // have bunny hop tails
|
||||
void A_BubbleSpawn(struct mobj_s *actor); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn(struct mobj_s *actor);
|
||||
void A_BubbleRise(struct mobj_s *actor); // Bubbles float to surface
|
||||
void A_BubbleCheck(struct mobj_s *actor); // Don't draw if not underwater
|
||||
void A_AwardScore(struct mobj_s *actor);
|
||||
void A_ExtraLife(struct mobj_s *actor); // Extra Life
|
||||
void A_BombShield(struct mobj_s *actor); // Obtained Bomb Shield
|
||||
void A_WaterShield(struct mobj_s *actor); // Obtained Water Shield
|
||||
void A_ForceShield(struct mobj_s *actor); // Obtained Force Shield
|
||||
void A_PityShield(struct mobj_s *actor); // Obtained Pity Shield. We're... sorry.
|
||||
void A_GravityBox(struct mobj_s *actor);
|
||||
void A_ScoreRise(struct mobj_s *actor); // Rise the score logo
|
||||
void A_ParticleSpawn(struct mobj_s *actor);
|
||||
void A_AttractChase(struct mobj_s *actor); // Ring Chase
|
||||
void A_DropMine(struct mobj_s *actor); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(struct mobj_s *actor); // Fish Jump
|
||||
void A_ThrownRing(struct mobj_s *actor); // Sparkle trail for red ring
|
||||
void A_GrenadeRing(struct mobj_s *actor); // SRB2kart
|
||||
void A_SetSolidSteam(struct mobj_s *actor);
|
||||
void A_UnsetSolidSteam(struct mobj_s *actor);
|
||||
void A_SignPlayer(struct mobj_s *actor);
|
||||
void A_OverlayThink(struct mobj_s *actor);
|
||||
void A_JetChase(struct mobj_s *actor);
|
||||
void A_JetbThink(struct mobj_s *actor); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(struct mobj_s *actor); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(struct mobj_s *actor); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(struct mobj_s *actor); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging(struct mobj_s *actor);
|
||||
void A_MinusPopup(struct mobj_s *actor);
|
||||
void A_MinusCheck(struct mobj_s *actor);
|
||||
void A_ChickenCheck(struct mobj_s *actor);
|
||||
void A_MouseThink(struct mobj_s *actor); // Mouse Thinker
|
||||
void A_DetonChase(struct mobj_s *actor); // Deton Chaser
|
||||
void A_CapeChase(struct mobj_s *actor); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(struct mobj_s *actor); // Spike ball rotation
|
||||
void A_SlingAppear(struct mobj_s *actor);
|
||||
void A_MaceRotate(struct mobj_s *actor);
|
||||
void A_UnidusBall(struct mobj_s *actor);
|
||||
void A_RockSpawn(struct mobj_s *actor);
|
||||
void A_SetFuse(struct mobj_s *actor);
|
||||
void A_CrawlaCommanderThink(struct mobj_s *actor); // Crawla Commander
|
||||
void A_SmokeTrailer(struct mobj_s *actor);
|
||||
void A_RingExplode(struct mobj_s *actor);
|
||||
void A_OldRingExplode(struct mobj_s *actor);
|
||||
void A_MixUp(struct mobj_s *actor);
|
||||
void A_RecyclePowers(struct mobj_s *actor);
|
||||
void A_BossScream(struct mobj_s *actor);
|
||||
void A_Boss2TakeDamage(struct mobj_s *actor);
|
||||
void A_GoopSplat(struct mobj_s *actor);
|
||||
void A_Boss2PogoSFX(struct mobj_s *actor);
|
||||
void A_Boss2PogoTarget(struct mobj_s *actor);
|
||||
void A_EggmanBox(struct mobj_s *actor);
|
||||
void A_TurretFire(struct mobj_s *actor);
|
||||
void A_SuperTurretFire(struct mobj_s *actor);
|
||||
void A_TurretStop(struct mobj_s *actor);
|
||||
void A_JetJawRoam(struct mobj_s *actor);
|
||||
void A_JetJawChomp(struct mobj_s *actor);
|
||||
void A_PointyThink(struct mobj_s *actor);
|
||||
void A_CheckBuddy(struct mobj_s *actor);
|
||||
void A_HoodThink(struct mobj_s *actor);
|
||||
void A_ArrowCheck(struct mobj_s *actor);
|
||||
void A_SnailerThink(struct mobj_s *actor);
|
||||
void A_SharpChase(struct mobj_s *actor);
|
||||
void A_SharpSpin(struct mobj_s *actor);
|
||||
void A_VultureVtol(struct mobj_s *actor);
|
||||
void A_VultureCheck(struct mobj_s *actor);
|
||||
void A_SkimChase(struct mobj_s *actor);
|
||||
void A_SkullAttack(struct mobj_s *actor);
|
||||
void A_LobShot(struct mobj_s *actor);
|
||||
void A_FireShot(struct mobj_s *actor);
|
||||
void A_SuperFireShot(struct mobj_s *actor);
|
||||
void A_BossFireShot(struct mobj_s *actor);
|
||||
void A_Boss7FireMissiles(struct mobj_s *actor);
|
||||
void A_Boss1Laser(struct mobj_s *actor);
|
||||
void A_FocusTarget(struct mobj_s *actor);
|
||||
void A_Boss4Reverse(struct mobj_s *actor);
|
||||
void A_Boss4SpeedUp(struct mobj_s *actor);
|
||||
void A_Boss4Raise(struct mobj_s *actor);
|
||||
void A_SparkFollow(struct mobj_s *actor);
|
||||
void A_BuzzFly(struct mobj_s *actor);
|
||||
void A_GuardChase(struct mobj_s *actor);
|
||||
void A_EggShield(struct mobj_s *actor);
|
||||
void A_SetReactionTime(struct mobj_s *actor);
|
||||
void A_Boss1Spikeballs(struct mobj_s *actor);
|
||||
void A_Boss3TakeDamage(struct mobj_s *actor);
|
||||
void A_Boss3Path(struct mobj_s *actor);
|
||||
void A_LinedefExecute(struct mobj_s *actor);
|
||||
void A_PlaySeeSound(struct mobj_s *actor);
|
||||
void A_PlayAttackSound(struct mobj_s *actor);
|
||||
void A_PlayActiveSound(struct mobj_s *actor);
|
||||
void A_1upThinker(struct mobj_s *actor);
|
||||
void A_BossZoom(struct mobj_s *actor); //Unused
|
||||
void A_Boss1Chase(struct mobj_s *actor);
|
||||
void A_Boss2Chase(struct mobj_s *actor);
|
||||
void A_Boss2Pogo(struct mobj_s *actor);
|
||||
void A_Boss7Chase(struct mobj_s *actor);
|
||||
void A_BossJetFume(struct mobj_s *actor);
|
||||
void A_SpawnObjectAbsolute(struct mobj_s *actor);
|
||||
void A_SpawnObjectRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleAbsolute(struct mobj_s *actor);
|
||||
void A_RollAngle(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleAbsolute(struct mobj_s *actor);
|
||||
void A_PlaySound(struct mobj_s *actor);
|
||||
void A_FindTarget(struct mobj_s *actor);
|
||||
void A_FindTracer(struct mobj_s *actor);
|
||||
void A_SetTics(struct mobj_s *actor);
|
||||
void A_SetRandomTics(struct mobj_s *actor);
|
||||
void A_ChangeColorRelative(struct mobj_s *actor);
|
||||
void A_ChangeColorAbsolute(struct mobj_s *actor);
|
||||
void A_MoveRelative(struct mobj_s *actor);
|
||||
void A_MoveAbsolute(struct mobj_s *actor);
|
||||
void A_Thrust(struct mobj_s *actor);
|
||||
void A_ZThrust(struct mobj_s *actor);
|
||||
void A_SetTargetsTarget(struct mobj_s *actor);
|
||||
void A_SetObjectFlags(struct mobj_s *actor);
|
||||
void A_SetObjectFlags2(struct mobj_s *actor);
|
||||
void A_RandomState(struct mobj_s *actor);
|
||||
void A_RandomStateRange(struct mobj_s *actor);
|
||||
void A_DualAction(struct mobj_s *actor);
|
||||
void A_RemoteAction(struct mobj_s *actor);
|
||||
void A_ToggleFlameJet(struct mobj_s *actor);
|
||||
void A_ItemPop(struct mobj_s *actor); // SRB2kart
|
||||
void A_JawzChase(struct mobj_s *actor); // SRB2kart
|
||||
void A_JawzExplode(struct mobj_s *actor); // SRB2kart
|
||||
void A_SPBChase(struct mobj_s *actor); // SRB2kart
|
||||
void A_MineExplode(struct mobj_s *actor); // SRB2kart
|
||||
void A_BallhogExplode(struct mobj_s *actor); // SRB2kart
|
||||
void A_LightningFollowPlayer(struct mobj_s *actor); // SRB2kart: Lightning shield effect player chasing
|
||||
void A_FZBoomFlash(struct mobj_s *actor); // SRB2kart
|
||||
void A_FZBoomSmoke(struct mobj_s *actor); // SRB2kart
|
||||
void A_RandomShadowFrame(struct mobj_s *actor); //SRB2kart: Shadow spawner frame randomizer
|
||||
void A_RoamingShadowThinker(struct mobj_s *actor); // SRB2kart: Roaming Shadow moving + attacking players.
|
||||
void A_MayonakaArrow(struct mobj_s *actor); //SRB2kart: midnight channel arrow sign
|
||||
void A_ReaperThinker(struct mobj_s *actor); //SRB2kart: mementos reaper
|
||||
void A_MementosTPParticles(struct mobj_s *actor); //SRB2kart: mementos teleporter particles. Man that's a lot of actions for my shite.
|
||||
void A_FlameParticle(struct mobj_s *actor); // SRB2kart
|
||||
void A_OrbitNights(struct mobj_s *actor);
|
||||
void A_GhostMe(struct mobj_s *actor);
|
||||
void A_SetObjectState(struct mobj_s *actor);
|
||||
void A_SetObjectTypeState(struct mobj_s *actor);
|
||||
void A_KnockBack(struct mobj_s *actor);
|
||||
void A_PushAway(struct mobj_s *actor);
|
||||
void A_RingDrain(struct mobj_s *actor);
|
||||
void A_SplitShot(struct mobj_s *actor);
|
||||
void A_MissileSplit(struct mobj_s *actor);
|
||||
void A_MultiShot(struct mobj_s *actor);
|
||||
void A_InstaLoop(struct mobj_s *actor);
|
||||
void A_Custom3DRotate(struct mobj_s *actor);
|
||||
void A_SearchForPlayers(struct mobj_s *actor);
|
||||
void A_CheckRandom(struct mobj_s *actor);
|
||||
void A_CheckTargetRings(struct mobj_s *actor);
|
||||
void A_CheckRings(struct mobj_s *actor);
|
||||
void A_CheckTotalRings(struct mobj_s *actor);
|
||||
void A_CheckHealth(struct mobj_s *actor);
|
||||
void A_CheckRange(struct mobj_s *actor);
|
||||
void A_CheckHeight(struct mobj_s *actor);
|
||||
void A_CheckTrueRange(struct mobj_s *actor);
|
||||
void A_CheckThingCount(struct mobj_s *actor);
|
||||
void A_CheckAmbush(struct mobj_s *actor);
|
||||
void A_CheckCustomValue(struct mobj_s *actor);
|
||||
void A_CheckCusValMemo(struct mobj_s *actor);
|
||||
void A_SetCustomValue(struct mobj_s *actor);
|
||||
void A_UseCusValMemo(struct mobj_s *actor);
|
||||
void A_RelayCustomValue(struct mobj_s *actor);
|
||||
void A_CusValAction(struct mobj_s *actor);
|
||||
void A_ForceStop(struct mobj_s *actor);
|
||||
void A_ForceWin(struct mobj_s *actor);
|
||||
void A_SpikeRetract(struct mobj_s *actor);
|
||||
void A_InfoState(struct mobj_s *actor);
|
||||
void A_Repeat(struct mobj_s *actor);
|
||||
void A_SetScale(struct mobj_s *actor);
|
||||
void A_RemoteDamage(struct mobj_s *actor);
|
||||
void A_HomingChase(struct mobj_s *actor);
|
||||
void A_TrapShot(struct mobj_s *actor);
|
||||
void A_VileTarget(struct mobj_s *actor);
|
||||
void A_VileAttack(struct mobj_s *actor);
|
||||
void A_VileFire(struct mobj_s *actor);
|
||||
void A_BrakChase(struct mobj_s *actor);
|
||||
void A_BrakFireShot(struct mobj_s *actor);
|
||||
void A_BrakLobShot(struct mobj_s *actor);
|
||||
void A_NapalmScatter(struct mobj_s *actor);
|
||||
void A_SpawnFreshCopy(struct mobj_s *actor);
|
||||
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by AJ "Tyron" Martinez.
|
||||
// Copyright (C) 2024 by James Robert Roman.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_director.c
|
||||
/// \brief SRB2kart automatic spectator camera.
|
||||
|
||||
//#include "k_kart.h"
|
||||
#include "doomdef.h"
|
||||
#include "g_game.h"
|
||||
#include "v_video.h"
|
||||
#include "k_director.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "p_local.h"
|
||||
#include "st_stuff.h"
|
||||
|
||||
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
|
||||
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
|
||||
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
|
||||
#define BREAKAWAYDIST 2000 // how *far* until players considered far apart?
|
||||
#define WALKBACKDIST 400 // how close should a trailing player be before we switch?
|
||||
#define PINCHDIST 20000 // how close should the leader be to be considered "end of race"?
|
||||
|
||||
struct directorinfo
|
||||
{
|
||||
tic_t cooldown; // how long has it been since we last switched?
|
||||
tic_t freeze; // when nonzero, fixed switch pending, freeze logic!
|
||||
INT32 attacker; // who to switch to when freeze delay elapses
|
||||
INT32 maxdist; // how far is the closest player from finishing?
|
||||
|
||||
INT32 sortedplayers[MAXPLAYERS]; // position-1 goes in, player index comes out.
|
||||
INT32 gap[MAXPLAYERS]; // gap between a given position and their closest pursuer
|
||||
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
|
||||
} directorinfo;
|
||||
|
||||
boolean K_DirectorIsPlayerAlone(void)
|
||||
{
|
||||
UINT8 pingame = 0;
|
||||
|
||||
// Gotta check how many players are active at this moment.
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
pingame++;
|
||||
|
||||
if (pingame >= 2) // we dont need to check further
|
||||
break;
|
||||
}
|
||||
|
||||
return (pingame <= 1);
|
||||
}
|
||||
|
||||
static inline boolean race_rules(void)
|
||||
{
|
||||
return gametype == GT_RACE;
|
||||
}
|
||||
|
||||
static fixed_t ScaleFromMap(fixed_t n, fixed_t scale)
|
||||
{
|
||||
return FixedMul(n, FixedDiv(scale, mapobjectscale));
|
||||
}
|
||||
|
||||
static boolean K_DirectorIsEnabled(void)
|
||||
{
|
||||
return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (((stplyr && !stplyr->spectator) && (!playeringame[consoleplayer] || players[consoleplayer].spectator)) || (demo.playback && !demo.freecam && (!demo.title || !modeattacking))) && !K_DirectorIsPlayerAlone());
|
||||
}
|
||||
|
||||
void K_InitDirector(void)
|
||||
{
|
||||
INT32 playernum;
|
||||
|
||||
directorinfo.cooldown = SWITCHTIME;
|
||||
directorinfo.freeze = 0;
|
||||
directorinfo.attacker = 0;
|
||||
directorinfo.maxdist = 0;
|
||||
|
||||
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||
{
|
||||
directorinfo.sortedplayers[playernum] = -1;
|
||||
directorinfo.gap[playernum] = INT32_MAX;
|
||||
directorinfo.boredom[playernum] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static fixed_t K_GetDistanceToFinish(player_t player)
|
||||
{
|
||||
mobj_t *mo;
|
||||
fixed_t dist = 0;
|
||||
INT16 maxMoveCount = -1;
|
||||
INT16 maxAngle = -1;
|
||||
|
||||
if (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE))
|
||||
{
|
||||
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
|
||||
{
|
||||
if (mo->spawnpoint->angle != 0)
|
||||
continue;
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(mo->x - player.mo->x,
|
||||
mo->y - player.mo->y),
|
||||
mo->z - player.mo->z) / FRACUNIT;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // crappy optimization weeeee
|
||||
{
|
||||
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
|
||||
{
|
||||
if (mo->movecount > maxMoveCount)
|
||||
maxMoveCount = mo->movecount;
|
||||
if (mo->spawnpoint->angle > maxAngle)
|
||||
maxAngle = mo->spawnpoint->angle;
|
||||
|
||||
if (!(mo->movecount == maxMoveCount && mo->spawnpoint->angle == maxAngle)) // sprint maps finishline waypoint is the one with highest movecount AND angle
|
||||
continue;
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(mo->x - player.mo->x,
|
||||
mo->y - player.mo->y),
|
||||
mo->z - player.mo->z) / FRACUNIT;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
static fixed_t K_GetFinishGap(INT32 leader, INT32 follower)
|
||||
{
|
||||
fixed_t dista = K_GetDistanceToFinish(players[follower]);
|
||||
fixed_t distb = K_GetDistanceToFinish(players[leader]);
|
||||
|
||||
if (players[follower].kartstuff[k_position] < players[leader].kartstuff[k_position])
|
||||
{
|
||||
return distb - dista;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dista - distb;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_UpdateDirectorPositions(void)
|
||||
{
|
||||
INT32 playernum;
|
||||
INT32 position;
|
||||
player_t* target;
|
||||
|
||||
memset(directorinfo.sortedplayers, -1, sizeof(directorinfo.sortedplayers));
|
||||
|
||||
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||
{
|
||||
target = &players[playernum];
|
||||
|
||||
if (playeringame[playernum] && !target->spectator && target->kartstuff[k_position] > 0)
|
||||
{
|
||||
directorinfo.sortedplayers[target->kartstuff[k_position] - 1] = playernum;
|
||||
}
|
||||
}
|
||||
|
||||
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||
{
|
||||
directorinfo.gap[position] = INT32_MAX;
|
||||
|
||||
if (directorinfo.sortedplayers[position] == -1 || directorinfo.sortedplayers[position + 1] == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
directorinfo.gap[position] = ScaleFromMap(K_GetFinishGap(directorinfo.sortedplayers[position], directorinfo.sortedplayers[position + 1]), FRACUNIT);
|
||||
|
||||
if (directorinfo.gap[position] >= BREAKAWAYDIST)
|
||||
{
|
||||
directorinfo.boredom[position] = (INT32)(min(BOREDOMTIME * 2, directorinfo.boredom[position] + 1));
|
||||
}
|
||||
else if (directorinfo.boredom[position] > 0)
|
||||
{
|
||||
directorinfo.boredom[position]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (directorinfo.sortedplayers[0] == -1)
|
||||
{
|
||||
directorinfo.maxdist = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
directorinfo.maxdist = ScaleFromMap(K_GetDistanceToFinish(players[directorinfo.sortedplayers[0]]), FRACUNIT);
|
||||
}
|
||||
|
||||
static boolean K_CanSwitchDirector(void)
|
||||
{
|
||||
if (directorinfo.cooldown > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void K_DirectorSwitch(INT32 player, boolean force)
|
||||
{
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsDisplayPlayer(&players[player]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (players[player].exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force && !K_CanSwitchDirector())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G_ResetView(1, player, true);
|
||||
directorinfo.cooldown = SWITCHTIME;
|
||||
}
|
||||
|
||||
static void K_DirectorForceSwitch(INT32 player, INT32 time)
|
||||
{
|
||||
if (players[player].exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
directorinfo.attacker = player;
|
||||
directorinfo.freeze = time;
|
||||
}
|
||||
|
||||
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!P_IsDisplayPlayer(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inflictor && inflictor->player)
|
||||
{
|
||||
K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME);
|
||||
}
|
||||
else if (source && source->player)
|
||||
{
|
||||
K_DirectorForceSwitch(source->player - players, TRANSFERTIME);
|
||||
}
|
||||
}
|
||||
|
||||
void K_DrawDirectorDebugger(void)
|
||||
{
|
||||
INT32 position;
|
||||
INT32 leader;
|
||||
INT32 follower;
|
||||
INT32 ytxt;
|
||||
|
||||
if (!cv_kartdebugdirector.value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
V_DrawThinString(10, 0, V_70TRANS, va("PLACE"));
|
||||
V_DrawThinString(40, 0, V_70TRANS, va("CONF?"));
|
||||
V_DrawThinString(80, 0, V_70TRANS, va("GAP"));
|
||||
V_DrawThinString(120, 0, V_70TRANS, va("BORED"));
|
||||
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfo.cooldown));
|
||||
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfo.maxdist));
|
||||
|
||||
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||
{
|
||||
ytxt = 10 * (position + 1);
|
||||
leader = directorinfo.sortedplayers[position];
|
||||
follower = directorinfo.sortedplayers[position + 1];
|
||||
|
||||
if (leader == -1 || follower == -1)
|
||||
break;
|
||||
|
||||
V_DrawThinString(10, ytxt, V_70TRANS, va("%d", position));
|
||||
V_DrawThinString(20, ytxt, V_70TRANS, va("%d", position + 1));
|
||||
|
||||
if (players[leader].kartstuff[k_positiondelay])
|
||||
{
|
||||
V_DrawThinString(40, ytxt, V_70TRANS, va("NG"));
|
||||
}
|
||||
|
||||
V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfo.gap[position]));
|
||||
|
||||
if (directorinfo.boredom[position] >= BOREDOMTIME)
|
||||
{
|
||||
V_DrawThinString(120, ytxt, V_70TRANS, va("BORED"));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(120, ytxt, V_70TRANS, va("%d", directorinfo.boredom[position]));
|
||||
}
|
||||
|
||||
V_DrawThinString(150, ytxt, V_70TRANS, va("%s", player_names[leader]));
|
||||
V_DrawThinString(230, ytxt, V_70TRANS, va("%s", player_names[follower]));
|
||||
}
|
||||
}
|
||||
|
||||
void K_UpdateDirector(void)
|
||||
{
|
||||
INT32 *displayplayerp = &displayplayers[0];
|
||||
INT32 targetposition;
|
||||
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
K_UpdateDirectorPositions();
|
||||
|
||||
if (directorinfo.cooldown > 0) {
|
||||
directorinfo.cooldown--;
|
||||
}
|
||||
|
||||
// handle pending forced switches
|
||||
if (directorinfo.freeze > 0)
|
||||
{
|
||||
if (!(--directorinfo.freeze))
|
||||
K_DirectorSwitch(directorinfo.attacker, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if there's only one player left in the list, just switch to that player
|
||||
if (directorinfo.sortedplayers[0] != -1 && (directorinfo.sortedplayers[1] == -1 ||
|
||||
// TODO: Battle; I just threw this together quick. Focus on leader.
|
||||
!race_rules()))
|
||||
{
|
||||
K_DirectorSwitch(directorinfo.sortedplayers[0], false);
|
||||
return;
|
||||
}
|
||||
|
||||
// aaight, time to walk through the standings to find the first interesting pair
|
||||
// NB: targetposition/sortedplayers is 0-indexed, aiming at the "back half" of a given pair by default.
|
||||
// we adjust for this when comparing to player->position or when looking at the leading player, Don't Freak Out
|
||||
for (targetposition = 1; targetposition < MAXPLAYERS; targetposition++)
|
||||
{
|
||||
INT32 target;
|
||||
|
||||
// you are out of players, try again
|
||||
if (directorinfo.sortedplayers[targetposition] == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// pair too far apart? try the next one
|
||||
if (directorinfo.boredom[targetposition - 1] >= BOREDOMTIME)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// pair finished? try the next one
|
||||
if (players[directorinfo.sortedplayers[targetposition]].exiting)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't risk switching away from forward pairs at race end, might miss something!
|
||||
if (directorinfo.maxdist > PINCHDIST)
|
||||
{
|
||||
// if the "next" player is close enough, they should be able to see everyone fine!
|
||||
// walk back through the standings to find a vantage that gets everyone in frame.
|
||||
// (also creates a pretty cool effect w/ overtakes at speed)
|
||||
while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < WALKBACKDIST)
|
||||
{
|
||||
targetposition++;
|
||||
}
|
||||
}
|
||||
|
||||
target = directorinfo.sortedplayers[targetposition];
|
||||
|
||||
// stop here since we're already viewing this player
|
||||
if (*displayplayerp == target)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// if this is a splitscreen player, try next pair
|
||||
if (P_IsDisplayPlayer(&players[target]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we're certain the back half of the pair is actually in this position, try to switch
|
||||
if (!players[target].kartstuff[k_positiondelay])
|
||||
{
|
||||
K_DirectorSwitch(target, false);
|
||||
}
|
||||
|
||||
// even if we're not certain, if we're certain we're watching the WRONG player, try to switch
|
||||
if (players[*displayplayerp].kartstuff[k_position] != targetposition+1 && !players[*displayplayerp].kartstuff[k_positiondelay])
|
||||
{
|
||||
K_DirectorSwitch(target, false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void K_ToggleDirector(void)
|
||||
{
|
||||
if (!directortextactive)
|
||||
return;
|
||||
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
directorinfo.cooldown = 0; // switch immediately
|
||||
}
|
||||
|
||||
directortoggletimer = 0;
|
||||
|
||||
COM_ImmedExecute("add director 1");
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by AJ "Tyron" Martinez.
|
||||
// Copyright (C) 2024 by James Robert Roman.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_director.h
|
||||
/// \brief SRB2kart automatic spectator camera.
|
||||
|
||||
void K_InitDirector(void);
|
||||
void K_UpdateDirector(void);
|
||||
void K_DrawDirectorDebugger(void);
|
||||
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
void K_ToggleDirector(void);
|
||||
+381
-335
File diff suppressed because it is too large.
Load diff
+2
-1
@@ -31,6 +31,7 @@ extern consvar_t cv_highresportrait;
|
||||
extern consvar_t cv_stat_xoffset;
|
||||
extern consvar_t cv_stat_yoffset;
|
||||
extern consvar_t cv_showstats;
|
||||
extern consvar_t cv_showlaptimes;
|
||||
extern consvar_t cv_battlespeedo;
|
||||
|
||||
#define NUMSPEEDOSTUFF 6
|
||||
@@ -91,7 +92,7 @@ void K_UpdateSpectateGrief(void);
|
||||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
void K_PlayBoostTaunt(mobj_t *source);
|
||||
void K_PlayOvertakeSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *victim);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||
|
||||
+83
-8
@@ -20,6 +20,7 @@
|
||||
#include "m_random.h"
|
||||
#include "s_sound.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "console.h"
|
||||
#include "k_kart.h" // SRB2Kart
|
||||
@@ -1258,6 +1259,7 @@ static int lib_pPlayRinglossSound(lua_State *L)
|
||||
{
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
player_t *player = NULL;
|
||||
mobj_t *damager = NULL;
|
||||
NOHUD
|
||||
if (!source)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
@@ -1267,8 +1269,15 @@ static int lib_pPlayRinglossSound(lua_State *L)
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
if (!lua_isnoneornil(L, 3))
|
||||
{
|
||||
damager = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
||||
if (!damager)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
}
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
P_PlayRinglossSound(source);
|
||||
P_PlayRinglossSound(source, damager);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1544,8 +1553,9 @@ static int lib_pSetSkyboxMobj(lua_State *L)
|
||||
// Shhh, neither does P_StartQuake.
|
||||
static int lib_pStartQuake(lua_State *L)
|
||||
{
|
||||
tic_t q_time = (tic_t)luaL_checkinteger(L, 2);
|
||||
fixed_t q_intensity = luaL_checkinteger(L, 1);
|
||||
UINT16 q_time = (UINT16)luaL_checkinteger(L, 2);
|
||||
fixed_t q_radius = luaL_optinteger(L, 4, 512<<FRACBITS);
|
||||
static mappoint_t q_epicenter = {0,0,0};
|
||||
|
||||
NOHUD
|
||||
@@ -1597,11 +1607,8 @@ static int lib_pStartQuake(lua_State *L)
|
||||
}
|
||||
else
|
||||
quake.epicenter = NULL;
|
||||
quake.radius = luaL_optinteger(L, 4, 512*FRACUNIT);
|
||||
|
||||
// These things are actually used in 2.1.
|
||||
quake.intensity = q_intensity;
|
||||
quake.time = q_time;
|
||||
P_StartQuake(q_time, q_intensity, q_radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2556,10 +2563,22 @@ static int lib_kOvertakeSound(lua_State *L)
|
||||
static int lib_kHitEmSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *victim = NULL;
|
||||
|
||||
if (!lua_isnoneornil(L, 2))
|
||||
{
|
||||
victim = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
if (!victim)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
}
|
||||
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayHitEmSound(mobj);
|
||||
if (victim && !victim->player)
|
||||
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Same as above
|
||||
|
||||
K_PlayHitEmSound(mobj, victim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3000,6 +3019,58 @@ static int lib_kSetHyuCountdown(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// G_INPUT
|
||||
////////////
|
||||
|
||||
static int lib_gSetPlayerGamepadIndicatorColor(lua_State *L)
|
||||
{
|
||||
INT32 player = -1;
|
||||
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 2); // skincolor
|
||||
|
||||
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
if (plr - players == displayplayers[i])
|
||||
{
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a local player
|
||||
if (player == -1) return 0;
|
||||
|
||||
// pls update with color 0 when youre done with changing led stuff so it can get player color again
|
||||
G_SetPlayerGamepadIndicatorColor(player, color);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_gPlayerDeviceRumble(lua_State *L)
|
||||
{
|
||||
INT32 player = -1;
|
||||
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
UINT16 low_strength = (UINT16)luaL_checkinteger(L, 2); // low frequency rumble motor strenght
|
||||
UINT16 high_strength = (UINT16)luaL_checkinteger(L, 3); // high frequency rumble motor strenght
|
||||
UINT32 duration = (UINT32)luaL_optinteger(L, 4, 84); // duration of rumble in ms
|
||||
|
||||
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
if (plr - players == displayplayers[i])
|
||||
{
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a local player
|
||||
if (player == -1) return 0;
|
||||
|
||||
G_PlayerDeviceRumble(player, low_strength, high_strength, duration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static luaL_Reg lib[] = {
|
||||
{"print", lib_print},
|
||||
{"chatprint", lib_chatprint},
|
||||
@@ -3247,6 +3318,10 @@ static luaL_Reg lib[] = {
|
||||
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
|
||||
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
|
||||
|
||||
//g_input
|
||||
{"G_SetPlayerGamepadIndicatorColor",lib_gSetPlayerGamepadIndicatorColor},
|
||||
{"G_PlayerDeviceRumble",lib_gPlayerDeviceRumble},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -3266,4 +3341,4 @@ int LUA_BaseLib(lua_State *L)
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
luaL_register(L, NULL, lib);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+56
-13
@@ -81,6 +81,9 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
|
||||
lua_pushstring(gL, buf);
|
||||
}
|
||||
LUA_Call(gL, (int)argc, 0, 1); // argc is 1-based, so this will cover the player we passed too.
|
||||
|
||||
lua_pop(gL, 1); // Pop LUA_GetErrorMessage (lua_pcall doesn't pop it)
|
||||
|
||||
return;
|
||||
|
||||
deny:
|
||||
@@ -143,7 +146,7 @@ void COM_Lua_f(void)
|
||||
if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */
|
||||
{ // Send the command through the network
|
||||
UINT8 argc;
|
||||
lua_pop(gL, 1); // pop command info table
|
||||
lua_pop(gL, 2); // pop command info table and LUA_GetErrorMessage
|
||||
|
||||
if (flags & COM_ADMIN && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command.
|
||||
{
|
||||
@@ -182,6 +185,8 @@ void COM_Lua_f(void)
|
||||
for (i = 1; i < COM_Argc(); i++)
|
||||
lua_pushstring(gL, COM_Argv(i));
|
||||
LUA_Call(gL, (int)COM_Argc(), 0, 1); // COM_Argc is 1-based, so this will cover the player we passed too.
|
||||
|
||||
lua_pop(gL, 1); // Pop LUA_GetErrorMessage (lua_pcall doesn't pop it)
|
||||
}
|
||||
|
||||
// Wrapper for COM_AddCommand
|
||||
@@ -453,9 +458,11 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
|
||||
if (!(((cvar->flags & CV_HIDEN)) || (cvar->flags & CV_NOSHOWHELP)) && (cvar->PossibleValue || !(cvar->value == 0 && stricmp(cvar->string, "0"))))
|
||||
{
|
||||
char *temp = NULL;
|
||||
|
||||
if (!category)
|
||||
{
|
||||
char *temp = strdup(wadfiles[numwadfiles - 1]->filename);
|
||||
temp = strdup(wadfiles[numwadfiles - 1]->filename);
|
||||
nameonly(temp);
|
||||
|
||||
category = temp;
|
||||
@@ -465,6 +472,8 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
M_SlotCvarIntoModMenu(cvar, category, menu_name);
|
||||
else
|
||||
M_SlotCvarIntoModMenu(cvar, category, cvar->name);
|
||||
|
||||
free (temp);
|
||||
}
|
||||
|
||||
// return cvar userdata
|
||||
@@ -580,27 +589,59 @@ static luaL_Reg lib[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
enum cvar_e
|
||||
{
|
||||
cvar_name,
|
||||
cvar_defaultvalue,
|
||||
cvar_flags,
|
||||
cvar_value,
|
||||
cvar_string,
|
||||
cvar_changed,
|
||||
};
|
||||
|
||||
static const char *const cvar_opt[] = {
|
||||
"name",
|
||||
"defaultvalue",
|
||||
"flags",
|
||||
"value",
|
||||
"string",
|
||||
"changed",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int cvar_fields_ref = LUA_NOREF;
|
||||
|
||||
static int cvar_get(lua_State *L)
|
||||
{
|
||||
consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR);
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum cvar_e field = Lua_optoption(L, 2, -1, cvar_fields_ref);
|
||||
|
||||
if(fastcmp(field,"name"))
|
||||
switch (field)
|
||||
{
|
||||
case cvar_name:
|
||||
lua_pushstring(L, cvar->name);
|
||||
else if(fastcmp(field,"defaultvalue"))
|
||||
break;
|
||||
case cvar_defaultvalue:
|
||||
lua_pushstring(L, cvar->defaultvalue);
|
||||
else if(fastcmp(field,"flags"))
|
||||
break;
|
||||
case cvar_flags:
|
||||
lua_pushinteger(L, cvar->flags);
|
||||
else if(fastcmp(field,"value"))
|
||||
break;
|
||||
case cvar_value:
|
||||
lua_pushinteger(L, cvar->value);
|
||||
else if(fastcmp(field,"string"))
|
||||
break;
|
||||
case cvar_string:
|
||||
lua_pushstring(L, cvar->string);
|
||||
else if(fastcmp(field,"changed"))
|
||||
break;
|
||||
case cvar_changed:
|
||||
lua_pushboolean(L, cvar->changed);
|
||||
else if (devparm)
|
||||
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
if (devparm)
|
||||
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -612,6 +653,8 @@ int LUA_ConsoleLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L,1);
|
||||
|
||||
cvar_fields_ref = Lua_CreateFieldTable(L, cvar_opt);
|
||||
|
||||
// Set empty registry tables
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "COM_Command");
|
||||
|
||||
+4
-1
@@ -55,6 +55,7 @@ enum hook {
|
||||
hook_PlayerCmd, //SRB2KART
|
||||
hook_IntermissionThinker, //SRB2KART
|
||||
hook_VoteThinker, //SRB2KART
|
||||
hook_ServerJoin, // SRB2KART - Saturn 32p
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
@@ -106,8 +107,10 @@ boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); //
|
||||
boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
|
||||
void LUAh_ServerJoin(void); // SRB2KART - Saturn 32p: called by client when joining a server, allows lua to load any sort of config file
|
||||
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
|
||||
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
+1032
-811
File diff suppressed because it is too large.
Load diff
+10
-2
@@ -106,6 +106,8 @@ static const char *const hudhook_opt[] = {
|
||||
"vote",
|
||||
NULL};
|
||||
|
||||
static int patch_fields_ref = LUA_NOREF;
|
||||
|
||||
// alignment types for v.drawString
|
||||
enum align {
|
||||
align_left = 0,
|
||||
@@ -229,6 +231,8 @@ static const char *const hud_drawinfo_options[] = {
|
||||
"minimap",
|
||||
NULL};
|
||||
|
||||
static int camera_fields_ref = LUA_NOREF;
|
||||
|
||||
static int lib_getHudInfo(lua_State *L)
|
||||
{
|
||||
UINT32 i;
|
||||
@@ -298,7 +302,7 @@ static int colormap_get(lua_State *L)
|
||||
static int patch_get(lua_State *L)
|
||||
{
|
||||
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
|
||||
enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);
|
||||
enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref);
|
||||
|
||||
// patches are CURRENTLY always valid, expected to be cached with PU_STATIC
|
||||
// this may change in the future, so patch.valid still exists
|
||||
@@ -333,7 +337,7 @@ static int patch_set(lua_State *L)
|
||||
static int camera_get(lua_State *L)
|
||||
{
|
||||
camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA));
|
||||
enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt);
|
||||
enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref);
|
||||
|
||||
// cameras should always be valid unless I'm a nutter
|
||||
I_Assert(cam != NULL);
|
||||
@@ -1439,11 +1443,15 @@ int LUA_HudLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
patch_fields_ref = Lua_CreateFieldTable(L, patch_opt);
|
||||
|
||||
luaL_newmetatable(L, META_CAMERA);
|
||||
lua_pushcfunction(L, camera_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L,1);
|
||||
|
||||
camera_fields_ref = Lua_CreateFieldTable(L, camera_opt);
|
||||
|
||||
luaL_register(L, "hud", lib_hud);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ static UINT64 GetItemId(void)
|
||||
return 0;
|
||||
|
||||
// leave bits 0 and 1 free for the string mode
|
||||
UINT64 id = ((uintptr_t)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2);
|
||||
UINT64 id = ((UINT64)(uintptr_t)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2);
|
||||
|
||||
if (hud_interplatch)
|
||||
{
|
||||
@@ -632,12 +632,18 @@ void LUA_HUD_DrawList(huddrawlist_h list)
|
||||
switch (item->type)
|
||||
{
|
||||
case DI_Draw:
|
||||
if (!item->patch || item->patch == NULL)
|
||||
return;
|
||||
V_DrawFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap);
|
||||
break;
|
||||
case DI_DrawScaled:
|
||||
if (!item->patch || item->patch == NULL)
|
||||
return;
|
||||
V_DrawFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap);
|
||||
break;
|
||||
case DI_DrawStretched:
|
||||
if (!item->patch || item->patch == NULL)
|
||||
return;
|
||||
V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap);
|
||||
break;
|
||||
case DI_DrawNum:
|
||||
|
||||
+356
-162
@@ -23,34 +23,10 @@
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
|
||||
boolean LUA_CallAction(const char *action, mobj_t *actor);
|
||||
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
|
||||
state_t *astate;
|
||||
|
||||
enum sfxinfo_read {
|
||||
sfxinfor_name = 0,
|
||||
sfxinfor_singular,
|
||||
sfxinfor_priority,
|
||||
sfxinfor_flags, // "pitch"
|
||||
sfxinfor_skinsound
|
||||
};
|
||||
const char *const sfxinfo_ropt[] = {
|
||||
"name",
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
"skinsound",
|
||||
NULL};
|
||||
|
||||
enum sfxinfo_write {
|
||||
sfxinfow_singular = 0,
|
||||
sfxinfow_priority,
|
||||
sfxinfow_flags // "pitch"
|
||||
};
|
||||
const char *const sfxinfo_wopt[] = {
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
NULL};
|
||||
boolean actionsoverridden[NUMACTIONS] = {false};
|
||||
|
||||
//
|
||||
// Sprite Names
|
||||
@@ -101,7 +77,7 @@ static void A_Lua(mobj_t *actor)
|
||||
{
|
||||
boolean found = false;
|
||||
I_Assert(actor != NULL);
|
||||
|
||||
|
||||
lua_settop(gL, 0); // Just in case...
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
@@ -135,6 +111,8 @@ static void A_Lua(mobj_t *actor)
|
||||
lua_pushinteger(gL, var2);
|
||||
LUA_Call(gL, 3, 0, 1);
|
||||
|
||||
lua_pop(gL, 1); // pop error handler
|
||||
|
||||
if (found)
|
||||
{
|
||||
--superstack;
|
||||
@@ -276,27 +254,21 @@ boolean LUA_SetLuaAction(void *stv, const char *action)
|
||||
return true; // action successfully set.
|
||||
}
|
||||
|
||||
boolean LUA_CallAction(const char *csaction, mobj_t *actor)
|
||||
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor)
|
||||
{
|
||||
I_Assert(csaction != NULL);
|
||||
I_Assert(actor != NULL);
|
||||
|
||||
if (!gL) // Lua isn't loaded,
|
||||
if (!actionsoverridden[actionnum]) // The action is not overriden,
|
||||
return false; // action not called.
|
||||
|
||||
if (superstack && fasticmp(csaction, superactions[superstack-1])) // the action is calling itself,
|
||||
return false; // let it call the hardcoded function instead.
|
||||
if (superstack && fasticmp(actionpointers[actionnum].name, superactions[superstack-1])) // the action is calling itself,
|
||||
return false; // let it call the hardcoded function
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
// grab function by uppercase name.
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||
{
|
||||
char *action = Z_StrDup(csaction);
|
||||
strupr(action);
|
||||
lua_getfield(gL, -1, action);
|
||||
Z_Free(action);
|
||||
}
|
||||
lua_getfield(gL, -1, actionpointers[actionnum].name);
|
||||
lua_remove(gL, -2); // pop LREG_ACTIONS
|
||||
|
||||
if (lua_isnil(gL, -1)) // no match
|
||||
@@ -319,7 +291,7 @@ boolean LUA_CallAction(const char *csaction, mobj_t *actor)
|
||||
lua_pushinteger(gL, var1);
|
||||
lua_pushinteger(gL, var2);
|
||||
|
||||
superactions[superstack] = csaction;
|
||||
superactions[superstack] = actionpointers[actionnum].name;
|
||||
++superstack;
|
||||
|
||||
LUA_Call(gL, 3, 0, -(2 + 3));
|
||||
@@ -330,49 +302,93 @@ boolean LUA_CallAction(const char *csaction, mobj_t *actor)
|
||||
return true; // action successfully called.
|
||||
}
|
||||
|
||||
enum state_e {
|
||||
state_sprite = 0,
|
||||
state_frame,
|
||||
state_tics,
|
||||
state_action,
|
||||
state_var1,
|
||||
state_var2,
|
||||
state_nextstate,
|
||||
};
|
||||
|
||||
const char *const state_opt[] = {
|
||||
"sprite",
|
||||
"frame",
|
||||
"tics",
|
||||
"action",
|
||||
"var1",
|
||||
"var2",
|
||||
"nextstate",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int state_fields_ref = LUA_NOREF;
|
||||
|
||||
// state_t *, field -> number
|
||||
static int state_get(lua_State *L)
|
||||
{
|
||||
state_t *st = *((state_t **)luaL_checkudata(L, 1, META_STATE));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum state_e field = Lua_optoption(L, 2, -1, state_fields_ref);
|
||||
lua_Integer number;
|
||||
|
||||
if (fastcmp(field,"sprite"))
|
||||
number = st->sprite;
|
||||
else if (fastcmp(field,"frame"))
|
||||
number = st->frame;
|
||||
else if (fastcmp(field,"tics"))
|
||||
number = st->tics;
|
||||
else if (fastcmp(field,"action")) {
|
||||
const char *name;
|
||||
if (!st->action.acp1) // Action is NULL.
|
||||
return 0; // return nil.
|
||||
if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function?
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, st); // Push the state pointer and
|
||||
lua_rawget(L, -2); // use it to get the actual Lua function.
|
||||
lua_remove(L, -2); // pop LREG_STATEACTION
|
||||
return 1; // Return the Lua function.
|
||||
switch (field)
|
||||
{
|
||||
case state_sprite:
|
||||
number = st->sprite;
|
||||
break;
|
||||
|
||||
case state_frame:
|
||||
number = st->frame;
|
||||
break;
|
||||
|
||||
case state_tics:
|
||||
number = st->tics;
|
||||
break;
|
||||
|
||||
case state_action:
|
||||
{
|
||||
const char *name;
|
||||
if (!st->action.acp1) // Action is NULL.
|
||||
return 0; // return nil.
|
||||
if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function?
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, st); // Push the state pointer and
|
||||
lua_rawget(L, -2); // use it to get the actual Lua function.
|
||||
lua_remove(L, -2); // pop LREG_STATEACTION
|
||||
return 1; // Return the Lua function.
|
||||
}
|
||||
name = LUA_GetActionName(&st->action); // find a hardcoded function name
|
||||
if (!name) // If it's not a hardcoded function and it's not a Lua function...
|
||||
return 0; // Just what is this??
|
||||
// get the function from the global
|
||||
// because the metatable will trigger.
|
||||
lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a new C closure if not.
|
||||
lua_pushstring(L, name); // push the name we found.
|
||||
return 2; // return both the function and its name, in case somebody wanted to do a comparison by name or something?
|
||||
}
|
||||
name = LUA_GetActionName(&st->action); // find a hardcoded function name
|
||||
if (!name) // If it's not a hardcoded function and it's not a Lua function...
|
||||
return 0; // Just what is this??
|
||||
// get the function from the global
|
||||
// because the metatable will trigger.
|
||||
lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a new C closure if not.
|
||||
lua_pushstring(L, name); // push the name we found.
|
||||
return 2; // return both the function and its name, in case somebody wanted to do a comparison by name or something?
|
||||
} else if (fastcmp(field,"var1"))
|
||||
number = st->var1;
|
||||
else if (fastcmp(field,"var2"))
|
||||
number = st->var2;
|
||||
else if (fastcmp(field,"nextstate"))
|
||||
number = st->nextstate;
|
||||
else if (devparm)
|
||||
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case state_var1:
|
||||
number = st->var1;
|
||||
break;
|
||||
|
||||
case state_var2:
|
||||
number = st->var2;
|
||||
break;
|
||||
|
||||
case state_nextstate:
|
||||
number = st->nextstate;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (devparm)
|
||||
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushinteger(L, number);
|
||||
return 1;
|
||||
@@ -382,7 +398,7 @@ static int state_get(lua_State *L)
|
||||
static int state_set(lua_State *L)
|
||||
{
|
||||
state_t *st = *((state_t **)luaL_checkudata(L, 1, META_STATE));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum state_e field = Lua_optoption(L, 2, -1, state_fields_ref);
|
||||
lua_Integer value;
|
||||
|
||||
if (hud_running)
|
||||
@@ -390,16 +406,24 @@ static int state_set(lua_State *L)
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter states in BuildCMD code!");
|
||||
|
||||
if (fastcmp(field,"sprite")) {
|
||||
switch (field)
|
||||
{
|
||||
case state_sprite:
|
||||
value = luaL_checknumber(L, 3);
|
||||
if (value < SPR_NULL || value >= NUMSPRITES)
|
||||
return luaL_error(L, "sprite number %d is invalid.", value);
|
||||
st->sprite = (spritenum_t)value;
|
||||
} else if (fastcmp(field,"frame"))
|
||||
break;
|
||||
|
||||
case state_frame:
|
||||
st->frame = (UINT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"tics"))
|
||||
break;
|
||||
|
||||
case state_tics:
|
||||
st->tics = (INT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"action")) {
|
||||
break;
|
||||
|
||||
case state_action:
|
||||
switch(lua_type(L, 3))
|
||||
{
|
||||
case LUA_TNIL: // Null? Set the action to nothing, then.
|
||||
@@ -420,17 +444,26 @@ static int state_set(lua_State *L)
|
||||
default: // ?!
|
||||
return luaL_typerror(L, 3, "function");
|
||||
}
|
||||
} else if (fastcmp(field,"var1"))
|
||||
break;
|
||||
|
||||
case state_var1:
|
||||
st->var1 = (INT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"var2"))
|
||||
break;
|
||||
|
||||
case state_var2:
|
||||
st->var2 = (INT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"nextstate")) {
|
||||
break;
|
||||
|
||||
case state_nextstate:
|
||||
value = luaL_checkinteger(L, 3);
|
||||
if (value < S_NULL || value >= NUMSTATES)
|
||||
return luaL_error(L, "nextstate number %d is invalid.", value);
|
||||
st->nextstate = (statenum_t)value;
|
||||
} else
|
||||
break;
|
||||
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -565,75 +598,161 @@ static int lib_mobjinfolen(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum mobjinfo_e
|
||||
{
|
||||
mobjinfo_doomednum,
|
||||
mobjinfo_spawnstate,
|
||||
mobjinfo_spawnhealth,
|
||||
mobjinfo_seestate,
|
||||
mobjinfo_seesound,
|
||||
mobjinfo_reactiontime,
|
||||
mobjinfo_attacksound,
|
||||
mobjinfo_painstate,
|
||||
mobjinfo_painchance,
|
||||
mobjinfo_painsound,
|
||||
mobjinfo_meleestate,
|
||||
mobjinfo_missilestate,
|
||||
mobjinfo_deathstate,
|
||||
mobjinfo_xdeathstate,
|
||||
mobjinfo_deathsound,
|
||||
mobjinfo_speed,
|
||||
mobjinfo_radius,
|
||||
mobjinfo_height,
|
||||
mobjinfo_dispoffset,
|
||||
mobjinfo_mass,
|
||||
mobjinfo_damage,
|
||||
mobjinfo_activesound,
|
||||
mobjinfo_flags,
|
||||
mobjinfo_raisestate,
|
||||
};
|
||||
|
||||
const char *const mobjinfo_opt[] = {
|
||||
"doomednum",
|
||||
"spawnstate",
|
||||
"spawnhealth",
|
||||
"seestate",
|
||||
"seesound",
|
||||
"reactiontime",
|
||||
"attacksound",
|
||||
"painstate",
|
||||
"painchance",
|
||||
"painsound",
|
||||
"meleestate",
|
||||
"missilestate",
|
||||
"deathstate",
|
||||
"xdeathstate",
|
||||
"deathsound",
|
||||
"speed",
|
||||
"radius",
|
||||
"height",
|
||||
"dispoffset",
|
||||
"mass",
|
||||
"damage",
|
||||
"activesound",
|
||||
"flags",
|
||||
"raisestate",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int mobjinfo_fields_ref = LUA_NOREF;
|
||||
|
||||
// mobjinfo_t *, field -> number
|
||||
static int mobjinfo_get(lua_State *L)
|
||||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mobjinfo_e field = Lua_optoption(L, 2, -1, mobjinfo_fields_ref);
|
||||
|
||||
I_Assert(info != NULL);
|
||||
I_Assert(info >= mobjinfo);
|
||||
|
||||
if (fastcmp(field,"doomednum"))
|
||||
switch (field)
|
||||
{
|
||||
case mobjinfo_doomednum:
|
||||
lua_pushinteger(L, info->doomednum);
|
||||
else if (fastcmp(field,"spawnstate"))
|
||||
break;
|
||||
case mobjinfo_spawnstate:
|
||||
lua_pushinteger(L, info->spawnstate);
|
||||
else if (fastcmp(field,"spawnhealth"))
|
||||
break;
|
||||
case mobjinfo_spawnhealth:
|
||||
lua_pushinteger(L, info->spawnhealth);
|
||||
else if (fastcmp(field,"seestate"))
|
||||
break;
|
||||
case mobjinfo_seestate:
|
||||
lua_pushinteger(L, info->seestate);
|
||||
else if (fastcmp(field,"seesound"))
|
||||
break;
|
||||
case mobjinfo_seesound:
|
||||
lua_pushinteger(L, info->seesound);
|
||||
else if (fastcmp(field,"reactiontime"))
|
||||
break;
|
||||
case mobjinfo_reactiontime:
|
||||
lua_pushinteger(L, info->reactiontime);
|
||||
else if (fastcmp(field,"attacksound"))
|
||||
break;
|
||||
case mobjinfo_attacksound:
|
||||
lua_pushinteger(L, info->attacksound);
|
||||
else if (fastcmp(field,"painstate"))
|
||||
break;
|
||||
case mobjinfo_painstate:
|
||||
lua_pushinteger(L, info->painstate);
|
||||
else if (fastcmp(field,"painchance"))
|
||||
break;
|
||||
case mobjinfo_painchance:
|
||||
lua_pushinteger(L, info->painchance);
|
||||
else if (fastcmp(field,"painsound"))
|
||||
break;
|
||||
case mobjinfo_painsound:
|
||||
lua_pushinteger(L, info->painsound);
|
||||
else if (fastcmp(field,"meleestate"))
|
||||
break;
|
||||
case mobjinfo_meleestate:
|
||||
lua_pushinteger(L, info->meleestate);
|
||||
else if (fastcmp(field,"missilestate"))
|
||||
break;
|
||||
case mobjinfo_missilestate:
|
||||
lua_pushinteger(L, info->missilestate);
|
||||
else if (fastcmp(field,"deathstate"))
|
||||
break;
|
||||
case mobjinfo_deathstate:
|
||||
lua_pushinteger(L, info->deathstate);
|
||||
else if (fastcmp(field,"xdeathstate"))
|
||||
break;
|
||||
case mobjinfo_xdeathstate:
|
||||
lua_pushinteger(L, info->xdeathstate);
|
||||
else if (fastcmp(field,"deathsound"))
|
||||
break;
|
||||
case mobjinfo_deathsound:
|
||||
lua_pushinteger(L, info->deathsound);
|
||||
else if (fastcmp(field,"speed"))
|
||||
break;
|
||||
case mobjinfo_speed:
|
||||
lua_pushinteger(L, info->speed); // sometimes it's fixed_t, sometimes it's not...
|
||||
else if (fastcmp(field,"radius"))
|
||||
break;
|
||||
case mobjinfo_radius:
|
||||
lua_pushfixed(L, info->radius);
|
||||
else if (fastcmp(field,"height"))
|
||||
break;
|
||||
case mobjinfo_height:
|
||||
lua_pushfixed(L, info->height);
|
||||
else if (fastcmp(field,"dispoffset"))
|
||||
break;
|
||||
case mobjinfo_dispoffset:
|
||||
lua_pushinteger(L, info->dispoffset);
|
||||
else if (fastcmp(field,"mass"))
|
||||
break;
|
||||
case mobjinfo_mass:
|
||||
lua_pushinteger(L, info->mass);
|
||||
else if (fastcmp(field,"damage"))
|
||||
break;
|
||||
case mobjinfo_damage:
|
||||
lua_pushinteger(L, info->damage);
|
||||
else if (fastcmp(field,"activesound"))
|
||||
break;
|
||||
case mobjinfo_activesound:
|
||||
lua_pushinteger(L, info->activesound);
|
||||
else if (fastcmp(field,"flags"))
|
||||
break;
|
||||
case mobjinfo_flags:
|
||||
lua_pushinteger(L, info->flags);
|
||||
else if (fastcmp(field,"raisestate"))
|
||||
break;
|
||||
case mobjinfo_raisestate:
|
||||
lua_pushinteger(L, info->raisestate);
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, info);
|
||||
lua_rawget(L, -2);
|
||||
if (!lua_istable(L, -1)) { // no extra values table
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2));
|
||||
return 0;
|
||||
}
|
||||
lua_getfield(L, -1, field);
|
||||
lua_pushvalue(L, 2); // field name
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isnil(L, -1)) // no value for this field
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2));
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -642,7 +761,7 @@ static int mobjinfo_get(lua_State *L)
|
||||
static int mobjinfo_set(lua_State *L)
|
||||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mobjinfo_e field = Lua_optoption(L, 2, -1, mobjinfo_fields_ref);
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
||||
@@ -652,55 +771,81 @@ static int mobjinfo_set(lua_State *L)
|
||||
I_Assert(info != NULL);
|
||||
I_Assert(info >= mobjinfo);
|
||||
|
||||
if (fastcmp(field,"doomednum"))
|
||||
switch (field)
|
||||
{
|
||||
case mobjinfo_doomednum:
|
||||
info->doomednum = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spawnstate"))
|
||||
break;
|
||||
case mobjinfo_spawnstate:
|
||||
info->spawnstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spawnhealth"))
|
||||
break;
|
||||
case mobjinfo_spawnhealth:
|
||||
info->spawnhealth = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seestate"))
|
||||
break;
|
||||
case mobjinfo_seestate:
|
||||
info->seestate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seesound"))
|
||||
break;
|
||||
case mobjinfo_seesound:
|
||||
info->seesound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"reactiontime"))
|
||||
break;
|
||||
case mobjinfo_reactiontime:
|
||||
info->reactiontime = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"attacksound"))
|
||||
break;
|
||||
case mobjinfo_attacksound:
|
||||
info->attacksound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"painstate"))
|
||||
break;
|
||||
case mobjinfo_painstate:
|
||||
info->painstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"painchance"))
|
||||
break;
|
||||
case mobjinfo_painchance:
|
||||
info->painchance = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"painsound"))
|
||||
break;
|
||||
case mobjinfo_painsound:
|
||||
info->painsound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"meleestate"))
|
||||
break;
|
||||
case mobjinfo_meleestate:
|
||||
info->meleestate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"missilestate"))
|
||||
break;
|
||||
case mobjinfo_missilestate:
|
||||
info->missilestate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"deathstate"))
|
||||
break;
|
||||
case mobjinfo_deathstate:
|
||||
info->deathstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"xdeathstate"))
|
||||
break;
|
||||
case mobjinfo_xdeathstate:
|
||||
info->xdeathstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"deathsound"))
|
||||
break;
|
||||
case mobjinfo_deathsound:
|
||||
info->deathsound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"speed"))
|
||||
break;
|
||||
case mobjinfo_speed:
|
||||
info->speed = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"radius"))
|
||||
break;
|
||||
case mobjinfo_radius:
|
||||
info->radius = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"height"))
|
||||
break;
|
||||
case mobjinfo_height:
|
||||
info->height = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"dispoffset"))
|
||||
break;
|
||||
case mobjinfo_dispoffset:
|
||||
info->dispoffset = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"mass"))
|
||||
break;
|
||||
case mobjinfo_mass:
|
||||
info->mass = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"damage"))
|
||||
break;
|
||||
case mobjinfo_damage:
|
||||
info->damage = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"activesound"))
|
||||
break;
|
||||
case mobjinfo_activesound:
|
||||
info->activesound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"flags"))
|
||||
break;
|
||||
case mobjinfo_flags:
|
||||
info->flags = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"raisestate"))
|
||||
break;
|
||||
case mobjinfo_raisestate:
|
||||
info->raisestate = luaL_checkinteger(L, 3);
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, info);
|
||||
@@ -708,18 +853,17 @@ static int mobjinfo_set(lua_State *L)
|
||||
if (lua_isnil(L, -1)) {
|
||||
// This index doesn't have a table for extra values yet, let's make one.
|
||||
lua_pop(L, 1);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", field);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", lua_tostring(L, 2));
|
||||
lua_newtable(L);
|
||||
lua_pushlightuserdata(L, info);
|
||||
lua_pushvalue(L, -2); // ext value table
|
||||
lua_rawset(L, -4); // LREG_EXTVARS table
|
||||
}
|
||||
lua_pushvalue(L, 2); // key
|
||||
lua_pushvalue(L, 3); // value to store
|
||||
lua_setfield(L, -2, field);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
//else
|
||||
//return luaL_error(L, LUA_QL("mobjinfo_t") " has no field named " LUA_QS, field);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -752,6 +896,25 @@ static int lib_getSfxInfo(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum sfxinfo_e {
|
||||
sfxinfo_name = 0,
|
||||
sfxinfo_singular,
|
||||
sfxinfo_priority,
|
||||
sfxinfo_flags, // "pitch"
|
||||
sfxinfo_skinsound
|
||||
};
|
||||
|
||||
const char *const sfxinfo_opt[] = {
|
||||
"name",
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
"skinsound",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int sfxinfo_fields_ref = LUA_NOREF;
|
||||
|
||||
// stack: dummy, S_sfx[] table index, table of values to set.
|
||||
static int lib_setSfxInfo(lua_State *L)
|
||||
{
|
||||
@@ -775,22 +938,44 @@ static int lib_setSfxInfo(lua_State *L)
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
enum sfxinfo_write i;
|
||||
enum sfxinfo_e i;
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
i = lua_tointeger(L, 2) - 1; // lua is one based, this enum is zero based.
|
||||
{
|
||||
int j = lua_tointeger(L, 2);
|
||||
|
||||
// Read and Write enums were combined, need to do this switch now
|
||||
switch (j)
|
||||
{
|
||||
case 1:
|
||||
i = sfxinfo_singular;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
i = sfxinfo_priority;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
i = sfxinfo_flags;
|
||||
break;
|
||||
|
||||
default:
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
i = luaL_checkoption(L, 2, NULL, sfxinfo_wopt);
|
||||
i = Lua_optoption(L, 2, -1, sfxinfo_fields_ref);
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case sfxinfow_singular:
|
||||
case sfxinfo_singular:
|
||||
info->singularity = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case sfxinfow_priority:
|
||||
case sfxinfo_priority:
|
||||
info->priority = (INT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case sfxinfow_flags:
|
||||
case sfxinfo_flags:
|
||||
info->pitch = (INT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
default:
|
||||
@@ -812,29 +997,29 @@ static int lib_sfxlen(lua_State *L)
|
||||
static int sfxinfo_get(lua_State *L)
|
||||
{
|
||||
sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
|
||||
enum sfxinfo_read field = luaL_checkoption(L, 2, NULL, sfxinfo_ropt);
|
||||
enum sfxinfo_e field = Lua_optoption(L, 2, -1, sfxinfo_fields_ref);
|
||||
|
||||
I_Assert(sfx != NULL);
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case sfxinfor_name:
|
||||
case sfxinfo_name:
|
||||
lua_pushstring(L, sfx->name);
|
||||
return 1;
|
||||
case sfxinfor_singular:
|
||||
case sfxinfo_singular:
|
||||
lua_pushboolean(L, sfx->singularity);
|
||||
return 1;
|
||||
case sfxinfor_priority:
|
||||
case sfxinfo_priority:
|
||||
lua_pushinteger(L, sfx->priority);
|
||||
return 1;
|
||||
case sfxinfor_flags:
|
||||
case sfxinfo_flags:
|
||||
lua_pushinteger(L, sfx->pitch);
|
||||
return 1;
|
||||
case sfxinfor_skinsound:
|
||||
case sfxinfo_skinsound:
|
||||
lua_pushinteger(L, sfx->skinsound);
|
||||
return 1;
|
||||
default:
|
||||
return luaL_error(L, "impossible error");
|
||||
return luaL_error(L, LUA_QL("sfxinfo_t") " has no field named " LUA_QS, lua_tostring(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -843,7 +1028,7 @@ static int sfxinfo_get(lua_State *L)
|
||||
static int sfxinfo_set(lua_State *L)
|
||||
{
|
||||
sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
|
||||
enum sfxinfo_write field = luaL_checkoption(L, 2, NULL, sfxinfo_wopt);
|
||||
int field = Lua_optoption(L, 2, -1, sfxinfo_fields_ref);
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter S_sfx in HUD rendering code!");
|
||||
@@ -858,17 +1043,20 @@ static int sfxinfo_set(lua_State *L)
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case sfxinfow_singular:
|
||||
case sfxinfo_singular:
|
||||
sfx->singularity = luaL_checkboolean(L, 1);
|
||||
break;
|
||||
case sfxinfow_priority:
|
||||
case sfxinfo_priority:
|
||||
sfx->priority = luaL_checkinteger(L, 1);
|
||||
break;
|
||||
case sfxinfow_flags:
|
||||
case sfxinfo_flags:
|
||||
sfx->pitch = luaL_checkinteger(L, 1);
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, "impossible error");
|
||||
if (field == -1)
|
||||
return luaL_error(L, LUA_QL("sfxinfo_t") " has no field named " LUA_QS, lua_tostring(L, 2));
|
||||
else
|
||||
return luaL_error(L, LUA_QL("sfxinfo_t") " field " LUA_QS " is read-only", lua_tostring(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -910,6 +1098,8 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
state_fields_ref = Lua_CreateFieldTable(L, state_opt);
|
||||
|
||||
luaL_newmetatable(L, META_MOBJINFO);
|
||||
lua_pushcfunction(L, mobjinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -921,6 +1111,8 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
mobjinfo_fields_ref = Lua_CreateFieldTable(L, mobjinfo_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SFXINFO);
|
||||
lua_pushcfunction(L, sfxinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -932,6 +1124,8 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
sfxinfo_fields_ref = Lua_CreateFieldTable(L, sfxinfo_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSprname);
|
||||
@@ -983,4 +1177,4 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setglobal(L, "S_sfx");
|
||||
lua_setglobal(L, "sfxinfo");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+194
-50
@@ -71,6 +71,8 @@ enum subsector_e {
|
||||
subsector_firstline,
|
||||
};
|
||||
|
||||
static int sector_fields_ref = LUA_NOREF;
|
||||
|
||||
static const char *const subsector_opt[] = {
|
||||
"valid",
|
||||
"sector",
|
||||
@@ -78,6 +80,8 @@ static const char *const subsector_opt[] = {
|
||||
"firstline",
|
||||
NULL};
|
||||
|
||||
static int subsector_fields_ref = LUA_NOREF;
|
||||
|
||||
enum line_e {
|
||||
line_valid = 0,
|
||||
line_v1,
|
||||
@@ -120,6 +124,8 @@ static const char *const line_opt[] = {
|
||||
"callcount",
|
||||
NULL};
|
||||
|
||||
static int line_fields_ref = LUA_NOREF;
|
||||
|
||||
enum side_e {
|
||||
side_valid = 0,
|
||||
side_textureoffset,
|
||||
@@ -146,6 +152,8 @@ static const char *const side_opt[] = {
|
||||
"text",
|
||||
NULL};
|
||||
|
||||
static int side_fields_ref = LUA_NOREF;
|
||||
|
||||
enum vertex_e {
|
||||
vertex_valid = 0,
|
||||
vertex_x,
|
||||
@@ -160,6 +168,8 @@ static const char *const vertex_opt[] = {
|
||||
"z",
|
||||
NULL};
|
||||
|
||||
static int vertex_fields_ref = LUA_NOREF;
|
||||
|
||||
enum ffloor_e {
|
||||
ffloor_valid = 0,
|
||||
ffloor_topheight,
|
||||
@@ -196,6 +206,8 @@ static const char *const ffloor_opt[] = {
|
||||
"alpha",
|
||||
NULL};
|
||||
|
||||
static int ffloor_fields_ref = LUA_NOREF;
|
||||
|
||||
enum slope_e {
|
||||
slope_valid = 0,
|
||||
slope_o,
|
||||
@@ -222,6 +234,8 @@ static const char *const slope_opt[] = {
|
||||
"flags",
|
||||
NULL};
|
||||
|
||||
static int slope_fields_ref = LUA_NOREF;
|
||||
|
||||
// shared by both vector2_t and vector3_t
|
||||
enum vector_e {
|
||||
vector_x = 0,
|
||||
@@ -267,7 +281,7 @@ static int lib_iterateSectorThinglist(lua_State *L)
|
||||
if (!lua_isnil(L, 1))
|
||||
{
|
||||
thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
if (P_MobjWasRemoved(thing))
|
||||
if (!thing)
|
||||
return luaL_error(L, "current entry in thinglist was removed; avoid calling P_RemoveMobj on entries!");
|
||||
thing = thing->snext;
|
||||
}
|
||||
@@ -387,7 +401,7 @@ static int sectorlines_num(lua_State *L)
|
||||
static int sector_get(lua_State *L)
|
||||
{
|
||||
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
||||
enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref);
|
||||
INT16 i;
|
||||
|
||||
if (!sector)
|
||||
@@ -473,7 +487,7 @@ static int sector_get(lua_State *L)
|
||||
static int sector_set(lua_State *L)
|
||||
{
|
||||
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
||||
enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref);
|
||||
|
||||
if (!sector)
|
||||
return luaL_error(L, "accessed sector_t doesn't exist anymore.");
|
||||
@@ -551,7 +565,7 @@ static int sector_num(lua_State *L)
|
||||
static int subsector_get(lua_State *L)
|
||||
{
|
||||
subsector_t *subsector = *((subsector_t **)luaL_checkudata(L, 1, META_SUBSECTOR));
|
||||
enum subsector_e field = luaL_checkoption(L, 2, subsector_opt[0], subsector_opt);
|
||||
enum subsector_e field = Lua_optoption(L, 2, subsector_valid, subsector_fields_ref);
|
||||
|
||||
if (!subsector)
|
||||
{
|
||||
@@ -590,7 +604,7 @@ static int subsector_num(lua_State *L)
|
||||
static int line_get(lua_State *L)
|
||||
{
|
||||
line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE));
|
||||
enum line_e field = luaL_checkoption(L, 2, line_opt[0], line_opt);
|
||||
enum line_e field = Lua_optoption(L, 2, line_valid, line_fields_ref);
|
||||
|
||||
if (!line)
|
||||
{
|
||||
@@ -715,7 +729,7 @@ static int sidenum_get(lua_State *L)
|
||||
static int side_get(lua_State *L)
|
||||
{
|
||||
side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
|
||||
enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt);
|
||||
enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref);
|
||||
|
||||
if (!side)
|
||||
{
|
||||
@@ -765,7 +779,7 @@ static int side_get(lua_State *L)
|
||||
static int side_set(lua_State *L)
|
||||
{
|
||||
side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
|
||||
enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt);
|
||||
enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref);
|
||||
|
||||
if (!side)
|
||||
{
|
||||
@@ -816,7 +830,7 @@ static int side_num(lua_State *L)
|
||||
static int vertex_get(lua_State *L)
|
||||
{
|
||||
vertex_t *vertex = *((vertex_t **)luaL_checkudata(L, 1, META_VERTEX));
|
||||
enum vertex_e field = luaL_checkoption(L, 2, vertex_opt[0], vertex_opt);
|
||||
enum vertex_e field = Lua_optoption(L, 2, vertex_valid, vertex_fields_ref);
|
||||
|
||||
if (!vertex)
|
||||
{
|
||||
@@ -1085,7 +1099,7 @@ static int lib_numvertexes(lua_State *L)
|
||||
static int ffloor_get(lua_State *L)
|
||||
{
|
||||
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt);
|
||||
enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref);
|
||||
INT16 i;
|
||||
|
||||
if (!ffloor)
|
||||
@@ -1161,7 +1175,7 @@ static int ffloor_get(lua_State *L)
|
||||
static int ffloor_set(lua_State *L)
|
||||
{
|
||||
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt);
|
||||
enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref);
|
||||
|
||||
if (!ffloor)
|
||||
return luaL_error(L, "accessed ffloor_t doesn't exist anymore.");
|
||||
@@ -1239,7 +1253,7 @@ static int ffloor_set(lua_State *L)
|
||||
static int slope_get(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref);
|
||||
|
||||
if (!slope)
|
||||
{
|
||||
@@ -1289,7 +1303,7 @@ static int slope_get(lua_State *L)
|
||||
static int slope_set(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref);
|
||||
|
||||
if (!slope)
|
||||
return luaL_error(L, "accessed pslope_t doesn't exist anymore.");
|
||||
@@ -1446,93 +1460,207 @@ static int lib_nummapheaders(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum mapheaderinfo_e
|
||||
{
|
||||
mapheaderinfo_lvlttl,
|
||||
mapheaderinfo_subttl,
|
||||
mapheaderinfo_zonttl,
|
||||
mapheaderinfo_actnum,
|
||||
mapheaderinfo_typeoflevel,
|
||||
mapheaderinfo_nextlevel,
|
||||
mapheaderinfo_musname,
|
||||
mapheaderinfo_mustrack,
|
||||
mapheaderinfo_muspos,
|
||||
mapheaderinfo_musinterfadeout,
|
||||
mapheaderinfo_musintername,
|
||||
mapheaderinfo_forcecharacter,
|
||||
mapheaderinfo_weather,
|
||||
mapheaderinfo_skynum,
|
||||
mapheaderinfo_skybox_scalex,
|
||||
mapheaderinfo_skybox_scaley,
|
||||
mapheaderinfo_skybox_scalez,
|
||||
mapheaderinfo_interscreen,
|
||||
mapheaderinfo_runsoc,
|
||||
mapheaderinfo_scriptname,
|
||||
mapheaderinfo_precutscenenum,
|
||||
mapheaderinfo_cutscenenum,
|
||||
mapheaderinfo_countdown,
|
||||
mapheaderinfo_palette,
|
||||
mapheaderinfo_numlaps,
|
||||
mapheaderinfo_unlockrequired,
|
||||
mapheaderinfo_levelselect,
|
||||
mapheaderinfo_bonustype,
|
||||
mapheaderinfo_saveoverride,
|
||||
mapheaderinfo_levelflags,
|
||||
mapheaderinfo_menuflags,
|
||||
//mapheaderinfo_automap,
|
||||
mapheaderinfo_mobj_scale,
|
||||
};
|
||||
|
||||
static const char *const mapheaderinfo_opt[] = {
|
||||
"lvlttl",
|
||||
"subttl",
|
||||
"zonttl",
|
||||
"actnum",
|
||||
"typeoflevel",
|
||||
"nextlevel",
|
||||
"musname",
|
||||
"mustrack",
|
||||
"muspos",
|
||||
"musinterfadeout",
|
||||
"musintername",
|
||||
"forcecharacter",
|
||||
"weather",
|
||||
"skynum",
|
||||
"skybox_scalex",
|
||||
"skybox_scaley",
|
||||
"skybox_scalez",
|
||||
"interscreen",
|
||||
"runsoc",
|
||||
"scriptname",
|
||||
"precutscenenum",
|
||||
"cutscenenum",
|
||||
"countdown",
|
||||
"palette",
|
||||
"numlaps",
|
||||
"unlockrequired",
|
||||
"levelselect",
|
||||
"bonustype",
|
||||
"saveoverride",
|
||||
"levelflags",
|
||||
"menuflags",
|
||||
//"automap",
|
||||
"mobj_scale",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int mapheaderinfo_fields_ref = LUA_NOREF;
|
||||
|
||||
static int mapheaderinfo_get(lua_State *L)
|
||||
{
|
||||
mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mapheaderinfo_e field = Lua_optoption(L, 2, -1, mapheaderinfo_fields_ref);
|
||||
INT16 i;
|
||||
if (fastcmp(field,"lvlttl"))
|
||||
switch (field)
|
||||
{
|
||||
case mapheaderinfo_lvlttl:
|
||||
lua_pushstring(L, header->lvlttl);
|
||||
else if (fastcmp(field,"subttl"))
|
||||
break;
|
||||
case mapheaderinfo_subttl:
|
||||
lua_pushstring(L, header->subttl);
|
||||
else if (fastcmp(field,"zonttl"))
|
||||
break;
|
||||
case mapheaderinfo_zonttl:
|
||||
lua_pushstring(L, header->zonttl);
|
||||
else if (fastcmp(field,"actnum"))
|
||||
break;
|
||||
case mapheaderinfo_actnum:
|
||||
lua_pushstring(L, header->actnum);
|
||||
else if (fastcmp(field,"typeoflevel"))
|
||||
break;
|
||||
case mapheaderinfo_typeoflevel:
|
||||
lua_pushinteger(L, header->typeoflevel);
|
||||
else if (fastcmp(field,"nextlevel"))
|
||||
break;
|
||||
case mapheaderinfo_nextlevel:
|
||||
lua_pushinteger(L, header->nextlevel);
|
||||
else if (fastcmp(field,"musname"))
|
||||
break;
|
||||
case mapheaderinfo_musname:
|
||||
lua_pushstring(L, header->musname);
|
||||
else if (fastcmp(field,"mustrack"))
|
||||
break;
|
||||
case mapheaderinfo_mustrack:
|
||||
lua_pushinteger(L, header->mustrack);
|
||||
else if (fastcmp(field,"muspos"))
|
||||
break;
|
||||
case mapheaderinfo_muspos:
|
||||
lua_pushinteger(L, header->muspos);
|
||||
else if (fastcmp(field,"musinterfadeout"))
|
||||
break;
|
||||
case mapheaderinfo_musinterfadeout:
|
||||
lua_pushinteger(L, header->musinterfadeout);
|
||||
else if (fastcmp(field,"musintername"))
|
||||
break;
|
||||
case mapheaderinfo_musintername:
|
||||
lua_pushstring(L, header->musintername);
|
||||
else if (fastcmp(field,"forcecharacter"))
|
||||
break;
|
||||
case mapheaderinfo_forcecharacter:
|
||||
lua_pushstring(L, header->forcecharacter);
|
||||
else if (fastcmp(field,"weather"))
|
||||
break;
|
||||
case mapheaderinfo_weather:
|
||||
lua_pushinteger(L, header->weather);
|
||||
else if (fastcmp(field,"skynum"))
|
||||
break;
|
||||
case mapheaderinfo_skynum:
|
||||
lua_pushinteger(L, header->skynum);
|
||||
else if (fastcmp(field,"skybox_scalex"))
|
||||
break;
|
||||
case mapheaderinfo_skybox_scalex:
|
||||
lua_pushinteger(L, header->skybox_scalex);
|
||||
else if (fastcmp(field,"skybox_scaley"))
|
||||
break;
|
||||
case mapheaderinfo_skybox_scaley:
|
||||
lua_pushinteger(L, header->skybox_scaley);
|
||||
else if (fastcmp(field,"skybox_scalez"))
|
||||
break;
|
||||
case mapheaderinfo_skybox_scalez:
|
||||
lua_pushinteger(L, header->skybox_scalez);
|
||||
else if (fastcmp(field,"interscreen")) {
|
||||
break;
|
||||
case mapheaderinfo_interscreen:
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!header->interscreen[i])
|
||||
break;
|
||||
lua_pushlstring(L, header->interscreen, i);
|
||||
} else if (fastcmp(field,"runsoc"))
|
||||
break;
|
||||
case mapheaderinfo_runsoc:
|
||||
lua_pushstring(L, header->runsoc);
|
||||
else if (fastcmp(field,"scriptname"))
|
||||
break;
|
||||
case mapheaderinfo_scriptname:
|
||||
lua_pushstring(L, header->scriptname);
|
||||
else if (fastcmp(field,"precutscenenum"))
|
||||
break;
|
||||
case mapheaderinfo_precutscenenum:
|
||||
lua_pushinteger(L, header->precutscenenum);
|
||||
else if (fastcmp(field,"cutscenenum"))
|
||||
break;
|
||||
case mapheaderinfo_cutscenenum:
|
||||
lua_pushinteger(L, header->cutscenenum);
|
||||
else if (fastcmp(field,"countdown"))
|
||||
break;
|
||||
case mapheaderinfo_countdown:
|
||||
lua_pushinteger(L, header->countdown);
|
||||
else if (fastcmp(field,"palette"))
|
||||
break;
|
||||
case mapheaderinfo_palette:
|
||||
lua_pushinteger(L, header->palette);
|
||||
else if (fastcmp(field,"numlaps"))
|
||||
break;
|
||||
case mapheaderinfo_numlaps:
|
||||
lua_pushinteger(L, header->numlaps);
|
||||
else if (fastcmp(field,"unlockrequired"))
|
||||
break;
|
||||
case mapheaderinfo_unlockrequired:
|
||||
lua_pushinteger(L, header->unlockrequired);
|
||||
else if (fastcmp(field,"levelselect"))
|
||||
break;
|
||||
case mapheaderinfo_levelselect:
|
||||
lua_pushinteger(L, header->levelselect);
|
||||
else if (fastcmp(field,"bonustype"))
|
||||
break;
|
||||
case mapheaderinfo_bonustype:
|
||||
lua_pushinteger(L, header->bonustype);
|
||||
else if (fastcmp(field,"saveoverride"))
|
||||
break;
|
||||
case mapheaderinfo_saveoverride:
|
||||
lua_pushinteger(L, header->saveoverride);
|
||||
else if (fastcmp(field,"levelflags"))
|
||||
break;
|
||||
case mapheaderinfo_levelflags:
|
||||
lua_pushinteger(L, header->levelflags);
|
||||
else if (fastcmp(field,"menuflags"))
|
||||
break;
|
||||
case mapheaderinfo_menuflags:
|
||||
lua_pushinteger(L, header->menuflags);
|
||||
/*else if (fastcmp(field,"automap"))
|
||||
lua_pushboolean(L, header->automap);*/
|
||||
else if (fastcmp(field,"mobj_scale"))
|
||||
break;
|
||||
/*case mapheaderinfo_automap:
|
||||
lua_pushstring(L, header->selectheading);
|
||||
break;*/
|
||||
case mapheaderinfo_mobj_scale:
|
||||
lua_pushfixed(L, header->mobj_scale);
|
||||
break;
|
||||
// TODO add support for reading numGradedMares and grades
|
||||
else {
|
||||
default:
|
||||
{
|
||||
// Read custom vars now
|
||||
// (note: don't include the "LUA." in your lua scripts!)
|
||||
UINT8 j = 0;
|
||||
for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j);
|
||||
for (;j < header->numCustomOptions && !fastcmp(lua_tostring(L, 2), header->customopts[j].option); ++j);
|
||||
|
||||
if(j < header->numCustomOptions)
|
||||
lua_pushstring(L, header->customopts[j].value);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int LUA_MapLib(lua_State *L)
|
||||
@@ -1556,6 +1684,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
sector_fields_ref = Lua_CreateFieldTable(L, sector_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SUBSECTOR);
|
||||
lua_pushcfunction(L, subsector_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1564,6 +1694,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt);
|
||||
|
||||
luaL_newmetatable(L, META_LINE);
|
||||
lua_pushcfunction(L, line_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1572,6 +1704,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
line_fields_ref = Lua_CreateFieldTable(L, line_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SIDENUM);
|
||||
lua_pushcfunction(L, sidenum_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1588,6 +1722,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
side_fields_ref = Lua_CreateFieldTable(L, side_opt);
|
||||
|
||||
luaL_newmetatable(L, META_VERTEX);
|
||||
lua_pushcfunction(L, vertex_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1596,6 +1732,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
vertex_fields_ref = Lua_CreateFieldTable(L, vertex_opt);
|
||||
|
||||
luaL_newmetatable(L, META_FFLOOR);
|
||||
lua_pushcfunction(L, ffloor_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1604,6 +1742,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
ffloor_fields_ref = Lua_CreateFieldTable(L, ffloor_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SLOPE);
|
||||
lua_pushcfunction(L, slope_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1612,6 +1752,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
slope_fields_ref = Lua_CreateFieldTable(L, slope_opt);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR2);
|
||||
lua_pushcfunction(L, vector2_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1630,6 +1772,8 @@ int LUA_MapLib(lua_State *L)
|
||||
//lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
mapheaderinfo_fields_ref = Lua_CreateFieldTable(L, mapheaderinfo_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSector);
|
||||
@@ -1690,4 +1834,4 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapheaderinfo");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+105
-49
@@ -147,7 +147,7 @@ static const udata_field_t mobj_fields[] = {
|
||||
FIELD(mobj_t, colorized, udatalib_getter_boolean, udatalib_setter_boolean),
|
||||
FIELD(mobj_t, mirrored, udatalib_getter_boolean, udatalib_setter_boolean),
|
||||
FIELD(mobj_t, rollmodel, udatalib_getter_boolean, udatalib_setter_boolean),
|
||||
{ NULL },
|
||||
{ NULL, 0, NULL, NULL },
|
||||
};
|
||||
#undef FIELD
|
||||
|
||||
@@ -769,14 +769,41 @@ static int mobj_set(lua_State *L)
|
||||
#undef NOSETPOS
|
||||
#undef NOFIELD
|
||||
|
||||
enum mapthing_e {
|
||||
mapthing_valid = 0,
|
||||
mapthing_x,
|
||||
mapthing_y,
|
||||
mapthing_angle,
|
||||
mapthing_type,
|
||||
mapthing_options,
|
||||
mapthing_z,
|
||||
mapthing_extrainfo,
|
||||
mapthing_mobj,
|
||||
};
|
||||
|
||||
const char *const mapthing_opt[] = {
|
||||
"valid",
|
||||
"x",
|
||||
"y",
|
||||
"angle",
|
||||
"type",
|
||||
"options",
|
||||
"z",
|
||||
"extrainfo",
|
||||
"mobj",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int mapthing_fields_ref = LUA_NOREF;
|
||||
|
||||
static int mapthing_get(lua_State *L)
|
||||
{
|
||||
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
lua_Integer number;
|
||||
enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref);
|
||||
lua_settop(L, 2);
|
||||
|
||||
if (!mt) {
|
||||
if (fastcmp(field,"valid")) {
|
||||
if (field == mapthing_valid) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
@@ -785,39 +812,50 @@ static int mapthing_get(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fastcmp(field,"valid")) {
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
} else if(fastcmp(field,"x"))
|
||||
number = mt->x;
|
||||
else if(fastcmp(field,"y"))
|
||||
number = mt->y;
|
||||
else if(fastcmp(field,"angle"))
|
||||
number = mt->angle;
|
||||
else if(fastcmp(field,"type"))
|
||||
number = mt->type;
|
||||
else if(fastcmp(field,"options"))
|
||||
number = mt->options;
|
||||
else if(fastcmp(field,"z"))
|
||||
number = mt->z;
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
number = mt->extrainfo;
|
||||
else if(fastcmp(field,"mobj")) {
|
||||
LUA_PushUserdata(L, mt->mobj, META_MOBJ);
|
||||
return 1;
|
||||
} else if (devparm)
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
switch (field)
|
||||
{
|
||||
case mapthing_valid:
|
||||
lua_pushboolean(L, true);
|
||||
break;
|
||||
case mapthing_x:
|
||||
lua_pushinteger(L, mt->x);
|
||||
break;
|
||||
case mapthing_y:
|
||||
lua_pushinteger(L, mt->y);
|
||||
break;
|
||||
case mapthing_angle:
|
||||
lua_pushinteger(L, mt->angle);
|
||||
break;
|
||||
case mapthing_type:
|
||||
lua_pushinteger(L, mt->type);
|
||||
break;
|
||||
case mapthing_options:
|
||||
lua_pushinteger(L, mt->options);
|
||||
break;
|
||||
case mapthing_z:
|
||||
lua_pushinteger(L, mt->z);
|
||||
break;
|
||||
case mapthing_extrainfo:
|
||||
lua_pushinteger(L, mt->extrainfo);
|
||||
break;
|
||||
case mapthing_mobj:
|
||||
LUA_PushUserdata(L, mt->mobj, META_MOBJ);
|
||||
break;
|
||||
default:
|
||||
if (devparm)
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, number);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mapthing_set(lua_State *L)
|
||||
{
|
||||
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref);
|
||||
lua_settop(L, 3);
|
||||
|
||||
if (!mt)
|
||||
return luaL_error(L, "accessed mapthing_t doesn't exist anymore.");
|
||||
@@ -827,24 +865,40 @@ static int mapthing_set(lua_State *L)
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mapthing_t in BuildCMD code!");
|
||||
|
||||
if(fastcmp(field,"x"))
|
||||
mt->x = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"y"))
|
||||
mt->y = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"angle"))
|
||||
mt->angle = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"type"))
|
||||
mt->type = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"options"))
|
||||
mt->options = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"z"))
|
||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
mt->extrainfo = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"mobj"))
|
||||
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
else
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
switch (field)
|
||||
{
|
||||
case mapthing_x:
|
||||
mt->x = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_y:
|
||||
mt->y = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_angle:
|
||||
mt->angle = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_type:
|
||||
mt->type = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_options:
|
||||
mt->options = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_z:
|
||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_extrainfo:
|
||||
{
|
||||
INT32 extrainfo = luaL_checkinteger(L, 3);
|
||||
if (extrainfo & ~15)
|
||||
return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15);
|
||||
mt->extrainfo = (UINT8)extrainfo;
|
||||
break;
|
||||
}
|
||||
case mapthing_mobj:
|
||||
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -915,6 +969,8 @@ int LUA_MobjLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
mapthing_fields_ref = Lua_CreateFieldTable(L, mapthing_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getMapthing);
|
||||
@@ -925,4 +981,4 @@ int LUA_MobjLib(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapthings");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+81
-18
@@ -51,6 +51,9 @@ int player_localskin_setter(lua_State *L);
|
||||
int player_sliproll_getter(lua_State *L);
|
||||
int player_sliproll_noset(lua_State *L);
|
||||
|
||||
int player_viewrollangle_getter(lua_State *L);
|
||||
int player_viewrollangle_noset(lua_State *L);
|
||||
|
||||
#define FIELD(type, field_name, getter, setter) { #field_name, offsetof(type, field_name), getter, setter }
|
||||
static const udata_field_t player_fields[] = {
|
||||
// Player doesn't actually have field "name" so macro fails. Need to declare field manually.
|
||||
@@ -159,8 +162,9 @@ static const udata_field_t player_fields[] = {
|
||||
#endif
|
||||
// Same as player.name
|
||||
{ "sliproll", 0, player_sliproll_getter, player_sliproll_noset },
|
||||
{ "viewrollangle", 0, player_viewrollangle_getter, player_viewrollangle_noset },
|
||||
{ "ping", 0, player_ping_getter, player_ping_noset }, // Hmm originally setter doesn't exist so data is written as unreachable custom field...
|
||||
{ NULL },
|
||||
{ NULL, 0, NULL, NULL },
|
||||
};
|
||||
#undef FIELD
|
||||
|
||||
@@ -217,6 +221,7 @@ NOSET(bot)
|
||||
NOSET(splitscreenindex)
|
||||
NOSET(ping)
|
||||
NOSET(sliproll)
|
||||
NOSET(viewrollangle)
|
||||
|
||||
#undef NOSET
|
||||
|
||||
@@ -372,6 +377,15 @@ int player_sliproll_getter(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int player_viewrollangle_getter(lua_State *L)
|
||||
{
|
||||
player_t *plr = GETPLAYER();
|
||||
|
||||
lua_pushangle(L, R_ViewRollAngle(plr));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
@@ -694,30 +708,65 @@ static int kartstuff_len(lua_State *L)
|
||||
}
|
||||
|
||||
#define NOFIELD luaL_error(L, LUA_QL("ticcmd_t") " has no field named " LUA_QS, field)
|
||||
#define NOSET luaL_error(L, LUA_QL("ticcmd_t") " field " LUA_QS " should not be set directly.", field)
|
||||
|
||||
enum ticcmd_e
|
||||
{
|
||||
ticcmd_forwardmove,
|
||||
ticcmd_sidemove,
|
||||
ticcmd_angleturn,
|
||||
ticcmd_aiming,
|
||||
ticcmd_buttons,
|
||||
ticcmd_driftturn,
|
||||
ticcmd_latency,
|
||||
};
|
||||
|
||||
static const char *const ticcmd_opt[] = {
|
||||
"forwardmove",
|
||||
"sidemove",
|
||||
"angleturn",
|
||||
"aiming",
|
||||
"buttons",
|
||||
"driftturn",
|
||||
"latency",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int ticcmd_fields_ref = LUA_NOREF;
|
||||
|
||||
static int ticcmd_get(lua_State *L)
|
||||
{
|
||||
ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref);
|
||||
if (!cmd)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (fastcmp(field,"forwardmove"))
|
||||
switch (field)
|
||||
{
|
||||
case ticcmd_forwardmove:
|
||||
lua_pushinteger(L, cmd->forwardmove);
|
||||
else if (fastcmp(field,"sidemove"))
|
||||
break;
|
||||
case ticcmd_sidemove:
|
||||
lua_pushinteger(L, cmd->sidemove);
|
||||
else if (fastcmp(field,"angleturn"))
|
||||
break;
|
||||
case ticcmd_angleturn:
|
||||
lua_pushinteger(L, cmd->angleturn);
|
||||
else if (fastcmp(field,"aiming"))
|
||||
break;
|
||||
case ticcmd_aiming:
|
||||
lua_pushinteger(L, cmd->aiming);
|
||||
else if (fastcmp(field,"buttons"))
|
||||
break;
|
||||
case ticcmd_buttons:
|
||||
lua_pushinteger(L, cmd->buttons);
|
||||
else if (fastcmp(field,"driftturn"))
|
||||
break;
|
||||
case ticcmd_driftturn:
|
||||
lua_pushinteger(L, cmd->driftturn);
|
||||
else if (fastcmp(field,"latency"))
|
||||
break;
|
||||
case ticcmd_latency:
|
||||
lua_pushinteger(L, cmd->latency);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return NOFIELD;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -725,32 +774,44 @@ static int ticcmd_get(lua_State *L)
|
||||
static int ticcmd_set(lua_State *L)
|
||||
{
|
||||
ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref);
|
||||
if (!cmd)
|
||||
return LUA_ErrInvalid(L, "ticcmd_t");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
|
||||
if (fastcmp(field,"forwardmove"))
|
||||
switch (field)
|
||||
{
|
||||
case ticcmd_forwardmove:
|
||||
cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"sidemove"))
|
||||
break;
|
||||
case ticcmd_sidemove:
|
||||
cmd->sidemove = (SINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"angleturn"))
|
||||
break;
|
||||
case ticcmd_angleturn:
|
||||
cmd->angleturn = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"aiming"))
|
||||
break;
|
||||
case ticcmd_aiming:
|
||||
cmd->aiming = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"buttons"))
|
||||
break;
|
||||
case ticcmd_buttons:
|
||||
cmd->buttons = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"driftturn"))
|
||||
break;
|
||||
case ticcmd_driftturn:
|
||||
cmd->driftturn = (INT16)luaL_checkinteger(L, 3);
|
||||
else
|
||||
break;
|
||||
case ticcmd_latency:
|
||||
return NOSET;
|
||||
default:
|
||||
return NOFIELD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef NOFIELD
|
||||
#undef NOSET
|
||||
|
||||
int LUA_PlayerLib(lua_State *L)
|
||||
{
|
||||
@@ -797,6 +858,8 @@ int LUA_PlayerLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
ticcmd_fields_ref = Lua_CreateFieldTable(L, ticcmd_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getPlayer);
|
||||
|
||||
+120
-25
@@ -22,6 +22,8 @@
|
||||
#include "p_saveg.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h" // for P_SlopeById
|
||||
#include "s_sound.h"
|
||||
#include "m_menu.h"
|
||||
#ifdef LUA_ALLOW_BYTECODE
|
||||
#include "d_netfil.h" // for LUA_DumpFile
|
||||
#endif
|
||||
@@ -152,6 +154,7 @@ static int noglobals(lua_State *L)
|
||||
{
|
||||
const char *csname;
|
||||
char *name;
|
||||
enum actionnum actionnum;
|
||||
|
||||
lua_remove(L, 1); // we're not gonna be using _G
|
||||
csname = lua_tostring(L, 1);
|
||||
@@ -170,6 +173,10 @@ static int noglobals(lua_State *L)
|
||||
lua_rawset(L, -3); // rawset doesn't trigger this metatable again.
|
||||
// otherwise we would've used setfield, obviously.
|
||||
|
||||
actionnum = LUA_GetActionNumByName(name);
|
||||
if (actionnum < NUMACTIONS)
|
||||
actionsoverridden[actionnum] = true;
|
||||
|
||||
Z_Free(name);
|
||||
return 0;
|
||||
}
|
||||
@@ -394,8 +401,14 @@ fixed_t LUA_EvalMath(const char *word)
|
||||
if (luaL_dostring(mL, buf))
|
||||
{
|
||||
p = lua_tostring(mL, -1);
|
||||
while (*p++ != ':' && *p) ;
|
||||
p += 3; // "1: "
|
||||
|
||||
// If there is [string "..."]:1: text, skip it
|
||||
if (strstr(p, ":") != NULL)
|
||||
{
|
||||
while (*p++ != ':' && *p);
|
||||
|
||||
p += 3; // "1: "
|
||||
}
|
||||
CONS_Alert(CONS_WARNING, "%s\n", p);
|
||||
}
|
||||
else
|
||||
@@ -659,8 +672,17 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
t++;
|
||||
|
||||
if (t == 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Too many tables to archive!\n");
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT8(save_p, ARCH_TABLE);
|
||||
WRITEUINT16(save_p, t);
|
||||
|
||||
@@ -1313,6 +1335,12 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
||||
break;
|
||||
case ARCH_TEND:
|
||||
return 1;
|
||||
default:
|
||||
CONS_Alert(CONS_ERROR, "Unknown value type unarchived, save is corrupted!\n");
|
||||
G_SetExitGameFlag();
|
||||
S_StartSound(NULL, sfx_syfail); // he he he
|
||||
M_StartMessage(M_GetText("Corrupted save received\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1427,7 +1455,12 @@ static void UnArchiveExtVars(void *pointer)
|
||||
|
||||
if (field_count == 0)
|
||||
return;
|
||||
I_Assert(gL != NULL);
|
||||
|
||||
// Technically possible new, since server may have local lua scripts but no "public" ones, so
|
||||
// field_count would be non zero (there is no way to tell local field from non-local, so
|
||||
// everything gets archived)
|
||||
if (!gL)
|
||||
return;
|
||||
|
||||
TABLESINDEX = lua_gettop(gL);
|
||||
lua_createtable(gL, 0, field_count); // pointer's ext vars subtable
|
||||
@@ -1435,7 +1468,13 @@ static void UnArchiveExtVars(void *pointer)
|
||||
for (i = 0; i < field_count; i++)
|
||||
{
|
||||
READSTRING(save_p, field);
|
||||
UnArchiveValue(TABLESINDEX);
|
||||
|
||||
if (UnArchiveValue(TABLESINDEX) == 1)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Unexpected end marker when reading ExtVars (field '%s')\n", field);
|
||||
break;
|
||||
}
|
||||
|
||||
lua_setfield(gL, -2, field);
|
||||
}
|
||||
|
||||
@@ -1499,12 +1538,29 @@ static void UnArchiveTables(void)
|
||||
for (i = 1; i <= n; i++)
|
||||
{
|
||||
lua_rawgeti(gL, TABLESINDEX, i);
|
||||
|
||||
if (!lua_istable(gL, -1))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Value in tables list #%d is not a table! (corrupted save?)\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (UnArchiveValue(TABLESINDEX) == 1) // read key
|
||||
break;
|
||||
if (UnArchiveValue(TABLESINDEX) == 2) // read value
|
||||
|
||||
UINT8 ret = UnArchiveValue(TABLESINDEX);
|
||||
|
||||
if (ret == 1)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Unexpected end of save reached (Corrupted save?)\n");
|
||||
lua_pop(gL, 1); // Pop key
|
||||
break;
|
||||
}
|
||||
else if (ret == 2) // read value
|
||||
n++;
|
||||
|
||||
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "A nil key in table %d was found! (Invalid key type or corrupted save?)\n", i);
|
||||
@@ -1564,8 +1620,13 @@ void LUA_Step(void)
|
||||
{
|
||||
if (!gL)
|
||||
return;
|
||||
lua_settop(gL, 0);
|
||||
lua_gc(gL, LUA_GCSTEP, 1);
|
||||
|
||||
if (lua_gettop(gL) != 0)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Eek, there is garbage on lua stack!\n");
|
||||
lua_settop(gL, 0);
|
||||
lua_gc(gL, LUA_GCSTEP, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_Archive(void)
|
||||
@@ -1587,12 +1648,14 @@ void LUA_Archive(void)
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
// archive function will determine when to skip mobjs,
|
||||
// and write mobjnum in otherwise.
|
||||
ArchiveExtVars(th, "mobj");
|
||||
}
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
// archive function will determine when to skip mobjs,
|
||||
// and write mobjnum in otherwise.
|
||||
ArchiveExtVars(th, "mobj");
|
||||
}
|
||||
}
|
||||
WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
|
||||
|
||||
@@ -1620,11 +1683,15 @@ void LUA_UnArchive(void)
|
||||
}
|
||||
|
||||
do {
|
||||
mobjnum = READUINT32(save_p); // read a mobjnum
|
||||
mobjnum = READUINT32(save_p); // read a mobjnum
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker
|
||||
&& ((mobj_t *)th)->mobjnum == mobjnum) // find matching mobj
|
||||
UnArchiveExtVars(th); // apply variables
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj
|
||||
continue;
|
||||
UnArchiveExtVars(th); // apply variables
|
||||
}
|
||||
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
|
||||
|
||||
LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode
|
||||
@@ -1678,13 +1745,41 @@ void LUA_UnArchiveDemo(void)
|
||||
}
|
||||
|
||||
// For mobj_t, player_t, etc. to take custom variables.
|
||||
int Lua_optoption(lua_State *L, int narg,
|
||||
const char *def, const char *const lst[])
|
||||
int Lua_optoption(lua_State *L, int narg, int def, int list_ref)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (lua_isnoneornil(L, narg))
|
||||
return def;
|
||||
|
||||
I_Assert(lua_checkstack(L, 2));
|
||||
luaL_checkstring(L, narg);
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, list_ref);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushvalue(L, narg);
|
||||
lua_rawget(L, -2);
|
||||
|
||||
if (lua_isnumber(L, -1))
|
||||
result = lua_tointeger(L, -1);
|
||||
|
||||
lua_pop(L, 2); // Pop result and fields table
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int Lua_CreateFieldTable(lua_State *L, const char *const lst[])
|
||||
{
|
||||
const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg);
|
||||
int i;
|
||||
for (i=0; lst[i]; i++)
|
||||
if (fastcmp(lst[i], name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
for (i = 0; lst[i] != NULL; i++)
|
||||
{
|
||||
lua_pushstring(L, lst[i]);
|
||||
lua_pushinteger(L, i);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
+2
-2
@@ -63,8 +63,8 @@ void LUA_UnArchiveDemo(void);
|
||||
|
||||
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
|
||||
void LUA_CVarChanged(const char *name); // lua_consolelib.c
|
||||
int Lua_optoption(lua_State *L, int narg,
|
||||
const char *def, const char *const lst[]);
|
||||
int Lua_optoption(lua_State *L, int narg, int def, int list_ref);
|
||||
int Lua_CreateFieldTable(lua_State *L, const char *const lst[]);
|
||||
void LUAh_NetArchiveHook(lua_CFunction archFunc);
|
||||
|
||||
// Console wrapper
|
||||
|
||||
+6
-1
@@ -38,6 +38,7 @@ enum skin {
|
||||
skin_highresscale,
|
||||
skin_soundsid
|
||||
};
|
||||
|
||||
static const char *const skin_opt[] = {
|
||||
"valid",
|
||||
"name",
|
||||
@@ -61,10 +62,12 @@ static const char *const skin_opt[] = {
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field])
|
||||
|
||||
static int skin_fields_ref = LUA_NOREF;
|
||||
|
||||
static int skin_get(lua_State *L)
|
||||
{
|
||||
skin_t *skin = *((skin_t **)luaL_checkudata(L, 1, META_SKIN));
|
||||
enum skin field = luaL_checkoption(L, 2, NULL, skin_opt);
|
||||
enum skin field = Lua_optoption(L, 2, -1, skin_fields_ref);
|
||||
INT32 i;
|
||||
|
||||
// skins are always valid, only added, never removed
|
||||
@@ -253,6 +256,8 @@ int LUA_SkinLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L,1);
|
||||
|
||||
skin_fields_ref = Lua_CreateFieldTable(L, skin_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SOUNDSID);
|
||||
lua_pushcfunction(L, soundsid_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
+3
-2
@@ -909,8 +909,9 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
// get offset from mt, which points to old mapthings, then add new location
|
||||
if (mo->spawnpoint)
|
||||
mo->spawnpoint = (mo->spawnpoint - mt) + mapthings;
|
||||
if (!mo->spawnpoint)
|
||||
continue;
|
||||
mo->spawnpoint = (mo->spawnpoint - mt) + mapthings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1011,13 +1011,6 @@ int main(int argc, char** argv)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void *cpu_cpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy;
|
||||
|
||||
void I_Error(const char *error, ...)
|
||||
{
|
||||
(void)error;
|
||||
|
||||
+984
-959
File diff suppressed because it is too large.
Load diff
+23
-2
@@ -21,6 +21,8 @@
|
||||
#include "mserv.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
|
||||
extern boolean forceshowhud;
|
||||
|
||||
//
|
||||
// MENUS
|
||||
//
|
||||
@@ -59,6 +61,13 @@ void M_SortServerList(void);
|
||||
// Draws a box with a texture inside as background for messages
|
||||
void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines);
|
||||
|
||||
// Same but with extra flags applied
|
||||
void M_DrawTextBoxFlags(INT32 x, INT32 y, INT32 width, INT32 boxlines, INT32 flags);
|
||||
|
||||
// Draw text input
|
||||
typedef struct textinput_s textinput_t;
|
||||
void M_DrawTextInput(INT32 x, INT32 y, textinput_t *input, INT32 flags);
|
||||
|
||||
// Used in d_netcmd to restart time attack
|
||||
void M_ModeAttackRetry(INT32 choice);
|
||||
|
||||
@@ -255,6 +264,7 @@ extern INT32 mapwads[NUMMAPS];
|
||||
|
||||
extern description_t description[MAXSKINS];
|
||||
|
||||
extern consvar_t cv_replaysearchrate;
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||
extern consvar_t cv_showallmaps;
|
||||
@@ -286,8 +296,8 @@ void PDistort_menu_Onchange(void);
|
||||
// Bird menu updating
|
||||
void Bird_menu_Onchange(void);
|
||||
|
||||
// Saturn menu updating
|
||||
void Saturn_menu_Onchange(void);
|
||||
// Saturn Hud menu updating
|
||||
void SaturnHud_menu_Onchange(void);
|
||||
|
||||
void M_ReplayHut(INT32 choice);
|
||||
void M_SetPlaybackMenuPointer(void);
|
||||
@@ -397,4 +407,15 @@ void M_SlotCvarIntoModMenu(consvar_t* cvar, const char* category, const char* na
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define DoToolTips(menu, tooltip)\
|
||||
if (currentMenu == &menu)\
|
||||
{\
|
||||
if (!(tooltip[itemOn] == NULL))\
|
||||
{\
|
||||
M_DrawSplitText(BASEVIDWIDTH / 2, BASEVIDHEIGHT-50, V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, tooltip[itemOn], coolalphatimer);\
|
||||
if (coolalphatimer > 0 && interpTimerHackAllow)\
|
||||
coolalphatimer--;\
|
||||
}\
|
||||
}
|
||||
|
||||
#endif //__X_MENU__
|
||||
+49
-5
@@ -334,6 +334,38 @@ boolean FIL_FileOK(char const *name)
|
||||
return access(name,6)+1; //R_OK|W_OK
|
||||
}
|
||||
|
||||
/** Copies contents of one file to another
|
||||
*
|
||||
* \param src File to copy from
|
||||
* \param dst File to write into
|
||||
* \return true if copy was succesful, false if it doesn't.
|
||||
*/
|
||||
boolean FIL_CopyFile(const char *src, const char *dst)
|
||||
{
|
||||
FILE *srcFile = fopen(src, "rb");
|
||||
|
||||
if (srcFile == NULL)
|
||||
return false;
|
||||
|
||||
FILE *dstFile = fopen(dst, "wb");
|
||||
|
||||
if (dstFile == NULL)
|
||||
{
|
||||
fclose(srcFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
size_t n;
|
||||
|
||||
while ((n = fread(buffer, 1, sizeof(buffer), srcFile)) > 0)
|
||||
fwrite(buffer, 1, n, dstFile);
|
||||
|
||||
fclose(srcFile);
|
||||
fclose(dstFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Checks if a pathname has a file extension and adds the extension provided
|
||||
* if not.
|
||||
@@ -525,11 +557,28 @@ void M_SaveConfig(const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
char *filepath;
|
||||
char backupfile[MAX_WADPATH+4];
|
||||
|
||||
// make sure not to write back the config until it's been correctly loaded
|
||||
if (!gameconfig_loaded)
|
||||
return;
|
||||
|
||||
// Create backup of the config file
|
||||
snprintf(backupfile, sizeof backupfile, "%s.bak", configfile);
|
||||
backupfile[sizeof backupfile - 1] = '\0';
|
||||
|
||||
FILE *config = fopen(configfile, "r");
|
||||
|
||||
if (config != NULL)
|
||||
{
|
||||
fclose(config);
|
||||
if (FIL_CopyFile(configfile, backupfile) == false)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,"Failed to create a backup of the configuration file. Will not attempt to write to file\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// can change the file name
|
||||
if (filename)
|
||||
{
|
||||
@@ -1938,11 +1987,6 @@ char *sizeu5(size_t num)
|
||||
return sizeu5_buf;
|
||||
}
|
||||
|
||||
void *M_Memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
/** Return the appropriate message for a file error or end of file.
|
||||
*/
|
||||
const char *M_FileError(FILE *fp)
|
||||
|
||||
@@ -54,6 +54,7 @@ boolean FIL_FileExists(const char *name);
|
||||
boolean FIL_WriteFileOK(char const *name);
|
||||
boolean FIL_ReadFileOK(char const *name);
|
||||
boolean FIL_FileOK(char const *name);
|
||||
boolean FIL_CopyFile(const char *src, const char *dst);
|
||||
|
||||
void FIL_DefaultExtension (char *path, const char *extension);
|
||||
void FIL_ForceExtension(char *path, const char *extension);
|
||||
|
||||
+6
-3
@@ -10,6 +10,7 @@
|
||||
/// \brief Performance measurement tools.
|
||||
|
||||
#include "m_perfstats.h"
|
||||
#include "p_mobj.h"
|
||||
#include "v_video.h"
|
||||
#include "i_video.h"
|
||||
#include "d_netcmd.h"
|
||||
@@ -172,8 +173,8 @@ perfstatrow_t thinkercount_rows[] = {
|
||||
{" regular", " Regular: ", &ps_regularcount, PS_LEVEL},
|
||||
{" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL},
|
||||
{" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL},
|
||||
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
|
||||
{" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL},
|
||||
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
|
||||
{" remove ", " Pending removal:", &ps_removecount, PS_LEVEL},
|
||||
{0}
|
||||
};
|
||||
@@ -571,12 +572,14 @@ static void PS_CountThinkers(void)
|
||||
ps_regularcount.value.i = 0;
|
||||
ps_scenerycount.value.i = 0;
|
||||
ps_nothinkcount.value.i = 0;
|
||||
ps_otherthcount.value.i = 0;
|
||||
ps_precipcount.value.i = 0;
|
||||
ps_otherthcount.value.i = 0;
|
||||
ps_removecount.value.i = 0;
|
||||
for (thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next)
|
||||
{
|
||||
ps_thinkercount.value.i++;
|
||||
if (thinker->function.acp1 != (actionf_p1)P_NullPrecipThinker)
|
||||
ps_thinkercount.value.i++;
|
||||
|
||||
if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
ps_removecount.value.i++;
|
||||
else if (thinker->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
#include "m_textinput.h"
|
||||
#include "i_system.h"
|
||||
#include "keys.h"
|
||||
#include "console.h"
|
||||
|
||||
static void M_TextInputDel(textinput_t *input, size_t start, size_t end)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = (end - start);
|
||||
|
||||
if (end != input->length)
|
||||
memmove(&input->buffer[start], &input->buffer[end], input->length-end);
|
||||
memset(&input->buffer[input->length - len], 0, len);
|
||||
|
||||
input->length -= len;
|
||||
|
||||
if (input->select >= end)
|
||||
input->select -= len;
|
||||
else if (input->select > start)
|
||||
input->select = start;
|
||||
|
||||
if (input->cursor >= end)
|
||||
input->cursor -= len;
|
||||
else if (input->cursor > start)
|
||||
input->cursor = start;
|
||||
}
|
||||
|
||||
static void M_TextInputDelSelection(textinput_t *input)
|
||||
{
|
||||
size_t start, end;
|
||||
|
||||
if (input->cursor > input->select)
|
||||
{
|
||||
start = input->select;
|
||||
end = input->cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = input->cursor;
|
||||
end = input->select;
|
||||
}
|
||||
|
||||
M_TextInputDel(input, start, end);
|
||||
|
||||
input->select = input->cursor = start;
|
||||
}
|
||||
|
||||
static void M_TextInputAddString(textinput_t *input, const char *c)
|
||||
{
|
||||
size_t csize = strlen(c);
|
||||
|
||||
if (input->length + csize > input->buffer_size-1)
|
||||
return;
|
||||
|
||||
if (input->cursor != input->length)
|
||||
memmove(&input->buffer[input->cursor+csize], &input->buffer[input->cursor], input->length-input->cursor);
|
||||
memcpy(&input->buffer[input->cursor], c, csize);
|
||||
input->length += csize;
|
||||
input->select = (input->cursor += csize);
|
||||
input->buffer[input->length] = 0;
|
||||
}
|
||||
|
||||
static void M_TextInputAddChar(textinput_t *input, char c)
|
||||
{
|
||||
if (input->length >= input->buffer_size-1)
|
||||
return;
|
||||
|
||||
if (input->cursor != input->length)
|
||||
memmove(&input->buffer[input->cursor+1], &input->buffer[input->cursor], input->length-input->cursor);
|
||||
input->buffer[input->cursor++] = c;
|
||||
input->buffer[++input->length] = 0;
|
||||
input->select = input->cursor;
|
||||
}
|
||||
|
||||
static void M_TextInputDelChar(textinput_t *input)
|
||||
{
|
||||
if (!input->cursor)
|
||||
return;
|
||||
|
||||
if (input->cursor != input->length)
|
||||
memmove(&input->buffer[input->cursor-1], &input->buffer[input->cursor], input->length-input->cursor);
|
||||
input->buffer[--input->length] = 0;
|
||||
input->select = --input->cursor;
|
||||
}
|
||||
|
||||
static void M_TextInputToWordEnd(textinput_t *input, boolean move_sel)
|
||||
{
|
||||
// Skip spaces
|
||||
while (input->cursor < input->length && isspace(input->buffer[input->cursor]))
|
||||
++input->cursor;
|
||||
|
||||
// Skip word
|
||||
while (input->cursor < input->length && !isspace(input->buffer[input->cursor]))
|
||||
++input->cursor;
|
||||
|
||||
if (move_sel) input->select = input->cursor;
|
||||
}
|
||||
|
||||
static void M_TextInputToWordBegin(textinput_t *input, boolean move_sel)
|
||||
{
|
||||
// Hack, always move back 1 character if possible so if we press ctrl-left at a word beginning
|
||||
// we move to previous word
|
||||
if (input->cursor) --input->cursor;
|
||||
|
||||
// Skip spaces
|
||||
while (input->cursor && isspace(input->buffer[input->cursor]))
|
||||
--input->cursor;
|
||||
|
||||
// Skip word
|
||||
while (input->cursor && !isspace(input->buffer[input->cursor]))
|
||||
--input->cursor;
|
||||
|
||||
// Unless we reached beginning of line, we're pointing at a space before word, so move cursor
|
||||
// forward to fix that
|
||||
if (input->cursor) ++input->cursor;
|
||||
|
||||
if (move_sel) input->select = input->cursor;
|
||||
}
|
||||
|
||||
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size)
|
||||
{
|
||||
input->buffer = buffer;
|
||||
input->buffer_size = buffer_size;
|
||||
|
||||
M_TextInputClear(input);
|
||||
}
|
||||
|
||||
void M_TextInputClear(textinput_t *input)
|
||||
{
|
||||
input->cursor = 0;
|
||||
input->select = 0;
|
||||
input->length = 0;
|
||||
}
|
||||
|
||||
void M_TextInputSetString(textinput_t *input, const char *c)
|
||||
{
|
||||
memset(input->buffer, 0, input->buffer_size);
|
||||
strcpy(input->buffer, c);
|
||||
input->cursor = input->select = input->length = strlen(c);
|
||||
}
|
||||
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
{
|
||||
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|
||||
|| key == KEY_LCTRL || key == KEY_RCTRL
|
||||
|| key == KEY_LALT || key == KEY_RALT)
|
||||
return false;
|
||||
|
||||
if ((cv_keyboardlayout.value != 3 && ctrldown) || (cv_keyboardlayout.value == 3 && ctrldown && !altdown))
|
||||
{
|
||||
if (key == 'x' || key == 'X')
|
||||
{
|
||||
if (input->select > input->cursor)
|
||||
I_ClipboardCopy(&input->buffer[input->cursor], input->select-input->cursor);
|
||||
else
|
||||
I_ClipboardCopy(&input->buffer[input->select], input->cursor-input->select);
|
||||
M_TextInputDelSelection(input);
|
||||
return true;
|
||||
}
|
||||
else if (key == 'c' || key == 'C')
|
||||
{
|
||||
if (input->select > input->cursor)
|
||||
I_ClipboardCopy(&input->buffer[input->cursor], input->select-input->cursor);
|
||||
else
|
||||
I_ClipboardCopy(&input->buffer[input->select], input->cursor-input->select);
|
||||
return true;
|
||||
}
|
||||
else if (key == 'v' || key == 'V')
|
||||
{
|
||||
const char *paste = I_ClipboardPaste();
|
||||
if (input->select != input->cursor)
|
||||
M_TextInputDelSelection(input);
|
||||
if (paste != NULL)
|
||||
M_TextInputAddString(input, paste);
|
||||
return true;
|
||||
}
|
||||
else if (key == 'w' || key == 'W')
|
||||
{
|
||||
size_t word_start, word_end, i;
|
||||
word_end = i = input->cursor;
|
||||
|
||||
// Unless we're pointing at the beginning of line, decrement i so we only start
|
||||
// removing symbols that come before the cursor
|
||||
if (i) --i;
|
||||
|
||||
// We might be pointing to spaces, skip them first
|
||||
while (i && isspace(input->buffer[i]))
|
||||
--i;
|
||||
|
||||
// Now skip the "word"
|
||||
while (i && !isspace(input->buffer[i]))
|
||||
--i;
|
||||
|
||||
// Unless we reached beginning of line, i is pointing at first space that was found
|
||||
// before word start, and we don't want to remove it
|
||||
if (i) ++i;
|
||||
|
||||
word_start = i;
|
||||
|
||||
if (word_start != word_end)
|
||||
M_TextInputDel(input, word_start, word_end);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
M_TextInputToWordEnd(input, !shiftdown);
|
||||
else if (key == KEY_LEFTARROW)
|
||||
M_TextInputToWordBegin(input, !shiftdown);
|
||||
|
||||
// Select all
|
||||
if (key == 'a' || key == 'A')
|
||||
{
|
||||
input->select = 0;
|
||||
input->cursor = input->length;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ...why shouldn't it eat the key? if it doesn't, it just means you
|
||||
// can control Sonic from the console, which is silly
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == KEY_LEFTARROW)
|
||||
{
|
||||
if (input->cursor != 0)
|
||||
--input->cursor;
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
{
|
||||
if (input->cursor < input->length)
|
||||
++input->cursor;
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_HOME)
|
||||
{
|
||||
input->cursor = 0;
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_END)
|
||||
{
|
||||
input->cursor = input->length;
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
}
|
||||
|
||||
// backspace and delete command prompt
|
||||
if (input->select != input->cursor)
|
||||
{
|
||||
if (key == KEY_BACKSPACE || key == KEY_DEL)
|
||||
{
|
||||
M_TextInputDelSelection(input);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == KEY_BACKSPACE)
|
||||
{
|
||||
M_TextInputDelChar(input);
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_DEL)
|
||||
{
|
||||
if (input->cursor == input->length)
|
||||
return true;
|
||||
++input->cursor;
|
||||
M_TextInputDelChar(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
// allow people to use keypad in console (good for typing IP addresses) - Calum
|
||||
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
|
||||
{
|
||||
char keypad_translation[] = {'7','8','9','-',
|
||||
'4','5','6','+',
|
||||
'1','2','3',
|
||||
'0','.'};
|
||||
|
||||
key = keypad_translation[key - KEY_KEYPAD7];
|
||||
}
|
||||
else if (key == KEY_KPADSLASH)
|
||||
key = '/';
|
||||
|
||||
// same capslock code as hu_stuff.c's HU_responder. Check there for details.
|
||||
key = cv_keyboardlayout.value == 3 ? CON_ShitAndAltGrChar(key) : CON_ShiftChar(key);
|
||||
|
||||
// enter a char into the command prompt
|
||||
if (key < 32 || key > 127)
|
||||
return false;
|
||||
|
||||
if (input->select != input->cursor)
|
||||
M_TextInputDelSelection(input);
|
||||
M_TextInputAddChar(input, key);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef __M_TEXTINPUT__
|
||||
#define __M_TEXTINPUT__
|
||||
|
||||
#include "doomtype.h"
|
||||
|
||||
typedef struct textinput_s {
|
||||
size_t cursor;
|
||||
size_t select;
|
||||
size_t length;
|
||||
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
} textinput_t;
|
||||
|
||||
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size);
|
||||
|
||||
void M_TextInputClear(textinput_t *input);
|
||||
|
||||
void M_TextInputSetString(textinput_t *input, const char *c);
|
||||
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key);
|
||||
|
||||
#endif
|
||||
+73
-16
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "doomdef.h"
|
||||
#include "console.h" // con_startup
|
||||
#include "command.h"
|
||||
#include "i_threads.h"
|
||||
#include "mserv.h"
|
||||
@@ -212,20 +213,50 @@ static void Command_Listserv_f(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean firstmsrules = false;
|
||||
|
||||
static void
|
||||
Get_masterserver_rules (boolean checkfirst)
|
||||
{
|
||||
char rules[256];
|
||||
|
||||
if (checkfirst)
|
||||
{
|
||||
boolean MSRulesExist;
|
||||
|
||||
Lock_state();
|
||||
MSRulesExist = (MSRules != NULL);
|
||||
Unlock_state();
|
||||
|
||||
if (MSRulesExist)
|
||||
return;
|
||||
}
|
||||
|
||||
if (HMS_fetch_rules(rules, sizeof rules))
|
||||
{
|
||||
Lock_state();
|
||||
Z_Free(MSRules);
|
||||
MSRules = Z_StrDup(rules);
|
||||
|
||||
if (MSRegistered == true)
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
firstmsrules = true;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Finish_registration (void)
|
||||
{
|
||||
int registered;
|
||||
char *rules = GetMasterServerRules();
|
||||
|
||||
CONS_Printf("Registering this server on the master server...\n");
|
||||
|
||||
if (rules)
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
registered = HMS_register();
|
||||
|
||||
Lock_state();
|
||||
@@ -237,6 +268,17 @@ Finish_registration (void)
|
||||
}
|
||||
Unlock_state();
|
||||
|
||||
char *rules = GetMasterServerRules();
|
||||
if (rules == NULL)
|
||||
{
|
||||
Get_masterserver_rules(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
if (registered)
|
||||
CONS_Printf("Master server registration successful.\n");
|
||||
}
|
||||
@@ -322,17 +364,10 @@ Finish_unlist (void)
|
||||
static void
|
||||
Finish_masterserver_change (char *api)
|
||||
{
|
||||
char rules[256];
|
||||
|
||||
HMS_set_api(api);
|
||||
|
||||
if (HMS_fetch_rules(rules, sizeof rules))
|
||||
{
|
||||
Lock_state();
|
||||
Z_Free(MSRules);
|
||||
MSRules = Z_StrDup(rules);
|
||||
Unlock_state();
|
||||
}
|
||||
if (!con_startup)
|
||||
Get_masterserver_rules(false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
@@ -430,6 +465,14 @@ Change_masterserver_thread (char *api)
|
||||
|
||||
Finish_masterserver_change(api);
|
||||
}
|
||||
|
||||
static void
|
||||
Get_masterserver_rules_thread (void)
|
||||
{
|
||||
// THIS FUNC has its own lock check in it
|
||||
Get_masterserver_rules(true);
|
||||
}
|
||||
|
||||
#endif/*HAVE_THREADS*/
|
||||
|
||||
void RegisterServer(void)
|
||||
@@ -540,6 +583,20 @@ Set_api (const char *api)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Get_rules (void)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"get-masterserver-rules",
|
||||
(I_thread_fn)Get_masterserver_rules_thread,
|
||||
NULL
|
||||
);
|
||||
#else
|
||||
Get_masterserver_rules(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static void
|
||||
|
||||
+5
-1
@@ -82,6 +82,8 @@ extern I_mutex ms_ServerList_mutex;
|
||||
void RegisterServer(void);
|
||||
void UnregisterServer(void);
|
||||
|
||||
void Get_rules(void);
|
||||
|
||||
void MasterClient_Ticker(void);
|
||||
|
||||
msg_server_t *GetShortServersList(int id);
|
||||
@@ -90,9 +92,11 @@ char *GetMODVersion(int id);
|
||||
#endif
|
||||
|
||||
char *GetMasterServerRules(void);
|
||||
#endif
|
||||
|
||||
void AddMServCommands(void);
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
/* HTTP */
|
||||
void HMS_set_api (char *api);
|
||||
int HMS_register (void);
|
||||
@@ -105,4 +109,4 @@ const char * HMS_fetch_rules (char *buffer, size_t size_of_buffer);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+203
-203
File diff suppressed because it is too large.
Load diff
@@ -1968,32 +1968,8 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||
}
|
||||
else // Not going anywhere, so look for players.
|
||||
{
|
||||
//thinker_t *th;
|
||||
//mobj_t *mo;
|
||||
|
||||
thwomp->direction = -1;
|
||||
|
||||
/* // SRB2kart 170217 - Thwomps are automatic.
|
||||
// scan the thinkers to find players!
|
||||
if (!rover || (rover->flags & FF_EXISTS))
|
||||
{
|
||||
// scan the thinkers to find players!
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator
|
||||
&& mo->z <= thwomp->sector->ceilingheight
|
||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||
{
|
||||
thwomp->direction = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
thwomp->sector->ceilspeed = 0;
|
||||
thwomp->sector->floorspeed = 0;
|
||||
}
|
||||
|
||||
+68
-601
@@ -17,6 +17,7 @@
|
||||
#include "g_game.h"
|
||||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "s_sound.h"
|
||||
#include "r_main.h"
|
||||
#include "st_stuff.h"
|
||||
@@ -253,26 +254,21 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
|
||||
if (heightcheck)
|
||||
{
|
||||
/*if (special->type == MT_FLINGEMERALD) // little hack here...
|
||||
{ // flingemerald sprites are low to the ground, so extend collision radius down some.
|
||||
if (toucher->z > (special->z + special->height))
|
||||
return;
|
||||
if (special->z - special->height > (toucher->z + toucher->height))
|
||||
return;
|
||||
}
|
||||
else*/
|
||||
if (toucher->momz < 0)
|
||||
{
|
||||
if (toucher->momz < 0) {
|
||||
if (toucher->z + toucher->momz > special->z + special->height)
|
||||
return;
|
||||
} else if (toucher->z > special->z + special->height)
|
||||
return;
|
||||
if (toucher->momz > 0) {
|
||||
if (toucher->z + toucher->height + toucher->momz < special->z)
|
||||
return;
|
||||
} else if (toucher->z + toucher->height < special->z)
|
||||
if (toucher->z + toucher->momz > special->z + special->height)
|
||||
return;
|
||||
}
|
||||
else if (toucher->z > special->z + special->height)
|
||||
return;
|
||||
|
||||
if (toucher->momz > 0)
|
||||
{
|
||||
if (toucher->z + toucher->height + toucher->momz < special->z)
|
||||
return;
|
||||
}
|
||||
else if (toucher->z + toucher->height < special->z)
|
||||
return;
|
||||
}
|
||||
|
||||
if (special->health <= 0)
|
||||
@@ -383,16 +379,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
player->kartstuff[k_roulettetype] = 2;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Eggbox snipe!
|
||||
if (special->type == MT_EGGMANITEM && special->health > 1)
|
||||
S_StartSound(toucher, sfx_bsnipe);
|
||||
#endif
|
||||
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->deathsound);
|
||||
}
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->deathsound);
|
||||
|
||||
if (special->target && special->target->player)
|
||||
{
|
||||
@@ -475,8 +463,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1))
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->seesound);
|
||||
mobj_t *poof2 = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof2, special->info->seesound);
|
||||
|
||||
// Karma fireworks
|
||||
for (i = 0; i < 5; i++)
|
||||
@@ -502,10 +490,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
else if (special->target->player->kartstuff[k_comebackmode] == 2 && P_CanPickupItem(player, 2))
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
mobj_t *poof3 = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
UINT8 ptadd = 1; // No WANTED bonus for tricking
|
||||
|
||||
S_StartSound(poof, special->info->seesound);
|
||||
S_StartSound(poof3, special->info->seesound);
|
||||
|
||||
if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1
|
||||
{
|
||||
@@ -583,10 +571,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
else
|
||||
K_SpinPlayer(player, special->target, 0, special, false);
|
||||
return;
|
||||
/*case MT_EERIEFOG:
|
||||
special->frame &= ~FF_TRANS80;
|
||||
special->frame |= FF_TRANS90;
|
||||
return;*/
|
||||
case MT_SMK_MOLE:
|
||||
if (special->target && !P_MobjWasRemoved(special->target))
|
||||
return;
|
||||
@@ -935,12 +919,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
player->flyangle = special->threshold;
|
||||
|
||||
player->speed = FixedMul(special->info->speed, special->scale);
|
||||
// Potentially causes axis transfer failures.
|
||||
// Also rarely worked properly anyway.
|
||||
//P_UnsetThingPosition(player->mo);
|
||||
//player->mo->x = special->x;
|
||||
//player->mo->y = special->y;
|
||||
//P_SetThingPosition(player->mo);
|
||||
toucher->z = special->z+(special->height/4);
|
||||
}
|
||||
else // More like a spring
|
||||
@@ -985,140 +963,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
}
|
||||
return;
|
||||
/*case MT_NIGHTSSUPERLOOP:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
player->powers[pw_nights_superloop] = (UINT16)special->info->speed;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed;
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Super Paraloop"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSDRILLREFILL:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
player->drillmeter = special->info->speed;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
players[i].drillmeter = special->info->speed;
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Drill Refill"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSHELPER:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
// A flicky orbits us now
|
||||
mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, toucher);
|
||||
|
||||
player->powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj_t *flickyobj;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mo && players[i].pflags & PF_NIGHTSMODE) {
|
||||
players[i].powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, players[i].mo);
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Nightopian Helper"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSEXTRATIME:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
player->nightstime += special->info->speed;
|
||||
player->startedtime += special->info->speed;
|
||||
P_RestoreMusic(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
players[i].nightstime += special->info->speed;
|
||||
players[i].startedtime += special->info->speed;
|
||||
P_RestoreMusic(&players[i]);
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Extra Time"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSLINKFREEZE:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
player->powers[pw_nights_linkfreeze] = (UINT16)special->info->speed;
|
||||
player->linktimer = 2*TICRATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed;
|
||||
players[i].linktimer = 2*TICRATE;
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Link Freeze"));
|
||||
}
|
||||
break;*/
|
||||
case MT_NIGHTSWING:
|
||||
if (G_IsSpecialStage(gamemap) && useNightsSS)
|
||||
{ // Pseudo-ring.
|
||||
@@ -1132,7 +976,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
break;
|
||||
case MT_HOOPCOLLIDE:
|
||||
// This produces a kind of 'domino effect' with the hoop's pieces.
|
||||
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
if (!midgamejoin)
|
||||
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
|
||||
i = 0;
|
||||
for (; special->type == MT_HOOP; special = special->hnext)
|
||||
{
|
||||
@@ -1464,7 +1310,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
else
|
||||
{
|
||||
P_PlayRinglossSound(toucher);
|
||||
P_PlayRinglossSound(toucher, NULL);
|
||||
if (toucher->health > 10)
|
||||
toucher->health -= 10;
|
||||
else
|
||||
@@ -1510,23 +1356,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
|| special->z > toucher->z + (toucher->height*2/3))
|
||||
return; // Only go in the mouth
|
||||
|
||||
/* // SRB2kart - Can't drown.
|
||||
// Eaten by player!
|
||||
if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)
|
||||
P_RestoreMusic(player);
|
||||
|
||||
if (player->powers[pw_underwater] < underwatertics + 1)
|
||||
player->powers[pw_underwater] = underwatertics + 1;
|
||||
*/
|
||||
|
||||
/*
|
||||
if (!player->climbing)
|
||||
{
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_GASP);
|
||||
P_ResetPlayer(player);
|
||||
}
|
||||
*/
|
||||
|
||||
toucher->momx = toucher->momy = toucher->momz = 0;
|
||||
break;
|
||||
|
||||
@@ -1583,26 +1412,7 @@ void P_CheckTimeLimit(void)
|
||||
if (gameaction == ga_completed)
|
||||
return;
|
||||
|
||||
//Tagmode round end but only on the tic before the
|
||||
//XD_EXITLEVEL packet is received by all players.
|
||||
/*if (G_TagGametype())
|
||||
{
|
||||
if (leveltime == (timelimitintics + 1))
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator
|
||||
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
|
||||
continue;
|
||||
|
||||
CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]);
|
||||
P_AddPlayerScore(&players[i], players[i].score);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Optional tie-breaker for Match/CTF
|
||||
else*/ if (cv_overtime.value)
|
||||
if (cv_overtime.value)
|
||||
{
|
||||
INT32 playerarray[MAXPLAYERS];
|
||||
INT32 tempplayer = 0;
|
||||
@@ -1675,9 +1485,6 @@ void P_CheckTimeLimit(void)
|
||||
return;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
/*if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/
|
||||
}
|
||||
|
||||
/** Checks if a player's score is over the pointlimit and the round should end.
|
||||
@@ -1699,127 +1506,27 @@ void P_CheckPointLimit(void)
|
||||
if (G_RaceGametype())
|
||||
return;
|
||||
|
||||
// pointlimit is nonzero, check if it's been reached by this player
|
||||
/*if (G_GametypeHasTeams())
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
// Just check both teams
|
||||
if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore)
|
||||
{
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
}
|
||||
else*/
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if ((UINT32)cv_pointlimit.value <= players[i].marescore)
|
||||
if ((UINT32)cv_pointlimit.value <= players[i].marescore)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++) // AAAAA nested loop using the same iteration variable ;;
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++) // AAAAA nested loop using the same iteration variable ;;
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
if (players[i].exiting)
|
||||
return;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
/*if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/
|
||||
return; // good thing we're leaving the function immediately instead of letting the loop get mangled!
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
if (players[i].exiting)
|
||||
return;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
return; // good thing we're leaving the function immediately instead of letting the loop get mangled!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Checks for untagged remaining players in both tag derivitave modes.
|
||||
*If no untagged players remain, end the round.
|
||||
*Also serves as error checking if the only IT player leaves.*/
|
||||
/*void P_CheckSurvivors(void)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 survivors = 0;
|
||||
INT32 taggers = 0;
|
||||
INT32 spectators = 0;
|
||||
INT32 survivorarray[MAXPLAYERS];
|
||||
|
||||
if (!D_NumPlayers()) //no players in the game, no check performed.
|
||||
return;
|
||||
|
||||
for (i=0; i < MAXPLAYERS; i++) //figure out counts of taggers, survivors and spectators.
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (players[i].spectator)
|
||||
spectators++;
|
||||
else if (players[i].pflags & PF_TAGIT)
|
||||
taggers++;
|
||||
else if (!(players[i].pflags & PF_TAGGED))
|
||||
{
|
||||
survivorarray[survivors] = i;
|
||||
survivors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!taggers) //If there are no taggers, pick a survivor at random to be it.
|
||||
{
|
||||
// Exception for hide and seek. If a round has started and the IT player leaves, end the round.
|
||||
if (gametype == GT_HIDEANDSEEK && (leveltime >= (hidetime * TICRATE)))
|
||||
{
|
||||
CONS_Printf(M_GetText("The IT player has left the game.\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (survivors)
|
||||
{
|
||||
INT32 newtagger = survivorarray[P_RandomKey(survivors)];
|
||||
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[newtagger]); // Tell everyone who is it!
|
||||
players[newtagger].pflags |= PF_TAGIT;
|
||||
|
||||
survivors--; //Get rid of the guy we just made IT.
|
||||
|
||||
//Yeah, we have an eligible tagger, but we may not have anybody for him to tag!
|
||||
//If there is only one guy waiting on the game to fill or spectators to enter game, don't bother.
|
||||
if (!survivors && (D_NumPlayers() - spectators) > 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//If we reach this point, no player can replace the one that was IT.
|
||||
//Unless it is one player waiting on a game, end the round.
|
||||
if ((D_NumPlayers() - spectators) > 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("There are no players able to become IT.\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//If there are taggers, but no survivors, end the round.
|
||||
//Except when the tagger is by himself and the rest of the game are spectators.
|
||||
if (!survivors && (D_NumPlayers() - spectators) > 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Checks whether or not to end a race netgame.
|
||||
boolean P_CheckRacers(void)
|
||||
{
|
||||
@@ -1908,9 +1615,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
mobj_t *mo;
|
||||
int ms;
|
||||
|
||||
//if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
|
||||
// P_SetTarget(&target->tracer, inflictor);
|
||||
|
||||
if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6)
|
||||
sstimer = 6; // Just let P_Ticker take care of the rest.
|
||||
|
||||
@@ -1959,7 +1663,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
K_KillBananaChain(target->target->hnext, inflictor, source);
|
||||
target->target->player->kartstuff[k_itemamount] = 0;
|
||||
}
|
||||
else
|
||||
else if (target->target->player->kartstuff[k_itemamount])
|
||||
target->target->player->kartstuff[k_itemamount]--;
|
||||
}
|
||||
else if ((target->type == MT_ORBINAUT_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) // orbit items
|
||||
@@ -1991,14 +1695,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
|
||||
G_StopMetalRecording();
|
||||
/*if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
|
||||
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
|
||||
{ // Suicide penalty - Not in Kart
|
||||
if (target->player->score >= 50)
|
||||
target->player->score -= 50;
|
||||
else
|
||||
target->player->score = 0;
|
||||
}*/
|
||||
|
||||
target->flags2 &= ~MF2_DONTDRAW;
|
||||
}
|
||||
@@ -2015,85 +1711,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
|
||||
}
|
||||
}
|
||||
|
||||
// Award Score Tails
|
||||
/*{ // Enemies shouldn't award points in Kart
|
||||
INT32 score = 0;
|
||||
|
||||
if (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything.
|
||||
{
|
||||
if ((target->flags & MF_ENEMY) && !(target->flags & (MF_MISSILE|MF_BOSS)))
|
||||
{
|
||||
score = 200;
|
||||
|
||||
if (source->player->bonustime)
|
||||
score *= 2;
|
||||
|
||||
// Also, add to the link.
|
||||
// I don't know if NiGHTS did this, but
|
||||
// Sonic Time Attacked did and it seems like a good enough incentive
|
||||
// to make people want to actually dash towards/paraloop enemies
|
||||
if (++source->player->linkcount > source->player->maxlink)
|
||||
source->player->maxlink = source->player->linkcount;
|
||||
source->player->linktimer = 2*TICRATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target->flags & MF_BOSS)
|
||||
score = 1000;
|
||||
else if ((target->flags & MF_ENEMY) && !(target->flags & MF_MISSILE))
|
||||
{
|
||||
mobj_t *scoremobj;
|
||||
UINT32 scorestate = mobjinfo[MT_SCORE].spawnstate;
|
||||
|
||||
scoremobj = P_SpawnMobj(target->x, target->y, target->z + (target->height / 2), MT_SCORE);
|
||||
|
||||
// On ground? No chain starts.
|
||||
if (!source->player->powers[pw_invulnerability] && P_IsObjectOnGround(source))
|
||||
{
|
||||
source->player->scoreadd = 0;
|
||||
score = 100;
|
||||
}
|
||||
// Mario Mode has Mario-like chain point values
|
||||
else if (mariomode) switch (++source->player->scoreadd)
|
||||
{
|
||||
case 1: score = 100; break;
|
||||
case 2: score = 200; scorestate += 1; break;
|
||||
case 3: score = 400; scorestate += 5; break;
|
||||
case 4: score = 800; scorestate += 6; break;
|
||||
case 5: score = 1000; scorestate += 3; break;
|
||||
case 6: score = 2000; scorestate += 7; break;
|
||||
case 7: score = 4000; scorestate += 8; break;
|
||||
case 8: score = 8000; scorestate += 9; break;
|
||||
default: // 1up for a chain this long
|
||||
if (modeattacking) // but 1ups don't exist in record attack!
|
||||
{ // So we just go back to 10k points.
|
||||
score = 10000; scorestate += 4; break;
|
||||
}
|
||||
P_GivePlayerLives(source->player, 1);
|
||||
P_PlayLivesJingle(source->player);
|
||||
scorestate += 10;
|
||||
break;
|
||||
}
|
||||
// More Sonic-like point system
|
||||
else switch (++source->player->scoreadd)
|
||||
{
|
||||
case 1: score = 100; break;
|
||||
case 2: score = 200; scorestate += 1; break;
|
||||
case 3: score = 500; scorestate += 2; break;
|
||||
case 4: case 5: case 6: case 7: case 8: case 9:
|
||||
case 10: case 11: case 12: case 13: case 14:
|
||||
score = 1000; scorestate += 3; break;
|
||||
default: score = 10000; scorestate += 4; break;
|
||||
}
|
||||
|
||||
P_SetMobjState(scoremobj, scorestate);
|
||||
}
|
||||
}
|
||||
|
||||
P_AddPlayerScore(source->player, score);
|
||||
}*/
|
||||
}
|
||||
|
||||
// if a player avatar dies...
|
||||
@@ -2120,7 +1737,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
}
|
||||
target->player->playerstate = PST_DEAD;
|
||||
|
||||
if (cv_fading.value && cv_birdmusic.value && P_IsLocalPlayer(target->player))
|
||||
if (cv_birdmusic.value && cv_fading.value && P_IsLocalPlayer(target->player))
|
||||
{
|
||||
if (netgame || multiplayer)
|
||||
ms = cv_respawntime.value * 1000;
|
||||
@@ -2131,7 +1748,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
If the time spent with the music paused is less than half
|
||||
a second, continue playing the song (just mute it).
|
||||
*/
|
||||
if (( ms - cv_respawnfademusicout.value ) < 500)
|
||||
if ((ms - cv_respawnfademusicout.value) < 500)
|
||||
S_FadeMusic(0, cv_respawnfademusicout.value);
|
||||
else
|
||||
S_FadeOutStopMusic(cv_respawnfademusicout.value);
|
||||
@@ -2157,42 +1774,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
if (target->player == &players[displayplayers[3]])
|
||||
localaiming[3] = 0;
|
||||
|
||||
//tag deaths handled differently in suicide cases. Don't count spectators!
|
||||
/*if (G_TagGametype()
|
||||
&& !(target->player->pflags & PF_TAGIT) && (!source || !source->player) && !(target->player->spectator))
|
||||
{
|
||||
// if you accidentally die before you run out of time to hide, ignore it.
|
||||
// allow them to try again, rather than sitting the whole thing out.
|
||||
if (leveltime >= hidetime * TICRATE)
|
||||
{
|
||||
if (gametype == GT_TAG)//suiciding in survivor makes you IT.
|
||||
{
|
||||
target->player->pflags |= PF_TAGIT;
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it!
|
||||
P_CheckSurvivors();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(target->player->pflags & PF_TAGGED))
|
||||
{
|
||||
//otherwise, increment the tagger's score.
|
||||
//in hide and seek, suiciding players are counted as found.
|
||||
INT32 w;
|
||||
|
||||
for (w=0; w < MAXPLAYERS; w++)
|
||||
{
|
||||
if (players[w].pflags & PF_TAGIT)
|
||||
P_AddPlayerScore(&players[w], 1);
|
||||
}
|
||||
|
||||
target->player->pflags |= PF_TAGGED;
|
||||
CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]);
|
||||
P_CheckSurvivors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else*/ if (G_BattleGametype())
|
||||
if (G_BattleGametype())
|
||||
K_CheckBumpers();
|
||||
|
||||
target->player->kartstuff[k_pogospring] = 0;
|
||||
@@ -2607,26 +2189,6 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
||||
return false;
|
||||
}
|
||||
|
||||
// The tag occurs so long as you aren't shooting another tagger with friendlyfire on.
|
||||
/*if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
|
||||
{
|
||||
P_AddPlayerScore(source->player, 1); //award points to tagger.
|
||||
|
||||
if (gametype == GT_TAG) //survivor
|
||||
{
|
||||
player->pflags |= PF_TAGIT; //in survivor, the player becomes IT and helps hunt down the survivors.
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it!
|
||||
}
|
||||
else
|
||||
{
|
||||
player->pflags |= PF_TAGGED; //in hide and seek, the player is tagged and stays stationary.
|
||||
CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it!
|
||||
}
|
||||
|
||||
//checks if tagger has tagged all players, if so, end round early.
|
||||
P_CheckSurvivors();
|
||||
}*/
|
||||
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
// Check for a shield
|
||||
@@ -2644,7 +2206,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
||||
}
|
||||
else if (target->health > 1) // Ring loss
|
||||
{
|
||||
P_PlayRinglossSound(target);
|
||||
P_PlayRinglossSound(target, source);
|
||||
P_PlayerRingBurst(player, player->mo->health - 1);
|
||||
}
|
||||
|
||||
@@ -2665,15 +2227,6 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
|
||||
{
|
||||
player_t *player = target->player;
|
||||
|
||||
// You can't kill yourself, idiot... // Unless it's Mario kart. Which it is. In this mod. All the time.
|
||||
//if (source == target)
|
||||
// return false;
|
||||
|
||||
// In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on
|
||||
// ...But in SRB2kart, you can!
|
||||
//if (!cv_friendlyfire.value && (G_RaceGametype()))
|
||||
// return false;
|
||||
|
||||
// Tag handling
|
||||
if (G_TagGametype())
|
||||
return P_TagDamage(target, inflictor, source, damage);
|
||||
@@ -2725,32 +2278,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
|
||||
|
||||
/*if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
}
|
||||
}
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
}
|
||||
|
||||
// If the player was super, tell them he/she ain't so super nomore.
|
||||
if (gametype != GT_COOP && player->powers[pw_super])
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
|
||||
}*/
|
||||
|
||||
if (player->pflags & PF_TIMEOVER)
|
||||
{
|
||||
mobj_t *boom;
|
||||
@@ -2811,44 +2338,8 @@ void P_RemoveShield(player_t *player)
|
||||
player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK;
|
||||
}
|
||||
|
||||
/*
|
||||
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) // SRB2kart - unused.
|
||||
{
|
||||
// Must do pain first to set flashing -- P_RemoveShield can cause damage
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_RemoveShield(player);
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
else
|
||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 25);
|
||||
}
|
||||
}
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, cv_match_scoring.value == 1 ? 25 : 50);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
//const UINT8 scoremultiply = ((K_IsWantedPlayer(player) && !trapitem) : 2 ? 1);
|
||||
|
||||
if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
{
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
@@ -2859,26 +2350,8 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
}
|
||||
|
||||
/*if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, scoremultiply);
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, scoremultiply);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Ring loss sound plays despite hitting spikes
|
||||
P_PlayRinglossSound(player->mo); // Ringledingle!
|
||||
P_PlayRinglossSound(player->mo, source); // Ringledingle!
|
||||
}
|
||||
|
||||
/** Damages an object, which may or may not be a player.
|
||||
@@ -2927,8 +2400,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
|
||||
if (P_MobjWasRemoved(target))
|
||||
return (shouldForce == 1); // mobj was removed
|
||||
if (P_MobjWasRemoved(source))
|
||||
source = NULL;
|
||||
if (shouldForce == 1)
|
||||
force = true;
|
||||
else if (shouldForce == 2)
|
||||
@@ -3091,8 +2562,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
P_PlayerRingBurst(player, 5);
|
||||
if (P_IsLocalPlayer(player))
|
||||
{
|
||||
quake.intensity = 32*FRACUNIT;
|
||||
quake.time = 5;
|
||||
P_StartQuake(5, 32<<FRACBITS, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3166,6 +2636,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
P_ResetPlayer(target->player);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (target->type)
|
||||
{
|
||||
case MT_EGGMOBILE2: // egg slimer
|
||||
@@ -3179,9 +2650,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
P_SetMobjState(target, target->info->painstate);
|
||||
break;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemoved(target))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!P_MobjWasRemoved(target))
|
||||
{
|
||||
@@ -3676,32 +3145,30 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
|
||||
P_SetTarget(&flag->target, player->mo);
|
||||
|
||||
// Flag text
|
||||
char plname[MAXPLAYERNAME+4];
|
||||
const char *flagtext;
|
||||
char flagcolor;
|
||||
|
||||
snprintf(plname, sizeof(plname), "%s%s%s",
|
||||
CTFTEAMCODE(player),
|
||||
player_names[player - players],
|
||||
CTFTEAMENDCODE(player));
|
||||
|
||||
if (type == MT_REDFLAG)
|
||||
{
|
||||
char plname[MAXPLAYERNAME+4];
|
||||
const char *flagtext;
|
||||
char flagcolor;
|
||||
|
||||
snprintf(plname, sizeof(plname), "%s%s%s",
|
||||
CTFTEAMCODE(player),
|
||||
player_names[player - players],
|
||||
CTFTEAMENDCODE(player));
|
||||
|
||||
if (type == MT_REDFLAG)
|
||||
{
|
||||
flagtext = M_GetText("Red flag");
|
||||
flagcolor = '\x85';
|
||||
}
|
||||
else
|
||||
{
|
||||
flagtext = M_GetText("Blue flag");
|
||||
flagcolor = '\x84';
|
||||
}
|
||||
|
||||
if (toss)
|
||||
CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
else
|
||||
CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
flagtext = M_GetText("Red flag");
|
||||
flagcolor = '\x85';
|
||||
}
|
||||
else
|
||||
{
|
||||
flagtext = M_GetText("Blue flag");
|
||||
flagcolor = '\x84';
|
||||
}
|
||||
|
||||
if (toss)
|
||||
CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
else
|
||||
CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
|
||||
player->gotflag = 0;
|
||||
|
||||
|
||||
+27
-5
@@ -70,6 +70,7 @@ extern thinker_t thinkercap;
|
||||
void P_InitThinkers(void);
|
||||
void P_AddThinker(thinker_t *thinker);
|
||||
void P_RemoveThinker(thinker_t *thinker);
|
||||
void P_UnlinkThinker(thinker_t *thinker);
|
||||
|
||||
//
|
||||
// P_USER
|
||||
@@ -143,6 +144,8 @@ extern consvar_t cv_tiltsmoothing;
|
||||
|
||||
extern consvar_t cv_actionmovie;
|
||||
|
||||
extern consvar_t cv_lookbackmom;
|
||||
|
||||
extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
|
||||
extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
|
||||
extern fixed_t t_cam3_dist, t_cam3_height, t_cam3_rotate;
|
||||
@@ -161,8 +164,9 @@ void P_InitCameraCmd(void);
|
||||
boolean P_PlayerInPain(player_t *player);
|
||||
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
|
||||
void P_ResetPlayer(player_t *player);
|
||||
boolean P_IsLocalPlayer(player_t *player);
|
||||
boolean P_IsDisplayPlayer(player_t *player);
|
||||
boolean P_IsLocalPlayer(const player_t *player);
|
||||
boolean P_IsDisplayPlayer(const player_t *player);
|
||||
|
||||
boolean P_SpectatorJoinGame(player_t *player);
|
||||
|
||||
boolean P_IsObjectInGoop(mobj_t *mo);
|
||||
@@ -215,7 +219,7 @@ boolean P_PlayerMoving(INT32 pnum);
|
||||
void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range);
|
||||
|
||||
void P_PlayLivesJingle(player_t *player);
|
||||
void P_PlayRinglossSound(mobj_t *source);
|
||||
void P_PlayRinglossSound(mobj_t *source, mobj_t *damager);
|
||||
void P_PlayDeathSound(mobj_t *source);
|
||||
void P_PlayVictorySound(mobj_t *source);
|
||||
|
||||
@@ -245,7 +249,7 @@ void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
||||
void P_RemoveMobj(mobj_t *th);
|
||||
boolean P_MobjWasRemoved(mobj_t *th);
|
||||
|
||||
void P_RemoveSavegameMobj(mobj_t *th);
|
||||
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
||||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
@@ -257,6 +261,12 @@ boolean P_RailThinker(mobj_t *mobj);
|
||||
void P_PushableThinker(mobj_t *mobj);
|
||||
void P_SceneryThinker(mobj_t *mobj);
|
||||
|
||||
// This does not need to be added to Lua.
|
||||
// To test it in Lua, check mobj.valid
|
||||
FUNCINLINE static ATTRINLINE boolean P_MobjWasRemoved(const mobj_t *mobj)
|
||||
{
|
||||
return !(mobj && mobj->thinker.function.acp1 == (actionf_p1)P_MobjThinker);
|
||||
}
|
||||
|
||||
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
@@ -288,7 +298,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype
|
||||
#define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0)
|
||||
#endif
|
||||
void P_ColorTeamMissile(mobj_t *missile, player_t *source);
|
||||
SINT8 P_MobjFlip(mobj_t *mobj);
|
||||
SINT8 P_MobjFlip(const mobj_t *mobj);
|
||||
fixed_t P_GetMobjGravity(mobj_t *mo);
|
||||
FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
|
||||
|
||||
@@ -389,6 +399,18 @@ extern fixed_t bmaporgy; // origin of block map
|
||||
extern mobj_t **blocklinks; // for thing chains
|
||||
extern precipmobj_t **precipblocklinks; // special blockmap for precip rendering
|
||||
|
||||
extern struct minimapinfo
|
||||
{
|
||||
patch_t *minimap_pic;
|
||||
UINT8 mapthingcount;
|
||||
INT32 min_x, min_y;
|
||||
INT32 max_x, max_y;
|
||||
INT32 map_w, map_h;
|
||||
INT32 minimap_w, minimap_h;
|
||||
fixed_t offs_x, offs_y;
|
||||
fixed_t zoom;
|
||||
} minimapinfo;
|
||||
|
||||
//
|
||||
// P_INTER
|
||||
//
|
||||
|
||||
+6
-86
@@ -319,78 +319,6 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
||||
{
|
||||
INT32 p;
|
||||
fixed_t zdist; // z distance between the two players' bottoms
|
||||
|
||||
if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo)
|
||||
return;
|
||||
if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo)
|
||||
return;
|
||||
if (tails->bot == 1)
|
||||
return;
|
||||
|
||||
if (sonic->pflags & PF_NIGHTSMODE)
|
||||
return;
|
||||
|
||||
if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT
|
||||
&& !(sonic->pflags & PF_ROPEHANG))
|
||||
return; // don't steal players from zoomtubes!
|
||||
|
||||
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
|
||||
return; // Both should be in same gravity
|
||||
|
||||
if (tails->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (tails->mo->ceilingz - (tails->mo->z + tails->mo->height) < sonic->mo->height-FixedMul(2*FRACUNIT, sonic->mo->scale))
|
||||
return;
|
||||
}
|
||||
else if (tails->mo->z - tails->mo->floorz < sonic->mo->height-FixedMul(2*FRACUNIT, sonic->mo->scale))
|
||||
return; // No room to pick up this guy!
|
||||
|
||||
// Search in case another player is already being carried by this fox.
|
||||
for (p = 0; p < MAXPLAYERS; p++)
|
||||
if (playeringame[p] && players[p].mo
|
||||
&& players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo)
|
||||
return;
|
||||
|
||||
if (tails->mo->eflags & MFE_VERTICALFLIP)
|
||||
zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height);
|
||||
else
|
||||
zdist = tails->mo->z - sonic->mo->z;
|
||||
|
||||
if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale)
|
||||
&& zdist > sonic->mo->height*2/3
|
||||
&& P_MobjFlip(tails->mo)*sonic->mo->momz <= 0)
|
||||
{
|
||||
// Why block opposing teams from tailsflying each other?
|
||||
// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
|
||||
if (tails->spectator || sonic->spectator || G_RaceGametype()) // SRB2kart
|
||||
sonic->pflags &= ~PF_CARRIED;
|
||||
else
|
||||
{
|
||||
if (sonic-players == consoleplayer && botingame)
|
||||
//CV_SetValue(&cv_analog2, false);
|
||||
P_ResetPlayer(sonic);
|
||||
P_SetTarget(&sonic->mo->tracer, tails->mo);
|
||||
sonic->pflags |= PF_CARRIED;
|
||||
S_StartSound(sonic->mo, sfx_s3k4a);
|
||||
P_UnsetThingPosition(sonic->mo);
|
||||
sonic->mo->x = tails->mo->x;
|
||||
sonic->mo->y = tails->mo->y;
|
||||
P_SetThingPosition(sonic->mo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (sonic-players == consoleplayer && botingame)
|
||||
//CV_SetValue(&cv_analog2, true);
|
||||
sonic->pflags &= ~PF_CARRIED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// PIT_CheckThing
|
||||
//
|
||||
@@ -588,9 +516,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
// check for skulls slamming into things
|
||||
if (tmthing->flags2 & MF2_SKULLFLY)
|
||||
{
|
||||
/*if (tmthing->type == MT_EGGMOBILE) // Don't make Eggman stop!
|
||||
return true; // Let him RUN YOU RIGHT OVER. >:3
|
||||
else*/
|
||||
{
|
||||
// see if it went over / under
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
@@ -1676,7 +1601,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||
return true;
|
||||
|
||||
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
||||
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
||||
{
|
||||
fixed_t cosradius, sinradius;
|
||||
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
|
||||
@@ -2245,6 +2170,9 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
|
||||
floatok = false;
|
||||
|
||||
if (dedicated) // this crashes so don't even try it
|
||||
return false;
|
||||
|
||||
if (twodlevel)
|
||||
itsatwodlevel = true;
|
||||
else
|
||||
@@ -2474,14 +2402,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12)
|
||||
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12)
|
||||
maxstep = 0;
|
||||
|
||||
// Don't 'step up' while springing,
|
||||
// Only step up "if needed".
|
||||
/* // SRB2kart - don't need
|
||||
if (thing->state == &states[S_PLAY_SPRING]
|
||||
&& P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale))
|
||||
maxstep = 0;
|
||||
*/
|
||||
}
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
@@ -4143,7 +4063,7 @@ static inline boolean PIT_GetSectors(line_t *ld)
|
||||
tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
|
||||
tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
|
||||
tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||
return true;
|
||||
@@ -4178,7 +4098,7 @@ static inline boolean PIT_GetPrecipSectors(line_t *ld)
|
||||
preciptmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
|
||||
preciptmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
|
||||
preciptmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (P_BoxOnLineSide(preciptmbbox, ld) != -1)
|
||||
return true;
|
||||
|
||||
+706
-619
File diff suppressed because it is too large.
Load diff
+19
-23
@@ -254,19 +254,14 @@ typedef enum
|
||||
// PRECIPITATION flags ?! ?! ?!
|
||||
//
|
||||
typedef enum {
|
||||
// Don't draw.
|
||||
PCF_INVISIBLE = 1,
|
||||
// Above pit.
|
||||
PCF_PIT = 2,
|
||||
// Above FOF.
|
||||
PCF_FOF = 4,
|
||||
// Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_MOVINGFOF = 8,
|
||||
// Is rain.
|
||||
PCF_RAIN = 16,
|
||||
// Ran the thinker this tic.
|
||||
PCF_THUNK = 32,
|
||||
PCF_INVISIBLE = 1, // Don't draw.
|
||||
PCF_PIT = 1<<1, // Above pit.
|
||||
PCF_FOF = 1<<2, // Above FOF.
|
||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
||||
} precipflag_t;
|
||||
|
||||
// Map Object definition.
|
||||
typedef struct mobj_s
|
||||
{
|
||||
@@ -278,6 +273,9 @@ typedef struct mobj_s
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
fixed_t old_x2, old_y2, old_z2;
|
||||
|
||||
mobjtype_t type;
|
||||
const mobjinfo_t *info; // &mobjinfo[mobj->type]
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct mobj_s *bnext;
|
||||
struct mobj_s **bprev; // killough 8/11/98: change to ptr-to-ptr
|
||||
@@ -290,8 +288,7 @@ typedef struct mobj_s
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
UINT32 renderflags; // render flags
|
||||
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
@@ -345,9 +342,6 @@ typedef struct mobj_s
|
||||
struct mobj_s *hnext;
|
||||
struct mobj_s *hprev;
|
||||
|
||||
mobjtype_t type;
|
||||
const mobjinfo_t *info; // &mobjinfo[mobj->type]
|
||||
|
||||
INT32 health; // for player this is rings + 1
|
||||
|
||||
// Movement direction, movement generation (zig-zagging).
|
||||
@@ -431,6 +425,9 @@ typedef struct precipmobj_s
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
fixed_t old_x2, old_y2, old_z2;
|
||||
|
||||
mobjtype_t type;
|
||||
const mobjinfo_t *info; // &mobjinfo[mobj->type]
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct precipmobj_s *bnext;
|
||||
struct precipmobj_s **bprev; // killough 8/11/98: change to ptr-to-ptr
|
||||
@@ -443,8 +440,7 @@ typedef struct precipmobj_s
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
UINT32 renderflags; // render flags
|
||||
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
@@ -453,7 +449,7 @@ typedef struct precipmobj_s
|
||||
fixed_t realxscale, realyscale; // funn-E streeetch
|
||||
|
||||
fixed_t stretchslam; // "squish" effect when you land
|
||||
|
||||
|
||||
//sloperollangle
|
||||
angle_t sloperoll, slopepitch;
|
||||
angle_t old_sloperoll, old_slopepitch;
|
||||
@@ -479,6 +475,7 @@ typedef struct precipmobj_s
|
||||
INT32 tics; // state tic counter
|
||||
state_t *state;
|
||||
INT32 flags; // flags from mobjinfo tables
|
||||
tic_t lastThink;
|
||||
} precipmobj_t;
|
||||
|
||||
typedef struct actioncache_s
|
||||
@@ -518,10 +515,9 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb
|
||||
boolean P_BossTargetPlayer(mobj_t *actor, boolean closest);
|
||||
boolean P_SupermanLook4Players(mobj_t *actor);
|
||||
void P_DestroyRobots(void);
|
||||
void P_SnowThinker(precipmobj_t *mobj);
|
||||
void P_RainThinker(precipmobj_t *mobj);
|
||||
boolean P_PrecipThinker(precipmobj_t *mobj);
|
||||
void P_NullPrecipThinker(precipmobj_t *mobj);
|
||||
void P_RemovePrecipMobj(precipmobj_t *mobj);
|
||||
void P_FreePrecipMobj(precipmobj_t *mobj);
|
||||
void P_SetScale(mobj_t *mobj, fixed_t newscale);
|
||||
void P_XYMovement(mobj_t *mo);
|
||||
void P_EmeraldManager(void);
|
||||
|
||||
+86
-230
@@ -28,6 +28,7 @@
|
||||
#include "r_main.h"
|
||||
#include "r_state.h"
|
||||
#include "r_defs.h"
|
||||
#include "qs22j.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -95,6 +96,8 @@ INT32 numPolyObjects;
|
||||
// Polyobject Blockmap -- initialized in P_LoadBlockMap
|
||||
polymaplink_t **polyblocklinks;
|
||||
|
||||
static size_t *KnownPolySides;
|
||||
static size_t KnownPolySidesCount;
|
||||
|
||||
//
|
||||
// Static Data
|
||||
@@ -152,6 +155,36 @@ FUNCINLINE static ATTRINLINE void PolyObj_AddThinker(thinker_t *th)
|
||||
thinkercap.next = th;
|
||||
}
|
||||
|
||||
static void FreeSideLists(void)
|
||||
{
|
||||
free(KnownPolySides);
|
||||
KnownPolySides = NULL;
|
||||
KnownPolySidesCount = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// InitSideLists [RH]
|
||||
//
|
||||
// Group sides by vertex and collect side that are known to belong to a
|
||||
// polyobject so that they can be initialized fast.
|
||||
//==========================================================================
|
||||
static void InitSideLists(void)
|
||||
{
|
||||
size_t i;
|
||||
FreeSideLists();
|
||||
KnownPolySides = malloc(numsegs * sizeof(KnownPolySides[0]));
|
||||
for (i = 0; i < numsegs; i++)
|
||||
{
|
||||
if (segs[i].linedef &&
|
||||
(segs[i].linedef->special == POLYOBJ_START_LINE ||
|
||||
segs[i].linedef->special == POLYOBJ_EXPLICIT_LINE))
|
||||
{
|
||||
KnownPolySides[KnownPolySidesCount++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_PointInsidePolyobj
|
||||
//
|
||||
@@ -512,11 +545,12 @@ static void Polyobj_findExplicit(polyobj_t *po)
|
||||
size_t numSegItems = 0;
|
||||
size_t numSegItemsAlloc = 0;
|
||||
|
||||
size_t i;
|
||||
size_t i, ii;
|
||||
|
||||
// first loop: save off all segs with polyobject's id number
|
||||
for (i = 0; i < numsegs; ++i)
|
||||
for (ii = 0; ii < KnownPolySidesCount; ii++)
|
||||
{
|
||||
i = KnownPolySides[ii];
|
||||
INT32 polyID, parentID;
|
||||
|
||||
if (segs[i].linedef->special != POLYOBJ_EXPLICIT_LINE)
|
||||
@@ -547,7 +581,7 @@ static void Polyobj_findExplicit(polyobj_t *po)
|
||||
|
||||
// sort the array if necessary
|
||||
if (numSegItems >= 2)
|
||||
qsort(segitems, numSegItems, sizeof(segitem_t), Polyobj_segCompare);
|
||||
qs22j(segitems, numSegItems, sizeof(segitem_t), Polyobj_segCompare);
|
||||
|
||||
// second loop: put the sorted segs into the polyobject
|
||||
for (i = 0; i < numSegItems; ++i)
|
||||
@@ -566,7 +600,7 @@ static void Polyobj_findExplicit(polyobj_t *po)
|
||||
//
|
||||
static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
|
||||
{
|
||||
size_t i;
|
||||
size_t i, ii;
|
||||
polyobj_t *po = &PolyObjects[num];
|
||||
|
||||
// don't spawn a polyobject more than once
|
||||
@@ -590,8 +624,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
|
||||
// 1. Search segs for "line start" special with tag matching this
|
||||
// polyobject's id number. If found, iterate through segs which
|
||||
// share common vertices and record them into the polyobject.
|
||||
for (i = 0; i < numsegs; ++i)
|
||||
for (ii = 0; ii < KnownPolySidesCount; ii++)
|
||||
{
|
||||
i = KnownPolySides[ii];
|
||||
seg_t *seg = &segs[i];
|
||||
INT32 polyID, parentID;
|
||||
|
||||
@@ -1415,7 +1450,10 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings)
|
||||
{
|
||||
// update seg angles (used only by renderer)
|
||||
for (i = 0; i < po->segCount; ++i)
|
||||
{
|
||||
po->segs[i]->angle += delta;
|
||||
P_UpdateSegLightOffset(po->segs[i]);
|
||||
}
|
||||
|
||||
// update polyobject's angle
|
||||
po->angle += delta;
|
||||
@@ -1514,29 +1552,29 @@ void Polyobj_InitLevel(void)
|
||||
// the mobj_t pointers on a queue for use below.
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj_t *mo = (mobj_t *)th;
|
||||
|
||||
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM ||
|
||||
mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM)
|
||||
{
|
||||
mobj_t *mo = (mobj_t *)th;
|
||||
++numPolyObjects;
|
||||
|
||||
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM ||
|
||||
mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM)
|
||||
{
|
||||
++numPolyObjects;
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &spawnqueue);
|
||||
}
|
||||
else if (mo->info->doomednum == POLYOBJ_ANCHOR_DOOMEDNUM)
|
||||
{
|
||||
++numAnchors;
|
||||
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &spawnqueue);
|
||||
}
|
||||
else if (mo->info->doomednum == POLYOBJ_ANCHOR_DOOMEDNUM)
|
||||
{
|
||||
++numAnchors;
|
||||
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &anchorqueue);
|
||||
}
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &anchorqueue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,6 +1588,9 @@ void Polyobj_InitLevel(void)
|
||||
for (i = 0; i < numPolyObjects; ++i)
|
||||
PolyObjects[i].first = PolyObjects[i].next = numPolyObjects;
|
||||
|
||||
// [RH] Make this faster
|
||||
InitSideLists();
|
||||
|
||||
// setup polyobjects
|
||||
for (i = 0; i < numPolyObjects; ++i)
|
||||
{
|
||||
@@ -1558,6 +1599,9 @@ void Polyobj_InitLevel(void)
|
||||
Polyobj_spawnPolyObj(i, qitem->mo, qitem->mo->spawnpoint->angle);
|
||||
}
|
||||
|
||||
// [RH] Don't need the side lists anymore
|
||||
FreeSideLists();
|
||||
|
||||
// move polyobjects to spawn points
|
||||
for (i = 0; i < numAnchors; ++i)
|
||||
{
|
||||
@@ -1571,39 +1615,6 @@ void Polyobj_InitLevel(void)
|
||||
Polyobj_linkToBlockmap(&PolyObjects[i]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// haleyjd 02/22/06: temporary debug
|
||||
printf("DEBUG: numPolyObjects = %d\n", numPolyObjects);
|
||||
for (i = 0; i < numPolyObjects; ++i)
|
||||
{
|
||||
INT32 j;
|
||||
polyobj_t *po = &PolyObjects[i];
|
||||
|
||||
printf("polyobj %d:\n", i);
|
||||
printf("id = %d, first = %d, next = %d\n", po->id, po->first, po->next);
|
||||
printf("segCount = %d, numSegsAlloc = %d\n", po->segCount, po->numSegsAlloc);
|
||||
for (j = 0; j < po->segCount; ++j)
|
||||
printf("\tseg %d: %p\n", j, po->segs[j]);
|
||||
printf("numVertices = %d, numVerticesAlloc = %d\n", po->numVertices, po->numVerticesAlloc);
|
||||
for (j = 0; j < po->numVertices; ++j)
|
||||
{
|
||||
printf("\tvtx %d: (%d, %d) / orig: (%d, %d)\n",
|
||||
j, po->vertices[j]->x>>FRACBITS, po->vertices[j]->y>>FRACBITS,
|
||||
po->origVerts[j].x>>FRACBITS, po->origVerts[j].y>>FRACBITS);
|
||||
}
|
||||
printf("numLines = %d, numLinesAlloc = %d\n", po->numLines, po->numLinesAlloc);
|
||||
for (j = 0; j < po->numLines; ++j)
|
||||
printf("\tline %d: %p\n", j, po->lines[j]);
|
||||
printf("spawnSpot = (%d, %d)\n", po->spawnSpot.x >> FRACBITS, po->spawnSpot.y >> FRACBITS);
|
||||
printf("centerPt = (%d, %d)\n", po->centerPt.x >> FRACBITS, po->centerPt.y >> FRACBITS);
|
||||
printf("attached = %d, linked = %d, validcount = %d, isBad = %d\n",
|
||||
po->attached, po->linked, po->validcount, po->isBad);
|
||||
printf("blockbox: [%d, %d, %d, %d]\n",
|
||||
po->blockbox[BOXLEFT], po->blockbox[BOXRIGHT], po->blockbox[BOXBOTTOM],
|
||||
po->blockbox[BOXTOP]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// done with mobj queues
|
||||
M_QueueFree(&spawnqueue);
|
||||
M_QueueFree(&anchorqueue);
|
||||
@@ -1789,12 +1800,12 @@ void T_PolyObjMove(polymove_t *th)
|
||||
//
|
||||
void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
{
|
||||
mobj_t *mo2;
|
||||
mobj_t *target = NULL;
|
||||
mobj_t *waypoint = NULL;
|
||||
thinker_t *wp;
|
||||
mobj_t *mo2;
|
||||
fixed_t adjustx, adjusty, adjustz;
|
||||
fixed_t momx, momy, momz, dist;
|
||||
thinker_t *wp;
|
||||
INT32 start;
|
||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
polyobj_t *oldpo = po;
|
||||
@@ -1811,7 +1822,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
if (!po->thinker)
|
||||
po->thinker = &th->thinker;
|
||||
|
||||
// Find out target first.
|
||||
@@ -1826,11 +1837,14 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence && mo2->health == th->pointnum)
|
||||
{
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
if (mo2->threshold != th->sequence)
|
||||
continue;
|
||||
|
||||
if (mo2->health != th->pointnum)
|
||||
continue;
|
||||
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!target)
|
||||
@@ -1896,37 +1910,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n");
|
||||
|
||||
// Find next waypoint
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1)
|
||||
{
|
||||
if (mo2->health == target->health - 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo2->health == target->health + 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
||||
|
||||
if (!waypoint && th->wrap) // If specified, wrap waypoints
|
||||
{
|
||||
@@ -1936,35 +1920,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
th->stophere = true;
|
||||
}
|
||||
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1)
|
||||
{
|
||||
if (waypoint == NULL)
|
||||
waypoint = mo2;
|
||||
else if (mo2->health > waypoint->health)
|
||||
waypoint = mo2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo2->health == 0)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
||||
}
|
||||
else if (!waypoint && th->comeback) // Come back to the start
|
||||
{
|
||||
@@ -1973,36 +1929,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
if (!th->continuous)
|
||||
th->comeback = false;
|
||||
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1)
|
||||
{
|
||||
if (mo2->health == target->health - 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo2->health == target->health + 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2452,11 +2379,9 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
polyobj_t *po;
|
||||
polyobj_t *oldpo;
|
||||
polywaypoint_t *th;
|
||||
mobj_t *mo2;
|
||||
mobj_t *first = NULL;
|
||||
mobj_t *last = NULL;
|
||||
mobj_t *target = NULL;
|
||||
thinker_t *wp;
|
||||
INT32 start;
|
||||
|
||||
if (!(po = Polyobj_GetForNum(pwdata->polyObjNum)))
|
||||
@@ -2482,10 +2407,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
th->polyObjNum = pwdata->polyObjNum;
|
||||
th->speed = pwdata->speed;
|
||||
th->sequence = pwdata->sequence; // Used to specify sequence #
|
||||
if (pwdata->reverse)
|
||||
th->direction = -1;
|
||||
else
|
||||
th->direction = 1;
|
||||
th->direction = pwdata->reverse ? -1 : 1;
|
||||
|
||||
th->comeback = pwdata->comeback;
|
||||
th->continuous = pwdata->continuous;
|
||||
@@ -2493,44 +2415,8 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
th->stophere = false;
|
||||
|
||||
// Find the first waypoint we need to use
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1) // highest waypoint #
|
||||
{
|
||||
if (mo2->health == 0)
|
||||
last = mo2;
|
||||
else
|
||||
{
|
||||
if (first == NULL)
|
||||
first = mo2;
|
||||
else if (mo2->health > first->health)
|
||||
first = mo2;
|
||||
}
|
||||
}
|
||||
else // waypoint 0
|
||||
{
|
||||
if (mo2->health == 0)
|
||||
first = mo2;
|
||||
else
|
||||
{
|
||||
if (last == NULL)
|
||||
last = mo2;
|
||||
else if (mo2->health > last->health)
|
||||
last = mo2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
first = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
||||
last = (th->direction == -1) ? P_GetFirstWaypoint(th->sequence) : P_GetLastWaypoint(th->sequence);
|
||||
|
||||
if (!first)
|
||||
{
|
||||
@@ -2564,36 +2450,6 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
|
||||
// Find the actual target movement waypoint
|
||||
target = first;
|
||||
/*for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1) // highest waypoint #
|
||||
{
|
||||
if (mo2->health == first->health - 1)
|
||||
{
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // waypoint 0
|
||||
{
|
||||
if (mo2->health == first->health + 1)
|
||||
{
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!target)
|
||||
{
|
||||
|
||||
+143
-119
@@ -107,7 +107,7 @@ static inline void P_UnArchivePlayer(void)
|
||||
//
|
||||
// P_NetArchivePlayers
|
||||
//
|
||||
static void P_NetArchivePlayers(void)
|
||||
static void P_NetArchivePlayers(boolean resending)
|
||||
{
|
||||
INT32 i, j;
|
||||
UINT16 flags;
|
||||
@@ -117,6 +117,9 @@ static void P_NetArchivePlayers(void)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (resending)
|
||||
WRITESINT8(save_p, (SINT8)adminplayers[i]);
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
@@ -124,6 +127,9 @@ static void P_NetArchivePlayers(void)
|
||||
|
||||
// no longer send ticcmds, player name, skin, or color
|
||||
|
||||
if (resending)
|
||||
WRITESTRINGN(save_p, player_names[i], MAXPLAYERNAME);
|
||||
|
||||
WRITEANGLE(save_p, players[i].aiming);
|
||||
WRITEANGLE(save_p, players[i].awayviewaiming);
|
||||
WRITEINT32(save_p, players[i].awayviewtics);
|
||||
@@ -148,6 +154,13 @@ static void P_NetArchivePlayers(void)
|
||||
WRITEUINT16(save_p, players[i].flashpal);
|
||||
WRITEUINT16(save_p, players[i].flashcount);
|
||||
|
||||
if (resending)
|
||||
{
|
||||
WRITEUINT8(save_p, players[i].skincolor);
|
||||
WRITEINT32(save_p, players[i].skin);
|
||||
}
|
||||
|
||||
|
||||
WRITEUINT32(save_p, players[i].score);
|
||||
WRITEFIXED(save_p, players[i].dashspeed);
|
||||
WRITEINT32(save_p, players[i].dashtime);
|
||||
@@ -285,7 +298,7 @@ static void P_NetArchivePlayers(void)
|
||||
//
|
||||
// P_NetUnArchivePlayers
|
||||
//
|
||||
static void P_NetUnArchivePlayers(void)
|
||||
static void P_NetUnArchivePlayers(boolean resending)
|
||||
{
|
||||
INT32 i, j;
|
||||
UINT16 flags;
|
||||
@@ -295,6 +308,8 @@ static void P_NetUnArchivePlayers(void)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (resending)
|
||||
adminplayers[i] = (INT32)READSINT8(save_p);
|
||||
// Do NOT memset player struct to 0
|
||||
// other areas may initialize data elsewhere
|
||||
//memset(&players[i], 0, sizeof (player_t));
|
||||
@@ -305,6 +320,9 @@ static void P_NetUnArchivePlayers(void)
|
||||
// sending player names, skin and color should not be necessary at all!
|
||||
// (that data is handled in the server config now)
|
||||
|
||||
if (resending)
|
||||
READSTRINGN(save_p, player_names[i], MAXPLAYERNAME);
|
||||
|
||||
players[i].aiming = READANGLE(save_p);
|
||||
players[i].awayviewaiming = READANGLE(save_p);
|
||||
players[i].awayviewtics = READINT32(save_p);
|
||||
@@ -329,6 +347,12 @@ static void P_NetUnArchivePlayers(void)
|
||||
players[i].flashpal = READUINT16(save_p);
|
||||
players[i].flashcount = READUINT16(save_p);
|
||||
|
||||
if (resending)
|
||||
{
|
||||
players[i].skincolor = READUINT8(save_p);
|
||||
players[i].skin = READINT32(save_p);
|
||||
}
|
||||
|
||||
players[i].score = READUINT32(save_p);
|
||||
players[i].dashspeed = READFIXED(save_p); // dashing speed
|
||||
players[i].dashtime = READINT32(save_p); // dashing speed
|
||||
@@ -499,35 +523,16 @@ static void P_NetArchiveWorld(void)
|
||||
UINT8 *put;
|
||||
|
||||
// reload the map just to see difference
|
||||
mapsector_t *ms;
|
||||
mapsidedef_t *msd;
|
||||
maplinedef_t *mld;
|
||||
virtres_t* virt = vres_GetMap(lastloadedmaplumpnum);
|
||||
mapsector_t *ms = (mapsector_t*) vres_Find(virt, "SECTORS")->data;
|
||||
mapsidedef_t *msd = (mapsidedef_t*) vres_Find(virt, "SIDEDEFS")->data;
|
||||
maplinedef_t *mld = (maplinedef_t*) vres_Find(virt, "LINEDEFS")->data;
|
||||
const sector_t *ss = sectors;
|
||||
UINT8 diff, diff2;
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||
put = save_p;
|
||||
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can get the data from the relevant lumps
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
#define retrieve_mapdata(d, f)\
|
||||
d = Z_Malloc((f)->size, PU_CACHE, NULL); \
|
||||
M_Memcpy(d, wadData + (f)->filepos, (f)->size)
|
||||
retrieve_mapdata(ms, fileinfo + ML_SECTORS);
|
||||
retrieve_mapdata(mld, fileinfo + ML_LINEDEFS);
|
||||
retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS);
|
||||
#undef retrieve_mapdata
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
{
|
||||
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
|
||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
||||
}
|
||||
|
||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||
{
|
||||
diff = diff2 = 0;
|
||||
@@ -737,6 +742,7 @@ static void P_NetArchiveWorld(void)
|
||||
WRITEUINT16(put, 0xffff);
|
||||
R_ClearTextureNumCache(false);
|
||||
|
||||
vres_Free(virt);
|
||||
save_p = put;
|
||||
}
|
||||
|
||||
@@ -1874,7 +1880,7 @@ static void P_NetArchiveThinkers(void)
|
||||
continue;
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
||||
else if (th->function.acp1 != P_RemoveThinkerDelayed) // wait garbage collection
|
||||
I_Error("unknown thinker type %p", th->function.acp1);
|
||||
#endif
|
||||
}
|
||||
@@ -1899,8 +1905,11 @@ mobj_t *P_FindNewPosition(UINT32 oldposition)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)th;
|
||||
if (mobj->mobjnum == oldposition)
|
||||
return mobj;
|
||||
|
||||
if (mobj->mobjnum != oldposition)
|
||||
continue;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
CONS_Debug(DBG_GAMELOGIC, "mobj not found\n");
|
||||
return NULL;
|
||||
@@ -2899,12 +2908,13 @@ static void P_NetUnArchiveThinkers(void)
|
||||
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 == (actionf_p1)T_ExecutorDelay)
|
||||
{
|
||||
delay = (void *)currentthinker;
|
||||
if ((mobjnum = (UINT32)(size_t)delay->caller))
|
||||
delay->caller = P_FindNewPosition(mobjnum);
|
||||
}
|
||||
if (currentthinker->function.acp1 != (actionf_p1)T_ExecutorDelay)
|
||||
continue;
|
||||
|
||||
delay = (void *)currentthinker;
|
||||
|
||||
if ((mobjnum = (UINT32)(size_t)delay->caller))
|
||||
delay->caller = P_FindNewPosition(mobjnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3013,87 +3023,77 @@ static inline void P_FinishMobjs(void)
|
||||
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
mobj->info = &mobjinfo[mobj->type];
|
||||
}
|
||||
if (currentthinker->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
mobj->info = &mobjinfo[mobj->type];
|
||||
}
|
||||
}
|
||||
|
||||
static inline mobj_t *RelinkMobj(mobj_t **ptr)
|
||||
{
|
||||
UINT32 temp = (UINT32)(size_t)*ptr;
|
||||
*ptr = NULL;
|
||||
return P_SetTarget(ptr, P_FindNewPosition(temp));
|
||||
}
|
||||
|
||||
static void P_RelinkPointers(void)
|
||||
{
|
||||
thinker_t *currentthinker;
|
||||
mobj_t *mobj;
|
||||
UINT32 temp;
|
||||
|
||||
// use info field (value = oldposition) to relink mobjs
|
||||
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
if (currentthinker->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
|
||||
if (mobj->tracer)
|
||||
{
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
|
||||
if (mobj->tracer)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->tracer;
|
||||
mobj->tracer = NULL;
|
||||
if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->target)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->target;
|
||||
mobj->target = NULL;
|
||||
if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hnext)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->hnext;
|
||||
mobj->hnext = NULL;
|
||||
if (!P_SetTarget(&mobj->hnext, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hprev)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->hprev;
|
||||
mobj->hprev = NULL;
|
||||
if (!P_SetTarget(&mobj->hprev, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->capsule)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->capsule;
|
||||
mobj->player->capsule = NULL;
|
||||
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis1)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->axis1;
|
||||
mobj->player->axis1 = NULL;
|
||||
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis2)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->axis2;
|
||||
mobj->player->axis2 = NULL;
|
||||
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->awayviewmobj)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->awayviewmobj;
|
||||
mobj->player->awayviewmobj = NULL;
|
||||
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
|
||||
}
|
||||
if (!RelinkMobj(&mobj->tracer))
|
||||
CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->target)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->target))
|
||||
CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hnext)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->hnext))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hprev)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->hprev))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->capsule)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->player->capsule))
|
||||
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis1)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->player->axis1))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis2)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->player->axis2))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->awayviewmobj)
|
||||
{
|
||||
if (!RelinkMobj(&mobj->player->awayviewmobj))
|
||||
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3242,19 +3242,25 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
|
||||
playeringame[consoleplayer] = true;
|
||||
}
|
||||
|
||||
static void P_NetArchiveMisc(void)
|
||||
static void P_NetArchiveMisc(boolean resending)
|
||||
{
|
||||
UINT32 pig = 0;
|
||||
INT32 i;
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_MISC);
|
||||
|
||||
if (resending)
|
||||
WRITEUINT32(save_p, gametic);
|
||||
|
||||
WRITEINT16(save_p, gamemap);
|
||||
if (gamestate != GS_LEVEL)
|
||||
WRITEINT16(save_p, GS_WAITINGPLAYERS); // nice hack to put people back into waitingplayers
|
||||
else
|
||||
WRITEINT16(save_p, gamestate);
|
||||
|
||||
if (resending)
|
||||
WRITEINT16(save_p, gametype);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
pig |= (playeringame[i] != 0)<<i;
|
||||
WRITEUINT32(save_p, pig);
|
||||
@@ -3337,14 +3343,18 @@ static void P_NetArchiveMisc(void)
|
||||
WRITEUINT8(save_p, 0x2e);
|
||||
}
|
||||
|
||||
FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(void)
|
||||
FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(boolean reloading)
|
||||
{
|
||||
UINT32 pig;
|
||||
INT32 i;
|
||||
UINT8 *old_save_p;
|
||||
|
||||
if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
|
||||
I_Error("Bad $$$.sav at archive block Misc");
|
||||
|
||||
if (reloading)
|
||||
gametic = READUINT32(save_p);
|
||||
|
||||
gamemap = READINT16(save_p);
|
||||
|
||||
// gamemap changed; we assume that its map header is always valid,
|
||||
@@ -3354,10 +3364,14 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(void)
|
||||
|
||||
// tell the sound code to reset the music since we're skipping what
|
||||
// normally sets this flag
|
||||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
if (!reloading)
|
||||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
|
||||
G_SetGamestate(READINT16(save_p));
|
||||
|
||||
if (reloading)
|
||||
gametype = READINT16(save_p);
|
||||
|
||||
pig = READUINT32(save_p);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -3371,8 +3385,16 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(void)
|
||||
|
||||
encoremode = (boolean)READUINT8(save_p);
|
||||
|
||||
if (!P_SetupLevel(true))
|
||||
// FIXME: save_p should not be global!!!
|
||||
old_save_p = save_p;
|
||||
|
||||
if (!P_SetupLevel(true, reloading))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
save_p = old_save_p;
|
||||
|
||||
// get the time
|
||||
leveltime = READUINT32(save_p);
|
||||
@@ -3455,31 +3477,33 @@ void P_SaveGame(void)
|
||||
WRITEUINT8(save_p, 0x1d); // consistency marker
|
||||
}
|
||||
|
||||
void P_SaveNetGame(void)
|
||||
void P_SaveNetGame(boolean resending)
|
||||
{
|
||||
thinker_t *th;
|
||||
mobj_t *mobj;
|
||||
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
|
||||
|
||||
CV_SaveNetVars(&save_p, false);
|
||||
P_NetArchiveMisc();
|
||||
P_NetArchiveMisc(resending);
|
||||
|
||||
// Assign the mobjnumber for pointer tracking
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
mobj = (mobj_t *)th;
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
mobj->mobjnum = i++;
|
||||
}
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)th;
|
||||
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
|
||||
mobj->mobjnum = i++;
|
||||
}
|
||||
}
|
||||
|
||||
P_NetArchivePlayers();
|
||||
P_NetArchivePlayers(resending);
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
P_NetArchiveWorld();
|
||||
@@ -3514,12 +3538,12 @@ boolean P_LoadGame(INT16 mapoverride)
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean P_LoadNetGame(void)
|
||||
boolean P_LoadNetGame(boolean resending)
|
||||
{
|
||||
CV_LoadNetVars(&save_p);
|
||||
if (!P_NetUnArchiveMisc())
|
||||
if (!P_NetUnArchiveMisc(resending))
|
||||
return false;
|
||||
P_NetUnArchivePlayers();
|
||||
P_NetUnArchivePlayers(resending);
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
P_NetUnArchiveWorld();
|
||||
|
||||
+2
-2
@@ -22,9 +22,9 @@
|
||||
// These are the load / save game routines.
|
||||
|
||||
void P_SaveGame(void);
|
||||
void P_SaveNetGame(void);
|
||||
void P_SaveNetGame(boolean resending);
|
||||
boolean P_LoadGame(INT16 mapoverride);
|
||||
boolean P_LoadNetGame(void);
|
||||
boolean P_LoadNetGame(boolean resending);
|
||||
|
||||
mobj_t *P_FindNewPosition(UINT32 oldposition);
|
||||
|
||||
|
||||
+443
-743
File diff suppressed because it is too large.
Load diff
+6
-5
@@ -17,6 +17,9 @@
|
||||
#include "doomdata.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_defs.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
extern SINT8 midgamejoin;
|
||||
|
||||
// map md5, sent to players via PT_SERVERINFO
|
||||
extern unsigned char mapmd5[16];
|
||||
@@ -30,6 +33,7 @@ extern boolean levelloading;
|
||||
extern UINT8 levelfadecol;
|
||||
|
||||
extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
|
||||
extern virtres_t *curmapvirt;
|
||||
//
|
||||
// MAP used flats lookup table
|
||||
//
|
||||
@@ -55,11 +59,8 @@ extern size_t nummapthings;
|
||||
extern mapthing_t *mapthings;
|
||||
|
||||
void P_SetupLevelSky(INT32 skynum, boolean global);
|
||||
#ifdef SCANTHINGS
|
||||
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
|
||||
#endif
|
||||
void P_LoadThingsOnly(void);
|
||||
boolean P_SetupLevel(boolean skipprecip);
|
||||
boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate);
|
||||
#ifdef HWRENDER
|
||||
void HWR_LoadLevel(void);
|
||||
#endif
|
||||
@@ -87,11 +88,11 @@ SINT8 P_PartialAddGetStage(void);
|
||||
|
||||
boolean P_RunSOC(const char *socfilename);
|
||||
void P_WriteThings(lumpnum_t lump);
|
||||
void P_UpdateSegLightOffset(seg_t *li);
|
||||
size_t P_PrecacheLevelFlats(void);
|
||||
void P_AllocMapHeader(INT16 i);
|
||||
|
||||
// Needed for NiGHTS
|
||||
void P_ReloadRings(void);
|
||||
void P_DeleteGrades(INT16 i);
|
||||
void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
|
||||
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);
|
||||
|
||||
+60
-12
@@ -27,11 +27,51 @@
|
||||
static pslope_t *slopelist = NULL;
|
||||
static UINT16 slopecount = 0;
|
||||
|
||||
// Calculate light
|
||||
static void P_UpdateSlopeLightOffset(pslope_t *slope)
|
||||
{
|
||||
const boolean ceiling = (slope->normal.z < 0);
|
||||
const UINT8 contrast = 8;
|
||||
|
||||
fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
|
||||
fixed_t zMul = FRACUNIT;
|
||||
angle_t slopeDir = ANGLE_MAX;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
if (slope->normal.z == 0)
|
||||
{
|
||||
slope->lightOffset = 0;
|
||||
#ifdef HWRENDER
|
||||
slope->hwLightOffset = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
slopeDir = R_PointToAngle2(0, 0, abs(slope->normal.y), abs(slope->normal.x));
|
||||
if (ceiling == true)
|
||||
{
|
||||
slopeDir ^= ANGLE_180;
|
||||
}
|
||||
|
||||
zMul = min(FRACUNIT, abs(slope->zdelta)*3/2); // *3/2, to make 60 degree slopes match walls.
|
||||
contrastFixed = FixedMul(contrastFixed, zMul);
|
||||
extralight = -contrastFixed + FixedMul(FixedDiv(AngleFixed(slopeDir), ANGLE_90), (contrastFixed * 2));
|
||||
|
||||
// Between -2 and 2 for software, -8 and 8 for hardware
|
||||
slope->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#ifdef HWRENDER
|
||||
slope->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Calculate line normal
|
||||
void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
void P_CalculateSlopeNormal(pslope_t *slope)
|
||||
{
|
||||
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), -slope->d.x);
|
||||
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), -slope->d.y);
|
||||
|
||||
P_UpdateSlopeLightOffset(slope);
|
||||
}
|
||||
|
||||
// With a vertex slope that has its vertices set, configure relevant slope info
|
||||
@@ -89,18 +129,24 @@ static void P_ReconfigureVertexSlope(pslope_t *slope)
|
||||
slope->real_xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180;
|
||||
slope->real_zangle = InvAngle(R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta));
|
||||
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope"
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0) // Set some defaults for a non-sloped "slope"
|
||||
{
|
||||
slope->zangle = slope->xydirection = 0;
|
||||
slope->zdelta = slope->d.x = slope->d.y = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
slope->extent = extent;
|
||||
slope->xydirection = slope->real_xydirection;
|
||||
slope->zangle = slope->real_zangle;
|
||||
}
|
||||
|
||||
P_UpdateSlopeLightOffset(slope);
|
||||
}
|
||||
|
||||
// Recalculate dynamic slopes
|
||||
void P_RunDynamicSlopes(void) {
|
||||
void P_RunDynamicSlopes(void)
|
||||
{
|
||||
pslope_t *slope;
|
||||
|
||||
for (slope = slopelist; slope; slope = slope->next) {
|
||||
@@ -284,7 +330,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
|
||||
|
||||
// For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map!
|
||||
if(frontfloor || frontceil)
|
||||
if (frontfloor || frontceil)
|
||||
{
|
||||
line->frontsector->hasslope = true; // Tell the software renderer that we're sloped
|
||||
|
||||
@@ -308,7 +354,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
|
||||
// TODO: We take origin and point 's xy values and translate them to the center of an FOF!
|
||||
|
||||
if(frontfloor)
|
||||
if (frontfloor)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -369,7 +415,8 @@ void P_SpawnSlope_Line(int linenum)
|
||||
|
||||
P_CalculateSlopeNormal(fslope);
|
||||
}
|
||||
if(frontceil)
|
||||
|
||||
if (frontceil)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -416,7 +463,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
P_CalculateSlopeNormal(cslope);
|
||||
}
|
||||
}
|
||||
if(backfloor || backceil)
|
||||
if (backfloor || backceil)
|
||||
{
|
||||
line->backsector->hasslope = true; // Tell the software renderer that we're sloped
|
||||
|
||||
@@ -439,7 +486,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
direction.x = -direction.x;
|
||||
direction.y = -direction.y;
|
||||
|
||||
if(backfloor)
|
||||
if (backfloor)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -484,7 +531,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
|
||||
P_CalculateSlopeNormal(fslope);
|
||||
}
|
||||
if(backceil)
|
||||
if (backceil)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -634,7 +681,8 @@ pslope_t *P_SlopeById(UINT16 id)
|
||||
}
|
||||
|
||||
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
|
||||
void P_ResetDynamicSlopes(void) {
|
||||
void P_ResetDynamicSlopes(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
slopelist = NULL;
|
||||
@@ -934,4 +982,4 @@ void P_ButteredSlope(mobj_t *mo)
|
||||
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
||||
}
|
||||
|
||||
// EOF
|
||||
// EOF
|
||||
+131
-586
File diff suppressed because it is too large.
Load diff
+3
-1
@@ -32,7 +32,7 @@ void P_InitPicAnims(void);
|
||||
void P_SetupLevelFlatAnims(void);
|
||||
|
||||
// at map load
|
||||
void P_SpawnSpecials(INT32 fromnetsave);
|
||||
void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate);
|
||||
|
||||
// every tic
|
||||
void P_UpdateSpecials(void);
|
||||
@@ -454,4 +454,6 @@ void P_CalcHeight(player_t *player);
|
||||
|
||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
||||
|
||||
void P_StartQuake(tic_t time, fixed_t intensity, fixed_t radius);
|
||||
|
||||
#endif
|
||||
Loaded 100 of 145 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user