mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
1111
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00d7cd8a17 | ||
|
|
33f47d53c7 | ||
|
|
db2e20e59a | ||
|
|
67e89bdd8d | ||
|
|
c0e55de8f0 | ||
|
|
0d2c96ba09 | ||
|
|
02e76c00e9 | ||
|
|
7b8c035320 | ||
|
|
d41fa67715 | ||
|
|
7cfdf27b78 | ||
|
|
5cc6f5e4fd | ||
|
|
4b66b6e42c | ||
|
|
8edeb00886 | ||
|
|
c01b067c1a | ||
|
|
9940f9a752 | ||
|
|
9d75c04e99 | ||
|
|
56c1699aee | ||
|
|
a9e043f156 | ||
|
|
2296b885b5 | ||
|
|
36f1acb0ae | ||
|
|
add696869b | ||
|
|
a6066d79a9 | ||
|
|
bbeba26c70 | ||
|
|
b59580e84c | ||
|
|
a992f0687c | ||
|
|
5d5b377ad8 | ||
|
|
a971f3d768 | ||
|
|
5e943b843c | ||
|
|
67a5d89d47 | ||
|
|
f80dcd4a87 | ||
|
|
96d93607dd | ||
|
|
03d0b66214 | ||
|
|
719eb41cd8 | ||
|
|
f37ff6da68 | ||
|
|
3005e447d3 | ||
|
|
1dbe105933 | ||
|
|
04cac71fe9 | ||
|
|
4bee746897 | ||
|
|
4b34460f06 | ||
|
|
af574dacff | ||
|
|
e101736d8f | ||
|
|
f06ef36ca6 | ||
|
|
1491795451 | ||
|
|
0a17554c4f | ||
|
|
b287ecfef9 | ||
|
|
a7bac8679c | ||
|
|
f72d0a4cd5 | ||
|
|
d3e750edf7 | ||
|
|
7f9df9c09e | ||
|
|
89d7a512af | ||
|
|
61af589c21 | ||
|
|
270734b6f3 | ||
|
|
5704dce248 | ||
|
|
f993f7ced1 | ||
|
|
04436d634f | ||
|
|
e63505510b | ||
|
|
c5e3600bef | ||
|
|
acdc56272b | ||
|
|
7a44b33152 | ||
|
|
ec2542fa1e | ||
|
|
1eb544da58 | ||
|
|
71ba95081c | ||
|
|
b01b4a1778 | ||
|
|
e46ba43891 | ||
|
|
e2c5ff679c | ||
|
|
132ba60085 | ||
|
|
fdb7de88da | ||
|
|
44886e1ba5 | ||
|
|
63b9efeb3a | ||
|
|
e702ce2267 | ||
|
|
de0c889d10 | ||
|
|
e2fbbb5e19 | ||
|
|
27f58de890 | ||
|
|
c07d555346 | ||
|
|
2f635ad879 | ||
|
|
10d6940145 | ||
|
|
c6b8d515a4 | ||
|
|
34c61a7caa | ||
|
|
39d5580651 | ||
|
|
0d75839a9d | ||
|
|
35ac7d6afa | ||
|
|
b48b7f76ac | ||
|
|
a2afa2b67a | ||
|
|
0889d77f9f | ||
|
|
b72514fbaa | ||
|
|
475853afa3 | ||
|
|
047ae70637 | ||
|
|
2e58278eba | ||
|
|
26f33cba24 | ||
|
|
7846af6c24 | ||
|
|
aa0c39cb7d | ||
|
|
63909095f5 | ||
|
|
e537b1e133 | ||
|
|
09602a9ffa | ||
|
|
f7ebd3c636 | ||
|
|
52fb26169c | ||
|
|
ff7f028e0e | ||
|
|
1362e16c4c | ||
|
|
4178c4b65c | ||
|
|
f59fd543c9 | ||
|
|
0dddfbca74 | ||
|
|
0c025d96f6 | ||
|
|
4b662a3649 | ||
|
|
d6d69d9ac7 | ||
|
|
59c7c56dd4 | ||
|
|
c2a2f0727f | ||
|
|
a5078ce0aa | ||
|
|
36f2e4fd73 | ||
|
|
0458d83f94 | ||
|
|
c66a0b8e05 | ||
|
|
725b48d2b9 | ||
|
|
b7f4d00358 | ||
|
|
5a3fa6f576 | ||
|
|
28d23c56c0 | ||
|
|
7181e3d602 | ||
|
|
774f34dea4 | ||
|
|
7fa0a70c9e | ||
|
|
27f70fe135 | ||
|
|
1530e3556b | ||
|
|
b6914428ad | ||
|
|
d36f675f50 | ||
|
|
ca90928e08 | ||
|
|
f19a74b5c2 | ||
|
|
e8d72f5a50 | ||
|
|
be06149719 | ||
|
|
d0b3d8fe30 | ||
|
|
46ea3669d5 | ||
|
|
96c365ca86 | ||
|
|
f93e369d73 | ||
|
|
5983a47bc4 | ||
|
|
c4df09934c | ||
|
|
3b1597f2d9 | ||
|
|
56102ad328 | ||
|
|
8d2b02efb7 | ||
|
|
de60dfe106 | ||
|
|
7b293cd972 | ||
|
|
1ad8db2238 | ||
|
|
bce97dae91 | ||
|
|
721e71f860 | ||
|
|
a8510f8a51 | ||
|
|
f818572382 | ||
|
|
64d3a85dfa | ||
|
|
b9baca78ed | ||
|
|
e12b4c3840 | ||
|
|
b464f2a558 | ||
|
|
abd020529d | ||
|
|
d4b6ae7b8d | ||
|
|
5a92218ce6 | ||
|
|
38a42dd2e4 | ||
|
|
e7b0c695ea | ||
|
|
a77a92b8f0 | ||
|
|
bfdf0c5b48 | ||
|
|
5fc6743d4c | ||
|
|
b124ff648b | ||
|
|
5c032efc72 | ||
|
|
01a242f269 | ||
|
|
e96e973a54 | ||
|
|
cebcd67cfc | ||
|
|
41adc2f68b | ||
|
|
f7126d9c9c | ||
|
|
4efaaf4523 | ||
|
|
ba9c45714a | ||
|
|
99aa1e74a0 | ||
|
|
3761e36f4c | ||
|
|
271044cb70 | ||
|
|
7d4f9f0fb5 | ||
|
|
8651bb3a0b | ||
|
|
1a4917ca2b | ||
|
|
9d705df121 | ||
|
|
ceebf42868 | ||
|
|
a1f100d0a3 | ||
|
|
8555140cf6 | ||
|
|
77dacf4307 | ||
|
|
6dffec5d23 | ||
|
|
14e0a7f257 | ||
|
|
9473a345fc | ||
|
|
20d6d6116f | ||
|
|
e226c8e7f4 | ||
|
|
c2a1ff57c9 | ||
|
|
3b84da5af0 | ||
|
|
ab17ff4d40 | ||
|
|
6a6a3ac822 | ||
|
|
47faa1c364 | ||
|
|
b2a443a225 | ||
|
|
6d4fb01f67 | ||
|
|
7096cd3d11 | ||
|
|
05f95e05ee | ||
|
|
1cc80c2841 | ||
|
|
17decc5654 | ||
|
|
e3e7bbfd05 | ||
|
|
e8e37e8620 | ||
|
|
10d94a24e8 | ||
|
|
6d273e9495 | ||
|
|
650c8010bc | ||
|
|
1f9d15d20e | ||
|
|
b40359cd30 | ||
|
|
40f0b0b279 | ||
|
|
4b40d32f3d | ||
|
|
a4f587110d | ||
|
|
32f4c944e6 | ||
|
|
8f8a8486a1 | ||
|
|
99c4490bb0 | ||
|
|
76d4ba4479 | ||
|
|
6cc6bd9119 | ||
|
|
05b47ecfec | ||
|
|
5ddd75b11e | ||
|
|
96d93caf1b | ||
|
|
7630b1669c | ||
|
|
0e7bdf926d | ||
|
|
274aa3cf93 | ||
|
|
38c1682975 | ||
|
|
170266436b | ||
|
|
13a3308e23 | ||
|
|
a3ca4f4ef7 | ||
|
|
b0e8ce130e | ||
|
|
d89a92c6e7 | ||
|
|
51ef10452c | ||
|
|
4d643bfe6b | ||
|
|
ffaca21fdd | ||
|
|
ec0a7e930e | ||
|
|
fba4e77284 | ||
|
|
b53a2b9cd3 | ||
|
|
266737ff84 | ||
|
|
d5829ad173 | ||
|
|
8279944008 | ||
|
|
8549f3c71a | ||
|
|
1375bab654 | ||
|
|
f514d2b25a | ||
|
|
27ac3b0c05 | ||
|
|
afbb428349 | ||
|
|
ed5cd1d06b | ||
|
|
1de215abd5 | ||
|
|
f7d04a9311 | ||
|
|
d30cc69e36 | ||
|
|
47869f4f32 | ||
|
|
03c24467ea | ||
|
|
74225ecac9 | ||
|
|
8546cac0c0 | ||
|
|
dbf5d60ab2 | ||
|
|
834e4321a7 | ||
|
|
2db4d1c9c2 | ||
|
|
8694bb1a29 | ||
|
|
9e9b6ada2d | ||
|
|
c18119c729 | ||
|
|
d41514c78e | ||
|
|
9a8202cfd0 | ||
|
|
e2cfb8017a | ||
|
|
e12839e11e | ||
|
|
f168b7aab7 | ||
|
|
cfec9106be | ||
|
|
9824b21218 | ||
|
|
0eca97a967 | ||
|
|
abfb3b7298 | ||
|
|
9f4b691a98 | ||
|
|
951ec34a36 | ||
|
|
680edc2da3 | ||
|
|
3085dd4b1c | ||
|
|
d5ab81c947 | ||
|
|
9ead43eccd | ||
|
|
cd15f39847 | ||
|
|
c0b2e1b1ec | ||
|
|
1f40c55c1a | ||
|
|
3572226340 | ||
|
|
93524920bd | ||
|
|
cdb6ceb1f1 | ||
|
|
99be9d044d | ||
|
|
65fc924f92 | ||
|
|
8116b15105 | ||
|
|
169e4e8518 | ||
|
|
2cc225ba3f | ||
|
|
c2b601bd5c | ||
|
|
67b86f7377 | ||
|
|
3c6f77811a | ||
|
|
dce9388543 | ||
|
|
5f7684a795 | ||
|
|
05b509d813 | ||
|
|
ba9353ee54 | ||
|
|
21c28412e3 | ||
|
|
407c670e74 | ||
|
|
155907b7d0 | ||
|
|
442ea06112 | ||
|
|
770095c84c | ||
|
|
4edb31de72 | ||
|
|
345f7b4bc3 | ||
|
|
44b04ddb93 | ||
|
|
bce99b342e | ||
|
|
2449c9abb4 | ||
|
|
bc369d5566 | ||
|
|
6939a6c05b | ||
|
|
41156280df | ||
|
|
7b730af602 | ||
|
|
22869bd825 | ||
|
|
b8af21a85b | ||
|
|
1b7863f1d3 | ||
|
|
a386e6ae74 | ||
|
|
45b6069d74 | ||
|
|
b3bc073a73 | ||
|
|
9d342e4133 | ||
|
|
86b9f2f1f8 | ||
|
|
de4d3ea105 | ||
|
|
b8c080bb8e | ||
|
|
0dbed68b2a | ||
|
|
5b633a3342 | ||
|
|
0c1a0951d7 | ||
|
|
dfd4f33c1f | ||
|
|
8822a79e42 | ||
|
|
fc26bd16da | ||
|
|
f69d5881ed | ||
|
|
80545a8a96 | ||
|
|
c2a526db7d | ||
|
|
e67a50beca | ||
|
|
c0d76ee6c9 | ||
|
|
02414bc9d6 | ||
|
|
94a1b2d275 | ||
|
|
5f636a00f1 | ||
|
|
8ccf735e27 | ||
|
|
016d01c345 | ||
|
|
cf3a4975da | ||
|
|
6993a136c0 | ||
|
|
cc4fb68ea6 | ||
|
|
54ebd3ad25 | ||
|
|
11c87b9934 | ||
|
|
22586a2fb4 | ||
|
|
6120956cd6 | ||
|
|
d9808e04f6 | ||
|
|
97c7fb934d | ||
|
|
a679a8f597 | ||
|
|
62575f7e23 | ||
|
|
66e3333392 | ||
|
|
434059b5a2 | ||
|
|
cbdca14ea4 | ||
|
|
0db2ca515f | ||
|
|
0b2c715162 | ||
|
|
17391ffc18 | ||
|
|
2560ae1109 | ||
|
|
4c16a66ba9 | ||
|
|
031f448be2 | ||
|
|
54f63a1357 | ||
|
|
7445380789 | ||
|
|
b9fc819ce2 | ||
|
|
c092173f36 | ||
|
|
b98c4e8b75 | ||
|
|
34179e931a | ||
|
|
cc3e1fd071 | ||
|
|
0bf1baac94 | ||
|
|
02b5fd1496 | ||
|
|
583e03890f | ||
|
|
af7ba40eb4 | ||
|
|
67e79b3177 | ||
|
|
554de8e375 | ||
|
|
5c88548cab | ||
|
|
aac68877ec | ||
|
|
b9a95040f7 | ||
|
|
9a98a31b1b | ||
|
|
c90151f94a | ||
|
|
65a31a1676 | ||
|
|
1435ef0752 | ||
|
|
2cc02d72e3 | ||
|
|
6008752531 | ||
|
|
aeb5fd2789 | ||
|
|
33203d244a | ||
|
|
6f3a91c53f | ||
|
|
769d3a4d89 | ||
|
|
2da096f845 | ||
|
|
f33a638c61 | ||
|
|
12033c664b | ||
|
|
9ee90c41b7 | ||
|
|
e900e56e1a | ||
|
|
39550294bd | ||
|
|
b323aa89b9 | ||
|
|
35aaf68496 | ||
|
|
c178b00fc1 | ||
|
|
7e65e47acc | ||
|
|
cbaf0e5cc3 | ||
|
|
5fd345352e | ||
|
|
9c85ac2835 | ||
|
|
28120ca20c | ||
|
|
6011414dcc | ||
|
|
52a939531a | ||
|
|
18933d071a | ||
|
|
03c0f38796 | ||
|
|
771571be7e | ||
|
|
74d1c139ed | ||
|
|
3aaf81208b | ||
|
|
b37058615f | ||
|
|
25e3fe0f80 | ||
|
|
133a331fc8 | ||
|
|
6d4a7ec889 | ||
|
|
2e8a49a05b | ||
|
|
9f44258319 | ||
|
|
32450e2984 | ||
|
|
5e968aac93 | ||
|
|
3d98b9aeae | ||
|
|
38682babc3 | ||
|
|
b43417882f | ||
|
|
47e03f4a32 | ||
|
|
fbcb83b9db | ||
|
|
de43cc3488 | ||
|
|
e1df65d0e4 | ||
|
|
56ff4f45c6 | ||
|
|
983d9cb94a | ||
|
|
f0b8f077d5 | ||
|
|
f4bd24d720 | ||
|
|
b12b60d577 | ||
|
|
94038d3822 | ||
|
|
076cbcf818 | ||
|
|
f3fa70b18b | ||
|
|
7a3b09e132 | ||
|
|
0383415a3b | ||
|
|
6542269c77 | ||
|
|
e516f97d49 | ||
|
|
d4f1e1132c | ||
|
|
664df3af89 | ||
|
|
2a1b807bdb | ||
|
|
27e87c6a0f | ||
|
|
06f0b169e4 | ||
|
|
2e833278ea | ||
|
|
f2158a72fa | ||
|
|
c81d8fdeec | ||
|
|
5e92431d02 | ||
|
|
057ef78c09 | ||
|
|
2ee628829a | ||
|
|
1a8acd364b | ||
|
|
be79cb4991 | ||
|
|
6cf641cb96 | ||
|
|
884de6da24 | ||
|
|
44f8eab341 | ||
|
|
976b86d607 | ||
|
|
f53e3a9143 | ||
|
|
585981e24b | ||
|
|
b91c8cd616 | ||
|
|
01c5a62b1a | ||
|
|
890b1bee36 | ||
|
|
780f5e9d09 | ||
|
|
f675bde3db | ||
|
|
5b1ceed359 | ||
|
|
2e08994ede | ||
|
|
49ce1e23a5 | ||
|
|
07b1ea4a3a | ||
|
|
db1a9508b6 | ||
|
|
c9adb19837 | ||
|
|
84c2ad3461 | ||
|
|
0b742d2301 | ||
|
|
0de4a7d9ae | ||
|
|
cf2ef994e9 | ||
|
|
d21f8d106f | ||
|
|
087f141218 | ||
|
|
f6fbd4aa1d | ||
|
|
7678d0b0c8 | ||
|
|
5e9bf597c5 | ||
|
|
0715c8d504 | ||
|
|
468fd91442 | ||
|
|
9eb42469a9 | ||
|
|
822828f412 | ||
|
|
a92e6bfb1d | ||
|
|
4ce4880c70 | ||
|
|
fb3c9dd696 | ||
|
|
f1e808aa62 | ||
|
|
78deb06ea2 | ||
|
|
cf949cc6ad | ||
|
|
8b8f325e71 | ||
|
|
24c94fc72c | ||
|
|
5294e3e1ee | ||
|
|
72af11bb6d | ||
|
|
ccda696429 | ||
|
|
8a10fb3181 | ||
|
|
9a1bfaf9c1 | ||
|
|
1fb668de99 | ||
|
|
5180dc1146 | ||
|
|
cb5bcc3369 | ||
|
|
8edf0d43ed | ||
|
|
1529b99932 | ||
|
|
85920f2151 | ||
|
|
a1259d02a8 | ||
|
|
867a8a643f | ||
|
|
9990637240 | ||
|
|
95a8b8c730 | ||
|
|
75a514b5f9 | ||
|
|
b559c0959b | ||
|
|
48cc61733c | ||
|
|
b77b9adf39 | ||
|
|
8124f3d81d | ||
|
|
23521c1e3b | ||
|
|
064ab52578 | ||
|
|
09db476623 | ||
|
|
3d02219bd7 | ||
|
|
eb4b7c03e9 | ||
|
|
02718dd5eb | ||
|
|
6d7343b17d | ||
|
|
6a1d3d3862 | ||
|
|
06ef9910c4 | ||
|
|
ed0821391e | ||
|
|
8826c47460 | ||
|
|
3810491748 | ||
|
|
6c2aea0db5 | ||
|
|
560ab1a5b0 | ||
|
|
35a8b8bb08 | ||
|
|
66db559d2c | ||
|
|
1a70dbca7a | ||
|
|
8fc13dc9d7 | ||
|
|
cc624e61cd | ||
|
|
aa25b5a591 | ||
|
|
be186cd01d | ||
|
|
c19d78f82f | ||
|
|
0dc516368a | ||
|
|
0b1bfe8003 | ||
|
|
2706a10aca | ||
|
|
dcafaa6780 | ||
|
|
dac9c92928 | ||
|
|
e7ff18e13d | ||
|
|
9bafc782f9 | ||
|
|
8cd76d8d41 | ||
|
|
98f337f701 | ||
|
|
fe7ff55ea2 | ||
|
|
8a811104b5 | ||
|
|
f848621a1b | ||
|
|
414ce88c58 | ||
|
|
25e3cd89c4 | ||
|
|
11034e3376 | ||
|
|
aadd6ca7c1 | ||
|
|
3bf44ae5b1 | ||
|
|
673ac40dba | ||
|
|
737496d65c | ||
|
|
95ab9dffa9 | ||
|
|
7c0008c211 | ||
|
|
2f1ca39df8 | ||
|
|
060cfbc7ae | ||
|
|
c1a599ac0f | ||
|
|
90d350816c | ||
|
|
014b7e4300 | ||
|
|
4c350109dd | ||
|
|
90943b80c2 | ||
|
|
013997a0dd | ||
|
|
9fce479b91 | ||
|
|
c5ee5f5e33 | ||
|
|
a1699f9edd | ||
|
|
89f4e8985b | ||
|
|
7db0e1c4f1 | ||
|
|
41bf8dd1d4 | ||
|
|
ee761c8dfc | ||
|
|
86fd3cc17d | ||
|
|
cfb53105be | ||
|
|
c9ca0cab25 | ||
|
|
3ac9167ac7 | ||
|
|
23fcd2968e | ||
|
|
51968f1a77 | ||
|
|
e7db3e6bef | ||
|
|
76ddbc8c2a | ||
|
|
0bde3e5d8f | ||
|
|
f20e481ba2 | ||
|
|
d4cc6c215e | ||
|
|
2ffc8487c4 | ||
|
|
4e5c2a89d8 | ||
|
|
9246a2f74d | ||
|
|
915a9270c9 | ||
|
|
29abf1f51c | ||
|
|
b0b03a7f7d | ||
|
|
7af7b91b56 | ||
|
|
c77a70bfda | ||
|
|
1e80a663af | ||
|
|
fcd9f2b8fb | ||
|
|
6a8d45c93d | ||
|
|
a9179e2db4 | ||
|
|
c91bf775bb | ||
|
|
5d6b9be53c | ||
|
|
ba4d5c7132 | ||
|
|
48d8822bd9 | ||
|
|
657eed8106 | ||
|
|
a5f5e912c3 | ||
|
|
81c1002211 | ||
|
|
94ddf755da | ||
|
|
31d6469fde | ||
|
|
5efb4abb9f | ||
|
|
bc633ce96e | ||
|
|
d121b449d3 | ||
|
|
772865c027 | ||
|
|
963fcf87b4 | ||
|
|
720391f8f4 | ||
|
|
d14ace67b0 | ||
|
|
85eab173d2 | ||
|
|
bdd1f5ff9f | ||
|
|
e704b86f72 | ||
|
|
d973756d7f | ||
|
|
ee5e08868d | ||
|
|
3e9707bd0b | ||
|
|
8b7917d084 | ||
|
|
f24633cba2 | ||
|
|
aebae0185a | ||
|
|
4808e4557a | ||
|
|
b6e4ccfd05 | ||
|
|
9df31c7d79 | ||
|
|
5992a55a77 | ||
|
|
6281b057ee | ||
|
|
948ccf959e | ||
|
|
f1cc46a562 | ||
|
|
f67596bc5e | ||
|
|
fe87aed445 | ||
|
|
c9631721c5 | ||
|
|
7015ffa0b2 | ||
|
|
be743859c0 | ||
|
|
0ebf630314 | ||
|
|
7a37841292 | ||
|
|
0c93ba4501 | ||
|
|
b91be33343 | ||
|
|
0cc4ebc9ef | ||
|
|
7f79f08d32 | ||
|
|
4c55c88b22 | ||
|
|
0666011353 | ||
|
|
015f4a5ef6 | ||
|
|
5ad2dcf4b5 | ||
|
|
5b4c5f388c | ||
|
|
cb51bf1eb5 | ||
|
|
9103c5f217 | ||
|
|
18f82eab12 | ||
|
|
7d08f2fecb | ||
|
|
98f27b88dd | ||
|
|
719825f80d | ||
|
|
af37fc1b1b | ||
|
|
8b43ed823c | ||
|
|
2f307a06fe | ||
|
|
da4d3ce2af | ||
|
|
f7a8bf844b | ||
|
|
9abc540362 | ||
|
|
dfb8d4cadf | ||
|
|
286a7fca3e | ||
|
|
77a8ab89e8 | ||
|
|
5e3ca2f514 | ||
|
|
c817826d45 | ||
|
|
87fa567516 | ||
|
|
5bd74f4ab3 | ||
|
|
79adc6dde8 | ||
|
|
16db9601ac | ||
|
|
15fe7f2ffe | ||
|
|
7121dd75d5 | ||
|
|
1e4447111a | ||
|
|
dbd42fca7c | ||
|
|
6d999b5b9d | ||
|
|
cd5faf4e8c | ||
|
|
0c8b78505f | ||
|
|
a482a9a4a5 | ||
|
|
f0feac6f70 | ||
|
|
96852832cc | ||
|
|
84423fbcf3 | ||
|
|
8bdc2c1a9f | ||
|
|
875b735417 | ||
|
|
de5f86bd79 | ||
|
|
eb1bd98ee8 | ||
|
|
2a69aaa23b | ||
|
|
24de2cb225 | ||
|
|
77d60f603c | ||
|
|
1302964fbf | ||
|
|
7f36e6dc8f | ||
|
|
8fcee4ebe2 | ||
|
|
e79c4fd923 | ||
|
|
943969aac1 | ||
|
|
7cc7000f88 | ||
|
|
629b7558f7 | ||
|
|
2036fb95cc | ||
|
|
e05276ea1e | ||
|
|
fdb2de32e7 | ||
|
|
b4eb17bd7f | ||
|
|
0920dc10ed | ||
|
|
fa24bc0b39 | ||
|
|
4cd2a011db | ||
|
|
cb3085e58c | ||
|
|
d320ebf724 | ||
|
|
01cb760ae5 | ||
|
|
3c64b07134 | ||
|
|
9c7b1a1292 | ||
|
|
d7f721f3b1 | ||
|
|
b399e066f7 | ||
|
|
4def2aebce | ||
|
|
fc2f05c747 | ||
|
|
ea1cc6ca27 | ||
|
|
cabc75bfe5 | ||
|
|
3b912c0ca3 | ||
|
|
ab316e895f | ||
|
|
5c1a6ef841 | ||
|
|
a4e623db23 | ||
|
|
d599cc1d6b | ||
|
|
67406e5952 | ||
|
|
3ac6b9aa80 | ||
|
|
2f33c72ba7 | ||
|
|
1a1f81f86d | ||
|
|
9f9f4dae6c | ||
|
|
5d9af246c5 | ||
|
|
7c70f212ba | ||
|
|
f95777ebe3 | ||
|
|
fc12d0a5b7 | ||
|
|
0a4ca2f858 | ||
|
|
fbf44b51e0 | ||
|
|
321c1cd30e | ||
|
|
e63ea3738b | ||
|
|
0adb576247 | ||
|
|
b67289e52a | ||
|
|
1ea70f7122 | ||
|
|
0512409e18 | ||
|
|
39adc73583 | ||
|
|
4bd18224fe | ||
|
|
961c88132b | ||
|
|
ba4e5132ef | ||
|
|
251285cacc | ||
|
|
a9219ca129 | ||
|
|
616b19772e | ||
|
|
4485f12c24 | ||
|
|
fe352da2a2 | ||
|
|
1d8f54cf29 | ||
|
|
5ec562973b | ||
|
|
dc934368ab | ||
|
|
b33f468e38 | ||
|
|
428e5d67c9 | ||
|
|
6a5bf64aeb | ||
|
|
5a919c3e49 | ||
|
|
2c8d1795e6 | ||
|
|
be03d7e3f1 | ||
|
|
ad31fc80be | ||
|
|
63f00de6e0 | ||
|
|
c35da651ea | ||
|
|
6ba239d6a0 | ||
|
|
edd046798a | ||
|
|
09adeaea8a | ||
|
|
62b5d676cd | ||
|
|
61d9326eb8 | ||
|
|
5e54017f15 | ||
|
|
0cb0206db2 | ||
|
|
d4f6ec98b9 | ||
|
|
35dbaac407 | ||
|
|
c695230883 | ||
|
|
e2f1229d79 | ||
|
|
bdb1569898 | ||
|
|
4f18bbd624 | ||
|
|
b78f77f0a0 | ||
|
|
3427549f9b | ||
|
|
f711df0fd1 | ||
|
|
5119664e14 | ||
|
|
6e4021888d | ||
|
|
03123b1437 | ||
|
|
47060c5c9b | ||
|
|
0c628834c5 | ||
|
|
b4a20998e1 | ||
|
|
b4d35f6afe | ||
|
|
144a30b20f | ||
|
|
fe5c1f3bad | ||
|
|
763f714864 | ||
|
|
26217893fd | ||
|
|
ce24e12816 | ||
|
|
570755309c | ||
|
|
4f22d45411 | ||
|
|
26db4ff799 | ||
|
|
aa49d10143 | ||
|
|
d5168e3592 | ||
|
|
d8a1a68c16 | ||
|
|
70ecaa5d86 | ||
|
|
bdf9f7008b | ||
|
|
1637424c35 | ||
|
|
26b7f17c41 | ||
|
|
fff260ae8e | ||
|
|
5dcf9f7880 | ||
|
|
bf6391e4c2 | ||
|
|
87774d9ce8 | ||
|
|
b4abe9f24d | ||
|
|
3f1880d22c | ||
|
|
9e61bb1df9 | ||
|
|
26dfa5f47f | ||
|
|
e302a90a1e | ||
|
|
bec2409fba | ||
|
|
812e480bb3 | ||
|
|
d704a450cb | ||
|
|
4ea1424e64 | ||
|
|
0272c785dd | ||
|
|
8e83b3f502 | ||
|
|
2d495a3c15 | ||
|
|
e57d4ff5f2 | ||
|
|
6e0200d27e | ||
|
|
38eff95a7f | ||
|
|
d6f28ceb97 | ||
|
|
b8375fa785 | ||
|
|
d5f2b68044 | ||
|
|
afd60862ab | ||
|
|
deaad91241 | ||
|
|
6842f9d910 | ||
|
|
eb862504f4 | ||
|
|
ec427000eb | ||
|
|
87dd770d93 | ||
|
|
39efcaf386 | ||
|
|
a58ae3d02e | ||
|
|
2f0c86dd01 | ||
|
|
98e1d6b56f | ||
|
|
6d8ca2c14b | ||
|
|
d448ff3632 | ||
|
|
978f5f363f | ||
|
|
51a6901dae | ||
|
|
da0dbe84b3 | ||
|
|
6fc6267fca | ||
|
|
f5f0713345 | ||
|
|
054d745ece | ||
|
|
53492408c9 | ||
|
|
506ee1f517 | ||
|
|
58b171ce76 | ||
|
|
673f10485b | ||
|
|
1323b85c9d | ||
|
|
f80572c172 | ||
|
|
25c6d6340c | ||
|
|
33034e581b | ||
|
|
88f71ef237 | ||
|
|
69b0a7a250 | ||
|
|
cd7ce4e88b | ||
|
|
c37055ea42 | ||
|
|
b7a51a86b5 | ||
|
|
af9eea721c | ||
|
|
6ba6544036 | ||
|
|
2835c6950b | ||
|
|
0562982e02 | ||
|
|
3dd6ce5bb7 | ||
|
|
04f77b4e7c | ||
|
|
be97108d6c | ||
|
|
adbb60d8bc | ||
|
|
28a408deee | ||
|
|
6208959b49 | ||
|
|
ee75c69ab9 | ||
|
|
548faf84bc | ||
|
|
90ea4099fb | ||
|
|
e1416453a8 | ||
|
|
d18a78ef05 | ||
|
|
8406bfada6 | ||
|
|
23742e8261 | ||
|
|
f75be11102 | ||
|
|
1d453b80f2 | ||
|
|
b290f5281a | ||
|
|
89a7c1e0f4 | ||
|
|
6f32344d45 | ||
|
|
fb37f654f0 | ||
|
|
9c0dbb7acb | ||
|
|
5c12c0ef48 | ||
|
|
e55577111e | ||
|
|
61891ed5ec | ||
|
|
84e6b6eabe | ||
|
|
1f5444b850 | ||
|
|
d12f0c7ae9 | ||
|
|
3736999bdc | ||
|
|
93bb980ff3 | ||
|
|
4862747454 | ||
|
|
42b5befef0 | ||
|
|
78cda09d2c | ||
|
|
b06a4a5349 | ||
|
|
21d258925d | ||
|
|
d6399427ff | ||
|
|
4bf6b83e93 | ||
|
|
07d6f2bff9 | ||
|
|
1bc83969ac | ||
|
|
aa7fc2d713 | ||
|
|
4a4268e77d | ||
|
|
66019a11ca | ||
|
|
219c7541f8 | ||
|
|
09d116f667 | ||
|
|
8c521c771b | ||
|
|
cfa7e2d7c8 | ||
|
|
6d13cce780 | ||
|
|
d1f6caaaaa | ||
|
|
871b316add | ||
|
|
9eb55188d5 | ||
|
|
9b7fff7e99 | ||
|
|
53143dee9c | ||
|
|
a6bae2c557 | ||
|
|
55aea5cf13 | ||
|
|
643a1aa230 | ||
|
|
fe03b667cd | ||
|
|
570e4cb1e6 | ||
|
|
2c45dbbb5f | ||
|
|
307106f983 | ||
|
|
68c51f242a | ||
|
|
ad1c5055d4 | ||
|
|
3abccfa76c | ||
|
|
42683318f7 | ||
|
|
f4ba5d0bb2 | ||
|
|
8d70f8c15f | ||
|
|
73f924163c | ||
|
|
83a57be996 | ||
|
|
50cc1331ae | ||
|
|
1b5f722967 | ||
|
|
33ab6d34ef | ||
|
|
d7fd6b4454 | ||
|
|
028bfecc70 | ||
|
|
e6b801595b | ||
|
|
d3f38e26bc | ||
|
|
d4305fbd85 | ||
|
|
70059a94d6 | ||
|
|
262c3178e9 | ||
|
|
91dd16167b | ||
|
|
862d6f43db | ||
|
|
966ec358e9 | ||
|
|
6ed6ecbfb8 | ||
|
|
1062040fbf | ||
|
|
0f01a1bd4c | ||
|
|
0b1ea9a58d | ||
|
|
19c1520dba | ||
|
|
3032a0f5d9 | ||
|
|
fbe14f5a5e | ||
|
|
c4b763680c | ||
|
|
60fca98974 | ||
|
|
15dbb9e8b4 | ||
|
|
9bce69ef79 | ||
|
|
fdcaebfad3 | ||
|
|
ef0c0e994b | ||
|
|
249b8496e3 | ||
|
|
7c944ed2a3 | ||
|
|
aab688222c | ||
|
|
acc7fa2b16 | ||
|
|
1ccfa433d6 | ||
|
|
a832c11585 | ||
|
|
10340678cb | ||
|
|
a82b7862d8 | ||
|
|
2ccbedd071 | ||
|
|
280b979d09 | ||
|
|
8a2af2b13b | ||
|
|
400e950190 | ||
|
|
36ac0cb908 | ||
|
|
ae062bcc0b | ||
|
|
4d0f978e1c | ||
|
|
4f7744cf36 | ||
|
|
acf1aa60ac | ||
|
|
e44de24957 | ||
|
|
6e42152761 | ||
|
|
251f52796c | ||
|
|
c5f9ba424c | ||
|
|
d23e80bdef | ||
|
|
ddd6ce2cf6 | ||
|
|
f2e2297e9f | ||
|
|
0253d298e9 | ||
|
|
f6d26f915a | ||
|
|
941faf9ab9 | ||
|
|
d0af5c2169 | ||
|
|
05769b3ffe | ||
|
|
6a3cf80be0 | ||
|
|
55c8720e90 | ||
|
|
e461625622 | ||
|
|
f598aafeb0 | ||
|
|
71e948278b | ||
|
|
ee57fa59ca | ||
|
|
dbe8e071bb | ||
|
|
27f2f168dc | ||
|
|
beafe688bb | ||
|
|
01c783e27d | ||
|
|
c7b8cd7021 | ||
|
|
6ca5bdcffa | ||
|
|
18b2922455 | ||
|
|
de28613166 | ||
|
|
9a3a1b051e | ||
|
|
8650ee98bd | ||
|
|
a4889e49e9 | ||
|
|
fcb28b51f1 | ||
|
|
7938c36df2 | ||
|
|
ceea88037c | ||
|
|
d17ea1d102 | ||
|
|
db5767b18a | ||
|
|
04fc426d90 | ||
|
|
4524583f06 | ||
|
|
f445aedaf1 | ||
|
|
666cbd4bc5 | ||
|
|
99446022fc | ||
|
|
d37828e00a | ||
|
|
818b6a40ac | ||
|
|
3bc9a692af | ||
|
|
9ef6d889d3 | ||
|
|
a0344aefae | ||
|
|
f0e53971f6 | ||
|
|
8340ed5943 | ||
|
|
89d3b62524 | ||
|
|
fdd2daebad | ||
|
|
d3509e1aba | ||
|
|
52c04fdf18 | ||
|
|
42b5c942f5 | ||
|
|
b2f21047da | ||
|
|
c3e32613d7 | ||
|
|
146d3cdd8f | ||
|
|
16a3ed9f4b | ||
|
|
b5cc4e46fb | ||
|
|
485a98ac3e | ||
|
|
4e872096b1 | ||
|
|
0248c6988a | ||
|
|
3189278d43 | ||
|
|
9278f421ad | ||
|
|
0f13bcee06 | ||
|
|
f78749be88 | ||
|
|
b784bb6cff | ||
|
|
0ae4939981 | ||
|
|
2c34c391d2 | ||
|
|
14c478376b | ||
|
|
8bf826793a | ||
|
|
58fc12fc57 | ||
|
|
61ef271683 | ||
|
|
81811ff842 | ||
|
|
455180fa4a | ||
|
|
25b56bfac6 | ||
|
|
7e047b5c98 | ||
|
|
ac4fb52604 | ||
|
|
57fbb21c62 | ||
|
|
21aa72ae2f | ||
|
|
04e4095b36 | ||
|
|
38abe31509 | ||
|
|
3b6e62805f | ||
|
|
4bff232cad | ||
|
|
ddf75fc7e0 | ||
|
|
b4b2f7d54f | ||
|
|
e71d060984 | ||
|
|
c9e3d746d4 | ||
|
|
9d4bad1c7f | ||
|
|
74a6636bc6 | ||
|
|
19ed659d6b | ||
|
|
48d8f030b3 | ||
|
|
7ef7959d77 | ||
|
|
6c7ccad82f | ||
|
|
36e44e7f2b | ||
|
|
6cfab94ef0 | ||
|
|
9764ce9ea8 | ||
|
|
d0808e2bf0 | ||
|
|
d2e4d0d6ee | ||
|
|
699ac0f2bd | ||
|
|
39d623c7c2 | ||
|
|
5404b776aa | ||
|
|
5a72f40f62 | ||
|
|
525e45db77 | ||
|
|
3f02f79b3d | ||
|
|
9360d3b580 | ||
|
|
f51a8cf3c0 | ||
|
|
743c9eb82d | ||
|
|
752bff94cc | ||
|
|
fd7cbf5750 | ||
|
|
13eb0e77e4 | ||
|
|
896b61f2fe | ||
|
|
1859ae688e | ||
|
|
943ee9b8a2 | ||
|
|
81a851e33a | ||
|
|
97951efa9d | ||
|
|
672e34c166 | ||
|
|
4ea2ca2b64 | ||
|
|
61dbdc24b3 | ||
|
|
2d79e4eee4 | ||
|
|
1a3e5f28af | ||
|
|
69b61ceaa4 | ||
|
|
ca0df1f2b0 | ||
|
|
3f48553935 | ||
|
|
cb6dbe5214 | ||
|
|
52829ea14e | ||
|
|
4e1fdc6c8b | ||
|
|
f419106805 | ||
|
|
bfe417ff2f | ||
|
|
3a54776c6b | ||
|
|
6de7ba0deb | ||
|
|
da6fa5a429 | ||
|
|
a70c5ffb1d | ||
|
|
bcdc1c1589 | ||
|
|
9a28c24f70 | ||
|
|
4374fcd1ce | ||
|
|
90e30ee37e | ||
|
|
bf23eb17c8 | ||
|
|
e10379ad18 | ||
|
|
d094476101 | ||
|
|
0a9903f48d | ||
|
|
a05b1ef11f | ||
|
|
b3d7dba2a4 | ||
|
|
a360a8e606 | ||
|
|
e44f2c1911 | ||
|
|
5b05ce6028 | ||
|
|
952c057ff9 | ||
|
|
e1044c578d | ||
|
|
bba43b5a79 | ||
|
|
f2f6bef1fa | ||
|
|
9231692e48 | ||
|
|
6e3aa4a33a | ||
|
|
663ff9d0b1 | ||
|
|
a9c8558507 | ||
|
|
d5e1312e19 | ||
|
|
2494bd0291 | ||
|
|
6c255cf1c9 | ||
|
|
16f8087433 | ||
|
|
14c7b2c4c8 | ||
|
|
9d5d21c39d | ||
|
|
466d3a2811 | ||
|
|
b57c41c6f7 | ||
|
|
ebc331324d | ||
|
|
ccbdf0ead1 | ||
|
|
0fff5c7da0 | ||
|
|
78d512002e | ||
|
|
7ce2d59bce | ||
|
|
a10ea210b3 | ||
|
|
89f5949071 | ||
|
|
1746c4ce94 | ||
|
|
4a2b028463 | ||
|
|
468bcc6441 | ||
|
|
73aaa87bd3 | ||
|
|
ea02c08748 | ||
|
|
87b4f5ef8d | ||
|
|
1dcb42aa5d | ||
|
|
0c1d218fb4 | ||
|
|
d9432e7e82 | ||
|
|
5b45bf9029 | ||
|
|
6f67df5835 | ||
|
|
380b3e658e | ||
|
|
ece785dee7 | ||
|
|
db2e91478b | ||
|
|
90238d4e69 | ||
|
|
939dcaa849 | ||
|
|
25c0d647bd | ||
|
|
b99f4d98a2 | ||
|
|
81b3aad776 | ||
|
|
43407479d5 | ||
|
|
2661893a44 | ||
|
|
b909ada973 | ||
|
|
cdffd39097 | ||
|
|
15209a2a5f |
No files matched your search
+14
-2
@@ -32,7 +32,7 @@ EXTRA_DIST = \
|
||||
AM_CXXFLAGS = -I./code @D_CFLAGS@
|
||||
AM_LDFLAGS = @D_LDFLAGS@
|
||||
|
||||
EXTRA_PROGRAMS = cfilearchiver cfileextractor
|
||||
EXTRA_PROGRAMS = cfilearchiver cfileextractor cryptstring scramble
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
@@ -47,8 +47,20 @@ cfilearchiver_SOURCES = \
|
||||
cfileextractor_SOURCES = \
|
||||
code/cfileextractor/cfileextractor.cpp
|
||||
|
||||
# cryptstring -- to encrypt strings that are used as cheat codes
|
||||
cryptstring_SOURCES = \
|
||||
code/cryptstring/cryptstring.cpp
|
||||
|
||||
# scramble -- to encrypt tables
|
||||
scramble_SOURCES = \
|
||||
code/parse/encrypt.cpp \
|
||||
code/scramble/scramble.cpp \
|
||||
code/scramble/scramble.h
|
||||
|
||||
|
||||
# catch all to build utilitites
|
||||
tools: cfilearchiver cfileextractor
|
||||
tools: cfilearchiver cfileextractor cryptstring scramble
|
||||
|
||||
|
||||
# cleaning
|
||||
clean-tools:
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
The "projects" directory contains ready projects for:
|
||||
Microsoft Visual C++ 6
|
||||
Microsoft Visual C++ 2005
|
||||
Microsoft Visual C++ 2008
|
||||
Micrsofot Visual C++ 2010
|
||||
Apple Xcode
|
||||
Code::Blocks
|
||||
Anjuta 1 (please see README with project before using)
|
||||
|
||||
|
||||
See the ChangeLog to see what's new.
|
||||
|
||||
@@ -128,8 +128,6 @@ done
|
||||
|
||||
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
|
||||
|
||||
# to not run configure, call autogen.sh as,
|
||||
# NOCONFIGURE=1 ./autogen.sh
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure $conf_flags "$@" ...
|
||||
$srcdir/configure $conf_flags "$@" \
|
||||
|
||||
+10
-4
@@ -258,6 +258,10 @@ FS2_SOURCES = \
|
||||
debugconsole/dbugfile.h \
|
||||
debugconsole/timerbar.cpp \
|
||||
debugconsole/timerbar.h \
|
||||
decals/decals.cpp \
|
||||
decals/decals.h \
|
||||
demo/demo.cpp \
|
||||
demo/demo.h \
|
||||
exceptionhandler/exceptionhandler.cpp \
|
||||
exceptionhandler/exceptionhandler.h \
|
||||
external_dll/externalcode.h \
|
||||
@@ -285,10 +289,10 @@ FS2_SOURCES = \
|
||||
gamesnd/gamesnd.h \
|
||||
globalincs/alphacolors.cpp \
|
||||
globalincs/alphacolors.h \
|
||||
globalincs/crypt.cpp \
|
||||
globalincs/crypt.h \
|
||||
globalincs/def_files.cpp \
|
||||
globalincs/def_files.h \
|
||||
globalincs/fsmemory.cpp \
|
||||
globalincs/fsmemory.h \
|
||||
globalincs/globals.h \
|
||||
globalincs/linklist.h \
|
||||
globalincs/pstypes.h \
|
||||
@@ -355,6 +359,7 @@ FS2_SOURCES = \
|
||||
hud/hudobserver.h \
|
||||
hud/hudparse.cpp \
|
||||
hud/hudparse.h \
|
||||
hud/hudresource.h \
|
||||
hud/hudreticle.cpp \
|
||||
hud/hudreticle.h \
|
||||
hud/hudshield.cpp \
|
||||
@@ -523,6 +528,7 @@ FS2_SOURCES = \
|
||||
network/multi_obj.h \
|
||||
network/multi_observer.cpp \
|
||||
network/multi_observer.h \
|
||||
network/multi_oo.h \
|
||||
network/multi_options.cpp \
|
||||
network/multi_options.h \
|
||||
network/multi_pause.cpp \
|
||||
@@ -548,6 +554,8 @@ FS2_SOURCES = \
|
||||
network/multi_voice.h \
|
||||
network/multi_xfer.cpp \
|
||||
network/multi_xfer.h \
|
||||
network/psnet.cpp \
|
||||
network/psnet.h \
|
||||
network/psnet2.cpp \
|
||||
network/psnet2.h \
|
||||
network/stand_gui.cpp \
|
||||
@@ -607,8 +615,6 @@ FS2_SOURCES = \
|
||||
popup/popupdead.h \
|
||||
radar/radar.cpp \
|
||||
radar/radar.h \
|
||||
radar/radardradis.cpp \
|
||||
radar/radardradis.h \
|
||||
radar/radarorb.cpp \
|
||||
radar/radarorb.h \
|
||||
radar/radarsetup.cpp \
|
||||
|
||||
+19
-26
@@ -7,26 +7,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The code in here is just for bookeeping, allocating AI slots and linking them to ships.
|
||||
* See AiCode.cpp for the actual AI code.
|
||||
*/
|
||||
// The code in here is just for bookeeping, allocating
|
||||
// ai slots and linking them to ships.
|
||||
// See AiCode.cpp for the actual AI code.
|
||||
|
||||
#include "ai/ai.h"
|
||||
#include "object/object.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
|
||||
int Total_goal_target_names = 0;
|
||||
char Goal_target_names[MAX_GOAL_TARGET_NAMES][NAME_LENGTH];
|
||||
|
||||
int Total_goal_ship_names = 0;
|
||||
char Goal_ship_names[MAX_GOAL_SHIP_NAMES][NAME_LENGTH];
|
||||
ai_info Ai_info[MAX_AI_INFO];
|
||||
ai_info *Player_ai;
|
||||
|
||||
/**
|
||||
* @brief Returns index of free AI slot.
|
||||
* @return Return -1 if no free slot.
|
||||
*/
|
||||
// Return index of free AI slot.
|
||||
// Return -1 if no free slot.
|
||||
int ai_get_slot(int shipnum)
|
||||
{
|
||||
int i;
|
||||
@@ -43,10 +40,8 @@ int ai_get_slot(int shipnum)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees a currently used AI slot.
|
||||
* @details Only modifies in ::Ai_info struct. Does not modify hook in ship.
|
||||
*/
|
||||
// Releases an AI slot to be used by someone else.
|
||||
// Only modifies in Ai_info struct. Does not modify hook in ship.
|
||||
void ai_free_slot(int ai_index)
|
||||
{
|
||||
Assert( (ai_index >= 0) && (ai_index < MAX_AI_INFO) );
|
||||
@@ -82,22 +77,20 @@ void set_wingnum(int objnum, int wingnum)
|
||||
Ai_info[ai_index].wing = wingnum;
|
||||
}
|
||||
|
||||
char *ai_get_goal_target_name(char *name, int *index)
|
||||
char *ai_get_goal_ship_name(char *name, int *index)
|
||||
{
|
||||
Assert(name != NULL);
|
||||
Assert(index != NULL);
|
||||
int i;
|
||||
|
||||
for (i=0; i < Total_goal_target_names; i++)
|
||||
if (!stricmp(name, Goal_target_names[i])) {
|
||||
for (i=0; i < Total_goal_ship_names; i++)
|
||||
if (!stricmp(name, Goal_ship_names[i])) {
|
||||
*index = i;
|
||||
return Goal_target_names[i];
|
||||
return Goal_ship_names[i];
|
||||
}
|
||||
|
||||
Assert(Total_goal_target_names < MAX_GOAL_TARGET_NAMES);
|
||||
Assertion(strlen(name) <= NAME_LENGTH - 1, "Goal target name %s is too long. Needs to be 31 characters or less.", name);
|
||||
i = Total_goal_target_names++;
|
||||
strcpy_s(Goal_target_names[i], name);
|
||||
Assert(Total_goal_ship_names < MAX_GOAL_SHIP_NAMES);
|
||||
Assert(strlen(name) < NAME_LENGTH - 1);
|
||||
i = Total_goal_ship_names++;
|
||||
strcpy_s(Goal_ship_names[i], name);
|
||||
*index = i;
|
||||
return Goal_target_names[i];
|
||||
return Goal_ship_names[i];
|
||||
}
|
||||
+42
-62
@@ -17,12 +17,10 @@
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "ai/ai_profiles.h"
|
||||
#include "physics/physics.h"
|
||||
#include "object/waypoint.h"
|
||||
|
||||
struct ship_weapon;
|
||||
struct ship_subsys;
|
||||
struct object;
|
||||
struct ship_info;
|
||||
|
||||
#define AI_DEFAULT_CLASS 3 // default AI class for new ships (Fred)
|
||||
|
||||
@@ -33,11 +31,11 @@ struct ship_info;
|
||||
#define AIF_SEEK_LOCK (1 << 4) // set if should focus on gaining aspect lock, not hitting with lasers
|
||||
#define AIF_FORMATION_OBJECT (1 << 5) // Fly in formation off a specific object.
|
||||
#define AIF_TEMPORARY_IGNORE (1 << 6) // Means current ignore_objnum is only temporary, not an order from the player.
|
||||
#define AIF_USE_EXIT_PATH (1 << 7) // Used by path code, to flag path as an exit path
|
||||
#define AIF_USE_STATIC_PATH (1 << 8) // Used by path code, use fixed path, don't try to recreate
|
||||
#define AIF_USE_EXIT_PATH (1 << 7) // Used by path code, to flag path as an exit path
|
||||
#define AIF_USE_STATIC_PATH (1 << 8) // Used by path code, use fixed path, don't try to recreate
|
||||
#define AIF_TARGET_COLLISION (1 << 9) // Collided with aip->target_objnum last frame. Avoid that ship for half a second or so.
|
||||
#define AIF_UNLOAD_SECONDARIES (1 << 10) // Fire secondaries as fast as possible!
|
||||
#define AIF_ON_SUBSYS_PATH (1 << 11) // Current path leads to a subsystem
|
||||
#define AIF_ON_SUBSYS_PATH (1 << 11) // Current path leads to a subsystem
|
||||
#define AIF_AVOID_SHOCKWAVE_SHIP (1 << 12) // Avoid an existing shockwave from a ship.
|
||||
#define AIF_AVOID_SHOCKWAVE_WEAPON (1 << 13) // Avoid an expected shockwave from a weapon. shockwave_object field contains object index.
|
||||
#define AIF_AVOID_SHOCKWAVE_STARTED (1 << 14) // Already started avoiding shockwave, don't keep deciding whether to avoid.
|
||||
@@ -49,7 +47,7 @@ struct ship_info;
|
||||
#define AIF_AVOIDING_BIG_SHIP (1 << 20) // Avoiding a large ship.
|
||||
#define AIF_BIG_SHIP_COLLIDE_RECOVER_1 (1 << 21) // Collided into a big ship. Recovering by flying away.
|
||||
#define AIF_BIG_SHIP_COLLIDE_RECOVER_2 (1 << 22) // Collided into a big ship. Fly towards big ship sphere perimeter.
|
||||
#define AIF_STEALTH_PURSUIT (1 << 23) // AI is trying to fight stealth ship
|
||||
#define AIF_STEALTH_PURSUIT (1 << 23) // Ai is trying to fight stealth ship
|
||||
|
||||
// Goober5000
|
||||
#define AIF_UNLOAD_PRIMARIES (1 << 24) // Fire primaries as fast as possible!
|
||||
@@ -60,7 +58,7 @@ struct ship_info;
|
||||
|
||||
// dock_orient_and_approach() modes.
|
||||
#define DOA_APPROACH 1 // Approach the current point on the path (aip->path_cur)
|
||||
#define DOA_DOCK 2 // Dock with goal object.
|
||||
#define DOA_DOCK 2 // Dock with goal object.
|
||||
#define DOA_UNDOCK_1 3 // Begin undocking with goal object. Just move away.
|
||||
#define DOA_UNDOCK_2 4 // Secondary undocking. Move away.
|
||||
#define DOA_UNDOCK_3 5 // Tertiary undocking. Move away and orient away.
|
||||
@@ -74,7 +72,7 @@ struct ship_info;
|
||||
// Submodes for seeking safety.
|
||||
#define AISS_1 41 // Pick a spot to fly to.
|
||||
#define AISS_2 42 // Flying to spot.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_1a 44 // Pick a new nearby spot because we are endangered, then go to AISS_2
|
||||
|
||||
#define MAX_AI_GOALS 5
|
||||
@@ -83,8 +81,8 @@ struct ship_info;
|
||||
// have priority over others (i.e. when a player issues a goal to a wing, then a seperate
|
||||
// goal to a ship in that wing). We would probably use this type in conjunction with
|
||||
// goal priority to establish which goal to follow
|
||||
#define AIG_TYPE_EVENT_SHIP 1 // from mission event direct to ship
|
||||
#define AIG_TYPE_EVENT_WING 2 // from mission event direct to wing
|
||||
#define AIG_TYPE_EVENT_SHIP 1 // from mission event direct to ship
|
||||
#define AIG_TYPE_EVENT_WING 2 // from mission event direct to wing
|
||||
#define AIG_TYPE_PLAYER_SHIP 3 // from player direct to ship
|
||||
#define AIG_TYPE_PLAYER_WING 4 // from player direct to wing
|
||||
#define AIG_TYPE_DYNAMIC 5 // created on the fly
|
||||
@@ -97,7 +95,7 @@ struct ship_info;
|
||||
#define AIGF_GOAL_OVERRIDE (1<<4) // paired with AIG_TYPE_DYNAMIC to mean this goal overrides any other goal
|
||||
#define AIGF_PURGE (1<<5) // purge this goal next time we process
|
||||
#define AIGF_GOALS_PURGED (1<<6) // this goal has already caused other goals to get purged
|
||||
#define AIGF_DEPART_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
|
||||
#define AIGF_DOCK_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
|
||||
|
||||
#define AIGF_DOCK_INDEXES_VALID (AIGF_DOCKER_INDEX_VALID|AIGF_DOCKEE_INDEX_VALID)
|
||||
|
||||
@@ -127,12 +125,10 @@ typedef struct ai_goal {
|
||||
int flags; // one of the AIGF_* values above
|
||||
fix time; // time at which this goal was issued.
|
||||
int priority; // how important is this goal -- number 0 - 100
|
||||
|
||||
char *target_name; // name of the thing that this goal acts upon
|
||||
int target_name_index; // index of goal_target_name in Goal_target_names[][]
|
||||
waypoint_list *wp_list; // waypoints that this ship might fly.
|
||||
int target_instance; // instance of thing this ship might be chasing (currently only used for weapons; note, not the same as objnum!)
|
||||
int target_signature; // signature of object this ship might be chasing (currently only used for weapons; paired with above value to confirm target)
|
||||
char *ship_name; // name of the ship that this goal acts upon
|
||||
int ship_name_index; // index of ship_name in Goal_ship_names[][]
|
||||
int wp_index; // index into waypoints list of waypoints that this ship might fly.
|
||||
int weapon_signature; // signature of weapon this ship might be chasing. Paired with above value to get target.
|
||||
|
||||
// unions for docking stuff.
|
||||
// (AIGF_DOCKER_INDEX_VALID and AIGF_DOCKEE_INDEX_VALID tell us to use indexes; otherwise we use names)
|
||||
@@ -149,7 +145,7 @@ typedef struct ai_goal {
|
||||
|
||||
} ai_goal;
|
||||
|
||||
#define MAX_GOAL_TARGET_NAMES 100
|
||||
#define MAX_GOAL_SHIP_NAMES 100
|
||||
|
||||
#define AIM_CHASE 0
|
||||
#define AIM_EVADE 1
|
||||
@@ -159,25 +155,25 @@ typedef struct ai_goal {
|
||||
#define AIM_GUARD 5 // Guard an object
|
||||
#define AIM_AVOID 6 // Avoid an object
|
||||
#define AIM_WAYPOINTS 7 // Fly waypoints
|
||||
#define AIM_DOCK 8 // Dock with ship.
|
||||
#define AIM_NONE 9 // Uh, do nothing.
|
||||
#define AIM_DOCK 8 // Dock with ship.
|
||||
#define AIM_NONE 9 // Uh, do nothing.
|
||||
#define AIM_BIGSHIP 10 // Like a capital ship, doesn't focus on one ship.
|
||||
#define AIM_PATH 11 // Follow path on ship
|
||||
#define AIM_PATH 11 // Follow path on ship
|
||||
#define AIM_BE_REARMED 12 // Allow self to be rearmed
|
||||
#define AIM_SAFETY 13 // Seek safety at periphery of battle
|
||||
#define AIM_EVADE_WEAPON 14 // Evade a weapon.
|
||||
#define AIM_STRAFE 15 // Attack a big ship by strafing it
|
||||
#define AIM_STRAFE 15 // attack a big ship by strafing it
|
||||
#define AIM_PLAY_DEAD 16 // Play dead. Get it? Don't move, fire, etc.
|
||||
#define AIM_BAY_EMERGE 17 // Emerging from a fighter bay, following path to do so
|
||||
#define AIM_BAY_DEPART 18 // Departing to a fighter bay, following path to do so
|
||||
#define AIM_SENTRYGUN 19 // AI mode for sentry guns only (floating turrets)
|
||||
#define AIM_BAY_EMERGE 17 // Emerging from a fighter bay, following path to do so
|
||||
#define AIM_BAY_DEPART 18 // Departing to a fighter bay, following path to do so
|
||||
#define AIM_SENTRYGUN 19 // AI mode for sentry guns only (floating turrets)
|
||||
#define AIM_WARP_OUT 20 // Commence warp out sequence. Point in legal direction. Then call John's code.
|
||||
#define AIM_FLY_TO_SHIP 21 // [Kazan] Fly to a ship, doesn't matter if it's hostile or friendly -- for Autopilot usage
|
||||
#define AIM_FLY_TO_SHIP 21 // [Kazan] Fly to a ship, doesn't matter if it's hostile or friendly -- for Autopilot usage
|
||||
|
||||
#define MAX_AI_BEHAVIORS 22 // Number of AIM_xxxx types
|
||||
#define MAX_AI_BEHAVIORS 22 // Number of AIM_xxxx types
|
||||
|
||||
#define MAX_WAYPOINTS_PER_LIST 20
|
||||
#define MAX_ENEMY_DISTANCE 2500.0f // Maximum distance from which a ship will pursue an enemy.
|
||||
#define MAX_ENEMY_DISTANCE 2500.0f // maximum distance from which a ship will pursue an enemy.
|
||||
|
||||
#define AI_GOAL_NONE -1
|
||||
|
||||
@@ -254,12 +250,13 @@ typedef struct ai_class {
|
||||
#define AIS_CHASE_CIRCLESTRAFE 19 // Attempt a circle-strafe on the target
|
||||
|
||||
// Submodes for docking behavior
|
||||
#define AIS_DOCK_0 20
|
||||
#define AIS_DOCK_1 21
|
||||
#define AIS_DOCK_2 22
|
||||
#define AIS_DOCK_3 23
|
||||
#define AIS_DOCK_4 24 // Only for rearm/repair.
|
||||
#define AIS_DOCK_4A 25 // Only for not rearm/repair. MK, 7/15/97
|
||||
#define AIS_DOCK_0 21
|
||||
#define AIS_DOCK_1 22
|
||||
#define AIS_DOCK_2 23
|
||||
#define AIS_DOCK_3 24
|
||||
//#define AIS_DOCK_3A 25
|
||||
#define AIS_DOCK_4 26 // Only for rearm/repair.
|
||||
#define AIS_DOCK_4A 27 // Only for not rearm/repair. MK, 7/15/97
|
||||
#define AIS_UNDOCK_0 30
|
||||
#define AIS_UNDOCK_1 31
|
||||
#define AIS_UNDOCK_2 32
|
||||
@@ -357,9 +354,10 @@ typedef struct ai_info {
|
||||
int ai_class; // Class. Might be override of default.
|
||||
|
||||
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
|
||||
waypoint_list *wp_list; // waypoint list being followed
|
||||
SCP_list<waypoint>::iterator wp_index; // waypoint index in list
|
||||
int wp_list; // waypoint list index
|
||||
int wp_index; // waypoint index in list
|
||||
int wp_flags; // waypoint flags, see WPF_xxxx
|
||||
int wp_dir; // 1 or -1, amount to add to get to next waypoint index.
|
||||
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
|
||||
|
||||
// Path following information
|
||||
@@ -377,7 +375,6 @@ typedef struct ai_info {
|
||||
fix path_next_check_time; // Last time checked to see if would collide with model.
|
||||
int path_goal_dist; // minimum distance to first path point to consider path reached
|
||||
int path_subsystem_next_check; // timestamp to next check if subsystem is still visible
|
||||
vec3d path_depart_orient; //Rotational orientation associated with the path
|
||||
|
||||
int submode;
|
||||
int previous_submode; // previous submode, get it?
|
||||
@@ -463,6 +460,9 @@ typedef struct ai_info {
|
||||
|
||||
float aspect_locked_time; // Time towards acquiring lock for current_target
|
||||
|
||||
// ship_subsys *targeted_subobject; // subsystem to attack
|
||||
// int attack_subsystem_parent; // objnum of the object containing the attack_subsystem
|
||||
|
||||
// Goober5000
|
||||
int support_ship_objnum; // objnum of support ship docking with us, or (if we're a support ship) object we're docking to
|
||||
int support_ship_signature; // signature of the same
|
||||
@@ -508,7 +508,7 @@ typedef struct ai_info {
|
||||
int self_destruct_timestamp; // Time at which to self-destruct, probably due to being disabled.
|
||||
int ok_to_target_timestamp; // Time at which this ship can dynamically target.
|
||||
|
||||
int kamikaze_damage; // some damage value used to produce a shockwave from a kamikaze ship
|
||||
float kamikaze_damage; // some damage value used to produce a shockwave from a kamikaze ship
|
||||
vec3d big_attack_point; // Global point this ship is attacking on a big ship.
|
||||
vec3d big_attack_surface_normal; // Surface normal at ship at big_attack_point;
|
||||
int pick_big_attack_point_timestamp; // timestamp at which to pick a new point to attack on a big ship.
|
||||
@@ -538,17 +538,6 @@ typedef struct ai_info {
|
||||
int ai_override_timestamp; // mark for when to end the current override
|
||||
} ai_info;
|
||||
|
||||
// Goober5000
|
||||
typedef struct {
|
||||
vec3d docker_point;
|
||||
vec3d dockee_point;
|
||||
int dock_mode;
|
||||
int submodel;
|
||||
vec3d submodel_pos;
|
||||
float submodel_r;
|
||||
float submodel_w;
|
||||
} rotating_dockpoint_info;
|
||||
|
||||
#define MAX_AI_INFO MAX_SHIPS
|
||||
|
||||
// SUBSYS_PATH_DIST is used as the distance that a subsystem path should terminate from the actual
|
||||
@@ -561,8 +550,8 @@ typedef struct {
|
||||
#define BURST_DURATION 500 // decay time over which Player->damage_this_burst falls from MAX_BURST_DAMAGE to 0
|
||||
|
||||
extern int Mission_all_attack; // !0 means all teams attack all teams.
|
||||
extern int Total_goal_target_names;
|
||||
extern char Goal_target_names[MAX_GOAL_TARGET_NAMES][NAME_LENGTH];
|
||||
extern int Total_goal_ship_names;
|
||||
extern char Goal_ship_names[MAX_GOAL_SHIP_NAMES][NAME_LENGTH];
|
||||
|
||||
extern void update_ai_info_for_hit(int hitter_obj, int hit_obj);
|
||||
extern void ai_frame_all(void);
|
||||
@@ -604,7 +593,7 @@ void ai_process( object * obj, int ai_index, float frametime );
|
||||
int get_wingnum(int objnum);
|
||||
|
||||
void set_wingnum(int objnum, int wingnum);
|
||||
char *ai_get_goal_target_name(char *name, int *index);
|
||||
char *ai_get_goal_ship_name(char *name, int *index);
|
||||
|
||||
extern void init_ai_system(void);
|
||||
extern void ai_attack_object(object *attacker, object *attacked, ship_subsys *ssp);
|
||||
@@ -615,7 +604,7 @@ extern void ai_dock_with_object(object *docker, int docker_index, object *dockee
|
||||
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
|
||||
extern void ai_set_default_behavior(object *obj, int classnum);
|
||||
extern void ai_do_default_behavior(object *obj);
|
||||
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags);
|
||||
extern void ai_start_waypoints(object *objp, int waypoint_list_index, int wp_flags);
|
||||
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
|
||||
extern void ai_ship_destroy(int shipnum, int method);
|
||||
extern void ai_turn_towards_vector(vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = NULL, int sexp_flags = 0);
|
||||
@@ -650,7 +639,6 @@ extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, i
|
||||
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
|
||||
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
|
||||
extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path=0);
|
||||
extern int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 );
|
||||
|
||||
// Goober5000
|
||||
extern void ai_do_safety(object *objp);
|
||||
@@ -691,10 +679,6 @@ extern void ai_do_objects_docked_stuff(object *docker, int docker_point, object
|
||||
extern void ai_do_objects_undocked_stuff( object *docker, object *dockee );
|
||||
extern void ai_do_objects_repairing_stuff( object *repaired_obj, object *repair_obj, int how );
|
||||
|
||||
// Goober5000
|
||||
// Move to a position relative to a dock bay using thrusters.
|
||||
extern float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo = NULL);
|
||||
|
||||
extern int find_danger_weapon(object *sobjp, float dtime, float *atime, float dot_threshhold);
|
||||
|
||||
void ai_set_mode_warp_out(object *objp, ai_info *aip);
|
||||
@@ -717,8 +701,4 @@ void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t
|
||||
|
||||
//SUSHI: Updating AI aim
|
||||
void ai_update_aim(ai_info *aip, object* En_Objp);
|
||||
|
||||
//SUSHI: Random evasive sidethrust
|
||||
void do_random_sidethrust(ai_info *aip, ship_info *sip);
|
||||
|
||||
#endif
|
||||
+9
-105
@@ -12,8 +12,6 @@
|
||||
#include "ai/ai_profiles.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "localization/localize.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
|
||||
// global stuff
|
||||
@@ -48,32 +46,13 @@ void set_flag(ai_profile_t *profile, char *name, int flag, int type)
|
||||
}
|
||||
}
|
||||
|
||||
char *AI_path_types[] = {
|
||||
"normal",
|
||||
"alt1",
|
||||
};
|
||||
|
||||
int Num_ai_path_types = sizeof(AI_path_types)/sizeof(char*);
|
||||
|
||||
int ai_path_type_match(char *p)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < Num_ai_path_types; i++)
|
||||
{
|
||||
if(!stricmp(AI_path_types[i], p))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void parse_ai_profiles_tbl(char *filename)
|
||||
{
|
||||
int i, rval;
|
||||
bool no_create = false;
|
||||
char profile_name[NAME_LENGTH];
|
||||
ai_profile_t dummy_profile;
|
||||
char *saved_Mp = NULL;
|
||||
char buf[NAME_LENGTH];
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
@@ -105,7 +84,6 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
{
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
bool no_create = false;
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
@@ -260,10 +238,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Attack Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_attack_percent[i]);
|
||||
profile->glide_attack_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Glide Attack Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_attack_percent[i]);
|
||||
}
|
||||
profile->glide_attack_percent[i] /= 100.0;
|
||||
}
|
||||
@@ -273,10 +251,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Circle Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->circle_strafe_percent[i]);
|
||||
profile->circle_strafe_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Circle Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->circle_strafe_percent[i]);
|
||||
}
|
||||
profile->circle_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
@@ -286,10 +264,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_strafe_percent[i]);
|
||||
profile->glide_strafe_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Glide Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_strafe_percent[i]);
|
||||
}
|
||||
profile->glide_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
@@ -299,10 +277,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
profile->random_sidethrust_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
}
|
||||
profile->random_sidethrust_percent[i] /= 100.0;
|
||||
}
|
||||
@@ -347,27 +325,6 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
if (optional_string("$Turret Max Aim Update Delay:"))
|
||||
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Autoaim FOV:"))
|
||||
{
|
||||
float fov_list[NUM_SKILL_LEVELS];
|
||||
parse_float_list(fov_list, NUM_SKILL_LEVELS);
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++)
|
||||
{
|
||||
//Enforce range
|
||||
if (fov_list[i] < 0.0f || fov_list[i] >= 360.0f)
|
||||
{
|
||||
Warning(LOCATION, "$Player Autoaim FOV should be >= 0 and < 360.0 (read %f). Setting to 0.", fov_list[i]);
|
||||
fov_list[i] = 0.0f;
|
||||
}
|
||||
|
||||
//Convert units
|
||||
profile->player_autoaim_fov[i] = fov_list[i] * PI / 180.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Detail Distance Multiplier:"))
|
||||
parse_float_list(profile->detail_distance_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
@@ -436,62 +393,9 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
|
||||
set_flag(profile, "$perform less checks for death screams:", AIPF2_PERFORM_LESS_SCREAM_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$advanced turret fov edge checks:", AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$require turrets to have target in fov:", AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai aims from ship center:", AIPF2_AI_AIMS_FROM_SHIP_CENTER, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow primary link delay:", AIPF2_ALLOW_PRIMARY_LINK_DELAY, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow beams to damage bombs:", AIPF2_BEAMS_DAMAGE_WEAPONS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling for player:", AIPF2_PLAYER_WEAPON_SCALE_FIX, AIP_FLAG2);
|
||||
|
||||
profile->ai_path_mode = AI_PATH_MODE_NORMAL;
|
||||
if(optional_string("$ai path mode:"))
|
||||
{
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
int j = ai_path_type_match(buf);
|
||||
if(j >= 0) {
|
||||
profile->ai_path_mode = j;
|
||||
} else {
|
||||
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Default weapon select effect:")) {
|
||||
char effect[NAME_LENGTH];
|
||||
stuff_string(effect, F_NAME, NAME_LENGTH);
|
||||
if (!stricmp(effect, "FS1"))
|
||||
Default_weapon_select_effect = 1;
|
||||
if (!stricmp(effect, "off"))
|
||||
Default_weapon_select_effect = 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Default ship select effect:")) {
|
||||
char effect[NAME_LENGTH];
|
||||
stuff_string(effect, F_NAME, NAME_LENGTH);
|
||||
if (!stricmp(effect, "FS1"))
|
||||
Default_ship_select_effect = 1;
|
||||
if (!stricmp(effect, "off"))
|
||||
Default_ship_select_effect = 0;
|
||||
}
|
||||
|
||||
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if ( saved_Mp && (saved_Mp == Mp) )
|
||||
{
|
||||
char buf[60];
|
||||
memset(buf, 0, 60);
|
||||
strncpy(buf, Mp, 59);
|
||||
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", buf));
|
||||
|
||||
Mp++;
|
||||
}
|
||||
|
||||
// find next valid option
|
||||
skip_to_start_of_string_either("$", "#");
|
||||
|
||||
@@ -54,19 +54,7 @@
|
||||
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
|
||||
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
|
||||
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
|
||||
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
|
||||
#define AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS (1 << 4)
|
||||
#define AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV (1 << 5)
|
||||
#define AIPF2_AI_AIMS_FROM_SHIP_CENTER (1 << 6)
|
||||
#define AIPF2_ALLOW_PRIMARY_LINK_DELAY (1 << 7)
|
||||
#define AIPF2_BEAMS_DAMAGE_WEAPONS (1 << 8)
|
||||
#define AIPF2_PLAYER_WEAPON_SCALE_FIX (1 << 9)
|
||||
#define AIPF2_NO_WARP_CAMERA (1 << 10)
|
||||
|
||||
// AI Path types
|
||||
#define AI_PATH_MODE_NORMAL 0
|
||||
#define AI_PATH_MODE_ALT1 1
|
||||
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
typedef struct ai_profile_t {
|
||||
@@ -140,12 +128,6 @@ typedef struct ai_profile_t {
|
||||
// the chance (x/7) that ship is allowed to fire missiles at player ship.
|
||||
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
|
||||
// Player-specific autoaim FOV override
|
||||
float player_autoaim_fov[NUM_SKILL_LEVELS];
|
||||
|
||||
float detail_distance_mult[MAX_DETAIL_LEVEL + 1]; //MAX_DETAIL_LEVEL really needs to be 4
|
||||
|
||||
int ai_path_mode;
|
||||
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
+16
-28
@@ -173,7 +173,6 @@ done_1:
|
||||
}
|
||||
|
||||
mc_info mc;
|
||||
mc.model_instance_num = Ships[objp->instance].model_instance_num;
|
||||
mc.model_num = sip->model_num;
|
||||
mc.orient = &objp->orient;
|
||||
mc.pos = &objp->pos;
|
||||
@@ -377,12 +376,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
float dist;
|
||||
|
||||
pm = model_get( Ship_info[Ships[Pl_objp->instance].ship_info_index].model_num );
|
||||
//Necessary sanity check
|
||||
polymodel *pm_t;
|
||||
pm_t = model_get(Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].model_num);
|
||||
Assertion(aip->targeted_subsys->system_info->path_num <= pm_t->n_paths, "Invalid Path number %d for subsystem %s on ship %s (Model: %s)\n", aip->targeted_subsys->system_info->path_num, aip->targeted_subsys->system_info->name, Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].name, pm_t->filename );
|
||||
if (aip->targeted_subsys->system_info->path_num > pm_t->n_paths)
|
||||
return 0;
|
||||
|
||||
// If attacking a subsystem, ensure that we have an unobstructed line of sight... if not, then move
|
||||
// towards path linked to subsystem
|
||||
subsys_in_sight = 0; // assume Pl_objp doesn't have line of sight to subys
|
||||
@@ -426,7 +420,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
|
||||
aip->path_goal_dist = 5;
|
||||
subsys_path_num = aip->targeted_subsys->system_info->path_num;
|
||||
if ( ((aip->path_start) == -1 || (aip->mp_index != subsys_path_num)) && subsys_path_num <= pm->n_paths ) {
|
||||
if ( (aip->path_start) == -1 || (aip->mp_index != subsys_path_num) ) {
|
||||
// maybe create a new path
|
||||
if ( subsys_path_num >= 0 ) {
|
||||
Assert(aip->target_objnum >= 0);
|
||||
@@ -472,6 +466,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
// for now, only follow the path to the first point
|
||||
if ( aip->path_cur < (aip->path_start+aip->path_length-1) ) {
|
||||
if ( aip->goal_objnum != aip->target_objnum ) {
|
||||
//Int3(); // what is going on here? - Get Alan
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_NONE;
|
||||
aip->submode = -1;
|
||||
@@ -552,7 +547,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
object *objp;
|
||||
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
|
||||
if ((objp->type == OBJ_WEAPON) && (iff_x_attacks_y(Ships[Pl_objp->instance].team, Weapons[objp->instance].team)))
|
||||
if (Weapon_info[Weapons[objp->instance].weapon_info_index].subtype == WP_LASER) {
|
||||
if (Weapon_info[objp->instance].subtype == WP_LASER) {
|
||||
vec3d in_vec;
|
||||
float dist;
|
||||
|
||||
@@ -699,7 +694,7 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
|
||||
ship_weapon *tswp = &temp_shipp->weapons;
|
||||
|
||||
if ( tswp->num_primary_banks > 0 ) {
|
||||
Assertion(tswp->current_primary_bank < tswp->num_primary_banks, "AI tried to select primary bank %d. Might be a model error\n", tswp->current_primary_bank);
|
||||
Assert(tswp->current_primary_bank < tswp->num_primary_banks);
|
||||
weapon_info *wip = &Weapon_info[tswp->primary_bank_weapons[tswp->current_primary_bank]];
|
||||
|
||||
if (dist_to_enemy < MIN((wip->max_speed * wip->lifetime), wip->weapon_range)){
|
||||
@@ -826,12 +821,15 @@ void ai_big_chase()
|
||||
ship_info *sip = &Ship_info[Ships[Pl_objp->instance].ship_info_index];
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
ai_info *aip = &Ai_info[shipp->ai_index];
|
||||
int enemy_ship_type;
|
||||
vec3d predicted_enemy_pos;
|
||||
|
||||
Assert(aip->mode == AIM_CHASE);
|
||||
|
||||
maybe_cheat_fire_synaptic(Pl_objp, aip);
|
||||
|
||||
enemy_ship_type = Ship_info[Ships[En_objp->instance].ship_info_index].flags;
|
||||
|
||||
ai_set_positions(Pl_objp, En_objp, aip, &player_pos, &enemy_pos);
|
||||
|
||||
player_pos = Pl_objp->pos;
|
||||
@@ -1163,13 +1161,12 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
float weapon_speed;
|
||||
|
||||
// Compute position of gun in absolute space and use that as fire position.
|
||||
if (po->n_guns > 0 && !(The_mission.ai_profile->flags2 & AIPF2_AI_AIMS_FROM_SHIP_CENTER)) {
|
||||
if (po->n_guns > 0) {
|
||||
pnt = po->gun_banks[0].pnt[0];
|
||||
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
|
||||
vm_vec_add2(&gun_pos, &Pl_objp->pos);
|
||||
} else {
|
||||
//Use the convergence offset, if there is one
|
||||
vm_vec_copy_scale(&pnt, &Ship_info[shipp->ship_info_index].convergence_offset, 1.0f);
|
||||
gun_pos = Pl_objp->pos;
|
||||
}
|
||||
weapon_speed = ai_get_weapon_speed(&shipp->weapons);
|
||||
|
||||
@@ -1248,6 +1245,7 @@ void ai_big_strafe_attack()
|
||||
vec3d target_pos;
|
||||
vec3d rand_vec;
|
||||
float target_dist, target_dot, accel, t;
|
||||
object *target_objp;
|
||||
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
|
||||
@@ -1259,8 +1257,11 @@ void ai_big_strafe_attack()
|
||||
if ( ai_big_strafe_maybe_retreat(target_dist, &target_pos) )
|
||||
return;
|
||||
|
||||
target_objp = &Objects[aip->target_objnum];
|
||||
|
||||
if (aip->ai_flags & AIF_KAMIKAZE) {
|
||||
if (target_dist < 1200.0f) {
|
||||
//nprintf(("AI", "Kamikaze: %7.3f %7.3f\n", target_dot, target_dist));
|
||||
ai_turn_towards_vector(&target_pos, Pl_objp, flFrametime, Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time, NULL, NULL, 0.0f, 0);
|
||||
accelerate_ship(aip, 1.0f);
|
||||
if ((target_dist < 400.0f) && ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
@@ -1296,6 +1297,7 @@ void ai_big_strafe_attack()
|
||||
|
||||
aip->submode = AIS_STRAFE_AVOID;
|
||||
aip->submode_start_time = Missiontime;
|
||||
// nprintf(("Alan","Ship %s entering AIS_STRAFE_AVOID at frame %d\n", Ships[aip->shipnum].ship_name, Framecount));
|
||||
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
@@ -1638,20 +1640,6 @@ void ai_big_strafe()
|
||||
Int3(); // Illegal submode for AIM_STRAFE
|
||||
break;
|
||||
}
|
||||
|
||||
//Maybe apply random sidethrust, depending on the current submode
|
||||
//The following are valid targets for random sidethrust (circle strafe uses it too, but that is handled separately)
|
||||
if (aip->submode == AIS_STRAFE_ATTACK ||
|
||||
aip->submode == AIS_STRAFE_AVOID ||
|
||||
aip->submode == AIS_STRAFE_RETREAT1 ||
|
||||
aip->submode == AIS_STRAFE_RETREAT2 ||
|
||||
aip->submode == AIS_STRAFE_POSITION)
|
||||
{
|
||||
//Re-roll for random sidethrust every 2 seconds
|
||||
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent) {
|
||||
do_random_sidethrust(aip, &Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if Pl_objp should enter strafe mode (This is called from maybe_evade_dumbfire_weapon(), and the
|
||||
@@ -1765,7 +1753,7 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
// Approx 1/4 chance we'll go after the other ship's beam.
|
||||
|
||||
bool attack_turret_on_different_ship = (aip->ai_profile_flags & AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS)
|
||||
&& (Weapon_info[Weapons[weapon_objp->instance].weapon_info_index].wi_flags & WIF_BEAM) && (frand()*100 < 25.0f);
|
||||
&& (Weapon_info[weapon_objp->instance].wi_flags & WIF_BEAM) && (frand()*100 < 25.0f);
|
||||
|
||||
// unless we're making an exception, we should only attack a turret if it sits on the current target
|
||||
if ( !attack_turret_on_different_ship )
|
||||
|
||||
+2012
-1340
File diff suppressed because it is too large.
Load diff
+117
-117
@@ -329,7 +329,7 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
mode = remove_goalp->ai_mode;
|
||||
submode = remove_goalp->ai_submode;
|
||||
priority = remove_goalp->priority;
|
||||
name = remove_goalp->target_name;
|
||||
name = remove_goalp->ship_name;
|
||||
|
||||
Assert ( name ); // should not be NULL!!!!
|
||||
|
||||
@@ -345,10 +345,10 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
aigp = &(aip->goals[j]);
|
||||
|
||||
// don't need to worry about these types of goals since they can't possibly be a goal we are looking for.
|
||||
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->target_name )
|
||||
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->ship_name )
|
||||
continue;
|
||||
|
||||
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->target_name) ) {
|
||||
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->ship_name) ) {
|
||||
ai_remove_ship_goal( aip, j );
|
||||
ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] ); // do the default behavior
|
||||
break; // we are all done
|
||||
@@ -359,10 +359,10 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
// now remove the goal from the wing
|
||||
for (i = 0; i < MAX_AI_GOALS; i++ ) {
|
||||
aigp = &(wingp->ai_goals[i]);
|
||||
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->target_name )
|
||||
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->ship_name )
|
||||
continue;
|
||||
|
||||
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->target_name) ) {
|
||||
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->ship_name) ) {
|
||||
wingp->ai_goals[i].ai_mode = AI_GOAL_NONE;
|
||||
wingp->ai_goals[i].signature = -1;
|
||||
wingp->ai_goals[i].priority = -1;
|
||||
@@ -401,7 +401,7 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai
|
||||
int mode, ship_index, wingnum;
|
||||
|
||||
// get locals for easer access
|
||||
name = aigp->target_name;
|
||||
name = aigp->ship_name;
|
||||
mode = aigp->ai_mode;
|
||||
|
||||
// these goals cannot be associated to wings, but can to a ship in a wing. So, we should find out
|
||||
@@ -424,17 +424,17 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai
|
||||
continue;
|
||||
|
||||
// goals must operate on something to be purged.
|
||||
if ( purge_goal->target_name == NULL )
|
||||
if ( purge_goal->ship_name == NULL )
|
||||
continue;
|
||||
|
||||
// determine if the purge goal is acting either on the ship or the ship's wing.
|
||||
purge_wing = wing_name_lookup( purge_goal->target_name, 1 );
|
||||
purge_wing = wing_name_lookup( purge_goal->ship_name, 1 );
|
||||
|
||||
// if the target of the purge goal is a ship (purge_wing will be -1), then if the names
|
||||
// don't match, we can continue; if the wing is valid, don't process if the wing numbers
|
||||
// are different.
|
||||
if ( purge_wing == -1 ) {
|
||||
if ( stricmp(purge_goal->target_name, name ) )
|
||||
if ( stricmp(purge_goal->ship_name, name ) )
|
||||
continue;
|
||||
} else if ( purge_wing != wingnum )
|
||||
continue;
|
||||
@@ -560,7 +560,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
int shipnum, docker_index, dockee_index;
|
||||
|
||||
Assert ( aip->shipnum != -1 );
|
||||
shipnum = ship_name_lookup( aigp->target_name );
|
||||
shipnum = ship_name_lookup( aigp->ship_name );
|
||||
docker_index = -1;
|
||||
dockee_index = -1;
|
||||
|
||||
@@ -626,36 +626,27 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
// from the mission goals (i.e. those goals which come from events) in that we don't
|
||||
// use sexpressions for goals from the player...so we enumerate all the parameters
|
||||
|
||||
void ai_add_goal_sub_player(int type, int mode, int submode, char *target_name, ai_goal *aigp )
|
||||
void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
|
||||
{
|
||||
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
|
||||
|
||||
aigp->time = Missiontime;
|
||||
aigp->type = type; // from player for sure -- could be to ship or to wing
|
||||
aigp->ai_mode = mode; // major mode for this goal
|
||||
aigp->type = type; // from player for sure -- could be to ship or to wing
|
||||
aigp->ai_mode = mode; // major mode for this goal
|
||||
aigp->ai_submode = submode; // could mean different things depending on mode
|
||||
|
||||
if ( mode == AI_GOAL_WARP ) {
|
||||
if (submode >= 0) {
|
||||
aigp->wp_list = find_waypoint_list_at_index(submode);
|
||||
Assert(aigp->wp_list != NULL);
|
||||
} else {
|
||||
aigp->wp_list = NULL;
|
||||
}
|
||||
}
|
||||
if ( mode == AI_GOAL_WARP )
|
||||
aigp->wp_index = submode;
|
||||
|
||||
if ( mode == AI_GOAL_CHASE_WEAPON ) {
|
||||
aigp->target_instance = submode; // submode contains the instance of the weapon
|
||||
aigp->target_signature = Objects[Weapons[submode].objnum].signature;
|
||||
} else {
|
||||
aigp->target_instance = -1;
|
||||
aigp->target_signature = -1;
|
||||
aigp->wp_index = submode; // submode contains the instance of the weapon
|
||||
aigp->weapon_signature = Objects[Weapons[submode].objnum].signature;
|
||||
}
|
||||
|
||||
if ( target_name != NULL )
|
||||
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
|
||||
if ( shipname != NULL )
|
||||
aigp->ship_name = ai_get_goal_ship_name( shipname, &aigp->ship_name_index );
|
||||
else
|
||||
aigp->target_name = NULL;
|
||||
aigp->ship_name = NULL;
|
||||
|
||||
// special case certain orders from player so that ships continue to do the right thing
|
||||
|
||||
@@ -720,7 +711,7 @@ int ai_goal_num(ai_goal *goals)
|
||||
}
|
||||
|
||||
|
||||
void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, char *target_name, ai_goal *aigp )
|
||||
void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, char *shipname, ai_goal *aigp )
|
||||
{
|
||||
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
|
||||
|
||||
@@ -730,17 +721,17 @@ void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, ch
|
||||
aigp->ai_submode = submode; // could mean different things depending on mode
|
||||
|
||||
if ( mode == AI_GOAL_WARP )
|
||||
aigp->wp_list = NULL;
|
||||
aigp->wp_index = submode;
|
||||
|
||||
if ( mode == AI_GOAL_CHASE_WEAPON ) {
|
||||
aigp->target_instance = submode; // submode contains the instance of the weapon
|
||||
aigp->target_signature = Objects[Weapons[submode].objnum].signature;
|
||||
aigp->wp_index = submode; // submode contains the instance of the weapon
|
||||
aigp->weapon_signature = Objects[Weapons[submode].objnum].signature;
|
||||
}
|
||||
|
||||
if ( target_name != NULL )
|
||||
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
|
||||
if ( shipname != NULL )
|
||||
aigp->ship_name = ai_get_goal_ship_name( shipname, &aigp->ship_name_index );
|
||||
else
|
||||
aigp->target_name = NULL;
|
||||
aigp->ship_name = NULL;
|
||||
|
||||
aigp->priority = priority;
|
||||
}
|
||||
@@ -833,7 +824,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
aigp->signature = Ai_goal_signature++;
|
||||
|
||||
aigp->target_name = NULL;
|
||||
aigp->ship_name = NULL;
|
||||
aigp->time = Missiontime;
|
||||
aigp->type = type;
|
||||
aigp->flags = 0;
|
||||
@@ -848,10 +839,10 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
ref_type = Sexp_nodes[CDR(node)].subtype;
|
||||
if (ref_type == SEXP_ATOM_STRING) { // referenced by name
|
||||
// save the waypoint path name -- the list will get resolved when the goal is checked
|
||||
// for achievability.
|
||||
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
|
||||
aigp->wp_list = NULL;
|
||||
// save the waypoint path name -- the index will get resolved when the goal is checked
|
||||
// for acheivability.
|
||||
aigp->ship_name = ai_get_goal_ship_name(CTEXT(CDR(node)), &aigp->ship_name_index); // waypoint path name;
|
||||
aigp->wp_index = -1;
|
||||
|
||||
} else
|
||||
Int3();
|
||||
@@ -865,24 +856,24 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
case OP_AI_DESTROY_SUBSYS:
|
||||
aigp->ai_mode = AI_GOAL_DESTROY_SUBSYSTEM;
|
||||
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
|
||||
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
|
||||
// store the name of the subsystem in the docker.name field for now -- this field must get
|
||||
// fixed up when the goal is valid since we need to locate the subsystem on the ship's model
|
||||
aigp->docker.name = ai_get_goal_target_name(CTEXT(CDR(CDR(node))), &dummy);
|
||||
aigp->docker.name = ai_get_goal_ship_name(CTEXT(CDR(CDR(node))), &dummy);
|
||||
aigp->flags |= AIGF_SUBSYS_NEEDS_FIXUP;
|
||||
aigp->priority = atoi( CTEXT(CDR(CDR(CDR(node)))) );
|
||||
break;
|
||||
|
||||
case OP_AI_DISABLE_SHIP:
|
||||
aigp->ai_mode = AI_GOAL_DISABLE_SHIP;
|
||||
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
|
||||
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
|
||||
aigp->ai_submode = -SUBSYSTEM_ENGINE;
|
||||
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
|
||||
break;
|
||||
|
||||
case OP_AI_DISARM_SHIP:
|
||||
aigp->ai_mode = AI_GOAL_DISARM_SHIP;
|
||||
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
|
||||
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
|
||||
aigp->ai_submode = -SUBSYSTEM_TURRET;
|
||||
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
|
||||
break;
|
||||
@@ -895,8 +886,9 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
// the following goal is obsolete, but here for compatibility
|
||||
case OP_AI_WARP:
|
||||
aigp->ai_mode = AI_GOAL_WARP;
|
||||
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
|
||||
aigp->wp_list = NULL;
|
||||
aigp->ship_name = ai_get_goal_ship_name(CTEXT(CDR(node)), &aigp->ship_name_index); // waypoint path name;
|
||||
//aigp->wp_index = atoi( CTEXT(CDR(node)) ); // this is the index into the warp points
|
||||
aigp->wp_index = -1;
|
||||
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
|
||||
break;
|
||||
|
||||
@@ -905,9 +897,9 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
// Goober5000 - optional undock with something
|
||||
if (CDR(CDR(node)) != -1)
|
||||
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(CDR(node))), &aigp->target_name_index );
|
||||
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(CDR(node))), &aigp->ship_name_index );
|
||||
else
|
||||
aigp->target_name = NULL;
|
||||
aigp->ship_name = NULL;
|
||||
|
||||
aigp->ai_mode = AI_GOAL_UNDOCK;
|
||||
aigp->ai_submode = AIS_UNDOCK_0;
|
||||
@@ -915,12 +907,12 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
case OP_AI_STAY_STILL:
|
||||
aigp->ai_mode = AI_GOAL_STAY_STILL;
|
||||
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
|
||||
aigp->ship_name = ai_get_goal_ship_name(CTEXT(CDR(node)), &aigp->ship_name_index); // waypoint path name;
|
||||
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
|
||||
break;
|
||||
|
||||
case OP_AI_DOCK:
|
||||
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
|
||||
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
|
||||
aigp->docker.name = ai_add_dock_name(CTEXT(CDR(CDR(node))));
|
||||
aigp->dockee.name = ai_add_dock_name(CTEXT(CDR(CDR(CDR(node)))));
|
||||
aigp->flags &= ~AIGF_DOCK_INDEXES_VALID;
|
||||
@@ -945,12 +937,6 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
aigp->ai_mode = AI_GOAL_KEEP_SAFE_DISTANCE;
|
||||
break;
|
||||
|
||||
case OP_AI_FORM_ON_WING:
|
||||
aigp->priority = 99;
|
||||
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index);
|
||||
aigp->ai_mode = AI_GOAL_FORM_ON_WING;
|
||||
break;
|
||||
|
||||
case OP_AI_CHASE:
|
||||
case OP_AI_GUARD:
|
||||
case OP_AI_GUARD_WING:
|
||||
@@ -959,7 +945,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
case OP_AI_STAY_NEAR_SHIP:
|
||||
case OP_AI_IGNORE:
|
||||
case OP_AI_IGNORE_NEW:
|
||||
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
|
||||
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
|
||||
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
|
||||
|
||||
if ( op == OP_AI_CHASE ) {
|
||||
@@ -968,12 +954,12 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
// in the case of ai_chase (and ai_guard) we must do a wing_name_lookup on the name
|
||||
// passed here to see if we could be chasing a wing. Hoffoss and I have consolidated
|
||||
// sexpression operators which makes this step necessary
|
||||
if ( wing_name_lookup(aigp->target_name, 1) != -1 )
|
||||
if ( wing_name_lookup(aigp->ship_name, 1) != -1 )
|
||||
aigp->ai_mode = AI_GOAL_CHASE_WING;
|
||||
|
||||
} else if ( op == OP_AI_GUARD ) {
|
||||
aigp->ai_mode = AI_GOAL_GUARD;
|
||||
if ( wing_name_lookup(aigp->target_name, 1) != -1 )
|
||||
if ( wing_name_lookup(aigp->ship_name, 1) != -1 )
|
||||
aigp->ai_mode = AI_GOAL_GUARD_WING;
|
||||
|
||||
} else if ( op == OP_AI_EVADE_SHIP ) {
|
||||
@@ -1005,7 +991,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
// Goober5000 - since none of the goals act on the actor,
|
||||
// don't assign the goal if the actor's goal target is itself
|
||||
if (aigp->target_name != NULL && !strcmp(aigp->target_name, actor_name))
|
||||
if (aigp->ship_name != NULL && !strcmp(aigp->ship_name, actor_name))
|
||||
{
|
||||
// based on ai_remove_ship_goal, these seem to be the only statements
|
||||
// necessary to cause this goal to "never have been assigned"
|
||||
@@ -1022,7 +1008,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
* Pass -1 in priority to ignore priority when searching
|
||||
* Returns -1 if not found, or [0, MAX_AI_GOALS)
|
||||
*/
|
||||
int ai_find_goal_index( ai_goal* aigp, int mode, int submode, int priority )
|
||||
int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 )
|
||||
{
|
||||
Assert( aigp != NULL );
|
||||
for ( int i = 0; i < MAX_AI_GOALS; i++ )
|
||||
@@ -1289,7 +1275,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
|
||||
*/
|
||||
|
||||
case AI_GOAL_UNDOCK:
|
||||
aigp->target_name = name;
|
||||
aigp->ship_name = name;
|
||||
aigp->priority = MAX_GOAL_PRIORITY;
|
||||
aigp->ai_mode = AI_GOAL_UNDOCK;
|
||||
aigp->ai_submode = AIS_UNDOCK_0;
|
||||
@@ -1308,7 +1294,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
|
||||
case AI_GOAL_REARM_REPAIR:
|
||||
aigp->ai_mode = AI_GOAL_REARM_REPAIR;
|
||||
aigp->ai_submode = 0;
|
||||
aigp->target_name = name;
|
||||
aigp->ship_name = name;
|
||||
aigp->priority = PLAYER_PRIORITY_MIN-1; // make the priority always less than what the player's is
|
||||
aigp->flags &= ~AIGF_GOAL_OVERRIDE; // don't override this goal. rearm repair requests should happen in order
|
||||
ai_goal_fixup_dockpoints( aip, aigp );
|
||||
@@ -1373,6 +1359,7 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
int status;
|
||||
char *ai_shipname;
|
||||
int return_val;
|
||||
object *objp;
|
||||
ai_info *aip;
|
||||
@@ -1381,6 +1368,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
objp = &Objects[objnum];
|
||||
Assert( objp->instance != -1 );
|
||||
ai_shipname = Ships[objp->instance].ship_name;
|
||||
aip = &Ai_info[Ships[objp->instance].ai_index];
|
||||
|
||||
// these orders are always achievable.
|
||||
@@ -1412,7 +1400,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// if the wing target is valid then be sure to set the override bit so that it always
|
||||
// gets executed next
|
||||
if ( aigp->ai_mode == AI_GOAL_FORM_ON_WING ) {
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
sindex = ship_name_lookup( aigp->ship_name );
|
||||
|
||||
if (sindex < 0)
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
@@ -1421,14 +1409,20 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
}
|
||||
|
||||
// check to see if we have a valid list. If not, then try to set one up. If that
|
||||
// check to see if we have a valid index. If not, then try to set one up. If that
|
||||
// fails, then we must pitch this order
|
||||
if ( (aigp->ai_mode == AI_GOAL_WAYPOINTS_ONCE) || (aigp->ai_mode == AI_GOAL_WAYPOINTS) ) {
|
||||
if ( aigp->wp_list == NULL ) {
|
||||
aigp->wp_list = find_matching_waypoint_list(aigp->target_name);
|
||||
if ( aigp->wp_index == -1 ) {
|
||||
int i;
|
||||
|
||||
if ( aigp->wp_list == NULL ) {
|
||||
Warning(LOCATION, "Unknown waypoint list %s - not found in mission file. Killing ai goal", aigp->target_name );
|
||||
for (i = 0; i < Num_waypoint_lists; i++) {
|
||||
if (!stricmp(aigp->ship_name, Waypoint_lists[i].name)) {
|
||||
aigp->wp_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == Num_waypoint_lists ) {
|
||||
Warning(LOCATION, "Unknown waypoint %s. not found in mission file. Killing ai goal", aigp->ship_name );
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
}
|
||||
@@ -1443,6 +1437,8 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
case AI_GOAL_DOCK:
|
||||
case AI_GOAL_UNDOCK:
|
||||
//status = mission_log_get_time( LOG_SHIP_DOCK, ai_shipname, aigp->ship_name, NULL );
|
||||
//status = mission_log_get_time( LOG_SHIP_UNDOCK, ai_shipname, aigp->ship_name, NULL );
|
||||
//MWA 3/20/97 -- cannot short circuit a dock or undock goal already succeeded -- we must
|
||||
// rely on the goal removal code to just remove this goal. This is because docking/undock
|
||||
// can happen > 1 time per mission per pair of ships. The above checks will find only
|
||||
@@ -1456,7 +1452,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// shipnum could be -1 depending on if the ship hasn't arrived or died. only look for subsystem
|
||||
// destroyed when shipnum is valid
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
sindex = ship_name_lookup( aigp->ship_name );
|
||||
|
||||
// can't determine the status of this goal if ship not valid
|
||||
// or we haven't found a valid subsystem index yet
|
||||
@@ -1470,17 +1466,17 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// for this goal to be valid).
|
||||
Assert ( aigp->ai_submode >= 0 );
|
||||
ssp = ship_get_indexed_subsys( &Ships[sindex], aigp->ai_submode );
|
||||
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->target_name, ssp->system_info->subobj_name, NULL );
|
||||
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->ship_name, ssp->system_info->subobj_name, NULL );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AI_GOAL_DISABLE_SHIP:
|
||||
status = mission_log_get_time( LOG_SHIP_DISABLED, aigp->target_name, NULL, NULL );
|
||||
status = mission_log_get_time( LOG_SHIP_DISABLED, aigp->ship_name, NULL, NULL );
|
||||
break;
|
||||
|
||||
case AI_GOAL_DISARM_SHIP:
|
||||
status = mission_log_get_time( LOG_SHIP_DISARMED, aigp->target_name, NULL, NULL );
|
||||
status = mission_log_get_time( LOG_SHIP_DISARMED, aigp->ship_name, NULL, NULL );
|
||||
break;
|
||||
|
||||
// to guard or ignore a ship, the goal cannot continue if the ship being guarded is either destroyed
|
||||
@@ -1497,11 +1493,11 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// MWA -- 4/22/98. Check for the ship actually being in the mission before
|
||||
// checking departure and destroyed. In multiplayer, since ships can respawn,
|
||||
// they get log entries for being destroyed even though they have respawned.
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
sindex = ship_name_lookup( aigp->ship_name );
|
||||
if ( sindex == -1 ) {
|
||||
status = mission_log_get_time( LOG_SHIP_DEPARTED, aigp->target_name, NULL, NULL);
|
||||
status = mission_log_get_time( LOG_SHIP_DEPARTED, aigp->ship_name, NULL, NULL);
|
||||
if ( !status ) {
|
||||
status = mission_log_get_time( LOG_SHIP_DESTROYED, aigp->target_name, NULL, NULL);
|
||||
status = mission_log_get_time( LOG_SHIP_DESTROYED, aigp->ship_name, NULL, NULL);
|
||||
if ( status )
|
||||
return_val = AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
@@ -1515,9 +1511,9 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
case AI_GOAL_CHASE_WING:
|
||||
case AI_GOAL_GUARD_WING:
|
||||
{
|
||||
status = mission_log_get_time( LOG_WING_DEPARTED, aigp->target_name, NULL, NULL );
|
||||
status = mission_log_get_time( LOG_WING_DEPARTED, aigp->ship_name, NULL, NULL );
|
||||
if ( !status ) {
|
||||
status = mission_log_get_time( LOG_WING_DESTROYED, aigp->target_name, NULL, NULL);
|
||||
status = mission_log_get_time( LOG_WING_DESTROYED, aigp->ship_name, NULL, NULL);
|
||||
if ( status )
|
||||
return_val = AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
@@ -1530,13 +1526,13 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
// for chase weapon, we simply need to look at the weapon instance that we are trying to
|
||||
// attack and see if the object still exists, and has the same signature that we expect.
|
||||
Assert( aigp->target_instance >= 0 );
|
||||
Assert( aigp->wp_index >= 0 );
|
||||
|
||||
if ( Weapons[aigp->target_instance].objnum == -1 )
|
||||
if ( Weapons[aigp->wp_index].objnum == -1 )
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
|
||||
// if the signatures don't match, then goal isn't achievable.
|
||||
if ( Objects[Weapons[aigp->target_instance].objnum].signature != aigp->target_signature )
|
||||
if ( Objects[Weapons[aigp->wp_index].objnum].signature != aigp->weapon_signature )
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
|
||||
// otherwise, we should be good to go
|
||||
@@ -1561,7 +1557,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// the if statement.
|
||||
if ( (aigp->ai_mode == AI_GOAL_CHASE_WING) || (aigp->ai_mode == AI_GOAL_GUARD_WING) )
|
||||
{
|
||||
sindex = wing_name_lookup( aigp->target_name );
|
||||
sindex = wing_name_lookup( aigp->ship_name );
|
||||
|
||||
if (sindex < 0)
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
@@ -1577,24 +1573,24 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
}
|
||||
// Goober5000 - undocking from an unspecified object is always achievable;
|
||||
// undocking from a specified object is handled below
|
||||
else if ( (aigp->ai_mode == AI_GOAL_UNDOCK) && (aigp->target_name == NULL) )
|
||||
else if ( (aigp->ai_mode == AI_GOAL_UNDOCK) && (aigp->ship_name == NULL) )
|
||||
{
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// goal ship is currently in mission
|
||||
if ( ship_name_lookup( aigp->target_name ) != -1 )
|
||||
if ( ship_name_lookup( aigp->ship_name ) != -1 )
|
||||
{
|
||||
status = SHIP_STATUS_ARRIVED;
|
||||
}
|
||||
// goal ship is still on the arrival list
|
||||
else if ( mission_parse_get_arrival_ship(aigp->target_name) )
|
||||
else if ( mission_parse_get_arrival_ship(aigp->ship_name) )
|
||||
{
|
||||
status = SHIP_STATUS_NOT_ARRIVED;
|
||||
}
|
||||
// goal ship has left the area
|
||||
else if ( ship_find_exited_ship_by_name(aigp->target_name) != -1 )
|
||||
else if ( ship_find_exited_ship_by_name(aigp->ship_name) != -1 )
|
||||
{
|
||||
status = SHIP_STATUS_GONE;
|
||||
}
|
||||
@@ -1609,7 +1605,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
if ((status == SHIP_STATUS_ARRIVED) && (aigp->ai_mode == AI_GOAL_DISARM_SHIP))
|
||||
{
|
||||
// if the ship has no turrets, we can't disarm it!
|
||||
if (Ships[ship_name_lookup(aigp->target_name)].subsys_info[SUBSYSTEM_TURRET].type_count == 0)
|
||||
if (Ships[ship_name_lookup(aigp->ship_name)].subsys_info[SUBSYSTEM_TURRET].num == 0)
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
|
||||
@@ -1640,7 +1636,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
}
|
||||
|
||||
if (!(aigp->flags & AIGF_DOCKEE_INDEX_VALID)) {
|
||||
sindex = ship_name_lookup(aigp->target_name);
|
||||
sindex = ship_name_lookup(aigp->ship_name);
|
||||
if ( sindex != -1 ) {
|
||||
modelnum = Ship_info[Ships[sindex].ship_info_index].model_num;
|
||||
index = model_find_dock_name_index(modelnum, aigp->dockee.name);
|
||||
@@ -1660,7 +1656,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
|
||||
// we must also determine if we're prevented from docking for any reason
|
||||
sindex = ship_name_lookup(aigp->target_name);
|
||||
sindex = ship_name_lookup(aigp->ship_name);
|
||||
Assert( sindex >= 0 );
|
||||
object *goal_objp = &Objects[Ships[sindex].objnum];
|
||||
|
||||
@@ -1712,7 +1708,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
if ((aip->mode == AIM_DOCK) && (aip->submode >= AIS_UNDOCK_0))
|
||||
{
|
||||
// only put it on hold if it's someone other than the guy we're undocking from right now!!
|
||||
if (aip->goal_objnum != Ships[ship_name_lookup(aigp->target_name)].objnum)
|
||||
if (aip->goal_objnum != Ships[ship_name_lookup(aigp->ship_name)].objnum)
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
}
|
||||
|
||||
@@ -1721,7 +1717,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// have fixed up the subsystem name (of the subsystem to destroy) into an index into
|
||||
// the ship's subsystem list
|
||||
if ( aigp->flags & AIGF_SUBSYS_NEEDS_FIXUP ) {
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
sindex = ship_name_lookup( aigp->ship_name );
|
||||
|
||||
if ( sindex != -1 ) {
|
||||
aigp->ai_submode = ship_get_subsys_index( &Ships[sindex], aigp->docker.name );
|
||||
@@ -1735,7 +1731,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
object *ignored;
|
||||
|
||||
// for ignoring a ship, call the ai_ignore object function, then declare the goal satisfied
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
sindex = ship_name_lookup( aigp->ship_name );
|
||||
Assert( sindex != -1 ); // should be true because of above status
|
||||
ignored = &Objects[Ships[sindex].objnum];
|
||||
|
||||
@@ -1789,7 +1785,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
if ( status == SHIP_STATUS_GONE )
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
sindex = ship_name_lookup( aigp->ship_name );
|
||||
|
||||
if ( sindex < 0 ) {
|
||||
Int3();
|
||||
@@ -1815,6 +1811,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// test code!!!
|
||||
if ( aip->goal_objnum == -1 ) {
|
||||
// -- MK, 11/9/97 -- I was always hitting this: Int3();
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
}
|
||||
|
||||
@@ -2048,8 +2045,8 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
switch ( current_goal->ai_mode ) {
|
||||
|
||||
case AI_GOAL_CHASE:
|
||||
if ( current_goal->target_name ) {
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
if ( current_goal->ship_name ) {
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
} else
|
||||
@@ -2061,14 +2058,13 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
break;
|
||||
|
||||
case AI_GOAL_CHASE_WEAPON:
|
||||
Assert( Weapons[current_goal->target_instance].objnum >= 0 );
|
||||
other_obj = &Objects[Weapons[current_goal->target_instance].objnum];
|
||||
Assert( other_obj->signature == current_goal->target_signature );
|
||||
Assert( Weapons[current_goal->wp_index].objnum != -1 );
|
||||
other_obj = &Objects[Weapons[current_goal->wp_index].objnum];
|
||||
ai_attack_object( objp, other_obj, NULL );
|
||||
break;
|
||||
|
||||
case AI_GOAL_GUARD:
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
// shipnum and other_obj are the shipnumber and object pointer of the object that you should
|
||||
@@ -2083,7 +2079,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
break;
|
||||
|
||||
case AI_GOAL_GUARD_WING:
|
||||
wingnum = wing_name_lookup( current_goal->target_name );
|
||||
wingnum = wing_name_lookup( current_goal->ship_name );
|
||||
Assert (wingnum != -1 ); // shouldn't get here if this is false!!!!
|
||||
ai_set_guard_wing(objp, wingnum);
|
||||
aip->submode_start_time = Missiontime;
|
||||
@@ -2095,18 +2091,18 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
|
||||
if ( current_goal->ai_mode == AI_GOAL_WAYPOINTS)
|
||||
flags |= WPF_REPEAT;
|
||||
ai_start_waypoints(objp, current_goal->wp_list, flags);
|
||||
ai_start_waypoints(objp, current_goal->wp_index, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
case AI_GOAL_FLY_TO_SHIP:
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
|
||||
ai_start_fly_to_ship(objp, shipnum);
|
||||
break;
|
||||
|
||||
case AI_GOAL_DOCK: {
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
|
||||
@@ -2123,9 +2119,9 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
// goal cannot continue. Spit out a warning and remove the goal.
|
||||
|
||||
// Goober5000 - do we have a specific ship to undock from?
|
||||
if ( current_goal->target_name != NULL )
|
||||
if ( current_goal->ship_name != NULL )
|
||||
{
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
|
||||
// hmm, perhaps he was destroyed
|
||||
if (shipnum == -1)
|
||||
@@ -2148,7 +2144,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
other_obj = dock_get_first_docked_object( objp );
|
||||
|
||||
// and add the ship name so it displays on the HUD
|
||||
current_goal->target_name = Ships[other_obj->instance].ship_name;
|
||||
current_goal->ship_name = Ships[other_obj->instance].ship_name;
|
||||
}
|
||||
// hmm, nobody exists that we can undock from
|
||||
else
|
||||
@@ -2158,6 +2154,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
}
|
||||
|
||||
if ( other_obj == NULL ) {
|
||||
//Int3();
|
||||
// assume that the guy he was docked with doesn't exist anymore. (i.e. a cargo containuer
|
||||
// can get destroyed while docked with a freighter.) We should just remove this goal and
|
||||
// let this ship pick up it's next goal.
|
||||
@@ -2186,7 +2183,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
case AI_GOAL_DESTROY_SUBSYSTEM:
|
||||
case AI_GOAL_DISABLE_SHIP:
|
||||
case AI_GOAL_DISARM_SHIP: {
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert( shipnum >= 0 );
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
ai_attack_object( objp, other_obj, NULL);
|
||||
@@ -2205,7 +2202,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
}
|
||||
|
||||
case AI_GOAL_CHASE_WING:
|
||||
wingnum = wing_name_lookup( current_goal->target_name );
|
||||
wingnum = wing_name_lookup( current_goal->ship_name );
|
||||
Assert( wingnum >= 0 );
|
||||
ai_attack_wing(objp, wingnum);
|
||||
break;
|
||||
@@ -2215,12 +2212,15 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
break;
|
||||
|
||||
case AI_GOAL_WARP: {
|
||||
int index;
|
||||
|
||||
index = current_goal->wp_index;
|
||||
mission_do_departure( objp );
|
||||
break;
|
||||
}
|
||||
|
||||
case AI_GOAL_EVADE_SHIP:
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert( shipnum >= 0 );
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
ai_evade_object( objp, other_obj);
|
||||
@@ -2249,7 +2249,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
// on wing AI code
|
||||
// clearing out goals is okay here since we are now what mode to set this AI object to.
|
||||
ai_clear_ship_goals( aip );
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert( shipnum >= 0 );
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
ai_form_on_wing( objp, other_obj );
|
||||
@@ -2258,7 +2258,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
// labels for support ship commands
|
||||
|
||||
case AI_GOAL_STAY_NEAR_SHIP: {
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert( shipnum >= 0 );
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
// todo MK: hook to keep support ship near other_obj -- other_obj could be the player object!!!
|
||||
@@ -2275,7 +2275,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
break;
|
||||
|
||||
case AI_GOAL_REARM_REPAIR:
|
||||
shipnum = ship_name_lookup( current_goal->target_name );
|
||||
shipnum = ship_name_lookup( current_goal->ship_name );
|
||||
Assert( shipnum >= 0 );
|
||||
other_obj = &Objects[Ships[shipnum].objnum];
|
||||
ai_rearm_repair( objp, current_goal->docker.index, other_obj, current_goal->dockee.index );
|
||||
@@ -2346,11 +2346,11 @@ void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *n
|
||||
}
|
||||
|
||||
if (flag) // is this a valid goal to parse for this conversion?
|
||||
if (!stricmp(goals[i].target_name, old_name)) {
|
||||
if (!stricmp(goals[i].ship_name, old_name)) {
|
||||
if (*new_name == '<') // target was just deleted..
|
||||
goals[i].ai_mode = AI_GOAL_NONE;
|
||||
else
|
||||
goals[i].target_name = ai_get_goal_target_name(new_name, &dummy);
|
||||
goals[i].ship_name = ai_get_goal_ship_name(new_name, &dummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2412,7 +2412,7 @@ int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
|
||||
if (flag) // is this a valid goal to parse for this conversion?
|
||||
{
|
||||
if (!stricmp(goals[i].target_name, name))
|
||||
if (!stricmp(goals[i].ship_name, name))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -2425,7 +2425,7 @@ char *ai_add_dock_name(char *str)
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
Assert(strlen(str) <= NAME_LENGTH - 1);
|
||||
Assert(strlen(str) < NAME_LENGTH - 1);
|
||||
for (i=0; i<Num_ai_dock_names; i++)
|
||||
if (!stricmp(Ai_dock_names[i], str))
|
||||
return Ai_dock_names[i];
|
||||
|
||||
+24
-24
@@ -26,35 +26,35 @@ struct ai_goal;
|
||||
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
|
||||
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
|
||||
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
|
||||
#define AI_GOAL_CHASE (1<<1) // 0x00000002
|
||||
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
|
||||
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
|
||||
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
|
||||
#define AI_GOAL_WARP (1<<5) // 0x00000020
|
||||
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
|
||||
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
|
||||
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
|
||||
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
|
||||
#define AI_GOAL_GUARD (1<<10) // 0x00000400
|
||||
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
|
||||
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
|
||||
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
|
||||
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
|
||||
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
|
||||
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
|
||||
#define AI_GOAL_CHASE (1<<1)
|
||||
#define AI_GOAL_DOCK (1<<2) // used for undocking as well
|
||||
#define AI_GOAL_WAYPOINTS (1<<3)
|
||||
#define AI_GOAL_WAYPOINTS_ONCE (1<<4)
|
||||
#define AI_GOAL_WARP (1<<5)
|
||||
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6)
|
||||
#define AI_GOAL_FORM_ON_WING (1<<7)
|
||||
#define AI_GOAL_UNDOCK (1<<8)
|
||||
#define AI_GOAL_CHASE_WING (1<<9)
|
||||
#define AI_GOAL_GUARD (1<<10)
|
||||
#define AI_GOAL_DISABLE_SHIP (1<<11)
|
||||
#define AI_GOAL_DISARM_SHIP (1<<12)
|
||||
#define AI_GOAL_CHASE_ANY (1<<13)
|
||||
#define AI_GOAL_IGNORE (1<<14)
|
||||
#define AI_GOAL_GUARD_WING (1<<15)
|
||||
#define AI_GOAL_EVADE_SHIP (1<<16)
|
||||
|
||||
// the next goals are for support ships only
|
||||
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
|
||||
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
|
||||
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
|
||||
#define AI_GOAL_STAY_NEAR_SHIP (1<<17)
|
||||
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18)
|
||||
#define AI_GOAL_REARM_REPAIR (1<<19)
|
||||
|
||||
// resume regular goals
|
||||
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
|
||||
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
|
||||
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
|
||||
#define AI_GOAL_STAY_STILL (1<<20)
|
||||
#define AI_GOAL_PLAY_DEAD (1<<21)
|
||||
#define AI_GOAL_CHASE_WEAPON (1<<22)
|
||||
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // kazan
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // Goober5000
|
||||
|
||||
// now the masks for ship types
|
||||
|
||||
|
||||
+59
-363
@@ -21,7 +21,6 @@
|
||||
#include "ai/aiinternal.h" //Included last, so less includes are needed
|
||||
#include "iff_defs/iff_defs.h"
|
||||
#include "weapon/muzzleflash.h"
|
||||
#include "parse/scripting.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
@@ -53,21 +52,15 @@ char *Turret_target_order_names[NUM_TURRET_ORDER_TYPES] = {
|
||||
"Asteroids",
|
||||
};
|
||||
|
||||
#define EEOF_BIG_ONLY (1<<0) // turret fires only at big and huge ships
|
||||
#define EEOF_SMALL_ONLY (1<<1) // turret fires only at small ships
|
||||
#define EEOF_TAGGED_ONLY (1<<2) // turret fires only at tagged ships
|
||||
#define EEOF_BEAM (1<<3) // turret is a beam
|
||||
#define EEOF_FLAK (1<<4) // turret is flak
|
||||
#define EEOF_LASER (1<<5) // turret is a laser
|
||||
#define EEOF_MISSILE (1<<6) // turret is a missile
|
||||
|
||||
typedef struct eval_enemy_obj_struct {
|
||||
int turret_parent_objnum; // parent of turret
|
||||
float weapon_travel_dist; // max targeting range of turret weapon
|
||||
int enemy_team_mask;
|
||||
int weapon_system_ok; // is the weapon subsystem of turret ship ok
|
||||
int eeo_flags;
|
||||
|
||||
bool big_only_flag; // turret fires only at big and huge ships
|
||||
bool small_only_flag; // turret fires only at small ships
|
||||
bool tagged_only_flag; // turret fires only at tagged ships
|
||||
bool beam_flag; // turret is a beam
|
||||
vec3d *tpos;
|
||||
vec3d *tvec;
|
||||
ship_subsys *turret_subsys;
|
||||
@@ -107,101 +100,6 @@ int object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_object_radius_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, vec3d *v2e, vec3d *predicted_pos, float distance)
|
||||
{
|
||||
float target_dist = distance;
|
||||
if (distance == 0.0f)
|
||||
target_dist = vm_vec_dist(predicted_pos,tpos);
|
||||
|
||||
if (object_in_turret_fov(objp, ss, tvec, tpos, target_dist + objp->radius)) {
|
||||
// so the targeted spot in not in fov but the enemy + radius is
|
||||
// lets align the darn gun and try shooting there
|
||||
vec3d temp_vec;
|
||||
float multiplier = 0;
|
||||
model_subsystem *tp = ss->system_info;
|
||||
|
||||
// project v2e_from_turret to turret normal
|
||||
// substract resultant vector from the temp_vec (v2e_from_turret)
|
||||
// adjust z component as necessary
|
||||
// calculate multiplier for the resultant vector
|
||||
// use multiplier and the z component and compose a new vector
|
||||
float dot = vm_vec_dot(v2e, tvec);
|
||||
|
||||
vm_vec_scale_add(&temp_vec, v2e, tvec, -dot);
|
||||
|
||||
if (IS_VEC_NULL_SQ_SAFE(&temp_vec)) {
|
||||
// return false, target is perfectly aligned over or below the turret
|
||||
// safe bet is to allow turret to reacquire better target
|
||||
return false;
|
||||
}
|
||||
|
||||
// normalize the vec, it needs to be done regardless
|
||||
vm_vec_normalize(&temp_vec);
|
||||
bool fix_elevation = false;
|
||||
bool fix_base_rot = false;
|
||||
|
||||
if (dot < tp->turret_fov) {
|
||||
dot = tp->turret_fov;
|
||||
fix_elevation = true;
|
||||
}
|
||||
if (dot > tp->turret_max_fov) {
|
||||
dot = tp->turret_max_fov;
|
||||
fix_elevation = true;
|
||||
}
|
||||
|
||||
if (tp->flags & MSS_FLAG_TURRET_ALT_MATH) {
|
||||
vec3d temp_vec2;
|
||||
vm_vec_rotate(&temp_vec2, &temp_vec, &ss->world_to_turret_matrix);
|
||||
|
||||
// now in turrets frame of reference
|
||||
// check if math is actually possible
|
||||
if (!((temp_vec2.xyz.x == 0) && (temp_vec2.xyz.y == 0))) {
|
||||
float temp_z = temp_vec2.xyz.z;
|
||||
temp_vec2.xyz.z = 0.0f;
|
||||
// make sure null vecs wont happen
|
||||
if (!IS_VEC_NULL_SQ_SAFE(&temp_vec2)) {
|
||||
vm_vec_normalize(&temp_vec2);
|
||||
// only do this if it actually is required
|
||||
if (-temp_vec2.xyz.y < tp->turret_y_fov) {
|
||||
float check_pos = 1;
|
||||
|
||||
fix_base_rot = true;
|
||||
temp_vec2.xyz.y = -tp->turret_y_fov;
|
||||
if (temp_vec2.xyz.x < 0)
|
||||
check_pos = -1;
|
||||
temp_vec2.xyz.x = check_pos * sqrtf(1 - (temp_vec2.xyz.y*temp_vec2.xyz.y));
|
||||
|
||||
// restore z component
|
||||
float scaler = sqrtf(1 - (temp_z*temp_z));
|
||||
vm_vec_scale(&temp_vec2,scaler);
|
||||
temp_vec2.xyz.z = temp_z;
|
||||
// back to world frame
|
||||
vm_vec_unrotate(&temp_vec, &temp_vec2, &ss->world_to_turret_matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fix_elevation || fix_base_rot) {
|
||||
if (fix_elevation) {
|
||||
multiplier = sqrtf(1 - (dot*dot));
|
||||
// keep the temp_vec scaled with the tweaked vector
|
||||
vm_vec_scale(&temp_vec, multiplier);
|
||||
}
|
||||
vm_vec_scale_add(v2e, &temp_vec, tvec, dot);
|
||||
// and we are done with v2e...
|
||||
vm_vec_scale_add(predicted_pos, tpos, v2e, target_dist);
|
||||
// and we are done with predicted position
|
||||
return true;
|
||||
} else {
|
||||
mprintf(("Warning: Function 'is_object_radius_in_turret_fov' was called\nwithout need to fix turret alignments\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// outside of the expanded radii, unable to align, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
// return 1 if bomb_objp is headed towards ship_objp
|
||||
int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
|
||||
{
|
||||
@@ -402,7 +300,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( objp->type == OBJ_SHIP ) {
|
||||
if ( (objp->type == OBJ_SHIP) ) {
|
||||
Assert( objp->instance >= 0 );
|
||||
ship *shipp;
|
||||
ship_info *sip;
|
||||
@@ -459,10 +357,9 @@ extern int Player_attacking_enabled;
|
||||
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
{
|
||||
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
|
||||
ship *shipp;
|
||||
ship *shipp;
|
||||
ship_subsys *ss = eeo->turret_subsys;
|
||||
float dist, dist_comp;
|
||||
bool turret_has_no_target = false;
|
||||
|
||||
// Don't look for bombs when weapon system is not ok
|
||||
if (objp->type == OBJ_WEAPON && !eeo->weapon_system_ok) {
|
||||
@@ -493,49 +390,28 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
}
|
||||
|
||||
// check if beam protected
|
||||
if (eeo->eeo_flags & EEOF_BEAM) {
|
||||
if (eeo->beam_flag) {
|
||||
if (objp->flags & OF_BEAM_PROTECTED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check if flak protected
|
||||
if (eeo->eeo_flags & EEOF_FLAK) {
|
||||
if (objp->flags & OF_FLAK_PROTECTED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check if laser protected
|
||||
if (eeo->eeo_flags & EEOF_LASER) {
|
||||
if (objp->flags & OF_LASER_PROTECTED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check if missile protected
|
||||
if (eeo->eeo_flags & EEOF_MISSILE) {
|
||||
if (objp->flags & OF_MISSILE_PROTECTED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// don't shoot at small ships if we shouldn't
|
||||
if (eeo->eeo_flags & EEOF_BIG_ONLY) {
|
||||
if (eeo->big_only_flag) {
|
||||
if (!(Ship_info[shipp->ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// don't shoot at big ships if we shouldn't
|
||||
if (eeo->eeo_flags & EEOF_SMALL_ONLY) {
|
||||
if (eeo->small_only_flag) {
|
||||
if ((Ship_info[shipp->ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check if turret flagged to only target tagged ships
|
||||
if (eeo->eeo_flags & EEOF_TAGGED_ONLY) {
|
||||
if (eeo->tagged_only_flag) {
|
||||
if (!ship_is_tagged(objp)) {
|
||||
return;
|
||||
}
|
||||
@@ -598,20 +474,9 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
}
|
||||
|
||||
if ((objp->type == OBJ_WEAPON) && check_weapon) {
|
||||
//Maybe restrict the number of turrets attacking this bomb
|
||||
if (ss->turret_max_bomb_ownage != -1) {
|
||||
int num_att_turrets = num_turrets_attacking(turret_parent_obj, OBJ_INDEX(objp));
|
||||
if (num_att_turrets > ss->system_info->turret_max_bomb_ownage) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Weapons[objp->instance].homing_object == &Objects[eeo->turret_parent_objnum] ) {
|
||||
if ( dist_comp < eeo->nearest_homing_bomb_dist ) {
|
||||
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
|
||||
turret_has_no_target = true;
|
||||
}
|
||||
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
eeo->nearest_homing_bomb_dist = dist_comp;
|
||||
eeo->nearest_homing_bomb_objnum = OBJ_INDEX(objp);
|
||||
}
|
||||
@@ -619,10 +484,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
// if not homing, check if bomb is flying towards ship
|
||||
} else if ( bomb_headed_towards_ship(objp, &Objects[eeo->turret_parent_objnum]) ) {
|
||||
if ( dist_comp < eeo->nearest_bomb_dist ) {
|
||||
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
|
||||
turret_has_no_target = true;
|
||||
}
|
||||
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
eeo->nearest_bomb_dist = dist_comp;
|
||||
eeo->nearest_bomb_objnum = OBJ_INDEX(objp);
|
||||
}
|
||||
@@ -651,10 +513,6 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
if (objp->flags & OF_PLAYER_SHIP) {
|
||||
max_turrets = The_mission.ai_profile->max_turret_ownage_player[Game_skill_level];
|
||||
}
|
||||
// Apply the per-turret limit, if there is one
|
||||
if (ss->turret_max_target_ownage != -1) {
|
||||
max_turrets = MIN(max_turrets, ss->system_info->turret_max_target_ownage);
|
||||
}
|
||||
if (num_att_turrets > max_turrets) {
|
||||
return;
|
||||
}
|
||||
@@ -682,10 +540,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
|
||||
// maybe update nearest attacker
|
||||
if ( dist_comp < eeo->nearest_attacker_dist ) {
|
||||
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
|
||||
turret_has_no_target = true;
|
||||
}
|
||||
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
// nprintf(("AI", "Nearest enemy = %s, dist = %7.3f, dot = %6.3f, fov = %6.3f\n", Ships[objp->instance].ship_name, dist, vm_vec_dot(&v2e, tvec), tp->turret_fov));
|
||||
eeo->nearest_attacker_dist = dist_comp;
|
||||
eeo->nearest_attacker_objnum = OBJ_INDEX(objp);
|
||||
@@ -700,10 +555,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
dist_comp *= 0.9f + (0.01f * asteroid_time_to_impact(objp));
|
||||
|
||||
if (dist_comp < eeo->nearest_dist ) {
|
||||
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
|
||||
turret_has_no_target = true;
|
||||
}
|
||||
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
|
||||
eeo->nearest_dist = dist_comp;
|
||||
eeo->nearest_objnum = OBJ_INDEX(objp);
|
||||
}
|
||||
@@ -740,7 +592,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp)
|
||||
// tpos => position of turret (world coords)
|
||||
// tvec => forward vector of turret (world coords)
|
||||
// current_enemy => objnum of current turret target
|
||||
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag, bool flak_flag, bool laser_flag, bool missile_flag)
|
||||
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
{
|
||||
//float weapon_travel_dist;
|
||||
int weapon_system_ok;
|
||||
@@ -768,26 +620,10 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
eeo.turret_parent_objnum = turret_parent_objnum;
|
||||
eeo.weapon_system_ok = weapon_system_ok;
|
||||
eeo.weapon_travel_dist = longest_turret_weapon_range(swp);
|
||||
|
||||
// set flags
|
||||
eeo.eeo_flags = 0;
|
||||
if (big_only_flag)
|
||||
eeo.eeo_flags |= EEOF_BIG_ONLY;
|
||||
if (small_only_flag)
|
||||
eeo.eeo_flags |= EEOF_SMALL_ONLY;
|
||||
if (tagged_only_flag)
|
||||
eeo.eeo_flags |= EEOF_TAGGED_ONLY;
|
||||
|
||||
// flags for weapon types
|
||||
if (beam_flag)
|
||||
eeo.eeo_flags |= EEOF_BEAM;
|
||||
else if (flak_flag)
|
||||
eeo.eeo_flags |= EEOF_FLAK;
|
||||
else if (laser_flag)
|
||||
eeo.eeo_flags |= EEOF_LASER;
|
||||
else if (missile_flag)
|
||||
eeo.eeo_flags |= EEOF_MISSILE;
|
||||
|
||||
eeo.big_only_flag = big_only_flag;
|
||||
eeo.small_only_flag = small_only_flag;
|
||||
eeo.tagged_only_flag = tagged_only_flag;
|
||||
eeo.beam_flag = beam_flag;
|
||||
eeo.enemy_team_mask = enemy_team_mask;
|
||||
eeo.current_enemy = current_enemy;
|
||||
eeo.tpos = tpos;
|
||||
@@ -836,9 +672,9 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
else
|
||||
tt = &Ai_tp_list[Weapon_info[priority_weapon_idx].targeting_priorities[i]];
|
||||
|
||||
int n_types = (int)tt->ship_type.size();
|
||||
int n_s_classes = (int)tt->ship_class.size();
|
||||
int n_w_classes = (int)tt->weapon_class.size();
|
||||
int n_types = tt->ship_type.size();
|
||||
int n_s_classes = tt->ship_class.size();
|
||||
int n_w_classes = tt->weapon_class.size();
|
||||
|
||||
bool found_something;
|
||||
object *ptr = GET_FIRST(&obj_used_list);
|
||||
@@ -1058,15 +894,10 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
|
||||
|
||||
tp = turret_subsys->system_info;
|
||||
enemy_team_mask = iff_get_attackee_mask(obj_team(&Objects[objnum]));
|
||||
|
||||
bool big_only_flag = all_turret_weapons_have_flags(&turret_subsys->weapons, WIF_HUGE);
|
||||
bool small_only_flag = all_turret_weapons_have_flags2(&turret_subsys->weapons, WIF2_SMALL_ONLY);
|
||||
bool tagged_only_flag = all_turret_weapons_have_flags2(&turret_subsys->weapons, WIF2_TAGGED_ONLY) || (turret_subsys->weapons.flags & SW_FLAG_TAGGED_ONLY);
|
||||
|
||||
bool beam_flag = turret_weapon_has_flags(&turret_subsys->weapons, WIF_BEAM);
|
||||
bool flak_flag = turret_weapon_has_flags(&turret_subsys->weapons, WIF_FLAK);
|
||||
bool laser_flag = turret_weapon_has_subtype(&turret_subsys->weapons, WP_LASER);
|
||||
bool missile_flag = turret_weapon_has_subtype(&turret_subsys->weapons, WP_MISSILE);
|
||||
bool beam_flag = all_turret_weapons_have_flags(&turret_subsys->weapons, WIF_BEAM);
|
||||
|
||||
// If a small ship and target_objnum != -1, use that as goal.
|
||||
ai_info *aip = &Ai_info[Ships[Objects[objnum].instance].ai_index];
|
||||
@@ -1100,14 +931,8 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
|
||||
}
|
||||
|
||||
// maybe use ship target_objnum if valid for turret
|
||||
// check for beam weapon and beam protected, etc.
|
||||
bool skip = false;
|
||||
if ( (target_flags & OF_BEAM_PROTECTED) && beam_flag ) skip = true;
|
||||
else if ( (target_flags & OF_FLAK_PROTECTED) && flak_flag ) skip = true;
|
||||
else if ( (target_flags & OF_LASER_PROTECTED) && laser_flag ) skip = true;
|
||||
else if ( (target_flags & OF_MISSILE_PROTECTED) && missile_flag ) skip = true;
|
||||
|
||||
if (!skip) {
|
||||
// check for beam weapon and beam protected
|
||||
if ( !((target_flags & OF_BEAM_PROTECTED) && (beam_flag)) ) {
|
||||
if ( Objects[aip->target_objnum].type == OBJ_SHIP ) {
|
||||
// check for huge weapon and huge ship
|
||||
if ( !big_only_flag || (Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].flags & (SIF_BIG_SHIP|SIF_HUGE_SHIP)) ) {
|
||||
@@ -1120,13 +945,7 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
|
||||
dist = vm_vec_normalized_dir(&v2e, &Objects[aip->target_objnum].pos, tpos);
|
||||
|
||||
in_fov = turret_fov_test(turret_subsys, tvec, &v2e);
|
||||
|
||||
if (turret_subsys->flags & SSF_FOV_EDGE_CHECK) {
|
||||
if (in_fov == false)
|
||||
if (object_in_turret_fov(&Objects[aip->target_objnum], turret_subsys, tvec, tpos, dist + Objects[aip->target_objnum].radius))
|
||||
in_fov = true;
|
||||
}
|
||||
// MODIFY FOR ATTACKING BIG SHIP
|
||||
// MODIFY FOR ATTACKING BIG SHIP
|
||||
// dot += (0.5f * Objects[aip->target_objnum].radius / dist);
|
||||
if (in_fov) {
|
||||
return aip->target_objnum;
|
||||
@@ -1138,13 +957,9 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
|
||||
}
|
||||
}
|
||||
|
||||
enemy_objnum = get_nearest_turret_objnum(objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag, flak_flag, laser_flag, missile_flag);
|
||||
enemy_objnum = get_nearest_turret_objnum(objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag);
|
||||
if ( enemy_objnum >= 0 ) {
|
||||
Assert( !((Objects[enemy_objnum].flags & OF_BEAM_PROTECTED) && beam_flag) );
|
||||
Assert( !((Objects[enemy_objnum].flags & OF_FLAK_PROTECTED) && flak_flag) );
|
||||
Assert( !((Objects[enemy_objnum].flags & OF_LASER_PROTECTED) && laser_flag) );
|
||||
Assert( !((Objects[enemy_objnum].flags & OF_MISSILE_PROTECTED) && missile_flag) );
|
||||
|
||||
if ( Objects[enemy_objnum].flags & OF_PROTECTED ) {
|
||||
Int3();
|
||||
enemy_objnum = aip->target_objnum;
|
||||
@@ -1179,22 +994,21 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
vec3d * gun_pos;
|
||||
model_subsystem *tp = ssp->system_info;
|
||||
|
||||
//ship_model_start(objp);
|
||||
ship_model_start(objp);
|
||||
|
||||
gun_pos = &tp->turret_firing_point[ssp->turret_next_fire_pos % tp->turret_num_firing_points];
|
||||
|
||||
//model_find_world_point(gpos, gun_pos, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
|
||||
model_instance_find_world_point(gpos, gun_pos, tp->model_num, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient, &objp->pos);
|
||||
model_find_world_point(gpos, gun_pos, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
|
||||
|
||||
if (use_angles)
|
||||
model_instance_find_world_dir(gvec, &tp->turret_norm, tp->model_num, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
|
||||
model_find_world_dir(gvec, &tp->turret_norm, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
|
||||
else {
|
||||
//vector gun_pos2;
|
||||
//vm_vec_add(&gun_pos2, gpos, gun_pos);
|
||||
vm_vec_normalized_dir(gvec, targetp, gpos);
|
||||
}
|
||||
|
||||
//ship_model_stop(objp);
|
||||
ship_model_stop(objp);
|
||||
|
||||
// per firingpoint based changes go here for turrets
|
||||
}
|
||||
@@ -1292,11 +1106,6 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
|
||||
|
||||
in_fov = turret_fov_test(ss, gvec, &v2e);
|
||||
|
||||
if (ss->flags & SSF_FOV_EDGE_CHECK) {
|
||||
if (in_fov == false)
|
||||
in_fov = is_object_radius_in_turret_fov(&Objects[ss->turret_enemy_objnum], ss, gvec, &gun_pos, &v2e, predicted_enemy_pos, 0.0f);
|
||||
}
|
||||
|
||||
if (in_fov) {
|
||||
ret_val = model_rotate_gun(Ship_info[shipp->ship_info_index].model_num,
|
||||
tp, &Objects[parent_objnum].orient,
|
||||
@@ -1572,16 +1381,13 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
wait *= frand_range(0.9f, 1.1f);
|
||||
}
|
||||
|
||||
if(turret->rof_scaler != 1.0f)
|
||||
wait /= get_adjusted_turret_rof(turret);
|
||||
|
||||
(*fs_dest) = timestamp((int)wait);
|
||||
}
|
||||
|
||||
// Decide if a turret should launch an aspect seeking missile
|
||||
int turret_should_fire_aspect(ship_subsys *turret, weapon_info *wip, bool in_sight)
|
||||
int turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
|
||||
{
|
||||
if ( in_sight && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
|
||||
if ( (dot > AICODE_TURRET_DUMBFIRE_ANGLE) && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1636,34 +1442,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
wip = get_turret_weapon_wip(&turret->weapons, weapon_num);
|
||||
int turret_weapon_class = WEAPON_INFO_INDEX(wip);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// moved here from check_ok_to_fire
|
||||
if (turret->turret_enemy_objnum >= 0) {
|
||||
object *tobjp = &Objects[turret->turret_enemy_objnum];
|
||||
|
||||
// should not get this far. check if ship is protected from beam and weapon is type beam
|
||||
if ( (wip->wi_flags & WIF_BEAM) && (tobjp->flags & OF_BEAM_PROTECTED) ) {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
// should not get this far. check if ship is protected from flak and weapon is type flak
|
||||
else if ( (wip->wi_flags & WIF_FLAK) && (tobjp->flags & OF_FLAK_PROTECTED) ) {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
// should not get this far. check if ship is protected from laser and weapon is type laser
|
||||
else if ( (wip->subtype == WP_LASER) && (tobjp->flags & OF_LASER_PROTECTED) ) {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
// should not get this far. check if ship is protected from missile and weapon is type missile
|
||||
else if ( (wip->subtype == WP_MISSILE) && (tobjp->flags & OF_MISSILE_PROTECTED) ) {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (check_ok_to_fire(parent_objnum, turret->turret_enemy_objnum, wip)) {
|
||||
vm_vector_2_matrix(&turret_orient, turret_fvec, NULL, NULL);
|
||||
turret->turret_last_fire_direction = *turret_fvec;
|
||||
@@ -1676,6 +1454,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
if (wip->wi_flags & WIF_BEAM) {
|
||||
// if this beam isn't free to fire
|
||||
if (!(turret->weapons.flags & SW_FLAG_BEAM_FREE)) {
|
||||
//WMC - remove this
|
||||
//Int3(); // should never get this far
|
||||
return false;
|
||||
}
|
||||
beam_fire_info fire_info;
|
||||
@@ -1689,6 +1469,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
fire_info.target = &Objects[turret->turret_enemy_objnum];
|
||||
fire_info.target_subsys = NULL;
|
||||
fire_info.turret = turret;
|
||||
fire_info.fighter_beam = false;
|
||||
|
||||
// fire a beam weapon
|
||||
beam_fire(&fire_info);
|
||||
@@ -1706,11 +1487,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
// now do anything else
|
||||
else {
|
||||
for (int i=0; i < wip->shots; i++)
|
||||
{
|
||||
// zookeeper - Firepoints should cycle normally between shots,
|
||||
// so we need to get the position info separately for each shot
|
||||
ship_get_global_turret_gun_info(&Objects[parent_objnum], turret, turret_pos, turret_fvec, 1, NULL);
|
||||
|
||||
{
|
||||
weapon_objnum = weapon_create( turret_pos, &turret_orient, turret_weapon_class, parent_objnum, -1, 1);
|
||||
weapon_set_tracking_info(weapon_objnum, parent_objnum, turret->turret_enemy_objnum, 1, turret->targeted_subsys);
|
||||
|
||||
@@ -1718,12 +1495,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
objp=&Objects[weapon_objnum];
|
||||
wp=&Weapons[objp->instance];
|
||||
|
||||
parent_ship->last_fired_turret = turret;
|
||||
turret->last_fired_weapon_info_index = wp->weapon_info_index;
|
||||
|
||||
Script_system.SetHookObjects(3, "Ship", &Objects[parent_objnum], "Weapon", objp, "Target", &Objects[turret->turret_enemy_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
|
||||
|
||||
//nprintf(("AI", "Turret_time_enemy_in_range = %7.3f\n", ss->turret_time_enemy_in_range));
|
||||
if (weapon_objnum != -1) {
|
||||
wp->target_num = turret->turret_enemy_objnum;
|
||||
@@ -1766,14 +1537,13 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
|
||||
if ( wip->launch_snd != -1 ) {
|
||||
// Don't play turret firing sound if turret sits on player ship... it gets annoying.
|
||||
if ( parent_objnum != OBJ_INDEX(Player_obj) || (turret->flags & SSF_PLAY_SOUND_FOR_PLAYER) ) {
|
||||
if ( parent_objnum != OBJ_INDEX(Player_obj) ) {
|
||||
snd_play_3d( &Snds[wip->launch_snd], turret_pos, &View_position );
|
||||
}
|
||||
}
|
||||
}
|
||||
turret->turret_next_fire_pos++;
|
||||
}
|
||||
turret->turret_next_fire_pos--;
|
||||
|
||||
// reset any animations if we need to
|
||||
// (I'm not sure how accurate this timestamp would be in practice - taylor)
|
||||
if (turret->turret_animation_position == MA_POS_READY)
|
||||
@@ -1920,6 +1690,14 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
return;
|
||||
}
|
||||
|
||||
// starting animation checks
|
||||
if (ss->turret_animation_position == MA_POS_NOT_SET) {
|
||||
if ( model_anim_start_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num, 1) ) {
|
||||
ss->turret_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num);
|
||||
ss->turret_animation_position = MA_POS_SET;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss->turret_animation_position == MA_POS_SET) {
|
||||
if ( timestamp_elapsed(ss->turret_animation_done_time) ) {
|
||||
ss->turret_animation_position = MA_POS_READY;
|
||||
@@ -2091,12 +1869,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
}
|
||||
}
|
||||
|
||||
if ( wip->wi_flags2 & WIF2_SMALL_ONLY ) {
|
||||
if ( (lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lep->type == OBJ_SHIP) {
|
||||
// Check if we're targeting a protected ship
|
||||
if (lep->flags & OF_PROTECTED) {
|
||||
@@ -2111,24 +1883,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
continue;
|
||||
}
|
||||
// Check if we're targeting a flak protected ship with a flak weapon
|
||||
else if ( (lep->flags & OF_FLAK_PROTECTED) && (wip->wi_flags & WIF_FLAK) ) {
|
||||
ss->turret_enemy_objnum = -1;
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
continue;
|
||||
}
|
||||
// Check if we're targeting a laser protected ship with a laser weapon
|
||||
else if ( (lep->flags & OF_LASER_PROTECTED) && (wip->subtype == WP_LASER) ) {
|
||||
ss->turret_enemy_objnum = -1;
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
continue;
|
||||
}
|
||||
// Check if we're targeting a missile protected ship with a missile weapon
|
||||
else if ( (lep->flags & OF_MISSILE_PROTECTED) && (wip->subtype == WP_MISSILE) ) {
|
||||
ss->turret_enemy_objnum = -1;
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2151,8 +1905,8 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
if(num_valid < 1)
|
||||
ss->turret_enemy_objnum = -1;
|
||||
|
||||
// Maybe pick a new enemy, unless targeting has been taken over by scripting
|
||||
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override ) {
|
||||
// Maybe pick a new enemy.
|
||||
if ( turret_should_pick_new_target(ss) ) {
|
||||
Num_find_turret_enemy++;
|
||||
int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum);
|
||||
//Assert(objnum < 0 || is_target_beam_valid(tp, objnum));
|
||||
@@ -2338,7 +2092,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
{
|
||||
turret_update_enemy_in_range(ss, 2*wip->fire_wait);
|
||||
}
|
||||
if ( turret_should_fire_aspect(ss, wip, in_sight) )
|
||||
if ( turret_should_fire_aspect(ss, dot, wip) )
|
||||
{
|
||||
ok_to_fire = true;
|
||||
}
|
||||
@@ -2351,7 +2105,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
}
|
||||
// Check if turret should fire and enemy's engines are
|
||||
// in line of sight
|
||||
if (turret_should_fire_aspect(ss, wip, in_sight) &&
|
||||
if (turret_should_fire_aspect(ss, dot, wip) &&
|
||||
ship_get_closest_subsys_in_sight(&Ships[lep->signature], SUBSYSTEM_ENGINE, &gpos))
|
||||
{
|
||||
ok_to_fire = true;
|
||||
@@ -2365,7 +2119,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
|
||||
vm_vec_scale_add(&end, &gpos, &gvec, model_get_radius(model_num));
|
||||
|
||||
hull_check.model_instance_num = shipp->model_instance_num;
|
||||
hull_check.model_num = model_num;
|
||||
hull_check.orient = &objp->orient;
|
||||
hull_check.pos = &objp->pos;
|
||||
@@ -2378,40 +2131,18 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
}
|
||||
}
|
||||
|
||||
if ( ok_to_fire )
|
||||
{
|
||||
// starting animation checks
|
||||
if (ss->turret_animation_position == MA_POS_NOT_SET) {
|
||||
if ( model_anim_start_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num, 1) ) {
|
||||
ss->turret_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num);
|
||||
ss->turret_animation_position = MA_POS_SET;
|
||||
}
|
||||
}
|
||||
|
||||
//Wait until the animation is done to actually fire
|
||||
if (tp->flags & MSS_FLAG_TURRET_ANIM_WAIT && (ss->turret_animation_position != MA_POS_READY))
|
||||
{
|
||||
ok_to_fire = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ok_to_fire )
|
||||
{
|
||||
something_was_ok_to_fire = true;
|
||||
Num_turrets_fired++;
|
||||
|
||||
|
||||
//Pass along which gun we are using
|
||||
if (tp->flags & MSS_FLAG_TURRET_SALVO)
|
||||
turret_fire_weapon(valid_weapons[0], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
|
||||
else
|
||||
turret_fire_weapon(valid_weapons[i], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
|
||||
} else {
|
||||
// make sure salvo fire mode does not turn into autofire
|
||||
if ((tp->flags & MSS_FLAG_TURRET_SALVO) && ((i + 1) == number_of_firings)) {
|
||||
ai_info *parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
|
||||
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
|
||||
}
|
||||
}
|
||||
// moved this here so we increment the fire pos only after we have fired and not during it
|
||||
ss->turret_next_fire_pos++;
|
||||
}
|
||||
|
||||
@@ -2421,14 +2152,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
//Impose a penalty on turret accuracy for losing site of its goal, or just not being able to fire.
|
||||
turret_update_enemy_in_range(ss, -4*Weapon_info[ss->turret_best_weapon].fire_wait);
|
||||
ss->turret_next_fire_stamp = timestamp(500);
|
||||
|
||||
// If nothing is OK to fire (lost track of the target?)
|
||||
// reset the target (so we don't continue to track what we can't hit)
|
||||
if (tp->flags2 & MSS_FLAG2_TURRET_ONLY_TARGET_IF_CAN_FIRE)
|
||||
{
|
||||
ss->turret_enemy_objnum = -1; // Reset enemy objnum, find a new one next frame.
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2477,7 +2200,7 @@ bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
|
||||
{
|
||||
model_subsystem *tp = ss->system_info;
|
||||
float dot = vm_vec_dot(v2e, gvec);
|
||||
if (((dot + size_mod) >= tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov))
|
||||
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -2487,19 +2210,17 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
|
||||
{
|
||||
model_subsystem *tp = ss->system_info;
|
||||
float dot = vm_vec_dot(v2e, gvec);
|
||||
if (((dot + size_mod) >= tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
|
||||
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
|
||||
vec3d of_dst;
|
||||
vm_vec_rotate( &of_dst, v2e, &ss->world_to_turret_matrix );
|
||||
vm_vec_normalize(&of_dst);
|
||||
if ((of_dst.xyz.x == 0) && (of_dst.xyz.y == 0)) {
|
||||
return true;
|
||||
} else {
|
||||
of_dst.xyz.z = 0;
|
||||
if (!IS_VEC_NULL_SQ_SAFE(&of_dst)) {
|
||||
vm_vec_normalize(&of_dst);
|
||||
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
|
||||
if ((-of_dst.xyz.y + size_mod) >= tp->turret_y_fov)
|
||||
return true;
|
||||
}
|
||||
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
|
||||
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -2515,28 +2236,3 @@ bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
|
||||
|
||||
return in_fov;
|
||||
}
|
||||
|
||||
float get_adjusted_turret_rof(ship_subsys *ss)
|
||||
{
|
||||
float tempf = ss->rof_scaler;
|
||||
|
||||
// optional reset switch (negative value)
|
||||
if (tempf < 0) {
|
||||
ss->rof_scaler = 1.0f;
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if (tempf == 0) {
|
||||
// special case returning the number of firingpoints
|
||||
ss->rof_scaler = (float) ss->system_info->turret_num_firing_points;
|
||||
tempf = ss->rof_scaler;
|
||||
|
||||
// safety check to avoid div/0 issues
|
||||
if (tempf == 0) {
|
||||
ss->rof_scaler = 1.0f;
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return tempf;
|
||||
}
|
||||
+181
-110
@@ -31,17 +31,16 @@ anim_instance anim_render_list;
|
||||
#define MAX_ANIM_INSTANCES 25
|
||||
anim_instance anim_render_instance[MAX_ANIM_INSTANCES];
|
||||
|
||||
int Anim_paused; /// Global variable to pause the playing back of anims
|
||||
int Anim_paused; // global variable to pause the playing back of anims
|
||||
int Anim_inited = FALSE;
|
||||
|
||||
fix t1,t2;
|
||||
|
||||
int Anim_ignore_frametime=0; // flag used to ignore frametime... useful when need to avoid saturated frametimes
|
||||
|
||||
/**
|
||||
* @brief Initialise animation
|
||||
* @details Queue all the ::anim_render_instance[] elements onto the ::anim_free_list
|
||||
*/
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// anim_init() will queue all the anim_render_instance[] elements onto the anim_free_list
|
||||
//
|
||||
void anim_init()
|
||||
{
|
||||
int i;
|
||||
@@ -61,9 +60,9 @@ void anim_init()
|
||||
Anim_inited = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display the frames for the currently playing anims
|
||||
*/
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// anim_render_all() will display the frames for the currently playing anims
|
||||
//
|
||||
void anim_render_all(int screen_id, float frametime)
|
||||
{
|
||||
anim_instance* A;
|
||||
@@ -86,10 +85,10 @@ void anim_render_all(int screen_id, float frametime)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display the frames for the passed animation
|
||||
* @details It will ignore animations which do not have the same id as the passed screen_id
|
||||
*/
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// anim_render_one() will display the frames for the passed animation, it will ignore animations which
|
||||
// do not have the same id as the passed screen_id
|
||||
//
|
||||
void anim_render_one(int screen_id, anim_instance *ani, float frametime)
|
||||
{
|
||||
// make sure this guy's screen id matches the passed one
|
||||
@@ -110,17 +109,14 @@ void anim_render_one(int screen_id, anim_instance *ani, float frametime)
|
||||
|
||||
MONITOR(NumANIPlayed)
|
||||
|
||||
/**
|
||||
* @brief Setup an anim_play_struct for passing into ::anim_play().
|
||||
* @details Will fill in default values, which you can then change before calling ::anim_play().
|
||||
*/
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int base_w, int base_h)
|
||||
// Setup an anim_play_struct for passing into anim_play(). Will fill in default values, which you
|
||||
// can then change before calling anim_play().
|
||||
//
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y)
|
||||
{
|
||||
aps->anim_info = a_info;
|
||||
aps->x = x;
|
||||
aps->y = y;
|
||||
aps->base_w = base_w;
|
||||
aps->base_h = base_h;
|
||||
aps->start_at = 0;
|
||||
aps->stop_at = a_info->total_frames - 1;
|
||||
aps->screen_id = 0;
|
||||
@@ -133,21 +129,49 @@ void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int base_
|
||||
aps->ping_pong = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Will add an anim instance to the anim_render_list.
|
||||
* This will cause the anim to be played at the x,y position specified in the parameter list.
|
||||
*
|
||||
* @param aps Compressed animation that we should make an instance from
|
||||
* @return If success pointer to instance, NULL if anim anim could not be played
|
||||
*/
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// anim_play() will add an anim instance to the anim_render_list. This will cause the
|
||||
// anim to be played at the x,y position specified in the parameter list.
|
||||
//
|
||||
// input:
|
||||
//
|
||||
// anim_info => the compressed animation that we should make an instance from
|
||||
// x => x position of animation to play at (top left corner)
|
||||
// y => y position of animation to play at ( top left corner)
|
||||
// start_at => frame number to start at (note: numbering is from 0->num_frames-1)
|
||||
// stop_at => frame number to stop at (note: numbering is from 0->num_frames-1)
|
||||
// screen_id => OPTIONAL (default value 0): screen signature so animation only plays when
|
||||
// anim_render_all() called with that same signature
|
||||
// world_pos => OPTIONAL (default value NULL): only give a world pos when you want to
|
||||
// play the animation at a 3D location. You must specify radius when
|
||||
// this is non-null.
|
||||
// radius => OPTIONAL (default value 0): only needed when the animation is playing
|
||||
// as a 3D animation (this is only when world_pos in not NULL).
|
||||
// fi => OPTIONAL (default value 0): framerate indepentdent flag, when set TRUE
|
||||
// the animation will skip frames if necessary to maintain the fps value
|
||||
// associated with the animation
|
||||
// color => OPTIONAL (default value NULL) address of an alpha color struct. Only
|
||||
// required when the animation should be drawn with an alpha color.
|
||||
// skip_frames => OPTIONAL (default value 1) should anim skip frames when doing framerate
|
||||
// independent playback
|
||||
// looped => OPTIONAL (default value 0) should anim play looped (ie forever)
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// pointer to instance => success
|
||||
// NULL => if anim anim could not be played
|
||||
//
|
||||
anim_instance *anim_play(anim_play_struct *aps)
|
||||
{
|
||||
Assert( aps->anim_info != NULL );
|
||||
Assert( aps->start_at >= 0 );
|
||||
Assert( aps->stop_at < aps->anim_info->total_frames );
|
||||
// Assert( aps->stop_at >= aps->start_at );
|
||||
Assert( !(aps->looped && aps->ping_pong) ); // shouldn't have these both set at once
|
||||
|
||||
MONITOR_INC(NumANIPlayed, 1);
|
||||
|
||||
// if (aps->ping_pong && !(aps->anim_info->flags & ANF_ALL_KEYFRAMES));
|
||||
|
||||
anim_instance *instance;
|
||||
|
||||
@@ -195,14 +219,6 @@ anim_instance *anim_play(anim_play_struct *aps)
|
||||
instance->xlate_pal = 0;
|
||||
}
|
||||
|
||||
if(aps->base_w < 0 || aps->base_h < 0) {
|
||||
instance->base_w = gr_screen.max_w_unscaled;
|
||||
instance->base_h = gr_screen.max_h_unscaled;
|
||||
} else {
|
||||
instance->base_w = aps->base_w;
|
||||
instance->base_h = aps->base_h;
|
||||
}
|
||||
|
||||
// determining the start_at frame is more complicated, since it must be a key-frame.
|
||||
// Futhermore, need to subtract 1 from key-frame number, since frame number is always
|
||||
// incremented the first time anim_show_next_frame() is called
|
||||
@@ -227,6 +243,16 @@ anim_instance *anim_play(anim_play_struct *aps)
|
||||
|
||||
idx++;
|
||||
}
|
||||
/*while (keyp) {
|
||||
if (( (keyp->frame_num-1) <= frame_num) && ( (keyp->frame_num-1) > key)) { // find closest key
|
||||
key = keyp->frame_num-1;
|
||||
offset = keyp->offset;
|
||||
if ( key == frame_num )
|
||||
break;
|
||||
}
|
||||
|
||||
keyp = keyp->next;
|
||||
}*/
|
||||
|
||||
if (key > instance->frame_num) { // best key is closer than current position
|
||||
instance->frame_num = key;
|
||||
@@ -244,17 +270,20 @@ anim_instance *anim_play(anim_play_struct *aps)
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is called to blit the next frame of an anim instance to the screen.
|
||||
* This is normally called by the anim_render_all() function.
|
||||
*
|
||||
* @param instance Pointer to animation instance
|
||||
* @param frametime Time elapsed since last call, in seconds
|
||||
*/
|
||||
// -----------------------------------------------------------------------------
|
||||
// anim_show_next_frame()
|
||||
//
|
||||
// This function is called to blit the next frame of an anim instance to the
|
||||
// screen. This is normally called by the anim_render_all() function.
|
||||
//
|
||||
// input: instance => pointer to animation instance
|
||||
// frametime => time elapsed since last call, in seconds
|
||||
//
|
||||
|
||||
int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
{
|
||||
int bitmap_id, bitmap_flags=0, new_frame_num, frame_diff=0, i, n_frames=0,frame_save;
|
||||
float percent_through, decompress_time, render_time, time;
|
||||
int bitmap_id, bitmap_flags=0, new_frame_num, frame_diff=0, i, n_frames=0,frame_save;
|
||||
float percent_through, decompress_time, render_time, time;
|
||||
vertex image_vertex;
|
||||
int aabitmap = 0;
|
||||
int bpp = 16;
|
||||
@@ -336,6 +365,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
instance->time_elapsed = 0.0f;
|
||||
} else if(instance->ping_pong) { // pingponged animations
|
||||
instance->frame_num = instance->stop_at;
|
||||
// instance->time_elapsed = 0.0f;
|
||||
anim_reverse_direction(instance);
|
||||
} else { // one-shot animations
|
||||
instance->frame_num = instance->stop_at;
|
||||
@@ -350,6 +380,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
instance->time_elapsed = 0.0f;
|
||||
} else if(instance->ping_pong) { // pingponged animations
|
||||
instance->frame_num = instance->stop_at;
|
||||
// instance->time_elapsed = 0.0f;
|
||||
anim_reverse_direction(instance);
|
||||
} else { // one-shot animations
|
||||
instance->frame_num = instance->stop_at+1;
|
||||
@@ -373,6 +404,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
}
|
||||
}
|
||||
Assert(frame_diff >= 0);
|
||||
// nprintf(("Alan","FRAME DIFF: %d\n",frame_diff));
|
||||
Assert( instance->frame_num >= 0 && instance->frame_num < instance->parent->total_frames );
|
||||
|
||||
// if the anim is paused, ignore all the above changes and still display this frame
|
||||
@@ -383,6 +415,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
}
|
||||
|
||||
if (instance->parent->flags & ANF_XPARENT){
|
||||
// bitmap_flags = BMP_XPARENT;
|
||||
bitmap_flags = 0;
|
||||
}
|
||||
bpp = 16;
|
||||
@@ -488,8 +521,6 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
|
||||
// determine x,y to display the bitmap at
|
||||
if ( instance->world_pos == NULL ) {
|
||||
gr_set_screen_scale(instance->base_w, instance->base_h);
|
||||
gr_set_clip(0, 0, instance->base_w, instance->base_h, false);
|
||||
if ( instance->aa_color == NULL ) {
|
||||
gr_bitmap(instance->x, instance->y);
|
||||
}
|
||||
@@ -497,8 +528,6 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
gr_set_color_fast( (color*)instance->aa_color );
|
||||
gr_aabitmap(instance->x, instance->y);
|
||||
}
|
||||
gr_reset_screen_scale();
|
||||
gr_reset_clip();
|
||||
}
|
||||
else {
|
||||
g3_rotate_vertex(&image_vertex,instance->world_pos);
|
||||
@@ -506,18 +535,23 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
|
||||
}
|
||||
|
||||
//bm_release(bitmap_id);
|
||||
instance->last_bitmap = bitmap_id;
|
||||
}
|
||||
|
||||
t2 = timer_get_fixed_seconds();
|
||||
render_time = f2fl(t2-t1);
|
||||
|
||||
// nprintf(("Alan","DECOMPRESS: %.3fms RENDER: %.3fms\n", decompress_time*1000, render_time*1000));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop an anim instance that is on the anim_render_list from playing
|
||||
*/
|
||||
// -----------------------------------------------------------------------------
|
||||
// anim_stop_playing()
|
||||
//
|
||||
// Stop an anim instance that is on the anim_render_list from playing
|
||||
//
|
||||
int anim_stop_playing(anim_instance* instance)
|
||||
{
|
||||
Assert(instance != NULL);
|
||||
@@ -528,12 +562,14 @@ int anim_stop_playing(anim_instance* instance)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free a particular animation instance that is on the anim_render_list.
|
||||
* Do not call this function to free an animation instance in general (use
|
||||
* free_anim_instance() for that), only when you want to free an instance
|
||||
* that is on the anim_render_list
|
||||
*/
|
||||
// -----------------------------------------------------------------------------
|
||||
// anim_release_render_instance()
|
||||
//
|
||||
// Free a particular animation instance that is on the anim_render_list. Do
|
||||
// not call this function to free an animation instance in general (use
|
||||
// free_anim_instance() for that), only when you want to free an instance
|
||||
// that is on the anim_render_list
|
||||
//
|
||||
void anim_release_render_instance(anim_instance* instance)
|
||||
{
|
||||
Assert( instance != NULL );
|
||||
@@ -556,13 +592,16 @@ void anim_release_render_instance(anim_instance* instance)
|
||||
list_append( &anim_free_list, instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free all anim instances that are on the anim_render_list.
|
||||
*
|
||||
* @param screen_id Optional parameter that lets you only free a subset of the anim instances.
|
||||
* A screen_id of 0 is the default value, and this is used for animations that always play when
|
||||
* they are placed on the aim_render_list.
|
||||
*/
|
||||
// -----------------------------------------------------------------------------
|
||||
// anim_release_all_instances()
|
||||
//
|
||||
// Free all anim instances that are on the anim_render_list.
|
||||
//
|
||||
// input: screen_id => optional parameter that lets you only free a subset
|
||||
// of the anim instances. A screen_id of 0 is the default
|
||||
// value, and this is used for animations that always play
|
||||
// when they are placed on the aim_render_list.
|
||||
//
|
||||
void anim_release_all_instances(int screen_id)
|
||||
{
|
||||
anim_instance* A;
|
||||
@@ -586,18 +625,18 @@ void anim_release_all_instances(int screen_id)
|
||||
//
|
||||
// Read the header of a .ani file. Below is the format of a .ani header
|
||||
//
|
||||
// #bytes | description
|
||||
// #bytes | description
|
||||
// 2 | obsolete, kept for compatibility with old versions
|
||||
// 2 | version number
|
||||
// 2 | fps
|
||||
// 1 | transparent red value
|
||||
// 1 | transparent green value
|
||||
// 1 | transparent green value
|
||||
// 1 | transparent blue value
|
||||
// 2 | width
|
||||
// 2 | height
|
||||
// 2 | number of frames
|
||||
// 1 | packer code
|
||||
// 763 | palette
|
||||
// 763 | palette
|
||||
// 2 | number of key frames
|
||||
// 2 | key frame number } repeats
|
||||
// 4 | key frame offset } repeats
|
||||
@@ -607,7 +646,7 @@ void anim_read_header(anim *ptr, CFILE *fp)
|
||||
{
|
||||
ptr->width = cfread_short(fp);
|
||||
// If first 2 bytes are zero, this means we are using a new format, which includes
|
||||
// a version, and fps values. This is only done since a version number was not included
|
||||
// a version, and fps values. This is only done since a version number was not included
|
||||
// in the original header.
|
||||
|
||||
// default
|
||||
@@ -672,17 +711,20 @@ void anim_read_header(anim *ptr, CFILE *fp)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load an animation. This stores the compressed data, which instances of the animation can reference.
|
||||
* Must be free'ed later with anim_free().
|
||||
*
|
||||
* @param real_filename Filename of animation
|
||||
* @param cf_dir_type
|
||||
* @param file_mapped Whether to use memory-mapped file or not.
|
||||
*
|
||||
* @details Memory-mapped files will page in the animation from disk as it is needed, but performance is not as good.
|
||||
* @return Pointer to anim that is loaded if sucess, NULL if failure.
|
||||
*/
|
||||
// -----------------------------------------------------------------------------
|
||||
// anim_load()
|
||||
//
|
||||
// Load an animation. This stores the compressed data, which instances
|
||||
// of the animation can reference. Must be free'ed later with anim_free()
|
||||
//
|
||||
// input: name => filename of animation
|
||||
// file_mapped => boolean, whether to use memory-mapped file or not.
|
||||
// Memory-mapped files will page in the animation from disk
|
||||
// as it is needed, but performance is not as good
|
||||
//
|
||||
// returns: pointer to anim that is loaded => sucess
|
||||
// NULL => failure
|
||||
//
|
||||
anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
|
||||
{
|
||||
anim *ptr;
|
||||
@@ -690,7 +732,7 @@ anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
|
||||
int count,idx;
|
||||
char name[_MAX_PATH];
|
||||
|
||||
Assert( real_filename != NULL );
|
||||
Assert ( real_filename != NULL );
|
||||
|
||||
strcpy_s( name, real_filename );
|
||||
char *p = strchr( name, '.' );
|
||||
@@ -741,10 +783,22 @@ anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
|
||||
ptr->keys[idx].frame_num = 0;
|
||||
cfread(&ptr->keys[idx].frame_num, 2, 1, fp);
|
||||
cfread(&ptr->keys[idx].offset, 4, 1, fp);
|
||||
ptr->keys[idx].frame_num = INTEL_INT( ptr->keys[idx].frame_num ); //-V570
|
||||
ptr->keys[idx].offset = INTEL_INT( ptr->keys[idx].offset ); //-V570
|
||||
ptr->keys[idx].frame_num = INTEL_INT( ptr->keys[idx].frame_num );
|
||||
ptr->keys[idx].offset = INTEL_INT( ptr->keys[idx].offset );
|
||||
}
|
||||
|
||||
/*prev_keyp = &ptr->keys;
|
||||
count = ptr->num_keys;
|
||||
while (count--) {
|
||||
keyp = (key_frame *) vm_malloc(sizeof(key_frame));
|
||||
keyp->next = *prev_keyp;
|
||||
*prev_keyp = keyp;
|
||||
prev_keyp = &keyp->next;
|
||||
|
||||
keyp->frame_num = 0;
|
||||
cfread(&keyp->frame_num, 2, 1, fp);
|
||||
cfread(&keyp->offset, 4, 1, fp);
|
||||
}*/
|
||||
cfread(&count, 4, 1, fp); // size of compressed data
|
||||
count = INTEL_INT( count );
|
||||
|
||||
@@ -805,10 +859,12 @@ anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free an animation that was loaded with anim_load().
|
||||
* @details All instances referencing this animation must be free'ed or get an assert.
|
||||
*/
|
||||
// ---------------------------------------------------
|
||||
// anim_free()
|
||||
//
|
||||
// Free an animation that was loaded with anim_load(). All instances
|
||||
// referencing this animation must be free'ed or get an assert.
|
||||
//
|
||||
int anim_free(anim *ptr)
|
||||
{
|
||||
Assert ( ptr != NULL );
|
||||
@@ -840,14 +896,14 @@ int anim_free(anim *ptr)
|
||||
|
||||
if ( ptr->flags & (ANF_MEM_MAPPED|ANF_STREAMED) ) {
|
||||
cfclose(ptr->cfile_ptr);
|
||||
if (ptr->cache != NULL) {
|
||||
if ( ptr->cache ) {
|
||||
vm_free(ptr->cache);
|
||||
ptr->cache = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Assert(ptr->data);
|
||||
if (ptr->data != NULL) {
|
||||
if ( ptr->data ) {
|
||||
vm_free(ptr->data);
|
||||
ptr->data = NULL;
|
||||
}
|
||||
@@ -859,9 +915,11 @@ int anim_free(anim *ptr)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return if an anim is playing or not.
|
||||
*/
|
||||
// ---------------------------------------------------------------------
|
||||
// anim_playing()
|
||||
//
|
||||
// Return if an anim is playing or not.
|
||||
//
|
||||
int anim_playing(anim_instance *ai)
|
||||
{
|
||||
Assert(ai != NULL);
|
||||
@@ -872,28 +930,36 @@ int anim_playing(anim_instance *ai)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Called at the beginning of a mission to initialize any mission dependent anim data.
|
||||
* @todo Redundant?
|
||||
*/
|
||||
// ---------------------------------------------------------------------
|
||||
// anim_level_init()
|
||||
//
|
||||
// Called at the beginning of a mission to initialize any mission dependent
|
||||
// anim data.
|
||||
//
|
||||
void anim_level_init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called after the end of a mission to clean up any mission dependent anim data.
|
||||
*/
|
||||
// ---------------------------------------------------------------------
|
||||
// anim_level_close()
|
||||
//
|
||||
// Called after the end of a mission to clean up any mission dependent
|
||||
// anim data.
|
||||
//
|
||||
void anim_level_close()
|
||||
{
|
||||
anim_release_all_instances();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the frames of a .ani file out to disk as .pcx files.
|
||||
* @details Use naming convention: filename0000.pcx, filename0001.pcx etc.
|
||||
*
|
||||
* @return If success 0, or if failed -1
|
||||
*/
|
||||
// ---------------------------------------------------
|
||||
// anim_write_frames_out()
|
||||
//
|
||||
// Write the frames of a .ani file out to disk as .pcx files.
|
||||
// Use naming convention: filename0000.pcx, filename0001.pcx etc.
|
||||
//
|
||||
// return: 0 => success
|
||||
// -1 => failed
|
||||
//
|
||||
int anim_write_frames_out(char *filename)
|
||||
{
|
||||
anim *source_anim;
|
||||
@@ -939,10 +1005,12 @@ int anim_write_frames_out(char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display information and statistics about a .ani file.
|
||||
* @details This is called when -i switch is on when running ac.exe
|
||||
*/
|
||||
// ---------------------------------------------------
|
||||
// anim_display_info()
|
||||
//
|
||||
// Display information and statistics about a .ani file.
|
||||
// This is called when -i switch is on when running ac.exe
|
||||
//
|
||||
void anim_display_info(char *real_filename)
|
||||
{
|
||||
CFILE *fp;
|
||||
@@ -972,6 +1040,7 @@ void anim_display_info(char *real_filename)
|
||||
key_frame_nums[i] = 0;
|
||||
cfread(&key_frame_nums[i], 2, 1, fp);
|
||||
cfread(&tmp, 4, 1, fp);
|
||||
//printf("key frame num: %d,%d\n", key_frame_nums[i],tmp);
|
||||
}
|
||||
|
||||
cfread(&compressed, 4, 1, fp);
|
||||
@@ -1016,9 +1085,11 @@ void anim_reverse_direction(anim_instance *ai)
|
||||
{
|
||||
int temp;
|
||||
|
||||
// you're not allowed to call anim_reverse_direction(...) unless every frame is a keyframe!!!!
|
||||
// The God of Delta-RLE demands it be thus.
|
||||
Assertion( ai->parent->flags & ANF_ALL_KEYFRAMES, "Ani was set to play backwards. In order to enable this, all frames of the animation MUST be keyframes.");
|
||||
if(!(ai->parent->flags & ANF_ALL_KEYFRAMES)){
|
||||
// you're not allowed to call anim_reverse_direction(...) unless every frame is a keyframe!!!!
|
||||
// The God of Delta-RLE demands it be thus.
|
||||
Int3();
|
||||
}
|
||||
|
||||
// flip the animation direction
|
||||
if(ai->direction == ANIM_DIRECT_FORWARD){
|
||||
|
||||
@@ -24,8 +24,6 @@ typedef struct {
|
||||
anim *anim_info;
|
||||
int x;
|
||||
int y;
|
||||
int base_w;
|
||||
int base_h;
|
||||
int start_at;
|
||||
int stop_at;
|
||||
int screen_id;
|
||||
@@ -52,7 +50,7 @@ void anim_level_init();
|
||||
void anim_level_close();
|
||||
void anim_render_all(int screen_id, float frametime);
|
||||
void anim_render_one(int screen_id, anim_instance *ani, float frametime);
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int max_x = -1, int max_y = -1);
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y);
|
||||
anim_instance *anim_play(anim_play_struct *aps);
|
||||
void anim_ignore_next_frametime();
|
||||
int anim_stop_playing(anim_instance* anim_instance);
|
||||
|
||||
+203
-66
@@ -15,6 +15,8 @@
|
||||
#include "anim/animplay.h"
|
||||
|
||||
|
||||
|
||||
|
||||
const int packer_code = PACKER_CODE;
|
||||
const int transparent_code = 254;
|
||||
|
||||
@@ -49,7 +51,6 @@ anim_instance *init_anim_instance(anim *ptr, int bpp)
|
||||
ptr->instance_count++;
|
||||
inst = (anim_instance *) vm_malloc(sizeof(anim_instance));
|
||||
Assert(inst);
|
||||
memset(inst, 0, sizeof(anim_instance));
|
||||
inst->frame_num = -1;
|
||||
inst->last_frame_num = -1;
|
||||
inst->parent = ptr;
|
||||
@@ -100,7 +101,12 @@ int anim_get_next_frame(anim_instance *inst)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bitmap_flags = 0;
|
||||
if (inst->parent->flags & ANF_XPARENT) {
|
||||
// bitmap_flags = BMP_XPARENT;
|
||||
bitmap_flags = 0;
|
||||
} else {
|
||||
bitmap_flags = 0;
|
||||
}
|
||||
|
||||
bpp = 16;
|
||||
if(inst->aa_color != NULL){
|
||||
@@ -162,16 +168,159 @@ ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap
|
||||
return inst->frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack key frame
|
||||
*
|
||||
* @param frame Frame pixel data to pack
|
||||
* @param save Memory to store packed data to
|
||||
* @param size Number of bytes to pack
|
||||
* @param max Maximum number of packed bytes (size of buffer)
|
||||
* @param compress_type Compress type
|
||||
* @return Actual number of bytes data packed to or -1 if error
|
||||
*/
|
||||
// --------------------------------------------------------------------
|
||||
// anim_get_frame()
|
||||
//
|
||||
// Get a bitmap id from the anim_instance for the specified frame_num
|
||||
//
|
||||
// input: *inst => pointer to anim instance
|
||||
// frame_num => frame number to get (first frame is 0)
|
||||
// xlate_pal => DEFAULT PARM (value 1): whether to translate the palette
|
||||
// to the current game palette
|
||||
//
|
||||
int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal)
|
||||
{
|
||||
/*
|
||||
int bm, bitmap_flags, key = 0, offset = 0;
|
||||
int idx;
|
||||
|
||||
if ((frame_num < 0) || (frame_num >= inst->parent->total_frames)) // illegal frame number
|
||||
return -1;
|
||||
|
||||
int need_reset = 0;
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
if ( inst->file_offset < 0 ) {
|
||||
need_reset = 1;
|
||||
}
|
||||
} else {
|
||||
if ( !inst->data ) {
|
||||
need_reset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_reset || (inst->frame_num >= inst->parent->total_frames)) { // reset to valid info
|
||||
inst->data = inst->parent->data;
|
||||
inst->file_offset = inst->parent->file_offset;
|
||||
inst->frame_num = 0;
|
||||
}
|
||||
|
||||
bitmap_flags = 0;
|
||||
if (inst->parent->flags & ANF_XPARENT) {
|
||||
// bitmap_flags = BMP_XPARENT;
|
||||
bitmap_flags = 0;
|
||||
}
|
||||
|
||||
if ( inst->frame_num == frame_num ) {
|
||||
bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
|
||||
bm_unload(bm);
|
||||
return bm;
|
||||
}
|
||||
|
||||
if (inst->parent->flags & ANF_XPARENT){
|
||||
// bitmap_flags = BMP_XPARENT;
|
||||
bitmap_flags = 0;
|
||||
} else {
|
||||
bitmap_flags = 0;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
key = 0;
|
||||
while(idx < inst->parent->num_keys){
|
||||
if (( (inst->parent->keys[idx].frame_num-1) <= frame_num) && ( (inst->parent->keys[idx].frame_num-1) > key)) { // find closest key
|
||||
key = inst->parent->keys[idx].frame_num - 1;
|
||||
offset = inst->parent->keys[idx].offset;
|
||||
|
||||
if ( key == frame_num )
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
if ( key == frame_num ) {
|
||||
inst->frame_num = key;
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
inst->file_offset = inst->parent->file_offset + offset;
|
||||
} else {
|
||||
inst->data = inst->parent->data + offset;
|
||||
}
|
||||
|
||||
anim_check_for_palette_change(inst);
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
if ( xlate_pal ){
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
|
||||
} else {
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
|
||||
}
|
||||
} else {
|
||||
if ( xlate_pal ){
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
|
||||
} else {
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
goto create_bitmap;
|
||||
}
|
||||
|
||||
if (key > inst->frame_num) // best key is closer than current position
|
||||
{
|
||||
inst->frame_num = key;
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
inst->file_offset = inst->parent->file_offset + offset;
|
||||
} else {
|
||||
inst->data = inst->parent->data + offset;
|
||||
}
|
||||
|
||||
anim_check_for_palette_change(inst);
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
if ( xlate_pal )
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
|
||||
else
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
|
||||
} else {
|
||||
if ( xlate_pal )
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
|
||||
else
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
while (inst->frame_num != frame_num) {
|
||||
anim_check_for_palette_change(inst);
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
if ( xlate_pal )
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
|
||||
else
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
|
||||
} else {
|
||||
if ( xlate_pal )
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
|
||||
else
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
|
||||
}
|
||||
inst->frame_num++;
|
||||
}
|
||||
|
||||
create_bitmap:
|
||||
|
||||
bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
|
||||
bm_unload(bm);
|
||||
return bm;
|
||||
*/
|
||||
Int3();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// frame = frame pixel data to pack
|
||||
// save = memory to store packed data to
|
||||
// size = number of bytes to pack
|
||||
// max = maximum number of packed bytes (size of buffer)
|
||||
// returns: actual number of bytes data packed to or -1 if error
|
||||
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
|
||||
{
|
||||
int last = -32768, count = 0;
|
||||
@@ -256,12 +405,14 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
Assert( last != STD_RLE_CODE );
|
||||
// printf("Just packed %d 1 times, since pixel change, no count included\n",last);
|
||||
}
|
||||
else {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
// printf("Just packed %d %d times, since pixel change\n",last,count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +429,8 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
count = 0;
|
||||
// printf("Just packed %d %d times, since count overflow\n",last,count);
|
||||
|
||||
}
|
||||
} // end for
|
||||
|
||||
@@ -289,6 +442,7 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
|
||||
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
// printf("Just packed %d 1 times, at end since single pixel, no count\n",last);
|
||||
Assert( last != STD_RLE_CODE );
|
||||
}
|
||||
else {
|
||||
@@ -296,6 +450,7 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
// printf("Just packed %d %d times, at end since pixel change\n",last,count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,17 +468,12 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
|
||||
return packed_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack frame
|
||||
*
|
||||
* @param frame Frame pixel data to pack
|
||||
* @param frame2 Previous frame's pixel data
|
||||
* @param save Memory to store packed data to
|
||||
* @param size Number of bytes to pack
|
||||
* @param max Maximum number of packed bytes (size of buffer)
|
||||
* @param compress_type Compress type
|
||||
* @return Actual number of bytes data packed to or -1 if error
|
||||
*/
|
||||
// frame = frame pixel data to pack
|
||||
// frame2 = previous frame's pixel data
|
||||
// save = memory to store packed data to
|
||||
// size = number of bytes to pack
|
||||
// max = maximum number of packed bytes (size of buffer)
|
||||
// returns: actual number of bytes data packed to or -1 if error
|
||||
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
|
||||
{
|
||||
int pixel, last = -32768, count = 0, i;
|
||||
@@ -479,11 +629,7 @@ int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, in
|
||||
return packed_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a 24 bit value to a 16 bit value
|
||||
* @param bit_24 24 bit value
|
||||
* @param bit_16 16 bit value (output)
|
||||
*/
|
||||
// convert a 24 bit value to a 16 bit value
|
||||
void convert_24_to_16(int bit_24, ushort *bit_16)
|
||||
{
|
||||
ubyte *pixel = (ubyte*)&bit_24;
|
||||
@@ -492,10 +638,7 @@ void convert_24_to_16(int bit_24, ushort *bit_16)
|
||||
bm_set_components((ubyte*)bit_16, (ubyte*)&pixel[0], (ubyte*)&pixel[1], (ubyte*)&pixel[2], &alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack a pixel given the passed index and the anim_instance's palette
|
||||
* @return Bytes stuffed
|
||||
*/
|
||||
// unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
|
||||
int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
|
||||
{
|
||||
int bit_24;
|
||||
@@ -544,7 +687,7 @@ int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bp
|
||||
}
|
||||
} else {
|
||||
// stuff the 24 bit value
|
||||
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
|
||||
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
|
||||
|
||||
// convert to 16 bit
|
||||
convert_24_to_16(bit_24, &bit_16);
|
||||
@@ -575,10 +718,7 @@ int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bp
|
||||
return pixel_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack a pixel given the passed index and the anim_instance's palette
|
||||
* @return Bytes stuffed
|
||||
*/
|
||||
// unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
|
||||
int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0, int aabitmap = 0, int bpp = 8)
|
||||
{
|
||||
int bit_24;
|
||||
@@ -628,7 +768,7 @@ int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0,
|
||||
}
|
||||
} else {
|
||||
// stuff the 24 bit value
|
||||
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
|
||||
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
|
||||
|
||||
// convert to 16 bit
|
||||
convert_24_to_16(bit_24, &bit_16);
|
||||
@@ -657,17 +797,10 @@ int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0,
|
||||
return (pixel_size * count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack frame
|
||||
*
|
||||
* @param ai Animation instance
|
||||
* @param ptr Packed data to unpack
|
||||
* @param frame Where to store unpacked data to
|
||||
* @param size Total number of unpacked pixels requested
|
||||
* @param pal_translate Color translation lookup table (NULL if no palette translation desired)
|
||||
* @param aabitmap
|
||||
* @param bpp
|
||||
*/
|
||||
// ptr = packed data to unpack
|
||||
// frame = where to store unpacked data to
|
||||
// size = total number of unpacked pixels requested
|
||||
// pal_translate = color translation lookup table (NULL if no palette translation desired)
|
||||
ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
|
||||
{
|
||||
int xlate_pal, value, count = 0;
|
||||
@@ -750,6 +883,9 @@ ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte
|
||||
}
|
||||
}
|
||||
else if (*ptr == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
|
||||
|
||||
// test code, to show unused pixels
|
||||
// memset(frame, 255, size);
|
||||
|
||||
ptr++;
|
||||
while (size > 0) {
|
||||
@@ -840,23 +976,17 @@ ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte
|
||||
}
|
||||
}
|
||||
else {
|
||||
// unknown packing method
|
||||
// Assert(0); // unknown packing method
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack frame from file
|
||||
*
|
||||
* @param ai Animation instance
|
||||
* @param frame Where to store unpacked data to
|
||||
* @param size Total number of unpacked pixels requested
|
||||
* @param pal_translate Color translation lookup table (NULL if no palette translation desired)
|
||||
* @param aabitmap
|
||||
* @param bpp
|
||||
*/
|
||||
// ptr = packed data to unpack
|
||||
// frame = where to store unpacked data to
|
||||
// size = total number of unpacked pixels requested
|
||||
// pal_translate = color translation lookup table (NULL if no palette translation desired)
|
||||
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
|
||||
{
|
||||
int xlate_pal, value, count = 0;
|
||||
@@ -946,6 +1076,9 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
|
||||
}
|
||||
}
|
||||
else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
|
||||
|
||||
// test code, to show unused pixels
|
||||
// memset(frame, 255, size);
|
||||
|
||||
offset++;
|
||||
while (size > 0) {
|
||||
@@ -1040,7 +1173,7 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
|
||||
}
|
||||
}
|
||||
else {
|
||||
// unknown packing method
|
||||
// Int3(); // unknown packing method
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1048,17 +1181,21 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set animation palette
|
||||
* @todo Actually convert the frame data to correct palette at this point
|
||||
*/
|
||||
// TODO: actually convert the frame data to correct palette at this point
|
||||
void anim_set_palette(anim *ptr)
|
||||
{
|
||||
int i, xparent_found = 0;
|
||||
|
||||
// create the palette translation look-up table
|
||||
for ( i = 0; i < 256; i++ ) {
|
||||
ptr->palette_translation[i] = (ubyte)i;
|
||||
|
||||
//if ( (ptr->palette[i*3] == ptr->xparent_r) && (ptr->palette[i*3+1] == ptr->xparent_g) && (ptr->palette[i*3+2] == ptr->xparent_b) ) {
|
||||
// ptr->palette_translation[i] = 255;
|
||||
// xparent_found = 1;
|
||||
//} else {
|
||||
// ptr->palette_translation[i] = (ubyte)palette_find( ptr->palette[i*3], ptr->palette[i*3+1], ptr->palette[i*3+2] );
|
||||
ptr->palette_translation[i] = (ubyte)i;
|
||||
//}
|
||||
}
|
||||
|
||||
if ( xparent_found ) {
|
||||
|
||||
@@ -18,11 +18,11 @@ struct CFILE;
|
||||
|
||||
#define ANI_STREAM_CACHE_SIZE 4096
|
||||
|
||||
#define PACKER_CODE 0xEE /// Used by PACKING_METHOD_RLE
|
||||
#define PACKING_METHOD_RLE 0 /// Hoffoss's RLE format
|
||||
#define PACKING_METHOD_RLE_KEY 1 /// Hoffoss's key frame RLE format
|
||||
#define PACKING_METHOD_STD_RLE 2 /// Standard RLE format (high bit is count)
|
||||
#define PACKING_METHOD_STD_RLE_KEY 3 /// Standard RLE format key frame
|
||||
#define PACKER_CODE 0xEE // Use'd by PACKING_METHOD_RLE
|
||||
#define PACKING_METHOD_RLE 0 // Hoffoss's RLE format
|
||||
#define PACKING_METHOD_RLE_KEY 1 // Hoffoss's key frame RLE format
|
||||
#define PACKING_METHOD_STD_RLE 2 // Standard RLE format (high bit is count)
|
||||
#define PACKING_METHOD_STD_RLE_KEY 3 // Standard RLE format key frame
|
||||
|
||||
#define STD_RLE_CODE 0x80
|
||||
|
||||
@@ -71,7 +71,6 @@ typedef struct anim {
|
||||
typedef struct anim_instance {
|
||||
anim_instance *next, *prev;
|
||||
int x,y; // coordinates anim is played at (top left corner of anim)
|
||||
int base_w, base_h; // coordinate scale this anim is played in.
|
||||
vec3d *world_pos; // world (x,y,z) position of explosion
|
||||
float radius; // radius of image, needed for scaling
|
||||
int frame_num; // current frame, or last frame if between frames (first frame is 0)
|
||||
@@ -107,6 +106,7 @@ void anim_init();
|
||||
anim_instance *init_anim_instance(anim *ptr, int bpp);
|
||||
void free_anim_instance(anim_instance *inst);
|
||||
int anim_get_next_frame(anim_instance *inst);
|
||||
int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal=1);
|
||||
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
|
||||
void anim_set_palette(anim *a);
|
||||
void anim_check_for_palette_change(anim_instance *inst);
|
||||
|
||||
+214
-319
File diff suppressed because it is too large.
Load diff
+35
-43
@@ -22,13 +22,18 @@ struct collision_info_struct;
|
||||
|
||||
#define MAX_ASTEROIDS 512
|
||||
|
||||
#define NUM_DEBRIS_SIZES 3
|
||||
#define NUM_DEBRIS_POFS 3 // Number of POFs per debris size
|
||||
#define NUM_DEBRIS_SIZES 3
|
||||
#define NUM_DEBRIS_POFS 3 // Number of POFs per debris size
|
||||
|
||||
#define ASTEROID_TYPE_SMALL 0
|
||||
#define ASTEROID_TYPE_MEDIUM 1
|
||||
#define ASTEROID_TYPE_LARGE 2
|
||||
|
||||
// This is for the asteroid types plus DEBRIS_X_Y
|
||||
// (X is each species and Y is SMALL, MEDIUM, and LARGE)
|
||||
// 20060826 - made dynamic -- taylor
|
||||
//#define MAX_DEBRIS_TYPES ((MAX_SPECIES + 1) * NUM_DEBRIS_SIZES)
|
||||
|
||||
// these should always be equal for the benefit of generic asteroids (c.f. asteroid_page_in)
|
||||
#define MAX_ACTIVE_DEBRIS_TYPES NUM_DEBRIS_SIZES
|
||||
|
||||
@@ -44,39 +49,26 @@ typedef struct asteroid_obj {
|
||||
extern asteroid_obj Asteroid_obj_list;
|
||||
|
||||
|
||||
// Data structure for determining a type and amount of other asteroids an
|
||||
// asteroid will split to when destroyed.
|
||||
typedef struct asteroid_split_info {
|
||||
int asteroid_type;
|
||||
int min;
|
||||
int max;
|
||||
} asteroid_split_info;
|
||||
|
||||
typedef struct asteroid_info {
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
char pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
|
||||
float max_speed; // cap on speed for asteroid
|
||||
int damage_type_idx; //Damage type of the asteroid
|
||||
int damage_type_idx_sav; // stored value from table used to reset damage_type_idx
|
||||
float inner_rad; // radius within which maximum area effect damage is applied
|
||||
float outer_rad; // radius at which no area effect damage is applied
|
||||
float damage; // maximum damage applied from area effect explosion
|
||||
float blast; // maximum blast impulse from area effect explosion
|
||||
float initial_asteroid_strength; // starting strength of asteroid
|
||||
SCP_vector< asteroid_split_info > split_info;
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
char pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
|
||||
float max_speed; // cap on speed for asteroid
|
||||
int damage_type_idx; //Damage type of the asteroid
|
||||
float inner_rad; // radius within which maximum area effect damage is applied
|
||||
float outer_rad; // radius at which no area effect damage is applied
|
||||
float damage; // maximum damage applied from area effect explosion
|
||||
float blast; // maximum blast impulse from area effect explosion
|
||||
float initial_asteroid_strength; // starting strength of asteroid
|
||||
polymodel *modelp[NUM_DEBRIS_POFS];
|
||||
int model_num[NUM_DEBRIS_POFS];
|
||||
SCP_vector<int> explosion_bitmap_anims;
|
||||
float fireball_radius_multiplier; // the model radius is multiplied by this to determine the fireball size
|
||||
|
||||
asteroid_info( )
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( 0 ),
|
||||
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
|
||||
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
|
||||
fireball_radius_multiplier( -1 )
|
||||
{
|
||||
asteroid_info( )
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( -1 ),
|
||||
inner_rad( 0 ), outer_rad( 0 ), damage( 0 ), blast( 0 ),
|
||||
initial_asteroid_strength( 0 )
|
||||
{
|
||||
name[ 0 ] = NULL;
|
||||
memset( pof_files, 0, sizeof( pof_files ) );
|
||||
memset( detail_distance, 0, sizeof( detail_distance ) );
|
||||
@@ -86,20 +78,20 @@ typedef struct asteroid_info {
|
||||
} asteroid_info;
|
||||
|
||||
|
||||
#define AF_USED (1<<0) // Set means used.
|
||||
#define AF_USED (1<<0) // Set means used.
|
||||
|
||||
typedef struct asteroid {
|
||||
int flags;
|
||||
int objnum;
|
||||
int asteroid_type; // 0..MAX_DEBRIS_TYPES
|
||||
int asteroid_subtype; // Index in asteroid_info for modelnum and modelp
|
||||
int check_for_wrap; // timestamp to check for asteroid wrapping around field
|
||||
int check_for_wrap; // timestamp to check for asteroid wrapping around field
|
||||
int check_for_collide; // timestamp to check for asteroid colliding with escort ships
|
||||
int final_death_time; // timestamp to swap in new models after explosion starts
|
||||
int final_death_time; // timestamp to swap in new models after explosion starts
|
||||
int collide_objnum; // set to objnum that asteroid will be impacting soon
|
||||
int collide_objsig; // object signature corresponding to collide_objnum
|
||||
vec3d death_hit_pos; // hit pos that caused death
|
||||
int target_objnum; // Yes, hah! Asteroids can have targets. See asteroid_aim_at_target().
|
||||
vec3d death_hit_pos; // hit pos that caused death
|
||||
int target_objnum; // Yes, hah! Asteroids can have targets. See asteroid_aim_at_target().
|
||||
} asteroid;
|
||||
|
||||
|
||||
@@ -116,15 +108,15 @@ typedef enum {
|
||||
} field_type_t;
|
||||
|
||||
typedef struct asteroid_field {
|
||||
vec3d min_bound; // Minimum range of field.
|
||||
vec3d max_bound; // Maximum range of field.
|
||||
vec3d min_bound; // Minimum range of field.
|
||||
vec3d max_bound; // Maximum range of field.
|
||||
int has_inner_bound;
|
||||
vec3d inner_min_bound;
|
||||
vec3d inner_max_bound;
|
||||
vec3d vel; // Average asteroid moves at this velocity.
|
||||
float speed; // Average speed of field
|
||||
int num_initial_asteroids; // Number of asteroids at creation.
|
||||
field_type_t field_type; // active throws and wraps, passive does not
|
||||
vec3d vel; // Average asteroid moves at this velocity.
|
||||
float speed; // Average speed of field
|
||||
int num_initial_asteroids; // Number of asteroids at creation.
|
||||
field_type_t field_type; // active throws and wraps, passive does not
|
||||
debris_genre_t debris_genre; // type of debris (ship or asteroid) [generic type]
|
||||
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]; // one of the debris type defines above
|
||||
} asteroid_field;
|
||||
@@ -136,7 +128,7 @@ extern asteroid_field Asteroid_field;
|
||||
extern int Num_asteroids;
|
||||
extern int Asteroids_enabled;
|
||||
|
||||
void asteroid_init();
|
||||
void asteroid_init();
|
||||
void asteroid_level_init();
|
||||
void asteroid_level_close();
|
||||
void asteroid_create_all();
|
||||
|
||||
+183
-226
@@ -39,7 +39,6 @@ extern int Cmdline_autopilot_interruptable;
|
||||
// Module variables
|
||||
bool AutoPilotEngaged;
|
||||
bool UseCutsceneBars;
|
||||
bool LockWeaponsDuringAutopilot;
|
||||
int CurrentNav;
|
||||
float ramp_bias;
|
||||
NavPoint Navs[MAX_NAVPOINTS];
|
||||
@@ -54,10 +53,7 @@ int camMovingTime;
|
||||
//float CameraSpeed;
|
||||
bool CinematicStarted, CameraMoving;
|
||||
vec3d cameraPos, cameraTarget;
|
||||
SCP_map<int,int> autopilot_wings;
|
||||
|
||||
int AutopilotMinEnemyDistance;
|
||||
int AutopilotMinAsteroidDistance;
|
||||
std::map<int,int> autopilot_wings;
|
||||
|
||||
// used for ramping time compression;
|
||||
int start_dist;
|
||||
@@ -67,7 +63,14 @@ int start_dist;
|
||||
void autopilot_ai_waypoint_goal_fixup(ai_goal* aigp)
|
||||
{
|
||||
// this function sets wp_index properly;
|
||||
aigp->wp_list = find_matching_waypoint_list(aigp->target_name);
|
||||
for (int i = 0; i < Num_waypoint_lists; i++)
|
||||
{
|
||||
if (!stricmp(aigp->ship_name, Waypoint_lists[i].name))
|
||||
{
|
||||
aigp->wp_index = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,9 +115,7 @@ vec3d *NavPoint::GetPosition()
|
||||
{
|
||||
if (flags & NP_WAYPOINT)
|
||||
{
|
||||
waypoint *wpt = find_waypoint_at_index((waypoint_list*) target_obj, waypoint_num-1);
|
||||
Assert(wpt != NULL);
|
||||
return wpt->get_pos();
|
||||
return &((waypoint_list*) target_obj)->waypoints[waypoint_num-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,16 +123,16 @@ vec3d *NavPoint::GetPosition()
|
||||
}
|
||||
}
|
||||
|
||||
char* NavPoint::GetInternalName()
|
||||
char* NavPoint::GetInteralName()
|
||||
{
|
||||
char *NavName;
|
||||
char strtmp[33];
|
||||
|
||||
if (flags & NP_WAYPOINT)
|
||||
{
|
||||
NavName = new char[strlen(((waypoint_list*)target_obj)->get_name())+5];
|
||||
memset(NavName, 0, strlen(((waypoint_list*)target_obj)->get_name())+5);
|
||||
strcpy(NavName, ((waypoint_list*)target_obj)->get_name());
|
||||
NavName = new char[strlen(((waypoint_list*)target_obj)->name)+5];
|
||||
memset(NavName, 0, strlen(((waypoint_list*)target_obj)->name)+5);
|
||||
strcpy(NavName, ((waypoint_list*)target_obj)->name);
|
||||
|
||||
strcat(NavName, ":");
|
||||
sprintf(strtmp, "%d", waypoint_num);
|
||||
@@ -148,7 +149,12 @@ char* NavPoint::GetInternalName()
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg)
|
||||
// Tell us if autopilot is allowed
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within X distance
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilot(bool send_msg)
|
||||
{
|
||||
if (CurrentNav == -1)
|
||||
{
|
||||
@@ -156,69 +162,99 @@ bool CanAutopilot(vec3d targetPos, bool send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (object_get_gliding(Player_obj))
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_GLIDING);
|
||||
return false;
|
||||
}
|
||||
|
||||
// You cannot autopilot if you're within 1000 meters of your destination nav point
|
||||
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000) {
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, Navs[CurrentNav].GetPosition()) < 1000)
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( AutopilotMinEnemyDistance > 0 ) {
|
||||
// see if any hostiles are nearby
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
// see if any hostiles are nearby
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
{
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO))
|
||||
{
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
|
||||
// Cannot autopilot if enemy within 5,000 meters
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 5000)
|
||||
{
|
||||
// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
|
||||
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( AutopilotMinAsteroidDistance > 0 ) {
|
||||
//check for asteroids
|
||||
for (int n=0; n<MAX_ASTEROIDS; n++)
|
||||
{
|
||||
// asteroid
|
||||
if (Asteroids[n].flags & AF_USED)
|
||||
{
|
||||
// Cannot autopilot if asteroid within AutopilotMinAsteroidDistance meters
|
||||
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < AutopilotMinAsteroidDistance) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
|
||||
return false;
|
||||
}
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for support ships
|
||||
// cannot autopilot if support ship present
|
||||
if ( ship_find_repair_ship(Player_obj) != NULL ) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
|
||||
//check for asteroids
|
||||
for (int n=0; n<MAX_ASTEROIDS; n++)
|
||||
{
|
||||
// asteroid
|
||||
if (Asteroids[n].flags & AF_USED)
|
||||
{
|
||||
// Cannot autopilot if asteroid within 1,000 meters
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Asteroids[n].objnum].pos) < 1000)
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Tell us if autopilot is allowed at a certain position (only performs checks based on that position)
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within X distance
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilotPos(vec3d targetPos)
|
||||
{
|
||||
// You cannot autopilot if you're within 1000 meters of your destination nav point
|
||||
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000)
|
||||
return false;
|
||||
// see if any hostiles are nearby
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
{
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
|
||||
{
|
||||
// Cannot autopilot if enemy within 5,000 meters
|
||||
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < 5000)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//check for asteroids
|
||||
for (int n=0; n<MAX_ASTEROIDS; n++)
|
||||
{
|
||||
// asteroid
|
||||
if (Asteroids[n].flags & AF_USED)
|
||||
{
|
||||
// Cannot autopilot if asteroid within 1,000 meters
|
||||
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < 1000)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern object* Autopilot_flight_leader;
|
||||
// ********************************************************************************************
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
@@ -227,54 +263,13 @@ extern object* Autopilot_flight_leader;
|
||||
// * Lock time compression -WMC
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
bool StartAutopilot()
|
||||
void StartAutopilot()
|
||||
{
|
||||
// Check for support ship and dismiss it if it is not doing anything.
|
||||
// If the support ship is doing something then tell the user such.
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
object* support_ship_op = ship_find_repair_ship(Player_obj);
|
||||
if ( support_ship_op == NULL ) {
|
||||
// no more
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Assert( support_ship_op->type == OBJ_SHIP );
|
||||
Assert( support_ship_op->instance >= 0 );
|
||||
Assert( support_ship_op->instance < MAX_SHIPS );
|
||||
Assert( Ships[support_ship_op->instance].ai_index != -1 );
|
||||
|
||||
ai_info* support_ship_aip = &(Ai_info[Ships[support_ship_op->instance].ai_index]);
|
||||
|
||||
// is support ship trying to rearm-repair
|
||||
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
|
||||
// no, so tell it to depart
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
|
||||
} else {
|
||||
// yes
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
if (!CanAutopilot())
|
||||
return false;
|
||||
return;
|
||||
|
||||
AutoPilotEngaged = true;
|
||||
|
||||
// find the ship that is "leading" all of the ships when the player starts
|
||||
// autopilot
|
||||
// by default the ship that is leading the autopilot session the player's
|
||||
// wing leader (if the player is the wing leader then it will be the
|
||||
// player).
|
||||
// TODO:implement a way to allow a FREDer to say a different ship is leader
|
||||
Autopilot_flight_leader = get_wing_leader(Player_ship->wingnum);
|
||||
if ( Autopilot_flight_leader == NULL ) {
|
||||
// force player to be the leader if he doesn't have a wing
|
||||
Autopilot_flight_leader = Player_obj;
|
||||
}
|
||||
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
LockAPConv = timestamp(); // lock convergence instantly
|
||||
else
|
||||
@@ -333,20 +328,10 @@ bool StartAutopilot()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
speed_cap = 0.90f * speed_cap;
|
||||
|
||||
if ( speed_cap < 1.0f ) {
|
||||
/* We need to deal with this so that incorrectly flagged ships will not
|
||||
cause the engine to fail to limit all the ships speeds correctly. */
|
||||
Warning(LOCATION, "Ship speed cap is way too small (%f)!\n"
|
||||
"This is normally caused by a ship that has nav-carry-status set, but cannot move itself (like a Cargo container).\n"
|
||||
"Speed cap has been set to 1.0 m/s.",
|
||||
speed_cap);
|
||||
speed_cap = 1.0f;
|
||||
}
|
||||
|
||||
ramp_bias = speed_cap/50.0f;
|
||||
|
||||
// assign ship goals
|
||||
@@ -367,7 +352,8 @@ bool StartAutopilot()
|
||||
{
|
||||
capshipPresent = true;
|
||||
|
||||
capIndexes.push_back(i);
|
||||
capIndexes.resize(capIndexes.size()+1);
|
||||
capIndexes[capIndexes.size()-1] = i;
|
||||
// ok.. what size class
|
||||
|
||||
if (Ship_info[Ships[i].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
|
||||
@@ -411,10 +397,10 @@ bool StartAutopilot()
|
||||
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
|
||||
}
|
||||
|
||||
// snap wings into formation
|
||||
// snap wings into formation them into formation
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS && // only if using cinematics
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
|
||||
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
|
||||
&& Player_obj != &Objects[Ships[i].objnum]) //only if not player object
|
||||
{
|
||||
ai_info *aip = &Ai_info[Ships[i].ai_index];
|
||||
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
|
||||
@@ -433,34 +419,33 @@ bool StartAutopilot()
|
||||
switch (wcount % 2)
|
||||
{
|
||||
case 1: // back-left
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
|
||||
vm_vec_normalize(&perp);
|
||||
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
|
||||
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
|
||||
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
|
||||
break;
|
||||
|
||||
default: //back-right
|
||||
case 0:
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
|
||||
vm_vec_normalize(&perp);
|
||||
vm_vec_scale(&perp, 166.0f*j);
|
||||
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
|
||||
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
|
||||
break;
|
||||
}
|
||||
autopilot_wings[wingnum] = wcount;
|
||||
wcount++;
|
||||
}
|
||||
Objects[Ships[i].objnum].pos = goal_point;
|
||||
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
{
|
||||
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
|
||||
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
|
||||
}
|
||||
}
|
||||
// lock primary and secondary weapons
|
||||
if ( LockWeaponsDuringAutopilot )
|
||||
Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
//Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
|
||||
// clear the ship goals and cap the waypoint speed
|
||||
ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
|
||||
@@ -472,7 +457,7 @@ bool StartAutopilot()
|
||||
{
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), &Ai_info[Ships[i].ai_index] );
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->name, &Ai_info[Ships[i].ai_index] );
|
||||
//fixup has to wait until after wing goals
|
||||
}
|
||||
else
|
||||
@@ -501,7 +486,7 @@ bool StartAutopilot()
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
|
||||
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), i );
|
||||
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->name, i );
|
||||
|
||||
// "fix up" the goal
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
@@ -553,13 +538,13 @@ bool StartAutopilot()
|
||||
// position capships
|
||||
|
||||
vec3d right, front, up, offset;
|
||||
for (SCP_vector<int>::iterator idx = capIndexes.begin(); idx != capIndexes.end(); ++idx)
|
||||
for (i = 0; i < (int)capIndexes.size(); i++)
|
||||
{
|
||||
vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
|
||||
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
|
||||
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&right, &Player_obj->orient.vec.rvec, &zero);
|
||||
vm_vec_add(&front, &Player_obj->orient.vec.fvec, &zero);
|
||||
vm_vec_add(&up, &Player_obj->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&offset, &zero, &zero);
|
||||
if (Ship_info[Ships[*idx].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
|
||||
if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
|
||||
{
|
||||
//0 - below - three lines of position
|
||||
|
||||
@@ -593,7 +578,7 @@ bool StartAutopilot()
|
||||
|
||||
capship_placed[0]++;
|
||||
}
|
||||
else if (Ship_info[Ships[*idx].ship_info_index].flags & SIF_CORVETTE)
|
||||
else if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & SIF_CORVETTE)
|
||||
{
|
||||
//1 above - 3 lines of position
|
||||
// front/back to zero
|
||||
@@ -625,7 +610,7 @@ bool StartAutopilot()
|
||||
vm_vec_scale(&up, (1+((float)floor((float)capship_placed[1]/3))));
|
||||
|
||||
// move ourselves up and out of the way of the smaller ships
|
||||
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&perp, &Player_obj->orient.vec.uvec, &zero);
|
||||
vm_vec_scale(&perp, capship_spreads[2]);
|
||||
vm_vec_add(&up, &up, &perp);
|
||||
|
||||
@@ -680,7 +665,7 @@ bool StartAutopilot()
|
||||
vm_vec_scale(&front, 2*(1+((float)floor((float)capship_placed[2]/3))));
|
||||
|
||||
// move "out" by 166*(wcount-1) so we don't bump into fighters
|
||||
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.rvec, &zero);
|
||||
vm_vec_add(&perp, &Player_obj->orient.vec.rvec, &zero);
|
||||
vm_vec_scale(&perp, 166.0f*float(wcount-1));
|
||||
if ( (capship_placed[2] % 2) == 0)
|
||||
vm_vec_add(&right, &right, &perp);
|
||||
@@ -702,16 +687,16 @@ bool StartAutopilot()
|
||||
// global scale the position by 50%
|
||||
//vm_vec_scale(&offset, 1.5);
|
||||
|
||||
vm_vec_add(&Objects[Ships[*idx].objnum].pos, &Autopilot_flight_leader->pos, &offset);
|
||||
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Player_obj->pos, &offset);
|
||||
|
||||
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
{
|
||||
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
|
||||
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ftemp = floor(Autopilot_flight_leader->phys_info.max_vel.xyz.z/speed_cap);
|
||||
ftemp = floor(Player_obj->phys_info.max_vel.xyz.z/speed_cap);
|
||||
if (ftemp >= 2.0f && ftemp < 4.0f)
|
||||
tc_factor = 2;
|
||||
else if (ftemp >= 4.0f && ftemp < 8.0f)
|
||||
@@ -723,11 +708,11 @@ bool StartAutopilot()
|
||||
|
||||
tpos = *Navs[CurrentNav].GetPosition();
|
||||
// determine distance toward nav at which camera will be
|
||||
vm_vec_sub(&pos, &tpos, &Autopilot_flight_leader->pos);
|
||||
vm_vec_sub(&pos, &tpos, &Player_obj->pos);
|
||||
vm_vec_normalize(&pos); // pos is now a unit vector in the direction we will be moving the camera
|
||||
//norm1 = pos;
|
||||
vm_vec_scale(&pos, 5*speed_cap*tc_factor); // pos is now scaled by 5 times the speed (5 seconds ahead)
|
||||
vm_vec_add(&pos, &pos, &Autopilot_flight_leader->pos); // pos is now 5*speed cap in front of player ship
|
||||
vm_vec_add(&pos, &pos, &Player_obj->pos); // pos is now 5*speed cap in front of player ship
|
||||
|
||||
switch (myrand()%24)
|
||||
// 8 different ways of getting perp points
|
||||
@@ -738,74 +723,74 @@ bool StartAutopilot()
|
||||
case 9:
|
||||
case 16:
|
||||
if (capship_placed[0] == 0)
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.uvec);
|
||||
else
|
||||
{ // become up-left
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.rvec);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // up
|
||||
case 10:
|
||||
case 23:
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
if (capshipPresent) // become up-right
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.rvec);
|
||||
break;
|
||||
|
||||
case 3: // left
|
||||
case 11:
|
||||
case 22:
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
break;
|
||||
|
||||
case 4: // up-left
|
||||
case 12:
|
||||
case 21:
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 5: // up-right
|
||||
case 13:
|
||||
case 20:
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 6: // down-left
|
||||
case 14:
|
||||
case 19:
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
if (capship_placed[0] < 2)
|
||||
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
else
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 7: // down-right
|
||||
case 15:
|
||||
case 18:
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
if (capship_placed[0] < 1)
|
||||
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
else
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0: // right
|
||||
case 8:
|
||||
case 17:
|
||||
perp = Autopilot_flight_leader->orient.vec.rvec;
|
||||
perp = Player_obj->orient.vec.rvec;
|
||||
break;
|
||||
|
||||
}
|
||||
vm_vec_normalize(&perp);
|
||||
//vm_vec_scale(&perp, 2*radius+distance);
|
||||
|
||||
vm_vec_scale(&perp, Autopilot_flight_leader->radius+radius);
|
||||
vm_vec_scale(&perp, Player_obj->radius+radius);
|
||||
|
||||
// randomly scale up/down by up to 20%
|
||||
j = 20-myrand()%40; // [-20,20]
|
||||
@@ -845,8 +830,16 @@ bool StartAutopilot()
|
||||
camMovingTime = int(4.5*float(tc_factor));
|
||||
set_time_compression((float)tc_factor);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
// ********************************************************************************************
|
||||
// Checks if autopilot should automatically die
|
||||
// Returns true if:
|
||||
// * Targetted waypoint < 10,000 meters away
|
||||
// * Enemy < 10,000 meters
|
||||
bool Autopilot_AutoDiable()
|
||||
{
|
||||
return !CanAutopilot();
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -859,8 +852,6 @@ void EndAutoPilot()
|
||||
{
|
||||
AutoPilotEngaged = false;
|
||||
|
||||
Autopilot_flight_leader = NULL;
|
||||
|
||||
set_time_compression(1);
|
||||
lock_time_compression(false);
|
||||
Player_use_ai = 0;
|
||||
@@ -884,7 +875,7 @@ void EndAutoPilot()
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
goal = AI_GOAL_WAYPOINTS_ONCE;
|
||||
goal_name = ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name();
|
||||
goal_name = ((waypoint_list*)Navs[CurrentNav].target_obj)->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -908,16 +899,14 @@ void EndAutoPilot()
|
||||
)
|
||||
{
|
||||
//unlock their weaponry
|
||||
if ( LockWeaponsDuringAutopilot )
|
||||
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
//Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
|
||||
Ai_info[Ships[i].ai_index].mode = AIM_NONE; // make AI re-evaluate current ship mode
|
||||
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
{
|
||||
ai_goal *aigp = &Ai_info[Ships[i].ai_index].goals[j];
|
||||
|
||||
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
|
||||
if ( ((aigp->ship_name != NULL) && !stricmp(aigp->ship_name, goal_name))
|
||||
&& (aigp->ai_mode == goal) )
|
||||
{
|
||||
ai_remove_ship_goal(&Ai_info[Ships[i].ai_index], j);
|
||||
@@ -930,7 +919,7 @@ void EndAutoPilot()
|
||||
{
|
||||
ai_goal *aigp = &Wings[Ships[i].wingnum].ai_goals[j];
|
||||
|
||||
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
|
||||
if ( ((aigp->ship_name != NULL) && !stricmp(aigp->ship_name, goal_name))
|
||||
&& (aigp->ai_mode == goal) )
|
||||
{
|
||||
aigp->ai_mode = AI_GOAL_NONE;
|
||||
@@ -954,7 +943,7 @@ void EndAutoPilot()
|
||||
{
|
||||
ai_goal *aigp = &Wings[i].ai_goals[j];
|
||||
|
||||
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
|
||||
if ( ((aigp->ship_name != NULL) && !stricmp(aigp->ship_name, goal_name))
|
||||
&& (aigp->ai_mode == goal) )
|
||||
{
|
||||
aigp->ai_mode = AI_GOAL_NONE;
|
||||
@@ -986,54 +975,34 @@ camera* nav_get_set_camera()
|
||||
|
||||
void nav_warp(bool prewarp=false)
|
||||
{
|
||||
/* ok... find our end distance - norm1 is still a unit vector in the
|
||||
direction from the flight leader to the navpoint */
|
||||
vec3d targetPos, tpos=Autopilot_flight_leader->pos, pos, velocity;
|
||||
|
||||
/* calculate a vector that we can use to make a path from the flight
|
||||
leader's location to the nav point */
|
||||
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
|
||||
// ok... find our end distance - norm1 is still a unit vector in the direction from the player to the navpoint
|
||||
vec3d targetPos, tpos=Player_obj->pos, pos;
|
||||
|
||||
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
|
||||
vm_vec_normalize(&pos);
|
||||
velocity = pos; // make a copy for later when we do setup veleocity vector
|
||||
vm_vec_scale(&pos, 250.0f); // we move by increments of 250
|
||||
|
||||
/* using the vector of the flight leaders's path, simulate moving the
|
||||
flight along this path by checking the autopilot conditions as specific
|
||||
intervals along the path*/
|
||||
while (CanAutopilot(tpos))
|
||||
while (CanAutopilotPos(tpos))
|
||||
{
|
||||
vm_vec_add(&tpos, &tpos, &pos);
|
||||
}
|
||||
vm_vec_sub(&targetPos, &tpos, &Autopilot_flight_leader->pos);
|
||||
/* targetPos is actually a vector that describes the exact 3D movement that
|
||||
the flgith leader needs to execute to reach the location that the auto
|
||||
pilot is to shut off */
|
||||
vm_vec_sub(&targetPos, &tpos, &Player_obj->pos); //targetPos is actually a projection in a the direction toward the nav
|
||||
|
||||
// Check if we are actually just setting up for the cinimatic shot of the
|
||||
// flight flying on autopilot. Only jump halfway. Also we also need to
|
||||
// put the camera in the correct position to show the player this cinimatic
|
||||
if (prewarp)
|
||||
{
|
||||
vm_vec_scale(&targetPos, 0.5);
|
||||
vm_vec_add(&cameraPos, &cameraPos, &targetPos);
|
||||
}
|
||||
|
||||
/* calcuate the speed that everyone is supposed to be going so that there
|
||||
is no need for anyone to accelerate or decelerate (most obvious with
|
||||
the player's fighter slowing down as it changes the camera pan speed). */
|
||||
Assert( Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap > 0 );
|
||||
vm_vec_scale(&velocity, (float)Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap);
|
||||
|
||||
// Find all ships that are supposed to autopilot with the player and move them
|
||||
// to the cinimatic location or the final destination
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1
|
||||
&& (Ships[i].flags2 & SF2_NAVPOINT_CARRY
|
||||
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)))
|
||||
if (Ships[i].objnum != -1 &&
|
||||
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
|
||||
)
|
||||
)
|
||||
{
|
||||
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
|
||||
Objects[Ships[i].objnum].phys_info.vel = velocity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1072,7 +1041,7 @@ void NavSystem_Do()
|
||||
}
|
||||
|
||||
|
||||
if (timestamp() >= EndAPCinematic || !CanAutopilot())
|
||||
if (timestamp() >= EndAPCinematic || Autopilot_AutoDiable())
|
||||
{
|
||||
nav_warp();
|
||||
EndAutoPilot();
|
||||
@@ -1091,7 +1060,7 @@ void NavSystem_Do()
|
||||
if(cam != NULL)
|
||||
{
|
||||
cam->set_position(&cameraPos);
|
||||
cam->set_rotation_facing(&Autopilot_flight_leader->pos);
|
||||
cam->set_rotation_facing(&Player_obj->pos);
|
||||
}
|
||||
|
||||
CinematicStarted = true;
|
||||
@@ -1099,7 +1068,7 @@ void NavSystem_Do()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CanAutopilot())
|
||||
if (Autopilot_AutoDiable())
|
||||
EndAutoPilot();
|
||||
|
||||
}
|
||||
@@ -1172,10 +1141,7 @@ void NavSystem_Do()
|
||||
}
|
||||
}
|
||||
|
||||
/* Link in any ships that need to be linked in when the player gets close
|
||||
enough. Always done by the player because: "making sure the AI fighters
|
||||
are where they're supposed to be at all times is like herding cats" -Woolie Wool
|
||||
*/
|
||||
// autopilot linking
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
|
||||
@@ -1213,11 +1179,11 @@ void send_autopilot_msg(char *msg, char *snd)
|
||||
audio_handle = -1;
|
||||
}
|
||||
|
||||
if (msg[0] != '\0' && strcmp(msg, "none"))
|
||||
if (strlen(msg) != 0 && strcmp(msg, "none"))
|
||||
change_message("autopilot builtin message", msg, -1, 0);
|
||||
|
||||
// load sound
|
||||
if ((snd != NULL) && (snd[0] != '\0' && !strcmp(snd, "none")))
|
||||
if (snd != NULL || strlen(snd) == 0 || !strcmp(snd, "none"))
|
||||
{
|
||||
audio_handle = audiostream_open(snd, ASF_MENUMUSIC );
|
||||
}
|
||||
@@ -1225,10 +1191,10 @@ void send_autopilot_msg(char *msg, char *snd)
|
||||
// send/play
|
||||
if (audio_handle != -1)
|
||||
{
|
||||
audiostream_play(audio_handle, (Master_event_music_volume * aav_music_volume), 0);
|
||||
audiostream_play(audio_handle, Master_event_music_volume, 0);
|
||||
}
|
||||
|
||||
if (msg[0] != '\0' && strcmp(msg, "none"))
|
||||
if (strlen(msg) != 0 && strcmp(msg, "none"))
|
||||
message_training_queue("autopilot builtin message", timestamp(0), 5); // display message for five seconds
|
||||
}
|
||||
|
||||
@@ -1255,7 +1221,7 @@ void NavSystem_Init()
|
||||
void parse_autopilot_table(char *filename)
|
||||
{
|
||||
int rval;
|
||||
SCP_vector<SCP_string> lines;
|
||||
SCP_vector<std::string> lines;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
@@ -1281,21 +1247,6 @@ void parse_autopilot_table(char *filename)
|
||||
required_string("$Link Distance:");
|
||||
stuff_int(&NavLinkDistance);
|
||||
|
||||
if (optional_string("$Interrupt autopilot if enemy within distance:"))
|
||||
stuff_int(&AutopilotMinEnemyDistance);
|
||||
else
|
||||
AutopilotMinEnemyDistance = 5000;
|
||||
|
||||
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
|
||||
stuff_int(&AutopilotMinAsteroidDistance);
|
||||
else
|
||||
AutopilotMinAsteroidDistance = 1000;
|
||||
|
||||
if (optional_string("$Lock Weapons During Autopilot:"))
|
||||
stuff_boolean(&LockWeaponsDuringAutopilot);
|
||||
else
|
||||
LockWeaponsDuringAutopilot = false;
|
||||
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Cutscene_Bars"))
|
||||
UseCutsceneBars = false;
|
||||
@@ -1304,9 +1255,7 @@ void parse_autopilot_table(char *filename)
|
||||
Cmdline_autopilot_interruptable = 0;
|
||||
|
||||
// No Nav selected message
|
||||
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
|
||||
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
|
||||
"$Support Present:", "$Support Working:" };
|
||||
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:", "$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:" };
|
||||
for (int i = 0; i < NP_NUM_MESSAGES; i++)
|
||||
{
|
||||
required_string(msg_tags[i]);
|
||||
@@ -1448,7 +1397,15 @@ bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags)
|
||||
|
||||
Assert(!(tnav.flags & NP_SHIP));
|
||||
|
||||
tnav.target_obj = find_matching_waypoint_list(WP_Path);
|
||||
|
||||
for (i = 0; i < Num_waypoint_lists; i++)
|
||||
{
|
||||
if (!stricmp(WP_Path, Waypoint_lists[i].name))
|
||||
{
|
||||
tnav.target_obj = (void *)&Waypoint_lists[i];
|
||||
}
|
||||
}
|
||||
|
||||
tnav.waypoint_num = node;
|
||||
|
||||
// copy it into it's location
|
||||
@@ -1580,7 +1537,7 @@ unsigned int DistanceTo(char *nav)
|
||||
|
||||
unsigned int DistanceTo(int nav)
|
||||
{
|
||||
if (nav >= MAX_NAVPOINTS || nav < 0)
|
||||
if (nav >= MAX_NAVPOINTS && nav < 0)
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
return (uint)vm_vec_dist_quick(&Player_obj->pos, Navs[nav].GetPosition());
|
||||
@@ -1597,7 +1554,7 @@ bool IsVisited(char *nav)
|
||||
|
||||
bool IsVisited(int nav)
|
||||
{
|
||||
if (nav >= MAX_NAVPOINTS || nav < 0)
|
||||
if (nav >= MAX_NAVPOINTS && nav < 0)
|
||||
return 0;
|
||||
|
||||
if (Navs[nav].flags & NP_VISITED)
|
||||
|
||||
+17
-21
@@ -8,7 +8,6 @@
|
||||
#define _AUTOPILOT_H_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "object/object.h"
|
||||
#include <map>
|
||||
|
||||
// milliseconds between updates
|
||||
@@ -16,8 +15,8 @@
|
||||
|
||||
#define MAX_NAVPOINTS 8
|
||||
|
||||
#define NP_WAYPOINT 0x0001 // Nav Point is bound to the position of a single node of a waypoint path
|
||||
#define NP_SHIP 0x0002 // Nav Point is bound to the position of a certain ship
|
||||
#define NP_WAYPOINT 0x0001 // Nav Point is bound to the poistion of a single node of a waypoint path
|
||||
#define NP_SHIP 0x0002 // Nav Point is bound to the poisiton of a certain ship
|
||||
#define NP_HIDDEN 0x0004 // Nav Point doesn't show on map and isn't selectable
|
||||
#define NP_NOACCESS 0x0008 // Nav Point isn't selectable
|
||||
#define NP_VISITED 0x0100 // Whether we've been within 1,000 meters of this waypoint
|
||||
@@ -34,19 +33,17 @@ struct NavPoint
|
||||
int waypoint_num; //only used when flags & NP_WAYPOINT
|
||||
|
||||
vec3d *GetPosition();
|
||||
char* GetInternalName();
|
||||
char* GetInteralName();
|
||||
};
|
||||
|
||||
|
||||
#define NP_NUM_MESSAGES 6
|
||||
#define NP_MSG_FAIL_NOSEL 0
|
||||
#define NP_MSG_FAIL_GLIDING 1
|
||||
#define NP_MSG_FAIL_TOCLOSE 2
|
||||
#define NP_MSG_FAIL_HOSTILES 3
|
||||
#define NP_MSG_MISC_LINKED 4
|
||||
#define NP_MSG_FAIL_HAZARD 5
|
||||
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
|
||||
#define NP_MSG_FAIL_SUPPORT_WORKING 7
|
||||
#define NP_NUM_MESSAGES 8
|
||||
|
||||
struct NavMessage
|
||||
{
|
||||
@@ -59,34 +56,33 @@ extern int CurrentNav;
|
||||
extern NavPoint Navs[MAX_NAVPOINTS];
|
||||
extern NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
extern int LockAPConv;
|
||||
extern SCP_map<int,int> autopilot_wings;
|
||||
extern std::map<int,int> autopilot_wings;
|
||||
|
||||
// Cycles through the NavPoint List
|
||||
bool Sel_NextNav();
|
||||
|
||||
|
||||
// Tell us if autopilot is allowed
|
||||
// Tell us is autopilot is allow
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within AutopilotMinEnemyDistance meters
|
||||
// * No asteroids within AutopilotMinAsteroidDistance meters
|
||||
// * No enemies within 5,000 meters
|
||||
// * Destination > 1,000 meters away
|
||||
// * Support ship not present or is actively leaving
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
|
||||
|
||||
// Check if autopilot is allowed at player's current position
|
||||
// See CanAutopilot(vec3d, bool) for more information
|
||||
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
|
||||
bool CanAutopilot(bool send_msg=false);
|
||||
bool CanAutopilotPos(vec3d targetPos);
|
||||
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
// Returns false if autopilot cannot be started. True otherwise.
|
||||
bool StartAutopilot();
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
void StartAutopilot();
|
||||
|
||||
// Checks if autopilot should automatically die
|
||||
// Returns true if:
|
||||
// * Targetted waypoint < 1,000 meters away
|
||||
// * Enemy < 5,000 meters
|
||||
bool Autopilot_AutoDiable();
|
||||
|
||||
// Disengages autopilot
|
||||
// this does:
|
||||
|
||||
@@ -53,9 +53,9 @@ typedef union bm_extra_info {
|
||||
struct {
|
||||
// Stuff needed for animations
|
||||
int first_frame; // used for animations -- points to index of first frame
|
||||
int num_frames; // used for animation -- number of frames in the animation
|
||||
int keyframe; // used for animation -- keyframe info
|
||||
int num_frames; // used for animation -- number of frames in the animation
|
||||
ubyte fps; // used for animation -- frames per second
|
||||
int keyframe; // used for animation -- keyframe info
|
||||
|
||||
struct {
|
||||
// stuff for static animations
|
||||
|
||||
+176
-218
@@ -17,8 +17,6 @@
|
||||
#include <windows.h> // for MAX_PATH
|
||||
#endif
|
||||
|
||||
#include <limits.h> // for MAX_INT
|
||||
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "pcxutils/pcxutils.h"
|
||||
#include "palman/palman.h"
|
||||
@@ -62,7 +60,7 @@ int Bm_paging = 0;
|
||||
|
||||
// locals
|
||||
static unsigned int Bm_next_signature = 0x1234;
|
||||
static int bm_next_handle = 1;
|
||||
static int bm_next_handle = 0;
|
||||
int Bm_low_mem = 0;
|
||||
// Bm_max_ram - How much RAM bmpman can use for textures.
|
||||
// Set to <1 to make it use all it wants.
|
||||
@@ -80,33 +78,23 @@ static int Bm_ignore_load_count = 0;
|
||||
// 2 = Debug low memory ( only use first frame of each ani )
|
||||
void bm_set_low_mem( int mode )
|
||||
{
|
||||
Assert( (mode >= 0) && (mode<=2) );
|
||||
|
||||
CLAMP(mode, 0, 2);
|
||||
Assert( (mode >= 0) && (mode<=2 ));
|
||||
Bm_low_mem = mode;
|
||||
}
|
||||
|
||||
|
||||
int bm_get_next_handle()
|
||||
{
|
||||
//bm_next_handle used to wrap around to 1 if it was over 30000. Now, believe it or not, but that is actually not uncommon;
|
||||
//as bitmaps get allocated and released, bm_next_handle could get there far more often than you'd think.
|
||||
//The check introduced below is intended to replace this behaviour with one that ensures we won't be seeing handle collisions
|
||||
//for a very long time.
|
||||
|
||||
int n = bm_next_handle;
|
||||
bm_next_handle++;
|
||||
|
||||
//Due to the way bm_next_handle is used to generate the /actual/ bitmap handles ( (bm_next_handle * MAX_BITMAPS) + free slot index in bm_bitmaps[]),
|
||||
//this check is necessary to ensure we don't start giving out negative handles all of a sudden.
|
||||
if (( (bm_next_handle + 1) * MAX_BITMAPS) > INT_MAX)
|
||||
if ( bm_next_handle > 30000 ) {
|
||||
bm_next_handle = 1;
|
||||
|
||||
return bm_next_handle;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a bitmaps data if it can
|
||||
*/
|
||||
// Frees a bitmaps data if it should, and
|
||||
// Returns true if bitmap n can free it's data.
|
||||
static void bm_free_data(int n, bool release = false)
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -121,12 +109,12 @@ static void bm_free_data(int n, bool release = false)
|
||||
|
||||
// If there isn't a bitmap in this structure, don't
|
||||
// do anything but clear out the bitmap info
|
||||
if (be->type==BM_TYPE_NONE)
|
||||
if ( be->type==BM_TYPE_NONE)
|
||||
goto SkipFree;
|
||||
|
||||
// Don't free up memory for user defined bitmaps, since
|
||||
// BmpMan isn't the one in charge of allocating/deallocing them.
|
||||
if (be->type==BM_TYPE_USER) {
|
||||
if ( ( be->type==BM_TYPE_USER ) ) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -136,7 +124,7 @@ static void bm_free_data(int n, bool release = false)
|
||||
|
||||
// If this bitmap doesn't have any data to free, skip
|
||||
// the freeing it part of this.
|
||||
if (bmp->data == 0) {
|
||||
if ( (bmp->data == 0) ) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -145,6 +133,8 @@ static void bm_free_data(int n, bool release = false)
|
||||
}
|
||||
|
||||
// Free up the data now!
|
||||
|
||||
// mprintf(( "Bitmap %d freed %d bytes\n", n, bm_bitmaps[n].data_size ));
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
bm_texture_ram -= be->data_size;
|
||||
#endif
|
||||
@@ -164,16 +154,13 @@ SkipFree:
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
be->data_size = 0;
|
||||
#endif
|
||||
be->signature = Bm_next_signature++;
|
||||
be->signature = Bm_next_signature++;
|
||||
}
|
||||
|
||||
/**
|
||||
* A special version of bm_free_data() that can be safely used in gr_*_texture
|
||||
* to save system memory once textures have been transfered to API memory
|
||||
* it doesn't restore the slot to a pristine state, it only releases the data
|
||||
*
|
||||
* NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!!
|
||||
*/
|
||||
// a special version of bm_free_data() that can be safely used in gr_*_texture
|
||||
// to save system memory once textures have been transfered to API memory
|
||||
// it doesn't restore the slot to a pristine state, it only releases the data
|
||||
// NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!!
|
||||
static void bm_free_data_fast(int n)
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -186,12 +173,12 @@ static void bm_free_data_fast(int n)
|
||||
|
||||
// If there isn't a bitmap in this structure, don't
|
||||
// do anything but clear out the bitmap info
|
||||
if (be->type == BM_TYPE_NONE)
|
||||
if ( be->type == BM_TYPE_NONE)
|
||||
return;
|
||||
|
||||
// Don't free up memory for user defined bitmaps, since
|
||||
// BmpMan isn't the one in charge of allocating/deallocing them.
|
||||
if (be->type == BM_TYPE_USER) {
|
||||
if ( ( be->type == BM_TYPE_USER ) ) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -201,7 +188,7 @@ static void bm_free_data_fast(int n)
|
||||
|
||||
// If this bitmap doesn't have any data to free, skip
|
||||
// the freeing it part of this.
|
||||
if (bmp->data == 0) {
|
||||
if ( (bmp->data == 0) ) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 ) {
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -212,6 +199,8 @@ static void bm_free_data_fast(int n)
|
||||
}
|
||||
|
||||
// Free up the data now!
|
||||
|
||||
// mprintf(( "Bitmap %d freed %d bytes\n", n, bm_bitmaps[n].data_size ));
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
bm_texture_ram -= be->data_size;
|
||||
be->data_size = 0;
|
||||
@@ -240,12 +229,11 @@ void *bm_malloc( int n, int size )
|
||||
bm_texture_ram += size;
|
||||
#endif
|
||||
|
||||
// mprintf(( "Bitmap %d allocated %d bytes\n", n, size ));
|
||||
return vm_malloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like bm_malloc but only keeps track of how much memory is getting used
|
||||
*/
|
||||
// kinda like bm_malloc but only keeps track of how much memory is getting used
|
||||
void bm_update_memory_used( int n, int size )
|
||||
{
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
@@ -306,11 +294,9 @@ void bm_init()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of bytes of bitmaps locked this frame
|
||||
* @param ntotal number of bytes of bitmaps locked this frame
|
||||
* @param nnew number of bytes of bitmaps locked this frame that weren't locked last frame
|
||||
*/
|
||||
// Returns number of bytes of bitmaps locked this frame
|
||||
// ntotal = number of bytes of bitmaps locked this frame
|
||||
// nnew = number of bytes of bitmaps locked this frame that weren't locked last frame
|
||||
void bm_get_frame_usage(int *ntotal, int *nnew)
|
||||
{
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
@@ -332,17 +318,12 @@ void bm_get_frame_usage(int *ntotal, int *nnew)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bitmap that exists in RAM somewhere, instead
|
||||
* of coming from a disk file.
|
||||
*
|
||||
* You pass in a pointer to a block of 32 (or 8)-bit-per-pixel data.
|
||||
* Right now, the only bpp you can pass in is 32 or 8.
|
||||
*
|
||||
* On success, it returns the bitmap number.
|
||||
*
|
||||
* You cannot free that RAM until bm_release is called on that bitmap.
|
||||
*/
|
||||
// Creates a bitmap that exists in RAM somewhere, instead
|
||||
// of coming from a disk file. You pass in a pointer to a
|
||||
// block of 32 (or 8)-bit-per-pixel data. Right now, the only
|
||||
// bpp you can pass in is 32 or 8. On success, it returns the
|
||||
// bitmap number. You cannot free that RAM until bm_release
|
||||
// is called on that bitmap.
|
||||
int bm_create( int bpp, int w, int h, void *data, int flags )
|
||||
{
|
||||
if (bpp == 8) {
|
||||
@@ -408,12 +389,10 @@ int bm_create( int bpp, int w, int h, void *data, int flags )
|
||||
return bm_bitmaps[n].handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a raw filename and an extension set, try and find the bitmap
|
||||
* that isn't already loaded and may exist somewhere on the disk
|
||||
*
|
||||
* @return -1 if it could not be found index into ext_list[] if it was found as a file, fills img_cfg if available
|
||||
*/
|
||||
// slow sub helper function. Given a raw filename and an extension set, try and find the bitmap
|
||||
// that isn't already loaded and may exist somewhere on the disk
|
||||
// returns -1 if it could not be found
|
||||
// index into ext_list[] if it was found as a file, fills img_cfg if available
|
||||
int bm_load_sub_slow(char *real_filename, const int num_ext, const char **ext_list, CFILE **img_cfp = NULL, int dir_type = CF_TYPE_ANY)
|
||||
{
|
||||
char full_path[MAX_PATH];
|
||||
@@ -439,10 +418,10 @@ int bm_load_sub_slow(char *real_filename, const int num_ext, const char **ext_li
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a raw filename, try and find a bitmap that's already loaded
|
||||
* @return 0 if it could not be found, 1 if it already exists, fills in handle
|
||||
*/
|
||||
// fast sub helper function. Given a raw filename, try and find a bitmap
|
||||
// that's already loaded
|
||||
// returns 0 if it could not be found
|
||||
// 1 if it already exists, fills in handle
|
||||
int bm_load_sub_fast(char *real_filename, int *handle, int dir_type = CF_TYPE_ANY, bool animated_type = false)
|
||||
{
|
||||
if (Bm_ignore_duplicates)
|
||||
@@ -476,13 +455,11 @@ int bm_load_sub_fast(char *real_filename, int *handle, int dir_type = CF_TYPE_AN
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bitmap so we can draw with it later.
|
||||
* Function doesn't actually load the data, only width, height, and possibly flags.
|
||||
*
|
||||
* @return A negative number if it couldn't load the bitmap.
|
||||
* @return On success, it returns the bitmap number.
|
||||
*/
|
||||
// This loads a bitmap so we can draw with it later.
|
||||
// It returns a negative number if it couldn't load
|
||||
// the bitmap. On success, it returns the bitmap
|
||||
// number. Function doesn't actually load the data, only
|
||||
// width, height, and possibly flags.
|
||||
int bm_load( char *real_filename )
|
||||
{
|
||||
int i, free_slot = -1;
|
||||
@@ -508,6 +485,7 @@ int bm_load( char *real_filename )
|
||||
char *p = strrchr( filename, '.' );
|
||||
if ( p ) {
|
||||
mprintf(( "Someone passed an extension to bm_load for file '%s'\n", real_filename ));
|
||||
//Int3();
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
@@ -556,7 +534,7 @@ int bm_load( char *real_filename )
|
||||
}
|
||||
|
||||
if (free_slot < 0) {
|
||||
Assertion(free_slot < 0, "Could not find free BMPMAN slot for bitmap: %s", real_filename);
|
||||
Int3();
|
||||
goto Done;
|
||||
}
|
||||
|
||||
@@ -604,20 +582,9 @@ Done:
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as bm_load above, just with an SCP_string
|
||||
*/
|
||||
int bm_load(const SCP_string& filename)
|
||||
{
|
||||
return bm_load(const_cast<char*> (filename.c_str()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Special load function. Basically allows you to load a bitmap which already exists (by filename).
|
||||
*
|
||||
* This is useful because in some cases we need to have a bitmap which is locked in screen format
|
||||
* _and_ texture format, such as pilot pics and squad logos
|
||||
*/
|
||||
// special load function. basically allows you to load a bitmap which already exists (by filename).
|
||||
// this is useful because in some cases we need to have a bitmap which is locked in screen format
|
||||
// _and_ texture format, such as pilot pics and squad logos
|
||||
int bm_load_duplicate(char *filename)
|
||||
{
|
||||
int ret;
|
||||
@@ -701,6 +668,7 @@ static int find_block_of(int n)
|
||||
return nstart;
|
||||
}
|
||||
|
||||
// Error( LOCATION, "Couldn't find block of %d frames\n", n );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -709,8 +677,8 @@ int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps,
|
||||
int frames = 0, fps = 30, keyframe = 0, rval;
|
||||
char ext[8];
|
||||
ubyte c_type = BM_TYPE_NONE;
|
||||
char file_text[1024];
|
||||
char file_text_raw[1024];
|
||||
char file_text[50];
|
||||
char file_text_raw[50];
|
||||
|
||||
memset( ext, 0, sizeof(ext) );
|
||||
memset( file_text, 0, sizeof(file_text) );
|
||||
@@ -780,18 +748,15 @@ int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load animation
|
||||
*
|
||||
* @param real_filename filename of animation
|
||||
* @param nframes OUTPUT parameter: number of frames in the animation
|
||||
* @param fps OUTPUT/OPTIONAL parameter: intended fps for the animation
|
||||
* @param keyframe Keyframe number
|
||||
* @param can_drop_frames Toggle to allow dropped frames
|
||||
* @param dir_type Directory type
|
||||
*
|
||||
* @returns Bitmap number of first frame in the animation
|
||||
*/
|
||||
// ------------------------------------------------------------------
|
||||
// bm_load_animation()
|
||||
//
|
||||
// input: filename => filename of animation
|
||||
// nframes => OUTPUT parameter: number of frames in the animation
|
||||
// fps => OUTPUT/OPTIONAL parameter: intended fps for the animation
|
||||
//
|
||||
// returns: bitmap number of first frame in the animation
|
||||
//
|
||||
int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
|
||||
{
|
||||
int i, n;
|
||||
@@ -826,6 +791,7 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
|
||||
char *p = strchr( filename, '.' );
|
||||
if ( p ) {
|
||||
mprintf(( "Someone passed an extension to bm_load_animation for file '%s'\n", real_filename ));
|
||||
//Int3();
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
@@ -921,8 +887,8 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
|
||||
the_anim.keys[i].frame_num = 0;
|
||||
cfread(&the_anim.keys[i].frame_num, 2, 1, img_cfp);
|
||||
cfread(&the_anim.keys[i].offset, 4, 1, img_cfp);
|
||||
the_anim.keys[i].frame_num = INTEL_INT( the_anim.keys[i].frame_num ); //-V570
|
||||
the_anim.keys[i].offset = INTEL_INT( the_anim.keys[i].offset ); //-V570
|
||||
the_anim.keys[i].frame_num = INTEL_INT( the_anim.keys[i].frame_num );
|
||||
the_anim.keys[i].offset = INTEL_INT( the_anim.keys[i].offset );
|
||||
}
|
||||
//some retail anis have their keyframes reversed
|
||||
key = MAX(the_anim.keys[0].frame_num, the_anim.keys[1].frame_num);
|
||||
@@ -979,8 +945,8 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
|
||||
anim_frames = i;
|
||||
|
||||
// update all previous frames with the new count
|
||||
for (int j=0; j<anim_frames; j++)
|
||||
bm_bitmaps[n+j].info.ani.num_frames = anim_frames;
|
||||
for (i=0; i<anim_frames; i++)
|
||||
bm_bitmaps[n+i].info.ani.num_frames = anim_frames;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1065,10 +1031,7 @@ int bm_is_valid(int handle)
|
||||
return (bm_bitmaps[handle % MAX_BITMAPS].handle == handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets info.
|
||||
* w,h,flags,nframes or fps can be NULL if you don't care.
|
||||
*/
|
||||
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
|
||||
int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int *fps)
|
||||
{
|
||||
bitmap * bmp;
|
||||
@@ -1083,7 +1046,7 @@ int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int *
|
||||
}
|
||||
#endif
|
||||
|
||||
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_info().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
|
||||
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE!
|
||||
|
||||
if ( (bm_bitmaps[bitmapnum].type == BM_TYPE_NONE) || (bm_bitmaps[bitmapnum].handle != handle) ) {
|
||||
if (w) *w = 0;
|
||||
@@ -1126,24 +1089,23 @@ unsigned int bm_get_signature(int handle)
|
||||
if ( !bm_inited ) bm_init();
|
||||
|
||||
int bitmapnum = handle % MAX_BITMAPS;
|
||||
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_signature().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
|
||||
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
|
||||
|
||||
return bm_bitmaps[bitmapnum].signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image type
|
||||
*/
|
||||
//gets the image type
|
||||
ubyte bm_get_type(int handle)
|
||||
{
|
||||
if ( !bm_inited ) bm_init();
|
||||
|
||||
int bitmapnum = handle % MAX_BITMAPS;
|
||||
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_type().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
|
||||
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
|
||||
|
||||
return bm_bitmaps[bitmapnum].type;
|
||||
}
|
||||
|
||||
extern int palman_is_nondarkening(int r,int g, int b);
|
||||
static void bm_convert_format( int bitmapnum, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
int idx;
|
||||
@@ -1239,14 +1201,12 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
nframes = bm_bitmaps[first_frame].info.ani.num_frames;
|
||||
|
||||
if ( (the_anim = anim_load(bm_bitmaps[first_frame].filename, bm_bitmaps[first_frame].dir_type)) == NULL ) {
|
||||
nprintf(("BMPMAN", "Error opening %s in bm_lock\n", be->filename));
|
||||
return;
|
||||
// Error(LOCATION, "Error opening %s in bm_lock\n", be->filename);
|
||||
}
|
||||
|
||||
if ( (the_anim_instance = init_anim_instance(the_anim, bpp)) == NULL ) {
|
||||
nprintf(("BMPMAN", "Error opening %s in bm_lock\n", be->filename));
|
||||
// Error(LOCATION, "Error opening %s in bm_lock\n", be->filename);
|
||||
anim_free(the_anim);
|
||||
return;
|
||||
}
|
||||
|
||||
int can_drop_frames = 0;
|
||||
@@ -1275,7 +1235,11 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
|
||||
bm->data = (ptr_u)bm_malloc(first_frame + i, size);
|
||||
|
||||
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0 ,flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
|
||||
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0 ,flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
|
||||
|
||||
if ( frame_data == NULL ) {
|
||||
// Error(LOCATION,"Fatal error locking .ani file: %s\n", be->filename);
|
||||
}
|
||||
|
||||
ubyte *dptr, *sptr;
|
||||
|
||||
@@ -1284,6 +1248,8 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
|
||||
if ( (bm->w!=the_anim->width) || (bm->h!=the_anim->height) ) {
|
||||
// Scale it down
|
||||
// Int3(); // not ready yet - should only be ingame
|
||||
|
||||
// 8 bit
|
||||
if(bpp == 8){
|
||||
int w,h;
|
||||
@@ -1341,6 +1307,8 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
if ( (i < nframes-1) && can_drop_frames ) {
|
||||
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0, flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
|
||||
}
|
||||
|
||||
//mprintf(( "Checksum = %d\n", be->palette_checksum ));
|
||||
}
|
||||
|
||||
free_anim_instance(the_anim_instance);
|
||||
@@ -1383,8 +1351,9 @@ void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, uby
|
||||
break;
|
||||
|
||||
default:
|
||||
Error( LOCATION, "Unhandled user bitmap conversion from %d to %d bpp", be->info.user.bpp, bmp->bpp );
|
||||
Int3();
|
||||
break;
|
||||
// Error( LOCATION, "Unhandled user bitmap conversion from %d to %d bpp", be->info.user.bpp, bmp->bpp );
|
||||
}
|
||||
|
||||
bm_convert_format( bitmapnum, bmp, bpp, flags );
|
||||
@@ -1407,6 +1376,9 @@ void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
Assert( (bpp == 16) || (bpp == 24 ) || (bpp == 32) );
|
||||
}
|
||||
|
||||
// should never try to make an aabitmap out of a targa
|
||||
Assert(!(flags & BMP_AABITMAP));
|
||||
|
||||
// allocate bitmap data
|
||||
byte_size = (bpp >> 3);
|
||||
|
||||
@@ -1449,9 +1421,7 @@ void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
bm_convert_format( bitmapnum, bmp, bpp, flags );
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock a DDS file
|
||||
*/
|
||||
//lock a dds file
|
||||
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
ubyte *data = NULL;
|
||||
@@ -1515,9 +1485,7 @@ void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock a PNG file
|
||||
*/
|
||||
// lock a PNG file
|
||||
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
ubyte *data = NULL;
|
||||
@@ -1525,10 +1493,14 @@ void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
int d_size;
|
||||
int png_error = PNG_ERROR_INVALID;
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
//int size = bmp->w * bmp->h * d_size;
|
||||
|
||||
// Unload any existing data
|
||||
bm_free_data( bitmapnum );
|
||||
|
||||
// should never try to make an aabitmap out of a png
|
||||
Assert(!(flags & BMP_AABITMAP));
|
||||
|
||||
// allocate bitmap data
|
||||
Assert( bmp->w * bmp->h > 0 );
|
||||
|
||||
@@ -1562,9 +1534,7 @@ void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock a JPEG file
|
||||
*/
|
||||
// lock a JPEG file
|
||||
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
ubyte *data = NULL;
|
||||
@@ -1575,6 +1545,9 @@ void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
// Unload any existing data
|
||||
bm_free_data( bitmapnum );
|
||||
|
||||
// should never try to make an aabitmap out of a jpeg
|
||||
Assert(!(flags & BMP_AABITMAP));
|
||||
|
||||
d_size = (bpp >> 3);
|
||||
|
||||
// allocate bitmap data
|
||||
@@ -1611,11 +1584,10 @@ void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
MONITOR( NumBitmapPage )
|
||||
MONITOR( SizeBitmapPage )
|
||||
|
||||
/**
|
||||
* This locks down a bitmap and returns a pointer to a bitmap that can be accessed until you call bm_unlock.
|
||||
*
|
||||
* Only lock a bitmap when you need it! This will convert it into the appropriate format also.
|
||||
*/
|
||||
// This locks down a bitmap and returns a pointer to a bitmap
|
||||
// that can be accessed until you call bm_unlock. Only lock
|
||||
// a bitmap when you need it! This will convert it into the
|
||||
// appropriate format also.
|
||||
bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
{
|
||||
bitmap *bmp;
|
||||
@@ -1625,7 +1597,15 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
|
||||
int bitmapnum = handle % MAX_BITMAPS;
|
||||
|
||||
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid handle %d passed to bm_lock. This might be due to an animation elsewhere in the code being too short.\n", handle ); // INVALID BITMAP HANDLE
|
||||
#ifndef NDEBUG
|
||||
if(bm_bitmaps[bitmapnum].handle != handle) {
|
||||
mprintf(("bm_lock - %s: bm_bitmaps[%d].handle = %d, handle = %d\n", bm_bitmaps[bitmapnum].filename, bitmapnum, bm_bitmaps[bitmapnum].handle, handle));
|
||||
}
|
||||
#endif
|
||||
|
||||
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
|
||||
|
||||
// flags &= (~BMP_RLE);
|
||||
|
||||
// to fix a couple of OGL bpp passes, force 8bit on AABITMAP - taylor
|
||||
if (flags & BMP_AABITMAP)
|
||||
@@ -1715,12 +1695,11 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
return bmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks a bitmap
|
||||
*
|
||||
* Decrements the ref_count member of the bitmap_entry struct. A bitmap can only be unloaded
|
||||
* when the ref_count is 0.
|
||||
*/
|
||||
// Unlocks a bitmap
|
||||
//
|
||||
// Decrements the ref_count member of the bitmap_entry struct. A bitmap can only be unloaded
|
||||
// when the ref_count is 0.
|
||||
//
|
||||
void bm_unlock( int handle )
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -1747,6 +1726,11 @@ void bm_unlock( int handle )
|
||||
Assert(be->ref_count >= 0); // Trying to unlock data more times than lock was called!!!
|
||||
}
|
||||
|
||||
|
||||
void bm_update()
|
||||
{
|
||||
}
|
||||
|
||||
char *bm_get_filename(int handle)
|
||||
{
|
||||
int n;
|
||||
@@ -1776,19 +1760,16 @@ void bm_get_palette(int handle, ubyte *pal, char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the bitmap's data and entire slot, so bitmap 'handle' won't be valid anymore
|
||||
* NOTE: this releases the slot of EVERY frame in an ANI so don't pass any frame but the first
|
||||
*
|
||||
* @param handle index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param clear_render_targets Whether to release a render target
|
||||
*
|
||||
* @return 1 on successful release, 0 otherwise
|
||||
*/
|
||||
// --------------------------------------------------------------------------------------
|
||||
// bm_release() - unloads the bitmap's data and entire slot, so bitmap 'n' won't be valid anymore
|
||||
// NOTE: this releases the slot of EVERY frame in an ANI so don't pass any frame but the first
|
||||
//
|
||||
// parameters: n => index into bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
//
|
||||
// returns: 1 on successful release, 0 otherwise
|
||||
|
||||
int bm_release(int handle, int clear_render_targets)
|
||||
{
|
||||
Assert(handle >= 0);
|
||||
|
||||
bitmap_entry *be;
|
||||
|
||||
int n = handle % MAX_BITMAPS;
|
||||
@@ -1882,14 +1863,14 @@ int bm_release(int handle, int clear_render_targets)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the data, but not the bitmap info.
|
||||
*
|
||||
* @param handle index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param clear_render_targets Whether to release a render target
|
||||
*
|
||||
* @return 1 on successful release, 0 otherwise
|
||||
*/
|
||||
// --------------------------------------------------------------------------------------
|
||||
// bm_unload() - unloads the data, but not the bitmap info.
|
||||
//
|
||||
// parameters: n => index into bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
//
|
||||
// returns: 0 => unload failed
|
||||
// 1 => unload successful
|
||||
//
|
||||
int bm_unload( int handle, int clear_render_targets )
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -1951,12 +1932,9 @@ int bm_unload( int handle, int clear_render_targets )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just like bm_unload() except that it doesn't care about what load_count is
|
||||
* and will just plow through and release the data anyway
|
||||
*
|
||||
* NOTE: that bm_free_data_fast() is used here and NOT bm_free_data()!
|
||||
*/
|
||||
// just like bm_unload() except that it doesn't care about what load_count is
|
||||
// and will just plow through and release the data anyway
|
||||
// (NOTE that bm_free_data_fast() is used here and NOT bm_free_data()!)
|
||||
int bm_unload_fast( int handle, int clear_render_targets )
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -1964,6 +1942,7 @@ int bm_unload_fast( int handle, int clear_render_targets )
|
||||
|
||||
int n = handle % MAX_BITMAPS;
|
||||
|
||||
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
be = &bm_bitmaps[n];
|
||||
bmp = &be->bm;
|
||||
@@ -1995,9 +1974,7 @@ int bm_unload_fast( int handle, int clear_render_targets )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload all used bitmaps
|
||||
*/
|
||||
// unload all used bitmaps
|
||||
void bm_unload_all()
|
||||
{
|
||||
int i;
|
||||
@@ -2063,9 +2040,7 @@ DCF(bmpman,"Shows/changes bitmap caching parameters and usage")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a texture as being used for this level
|
||||
*/
|
||||
// Marks a texture as being used for this level
|
||||
void bm_page_in_texture( int bitmapnum, int nframes )
|
||||
{
|
||||
int i;
|
||||
@@ -2117,12 +2092,9 @@ void bm_page_in_texture( int bitmapnum, int nframes )
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a texture as being a transparent texture used for this level
|
||||
*
|
||||
* @param bitmapnum Index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param nframes Animation number of frames
|
||||
*/
|
||||
// marks a texture as being a transparent textyre used for this level
|
||||
// Marks a texture as being used for this level
|
||||
// If num_frames is passed, assume this is an animation
|
||||
void bm_page_in_xparent_texture( int bitmapnum, int nframes)
|
||||
{
|
||||
int i;
|
||||
@@ -2167,12 +2139,7 @@ void bm_page_in_xparent_texture( int bitmapnum, int nframes)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks an aabitmap as being used for this level
|
||||
*
|
||||
* @param bitmapnum Index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param nframes Animation number of frames
|
||||
*/
|
||||
// Marks an aabitmap as being used for this level
|
||||
void bm_page_in_aabitmap( int bitmapnum, int nframes )
|
||||
{
|
||||
int i;
|
||||
@@ -2192,9 +2159,9 @@ void bm_page_in_aabitmap( int bitmapnum, int nframes )
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the bitmap manager to start keeping track of what bitmaps are used where.
|
||||
*/
|
||||
|
||||
|
||||
// Tell the bitmap manager to start keeping track of what bitmaps are used where.
|
||||
void bm_page_in_start()
|
||||
{
|
||||
int i;
|
||||
@@ -2292,13 +2259,12 @@ void bm_page_in_stop()
|
||||
}
|
||||
|
||||
mprintf(( "Bmpman: %d/%d bitmap slots in use.\n", total_bitmaps, MAX_BITMAPS ));
|
||||
//mprintf(( "Bmpman: Usage went from %d KB to %d KB.\n", usage_before/1024, usage_after/1024 ));
|
||||
|
||||
Bm_paging = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* For unloading bitmaps while a mission is going
|
||||
*/
|
||||
// for unloading bitmaps while a mission is going
|
||||
int bm_page_out( int bitmap_id )
|
||||
{
|
||||
int n = bitmap_id % MAX_BITMAPS;
|
||||
@@ -2309,6 +2275,7 @@ int bm_page_out( int bitmap_id )
|
||||
if ( bm_bitmaps[n].type == BM_TYPE_NONE )
|
||||
return 0;
|
||||
|
||||
|
||||
Assert( bm_bitmaps[n].handle == bitmap_id ); // INVALID BITMAP HANDLE
|
||||
|
||||
// it's possible to hit < 0 here when model_page_out_textures() is called from
|
||||
@@ -2394,9 +2361,7 @@ void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv
|
||||
*((unsigned int*)pixel) |= (unsigned int)(Gr_current_alpha->mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* For selecting pixel formats
|
||||
*/
|
||||
// for selecting pixel formats
|
||||
void BM_SELECT_SCREEN_FORMAT()
|
||||
{
|
||||
Gr_current_red = &Gr_red;
|
||||
@@ -2436,9 +2401,7 @@ void BM_SELECT_ALPHA_TEX_FORMAT()
|
||||
bm_set_components = bm_set_components_argb_16_tex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rgba components of a pixel, any of the parameters can be NULL
|
||||
*/
|
||||
// get the rgba components of a pixel, any of the parameters can be NULL
|
||||
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
{
|
||||
int bit_32 = 0;
|
||||
@@ -2447,6 +2410,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
bit_32 = 1;
|
||||
}
|
||||
|
||||
|
||||
if(r != NULL){
|
||||
if(bit_32){
|
||||
*r = ubyte(( (*((unsigned int*)pixel) & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale);
|
||||
@@ -2454,7 +2418,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
*r = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale);
|
||||
}
|
||||
}
|
||||
|
||||
if(g != NULL){
|
||||
if(bit_32){
|
||||
*g = ubyte(( (*((unsigned int*)pixel) & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale);
|
||||
@@ -2462,7 +2425,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
*g = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale);
|
||||
}
|
||||
}
|
||||
|
||||
if(b != NULL){
|
||||
if(bit_32){
|
||||
*b = ubyte(( (*((unsigned int*)pixel) & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale);
|
||||
@@ -2482,9 +2444,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename
|
||||
*/
|
||||
// get filename
|
||||
void bm_get_filename(int bitmapnum, char *filename)
|
||||
{
|
||||
if(!bm_is_valid(bitmapnum))
|
||||
@@ -2499,9 +2459,7 @@ void bm_get_filename(int bitmapnum, char *filename)
|
||||
strcpy(filename, bm_bitmaps[n].filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed only for compressed bitmaps
|
||||
*/
|
||||
// needed only for compressed bitmaps
|
||||
int bm_is_compressed(int num)
|
||||
{
|
||||
int n = num % MAX_BITMAPS;
|
||||
@@ -2557,17 +2515,17 @@ int bm_has_alpha_channel(int handle)
|
||||
return (bm_bitmaps[n].bm.true_bpp == 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purpose for this is to return the correct TCACHE_TYPE for compressed graphics,
|
||||
* uncompressed graphics are assumed to be of type NORMAL.
|
||||
*
|
||||
* The only other real format to check for is TCACHE_TYPE_SECTIONED - taylor
|
||||
*/
|
||||
// the only real purpose for this is to return the correct TCACHE_TYPE for compressed graphics,
|
||||
// uncompressed graphics are assumed to be of type NORMAL. The only other real format to check
|
||||
// for is TCACHE_TYPE_SECTIONED - taylor
|
||||
int bm_get_tcache_type(int num)
|
||||
{
|
||||
if ( bm_is_compressed(num) )
|
||||
return TCACHE_TYPE_COMPRESSED;
|
||||
|
||||
// if ( bm_is_render_target(num) )
|
||||
// return TCACHE_TYPE_RENDER_TARGET;
|
||||
|
||||
return TCACHE_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
@@ -2594,9 +2552,7 @@ int bm_get_num_mipmaps(int num)
|
||||
return bm_bitmaps[n].num_mipmaps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an 8-bit (256 color) image to a 24-bit BGR image sending new bitmap data to "out_data"
|
||||
*/
|
||||
// convert an 8-bit (256 color) image to a 24-bit BGR image sending new bitmap data to "out_data"
|
||||
int bm_convert_color_index_to_BGR(int num, ubyte **out_data)
|
||||
{
|
||||
int n = num % MAX_BITMAPS;
|
||||
@@ -2679,10 +2635,8 @@ int bm_convert_color_index_to_BGR(int num, ubyte **out_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of all bitmaps loaded, but not necessarily in memory
|
||||
* used to debug bmpman after a mission load
|
||||
*/
|
||||
// list of all bitmaps loaded, but not necessarily in memory
|
||||
// used to debug bmpman after a mission load
|
||||
void bm_print_bitmaps()
|
||||
{
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
@@ -2701,11 +2655,12 @@ void bm_print_bitmaps()
|
||||
#endif
|
||||
}
|
||||
|
||||
// this will create a render target as close to the desired resolution as possable of the following base types:
|
||||
// this will create a render target as close to the desiered resolution as posable of the following base types:
|
||||
// - BMP_FLAG_RENDER_TARGET_STATIC
|
||||
// static render targets are ones that you intend to draw to once or not very often in game
|
||||
// - BMP_FLAG_RENDER_TARGET_DYNAMIC
|
||||
// dynamic render targets are ones that you will be drawing to all the time (like once per frame)
|
||||
|
||||
int bm_make_render_target( int width, int height, int flags )
|
||||
{
|
||||
int i, n;
|
||||
@@ -2730,9 +2685,11 @@ int bm_make_render_target( int width, int height, int flags )
|
||||
if ( n == -1 )
|
||||
return -1;
|
||||
|
||||
|
||||
if ( !gr_bm_make_render_target(n, &w, &h, &bpp, &mm_lvl, flags) )
|
||||
return -1;
|
||||
|
||||
|
||||
Assert( mm_lvl > 0 );
|
||||
|
||||
if (flags & BMP_FLAG_RENDER_TARGET_STATIC) {
|
||||
@@ -2775,6 +2732,7 @@ int bm_make_render_target( int width, int height, int flags )
|
||||
if (bm_bitmaps[n].mem_taken) {
|
||||
bm_bitmaps[n].bm.data = (ptr_u) bm_malloc(n, bm_bitmaps[n].mem_taken);
|
||||
}
|
||||
// bm_update_memory_used( n, bm_bitmaps[n].mem_taken );
|
||||
|
||||
return bm_bitmaps[n].handle;
|
||||
}
|
||||
@@ -2808,7 +2766,7 @@ int bm_set_render_target(int handle, int face)
|
||||
|
||||
if ( gr_bm_set_render_target(n, face) ) {
|
||||
if (gr_screen.rendering_to_texture == -1) {
|
||||
//if we are moving from the back buffer to a texture save whatever the current settings are
|
||||
//if we are moveing from the back buffer to a texture save whatever the current settings are
|
||||
gr_screen.save_max_w = gr_screen.max_w;
|
||||
gr_screen.save_max_h = gr_screen.max_h;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
#define BMPMAN_NDEBUG
|
||||
#endif
|
||||
|
||||
|
||||
// this is causing problems - let's UP IT -- Kazan
|
||||
// bumped from 3500 to 4500 2004/09/21 - taylor
|
||||
// bumped to 4750 2005/02/03 - taylor
|
||||
//#define MAX_BITMAPS 3500 // How many bitmaps the game can handle
|
||||
#define MAX_BITMAPS 4750 // How many bitmaps the game can handle
|
||||
// NOTE: MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's
|
||||
// proper use even the largest missions should stay under this number. With the largest retail
|
||||
@@ -89,7 +94,6 @@ extern int bm_texture_ram;
|
||||
// the bitmap. On success, it returns the bitmap
|
||||
// number.
|
||||
int bm_load(char * filename);
|
||||
int bm_load(const SCP_string& filename);
|
||||
|
||||
// special load function. basically allows you to load a bitmap which already exists (by filename).
|
||||
// this is useful because in some cases we need to have a bitmap which is locked in screen format
|
||||
@@ -156,6 +160,9 @@ int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, i
|
||||
// get filename
|
||||
extern void bm_get_filename(int bitmapnum, char *filename);
|
||||
|
||||
// resyncs all the bitmap palette
|
||||
extern void bm_update();
|
||||
|
||||
// call to load all data for all bitmaps that have been requested to be loaded
|
||||
extern void bm_gfx_load_all();
|
||||
extern void bm_unload_all();
|
||||
|
||||
+217
-37
@@ -24,12 +24,16 @@ SCP_vector<camera*> Cameras;
|
||||
camid Current_camera;
|
||||
camid Main_camera;
|
||||
|
||||
//*************************INTERNAL FUNCS*************************
|
||||
//static avd_camera *cam_upgrade_to_avd(camera *cam);
|
||||
|
||||
//*************************CLASS: camera*************************
|
||||
//This is where the camera class beings! :D
|
||||
camera::camera(char *in_name, int in_signature)
|
||||
{
|
||||
set_name(in_name);
|
||||
sig = in_signature;
|
||||
// flags = CAM_DEFAULT_FLAGS;
|
||||
|
||||
reset();
|
||||
}
|
||||
@@ -71,11 +75,31 @@ void camera::reset()
|
||||
pos_y.clear();
|
||||
pos_z.clear();
|
||||
|
||||
/*
|
||||
ori_p.clear();
|
||||
ori_b.clear();
|
||||
ori_h.clear();
|
||||
*/
|
||||
/*
|
||||
ori_progress.clear();
|
||||
ori_initial = ori_final = vmd_identity_matrix;
|
||||
*/
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
ori[i].clear();
|
||||
ori[i].set(vmd_identity_matrix.a1d[i]);
|
||||
}
|
||||
/*
|
||||
flags = CAM_DEFAULT_FLAGS;
|
||||
|
||||
desired_position = position = vmd_zero_vector;
|
||||
|
||||
translation_velocity = translation_vel_limit = translation_acc_limit = vmd_zero_vector;
|
||||
|
||||
vm_set_identity(&orientation);
|
||||
vm_set_identity(&desired_orientation);
|
||||
rotation_rate = rotation_vel_limit = rotation_acc_limit = vmd_zero_vector;
|
||||
*/
|
||||
}
|
||||
|
||||
void camera::set_name(char *in_name)
|
||||
@@ -120,19 +144,15 @@ void camera::set_object_target(object *objp, int n_object_target_submodel)
|
||||
object_target_submodel = n_object_target_submodel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom function receives the already-modified current position value.
|
||||
* It should be replaced or added to as the custom function modifier sees fit.
|
||||
*/
|
||||
//Custom function receives the already-modified current position value.
|
||||
//It should be replaced or added to as the custom function modifier sees fit.
|
||||
void camera::set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *camera_pos))
|
||||
{
|
||||
func_custom_position = n_func_custom_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom function receives the already-modified current orientation value.
|
||||
* It should be replaced or added to as the custom function modifier sees fit.
|
||||
*/
|
||||
//Custom function receives the already-modified current orientation value.
|
||||
//It should be replaced or added to as the custom function modifier sees fit.
|
||||
void camera::set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *camera_ori))
|
||||
{
|
||||
func_custom_orientation = n_func_custom_orientation;
|
||||
@@ -192,6 +212,26 @@ void camera::set_rotation(matrix *in_orientation, float in_rotation_time, float
|
||||
|
||||
for(int i = 0; i < 9; i++)
|
||||
ori[i].setAVD(in_orientation->a1d[i], in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time, 0.0f);
|
||||
//WMC - This stationary check is here because it's a lot more
|
||||
//accurate to directly save the matrix, if we've been provided one.
|
||||
//IMPORTANT: Without this chunk, the HUD and view waves around with
|
||||
// the main camera.
|
||||
/*
|
||||
angles a;
|
||||
vm_extract_angles_matrix(&a, in_orientation);
|
||||
if(in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f)
|
||||
{
|
||||
c_ori = *in_orientation;
|
||||
ori_p.set(a.p);
|
||||
ori_b.set(a.b);
|
||||
ori_h.set(a.h);
|
||||
flags |= CAM_STATIONARY_ORI;
|
||||
return;
|
||||
}
|
||||
|
||||
//Continue on
|
||||
this->set_rotation(&a, in_rotation_time, in_rotation_acceleration_time);
|
||||
*/
|
||||
}
|
||||
|
||||
void camera::set_rotation(angles *in_angles, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
|
||||
@@ -199,6 +239,33 @@ void camera::set_rotation(angles *in_angles, float in_rotation_time, float in_ro
|
||||
matrix mtx = IDENTITY_MATRIX;
|
||||
vm_rotate_matrix_by_angles(&mtx, in_angles);
|
||||
this->set_rotation(&mtx, in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time);
|
||||
/*
|
||||
if(in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f)
|
||||
{
|
||||
ori_p.set(in_angles->p);
|
||||
ori_b.set(in_angles->b);
|
||||
ori_h.set(in_angles->h);
|
||||
|
||||
c_ori = vmd_identity_matrix;
|
||||
vm_rotate_matrix_by_angles(&c_ori, in_angles);
|
||||
|
||||
flags |= CAM_STATIONARY_ORI;
|
||||
return;
|
||||
}
|
||||
|
||||
flags &= ~CAM_STATIONARY_ORI;
|
||||
if(in_angles == NULL)
|
||||
{
|
||||
ori_p.setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
|
||||
ori_b.setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
|
||||
ori_h.setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
ori_p.setAVD(in_angles->p, in_rotation_time, in_rotation_acceleration_time, in_rotation_acceleration_time, 0.0f);
|
||||
ori_b.setAVD(in_angles->b, in_rotation_time, in_rotation_acceleration_time, in_rotation_acceleration_time, 0.0f);
|
||||
ori_h.setAVD(in_angles->h, in_rotation_time, in_rotation_acceleration_time, in_rotation_acceleration_time, 0.0f);
|
||||
*/
|
||||
}
|
||||
|
||||
void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
|
||||
@@ -227,6 +294,27 @@ void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float
|
||||
void camera::set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time)
|
||||
{
|
||||
Error(LOCATION, "This function is disabled until further notice.");
|
||||
/*
|
||||
ori_p.setVD(in_acceleration_time, in_acceleration_time, in_rotation_rate->p);
|
||||
ori_b.setVD(in_acceleration_time, in_acceleration_time, in_rotation_rate->b);
|
||||
ori_h.setVD(in_acceleration_time, in_acceleration_time, in_rotation_rate->h);
|
||||
*/
|
||||
|
||||
/*if(in_rotation_rate == NULL)
|
||||
{
|
||||
rotation_rate.p = rotation_rate.b = rotation_rate.h = 0.0f;
|
||||
|
||||
rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time = 0.0f;
|
||||
rotation_rate_decel_time_til = -1.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time;
|
||||
rotation_rate_decel_time_til = -1.0f;
|
||||
|
||||
rotation_rate_delta.p = in_rotation_rate->p / in_rotation_acceleration_time;
|
||||
rotation_rate_delta.b = in_rotation_rate->b / in_rotation_acceleration_time;
|
||||
rotation_rate_delta.h = in_rotation_rate->h / in_rotation_acceleration_time;*/
|
||||
}
|
||||
|
||||
void camera::do_frame(float in_frametime)
|
||||
@@ -272,6 +360,7 @@ float camera::get_fov()
|
||||
|
||||
void camera::get_info(vec3d *position, matrix *orientation)
|
||||
{
|
||||
//WTF?
|
||||
if(position == NULL && orientation == NULL)
|
||||
return;
|
||||
|
||||
@@ -363,6 +452,17 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
c_ori = vmd_identity_matrix;
|
||||
}
|
||||
|
||||
//Do human interaction
|
||||
//WMC - Nevermind for now, maybe toggleable later.
|
||||
/*
|
||||
if ( Viewer_obj == object_host.objp || Viewer_mode & VM_CHASE ) {
|
||||
if ( Viewer_mode & VM_PADLOCK_ANY ) {
|
||||
player_get_padlock_orient(&c_ori);
|
||||
} else {
|
||||
compute_slew_matrix(&c_ori, &Viewer_slew_angles);
|
||||
}
|
||||
}*/
|
||||
|
||||
matrix mtxA = c_ori;
|
||||
matrix mtxB = IDENTITY_MATRIX;
|
||||
float pos = 0.0f;
|
||||
@@ -374,6 +474,15 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
vm_matrix_x_matrix(&c_ori, &mtxA, &mtxB);
|
||||
|
||||
vm_orthogonalize_matrix(&c_ori);
|
||||
/*
|
||||
angles a;
|
||||
ori_p.get(&a.p, NULL);
|
||||
ori_b.get(&a.b, NULL);
|
||||
ori_h.get(&a.h, NULL);
|
||||
|
||||
vm_rotate_matrix_by_angles(&c_ori, &a);
|
||||
*/
|
||||
//vm_angles_2_matrix(&c_ori, &a);
|
||||
}
|
||||
//Do custom orientation stuff, if needed
|
||||
if(func_custom_orientation != NULL)
|
||||
@@ -383,7 +492,6 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
*orientation = c_ori;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************warp_camera*************************
|
||||
warp_camera::warp_camera()
|
||||
{
|
||||
@@ -396,7 +504,16 @@ warp_camera::warp_camera(object *objp)
|
||||
vec3d object_pos = objp->pos;
|
||||
matrix tmp;
|
||||
ship_get_eye(&object_pos, &tmp, objp);
|
||||
|
||||
/*
|
||||
//matrix tmp_m = vmd_identity_matrix;
|
||||
camid cid = ship_get_eye( objp );
|
||||
if(cid.isValid())
|
||||
{
|
||||
camera *cam = cid.getCamera();
|
||||
cam->get_info(&player_pos, NULL);
|
||||
//tmp_m = *cam->get_orientation();
|
||||
}
|
||||
*/
|
||||
vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.rvec, 0.0f );
|
||||
vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.uvec, 0.952f );
|
||||
vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.fvec, -1.782f );
|
||||
@@ -442,6 +559,7 @@ void warp_camera::set_velocity( vec3d *in_vel, bool instantaneous )
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
void warp_camera::do_frame(float in_frametime)
|
||||
{
|
||||
vec3d new_vel, delta_pos;
|
||||
@@ -452,6 +570,8 @@ void warp_camera::do_frame(float in_frametime)
|
||||
|
||||
c_vel = new_vel;
|
||||
|
||||
// mprintf(( "Camera velocity = %.1f,%.1f, %.1f\n", Camera_velocity.xyz.x, Camera_velocity.xyz.y, Camera_velocity.xyz.z ));
|
||||
|
||||
vm_vec_add2( &c_pos, &delta_pos );
|
||||
|
||||
float ot = c_time+0.0f;
|
||||
@@ -471,6 +591,9 @@ void warp_camera::do_frame(float in_frametime)
|
||||
tmp.xyz.x = 22.0f * (float)sin(tmp_angle);
|
||||
tmp.xyz.y = -22.0f * (float)cos(tmp_angle);
|
||||
|
||||
//mprintf(( "Angle = %.1f, vx=%.1f, vy=%.1f\n", tmp_angle, tmp.xyz.x, tmp.xyz.y ));
|
||||
|
||||
//mprintf(( "Changing velocity!\n" ));
|
||||
this->set_velocity( &tmp, 0 );
|
||||
}
|
||||
|
||||
@@ -505,9 +628,9 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
|
||||
return;
|
||||
|
||||
char text_buf[256];
|
||||
if (in_text != NULL && in_text[0] != '\0')
|
||||
if (in_text != NULL && strlen(in_text) > 0)
|
||||
{
|
||||
strcpy_s(text_buf, in_text);
|
||||
strcpy(text_buf, in_text);
|
||||
sexp_replace_variable_names_with_values(text_buf, 256);
|
||||
in_text = text_buf;
|
||||
}
|
||||
@@ -518,11 +641,11 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
|
||||
int text_line_lens[MAX_SUBTITLE_LINES];
|
||||
|
||||
//Setup text
|
||||
if ( (in_text != NULL) && (in_text[0] != '\0') ) {
|
||||
if ( (in_text != NULL) && (strlen(in_text) > 0) ) {
|
||||
int split_width = (in_width > 0) ? in_width : 200;
|
||||
|
||||
num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
|
||||
SCP_string temp_str;
|
||||
std::string temp_str;
|
||||
for(int i = 0; i < num_text_lines; i++)
|
||||
{
|
||||
temp_str.assign(text_line_ptrs[i], text_line_lens[i]);
|
||||
@@ -542,7 +665,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
|
||||
fade_time = fl_abs(in_fade_time);
|
||||
|
||||
//Setup image
|
||||
if ( (in_imageanim != NULL) && (in_imageanim[0] != '\0') )
|
||||
if ( (in_imageanim != NULL) && (strlen(in_imageanim) > 0) )
|
||||
{
|
||||
image_id = bm_load(in_imageanim);
|
||||
|
||||
@@ -668,10 +791,9 @@ void subtitle::do_frame(float frametime)
|
||||
int x = text_pos.x;
|
||||
int y = text_pos.y;
|
||||
|
||||
|
||||
for(SCP_vector<SCP_string>::iterator line = text_lines.begin(); line != text_lines.end(); ++line)
|
||||
for(unsigned int i = 0; i < text_lines.size(); i++)
|
||||
{
|
||||
gr_string(x, y, (char*)line->c_str(), false);
|
||||
gr_string(x, y, (char*)text_lines[i].c_str(), false);
|
||||
y += font_height;
|
||||
}
|
||||
|
||||
@@ -721,8 +843,11 @@ subtitle::~subtitle()
|
||||
|
||||
void subtitle::clone(const subtitle &sub)
|
||||
{
|
||||
uint i = 0;
|
||||
|
||||
text_lines = sub.text_lines;
|
||||
for (i = 0; i < sub.text_lines.size(); i++) {
|
||||
text_lines.push_back(sub.text_lines[i]);
|
||||
}
|
||||
text_fontnum = sub.text_fontnum;
|
||||
|
||||
// copy the structs
|
||||
@@ -796,7 +921,7 @@ int camid::getSignature()
|
||||
|
||||
bool camid::isValid()
|
||||
{
|
||||
if(idx >= Cameras.size())
|
||||
if(idx < 0 || idx >= Cameras.size())
|
||||
return false;
|
||||
|
||||
if(Cameras[idx] == NULL)
|
||||
@@ -819,6 +944,14 @@ void cam_close()
|
||||
{
|
||||
//Set Current_camera to nothing
|
||||
Current_camera = camid();
|
||||
for(unsigned int i = 0; i < Cameras.size(); i++)
|
||||
{
|
||||
if(Cameras[i] != NULL)
|
||||
{
|
||||
delete Cameras[i];
|
||||
Cameras[i] = NULL;
|
||||
}
|
||||
}
|
||||
Cameras.clear();
|
||||
}
|
||||
|
||||
@@ -851,9 +984,29 @@ camid cam_create(char *n_name, vec3d *n_pos, matrix *n_ori, object *n_object, in
|
||||
strncpy(buf, n_name, NAME_LENGTH-1);
|
||||
|
||||
//Find a free slot
|
||||
cam = new camera(buf, sig);
|
||||
cid = camid(Cameras.size(), sig);
|
||||
Cameras.push_back(cam);
|
||||
for(uint i = 0; i < Cameras.size(); i++)
|
||||
{
|
||||
if(Cameras[i] == NULL)
|
||||
{
|
||||
cam = new camera(buf, sig);
|
||||
cid = camid(i, sig);
|
||||
Cameras[i] = cam;
|
||||
break;
|
||||
}
|
||||
else if(Cameras[i]->is_empty())
|
||||
{
|
||||
delete Cameras[i];
|
||||
cam = new camera(buf, sig);
|
||||
cid = camid(i, sig);
|
||||
Cameras[i] = cam;
|
||||
}
|
||||
}
|
||||
if(cam == NULL)
|
||||
{
|
||||
cam = new camera(buf, sig);
|
||||
cid = camid(Cameras.size(), sig);
|
||||
Cameras.push_back(cam);
|
||||
}
|
||||
|
||||
//Set attributes
|
||||
if(n_pos != NULL)
|
||||
@@ -876,7 +1029,7 @@ void cam_delete(camid cid)
|
||||
|
||||
void cam_do_frame(float frametime)
|
||||
{
|
||||
size_t i,size=Cameras.size();
|
||||
unsigned int i,size=Cameras.size();
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if(Cameras[i] != NULL)
|
||||
@@ -886,7 +1039,7 @@ void cam_do_frame(float frametime)
|
||||
|
||||
camid cam_get_camera(uint idx)
|
||||
{
|
||||
if(idx >= Cameras.size())
|
||||
if(idx < 0 || idx >= Cameras.size())
|
||||
return camid();
|
||||
|
||||
return camid(idx, Cameras[idx]->get_signature());
|
||||
@@ -902,12 +1055,10 @@ uint cam_get_num()
|
||||
return Cameras.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up camera by name, returns -1 on failure
|
||||
*/
|
||||
//Looks up camera by name, returns -1 on failure
|
||||
camid cam_lookup(char *name)
|
||||
{
|
||||
size_t i, size=Cameras.size();
|
||||
unsigned int i,size=Cameras.size();
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if(Cameras[i] != NULL && !stricmp(Cameras[i]->get_name(), name))
|
||||
@@ -947,6 +1098,35 @@ void cam_reset_camera()
|
||||
Camera_hud_draw_saved = false;
|
||||
}
|
||||
|
||||
//Functions must delete the original camera after calling this function.
|
||||
//Note that due to the esoteric nature of this function, it should not
|
||||
//be used outside camera.cpp
|
||||
/*
|
||||
static avd_camera *cam_upgrade_to_avd(camera *cam)
|
||||
{
|
||||
for(uint i = 0; i < Cameras.size(); i++)
|
||||
{
|
||||
if(Cameras[i] == cam)
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == Cameras.size())
|
||||
return NULL;
|
||||
|
||||
avd_camera *avdcam = new avd_camera(cam);
|
||||
|
||||
//Make the switch
|
||||
Cameras[i] = avdcam;
|
||||
|
||||
return avdcam;
|
||||
}
|
||||
*/
|
||||
|
||||
void subtitles_init()
|
||||
{
|
||||
//Do nothing!!
|
||||
}
|
||||
|
||||
void subtitles_close()
|
||||
{
|
||||
Subtitles.clear();
|
||||
@@ -954,20 +1134,20 @@ void subtitles_close()
|
||||
|
||||
void subtitles_do_frame(float frametime)
|
||||
{
|
||||
SCP_vector<subtitle>::iterator sub;
|
||||
for(sub = Subtitles.begin(); sub != Subtitles.end(); ++sub)
|
||||
unsigned int i,size=Subtitles.size();
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if ( !sub->is_post_shaded( ) )
|
||||
sub->do_frame(frametime);
|
||||
if ( !Subtitles[i].is_post_shaded( ) )
|
||||
Subtitles[i].do_frame(frametime);
|
||||
}
|
||||
}
|
||||
|
||||
void subtitles_do_frame_post_shaded(float frametime)
|
||||
{
|
||||
SCP_vector<subtitle>::iterator sub;
|
||||
for(sub = Subtitles.begin(); sub != Subtitles.end(); ++sub)
|
||||
unsigned int i,size=Subtitles.size();
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if ( sub->is_post_shaded( ) )
|
||||
sub->do_frame(frametime);
|
||||
if ( Subtitles[i].is_post_shaded( ) )
|
||||
Subtitles[i].do_frame(frametime);
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -33,9 +33,17 @@ protected:
|
||||
void (*func_custom_orientation)(camera *cam, matrix *ori);
|
||||
|
||||
avd_movement fov;
|
||||
|
||||
avd_movement pos_x;
|
||||
avd_movement pos_y;
|
||||
avd_movement pos_z;
|
||||
|
||||
//avd_movement ori_p;
|
||||
//avd_movement ori_b;
|
||||
//avd_movement ori_h;
|
||||
//avd_movement ori_progress;
|
||||
//matrix ori_initial;
|
||||
//matrix ori_final;
|
||||
avd_movement ori[9];
|
||||
|
||||
//Cache stuff
|
||||
@@ -116,7 +124,7 @@ class subtitle
|
||||
private:
|
||||
void clone(const subtitle &sub);
|
||||
|
||||
SCP_vector<SCP_string> text_lines;
|
||||
SCP_vector<std::string> text_lines;
|
||||
struct { int x; int y; } text_pos;
|
||||
|
||||
float display_time;
|
||||
@@ -168,6 +176,7 @@ camid cam_get_camera(uint index);
|
||||
camid cam_get_current();
|
||||
uint cam_get_num();
|
||||
|
||||
void subtitles_init();
|
||||
void subtitles_close();
|
||||
void subtitles_do_frame(float frametime);
|
||||
void subtitles_do_frame_post_shaded(float frametime);
|
||||
|
||||
+63
-53
@@ -52,7 +52,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_INVALID, NULL, NULL, CF_TYPE_INVALID },
|
||||
// Root must be index 1!!
|
||||
{ CF_TYPE_ROOT, "", ".mve .ogg", CF_TYPE_ROOT },
|
||||
{ CF_TYPE_DATA, "data", ".cfg .txt", CF_TYPE_ROOT },
|
||||
{ CF_TYPE_DATA, "data", ".cfg .log .txt", CF_TYPE_ROOT },
|
||||
{ CF_TYPE_MAPS, "data" DIR_SEPARATOR_STR "maps", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_TEXT, "data" DIR_SEPARATOR_STR "text", ".txt .net", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MODELS, "data" DIR_SEPARATOR_STR "models", ".pof", CF_TYPE_DATA },
|
||||
@@ -78,7 +78,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
|
||||
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .ibx .tsb", CF_TYPE_DATA }, //clr=cached color
|
||||
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .dds .fs2 .txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
|
||||
{ CF_TYPE_CONFIG, "data" DIR_SEPARATOR_STR "config", ".cfg", CF_TYPE_DATA },
|
||||
@@ -147,14 +147,9 @@ int cfile_in_root_dir(char *exe_path)
|
||||
token_count++;
|
||||
tok = strtok(NULL, DIR_SEPARATOR_STR);
|
||||
} while(tok != NULL);
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
// /freespace works, / does not
|
||||
if(token_count <= 1) {
|
||||
#else
|
||||
// C:/freespace works, C:/ does not
|
||||
|
||||
// root directory if we have <= 1 slash
|
||||
if(token_count <= 2){
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -818,6 +813,53 @@ CFILE *cfopen_special(char *file_path, char *mode, const int size, const int off
|
||||
// it's a normal file
|
||||
return cf_open_fill_cfblock(fp, dir_type);
|
||||
}
|
||||
|
||||
/* char longname[_MAX_PATH];
|
||||
|
||||
if ( !cfile_inited ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Check that all the parameters make sense
|
||||
Assert( file_path && strlen(file_path) );
|
||||
Assert( mode != NULL );
|
||||
|
||||
if ( (ext_num <= 0) || (!ext_list) ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// cfopen_ext() only supports reading files, not creating them
|
||||
if ( strchr(mode, 'w') ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Search for file on disk, on cdrom, or in a packfile
|
||||
|
||||
int offset, size;
|
||||
char copy_file_path[MAX_PATH_LEN]; // FIX change in memory from cf_find_file_location
|
||||
strcpy_s(copy_file_path, file_path);
|
||||
|
||||
if ( cf_find_file_location_ext(copy_file_path, ext_num, ext_list, dir_type, sizeof(longname) - 1, longname, &size, &offset, localize) ) {
|
||||
// Fount it, now create a cfile out of it
|
||||
FILE *fp = fopen( longname, "rb" );
|
||||
|
||||
if ( fp ) {
|
||||
if ( offset ) {
|
||||
// Found it in a pack file
|
||||
return cf_open_packed_cfblock(fp, dir_type, offset, size );
|
||||
} else {
|
||||
// Found it in a normal file
|
||||
return cf_open_fill_cfblock(fp, dir_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;*/
|
||||
}
|
||||
|
||||
|
||||
@@ -961,7 +1003,6 @@ CFILE *cf_open_fill_cfblock(FILE *fp, int type)
|
||||
cfbp->data = NULL;
|
||||
cfbp->fp = fp;
|
||||
cfbp->dir_type = type;
|
||||
cfbp->max_read_len = 0;
|
||||
|
||||
int pos = ftell(fp);
|
||||
if(pos == -1L)
|
||||
@@ -999,7 +1040,6 @@ CFILE *cf_open_packed_cfblock(FILE *fp, int type, int offset, int size)
|
||||
cfbp->data = NULL;
|
||||
cfbp->fp = fp;
|
||||
cfbp->dir_type = type;
|
||||
cfbp->max_read_len = 0;
|
||||
|
||||
cf_init_lowlevel_read_code(cfp,offset, size, 0 );
|
||||
|
||||
@@ -1037,8 +1077,6 @@ CFILE *cf_open_mapped_fill_cfblock(FILE *fp, int type)
|
||||
|
||||
cfp = &Cfile_list[cfile_block_index];
|
||||
cfp->id = cfile_block_index;
|
||||
cfp->version = 0;
|
||||
cfbp->max_read_len = 0;
|
||||
cfbp->fp = NULL;
|
||||
#if defined _WIN32
|
||||
cfbp->hInFile = hFile;
|
||||
@@ -1102,22 +1140,6 @@ void cf_set_version( CFILE * cfile, int version )
|
||||
cfile->version = version;
|
||||
}
|
||||
|
||||
// cutoff point where cfread() will throw an error when it hits this limit
|
||||
// if 'len' is 0 then this check will be disabled
|
||||
void cf_set_max_read_len( CFILE * cfile, size_t len )
|
||||
{
|
||||
Assert( cfile != NULL );
|
||||
Assert( (cfile->id >= 0) && (cfile->id < MAX_CFILE_BLOCKS) );
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
if (len) {
|
||||
cb->max_read_len = cb->raw_position + len;
|
||||
} else {
|
||||
cb->max_read_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// routines to read basic data types from CFILE's. Put here to
|
||||
// simplify mac/pc reading from cfiles.
|
||||
|
||||
@@ -1266,7 +1288,7 @@ void cfread_string_len(char *buf,int n, CFILE *file)
|
||||
{
|
||||
int len;
|
||||
len = cfread_int(file);
|
||||
Assertion( (len < n), "len: %i, n: %i", len, n );
|
||||
Assert( len < n );
|
||||
if (len)
|
||||
cfread(buf, len, 1, file);
|
||||
|
||||
@@ -1349,7 +1371,7 @@ int cfwrite_string(char *buf, CFILE *file)
|
||||
return cfwrite_char(0, file); // write out NULL termination
|
||||
}
|
||||
|
||||
int cfwrite_string_len(const char *buf, CFILE *file)
|
||||
int cfwrite_string_len(char *buf, CFILE *file)
|
||||
{
|
||||
int len = strlen(buf);
|
||||
|
||||
@@ -1385,7 +1407,7 @@ int cfilelength( CFILE * cfile )
|
||||
// returns: number of full elements actually written
|
||||
//
|
||||
//
|
||||
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
int cfwrite(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
{
|
||||
if(!cf_is_valid(cfile))
|
||||
return 0;
|
||||
@@ -1407,22 +1429,18 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
size_t bytes_written = 0;
|
||||
size_t size = elsize * nelem;
|
||||
int result = 0;
|
||||
|
||||
bytes_written = fwrite(buf, 1, size, cb->fp);
|
||||
result = fwrite(buf, elsize, nelem, cb->fp);
|
||||
|
||||
//WMC - update filesize and position
|
||||
if (bytes_written > 0) {
|
||||
cb->size += bytes_written;
|
||||
cb->raw_position += bytes_written;
|
||||
if(result > 0)
|
||||
{
|
||||
cb->size = filelength(fileno(cb->fp));
|
||||
cb->raw_position += result;
|
||||
}
|
||||
|
||||
#if defined(CHECK_SIZE) && !defined(NDEBUG)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
#endif
|
||||
|
||||
return ((int)bytes_written / elsize);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1458,14 +1476,10 @@ int cfputc(int c, CFILE *cfile)
|
||||
//WMC - update filesize and position
|
||||
if(result != EOF)
|
||||
{
|
||||
cb->size += 1;
|
||||
cb->size = filelength(fileno(cb->fp));
|
||||
cb->raw_position += 1;
|
||||
}
|
||||
|
||||
#if defined(CHECK_SIZE) && !defined(NDEBUG)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1502,14 +1516,10 @@ int cfputs(char *str, CFILE *cfile)
|
||||
//WMC - update filesize and position
|
||||
if(result != EOF)
|
||||
{
|
||||
cb->size += strlen(str);
|
||||
cb->size = filelength(fileno(cb->fp));
|
||||
cb->raw_position += strlen(str);
|
||||
}
|
||||
|
||||
#if defined(CHECK_SIZE) && !defined(NDEBUG)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+6
-72
@@ -16,9 +16,6 @@
|
||||
#include <time.h>
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
#define CF_EOF (-1)
|
||||
|
||||
#define CF_SEEK_SET (0)
|
||||
@@ -101,11 +98,6 @@ typedef struct {
|
||||
// to add file to list, or 0 to not add it.
|
||||
extern int (*Get_file_list_filter)(char *filename);
|
||||
|
||||
// extra check for child directory under CF_TYPE_*
|
||||
// NOTE: if specified cf_get_file_list() will not search pack files!
|
||||
// NOTE: specified string must not contain ':' or spaces or begin with DIR_SEPARATOR!
|
||||
extern const char *Get_file_list_child;
|
||||
|
||||
// cfile directory. valid after cfile_init() returns successfully
|
||||
#define CFILE_ROOT_DIRECTORY_LEN 256
|
||||
extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
@@ -143,11 +135,6 @@ int cflush(CFILE *cfile);
|
||||
// open a file. Once set, you can use minimum version numbers with the read functions.
|
||||
void cf_set_version( CFILE * cfile, int version );
|
||||
|
||||
// will throw an error if cfread*() functions read past this mark
|
||||
// converted to raw offsets when used, but gets passed actual length from current position
|
||||
// setting 'len' to zero will disable the check
|
||||
void cf_set_max_read_len(CFILE *cfile, size_t len);
|
||||
|
||||
// Deletes a file. Returns 0 on error, 1 if successful
|
||||
int cf_delete(char *filename, int dir_type);
|
||||
|
||||
@@ -181,7 +168,7 @@ int cfilelength(CFILE *fp);
|
||||
int cfread(void *buf, int elsize, int nelem, CFILE *fp);
|
||||
|
||||
// cfwrite() writes to the file
|
||||
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
int cfwrite(void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
|
||||
// Reads/writes RLE compressed data.
|
||||
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
@@ -271,15 +258,8 @@ void cfread_angles(angles *ang, CFILE *file, int ver = 0, angles *deflt = NULL);
|
||||
// Reads variable length, null-termined string. Will only read up
|
||||
// to n characters.
|
||||
void cfread_string(char *buf,int n, CFILE *file);
|
||||
/**
|
||||
* @brief Read a fixed length string that is not null-terminated, with the length stored in file
|
||||
*
|
||||
* @param buf Pre-allocated array to store string
|
||||
* @param n Size of pre-allocated array
|
||||
* @param file File to read from
|
||||
*
|
||||
* @note Appends NULL character to string (buf)
|
||||
*/
|
||||
// Read a fixed length that is null-terminatedm, and has the length
|
||||
// stored in file
|
||||
void cfread_string_len(char *buf,int n, CFILE *file);
|
||||
|
||||
// functions for writing cfiles
|
||||
@@ -296,19 +276,13 @@ int cfwrite_angles(angles *ang, CFILE *file);
|
||||
// writes variable length, null-termined string.
|
||||
int cfwrite_string(char *buf, CFILE *file);
|
||||
|
||||
/**
|
||||
* @brief Write a fixed length string (not including its null terminator), with the length stored in file
|
||||
*
|
||||
* @param buf String to write to file
|
||||
* @param file File to write to
|
||||
*/
|
||||
int cfwrite_string_len(const char *buf, CFILE *file);
|
||||
// write a fixed length that is null-terminatedm, and has the length
|
||||
// stored in file
|
||||
int cfwrite_string_len(char *buf, CFILE *file);
|
||||
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort = CF_SORT_NONE, SCP_vector<file_list_info> *info = NULL );
|
||||
int cf_get_file_list( int max, char **list, int type, char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int type, char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( int n, char **list, int sort, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info = NULL );
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files.
|
||||
@@ -348,45 +322,5 @@ int cfile_push_chdir(int type);
|
||||
// restore directory on top of the stack
|
||||
int cfile_pop_dir();
|
||||
|
||||
namespace cfile
|
||||
{
|
||||
// exceptions and other errors
|
||||
class cfile_error : public std::exception
|
||||
{
|
||||
public:
|
||||
cfile_error() : m_excuse("CFILE Exception")
|
||||
{
|
||||
}
|
||||
|
||||
cfile_error(const std::string &excuse) : m_excuse(excuse)
|
||||
{
|
||||
}
|
||||
|
||||
~cfile_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return m_excuse.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_excuse;
|
||||
};
|
||||
|
||||
class max_read_length : public cfile_error
|
||||
{
|
||||
public:
|
||||
max_read_length(const std::string &excuse) : cfile_error(excuse)
|
||||
{
|
||||
}
|
||||
|
||||
max_read_length() : cfile_error("Attempted to read beyond length limit")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif /* __CFILE_H__ */
|
||||
@@ -26,8 +26,6 @@
|
||||
#include "cfile/cfilearchive.h"
|
||||
#include "luaconf.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#define CHECK_POSITION
|
||||
|
||||
@@ -207,15 +205,6 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
//mprintf(( "CFILE: EOF encountered in file\n" ));
|
||||
}
|
||||
|
||||
if (cb->max_read_len) {
|
||||
if ( (size_t)(cb->raw_position+size) > cb->max_read_len ) {
|
||||
std::ostringstream s_buf;
|
||||
s_buf << "Attempted to read " << size << "-byte(s) beyond length limit";
|
||||
|
||||
throw cfile::max_read_length(s_buf.str());
|
||||
}
|
||||
}
|
||||
|
||||
int bytes_read = fread( buf, 1, size, cb->fp );
|
||||
if ( bytes_read > 0 ) {
|
||||
cb->raw_position += bytes_read;
|
||||
|
||||
@@ -37,8 +37,7 @@ typedef struct Cfile_block {
|
||||
int lib_offset;
|
||||
int raw_position;
|
||||
int size; // for packed files
|
||||
|
||||
size_t max_read_len; // max read offset, for special error handling
|
||||
|
||||
} Cfile_block;
|
||||
|
||||
#define MAX_CFILE_BLOCKS 64
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
@@ -26,84 +24,7 @@
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info )
|
||||
{
|
||||
// NOTE: This really needs to be updated to C++ style sorting at some point
|
||||
|
||||
int i, j, incr;
|
||||
SCP_string t;
|
||||
file_list_info tt;
|
||||
|
||||
int n = (int)list.size();
|
||||
|
||||
if (sort == CF_SORT_NAME) {
|
||||
incr = n / 2;
|
||||
while (incr > 0) {
|
||||
for (i=incr; i<n; i++) {
|
||||
j = i - incr;
|
||||
while (j >= 0) {
|
||||
if (stricmp(list[j].c_str(), list[j + incr].c_str()) > 0) {
|
||||
t = list[j];
|
||||
list[j] = list[j + incr];
|
||||
list[j + incr] = t;
|
||||
|
||||
if (info) {
|
||||
tt = (*info)[j];
|
||||
(*info)[j] = (*info)[j + incr];
|
||||
(*info)[j + incr] = tt;
|
||||
}
|
||||
|
||||
j -= incr;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
incr /= 2;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (sort == CF_SORT_TIME) {
|
||||
Assert(info);
|
||||
incr = n / 2;
|
||||
while (incr > 0) {
|
||||
for (i=incr; i<n; i++) {
|
||||
j = i - incr;
|
||||
while (j >= 0) {
|
||||
if ( (*info)[j].write_time < (*info)[j + incr].write_time ) {
|
||||
t = list[j];
|
||||
list[j] = list[j + incr];
|
||||
list[j + incr] = t;
|
||||
|
||||
tt = (*info)[j];
|
||||
(*info)[j] = (*info)[j + incr];
|
||||
(*info)[j + incr] = tt;
|
||||
j -= incr;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
incr /= 2;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (sort == CF_SORT_REVERSE) {
|
||||
std::reverse( list.begin(), list.end() );
|
||||
|
||||
if (info) {
|
||||
std::reverse( info->begin(), info->end() );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nprintf(("Error", "Unknown sorting method %d passed to cf_sort_filenames()\n", sort));
|
||||
}
|
||||
|
||||
// Sorts a list of filenames using the specified sorting method (CF_SORT_*).
|
||||
// n = number of filenames in list to sort
|
||||
|
||||
+71
-364
@@ -15,7 +15,6 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
@@ -86,14 +85,14 @@ typedef struct cf_file {
|
||||
int pack_offset; // For pack files, where it is at. 0 if not in a pack file. This can be used to tell if in a pack file.
|
||||
} cf_file;
|
||||
|
||||
#define CF_NUM_FILES_PER_BLOCK 512
|
||||
#define CF_MAX_FILE_BLOCKS 128 // Can store 512*128 = 65536 files
|
||||
#define CF_NUM_FILES_PER_BLOCK 256
|
||||
#define CF_MAX_FILE_BLOCKS 128 // Can store 256*128 = 32768 files
|
||||
|
||||
typedef struct cf_file_block {
|
||||
cf_file files[CF_NUM_FILES_PER_BLOCK];
|
||||
} cf_file_block;
|
||||
|
||||
static uint Num_files = 0;
|
||||
static int Num_files = 0;
|
||||
static cf_file_block *File_blocks[CF_MAX_FILE_BLOCKS];
|
||||
|
||||
|
||||
@@ -109,10 +108,8 @@ cf_file *cf_get_file(int index)
|
||||
// Create a new file and return a pointer to it.
|
||||
cf_file *cf_create_file()
|
||||
{
|
||||
Assertion(Num_files < CF_NUM_FILES_PER_BLOCK * CF_MAX_FILE_BLOCKS, "Too many files found. CFile cannot handle more than %d files.\n", CF_NUM_FILES_PER_BLOCK * CF_MAX_FILE_BLOCKS);
|
||||
|
||||
uint block = Num_files / CF_NUM_FILES_PER_BLOCK;
|
||||
uint offset = Num_files % CF_NUM_FILES_PER_BLOCK;
|
||||
int block = Num_files / CF_NUM_FILES_PER_BLOCK;
|
||||
int offset = Num_files % CF_NUM_FILES_PER_BLOCK;
|
||||
|
||||
if ( File_blocks[block] == NULL ) {
|
||||
File_blocks[block] = (cf_file_block *)vm_malloc( sizeof(cf_file_block) );
|
||||
@@ -373,7 +370,6 @@ void cf_build_root_list(char *cdrom_dir)
|
||||
|
||||
cf_root *root;
|
||||
char str_temp[CF_MAX_PATHNAME_LENGTH], *cur_pos;
|
||||
int path_len;
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
// =========================================================================
|
||||
@@ -430,7 +426,8 @@ void cf_build_root_list(char *cdrom_dir)
|
||||
|
||||
if(Cmdline_mod) {
|
||||
// stackable Mod support -- Kazan
|
||||
for (cur_pos=Cmdline_mod; *cur_pos != '\0'; cur_pos+= (strlen(cur_pos)+1))
|
||||
//This for statement is a work of art :D
|
||||
for (cur_pos=Cmdline_mod; strlen(cur_pos) != 0; cur_pos+= (strlen(cur_pos)+1))
|
||||
{
|
||||
memset(str_temp, 0, CF_MAX_PATHNAME_LENGTH);
|
||||
strncpy(str_temp, cur_pos, CF_MAX_PATHNAME_LENGTH-1);
|
||||
@@ -447,15 +444,12 @@ void cf_build_root_list(char *cdrom_dir)
|
||||
Int3();
|
||||
}
|
||||
|
||||
path_len = strlen(root->path);
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
if ( (strlen(root->path) < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
path_len++;
|
||||
}
|
||||
|
||||
strncat(root->path, str_temp, (CF_MAX_PATHNAME_LENGTH - path_len - 1));
|
||||
strncat(root->path, str_temp, (CF_MAX_PATHNAME_LENGTH - strlen(root->path) - 1));
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
cf_build_pack_list(root);
|
||||
}
|
||||
@@ -467,10 +461,8 @@ void cf_build_root_list(char *cdrom_dir)
|
||||
Error(LOCATION, "Can't get current working directory -- %d", errno );
|
||||
}
|
||||
|
||||
path_len = strlen(root->path);
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
if ( (strlen(root->path) < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
}
|
||||
|
||||
@@ -672,9 +664,9 @@ void cf_search_root_pack(int root_index)
|
||||
Assert( sizeof(VP_header) == 16 );
|
||||
fread(&VP_header, 1, sizeof(VP_header), fp);
|
||||
|
||||
VP_header.version = INTEL_INT( VP_header.version ); //-V570
|
||||
VP_header.index_offset = INTEL_INT( VP_header.index_offset ); //-V570
|
||||
VP_header.num_files = INTEL_INT( VP_header.num_files ); //-V570
|
||||
VP_header.version = INTEL_INT( VP_header.version );
|
||||
VP_header.index_offset = INTEL_INT( VP_header.index_offset );
|
||||
VP_header.num_files = INTEL_INT( VP_header.num_files );
|
||||
|
||||
mprintf(( "Searching root pack '%s' ... ", root->path ));
|
||||
|
||||
@@ -692,21 +684,21 @@ void cf_search_root_pack(int root_index)
|
||||
|
||||
fread( &find, sizeof(VP_FILE), 1, fp );
|
||||
|
||||
find.offset = INTEL_INT( find.offset ); //-V570
|
||||
find.size = INTEL_INT( find.size ); //-V570
|
||||
find.write_time = INTEL_INT( find.write_time ); //-V570
|
||||
find.offset = INTEL_INT( find.offset );
|
||||
find.size = INTEL_INT( find.size );
|
||||
find.write_time = INTEL_INT( find.write_time );
|
||||
|
||||
if ( find.size == 0 ) {
|
||||
int search_path_len = strlen(search_path);
|
||||
if ( !stricmp( find.filename, ".." )) {
|
||||
char *p = &search_path[search_path_len-1];
|
||||
int l = strlen(search_path);
|
||||
char *p = &search_path[l-1];
|
||||
while( (p > search_path) && (*p != DIR_SEPARATOR_CHAR) ) {
|
||||
p--;
|
||||
}
|
||||
*p = 0;
|
||||
} else {
|
||||
if ( search_path_len && (search_path[search_path_len-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s( search_path, DIR_SEPARATOR_STR );
|
||||
if ( strlen(search_path) && (search_path[strlen(search_path)-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s( search_path, DIR_SEPARATOR_STR );
|
||||
}
|
||||
strcat_s( search_path, find.filename );
|
||||
}
|
||||
@@ -829,7 +821,7 @@ void cf_free_secondary_filelist()
|
||||
// Returns: If not found returns 0.
|
||||
int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize )
|
||||
{
|
||||
uint i;
|
||||
int i;
|
||||
int cfs_slow_search = 0;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
@@ -838,7 +830,7 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
_finddata_t findstruct;
|
||||
#endif
|
||||
|
||||
Assert( (filespec != NULL) && (strlen(filespec) > 0) ); //-V805
|
||||
Assert( (filespec != NULL) && (strlen(filespec) > 0) );
|
||||
Assert( (pack_filename == NULL) || (max_out > 1) );
|
||||
|
||||
// see if we have something other than just a filename
|
||||
@@ -868,13 +860,13 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
}
|
||||
|
||||
// Search the hard drive for files first.
|
||||
uint num_search_dirs = 0;
|
||||
int num_search_dirs = 0;
|
||||
int search_order[CF_MAX_PATH_TYPES];
|
||||
|
||||
if ( CF_TYPE_SPECIFIED(pathtype) ) {
|
||||
search_order[num_search_dirs++] = pathtype;
|
||||
} else {
|
||||
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
|
||||
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
|
||||
if (i != pathtype)
|
||||
search_order[num_search_dirs++] = i;
|
||||
}
|
||||
@@ -906,21 +898,23 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
|
||||
|
||||
#if defined _WIN32
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
if (!Cmdline_safeloading) {
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
|
||||
_findclose(findhandle);
|
||||
_findclose(findhandle);
|
||||
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
if (pack_filename)
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
if (pack_filename)
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
FILE *fp = fopen(longname, "rb" );
|
||||
@@ -1034,8 +1028,7 @@ extern char *stristr(const char *str, const char *substr);
|
||||
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
|
||||
int cf_find_file_location_ext( char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize )
|
||||
{
|
||||
uint i;
|
||||
int cur_ext;
|
||||
int i, cur_ext;
|
||||
int cfs_slow_search = 0;
|
||||
char longname[MAX_PATH_LEN];
|
||||
char filespec[MAX_FILENAME_LEN];
|
||||
@@ -1063,13 +1056,13 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
|
||||
}
|
||||
|
||||
// Search the hard drive for files first.
|
||||
uint num_search_dirs = 0;
|
||||
int num_search_dirs = 0;
|
||||
int search_order[CF_MAX_PATH_TYPES];
|
||||
|
||||
if ( CF_TYPE_SPECIFIED(pathtype) ) {
|
||||
search_order[num_search_dirs++] = pathtype;
|
||||
} else {
|
||||
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
|
||||
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
|
||||
search_order[num_search_dirs++] = i;
|
||||
}
|
||||
|
||||
@@ -1116,21 +1109,23 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
|
||||
|
||||
#if defined _WIN32
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
if (!Cmdline_safeloading) {
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
|
||||
_findclose(findhandle);
|
||||
_findclose(findhandle);
|
||||
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
if (pack_filename)
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
if (pack_filename)
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
|
||||
return cur_ext;
|
||||
}
|
||||
return cur_ext;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
FILE *fp = fopen(longname, "rb" );
|
||||
@@ -1173,7 +1168,7 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
|
||||
int last_root_index = -1;
|
||||
int last_path_index = -1;
|
||||
|
||||
file_list_index.reserve( MIN(ext_num * 4, (int)Num_files) );
|
||||
file_list_index.reserve( MIN(ext_num * 4, Num_files) );
|
||||
|
||||
// next, run though and pick out base matches
|
||||
for (i = 0; i < Num_files; i++) {
|
||||
@@ -1219,10 +1214,17 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
|
||||
file_list_index.push_back( f );
|
||||
}
|
||||
|
||||
int file_list_size = (int)file_list_index.size();
|
||||
|
||||
// quick exit test
|
||||
if (file_list_size < 1)
|
||||
goto Bail;
|
||||
|
||||
|
||||
// now try and find our preferred match
|
||||
for (cur_ext = 0; cur_ext < ext_num; cur_ext++) {
|
||||
for (SCP_vector<cf_file*>::iterator fli = file_list_index.begin(); fli != file_list_index.end(); ++fli) {
|
||||
cf_file *f = *fli;
|
||||
for (i = 0; i < file_list_size; i++) {
|
||||
cf_file *f = file_list_index[i];
|
||||
|
||||
strcat_s( filespec, ext_list[cur_ext] );
|
||||
|
||||
@@ -1301,6 +1303,10 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
|
||||
}
|
||||
}
|
||||
|
||||
Bail:
|
||||
// didn't find anything, bail...
|
||||
file_list_index.clear();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1342,245 +1348,8 @@ int cf_matches_spec(char *filespec, char *filename)
|
||||
}
|
||||
|
||||
int (*Get_file_list_filter)(char *filename) = NULL;
|
||||
const char *Get_file_list_child = NULL;
|
||||
int Skip_packfile_search = 0;
|
||||
|
||||
static bool verify_file_list_child()
|
||||
{
|
||||
if (Get_file_list_child == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// empty or too long
|
||||
size_t len = strlen(Get_file_list_child);
|
||||
if ( !len || (len > MAX_FILENAME_LEN) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// can not being with directory separator
|
||||
if (Get_file_list_child[0] == DIR_SEPARATOR_CHAR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no ':' or spaces
|
||||
if ( strchr(Get_file_list_child, ':') || strchr(Get_file_list_child, ' ') ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cf_file_already_in_list( SCP_vector<SCP_string> &list, char *filename )
|
||||
{
|
||||
char name_no_extension[MAX_PATH_LEN];
|
||||
size_t i, size = list.size();
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy_s(name_no_extension, filename );
|
||||
char *p = strrchr( name_no_extension, '.' );
|
||||
if ( p ) *p = 0;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if ( !stricmp(list[i].c_str(), name_no_extension ) ) {
|
||||
// Match found!
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
// An alternative cf_get_file_list*(), true dynamic list version.
|
||||
// This one has a 'type', which is a CF_TYPE_* value. Because this specifies the directory
|
||||
// location, 'filter' only needs to be the filter itself, with no path information.
|
||||
// See above descriptions of cf_get_file_list() for more information about how it all works.
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort, SCP_vector<file_list_info> *info )
|
||||
{
|
||||
char *ptr;
|
||||
uint i;
|
||||
int l, own_flag = 0;
|
||||
SCP_vector<file_list_info> my_info;
|
||||
file_list_info tinfo;
|
||||
|
||||
if ( !info && (sort == CF_SORT_TIME) ) {
|
||||
info = &my_info;
|
||||
own_flag = 1;
|
||||
}
|
||||
|
||||
char filespec[MAX_PATH_LEN];
|
||||
|
||||
bool check_duplicates = !list.empty();
|
||||
|
||||
if ( check_duplicates && (sort != CF_SORT_NONE) ) {
|
||||
Int3();
|
||||
sort = CF_SORT_NONE;
|
||||
}
|
||||
|
||||
if (Get_file_list_child && !verify_file_list_child() ) {
|
||||
Get_file_list_child = NULL;
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, (char*)Get_file_list_child );
|
||||
strcat_s(filespec, DIR_SEPARATOR_STR);
|
||||
strcat_s(filespec, filter);
|
||||
|
||||
_finddata_t find;
|
||||
int find_handle;
|
||||
|
||||
find_handle = _findfirst( filespec, &find );
|
||||
if (find_handle != -1) {
|
||||
do {
|
||||
if (strcmp(strstr(filter, "."), strstr(find.name,".")) != 0)
|
||||
continue;
|
||||
|
||||
if ( strlen(find.name) >= MAX_FILENAME_LEN )
|
||||
continue;
|
||||
|
||||
if (!(find.attrib & _A_SUBDIR)) {
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(find.name) ) {
|
||||
if ( check_duplicates && cf_file_already_in_list(list, find.name) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr = strrchr(find.name, '.');
|
||||
if (ptr)
|
||||
l = ptr - find.name;
|
||||
else
|
||||
l = strlen(find.name);
|
||||
|
||||
list.push_back( SCP_string(find.name, l) );
|
||||
|
||||
if (info) {
|
||||
tinfo.write_time = find.time_write;
|
||||
info->push_back( tinfo );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (!_findnext(find_handle, &find));
|
||||
|
||||
_findclose( find_handle );
|
||||
}
|
||||
|
||||
#elif defined SCP_UNIX
|
||||
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, (char*)Get_file_list_child );
|
||||
|
||||
DIR *dirp;
|
||||
struct dirent *dir;
|
||||
|
||||
dirp = opendir (filespec);
|
||||
if ( dirp ) {
|
||||
while ((dir = readdir (dirp)) != NULL) {
|
||||
if ( strlen(dir->d_name) >= MAX_FILENAME_LEN ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fnmatch(filter, dir->d_name, 0) != 0)
|
||||
continue;
|
||||
|
||||
char fn[MAX_PATH];
|
||||
snprintf(fn, MAX_PATH-1, "%s/%s", filespec, dir->d_name);
|
||||
fn[MAX_PATH-1] = 0;
|
||||
|
||||
struct stat buf;
|
||||
if (stat(fn, &buf) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!S_ISREG(buf.st_mode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(dir->d_name) ) {
|
||||
if ( check_duplicates && cf_file_already_in_list(list, dir->d_name) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr = strrchr(dir->d_name, '.');
|
||||
if (ptr)
|
||||
l = ptr - dir->d_name;
|
||||
else
|
||||
l = strlen(dir->d_name);
|
||||
|
||||
list.push_back( SCP_string(dir->d_name, l) );
|
||||
|
||||
if (info) {
|
||||
tinfo.write_time = buf.st_mtime;
|
||||
info->push_back( tinfo );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool skip_packfiles = (Skip_packfile_search != 0);
|
||||
|
||||
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
|
||||
skip_packfiles = true;
|
||||
} else if (Get_file_list_child != NULL) {
|
||||
skip_packfiles = true;
|
||||
}
|
||||
|
||||
// Search all the packfiles and CD.
|
||||
if ( !skip_packfiles ) {
|
||||
for (i=0; i<Num_files; i++ ) {
|
||||
cf_file * f = cf_get_file(i);
|
||||
|
||||
// only search paths we're supposed to...
|
||||
if ( (pathtype != CF_TYPE_ANY) && (pathtype != f->pathtype_index) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !cf_matches_spec( filter,f->name_ext)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( cf_file_already_in_list(list, f->name_ext)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(f->name_ext) ) {
|
||||
//mprintf(( "Found '%s' in root %d path %d\n", f->name_ext, f->root_index, f->pathtype_index ));
|
||||
|
||||
ptr = strrchr(f->name_ext, '.');
|
||||
if (ptr)
|
||||
l = ptr - f->name_ext;
|
||||
else
|
||||
l = strlen(f->name_ext);
|
||||
|
||||
list.push_back( SCP_string(f->name_ext, l) );
|
||||
|
||||
if (info) {
|
||||
tinfo.write_time = f->write_time;
|
||||
info->push_back( tinfo );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (sort != CF_SORT_NONE) {
|
||||
cf_sort_filenames( list, sort, info );
|
||||
}
|
||||
|
||||
if (own_flag) {
|
||||
my_info.clear();
|
||||
}
|
||||
|
||||
Get_file_list_filter = NULL;
|
||||
Get_file_list_child = NULL;
|
||||
|
||||
return (int)list.size();
|
||||
}
|
||||
|
||||
int cf_file_already_in_list( int num_files, char **list, char *filename )
|
||||
{
|
||||
int i;
|
||||
@@ -1608,8 +1377,7 @@ int cf_file_already_in_list( int num_files, char **list, char *filename )
|
||||
int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort, file_list_info *info )
|
||||
{
|
||||
char *ptr;
|
||||
uint i;
|
||||
int l, num_files = 0, own_flag = 0;
|
||||
int i, l, num_files = 0, own_flag = 0;
|
||||
|
||||
if (max < 1) {
|
||||
Get_file_list_filter = NULL;
|
||||
@@ -1806,7 +1574,7 @@ int cf_file_already_in_list_preallocated( int num_files, char arr[][MAX_FILENAME
|
||||
// See above descriptions of cf_get_file_list() for more information about how it all works.
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int pathtype, char *filter, int sort, file_list_info *info )
|
||||
{
|
||||
int num_files = 0, own_flag = 0;
|
||||
int i, num_files = 0, own_flag = 0;
|
||||
|
||||
if (max < 1) {
|
||||
Get_file_list_filter = NULL;
|
||||
@@ -1815,7 +1583,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
}
|
||||
|
||||
if (list) {
|
||||
for (int i=0; i<max; i++) {
|
||||
for (i=0; i<max; i++) {
|
||||
list[i] = arr[i];
|
||||
}
|
||||
} else {
|
||||
@@ -1927,7 +1695,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
|
||||
// Search all the packfiles and CD.
|
||||
if ( !Skip_packfile_search ) {
|
||||
for (uint i=0; i<Num_files; i++ ) {
|
||||
for (i=0; i<Num_files; i++ ) {
|
||||
cf_file * f = cf_get_file(i);
|
||||
|
||||
// only search paths we're supposed to...
|
||||
@@ -2062,67 +1830,6 @@ int cf_create_default_path_string( char *path, uint path_max, int pathtype, char
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns the default storage path for files given a
|
||||
// particular pathtype. In other words, the path to
|
||||
// the unpacked, non-cd'd, stored on hard drive path.
|
||||
// If filename isn't null it will also tack the filename
|
||||
// on the end, creating a completely valid filename.
|
||||
// Input: pathtype - CF_TYPE_??
|
||||
// filename - optional, if set, tacks the filename onto end of path.
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if the result would be too long (invalid result)
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, char *filename, bool localize )
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
if ( filename && strpbrk(filename,"/") ) {
|
||||
#else
|
||||
if ( filename && strpbrk(filename,"/\\:") ) {
|
||||
#endif
|
||||
// Already has full path
|
||||
path.assign(filename);
|
||||
|
||||
} else {
|
||||
cf_root *root = cf_get_root(0);
|
||||
|
||||
if (!root) {
|
||||
Assert( filename != NULL );
|
||||
path.assign(filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Assert(CF_TYPE_SPECIFIED(pathtype));
|
||||
std::ostringstream s_path;
|
||||
|
||||
// force a specific directory to search for player files
|
||||
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
|
||||
s_path << Pilot_file_path;
|
||||
} else {
|
||||
s_path << root->path;
|
||||
}
|
||||
|
||||
s_path << Pathtypes[pathtype].path;
|
||||
|
||||
// Don't add slash for root directory
|
||||
if (Pathtypes[pathtype].path[0] != '\0') {
|
||||
if ( *(s_path.str().rbegin()) != DIR_SEPARATOR_CHAR ) {
|
||||
s_path << DIR_SEPARATOR_STR;
|
||||
}
|
||||
// if ( path[strlen(path)-1] != DIR_SEPARATOR_CHAR ) {
|
||||
// strcat_s(path, path_max, DIR_SEPARATOR_STR);
|
||||
// }
|
||||
}
|
||||
|
||||
// add filename
|
||||
if (filename) {
|
||||
s_path << filename;
|
||||
}
|
||||
|
||||
path = s_path.str().c_str();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cfile_spew_pack_file_crcs()
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -40,6 +40,6 @@ extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES];
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if result would be too long (invalid result)
|
||||
int cf_create_default_path_string( char *path, uint path_max, int pathtype, char *filename=NULL, bool localize = false);
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, char *filename=NULL, bool localize = false );
|
||||
|
||||
|
||||
#endif //_CFILESYSTEM_H
|
||||
@@ -140,7 +140,7 @@ void pack_file( char *filespec, char *filename, int filesize, _fs_time_t time_wr
|
||||
}
|
||||
|
||||
memset( path, 0, sizeof(path) );
|
||||
strcpy_s( path, filename );
|
||||
strcpy( path, filename );
|
||||
|
||||
fswrite_int( (int*)&Total_size, fp_out_hdr );
|
||||
fswrite_int( &filesize, fp_out_hdr );
|
||||
@@ -186,7 +186,7 @@ void add_directory( char * dirname)
|
||||
char *tmpptr;
|
||||
int i = 0;
|
||||
|
||||
strcpy_s(path, dirname);
|
||||
strcpy(path, dirname);
|
||||
|
||||
fswrite_int( (int*)&Total_size, fp_out_hdr);
|
||||
fswrite_int( &i, fp_out_hdr);
|
||||
@@ -217,7 +217,7 @@ void pack_directory( char * filespec)
|
||||
while ( (*ts == DIR_SEPARATOR_CHAR) && (ts > filespec) )
|
||||
*ts = '\0';
|
||||
|
||||
strcpy_s( tmp1, filespec );
|
||||
strcpy( tmp1, filespec );
|
||||
|
||||
add_directory(filespec);
|
||||
strcat( tmp1, DIR_SEPARATOR_STR"*.*" );
|
||||
@@ -229,7 +229,7 @@ void pack_directory( char * filespec)
|
||||
if( find_handle != -1 ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy_s( tmp, filespec );
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
pack_directory(tmp);
|
||||
@@ -241,7 +241,7 @@ void pack_directory( char * filespec)
|
||||
while( !_findnext( find_handle, &find ) ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy_s( tmp, filespec );
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
pack_directory(tmp);
|
||||
@@ -278,7 +278,7 @@ void pack_directory( char * filespec)
|
||||
}
|
||||
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
strcpy_s( tmp, filespec );
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "/" );
|
||||
strcat( tmp, dir->d_name );
|
||||
pack_directory(tmp);
|
||||
@@ -340,7 +340,7 @@ void print_instructions()
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redefine main() which is something
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redfine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
@@ -364,14 +364,14 @@ int main(int argc, char *argv[] )
|
||||
#endif
|
||||
}
|
||||
|
||||
strcpy_s( archive, argv[1] );
|
||||
strcpy( archive, argv[1] );
|
||||
p = strchr( archive, '.' );
|
||||
if (p) *p = 0; // remove extension
|
||||
|
||||
strcpy_s( archive_dat, archive );
|
||||
strcpy( archive_dat, archive );
|
||||
strcat( archive_dat, ".vp" );
|
||||
|
||||
strcpy_s( archive_hdr, archive );
|
||||
strcpy( archive_hdr, archive );
|
||||
strcat( archive_hdr, ".hdr" );
|
||||
|
||||
fp_out = fopen( archive_dat, "wb" );
|
||||
|
||||
@@ -97,7 +97,7 @@ typedef struct vp_fileinfo {
|
||||
~vp_fileinfo() {}
|
||||
} vp_fileinfo;
|
||||
|
||||
SCP_vector<vp_fileinfo> VP_FileInfo;
|
||||
std::vector<vp_fileinfo> VP_FileInfo;
|
||||
|
||||
// just like strlwr() but without actually including it here
|
||||
void lowercase(char *s)
|
||||
@@ -224,7 +224,7 @@ void read_index(int lc = 0)
|
||||
if (lc == 1)
|
||||
lowercase( vpinfo.file_name );
|
||||
|
||||
strcpy_s( vpinfo.file_path, path );
|
||||
strcpy( vpinfo.file_path, path );
|
||||
VP_FileInfo.push_back(vpinfo);
|
||||
}
|
||||
}
|
||||
@@ -261,7 +261,7 @@ void extract_all_files(char *file)
|
||||
|
||||
printf("Extracting: %s...\n", file);
|
||||
|
||||
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
|
||||
for (uint i = 0; i < VP_FileInfo.size(); i++) {
|
||||
// save the file path to a temp location and recursively make the needed directories
|
||||
if (have_outdir) {
|
||||
if ( (out_len + 1 + strlen(path)) > MAX_PATH-1 )
|
||||
@@ -311,7 +311,7 @@ void extract_all_files(char *file)
|
||||
|
||||
sprintf(path2, "%s%s%s", out_dir, DIR_SEPARATOR_STR, path);
|
||||
} else {
|
||||
strcpy_s(path2, path);
|
||||
strcpy(path2, path);
|
||||
}
|
||||
|
||||
fp_out = fopen(path2, "wb");
|
||||
@@ -365,7 +365,7 @@ void list_all_files(char *file)
|
||||
|
||||
printf(" Name Size Offset Date/Time Path\n");
|
||||
printf("-------------------------------------------------------------------------------\n");
|
||||
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
|
||||
for (uint i = 0; i < VP_FileInfo.size(); i++) {
|
||||
plat_time = VP_FileInfo[i].write_time; // gets rid of some platform strangeness this way
|
||||
strftime(out_time, 32, "%F %H:%M", localtime(&plat_time)); // YYYY-mm-dd HH:mm (ISO 8601 date format, 24-hr time)
|
||||
|
||||
@@ -422,7 +422,7 @@ void help()
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redefine main() which is something
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redfine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
|
||||
+108
-148
@@ -79,8 +79,6 @@ enum
|
||||
#define BUILD_CAP_NO_D3D (1<<1)
|
||||
#define BUILD_CAP_NEW_SND (1<<2)
|
||||
|
||||
#define PARSE_COMMAND_LINE_STRING "-parse_cmdline_only"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// DO NOT CHANGE THE SIZE OF THIS STRING!
|
||||
@@ -114,92 +112,86 @@ typedef struct
|
||||
Flag exe_params[] =
|
||||
{
|
||||
{ "-spec", "Enable specular", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
|
||||
{ "-glow", "Enable glow maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
|
||||
{ "-glow", "Enable glowmaps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
|
||||
{ "-env", "Enable environment maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
|
||||
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
|
||||
{ "-nomotiondebris", "Disable motion debris", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
|
||||
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
|
||||
{ "-missile_lighting", "Apply lighting to missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", },
|
||||
{ "-missile_lighting", "Apply Lighting to Missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", },
|
||||
{ "-normal", "Enable normal maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
|
||||
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
|
||||
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
|
||||
{ "-soft_particles", "Enable soft particles", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
|
||||
{ "-fxaa", "Enable FXAA anti-aliasing", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
|
||||
{ "-flightshaftsoff", "Force Lightshafts off", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
|
||||
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
|
||||
|
||||
{ "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", },
|
||||
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
|
||||
{ "-cache_bitmaps", "Cache bitmaps between missions", true, 0, EASY_DEFAULT_MEM, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-cache_bitmaps", },
|
||||
|
||||
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
|
||||
{ "-dualscanlines", "Another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
|
||||
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
|
||||
{ "-orbradar", "Enable 3D radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
|
||||
{ "-rearm_timer", "Enable rearm/repair completion timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
|
||||
{ "-ballistic_gauge", "Enable analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
|
||||
{ "-orbradar", "Enables 3d radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
|
||||
{ "-rearm_timer", "Enable Rearm/Repair Completion Timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
|
||||
{ "-ballistic_gauge", "Enable the analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
|
||||
|
||||
{ "-ship_choice_3d", "Use 3D models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
|
||||
{ "-weapon_choice_3d", "Use 3D models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
|
||||
{ "-3dwarp", "Enable 3D warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
|
||||
{ "-ship_choice_3d", "Use models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
|
||||
{ "-weapon_choice_3d", "Use models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
|
||||
{ "-3dwarp", "Enable 3d warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
|
||||
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
|
||||
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
|
||||
{ "-tbp", "Toggle features for The Babylon Project", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tbp", }, // TBP warp effects -Et1
|
||||
{ "-wcsaga", "Toggle features for Wing Commander Saga", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-wcsaga", },
|
||||
|
||||
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
|
||||
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
|
||||
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
|
||||
{ "-nosound", "Disable sound and music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
|
||||
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
|
||||
|
||||
{ "-standalone", "Run as standalone server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
|
||||
{ "-standalone", "Run as Stand Alone Server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
|
||||
{ "-startgame", "Skip mainhall and start hosting", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-startgame", },
|
||||
{ "-closed", "Start hosted server as closed", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-closed", },
|
||||
{ "-restricted", "Host confirms join requests", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-restricted", },
|
||||
{ "-multilog", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-multilog", },
|
||||
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
|
||||
{ "-mpnoreturn", "Disable flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
|
||||
{ "-mpnoreturn", "Disables flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
|
||||
|
||||
{ "-oldfire", "", false, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-oldfire", },
|
||||
{ "-nohtl", "Software mode (very slow)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nohtl", },
|
||||
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
||||
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
||||
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
|
||||
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
|
||||
{ "-query_speech", "Check if this build has speech", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
|
||||
{ "-novbo", "Disable OpenGL VBO", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-novbo", },
|
||||
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
|
||||
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
|
||||
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
|
||||
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_glsl", },
|
||||
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
|
||||
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
|
||||
{ "-disable_glsl_model","Don't use shaders for model rendering", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_glsl_model", },
|
||||
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
|
||||
#ifndef SCP_UNIX
|
||||
{ "-disable_di_mouse", "Don't use DirectInput for mouse control", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
#endif
|
||||
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-safeloading", "", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-safeloading", },
|
||||
{ "-query_speech", "Does this build have speech?", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
|
||||
{ "-d3d_bad_tsys", "Enable inefficient textures", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-d3d_bad_tsys", },
|
||||
{ "-novbo", "Disable OpenGL VBO", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-novbo", },
|
||||
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
|
||||
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
|
||||
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
|
||||
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
|
||||
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
|
||||
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, 0, EASY_DEFAULT, "Experimental", "", },
|
||||
{ "-ingame_join", "Allows ingame joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
{ "-voicer", "Voice recognition", true, 0, EASY_DEFAULT, "Experimental", "", },
|
||||
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
|
||||
|
||||
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
|
||||
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
|
||||
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
|
||||
#ifndef SCP_UNIX
|
||||
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
|
||||
#endif
|
||||
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-timerbar", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-timerbar", },
|
||||
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
|
||||
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
|
||||
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
|
||||
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
|
||||
{ "-pofspew", "", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
|
||||
{ "-tablecrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
|
||||
{ "-missioncrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
|
||||
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
|
||||
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
|
||||
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
|
||||
{ "-output_scripting", "Output scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
|
||||
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
|
||||
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
|
||||
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
|
||||
#ifdef SCP_UNIX
|
||||
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
|
||||
{ "-output_sexps", "Outputs SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
|
||||
{ "-output_scripting", "Outputs scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
|
||||
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-verify_vps", "Spew VP crcs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
#ifdef SCP_UNIX
|
||||
{ "-nograb", "Don't grab mouse/keyboard in a window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
|
||||
#endif
|
||||
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
|
||||
#endif
|
||||
};
|
||||
|
||||
// here are the command line parameters that we will be using for FreeSpace
|
||||
@@ -218,6 +210,7 @@ cmdline_parm gameclosed_arg("-closed", NULL); // Cmdline_closed_game
|
||||
cmdline_parm gamerestricted_arg("-restricted", NULL); // Cmdline_restricted_game
|
||||
cmdline_parm port_arg("-port", NULL);
|
||||
cmdline_parm multilog_arg("-multilog", NULL); // Cmdline_multi_log
|
||||
cmdline_parm server_firing_arg("-oldfire", NULL); // Cmdline_server_firing
|
||||
cmdline_parm client_dodamage("-clientdamage", NULL); // Cmdline_client_dodamage
|
||||
cmdline_parm pof_spew("-pofspew", NULL); // Cmdline_spew_pof_info
|
||||
cmdline_parm mouse_coords("-coords", NULL); // Cmdline_mouse_coords
|
||||
@@ -240,6 +233,7 @@ int Cmdline_multi_log = 0;
|
||||
int Cmdline_multi_stream_chat_to_file = 0;
|
||||
int Cmdline_network_port = -1;
|
||||
int Cmdline_restricted_game = 0;
|
||||
int Cmdline_server_firing = 0;
|
||||
int Cmdline_spew_pof_info = 0;
|
||||
int Cmdline_start_netgame = 0;
|
||||
int Cmdline_timeout = -1;
|
||||
@@ -257,7 +251,10 @@ cmdline_parm spec_static_arg("-spec_static", NULL);
|
||||
cmdline_parm spec_point_arg("-spec_point", NULL);
|
||||
cmdline_parm spec_tube_arg("-spec_tube", NULL);
|
||||
cmdline_parm ambient_factor_arg("-ambient_factor", NULL); // Cmdline_ambient_factor
|
||||
cmdline_parm cell_arg("-cell", NULL); // Cmdline_cell
|
||||
cmdline_parm decals("-decals", NULL); // Cmdline_decals
|
||||
cmdline_parm env("-env", NULL); // Cmdline_env
|
||||
cmdline_parm mipmap_arg("-mipmap", NULL); // Cmdline_mipmap
|
||||
cmdline_parm missile_lighting_arg("-missile_lighting", NULL); // Cmdline_missile_lighting
|
||||
cmdline_parm glow_arg("-glow", NULL); // Cmdline_glow -- use Bobs glow code
|
||||
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
|
||||
@@ -267,18 +264,15 @@ cmdline_parm noemissive_arg("-no_emissive_light", NULL); // Cmdline_no_emissive
|
||||
cmdline_parm normal_arg("-normal", NULL); // Cmdline_normal -- enable normal mapping
|
||||
cmdline_parm height_arg("-height", NULL); // Cmdline_height -- enable support for parallax mapping
|
||||
cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL);
|
||||
cmdline_parm softparticles_arg("-soft_particles", NULL);
|
||||
cmdline_parm postprocess_arg("-post_process", NULL);
|
||||
cmdline_parm bloom_intensity_arg("-bloom_intensity", NULL);
|
||||
cmdline_parm fxaa_arg("-fxaa", NULL);
|
||||
cmdline_parm fxaa_preset_arg("-fxaa_preset", NULL);
|
||||
cmdline_parm fb_explosions_arg("-fb_explosions", NULL);
|
||||
cmdline_parm flightshaftsoff_arg("-flightshaftsoff", NULL);
|
||||
|
||||
float Cmdline_clip_dist = Default_min_draw_distance;
|
||||
float Cmdline_fov = 0.75f;
|
||||
float Cmdline_ogl_spec = 80.0f;
|
||||
int Cmdline_ambient_factor = 128;
|
||||
int Cmdline_cell = 0;
|
||||
int Cmdline_decals = 0;
|
||||
int Cmdline_env = 0;
|
||||
int Cmdline_mipmap = 0;
|
||||
int Cmdline_missile_lighting = 0;
|
||||
@@ -290,14 +284,8 @@ int Cmdline_no_emissive = 0;
|
||||
int Cmdline_normal = 0;
|
||||
int Cmdline_height = 0;
|
||||
int Cmdline_enable_3d_shockwave = 0;
|
||||
int Cmdline_softparticles = 0;
|
||||
int Cmdline_postprocess = 0;
|
||||
int Cmdline_bloom_intensity = 75;
|
||||
bool Cmdline_fxaa = false;
|
||||
int Cmdline_fxaa_preset = 6;
|
||||
extern int Fxaa_preset_last_frame;
|
||||
bool Cmdline_fb_explosions = 0;
|
||||
extern bool ls_force_off;
|
||||
|
||||
// Game Speed related
|
||||
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL); // Cmdline_cache_bitmaps
|
||||
@@ -347,8 +335,10 @@ int Cmdline_voice_recognition = 0;
|
||||
|
||||
// MOD related
|
||||
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
|
||||
cmdline_parm tbp("-tbp", NULL); // Cmdline_tbp -- TBP warp effects -Et1
|
||||
|
||||
char *Cmdline_mod = NULL; //DTP for mod arguement
|
||||
int Cmdline_tbp = 0;
|
||||
|
||||
// Multiplayer/Network related
|
||||
cmdline_parm almission_arg("-almission", NULL); // Cmdline_almission -- DTP for autoload Multi mission
|
||||
@@ -366,36 +356,31 @@ char *Cmdline_spew_table_crcs = NULL;
|
||||
int Cmdline_objupd = 3; // client object updates on LAN by default
|
||||
|
||||
// Troubleshooting
|
||||
cmdline_parm d3d_lesstmem_arg("-d3d_bad_tsys", NULL); // Cmdline_d3d_lesstmem
|
||||
cmdline_parm loadallweapons_arg("-loadallweps", NULL); // Cmdline_load_all_weapons
|
||||
cmdline_parm htl_arg("-nohtl", NULL); // Cmdline_nohtl -- don't use HT&L
|
||||
cmdline_parm noibx_arg("-noibx", NULL); // Cmdline_noibx
|
||||
cmdline_parm nomovies_arg("-nomovies", NULL); // Cmdline_nomovies -- Allows video streaming
|
||||
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL); // Cmdline_no_set_gamma
|
||||
cmdline_parm no_vbo_arg("-novbo", NULL); // Cmdline_novbo
|
||||
cmdline_parm safeloading_arg("-safeloading", NULL); // Cmdline_safeloading -- Uses old loading method -C
|
||||
cmdline_parm no_fbo_arg("-disable_fbo", NULL); // Cmdline_no_fbo
|
||||
cmdline_parm noglsl_arg("-no_glsl", NULL); // Cmdline_noglsl -- disable GLSL support in OpenGL
|
||||
cmdline_parm mipmap_arg("-mipmap", NULL); // Cmdline_mipmap
|
||||
cmdline_parm atiswap_arg("-ati_swap", NULL); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
|
||||
cmdline_parm no3dsound_arg("-no_3d_sound", NULL); // Cmdline_no_3d_sound - Disable use of full 3D sounds
|
||||
cmdline_parm no_glsl_models_arg("-disable_glsl_model", NULL); // Cmdline_no_glsl_model_rendering -- switches model rendering to fixed pipeline
|
||||
cmdline_parm no_di_mouse_arg("-disable_di_mouse", NULL); // Cmdline_no_di_mouse -- Disables directinput use for mouse control
|
||||
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
|
||||
cmdline_parm keyboard_layout("-keyboard_layout", NULL);
|
||||
|
||||
int Cmdline_d3d_lesstmem = 0;
|
||||
int Cmdline_load_all_weapons = 0;
|
||||
int Cmdline_nohtl = 0;
|
||||
int Cmdline_noibx = 0;
|
||||
int Cmdline_nomovies = 0;
|
||||
int Cmdline_no_set_gamma = 0;
|
||||
int Cmdline_novbo = 0; // turn off OGL VBO support, troubleshooting
|
||||
int Cmdline_safeloading = 0;
|
||||
int Cmdline_no_fbo = 0;
|
||||
int Cmdline_noglsl = 0;
|
||||
int Cmdline_ati_color_swap = 0;
|
||||
int Cmdline_no_3d_sound = 0;
|
||||
int Cmdline_no_glsl_model_rendering = 0;
|
||||
int Cmdline_no_di_mouse = 0;
|
||||
int Cmdline_drawelements = 0;
|
||||
char* Cmdline_keyboard_layout = NULL;
|
||||
|
||||
// Developer/Testing related
|
||||
cmdline_parm start_mission_arg("-start_mission", NULL); // Cmdline_start_mission
|
||||
@@ -408,17 +393,16 @@ cmdline_parm fps_arg("-fps", NULL); // Cmdline_show_fps
|
||||
cmdline_parm show_mem_usage_arg("-show_mem_usage", NULL); // Cmdline_show_mem_usage
|
||||
cmdline_parm pos_arg("-pos", NULL); // Cmdline_show_pos
|
||||
cmdline_parm stats_arg("-stats", NULL); // Cmdline_show_stats
|
||||
cmdline_parm timerbar_arg("-timerbar", NULL); // Cmdline_timerbar
|
||||
cmdline_parm save_render_targets_arg("-save_render_target", NULL); // Cmdline_save_render_targets
|
||||
cmdline_parm debug_window_arg("-debug_window", NULL); // Cmdline_debug_window
|
||||
cmdline_parm window_arg("-window", NULL); // Cmdline_window
|
||||
cmdline_parm fullscreen_window_arg("-fullscreen_window",NULL);
|
||||
cmdline_parm res_arg("-res", NULL); // Cmdline_lores
|
||||
cmdline_parm verify_vps_arg("-verify_vps", NULL); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
|
||||
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, NULL);
|
||||
#ifdef SCP_UNIX
|
||||
cmdline_parm no_grab("-nograb", NULL); // Cmdline_no_grab
|
||||
#endif
|
||||
cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL); //Cmdline_reparse_mainhall
|
||||
|
||||
char *Cmdline_start_mission = NULL;
|
||||
int Cmdline_dis_collisions = 0;
|
||||
@@ -429,6 +413,7 @@ int Cmdline_extra_warn = 0;
|
||||
int Cmdline_show_mem_usage = 0;
|
||||
int Cmdline_show_pos = 0;
|
||||
int Cmdline_show_stats = 0;
|
||||
int Cmdline_timerbar = 0;
|
||||
int Cmdline_save_render_targets = 0;
|
||||
int Cmdline_debug_window = 0;
|
||||
int Cmdline_window = 0;
|
||||
@@ -438,7 +423,6 @@ int Cmdline_verify_vps = 0;
|
||||
#ifdef SCP_UNIX
|
||||
int Cmdline_no_grab = 0;
|
||||
#endif
|
||||
int Cmdline_reparse_mainhall = 0;
|
||||
|
||||
// Other
|
||||
cmdline_parm get_flags_arg("-get_flags", NULL);
|
||||
@@ -592,12 +576,10 @@ void os_parse_parms(char *cmdline)
|
||||
if ( !cmdline_offset )
|
||||
break;
|
||||
|
||||
int parmp_len = strlen(parmp->name);
|
||||
|
||||
// the new offset should be our currently location + the length of the current option
|
||||
get_new_offset = (strlen(cmdline) - strlen(cmdline_offset) + parmp_len);
|
||||
get_new_offset = (strlen(cmdline) - strlen(cmdline_offset) + strlen(parmp->name));
|
||||
|
||||
if ( (*(cmdline_offset + parmp_len)) && !is_extra_space(*(cmdline_offset + parmp_len)) ) {
|
||||
if ( (*(cmdline_offset + strlen(parmp->name))) && !is_extra_space(*(cmdline_offset + strlen(parmp->name))) ) {
|
||||
// we found a similar, but not exact, match for this option, continue checking for the correct one
|
||||
} else {
|
||||
// we found what we were looking for so break out and process it
|
||||
@@ -626,8 +608,8 @@ void os_validate_parms(char *cmdline)
|
||||
char *token;
|
||||
int parm_found;
|
||||
|
||||
token = strtok(cmdline, seps);
|
||||
while(token != NULL) {
|
||||
token = strtok(cmdline, seps);
|
||||
while(token != NULL) {
|
||||
|
||||
if (token[0] == '-') {
|
||||
parm_found = 0;
|
||||
@@ -653,17 +635,11 @@ void os_validate_parms(char *cmdline)
|
||||
snprintf(buffer, 128, "Unrecognized command line parameter, \"%s\", continue?", token);
|
||||
message = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingASCII);
|
||||
|
||||
if ( CFUserNotificationDisplayAlert(0, kCFUserNotificationPlainAlertLevel, NULL, NULL, NULL, CFSTR("Unknown Command"), message, NULL, CFSTR("Quit"), NULL, &result) ) {
|
||||
CFRelease(message);
|
||||
if ( CFUserNotificationDisplayAlert(0, kCFUserNotificationPlainAlertLevel, NULL, NULL, NULL, CFSTR("Unknown Command"), message, NULL, CFSTR("Quit"), NULL, &result) )
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (result != kCFUserNotificationDefaultResponse) {
|
||||
CFRelease(message);
|
||||
if (result != kCFUserNotificationDefaultResponse)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
CFRelease(message);
|
||||
#else
|
||||
// if we got a -help, --help, -h, or -? then show the help text, otherwise show unknown option
|
||||
if ( !stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?") ) {
|
||||
@@ -706,12 +682,6 @@ void os_init_cmdline(char *cmdline)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
bool parse_config = true;
|
||||
|
||||
if (strstr(cmdline, PARSE_COMMAND_LINE_STRING) != NULL) {
|
||||
parse_config = false;
|
||||
}
|
||||
|
||||
// read the cmdline.cfg file from the data folder, and pass the command line arguments to
|
||||
// the the parse_parms and validate_parms line. Read these first so anything actually on
|
||||
// the command line will take precedence
|
||||
@@ -736,7 +706,7 @@ void os_init_cmdline(char *cmdline)
|
||||
#endif
|
||||
|
||||
// if the file exists, get a single line, and deal with it
|
||||
if ( fp && parse_config ) {
|
||||
if ( fp ) {
|
||||
char *buf, *p;
|
||||
|
||||
size_t len = filelength( fileno(fp) ) + 2;
|
||||
@@ -938,12 +908,21 @@ bool SetCmdlineParams()
|
||||
{
|
||||
Cmdline_nowarn = 1;
|
||||
}
|
||||
/* karajorma - let's just use -nohtl instead
|
||||
if (fred2_htl_arg.found())
|
||||
{
|
||||
Cmdline_FRED2_htl = 1;
|
||||
}*/
|
||||
|
||||
if (extra_warn_arg.found())
|
||||
{
|
||||
Cmdline_extra_warn = 1;
|
||||
}
|
||||
|
||||
if (timerbar_arg.found()) {
|
||||
Cmdline_timerbar = 1;
|
||||
}
|
||||
|
||||
if ( missioncrcspew_arg.found() ) {
|
||||
Cmdline_spew_mission_crcs = missioncrcspew_arg.str();
|
||||
|
||||
@@ -962,11 +941,9 @@ bool SetCmdlineParams()
|
||||
}
|
||||
}
|
||||
|
||||
if (!Fred_running) { //There is no standalone FRED
|
||||
// is this a standalone server??
|
||||
if (standalone_arg.found()) {
|
||||
Is_standalone = 1;
|
||||
}
|
||||
// is this a standalone server??
|
||||
if (standalone_arg.found()) {
|
||||
Is_standalone = 1;
|
||||
}
|
||||
|
||||
// object update control
|
||||
@@ -1058,6 +1035,10 @@ bool SetCmdlineParams()
|
||||
Cmdline_multi_log = 1;
|
||||
}
|
||||
|
||||
// maybe use old-school server-side firing
|
||||
if (server_firing_arg.found() ){
|
||||
Cmdline_server_firing = 1;
|
||||
}
|
||||
|
||||
// maybe use old-school client damage
|
||||
if(client_dodamage.found()){
|
||||
@@ -1167,6 +1148,10 @@ bool SetCmdlineParams()
|
||||
Cmdline_show_pos = 1;
|
||||
}
|
||||
|
||||
if ( safeloading_arg.found() ) {
|
||||
Cmdline_safeloading = 1;
|
||||
}
|
||||
|
||||
if ( nomotiondebris_arg.found() ) {
|
||||
Cmdline_nomotiondebris = 1;
|
||||
}
|
||||
@@ -1197,6 +1182,16 @@ bool SetCmdlineParams()
|
||||
Cmdline_orb_radar = 1;
|
||||
}
|
||||
|
||||
// TBP warp effects -Et1
|
||||
// Chief1983 - Add 3d shockwave, ship choice 3d and weapon choice 3d if TBP is checked
|
||||
if( tbp.found() )
|
||||
{
|
||||
Cmdline_tbp = 1;
|
||||
Cmdline_enable_3d_shockwave = 1;
|
||||
Cmdline_ship_choice_3d = 1;
|
||||
Cmdline_weapon_choice_3d = 1;
|
||||
}
|
||||
|
||||
if ( use_3dwarp.found() ) {
|
||||
Cmdline_3dwarp = 1;
|
||||
}
|
||||
@@ -1225,6 +1220,10 @@ bool SetCmdlineParams()
|
||||
static_tube_factor = spec_tube_arg.get_float();
|
||||
}
|
||||
|
||||
if ( cell_arg.found() ) {
|
||||
Cmdline_cell = 1;
|
||||
}
|
||||
|
||||
if ( spec_arg.found() )
|
||||
{
|
||||
Cmdline_spec = 1;
|
||||
@@ -1265,24 +1264,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_noglsl = 1;
|
||||
}
|
||||
|
||||
if (no_glsl_models_arg.found() ) {
|
||||
Cmdline_no_glsl_model_rendering = 1;
|
||||
}
|
||||
|
||||
if (fxaa_arg.found() ) {
|
||||
Cmdline_fxaa = true;
|
||||
|
||||
if (fxaa_preset_arg.found()) {
|
||||
Cmdline_fxaa_preset = fxaa_preset_arg.get_int();
|
||||
}
|
||||
|
||||
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
|
||||
}
|
||||
|
||||
if (no_di_mouse_arg.found() ) {
|
||||
Cmdline_no_di_mouse = 1;
|
||||
}
|
||||
|
||||
if ( img2dds_arg.found() )
|
||||
Cmdline_img2dds = 1;
|
||||
|
||||
@@ -1363,21 +1344,13 @@ bool SetCmdlineParams()
|
||||
output_sexps("sexps.html");
|
||||
}
|
||||
|
||||
Cmdline_d3d_lesstmem = !d3d_lesstmem_arg.found();
|
||||
|
||||
if ( no_vbo_arg.found() )
|
||||
{
|
||||
Cmdline_novbo = 1;
|
||||
}
|
||||
|
||||
if ( no_drawrangeelements.found() )
|
||||
{
|
||||
Cmdline_drawelements = 1;
|
||||
}
|
||||
|
||||
if( keyboard_layout.found())
|
||||
{
|
||||
Cmdline_keyboard_layout = keyboard_layout.str();
|
||||
}
|
||||
|
||||
if ( snd_preload_arg.found() )
|
||||
{
|
||||
Cmdline_snd_preload = 1;
|
||||
@@ -1387,6 +1360,13 @@ bool SetCmdlineParams()
|
||||
Cmdline_env = 1;
|
||||
}
|
||||
|
||||
if ( decals.found() ) {
|
||||
|
||||
#ifdef WIN32
|
||||
MessageBox(NULL, "Decals have been disabled in builds after May 4, 2006. Please remove the \"-decals\" command line from the launcher to prevent this message from appearing the the future.", "", MB_OK | MB_ICONINFORMATION);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ballistic_gauge.found() ) {
|
||||
Cmdline_ballistic_gauge = 1;
|
||||
}
|
||||
@@ -1451,16 +1431,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_enable_3d_shockwave = 1;
|
||||
}
|
||||
|
||||
if ( softparticles_arg.found() )
|
||||
{
|
||||
Cmdline_softparticles = 1;
|
||||
}
|
||||
|
||||
if ( fb_explosions_arg.found() )
|
||||
{
|
||||
Cmdline_fb_explosions = 1;
|
||||
}
|
||||
|
||||
if ( postprocess_arg.found() )
|
||||
{
|
||||
Cmdline_postprocess = 1;
|
||||
@@ -1471,16 +1441,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_bloom_intensity = bloom_intensity_arg.get_int();
|
||||
}
|
||||
|
||||
if ( flightshaftsoff_arg.found() )
|
||||
{
|
||||
ls_force_off = true;
|
||||
}
|
||||
|
||||
if( reparse_mainhall_arg.found() )
|
||||
{
|
||||
Cmdline_reparse_mainhall = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -41,6 +41,7 @@ extern int Cmdline_multi_log;
|
||||
extern int Cmdline_multi_stream_chat_to_file;
|
||||
extern int Cmdline_network_port;
|
||||
extern int Cmdline_restricted_game;
|
||||
extern int Cmdline_server_firing;
|
||||
extern int Cmdline_spew_pof_info;
|
||||
extern int Cmdline_start_netgame;
|
||||
extern int Cmdline_timeout;
|
||||
@@ -61,7 +62,10 @@ extern float static_light_factor;
|
||||
extern float static_point_factor;
|
||||
extern float static_tube_factor;
|
||||
extern int Cmdline_ambient_factor;
|
||||
extern int Cmdline_cell;
|
||||
extern int Cmdline_decals;
|
||||
extern int Cmdline_env;
|
||||
extern int Cmdline_mipmap;
|
||||
extern int Cmdline_missile_lighting;
|
||||
extern int Cmdline_glow;
|
||||
extern int Cmdline_nomotiondebris;
|
||||
@@ -70,12 +74,8 @@ extern int Cmdline_spec;
|
||||
extern int Cmdline_normal;
|
||||
extern int Cmdline_height;
|
||||
extern int Cmdline_enable_3d_shockwave;
|
||||
extern int Cmdline_softparticles;
|
||||
extern int Cmdline_postprocess;
|
||||
extern int Cmdline_bloom_intensity;
|
||||
extern bool Cmdline_fxaa;
|
||||
extern int Cmdline_fxaa_preset;
|
||||
extern bool Cmdline_fb_explosions;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
@@ -104,6 +104,8 @@ extern int Cmdline_voice_recognition;
|
||||
|
||||
// MOD related
|
||||
extern char *Cmdline_mod; // DTP for mod support
|
||||
extern int Cmdline_tbp;
|
||||
|
||||
// Multiplayer/Network related
|
||||
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
|
||||
extern int Cmdline_ingamejoin;
|
||||
@@ -113,21 +115,18 @@ extern char *Cmdline_spew_table_crcs;
|
||||
extern int Cmdline_objupd;
|
||||
|
||||
// Troubleshooting
|
||||
extern int Cmdline_d3d_lesstmem;
|
||||
extern int Cmdline_load_all_weapons;
|
||||
extern int Cmdline_nohtl;
|
||||
extern int Cmdline_noibx;
|
||||
extern int Cmdline_nomovies; // WMC Toggles movie playing support
|
||||
extern int Cmdline_no_set_gamma;
|
||||
extern int Cmdline_novbo;
|
||||
extern int Cmdline_safeloading;
|
||||
extern int Cmdline_no_fbo;
|
||||
extern int Cmdline_noglsl;
|
||||
extern int Cmdline_mipmap;
|
||||
extern int Cmdline_ati_color_swap;
|
||||
extern int Cmdline_no_3d_sound;
|
||||
extern int Cmdline_no_glsl_model_rendering;
|
||||
extern int Cmdline_no_di_mouse;
|
||||
extern int Cmdline_drawelements;
|
||||
extern char* Cmdline_keyboard_layout;
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
@@ -139,12 +138,15 @@ extern int Cmdline_extra_warn;
|
||||
extern int Cmdline_show_mem_usage;
|
||||
extern int Cmdline_show_pos;
|
||||
extern int Cmdline_show_stats;
|
||||
extern int Cmdline_timerbar;
|
||||
extern int Cmdline_save_render_targets;
|
||||
extern int Cmdline_debug_window;
|
||||
extern int Cmdline_verify_vps;
|
||||
#ifdef SCP_UNIX
|
||||
extern int Cmdline_no_grab;
|
||||
#endif
|
||||
extern int Cmdline_reparse_mainhall;
|
||||
|
||||
|
||||
|
||||
//extern char FreeSpace_Directory[]; // allievating a cfilesystem problem caused by fred -- Kazan
|
||||
#endif
|
||||
+195
-10
@@ -10,6 +10,8 @@
|
||||
|
||||
|
||||
#include "cmeasure/cmeasure.h"
|
||||
//#include "freespace2/freespace.h"
|
||||
//#include "model/model.h"
|
||||
#include "ship/ship.h"
|
||||
#include "math/staticrand.h"
|
||||
#include "object/object.h"
|
||||
@@ -19,9 +21,192 @@
|
||||
#include "network/multimsgs.h"
|
||||
#include "mission/missionparse.h"
|
||||
|
||||
|
||||
//cmeasure_info Cmeasure_info[MAX_CMEASURE_TYPES];
|
||||
//cmeasure Cmeasures[MAX_CMEASURES];
|
||||
|
||||
//int Num_cmeasure_types = 0;
|
||||
//int Num_cmeasures = 0;
|
||||
//int Cmeasure_inited = 0;
|
||||
int Cmeasures_homing_check = 0;
|
||||
int Countermeasures_enabled = 1; // Debug, set to 0 means no one can fire countermeasures.
|
||||
|
||||
// This will get called at the start of each level.
|
||||
//Not anymore - WMC
|
||||
/*
|
||||
void cmeasure_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !Cmeasure_inited )
|
||||
Cmeasure_inited = 1;
|
||||
|
||||
// Reset everything between levels
|
||||
Num_cmeasures = 0;
|
||||
|
||||
for (i=0; i<MAX_CMEASURES; i++ ) {
|
||||
Cmeasures[i].subtype = CMEASURE_UNUSED;
|
||||
}
|
||||
|
||||
}*/
|
||||
/*
|
||||
void cmeasure_render(object * objp)
|
||||
{
|
||||
// JAS TODO: Replace with proper fireball
|
||||
cmeasure *cmp;
|
||||
cmeasure_info *cmip;
|
||||
|
||||
cmp = &Cmeasures[objp->instance];
|
||||
cmip = &Cmeasure_info[cmp->subtype];
|
||||
|
||||
if ( cmp->subtype == CMEASURE_UNUSED ) {
|
||||
Int3(); // Hey, what are we doing in here?
|
||||
return;
|
||||
}
|
||||
|
||||
if ( cmip->model_num > -1 ) {
|
||||
model_clear_instance(cmip->model_num);
|
||||
model_render(cmip->model_num, &objp->orient, &objp->pos, MR_NO_LIGHTING );
|
||||
} else {
|
||||
mprintf(( "Not rendering countermeasure because model_num is negative\n" ));
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
void cmeasure_delete( object * objp )
|
||||
{
|
||||
int num;
|
||||
|
||||
num = objp->instance;
|
||||
|
||||
// Assert( Cmeasures[num].objnum == OBJ_INDEX(objp));
|
||||
|
||||
Cmeasures[num].subtype = CMEASURE_UNUSED;
|
||||
Num_cmeasures--;
|
||||
Assert( Num_cmeasures >= 0 );
|
||||
}*/
|
||||
|
||||
// broke cmeasure_move into two functions -- process_pre and process_post (as was done with
|
||||
// all *_move functions). Nothing to do for process_pre
|
||||
/*
|
||||
void cmeasure_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}*/
|
||||
/*
|
||||
void cmeasure_process_post(object * objp, float frame_time)
|
||||
{
|
||||
int num;
|
||||
num = objp->instance;
|
||||
|
||||
// Assert( Cmeasures[num].objnum == objnum );
|
||||
cmeasure *cmp = &Cmeasures[num];
|
||||
|
||||
if ( cmp->lifeleft >= 0.0f) {
|
||||
cmp->lifeleft -= frame_time;
|
||||
if ( cmp->lifeleft < 0.0f ) {
|
||||
objp->flags |= OF_SHOULD_BE_DEAD;
|
||||
// demo_do_flag_dead(OBJ_INDEX(objp));
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
// creates one countermeasure. A ship fires 1 of these per launch. rand_val is used
|
||||
// in multiplayer. If -1, then create a random number. If non-negative, use this
|
||||
// number for static_rand functions
|
||||
/*
|
||||
int cmeasure_create( object * source_obj, vec3d * pos, int cm_type, int rand_val )
|
||||
{
|
||||
int n, objnum, parent_objnum, arand;
|
||||
object * obj;
|
||||
ship *shipp;
|
||||
cmeasure *cmp;
|
||||
cmeasure_info *cmeasurep;
|
||||
|
||||
Cmeasures_homing_check = 2; // Tell homing code to scan everything for two frames. If only one frame, get sync problems due to objects being created at end of frame!
|
||||
|
||||
parent_objnum = OBJ_INDEX(source_obj);
|
||||
|
||||
Assert( source_obj->type == OBJ_SHIP );
|
||||
Assert( source_obj->instance >= 0 && source_obj->instance < MAX_SHIPS );
|
||||
|
||||
shipp = &Ships[source_obj->instance];
|
||||
|
||||
if ( Num_cmeasures >= MAX_CMEASURES)
|
||||
return -1;
|
||||
|
||||
for (n=0; n<MAX_CMEASURES; n++ )
|
||||
if ( Cmeasures[n].subtype == CMEASURE_UNUSED)
|
||||
break;
|
||||
if ( n == MAX_CMEASURES)
|
||||
return -1;
|
||||
|
||||
nprintf(("Network", "Cmeasure created by %s\n", Ships[source_obj->instance].ship_name));
|
||||
|
||||
cmp = &Cmeasures[n];
|
||||
cmeasurep = &Cmeasure_info[cm_type];
|
||||
|
||||
if ( pos == NULL )
|
||||
pos = &source_obj->pos;
|
||||
|
||||
objnum = obj_create( OBJ_CMEASURE, parent_objnum, n, &source_obj->orient, pos, 1.0f, OF_RENDERS | OF_PHYSICS );
|
||||
|
||||
Assert( objnum >= 0 && objnum < MAX_OBJECTS );
|
||||
|
||||
// Create Debris piece n!
|
||||
if ( rand_val == -1 )
|
||||
arand = myrand(); // use a random number to get lifeleft, and random vector for displacement from ship
|
||||
else
|
||||
arand = rand_val;
|
||||
|
||||
cmp->lifeleft = static_randf(arand) * (cmeasurep->life_max - cmeasurep->life_min) / cmeasurep->life_min;
|
||||
if (source_obj->flags & OF_PLAYER_SHIP){
|
||||
cmp->lifeleft *= The_mission.ai_profile->cmeasure_life_scale[Game_skill_level];
|
||||
}
|
||||
cmp->lifeleft = cmeasurep->life_min + cmp->lifeleft * (cmeasurep->life_max - cmeasurep->life_min);
|
||||
|
||||
// cmp->objnum = objnum;
|
||||
cmp->team = shipp->team;
|
||||
cmp->subtype = cm_type;
|
||||
cmp->objnum = objnum;
|
||||
cmp->source_objnum = parent_objnum;
|
||||
cmp->source_sig = Objects[objnum].signature;
|
||||
|
||||
cmp->flags = 0;
|
||||
|
||||
nprintf(("Jim", "Frame %i: Launching countermeasure #%i\n", Framecount, Objects[objnum].signature));
|
||||
|
||||
obj = &Objects[objnum];
|
||||
|
||||
Num_cmeasures++;
|
||||
|
||||
//Set countermeasure velocity
|
||||
vec3d vel, rand_vec;
|
||||
|
||||
//Get cmeasure rear velocity in world
|
||||
vm_vec_scale_add(&vel, &source_obj->phys_info.vel, &source_obj->orient.vec.fvec, -25.0f);
|
||||
|
||||
//Get random velocity vector
|
||||
static_randvec(arand+1, &rand_vec);
|
||||
|
||||
//Add it to the rear velocity
|
||||
vm_vec_scale_add2(&vel, &rand_vec, 2.0f);
|
||||
|
||||
obj->phys_info.vel = vel;
|
||||
|
||||
vm_vec_zero(&obj->phys_info.rotvel);
|
||||
vm_vec_zero(&obj->phys_info.max_vel);
|
||||
vm_vec_zero(&obj->phys_info.max_rotvel);
|
||||
|
||||
// blow out his reverse thrusters. Or drag, same thing.
|
||||
obj->phys_info.rotdamp = 10000.0f;
|
||||
obj->phys_info.side_slip_time_const = 10000.0f;
|
||||
|
||||
obj->phys_info.max_vel.xyz.z = -25.0f;
|
||||
vm_vec_copy_scale(&obj->phys_info.desired_vel, &obj->orient.vec.fvec, obj->phys_info.max_vel.xyz.z );
|
||||
|
||||
return arand; // need to return this value for multiplayer purposes
|
||||
}*/
|
||||
|
||||
//Used to set a countermeasure velocity after being launched from a ship as a countermeasure
|
||||
//ie not as a primary or secondary.
|
||||
void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
|
||||
@@ -44,6 +229,12 @@ void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
|
||||
vm_vec_zero(&objp->phys_info.max_vel);
|
||||
vm_vec_zero(&objp->phys_info.max_rotvel);
|
||||
|
||||
//Idunnit. -WMC
|
||||
//objp->phys_info.flags |= PF_CONST_VEL;
|
||||
|
||||
//WMC - I don't think this stuff is needed with the flag I set
|
||||
//WMC - Or maybe it is.
|
||||
|
||||
// blow out his reverse thrusters. Or drag, same thing.
|
||||
objp->phys_info.rotdamp = 10000.0f;
|
||||
objp->phys_info.side_slip_time_const = 10000.0f;
|
||||
@@ -68,18 +259,12 @@ void cmeasure_select_next(ship *shipp)
|
||||
}
|
||||
}
|
||||
|
||||
//snd_play( &Snds[SND_CMEASURE_CYCLE] );
|
||||
|
||||
mprintf(("Countermeasure type set to %i in frame %i\n", shipp->current_cmeasure, Framecount));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief If this is a player countermeasure, let the player know they evaded a missile.
|
||||
* @param objp [description]
|
||||
*
|
||||
* During single player games, this function notifies the player that evasion has occurred.
|
||||
* Multiplayer games ensure that #send_countermeasure_success_packet() is called to notify the other player.
|
||||
*/
|
||||
|
||||
// If this is a player countermeasure, let the player know he evaded a missile
|
||||
void cmeasure_maybe_alert_success(object *objp)
|
||||
{
|
||||
//Is this a countermeasure, and does it have a parent
|
||||
@@ -91,7 +276,7 @@ void cmeasure_maybe_alert_success(object *objp)
|
||||
|
||||
if ( objp->parent == OBJ_INDEX(Player_obj) ) {
|
||||
hud_start_text_flash(XSTR("Evaded", 1430), 800);
|
||||
snd_play(&Snds[ship_get_sound(Player_obj, SND_MISSILE_EVADED_POPUP)]);
|
||||
snd_play(&Snds[SND_MISSILE_EVADED_POPUP]);
|
||||
} else if ( Objects[objp->parent].flags & OF_PLAYER_SHIP ) {
|
||||
send_countermeasure_success_packet( objp->parent );
|
||||
}
|
||||
|
||||
@@ -16,18 +16,63 @@
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
struct object;
|
||||
//struct vec3d;
|
||||
|
||||
//#define MAX_CMEASURES 64
|
||||
|
||||
// Goes in cmeasure.subtype
|
||||
//#define CMEASURE_UNUSED -1
|
||||
|
||||
//#define MAX_CMEASURE_TYPES 3
|
||||
|
||||
#define CMEASURE_WAIT 333 // delay in milliseconds between countermeasure firing.
|
||||
|
||||
//#define CMF_DUD_HEAT 0x01 // If set, this cmeasure is a dud to heat seekers. Set at create time.
|
||||
//#define CMF_DUD_ASPECT 0x02 // If set, this cmeasure is a dud to aspect seekers. Set at create time.
|
||||
|
||||
//#define CMF_DUD (CMF_DUD_HEAT | CMF_DUD_ASPECT)
|
||||
|
||||
// Maximum distance at which a countermeasure can be tracked
|
||||
// If this value is too large, missiles will always be tracking countermeasures.
|
||||
#define MAX_CMEASURE_TRACK_DIST 300.0f
|
||||
/*
|
||||
typedef struct cmeasure_info {
|
||||
char cmeasure_name[NAME_LENGTH];
|
||||
//float max_speed; // launch speed, relative to ship
|
||||
float fire_wait; // time between launches
|
||||
float life_min, life_max; // lifetime will be in range min..max.
|
||||
int launch_sound; // Sound played when launched.
|
||||
char pof_name[NAME_LENGTH];
|
||||
int model_num; // What this renders as
|
||||
} cmeasure_info;
|
||||
|
||||
typedef struct cmeasure {
|
||||
int flags; // You know, flag type things.
|
||||
int subtype; // See CMEASURE_??? defines
|
||||
int objnum;
|
||||
int source_objnum; // What object this came from
|
||||
int source_sig; // Signature of the source object
|
||||
int team; // Team of the ship where the cmeasure came from
|
||||
float lifeleft; // When 0 or less object dies
|
||||
} cmeasure;
|
||||
*/
|
||||
//extern cmeasure_info Cmeasure_info[MAX_CMEASURE_TYPES];
|
||||
//extern cmeasure Cmeasures[MAX_CMEASURES];
|
||||
//extern int Num_cmeasure_types;
|
||||
//extern int Num_cmeasures;
|
||||
extern int Cmeasures_homing_check;
|
||||
extern int Countermeasures_enabled;
|
||||
|
||||
//extern void cmeasure_init();
|
||||
//extern void cmeasure_render( object * obj );
|
||||
//extern void cmeasure_delete( object * obj );
|
||||
//extern void cmeasure_process_pre( object * obj, float frame_time);
|
||||
//extern void cmeasure_process_post( object * obj, float frame_time);
|
||||
//extern int cmeasure_create( object * source_obj, vec3d *pos, int cm_type, int rand_val = -1 );
|
||||
extern void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand);
|
||||
extern void cmeasure_select_next(object *objp);
|
||||
extern void cmeasure_maybe_alert_success(object *objp);
|
||||
|
||||
extern float Skill_level_cmeasure_life_scale[NUM_SKILL_LEVELS];
|
||||
|
||||
#endif // _CMEASURE_H
|
||||
File diff suppressed because it is too large.
Load diff
+143
-141
@@ -48,169 +48,171 @@ typedef struct config_item {
|
||||
int used; // has control been used yet in mission? If so, this is the timestamp
|
||||
} config_item;
|
||||
|
||||
/**
|
||||
* All available actions
|
||||
* This is the value of the id field in config_item
|
||||
*/
|
||||
enum IoActionId {
|
||||
// targeting a ship
|
||||
TARGET_NEXT =0, //!< target next
|
||||
TARGET_PREV =1, //!< target previous
|
||||
TARGET_NEXT_CLOSEST_HOSTILE =2, //!< target the next hostile target
|
||||
TARGET_PREV_CLOSEST_HOSTILE =3, //!< target the previous closest hostile
|
||||
TOGGLE_AUTO_TARGETING =4, //!< toggle auto-targeting
|
||||
TARGET_NEXT_CLOSEST_FRIENDLY =5, //!< target the next friendly ship
|
||||
TARGET_PREV_CLOSEST_FRIENDLY =6, //!< target the closest friendly ship
|
||||
TARGET_SHIP_IN_RETICLE =7, //!< target ship closest to center of reticle
|
||||
TARGET_CLOSEST_SHIP_ATTACKING_TARGET =8, //!< target the closest ship attacking current target
|
||||
TARGET_LAST_TRANMISSION_SENDER =9, //!< TARGET_LAST_TRANMISSION_SENDER
|
||||
STOP_TARGETING_SHIP =10, //!< stop targeting ship
|
||||
// --------------------------------------------------
|
||||
// Keyboard #defines for the actions
|
||||
// This is the value of the id field in config_item
|
||||
// --------------------------------------------------
|
||||
|
||||
// targeting a ship's subsystem
|
||||
TARGET_SUBOBJECT_IN_RETICLE =11, //!< target ships subsystem in reticle
|
||||
TARGET_NEXT_SUBOBJECT =12, //!< target next subsystem on current target
|
||||
TARGET_PREV_SUBOBJECT =13, //!< TARGET_PREV_SUBOBJECT
|
||||
STOP_TARGETING_SUBSYSTEM =14, //!< stop targeting subsystems on ship
|
||||
// targeting a ship
|
||||
|
||||
// speed matching
|
||||
MATCH_TARGET_SPEED =15, //!< match target speed
|
||||
TOGGLE_AUTO_MATCH_TARGET_SPEED =16, //!< toggle auto-match target speed
|
||||
#define TARGET_NEXT 0
|
||||
#define TARGET_PREV 1
|
||||
#define TARGET_NEXT_CLOSEST_HOSTILE 2
|
||||
#define TARGET_PREV_CLOSEST_HOSTILE 3
|
||||
#define TOGGLE_AUTO_TARGETING 4
|
||||
#define TARGET_NEXT_CLOSEST_FRIENDLY 5
|
||||
#define TARGET_PREV_CLOSEST_FRIENDLY 6
|
||||
#define TARGET_SHIP_IN_RETICLE 7
|
||||
#define TARGET_CLOSEST_SHIP_ATTACKING_TARGET 8
|
||||
#define TARGET_LAST_TRANMISSION_SENDER 9
|
||||
#define STOP_TARGETING_SHIP 10
|
||||
|
||||
// weapons
|
||||
FIRE_PRIMARY =17, //!< FIRE_PRIMARY
|
||||
FIRE_SECONDARY =18, //!< FIRE_SECONDARY
|
||||
CYCLE_NEXT_PRIMARY =19, //!< cycle to next primary weapon
|
||||
CYCLE_PREV_PRIMARY =20, //!< cycle to previous primary weapon
|
||||
CYCLE_SECONDARY =21, //!< cycle to next secondary weapon
|
||||
CYCLE_NUM_MISSLES =22, //!< cycle number of missiles fired from secondary bank
|
||||
LAUNCH_COUNTERMEASURE =23, //!< LAUNCH_COUNTERMEASURE
|
||||
// targeting a ship's subsystem
|
||||
#define TARGET_SUBOBJECT_IN_RETICLE 11
|
||||
#define TARGET_NEXT_SUBOBJECT 12
|
||||
#define TARGET_PREV_SUBOBJECT 13
|
||||
#define STOP_TARGETING_SUBSYSTEM 14
|
||||
|
||||
// controls
|
||||
FORWARD_THRUST =24, //!< FORWARD_THRUST
|
||||
REVERSE_THRUST =25, //!< REVERSE_THRUST
|
||||
BANK_LEFT =26, //!< BANK_LEFT
|
||||
BANK_RIGHT =27, //!< BANK_RIGHT
|
||||
PITCH_FORWARD =28, //!< PITCH_FORWARD
|
||||
PITCH_BACK =29, //!< PITCH_BACK
|
||||
YAW_LEFT =30, //!< YAW_LEFT
|
||||
YAW_RIGHT =31, //!< YAW_RIGHT
|
||||
// speed matching
|
||||
#define MATCH_TARGET_SPEED 15
|
||||
#define TOGGLE_AUTO_MATCH_TARGET_SPEED 16
|
||||
|
||||
// throttle control
|
||||
ZERO_THROTTLE =32, //!< ZERO_THROTTLE
|
||||
MAX_THROTTLE =33, //!< MAX_THROTTLE
|
||||
ONE_THIRD_THROTTLE =34, //!< ONE_THIRD_THROTTLE
|
||||
TWO_THIRDS_THROTTLE =35, //!< TWO_THIRDS_THROTTLE
|
||||
PLUS_5_PERCENT_THROTTLE =36, //!< PLUS_5_PERCENT_THROTTLE
|
||||
MINUS_5_PERCENT_THROTTLE =37, //!< MINUS_5_PERCENT_THROTTLE
|
||||
// weapons
|
||||
#define FIRE_PRIMARY 17
|
||||
#define FIRE_SECONDARY 18
|
||||
#define CYCLE_NEXT_PRIMARY 19
|
||||
#define CYCLE_PREV_PRIMARY 20
|
||||
#define CYCLE_SECONDARY 21
|
||||
#define CYCLE_NUM_MISSLES 22
|
||||
#define LAUNCH_COUNTERMEASURE 23
|
||||
|
||||
// squadmate messaging keys
|
||||
ATTACK_MESSAGE =38, //!< wingman message: attack current target
|
||||
DISARM_MESSAGE =39, //!< wingman message: disarm current target
|
||||
DISABLE_MESSAGE =40, //!< wingman message: disable current target
|
||||
ATTACK_SUBSYSTEM_MESSAGE =41, //!< wingman message: disable current target
|
||||
CAPTURE_MESSAGE =42, //!< wingman message: capture current target
|
||||
ENGAGE_MESSAGE =43, //!< wingman message: engage enemy
|
||||
FORM_MESSAGE =44, //!< wingman message: form on my wing
|
||||
IGNORE_MESSAGE =45, //!< IGNORE_MESSAGE
|
||||
PROTECT_MESSAGE =46, //!< wingman message: protect current target
|
||||
COVER_MESSAGE =47, //!< wingman message: cover me
|
||||
WARP_MESSAGE =48, //!< wingman message: warp out
|
||||
REARM_MESSAGE =49, //!< REARM_MESSAGE
|
||||
TARGET_CLOSEST_SHIP_ATTACKING_SELF =50, //!< target closest ship that is attacking player
|
||||
// controls
|
||||
#define FORWARD_THRUST 24
|
||||
#define REVERSE_THRUST 25
|
||||
#define BANK_LEFT 26
|
||||
#define BANK_RIGHT 27
|
||||
#define PITCH_FORWARD 28
|
||||
#define PITCH_BACK 29
|
||||
#define YAW_LEFT 30
|
||||
#define YAW_RIGHT 31
|
||||
|
||||
// Views
|
||||
VIEW_CHASE =51, //!< VIEW_CHASE
|
||||
VIEW_EXTERNAL =52, //!< VIEW_EXTERNAL
|
||||
VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK =53, //!< VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK
|
||||
VIEW_SLEW =54, //!< VIEW_SLEW
|
||||
VIEW_OTHER_SHIP =55, //!< VIEW_OTHER_SHIP
|
||||
VIEW_DIST_INCREASE =56, //!< VIEW_DIST_INCREASE
|
||||
VIEW_DIST_DECREASE =57, //!< VIEW_DIST_DECREASE
|
||||
VIEW_CENTER =58, //!< VIEW_CENTER
|
||||
PADLOCK_UP =59, //!< PADLOCK_UP
|
||||
PADLOCK_DOWN =60, //!< PADLOCK_DOWN
|
||||
PADLOCK_LEFT =61, //!< PADLOCK_LEFT
|
||||
PADLOCK_RIGHT =62, //!< PADLOCK_RIGHT
|
||||
// throttle control
|
||||
#define ZERO_THROTTLE 32
|
||||
#define MAX_THROTTLE 33
|
||||
#define ONE_THIRD_THROTTLE 34
|
||||
#define TWO_THIRDS_THROTTLE 35
|
||||
#define PLUS_5_PERCENT_THROTTLE 36
|
||||
#define MINUS_5_PERCENT_THROTTLE 37
|
||||
|
||||
RADAR_RANGE_CYCLE =63, //!< cycle to next radar range
|
||||
SQUADMSG_MENU =64, //!< toggle the squadmate messaging menu
|
||||
SHOW_GOALS =65, //!< show the mission goals screen
|
||||
END_MISSION =66, //!< end the mission
|
||||
TARGET_TARGETS_TARGET =67, //!< target your target's target
|
||||
AFTERBURNER =68, //!< AFTERBURNER
|
||||
// squadmate messaging keys
|
||||
#define ATTACK_MESSAGE 38
|
||||
#define DISARM_MESSAGE 39
|
||||
#define DISABLE_MESSAGE 40
|
||||
#define ATTACK_SUBSYSTEM_MESSAGE 41
|
||||
#define CAPTURE_MESSAGE 42
|
||||
#define ENGAGE_MESSAGE 43
|
||||
#define FORM_MESSAGE 44
|
||||
#define IGNORE_MESSAGE 45
|
||||
#define PROTECT_MESSAGE 46
|
||||
#define COVER_MESSAGE 47
|
||||
#define WARP_MESSAGE 48
|
||||
#define REARM_MESSAGE 49
|
||||
|
||||
INCREASE_WEAPON =69, //!< increase weapon recharge rate
|
||||
DECREASE_WEAPON =70, //!< decrease weapon recharge rate
|
||||
INCREASE_SHIELD =71, //!< increase shield recharge rate
|
||||
DECREASE_SHIELD =72, //!< decrease shield recharge rate
|
||||
INCREASE_ENGINE =73, //!< increase energy to engines
|
||||
DECREASE_ENGINE =74, //!< decrease energy to engines
|
||||
ETS_EQUALIZE =75, //!< equalize recharge rates
|
||||
SHIELD_EQUALIZE =76, //!< equalize shield energy to all quadrants
|
||||
SHIELD_XFER_TOP =77, //!< transfer shield energy to front
|
||||
SHIELD_XFER_BOTTOM =78, //!< transfer shield energy to rear
|
||||
SHIELD_XFER_LEFT =79, //!< transfer shield energy to left
|
||||
SHIELD_XFER_RIGHT =80, //!< transfer shield energy to right
|
||||
#define TARGET_CLOSEST_SHIP_ATTACKING_SELF 50
|
||||
|
||||
XFER_SHIELD =81, //!< transfer energy to shield from weapons
|
||||
XFER_LASER =82, //!< transfer energy to weapons from shield
|
||||
// Views
|
||||
#define VIEW_CHASE 51
|
||||
#define VIEW_EXTERNAL 52
|
||||
#define VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK 53
|
||||
#define VIEW_SLEW 54
|
||||
#define VIEW_OTHER_SHIP 55
|
||||
#define VIEW_DIST_INCREASE 56
|
||||
#define VIEW_DIST_DECREASE 57
|
||||
#define VIEW_CENTER 58
|
||||
#define PADLOCK_UP 59
|
||||
#define PADLOCK_DOWN 60
|
||||
#define PADLOCK_LEFT 61
|
||||
#define PADLOCK_RIGHT 62
|
||||
|
||||
//Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
|
||||
GLIDE_WHEN_PRESSED =83, //!< GLIDE_WHEN_PRESSED
|
||||
BANK_WHEN_PRESSED =84, //!< BANK_WHEN_PRESSED
|
||||
SHOW_NAVMAP =85, //!< SHOW_NAVMAP
|
||||
ADD_REMOVE_ESCORT =86, //!< ADD_REMOVE_ESCORT
|
||||
ESCORT_CLEAR =87, //!< ESCORT_CLEAR
|
||||
TARGET_NEXT_ESCORT_SHIP =88, //!< TARGET_NEXT_ESCORT_SHIP
|
||||
TARGET_CLOSEST_REPAIR_SHIP =89, //!< target the closest repair ship
|
||||
TARGET_NEXT_UNINSPECTED_CARGO =90, //!< TARGET_NEXT_UNINSPECTED_CARGO
|
||||
TARGET_PREV_UNINSPECTED_CARGO =91, //!< TARGET_PREV_UNINSPECTED_CARGO
|
||||
TARGET_NEWEST_SHIP =92, //!< TARGET_NEWEST_SHIP
|
||||
TARGET_NEXT_LIVE_TURRET =93, //!< TARGET_NEXT_LIVE_TURRET
|
||||
TARGET_PREV_LIVE_TURRET =94, //!< TARGET_PREV_LIVE_TURRET
|
||||
|
||||
TARGET_NEXT_BOMB =95, //!< TARGET_NEXT_BOMB
|
||||
TARGET_PREV_BOMB =96, //!< TARGET_PREV_BOMB
|
||||
#define RADAR_RANGE_CYCLE 63
|
||||
#define SQUADMSG_MENU 64
|
||||
#define SHOW_GOALS 65
|
||||
#define END_MISSION 66
|
||||
#define TARGET_TARGETS_TARGET 67
|
||||
#define AFTERBURNER 68
|
||||
|
||||
// multiplayer messaging keys
|
||||
MULTI_MESSAGE_ALL =97, //!< message all netplayers
|
||||
MULTI_MESSAGE_FRIENDLY =98, //!< message all friendlies
|
||||
MULTI_MESSAGE_HOSTILE =99, //!< message all hostiles
|
||||
MULTI_MESSAGE_TARGET =100, //!< message targeted ship (if player)
|
||||
#define INCREASE_WEAPON 69
|
||||
#define DECREASE_WEAPON 70
|
||||
#define INCREASE_SHIELD 71
|
||||
#define DECREASE_SHIELD 72
|
||||
#define INCREASE_ENGINE 73
|
||||
#define DECREASE_ENGINE 74
|
||||
#define ETS_EQUALIZE 75
|
||||
#define SHIELD_EQUALIZE 76
|
||||
#define SHIELD_XFER_TOP 77
|
||||
#define SHIELD_XFER_BOTTOM 78
|
||||
#define SHIELD_XFER_LEFT 79
|
||||
#define SHIELD_XFER_RIGHT 80
|
||||
|
||||
// multiplayer misc keys
|
||||
MULTI_OBSERVER_ZOOM_TO =101, //!< if i'm an observer, zoom to my targeted object
|
||||
#define XFER_SHIELD 81
|
||||
#define XFER_LASER 82
|
||||
//#define SHOW_DAMAGE_POPUP 83 // AL: this binding should be removing next time the controls are reorganized
|
||||
|
||||
TIME_SPEED_UP =102, //!< TIME_SPEED_UP
|
||||
TIME_SLOW_DOWN =103, //!< TIME_SLOW_DOWN
|
||||
#define GLIDE_WHEN_PRESSED 83
|
||||
//Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
|
||||
#define BANK_WHEN_PRESSED 84
|
||||
#define SHOW_NAVMAP 85
|
||||
#define ADD_REMOVE_ESCORT 86
|
||||
#define ESCORT_CLEAR 87
|
||||
#define TARGET_NEXT_ESCORT_SHIP 88
|
||||
|
||||
TOGGLE_HUD_CONTRAST =104, //!< toggle between high and low HUD contrast
|
||||
#define TARGET_CLOSEST_REPAIR_SHIP 89
|
||||
#define TARGET_NEXT_UNINSPECTED_CARGO 90
|
||||
#define TARGET_PREV_UNINSPECTED_CARGO 91
|
||||
#define TARGET_NEWEST_SHIP 92
|
||||
#define TARGET_NEXT_LIVE_TURRET 93
|
||||
#define TARGET_PREV_LIVE_TURRET 94
|
||||
|
||||
MULTI_TOGGLE_NETINFO =105, //!< toggle network info
|
||||
#define TARGET_NEXT_BOMB 95
|
||||
#define TARGET_PREV_BOMB 96
|
||||
|
||||
MULTI_SELF_DESTRUCT =106, //!< self destruct (multiplayer only)
|
||||
// multiplayer messaging keys
|
||||
#define MULTI_MESSAGE_ALL 97
|
||||
#define MULTI_MESSAGE_FRIENDLY 98
|
||||
#define MULTI_MESSAGE_HOSTILE 99
|
||||
#define MULTI_MESSAGE_TARGET 100
|
||||
|
||||
TOGGLE_HUD =107, //!< TOGGLE_HUD
|
||||
RIGHT_SLIDE_THRUST =108, //!< RIGHT_SLIDE_THRUST
|
||||
LEFT_SLIDE_THRUST =109, //!< LEFT_SLIDE_THRUST
|
||||
UP_SLIDE_THRUST =110, //!< UP_SLIDE_THRUST
|
||||
DOWN_SLIDE_THRUST =111, //!< DOWN_SLIDE_THRUST
|
||||
HUD_TARGETBOX_TOGGLE_WIREFRAME =112, //!< HUD_TARGETBOX_TOGGLE_WIREFRAME
|
||||
VIEW_TOPDOWN =113, //!< VIEW_TOPDOWN
|
||||
VIEW_TRACK_TARGET =114, //!< VIEW_TRACK_TARGET
|
||||
// multiplayer misc keys
|
||||
#define MULTI_OBSERVER_ZOOM_TO 101
|
||||
|
||||
//AutoPilot - Kazan
|
||||
AUTO_PILOT_TOGGLE =115, //!< Autopilot key control
|
||||
NAV_CYCLE =116, //!< NAV_CYCLE
|
||||
#define TIME_SPEED_UP 102
|
||||
#define TIME_SLOW_DOWN 103
|
||||
|
||||
//Gliding
|
||||
TOGGLE_GLIDING =117, //!< TOGGLE_GLIDING
|
||||
#define TOGGLE_HUD_CONTRAST 104
|
||||
|
||||
/**
|
||||
* This must always be below the last defined action
|
||||
*/
|
||||
CCFG_MAX //!< The total number of defined control actions (or last define + 1)
|
||||
};
|
||||
#define MULTI_TOGGLE_NETINFO 105
|
||||
|
||||
#define MULTI_SELF_DESTRUCT 106
|
||||
|
||||
#define TOGGLE_HUD 107
|
||||
#define RIGHT_SLIDE_THRUST 108
|
||||
#define LEFT_SLIDE_THRUST 109
|
||||
#define UP_SLIDE_THRUST 110
|
||||
#define DOWN_SLIDE_THRUST 111
|
||||
#define HUD_TARGETBOX_TOGGLE_WIREFRAME 112
|
||||
#define VIEW_TOPDOWN 113
|
||||
#define VIEW_TRACK_TARGET 114
|
||||
|
||||
//AutoPilot - Kazan
|
||||
#define AUTO_PILOT_TOGGLE 115
|
||||
#define NAV_CYCLE 116
|
||||
|
||||
//Gliding
|
||||
#define TOGGLE_GLIDING 117
|
||||
|
||||
// this should be the total number of control action defines above (or last define + 1)
|
||||
#define CCFG_MAX 118
|
||||
|
||||
extern int Failed_key_index;
|
||||
extern int Invert_heading;
|
||||
|
||||
@@ -7,17 +7,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
#include "controlconfig/controlsconfig.h"
|
||||
#include "io/key.h"
|
||||
#include "io/joy.h"
|
||||
#include "localization/localize.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "globalincs/def_files.h"
|
||||
|
||||
|
||||
#define TARGET_TAB 0
|
||||
#define SHIP_TAB 1
|
||||
@@ -289,7 +285,7 @@ char *Joy_button_text_french[] = {
|
||||
"Bouton 13", "Bouton 14", "Bouton 15", "Bouton 16", "Bouton 17", "Bouton 18",
|
||||
"Bouton 19", "Bouton 20", "Bouton 21", "Bouton 22", "Bouton 23", "Bouton 24",
|
||||
"Bouton 25", "Bouton 26", "Bouton 27", "Bouton 28", "Bouton 29", "Bouton 30",
|
||||
"Bouton 31", "Bouton 32", "Chapeau Arriere", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
|
||||
"Bouton 31", "Bouton 32", "Chapeau Arrière", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
|
||||
};
|
||||
|
||||
// This is the text that is displayed on the screen for the keys a player selects
|
||||
@@ -449,48 +445,21 @@ int translate_key_to_index(char *key)
|
||||
// or there is no key current bound to the function, NULL is returned.
|
||||
char *translate_key(char *key)
|
||||
{
|
||||
int index = -1, key_code = -1, joy_code = -1;
|
||||
char *key_text = NULL;
|
||||
char *joy_text = NULL;
|
||||
|
||||
static char text[40] = {"None"};
|
||||
int index = -1, code = -1;
|
||||
|
||||
index = translate_key_to_index(key);
|
||||
if (index < 0) {
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key_code = Control_config[index].key_id;
|
||||
joy_code = Control_config[index].joy_id;
|
||||
|
||||
code = Control_config[index].key_id;
|
||||
Failed_key_index = index;
|
||||
|
||||
if (key_code >= 0) {
|
||||
key_text = textify_scancode(key_code);
|
||||
if (code < 0) {
|
||||
code = Control_config[index].joy_id;
|
||||
if (code >= 0)
|
||||
return Joy_button_text[code];
|
||||
}
|
||||
|
||||
if (joy_code >= 0) {
|
||||
joy_text = Joy_button_text[joy_code];
|
||||
}
|
||||
|
||||
// both key and joystick button are mapped to this control
|
||||
if ((key_code >= 0 ) && (joy_code >= 0) ) {
|
||||
strcpy_s(text, key_text);
|
||||
strcat_s(text, " or ");
|
||||
strcat_s(text, joy_text);
|
||||
}
|
||||
// if we only have one
|
||||
else if (key_code >= 0 ) {
|
||||
strcpy_s(text, key_text);
|
||||
}
|
||||
else if (joy_code >= 0) {
|
||||
strcpy_s(text, joy_text);
|
||||
}
|
||||
else {
|
||||
strcpy_s(text, "None");
|
||||
}
|
||||
|
||||
return text;
|
||||
return textify_scancode(code);
|
||||
}
|
||||
|
||||
char *textify_scancode(int code)
|
||||
@@ -528,12 +497,9 @@ char *textify_scancode(int code)
|
||||
}
|
||||
//XSTR:ON
|
||||
|
||||
void control_config_common_load_overrides();
|
||||
|
||||
// initialize common control config stuff - call at game startup after localization has been initialized
|
||||
void control_config_common_init()
|
||||
{
|
||||
control_config_common_load_overrides();
|
||||
if(Lcl_gr){
|
||||
Scan_code_text = Scan_code_text_german;
|
||||
Joy_button_text = Joy_button_text_german;
|
||||
@@ -551,231 +517,3 @@ void control_config_common_init()
|
||||
Joy_button_text = Joy_button_text_english;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
SCP_map<SCP_string, int> mEnumNameToVal;
|
||||
|
||||
void LoadEnumsIntoMap();
|
||||
void control_config_common_load_overrides()
|
||||
{
|
||||
LoadEnumsIntoMap();
|
||||
|
||||
if (cf_exists_full("controlconfigdefaults.tbl", CF_TYPE_TABLES))
|
||||
read_file_text("controlconfigdefaults.tbl", CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("controlconfigdefaults.tbl"));
|
||||
|
||||
reset_parse();
|
||||
|
||||
// start parsing
|
||||
required_string("#ControlConfigOverride");
|
||||
|
||||
// read fonts
|
||||
while (required_string_either("#End","$Bind Name:"))
|
||||
{
|
||||
const int iBufferLength = 64;
|
||||
char szTempBuffer[iBufferLength];
|
||||
|
||||
required_string("$Bind Name:");
|
||||
stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
|
||||
const size_t cCntrlAryLength = sizeof(Control_config) / sizeof(Control_config[0]);
|
||||
for (size_t i = 0; i < cCntrlAryLength; ++i)
|
||||
{
|
||||
config_item& r_ccConfig = Control_config[i];
|
||||
|
||||
if (!strcmp(szTempBuffer, r_ccConfig.text))
|
||||
{
|
||||
/**
|
||||
* short key_default;
|
||||
* short joy_default;
|
||||
* char tab;
|
||||
* bool hasXSTR;
|
||||
* char type;
|
||||
*/
|
||||
|
||||
int iTemp;
|
||||
|
||||
if (optional_string("$Key Default:"))
|
||||
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.key_default = (short)mEnumNameToVal[szTempBuffer];}
|
||||
|
||||
if (optional_string("$Joy Default:"))
|
||||
{stuff_int(&iTemp); r_ccConfig.joy_default = (short)iTemp;}
|
||||
|
||||
if (optional_string("$Key Mod Shift:"))
|
||||
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_SHIFTED : 0;}
|
||||
|
||||
if (optional_string("$Key Mod Alt:"))
|
||||
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_ALTED : 0;}
|
||||
|
||||
if (optional_string("$Key Mod Ctrl:"))
|
||||
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_CTRLED : 0;}
|
||||
|
||||
if (optional_string("$Category:"))
|
||||
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.tab = (char)mEnumNameToVal[szTempBuffer];}
|
||||
|
||||
if (optional_string("$Has XStr:"))
|
||||
{stuff_int(&iTemp); r_ccConfig.hasXSTR = (iTemp == 1);}
|
||||
|
||||
if (optional_string("$Type:"))
|
||||
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.type = (char)mEnumNameToVal[szTempBuffer];}
|
||||
|
||||
// Nerf the buffer now.
|
||||
szTempBuffer[0] = '\0';
|
||||
}
|
||||
else if ((i + 1) == cCntrlAryLength)
|
||||
{
|
||||
error_display(1, "Bind Name not found: %s\n", szTempBuffer);
|
||||
advance_to_eoln(NULL);
|
||||
ignore_white_space();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
#define ADD_ENUM_TO_ENUM_MAP(Enum) mEnumNameToVal[#Enum] = (Enum);
|
||||
|
||||
void LoadEnumsIntoMap()
|
||||
{
|
||||
mEnumNameToVal["KEY_SHIFTED"] = KEY_SHIFTED;
|
||||
/*
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_SHIFTED)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_ALTED)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_CTRLED)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUGGED)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUGGED1)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_MASK)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUG_KEY)
|
||||
*/
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_0)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_1)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_2)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_3)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_4)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_5)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_6)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_7)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_8)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_9)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_A)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_B)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_C)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_D)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_E)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_G)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_H)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_I)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_J)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_K)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_L)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_M)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_N)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_O)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_P)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_Q)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_R)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_S)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_T)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_U)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_V)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_W)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_X)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_Y)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_Z)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_MINUS)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_EQUAL)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_DIVIDE)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_SLASH)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_SLASH_UK)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_COMMA)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PERIOD)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_SEMICOL)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_LBRACKET)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_RBRACKET)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_RAPOSTRO)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_LAPOSTRO)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_ESC)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_ENTER)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_BACKSP)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_TAB)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_SPACEBAR)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_NUMLOCK)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_SCROLLOCK)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_CAPSLOCK)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_LSHIFT)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_RSHIFT)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_LALT)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_RALT)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_LCTRL)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_RCTRL)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F1)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F2)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F3)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F4)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F5)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F6)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F7)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F8)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F9)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F10)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F11)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_F12)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD0)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD1)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD2)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD3)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD4)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD5)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD6)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD7)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD8)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAD9)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PADMINUS)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PADPLUS)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PADPERIOD)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PADDIVIDE)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PADMULTIPLY)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PADENTER)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_INSERT)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_HOME)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAGEUP)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_DELETE)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_END)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAGEDOWN)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_UP)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_DOWN)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_LEFT)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_RIGHT)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PRINT_SCRN)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_PAUSE)
|
||||
ADD_ENUM_TO_ENUM_MAP(KEY_BREAK)
|
||||
|
||||
ADD_ENUM_TO_ENUM_MAP(TARGET_TAB)
|
||||
ADD_ENUM_TO_ENUM_MAP(SHIP_TAB)
|
||||
ADD_ENUM_TO_ENUM_MAP(WEAPON_TAB)
|
||||
ADD_ENUM_TO_ENUM_MAP(COMPUTER_TAB)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "globalincs/crypt.h"
|
||||
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redfine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *crypt_string;
|
||||
|
||||
if ( argc == 1 ) {
|
||||
printf("Usage: cryptstring <string1> <string2> ...\n");
|
||||
printf("Output will be <crypt1> <crypt2>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for ( i = 1; i < argc; i++ ) {
|
||||
char *s;
|
||||
|
||||
s = argv[i];
|
||||
// if the length of the string is greater than the number of crypted symbols we
|
||||
// return, then pass only the maximum length
|
||||
if ( strlen(s) > CRYPT_STRING_LENGTH )
|
||||
s += (strlen(s) - CRYPT_STRING_LENGTH);
|
||||
|
||||
crypt_string = jcrypt(s);
|
||||
printf("%s\n", crypt_string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *jcrypt (char *plainstring)
|
||||
{
|
||||
int i,t,len;
|
||||
static char cryptstring[CRYPT_STRING_LENGTH + 1];
|
||||
|
||||
len=strlen (plainstring);
|
||||
if (len > CRYPT_STRING_LENGTH)
|
||||
len = CRYPT_STRING_LENGTH;
|
||||
|
||||
for (i = 0;i < len; i++) {
|
||||
cryptstring[i]=0;
|
||||
|
||||
for (t = 0; t < len; t++) {
|
||||
cryptstring[i]^=(plainstring[t] ^ plainstring[i%(t+1)]);
|
||||
cryptstring[i]%=90;
|
||||
cryptstring[i]+=33;
|
||||
}
|
||||
}
|
||||
|
||||
cryptstring[i]=0;
|
||||
return ((char *)cryptstring);
|
||||
}
|
||||
+49
-22
@@ -42,9 +42,13 @@ SCP_vector<cutscene_info> Cutscenes;
|
||||
//extern int All_movies_enabled; // If set, all movies may be viewed. Keyed off cheat code.
|
||||
void cutscene_close()
|
||||
{
|
||||
for(SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut)
|
||||
if(cut->description)
|
||||
vm_free(cut->description);
|
||||
for(size_t i = 0; i < Cutscenes.size(); i++)
|
||||
{
|
||||
if(Cutscenes[i].description)
|
||||
{
|
||||
vm_free(Cutscenes[i].description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialization stuff for cutscenes
|
||||
@@ -106,13 +110,18 @@ void cutscene_init()
|
||||
// returns -1 on failure.
|
||||
int cutscenes_get_cd_num( char *filename )
|
||||
{
|
||||
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut) {
|
||||
if ( !stricmp(cut->filename, filename) ) {
|
||||
return (cut->cd - 1);
|
||||
#if defined(OEM_BUILD)
|
||||
return 0; // only 1 cd for OEM
|
||||
#else
|
||||
|
||||
for (size_t i = 0; i < Cutscenes.size(); i++ ) {
|
||||
if ( !stricmp(Cutscenes[i].filename, filename) ) {
|
||||
return (Cutscenes[i].cd - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
#endif // defined(OEM_BUILD)
|
||||
}
|
||||
|
||||
// marks a cutscene as viewable
|
||||
@@ -132,10 +141,10 @@ void cutscene_mark_viewable(char *filename)
|
||||
|
||||
// change to lower case
|
||||
strlwr(file);
|
||||
int i = 0;
|
||||
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut) {
|
||||
|
||||
for (size_t i = 0; i < Cutscenes.size(); i++ ) {
|
||||
// change the cutscene file name to lower case
|
||||
strcpy_s(cut_file, cut->filename);
|
||||
strcpy_s(cut_file, Cutscenes[i].filename);
|
||||
strlwr(cut_file);
|
||||
|
||||
// see if the stripped filename matches the cutscene filename
|
||||
@@ -143,7 +152,6 @@ void cutscene_mark_viewable(char *filename)
|
||||
Cutscenes_viewable |= (1<<i);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +167,7 @@ void cutscene_mark_viewable(char *filename)
|
||||
#define PLAY_BUTTON 6
|
||||
#define EXIT_BUTTON 7
|
||||
|
||||
static int Num_files;
|
||||
static SCP_vector<int> Cutscene_list;
|
||||
//static int Stats_scroll_offset; // not used - taylor
|
||||
static int Selected_line = 0; // line that is currently selected for binding
|
||||
@@ -253,7 +262,9 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
int cd_mve_is_on;
|
||||
char volume_name[128];
|
||||
|
||||
#ifdef RELEASE_REAL
|
||||
int num_attempts = 0;
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
int path_set_ok;
|
||||
@@ -264,7 +275,12 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(OEM_BUILD)
|
||||
sprintf(volume_name, NOX("FS2_OEM"));
|
||||
#else
|
||||
sprintf(volume_name, NOX("FREESPACE2_%c"), '1' + cd_mve_is_on);
|
||||
#endif
|
||||
|
||||
|
||||
cd_drive_num = find_freespace_cd(volume_name);
|
||||
path_set_ok = set_cdrom_path(cd_drive_num);
|
||||
@@ -274,6 +290,7 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef RELEASE_REAL
|
||||
if ( !prompt_for_cd ) {
|
||||
cd_present = 0;
|
||||
break;
|
||||
@@ -283,7 +300,11 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
char popup_msg[256];
|
||||
int popup_rval;
|
||||
|
||||
#if defined(DVD_MESSAGE_HACK)
|
||||
sprintf(popup_msg, XSTR( "Movie not found\n\nInsert FreeSpace DVD to continue", 203));
|
||||
#else
|
||||
sprintf(popup_msg, XSTR( "Movie not found\n\nInsert FreeSpace CD #%d to continue", 203), cd_mve_is_on+1);
|
||||
#endif
|
||||
|
||||
popup_rval = popup(PF_BODY_BIG, 2, POPUP_CANCEL, POPUP_OK, popup_msg);
|
||||
if ( popup_rval != 1 ) {
|
||||
@@ -295,6 +316,11 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
cd_present = 0;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
cd_present = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return cd_present;
|
||||
@@ -305,7 +331,7 @@ void cutscenes_screen_play()
|
||||
char name[MAX_FILENAME_LEN]; // *full_name
|
||||
int which_cutscene;
|
||||
|
||||
Assert( (Selected_line >= 0) && (Selected_line < (int)Cutscene_list.size()) );
|
||||
Assert( (Selected_line >= 0) && (Selected_line < Num_files) );
|
||||
which_cutscene = Cutscene_list[Selected_line];
|
||||
|
||||
strcpy_s(name, Cutscenes[which_cutscene].filename );
|
||||
@@ -346,7 +372,7 @@ void cutscenes_screen_scroll_line_down()
|
||||
{
|
||||
int h;
|
||||
|
||||
if (Selected_line < (int)Cutscene_list.size() - 1) {
|
||||
if (Selected_line < Num_files - 1) {
|
||||
Selected_line++;
|
||||
gamesnd_play_iface(SND_SCROLL);
|
||||
|
||||
@@ -383,7 +409,7 @@ void cutscenes_screen_scroll_screen_down()
|
||||
int h;
|
||||
|
||||
h = Cutscene_list_coords[gr_screen.res][3] / gr_get_font_height();
|
||||
if (Scroll_offset + h < (int)Cutscene_list.size()) {
|
||||
if (Scroll_offset + h < Num_files) {
|
||||
Scroll_offset++;
|
||||
if (Selected_line < Scroll_offset){
|
||||
Selected_line = Scroll_offset;
|
||||
@@ -481,12 +507,12 @@ void cutscenes_screen_init()
|
||||
// if (All_movies_enabled)
|
||||
// Cutscenes_viewable = 0xffffffff; // Cheat code enables all movies.
|
||||
|
||||
Num_files = 0;
|
||||
Cutscene_list.clear();
|
||||
|
||||
size_t size = Cutscenes.size();
|
||||
for (size_t j=0;j < size;j++) {
|
||||
for (size_t j = 0; j < Cutscenes.size(); j++ ) {
|
||||
if ( Cutscenes_viewable & (1<<j) ) {
|
||||
Cutscene_list.push_back((int)j);
|
||||
Num_files++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,10 +570,11 @@ void cutscenes_screen_do_frame()
|
||||
// the "show-all" hotkey
|
||||
case KEY_CTRLED | KEY_SHIFTED | KEY_S:
|
||||
{
|
||||
Num_files = 0;
|
||||
Cutscene_list.clear();
|
||||
size_t size = Cutscenes.size();
|
||||
for (size_t t = 0; t < size; t++) {
|
||||
for (size_t t = 0; t < Cutscenes.size(); t++) {
|
||||
Cutscene_list.push_back((int)t);
|
||||
Num_files++;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -565,14 +592,14 @@ void cutscenes_screen_do_frame()
|
||||
if (List_region.button_down()) {
|
||||
List_region.get_mouse_pos(NULL, &y);
|
||||
z = Scroll_offset + y / font_height;
|
||||
if ((z >= 0) && (z < (int)Cutscene_list.size()))
|
||||
if ((z >= 0) && (z < Num_files))
|
||||
select_tease_line = z;
|
||||
}
|
||||
|
||||
if (List_region.pressed()) {
|
||||
List_region.get_mouse_pos(NULL, &y);
|
||||
z = Scroll_offset + y / font_height;
|
||||
if ((z >= 0) && (z < (int)Cutscene_list.size()))
|
||||
if ((z >= 0) && (z < Num_files))
|
||||
Selected_line = z;
|
||||
}
|
||||
|
||||
@@ -597,7 +624,7 @@ void cutscenes_screen_do_frame()
|
||||
y = 0;
|
||||
z = Scroll_offset;
|
||||
while (y + font_height <= Cutscene_list_coords[gr_screen.res][3]) {
|
||||
if (z >= (int)Cutscene_list.size()){
|
||||
if (z >= Num_files){
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -639,7 +666,7 @@ void cutscenes_screen_do_frame()
|
||||
y = 0;
|
||||
z = Text_offset;
|
||||
while (y + font_height <= Cutscene_desc_coords[gr_screen.res][3]) {
|
||||
if (z >= Text_size || z >= MAX_TEXT_LINES-1)
|
||||
if (z >= Text_size)
|
||||
break;
|
||||
|
||||
len = Text_line_size[z];
|
||||
|
||||
+112
-28
@@ -10,14 +10,18 @@ extern void *g_vBackBuf1, *g_vBackBuf2;
|
||||
static ushort *backBuf1, *backBuf2;
|
||||
static int lookup_initialized;
|
||||
|
||||
static void dispatchDecoder16(ushort **pFrame, ubyte codeType, ubyte **pData, ubyte **pOffData, int *pDataRemain, int *curXb, int *curYb);
|
||||
static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb);
|
||||
static void genLoopkupTable();
|
||||
|
||||
void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, unsigned char *pData, int dataRemain)
|
||||
void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
|
||||
{
|
||||
ubyte *pOrig, *pOffData, *pEnd, op;
|
||||
unsigned char *pOrig;
|
||||
unsigned char *pOffData, *pEnd;
|
||||
ushort offset;
|
||||
int length = 0, i, j, xb, yb;
|
||||
int length;
|
||||
int op;
|
||||
int i, j;
|
||||
int xb, yb;
|
||||
|
||||
if (!lookup_initialized) {
|
||||
genLoopkupTable();
|
||||
@@ -152,7 +156,21 @@ static void patternRow4Pixels2(ushort *pFrame, unsigned char pat0, ushort *p)
|
||||
unsigned char mask=0x03;
|
||||
unsigned char shift=0;
|
||||
ushort pel;
|
||||
/* ORIGINAL VERSION IS BUGGY
|
||||
int skip=1;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[2] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 2] = pel;
|
||||
pFrame += skip;
|
||||
skip = 4 - skip;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
*/
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
@@ -190,9 +208,10 @@ static void patternQuadrant4Pixels(ushort *pFrame, unsigned char pat0, unsigned
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) >> shift];
|
||||
if ((i&3) == 3) {
|
||||
|
||||
if ((i&3) == 3)
|
||||
pFrame += g_width;
|
||||
}
|
||||
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
@@ -213,6 +232,19 @@ static void patternRow2Pixels2(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
ushort pel;
|
||||
unsigned char mask=0x1;
|
||||
|
||||
/* ORIGINAL VERSION IS BUGGY
|
||||
int skip=1;
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
pFrame[0] = pel;
|
||||
pFrame[2] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 2] = pel;
|
||||
pFrame += skip;
|
||||
skip = 4 - skip;
|
||||
mask <<= 1;
|
||||
}
|
||||
*/
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
|
||||
@@ -234,9 +266,10 @@ static void patternQuadrant2Pixels(ushort *pFrame, unsigned char pat0, unsigned
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) ? 1 : 0];
|
||||
if ((i&3) == 3) {
|
||||
|
||||
if ((i&3) == 3)
|
||||
pFrame += g_width;
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
@@ -255,63 +288,76 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
switch(codeType) {
|
||||
case 0x0:
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
|
||||
break; // ADDED
|
||||
break; // ADDED
|
||||
|
||||
case 0x1:
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
/* relFar(*(*pOffData)++, 1, &x, &y); */
|
||||
|
||||
k = *(*pOffData)++;
|
||||
x = far_p_table[k*2+0];
|
||||
y = far_p_table[k*2+1];
|
||||
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
/* relFar(*(*pOffData)++, -1, &x, &y); */
|
||||
|
||||
k = *(*pOffData)++;
|
||||
x = far_n_table[k*2+0];
|
||||
y = far_n_table[k*2+1];
|
||||
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
/* relClose(*(*pOffData)++, &x, &y); */
|
||||
|
||||
k = *(*pOffData)++;
|
||||
x = close_table[k*2+0];
|
||||
y = close_table[k*2+1];
|
||||
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
x = (char)*(*pData)++;
|
||||
y = (char)*(*pData)++;
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
nprintf(("MVE", "STUB: encoding 6 not tested\n"));
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
*pFrame += 16;
|
||||
|
||||
if (++*curXb == (g_width >> 3)) {
|
||||
*pFrame += 7*g_width;
|
||||
*curXb = 0;
|
||||
if (++*curYb == (g_height >> 3)) {
|
||||
|
||||
if (++*curYb == (g_height >> 3))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
|
||||
if (!((p[0]/*|p[1]*/)&0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
patternRow2Pixels(*pFrame, *(*pData), p);
|
||||
(*pData)++;
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
} else {
|
||||
@@ -320,21 +366,26 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
*pFrame += 2*g_width;
|
||||
patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
|
||||
(*pData)++;
|
||||
|
||||
*pFrame += 2*g_width;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
(*pData) += 2;
|
||||
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
@@ -343,6 +394,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
}
|
||||
} else {
|
||||
p[2] = GETPIXEL(pData, 8);
|
||||
|
||||
if (!(p[2]&0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
if ((i & 1) == 0) {
|
||||
@@ -352,6 +404,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
@@ -366,18 +419,21 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
}
|
||||
patternRow2Pixels(*pFrame, *(*pData), p);
|
||||
(*pData)++;
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
|
||||
*pDataRemain -= 8;
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
if (!(p[2] & 0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
@@ -396,6 +452,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
patternRow4Pixels2(*pFrame, (*pData)[2], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[3], p);
|
||||
|
||||
(*pData) += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
@@ -412,7 +469,9 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
for (i=0; i<4; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
|
||||
(*pData) += 2;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
@@ -421,10 +480,11 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
@@ -435,8 +495,11 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
pat[1] = (*pData)[1];
|
||||
pat[2] = (*pData)[2];
|
||||
pat[3] = (*pData)[3];
|
||||
|
||||
(*pData) += 4;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
@@ -445,6 +508,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
}
|
||||
} else {
|
||||
p[0] = GETPIXEL(pData, 16);
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
if ((i&1) == 0) {
|
||||
@@ -453,12 +517,16 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
}
|
||||
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
pat[2] = (*pData)[2];
|
||||
pat[3] = (*pData)[3];
|
||||
|
||||
(*pData) += 4;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
@@ -473,21 +541,24 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
}
|
||||
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
|
||||
(*pData) += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
for (i=0; i<8; i++) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
ubyte frame_tmp[16];
|
||||
memcpy(&frame_tmp, *pData, 16);
|
||||
|
||||
ushort *swap_tmp;
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
swap_tmp = (ushort*)(frame_tmp + j);
|
||||
@@ -501,7 +572,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
*pData += 16;
|
||||
*pDataRemain -= 16;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
for (i=0; i<4; i++) {
|
||||
@@ -509,61 +580,74 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
|
||||
p[1] = GETPIXEL(pData, 2);
|
||||
p[2] = GETPIXEL(pData, 4);
|
||||
p[3] = GETPIXEL(pData, 6);
|
||||
|
||||
for (j=0; j<2; j++) {
|
||||
for (k=0; k<4; k++) {
|
||||
(*pFrame)[2*k] = p[k];
|
||||
(*pFrame)[2*k+1] = p[k];
|
||||
// (*pFrame)[j+2*k] = p[k];
|
||||
// (*pFrame)[g_width+j+2*k] = p[k];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 8;
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0xd:
|
||||
for (i=0; i<2; i++) {
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 2);
|
||||
|
||||
for (j=0; j<4; j++) {
|
||||
for (k=0; k<4; k++) {
|
||||
(*pFrame)[k*g_width+j] = p[0];
|
||||
(*pFrame)[k*g_width+j+4] = p[1];
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame += 4*g_width;
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*pFrame)[j] = p[0];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 1);
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
(*pFrame)[j] = p[(i+j)&1];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
*pFrame = pDstBak+8;
|
||||
|
||||
+20
-19
@@ -22,35 +22,36 @@ static int audio_exp_table[256] =
|
||||
|
||||
static int getWord(unsigned char **fin)
|
||||
{
|
||||
int value = ((*fin)[1] << 8) | (*fin)[0];
|
||||
*fin += 2;
|
||||
return value;
|
||||
int value = ((*fin)[1] << 8) | (*fin)[0];
|
||||
*fin += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void sendWord(short **fout, int nOffset)
|
||||
{
|
||||
*(*fout)++ = (short)nOffset;
|
||||
*(*fout)++ = nOffset;
|
||||
}
|
||||
|
||||
static void processSwath(short *fout, unsigned char *data, int swath, int *offsets)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<swath; i++) {
|
||||
offsets[i&1] += audio_exp_table[data[i]];
|
||||
sendWord(&fout, offsets[i&1]);
|
||||
}
|
||||
int i;
|
||||
for (i=0; i<swath; i++)
|
||||
{
|
||||
offsets[i&1] += audio_exp_table[data[i]];
|
||||
sendWord(&fout, offsets[i&1]);
|
||||
}
|
||||
}
|
||||
|
||||
void mveaudio_uncompress(short *buffer, unsigned char *data)
|
||||
void mveaudio_uncompress(short *buffer, unsigned char *data, int length)
|
||||
{
|
||||
int nCurOffsets[2];
|
||||
int swath;
|
||||
int nCurOffsets[2];
|
||||
int swath;
|
||||
|
||||
data += 4;
|
||||
swath = getWord(&data) / 2;
|
||||
nCurOffsets[0] = getWord(&data);
|
||||
nCurOffsets[1] = getWord(&data);
|
||||
sendWord(&buffer, nCurOffsets[0]);
|
||||
sendWord(&buffer, nCurOffsets[1]);
|
||||
processSwath(buffer, data, swath, nCurOffsets);
|
||||
data += 4;
|
||||
swath = getWord(&data) / 2;
|
||||
nCurOffsets[0] = getWord(&data);
|
||||
nCurOffsets[1] = getWord(&data);
|
||||
sendWord(&buffer, nCurOffsets[0]);
|
||||
sendWord(&buffer, nCurOffsets[1]);
|
||||
processSwath(buffer, data, swath, nCurOffsets);
|
||||
}
|
||||
+63
-71
@@ -59,7 +59,7 @@ typedef struct MVE_AUDIO_T {
|
||||
mve_audio_t *mas; // mve_audio_stream
|
||||
|
||||
// audio decompressor
|
||||
extern void mveaudio_uncompress(short *buffer, unsigned char *data);
|
||||
extern void mveaudio_uncompress(short *buffer, unsigned char *data, int length);
|
||||
|
||||
// video variables
|
||||
int g_width, g_height;
|
||||
@@ -137,9 +137,8 @@ static void mve_timer_start(void)
|
||||
|
||||
static int mve_do_timer_wait(void)
|
||||
{
|
||||
if (!timer_started) {
|
||||
if (!timer_started)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
int nsec = 0;
|
||||
@@ -148,13 +147,11 @@ static int mve_do_timer_wait(void)
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (tv.tv_sec > timer_expire.tv_sec) {
|
||||
if (tv.tv_sec > timer_expire.tv_sec)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) ) {
|
||||
if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) )
|
||||
goto end;
|
||||
}
|
||||
|
||||
ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
|
||||
ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
|
||||
@@ -173,24 +170,25 @@ static int mve_do_timer_wait(void)
|
||||
}
|
||||
|
||||
end:
|
||||
timer_expire.tv_usec += micro_frame_delay;
|
||||
timer_expire.tv_usec += micro_frame_delay;
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
int tv, ts, ts2;
|
||||
|
||||
tv = timer_get_microseconds();
|
||||
|
||||
if (tv > timer_expire) {
|
||||
if (tv > timer_expire)
|
||||
goto end;
|
||||
}
|
||||
|
||||
ts = timer_expire - tv;
|
||||
|
||||
ts2 = ts/1000;
|
||||
|
||||
Sleep(ts2);
|
||||
|
||||
end:
|
||||
@@ -218,9 +216,8 @@ static void mve_timer_stop()
|
||||
// setup the audio information from the data stream
|
||||
void mve_audio_createbuf(ubyte minor, ubyte *data)
|
||||
{
|
||||
if (audiobuf_created) {
|
||||
if (audiobuf_created)
|
||||
return;
|
||||
}
|
||||
|
||||
// if game sound disabled don't try and play movie audio
|
||||
if (!Sound_enabled) {
|
||||
@@ -228,29 +225,29 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
|
||||
return;
|
||||
}
|
||||
|
||||
int flags, desired_buffer, sample_rate;
|
||||
int flags, desired_buffer, sample_rate;
|
||||
|
||||
mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
|
||||
mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
|
||||
memset(mas, 0, sizeof(mve_audio_t));
|
||||
|
||||
mas->format = AL_INVALID;
|
||||
|
||||
flags = mve_get_ushort(data + 2);
|
||||
sample_rate = mve_get_ushort(data + 4);
|
||||
desired_buffer = mve_get_int(data + 6);
|
||||
flags = mve_get_ushort(data + 2);
|
||||
sample_rate = mve_get_ushort(data + 4);
|
||||
desired_buffer = mve_get_int(data + 6);
|
||||
|
||||
mas->channels = (flags & 0x0001) ? 2 : 1;
|
||||
mas->channels = (flags & 0x0001) ? 2 : 1;
|
||||
mas->bitsize = (flags & 0x0002) ? 16 : 8;
|
||||
|
||||
mas->sample_rate = sample_rate;
|
||||
|
||||
if (minor > 0) {
|
||||
mve_audio_compressed = flags & 0x0004 ? 1 : 0;
|
||||
} else {
|
||||
if (minor > 0) {
|
||||
mve_audio_compressed = flags & 0x0004 ? 1 : 0;
|
||||
} else {
|
||||
mve_audio_compressed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mas->bitsize == 16) {
|
||||
if (mas->bitsize == 16) {
|
||||
if (mas->channels == 2) {
|
||||
mas->format = AL_FORMAT_STEREO16;
|
||||
} else if (mas->channels == 1) {
|
||||
@@ -279,7 +276,7 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
|
||||
|
||||
memset(mas->audio_buffer, 0, MVE_AUDIO_BUFFERS * sizeof(ALuint));
|
||||
|
||||
mve_audio_buffer_tail = 0;
|
||||
mve_audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_created = 1;
|
||||
}
|
||||
@@ -291,9 +288,9 @@ void mve_audio_play()
|
||||
ALint status, bqueued;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return );
|
||||
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return );
|
||||
|
||||
|
||||
mve_audio_playing = 1;
|
||||
|
||||
if (status != AL_PLAYING && bqueued > 0) {
|
||||
@@ -305,9 +302,8 @@ void mve_audio_play()
|
||||
// call this in shutdown to stop and close audio
|
||||
static void mve_audio_stop()
|
||||
{
|
||||
if (!audiobuf_created) {
|
||||
if (!audiobuf_created)
|
||||
return;
|
||||
}
|
||||
|
||||
ALint p = 0;
|
||||
|
||||
@@ -347,15 +343,13 @@ int mve_audio_data(ubyte major, ubyte *data)
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &bprocessed), return 0 );
|
||||
|
||||
while (bprocessed-- > 2) {
|
||||
while (bprocessed-- > 2)
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, 1, &bid) );
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return 0 );
|
||||
|
||||
if (bqueued == 0) {
|
||||
|
||||
if (bqueued == 0)
|
||||
mprintf(("MVE: Buffer underun (First is normal)\n"));
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return 0 );
|
||||
|
||||
@@ -368,34 +362,37 @@ int mve_audio_data(ubyte major, ubyte *data)
|
||||
|
||||
/* HACK: +4 mveaudio_uncompress adds 4 more bytes */
|
||||
if (major == 8) {
|
||||
if (mve_audio_compressed) {
|
||||
if (mve_audio_compressed) {
|
||||
nsamp += 4;
|
||||
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
mveaudio_uncompress(buf, data); /* XXX */
|
||||
mveaudio_uncompress(buf, data, -1); /* XXX */
|
||||
} else {
|
||||
nsamp -= 8;
|
||||
data += 8;
|
||||
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
memcpy(buf, data, nsamp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
|
||||
memset(buf, 0, nsamp); /* XXX */
|
||||
}
|
||||
|
||||
|
||||
if (!mas->audio_buffer[mve_audio_buffer_tail]) {
|
||||
OpenAL_ErrorCheck( alGenBuffers(1,&mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0; } );
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alBufferData(mas->audio_buffer[mve_audio_buffer_tail], mas->format, buf, nsamp, mas->sample_rate), { vm_free(buf); return 0; } );
|
||||
|
||||
|
||||
OpenAL_ErrorCheck( alSourceQueueBuffers(mas->source_id, 1, &mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0;} );
|
||||
|
||||
//fprintf(stderr,"Queued buffer %d(%d)\n", mve_audio_buftail, mas->audio_buffer[mve_audio_buftail]);
|
||||
|
||||
if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS) {
|
||||
if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS)
|
||||
mve_audio_buffer_tail = 0;
|
||||
}
|
||||
|
||||
bqueued++;
|
||||
vm_free(buf);
|
||||
@@ -414,9 +411,8 @@ int mve_audio_data(ubyte major, ubyte *data)
|
||||
|
||||
int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
{
|
||||
if (videobuf_created) {
|
||||
if (videobuf_created)
|
||||
return 1;
|
||||
}
|
||||
|
||||
short w, h;
|
||||
short count, truecolor;
|
||||
@@ -446,11 +442,11 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (truecolor) {
|
||||
if (truecolor)
|
||||
g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
|
||||
} else {
|
||||
else
|
||||
g_vBackBuf2 = (ubyte *)g_vBackBuf1 + (g_width * g_height);
|
||||
}
|
||||
|
||||
memset(g_vBackBuf1, 0, g_width * g_height * 4);
|
||||
|
||||
g_truecolor = truecolor;
|
||||
@@ -462,11 +458,10 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
|
||||
float movie_ratio = (float)g_width / (float)g_height;
|
||||
|
||||
if (screen_ratio > movie_ratio) {
|
||||
if (screen_ratio > movie_ratio)
|
||||
scale_by = (float)gr_screen.max_h / (float)g_height;
|
||||
} else {
|
||||
else
|
||||
scale_by = (float)gr_screen.max_w / (float)g_width;
|
||||
}
|
||||
|
||||
// don't bother setting anything if we aren't going to need it
|
||||
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
|
||||
@@ -512,26 +507,26 @@ static void mve_convert_and_draw()
|
||||
ubyte r, g, b;
|
||||
ushort bit_16;
|
||||
|
||||
if (g_truecolor) {
|
||||
if (g_truecolor)
|
||||
pSrcs = pixels;
|
||||
} else {
|
||||
else
|
||||
pSrcs8 = pixels8;
|
||||
}
|
||||
|
||||
pDests = pixelbuf;
|
||||
|
||||
if (gr_screen.mode != GR_OPENGL) {
|
||||
if (g_screenWidth > g_width) {
|
||||
if (g_screenWidth > g_width)
|
||||
pDests += ((g_screenWidth - g_width) / 2) / 2;
|
||||
}
|
||||
if (g_screenHeight > g_height) {
|
||||
|
||||
if (g_screenHeight > g_height)
|
||||
pDests += ((g_screenHeight - g_height) / 2) * g_screenWidth;
|
||||
}
|
||||
}
|
||||
|
||||
for (y=0; y<g_height; y++) {
|
||||
for (x = 0; x < g_width; x++) {
|
||||
if (g_truecolor) {
|
||||
Assert( pSrcs != NULL );
|
||||
|
||||
pDests[x] = (1<<15)|*pSrcs;
|
||||
pSrcs++;
|
||||
} else {
|
||||
@@ -626,9 +621,8 @@ void mve_video_display()
|
||||
|
||||
int mve_video_init(ubyte *data)
|
||||
{
|
||||
if (video_inited) {
|
||||
if (video_inited)
|
||||
return 1;
|
||||
}
|
||||
|
||||
short width, height;
|
||||
|
||||
@@ -674,10 +668,8 @@ int mve_video_init(ubyte *data)
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
GL_state.Texture.SetWrapS(GL_CLAMP_TO_EDGE);
|
||||
GL_state.Texture.SetWrapT(GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB5_A1, wp2, hp2, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
||||
@@ -687,8 +679,9 @@ int mve_video_init(ubyte *data)
|
||||
}
|
||||
|
||||
memset(g_palette, 0, 768);
|
||||
|
||||
video_inited = 1;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -728,11 +721,10 @@ void mve_video_data(ubyte *data, int len)
|
||||
g_vBackBuf2 = temp;
|
||||
}
|
||||
|
||||
if (g_truecolor) {
|
||||
if (g_truecolor)
|
||||
decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
} else {
|
||||
else
|
||||
decodeFrame8((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
}
|
||||
}
|
||||
|
||||
void mve_end_chunk()
|
||||
@@ -761,9 +753,8 @@ void mve_play(MVESTREAM *mve)
|
||||
int init_timer = 0, timer_error = 0;
|
||||
int cont = 1;
|
||||
|
||||
if (!timer_started) {
|
||||
if (!timer_started)
|
||||
mve_timer_start();
|
||||
}
|
||||
|
||||
while (cont && mve_playing && !timer_error) {
|
||||
cont = mve_play_next_chunk(mve);
|
||||
@@ -802,5 +793,6 @@ void mve_shutdown()
|
||||
}
|
||||
|
||||
mve_audio_stop();
|
||||
|
||||
mve_timer_stop();
|
||||
}
|
||||
+34
-176
@@ -10,7 +10,6 @@
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/def_files.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
@@ -43,9 +42,6 @@ static int g_screenX = 0;
|
||||
static int g_screenY = 0;
|
||||
|
||||
static GLuint GLtex = 0;
|
||||
static GLuint ytex = 0;
|
||||
static GLuint utex = 0;
|
||||
static GLuint vtex = 0;
|
||||
static GLint gl_screenYH = 0;
|
||||
static GLint gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
@@ -78,7 +74,7 @@ static int audiofd_fragsize = 0;
|
||||
static longlong videobuf_granulepos = -1;
|
||||
static double videobuf_time = 0;
|
||||
|
||||
static bool use_shaders = true;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utility items
|
||||
//
|
||||
@@ -86,8 +82,8 @@ static bool use_shaders = true;
|
||||
// helper; just grab some more compressed bitstream and sync it for page extraction
|
||||
static int OGG_buffer_data(THEORAFILE *movie)
|
||||
{
|
||||
char *buffer = ogg_sync_buffer(&movie->osyncstate, 8192); // Doubled read size to fix choppy audio with high bitrate movies - Valathil
|
||||
int bytes = cfread(buffer, 1, 8192, movie->cfp);
|
||||
char *buffer = ogg_sync_buffer(&movie->osyncstate, 4096);
|
||||
int bytes = cfread(buffer, 1, 4096, movie->cfp);
|
||||
|
||||
ogg_sync_wrote(&movie->osyncstate, bytes);
|
||||
|
||||
@@ -330,8 +326,6 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
{
|
||||
float scale_by = 0.0f;
|
||||
|
||||
GLhandleARB shader_id = 0;
|
||||
|
||||
if (video_inited)
|
||||
return;
|
||||
|
||||
@@ -345,137 +339,33 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
opengl_set_texture_target(GL_TEXTURE_2D);
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
if(!Use_GLSL)
|
||||
use_shaders = false;
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
if(use_shaders) {
|
||||
glGenTextures(1, &ytex);
|
||||
glGenTextures(1, &utex);
|
||||
glGenTextures(1, &vtex);
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
Assert( ytex != 0 );
|
||||
Assert( utex != 0 );
|
||||
Assert( vtex != 0 );
|
||||
|
||||
|
||||
if ( ytex + utex + vtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
char *vert = NULL, *frag = NULL;
|
||||
opengl_shader_t new_shader;
|
||||
|
||||
// choose appropriate files
|
||||
char *vert_name = "video-v.sdr";
|
||||
char *frag_name = "video-f.sdr";
|
||||
|
||||
mprintf(("Compiling video-processing shader ... \n"));
|
||||
|
||||
// read vertex shader
|
||||
CFILE *cf_shader = cfopen(vert_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
vert = (char*) vm_malloc(len + 1);
|
||||
cfread(vert, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
} else {
|
||||
mprintf((" Loading built-in default shader for: %s\n", vert_name));
|
||||
vert = defaults_get_file(vert_name);
|
||||
}
|
||||
|
||||
if(!vert)
|
||||
use_shaders = false;
|
||||
|
||||
// read fragment shader
|
||||
cf_shader = cfopen(frag_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
frag = (char*) vm_malloc(len + 1);
|
||||
cfread(frag, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
} else {
|
||||
mprintf((" Loading built-in default shader for: %s\n", frag_name));
|
||||
frag = defaults_get_file(frag_name);
|
||||
}
|
||||
|
||||
if(!vert)
|
||||
use_shaders = false;
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
|
||||
shader_id = opengl_shader_create(vert, frag);
|
||||
vglUseProgramObjectARB(shader_id);
|
||||
if (!shader_id)
|
||||
use_shaders = false;
|
||||
}
|
||||
|
||||
if(!use_shaders) {
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
if(!use_shaders) {
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
|
||||
GL_state.SetTextureSource(TEXTURE_SOURCE_DECAL);
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
if(use_shaders) {
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(ytex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 2048, 2048, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||
GL_state.Texture.SetWrapS(GL_CLAMP_TO_EDGE);
|
||||
GL_state.Texture.SetWrapT(GL_CLAMP_TO_EDGE);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(utex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(2);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(vtex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
|
||||
float movie_ratio = (float)g_screenWidth / (float)g_screenHeight;
|
||||
|
||||
@@ -498,17 +388,15 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
if(!use_shaders) {
|
||||
pixelbuf = (ubyte *) vm_malloc_q(g_screenWidth * g_screenHeight * 3);
|
||||
pixelbuf = (ubyte *) vm_malloc_q(g_screenWidth * g_screenHeight * 3);
|
||||
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
memset( pixelbuf, 0, g_screenWidth * g_screenHeight * 3 );
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
memset( pixelbuf, 0, g_screenWidth * g_screenHeight * 3 );
|
||||
|
||||
if (scale_video) {
|
||||
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_screenWidth) / 2);
|
||||
@@ -526,19 +414,8 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
|
||||
gl_screenU = i2fl(g_screenWidth) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_screenHeight) / i2fl(hp2);
|
||||
}
|
||||
|
||||
if(use_shaders) {
|
||||
gl_screenU = i2fl(tinfo->frame_width-1) / i2fl(2048) ;
|
||||
gl_screenV = i2fl(tinfo->frame_height-1) / i2fl(2048);
|
||||
GL_state.Texture.SetShaderMode(GL_TRUE);
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "ytex"), 0 );
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "utex"), 1 );
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "vtex"), 2 );
|
||||
}
|
||||
}
|
||||
if(!use_shaders && tinfo->frame_height > 450) {
|
||||
mprintf(("VIDEO: No shader support and hd video is beeing played this can get choppy."));
|
||||
}
|
||||
video_inited = 1;
|
||||
}
|
||||
|
||||
@@ -555,23 +432,12 @@ static void OGG_video_close()
|
||||
}
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
if(use_shaders) {
|
||||
GL_state.Texture.Delete(ytex);
|
||||
GL_state.Texture.Delete(utex);
|
||||
GL_state.Texture.Delete(vtex);
|
||||
glDeleteTextures(1, &ytex);
|
||||
glDeleteTextures(1, &utex);
|
||||
glDeleteTextures(1, &vtex);
|
||||
} else {
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
}
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
|
||||
opengl_set_texture_target();
|
||||
|
||||
ytex = utex = vtex = 0;
|
||||
GLtex = 0;
|
||||
GL_state.Texture.SetShaderMode(GL_FALSE);
|
||||
opengl_shader_set_current( 0 );
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
@@ -587,6 +453,7 @@ static void OGG_video_close()
|
||||
g_screenX = 0;
|
||||
g_screenY = 0;
|
||||
|
||||
GLtex = 0;
|
||||
gl_screenYH = 0;
|
||||
gl_screenXW = 0;
|
||||
gl_screenU = 0;
|
||||
@@ -661,25 +528,16 @@ static void convert_YUV_to_RGB(yuv_buffer *yuv)
|
||||
}
|
||||
}
|
||||
|
||||
extern int Mouse_hidden;
|
||||
static void OGG_video_draw(theora_state *tstate)
|
||||
{
|
||||
yuv_buffer yuv;
|
||||
|
||||
theora_decode_YUVout(tstate, &yuv);
|
||||
if(!use_shaders)
|
||||
convert_YUV_to_RGB(&yuv);
|
||||
convert_YUV_to_RGB(&yuv);
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
if(use_shaders) {
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.y_stride, yuv.y_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.y);
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.u);
|
||||
GL_state.Texture.SetActiveUnit(2);
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.v);
|
||||
} else {
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
|
||||
}
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(g_screenX, g_screenY);
|
||||
@@ -694,7 +552,7 @@ static void OGG_video_draw(theora_state *tstate)
|
||||
glVertex2i(gl_screenXW, g_screenY);
|
||||
glEnd();
|
||||
}
|
||||
Mouse_hidden = 1;
|
||||
|
||||
gr_flip();
|
||||
os_poll();
|
||||
|
||||
|
||||
@@ -495,4 +495,7 @@ const char *dds_error_string(int code)
|
||||
default:
|
||||
return "Abort, retry, fail?";
|
||||
}
|
||||
|
||||
//get a warning otherwise
|
||||
return "Abort, retry, fail?";
|
||||
}
|
||||
+134
-96
@@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "debris/debris.h"
|
||||
#include "render/3d.h"
|
||||
#include "fireball/fireballs.h"
|
||||
@@ -27,14 +28,17 @@
|
||||
#include "network/multi.h"
|
||||
#include "network/multimsgs.h"
|
||||
#include "network/multiutil.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_LIFE 10.0f
|
||||
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
|
||||
#define DEBRIS_SOUND_DELAY 2000 // time to start debris sound after created
|
||||
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES // limit the number of hull debris chunks that can exist.
|
||||
|
||||
// limit the number of hull debris chunks that can exist.
|
||||
//#define MAX_HULL_PIECES 10
|
||||
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES //-WMCD
|
||||
int Num_hull_pieces; // number of hull pieces in existance
|
||||
debris Hull_debris_list; // head of linked list for hull debris chunks, for quick search
|
||||
|
||||
@@ -54,10 +58,13 @@ int Debris_num_submodels = 0;
|
||||
#define MAX_SPEED_SMALL_DEBRIS 200 // maximum velocity of small debris piece
|
||||
#define MAX_SPEED_BIG_DEBRIS 150 // maximum velocity of big debris piece
|
||||
#define MAX_SPEED_CAPITAL_DEBRIS 100 // maximum velocity of capital debris piece
|
||||
//#define DEBRIS_SPEED_DEBUG
|
||||
|
||||
/**
|
||||
* Start the sequence of a piece of debris writhing in unholy agony!!!
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_start_death_roll()
|
||||
//
|
||||
// Start the sequence of a piece of debris writhing in unholy agony!!!
|
||||
//
|
||||
static void debris_start_death_roll(object *debris_obj, debris *debris_p)
|
||||
{
|
||||
if (debris_p->is_hull) {
|
||||
@@ -79,11 +86,14 @@ static void debris_start_death_roll(object *debris_obj, debris *debris_p)
|
||||
}
|
||||
|
||||
debris_obj->flags |= OF_SHOULD_BE_DEAD;
|
||||
// demo_do_flag_dead(OBJ_INDEX(debris_obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* This will get called at the start of each level.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_init()
|
||||
//
|
||||
// This will get called at the start of each level.
|
||||
//
|
||||
void debris_init()
|
||||
{
|
||||
int i;
|
||||
@@ -107,9 +117,7 @@ void debris_init()
|
||||
list_init(&Hull_debris_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page in debris bitmaps at level load
|
||||
*/
|
||||
// Page in debris bitmaps at level load
|
||||
void debris_page_in()
|
||||
{
|
||||
uint i;
|
||||
@@ -143,9 +151,10 @@ void debris_page_in()
|
||||
MONITOR(NumSmallDebrisRend)
|
||||
MONITOR(NumHullDebrisRend)
|
||||
|
||||
/**
|
||||
* Render debris
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_render()
|
||||
//
|
||||
//
|
||||
void debris_render(object * obj)
|
||||
{
|
||||
int i, num, swapped;
|
||||
@@ -201,9 +210,7 @@ void debris_render(object * obj)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed the ::DEBRIS_EXPIRE flag, and remove item from ::Hull_debris_list
|
||||
*/
|
||||
// Removed the DEBRIS_EXPIRE flag, and remove item from Hull_debris_list
|
||||
void debris_clear_expired_flag(debris *db)
|
||||
{
|
||||
if ( db->flags & DEBRIS_EXPIRE ) {
|
||||
@@ -216,11 +223,12 @@ void debris_clear_expired_flag(debris *db)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the debris object.
|
||||
* This is only ever called via obj_delete(). Do not call directly.
|
||||
* Use debris_start_death_roll() if you want to force a debris piece to die.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_delete()
|
||||
//
|
||||
// Delete the debris object. This is only ever called via obj_delete(). Do not call directly.
|
||||
// Use debris_start_death_roll() if you want to force a debris piece to die.
|
||||
//
|
||||
void debris_delete( object * obj )
|
||||
{
|
||||
int num;
|
||||
@@ -240,11 +248,9 @@ void debris_delete( object * obj )
|
||||
Num_debris_pieces--;
|
||||
}
|
||||
|
||||
/**
|
||||
* If debris piece *db is far away from all players, make it go away very soon.
|
||||
* In single player game, delete if MAX_DEBRIS_DIST from player.
|
||||
* In multiplayer game, delete if MAX_DEBRIS_DIST from all players.
|
||||
*/
|
||||
// If debris piece *db is far away from all players, make it go away very soon.
|
||||
// In single player game, delete if MAX_DEBRIS_DIST from player.
|
||||
// In multiplayer game, delete if MAX_DEBRIS_DIST from all players.
|
||||
void maybe_delete_debris(debris *db)
|
||||
{
|
||||
object *objp;
|
||||
@@ -269,16 +275,24 @@ void maybe_delete_debris(debris *db)
|
||||
}
|
||||
}
|
||||
|
||||
// broke debris_move into debris_process_pre and debris_process_post as was done with all
|
||||
// *_move functions on 8/13 by MK and MA.
|
||||
void debris_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}
|
||||
|
||||
MONITOR(NumSmallDebris)
|
||||
MONITOR(NumHullDebris)
|
||||
|
||||
/**
|
||||
* Do various updates to debris: check if time to die, start fireballs
|
||||
* Maybe delete debris if it's very far away from player.
|
||||
*
|
||||
* @param obj pointer to debris object
|
||||
* @param frame_time time elapsed since last debris_move() called
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_process_post()
|
||||
//
|
||||
// Do various updates to debris: check if time to die, start fireballs
|
||||
//
|
||||
// parameters: obj => pointer to debris object
|
||||
// frame_time => time elapsed since last debris_move() called
|
||||
//
|
||||
// Maybe delete debris if it's very far away from player.
|
||||
void debris_process_post(object * obj, float frame_time)
|
||||
{
|
||||
int i, num;
|
||||
@@ -314,7 +328,10 @@ void debris_process_post(object * obj, float frame_time)
|
||||
return; // If arc_frequency <= 0, this piece has no arcs on it
|
||||
}
|
||||
|
||||
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
|
||||
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
|
||||
|
||||
// start the next fireball up in the next 50 - 100 ms
|
||||
//db->next_fireball = timestamp_rand(60,80);
|
||||
|
||||
db->next_fireball = timestamp_rand(db->arc_frequency,db->arc_frequency*2 );
|
||||
db->arc_frequency += 100;
|
||||
@@ -335,7 +352,7 @@ void debris_process_post(object * obj, float frame_time)
|
||||
// Create the spark effects
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
if ( !timestamp_valid( db->arc_timestamp[i] ) ) {
|
||||
|
||||
//db->arc_timestamp[i] = timestamp_rand(400,1000); // live up to a second
|
||||
db->arc_timestamp[i] = timestamp(lifetime); // live up to a second
|
||||
|
||||
switch( n ) {
|
||||
@@ -387,7 +404,11 @@ void debris_process_post(object * obj, float frame_time)
|
||||
// 0.10 second effect
|
||||
snd_play_3d( &Snds[SND_DEBRIS_ARC_01], &snd_pos, &View_position, obj->radius );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
@@ -406,12 +427,15 @@ void debris_process_post(object * obj, float frame_time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate the oldest hull debris chunk. Search through the ::Hull_debris_list, which is a list
|
||||
* of all the hull debris chunks.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_find_oldest()
|
||||
//
|
||||
// Locate the oldest hull debris chunk. Search through the Hull_debris_list, which is a list
|
||||
// of all the hull debris chunks.
|
||||
//
|
||||
int debris_find_oldest()
|
||||
{
|
||||
int oldest_index;
|
||||
@@ -433,18 +457,13 @@ int debris_find_oldest()
|
||||
|
||||
#define DEBRIS_ROTVEL_SCALE 5.0f
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *min, vec3d *max );
|
||||
|
||||
/**
|
||||
* Create debris from an object
|
||||
*
|
||||
* @param source_obj Source object
|
||||
* @param model_num Model number
|
||||
* @param submodel_num Sub-model number
|
||||
* @param pos Position in vector space
|
||||
* @param exp_center Explosion center in vector space
|
||||
* @param hull_flag Hull flag settings
|
||||
* @param exp_force Explosion force, used to assign velocity to pieces. 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_create()
|
||||
//
|
||||
// Create debris from an object
|
||||
//
|
||||
// exp_force: Explosion force, used to assign velocity to pieces.
|
||||
// 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
|
||||
object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force)
|
||||
{
|
||||
int i, n, objnum, parent_objnum;
|
||||
@@ -471,6 +490,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
dist /= 2.0f;
|
||||
}
|
||||
if ( dist > 200.0f ) {
|
||||
//mprintf(( "Not creating debris that is %.1f m away\n", dist ));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -560,6 +580,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
db->arc_timestamp[i] = timestamp(-1);
|
||||
// vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
|
||||
}
|
||||
|
||||
if ( db->is_hull ) {
|
||||
@@ -613,6 +634,8 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
obj->net_signature = multi_get_next_network_signature( MULTI_SIG_DEBRIS );
|
||||
}
|
||||
|
||||
// -- No long need shield: bset_shield_strength(obj, 100.0f); // Hey! Set to some meaningful value!
|
||||
|
||||
if (source_obj->type == OBJ_SHIP) {
|
||||
obj->hull_strength = Ships[source_obj->instance].ship_max_hull_strength/8.0f;
|
||||
} else
|
||||
@@ -685,8 +708,14 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_copy_scale(&radial_vel, &to_center, scale );
|
||||
}
|
||||
|
||||
// MK: This next line causes debris pieces to get between 50% and 100% of the parent ship's
|
||||
// velocity. What would be very cool is if the rotational velocity of the parent would become
|
||||
// translational velocity of the debris piece. This would be based on the location of the debris
|
||||
// piece in the parent object.
|
||||
|
||||
// DA: here we need to vel_from_rot = w x to_center, where w is world is unrotated to world coords and offset is the
|
||||
// displacement fromt the center of the parent object to the center of the debris piece
|
||||
|
||||
vec3d world_rotvel, vel_from_rotvel;
|
||||
vm_vec_unrotate ( &world_rotvel, &source_obj->phys_info.rotvel, &source_obj->orient );
|
||||
vm_vec_crossprod ( &vel_from_rotvel, &world_rotvel, &to_center );
|
||||
@@ -695,7 +724,10 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
|
||||
vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
|
||||
|
||||
// make sure rotational velocity does not get too high
|
||||
// vm_vec_scale_add(&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel, frand()/2.0f + 0.5f);
|
||||
// nprintf(("Andsager","object vel from rotvel: %0.2f, %0.2f, %0.2f\n",vel_from_rotvel.x, vel_from_rotvel.y, vel_from_rotvel.z));
|
||||
|
||||
// make sure rotational velocity does not get too high
|
||||
if (radius < 1.0) {
|
||||
radius = 1.0f;
|
||||
}
|
||||
@@ -723,20 +755,29 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_zero(&pi->max_vel); // make so he can't turn on his own VOLITION anymore.
|
||||
vm_vec_zero(&pi->max_rotvel); // make so he can't change speed on his own VOLITION anymore.
|
||||
|
||||
|
||||
// ensure vel is valid
|
||||
Assert( !vm_is_vec_nan(&obj->phys_info.vel) );
|
||||
|
||||
// if ( hull_flag ) {
|
||||
// vm_vec_zero(&pi->vel);
|
||||
// vm_vec_zero(&pi->rotvel);
|
||||
// }
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
|
||||
* can do something about it.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_hit()
|
||||
//
|
||||
// Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
|
||||
// can do something about it.
|
||||
//
|
||||
void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float damage)
|
||||
{
|
||||
debris *debris_p = &Debris[debris_obj->instance];
|
||||
|
||||
|
||||
// Do a little particle spark shower to show we hit
|
||||
{
|
||||
particle_emitter pe;
|
||||
@@ -785,11 +826,13 @@ void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float dama
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if poor debris object *obj got whacked by evil *other_obj at point *hitpos.
|
||||
* NOTE: debris_hit_info pointer NULL for debris:weapon collision, otherwise debris:ship collision.
|
||||
* @return true if hit, else return false.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_check_collision()
|
||||
//
|
||||
// See if poor debris object *obj got whacked by evil *other_obj at point *hitpos.
|
||||
// NOTE: debris_hit_info pointer NULL for debris:weapon collision, otherwise debris:ship collision.
|
||||
// Return true if hit, else return false.
|
||||
//
|
||||
int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, collision_info_struct *debris_hit_info)
|
||||
{
|
||||
mc_info mc;
|
||||
@@ -806,7 +849,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
if ( debris_hit_info == NULL ) {
|
||||
// debris weapon collision
|
||||
Assert( other_obj->type == OBJ_WEAPON );
|
||||
mc.model_instance_num = -1;
|
||||
mc.model_num = Debris[num].model_num; // Fill in the model to check
|
||||
mc.submodel_num = Debris[num].submodel_num;
|
||||
model_clear_instance( mc.model_num );
|
||||
@@ -820,10 +862,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
*hitpos = mc.hit_point_world;
|
||||
}
|
||||
|
||||
weapon *wp = &Weapons[other_obj->instance];
|
||||
wp->collisionOccured = true;
|
||||
wp->collisionInfo = mc_info(mc);
|
||||
|
||||
return mc.num_hits;
|
||||
}
|
||||
|
||||
@@ -866,7 +904,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
int mc_ret_val = 0;
|
||||
|
||||
if ( debris_hit_info->heavy == ship_obj ) { // ship is heavier, so debris is sphere. Check sphere collision against ship poly model
|
||||
mc.model_instance_num = Ships[ship_obj->instance].model_instance_num;
|
||||
mc.model_num = Ship_info[Ships[ship_obj->instance].ship_info_index].model_num; // Fill in the model to check
|
||||
mc.orient = &ship_obj->orient; // The object's orient
|
||||
mc.radius = pdebris->radius;
|
||||
@@ -881,9 +918,9 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
// first test against the sphere - if this fails then don't do any submodel tests
|
||||
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
|
||||
|
||||
SCP_vector<int> submodel_vector;
|
||||
int submodel_list[MAX_ROTATING_SUBMODELS];
|
||||
int num_rotating_submodels = 0;
|
||||
polymodel *pm;
|
||||
polymodel_instance *pmi;
|
||||
|
||||
ship_model_start(ship_obj);
|
||||
|
||||
@@ -894,43 +931,42 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
// Do collision the cool new way
|
||||
if ( debris_hit_info->collide_rotate ) {
|
||||
SCP_vector<int>::iterator smv;
|
||||
|
||||
// We collide with the sphere, find the list of rotating submodels and test one at a time
|
||||
model_get_rotating_submodel_list(&submodel_vector, heavy_obj);
|
||||
model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj);
|
||||
|
||||
// Get polymodel and turn off all rotating submodels, collide against only 1 at a time.
|
||||
pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num);
|
||||
pmi = model_get_instance(Ships[heavy_obj->instance].model_instance_num);
|
||||
|
||||
// turn off all rotating submodels and test for collision
|
||||
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
|
||||
pmi->submodel[*smv].collision_checked = true;
|
||||
int i;
|
||||
for (i=0; i<num_rotating_submodels; i++) {
|
||||
pm->submodel[submodel_list[i]].blown_off = 1;
|
||||
}
|
||||
|
||||
// reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE
|
||||
mc.flags = copy_flags | MC_SUBMODEL_INSTANCE;
|
||||
|
||||
// check each submodel in turn
|
||||
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
|
||||
for (i=0; i<num_rotating_submodels; i++) {
|
||||
// turn on submodel for collision test
|
||||
pmi->submodel[*smv].collision_checked = false;
|
||||
pm->submodel[submodel_list[i]].blown_off = 0;
|
||||
|
||||
// set angles for last frame (need to set to prev to get p0)
|
||||
angles copy_angles = pmi->submodel[*smv].angs;
|
||||
angles copy_angles = pm->submodel[submodel_list[i]].angs;
|
||||
|
||||
// find the start and end positions of the sphere in submodel RF
|
||||
pmi->submodel[*smv].angs = pmi->submodel[*smv].prev_angs;
|
||||
world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, *smv, &heavy_obj->last_orient, &heavy_obj->last_pos);
|
||||
pm->submodel[submodel_list[i]].angs = pm->submodel[submodel_list[i]].sii->prev_angs;
|
||||
world_find_model_point(&p0, &light_obj->last_pos, pm, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos);
|
||||
|
||||
pmi->submodel[*smv].angs = copy_angles;
|
||||
world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, *smv, &heavy_obj->orient, &heavy_obj->pos);
|
||||
pm->submodel[submodel_list[i]].angs = copy_angles;
|
||||
world_find_model_point(&p1, &light_obj->pos, pm, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos);
|
||||
|
||||
mc.p0 = &p0;
|
||||
mc.p1 = &p1;
|
||||
// mc.pos = zero // in submodel RF
|
||||
|
||||
mc.orient = &vmd_identity_matrix;
|
||||
mc.submodel_num = *smv;
|
||||
mc.submodel_num = submodel_list[i];
|
||||
|
||||
if ( model_collide(&mc) ) {
|
||||
if ( mc.hit_dist < debris_hit_info->hit_time ) {
|
||||
@@ -938,23 +974,24 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
// set up debris_hit_info common
|
||||
set_hit_struct_info(debris_hit_info, &mc, SUBMODEL_ROT_HIT);
|
||||
model_instance_find_world_point(&debris_hit_info->hit_pos, &mc.hit_point, mc.model_num, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
|
||||
model_find_world_point(&debris_hit_info->hit_pos, &mc.hit_point, mc.model_num, mc.hit_submodel, &heavy_obj->orient, &zero);
|
||||
|
||||
// set up debris_hit_info for rotating submodel
|
||||
if (debris_hit_info->edge_hit == 0) {
|
||||
model_instance_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
|
||||
model_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
|
||||
}
|
||||
|
||||
// find position in submodel RF of light object at collison
|
||||
vec3d int_light_pos, diff;
|
||||
vm_vec_sub(&diff, mc.p1, mc.p0);
|
||||
vm_vec_scale_add(&int_light_pos, mc.p0, &diff, mc.hit_dist);
|
||||
model_instance_find_world_point(&debris_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_num, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
|
||||
model_find_world_point(&debris_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_num, mc.hit_submodel, &heavy_obj->orient, &zero);
|
||||
}
|
||||
}
|
||||
// Don't look at this submodel again
|
||||
pmi->submodel[*smv].collision_checked = true;
|
||||
pm->submodel[submodel_list[i]].blown_off = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Recover and do usual ship_ship collision, but without rotating submodels
|
||||
@@ -973,7 +1010,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
// get collision normal if not edge hit
|
||||
if (debris_hit_info->edge_hit == 0) {
|
||||
model_instance_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
|
||||
model_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
|
||||
}
|
||||
|
||||
// find position in submodel RF of light object at collison
|
||||
@@ -983,11 +1020,12 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ship_model_stop( ship_obj );
|
||||
}
|
||||
|
||||
} else {
|
||||
// Debris is heavier obj
|
||||
mc.model_instance_num = -1;
|
||||
mc.model_num = Debris[num].model_num; // Fill in the model to check
|
||||
mc.submodel_num = Debris[num].submodel_num;
|
||||
model_clear_instance( mc.model_num );
|
||||
@@ -1043,9 +1081,11 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the team field for a debris object
|
||||
*/
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_get_team()
|
||||
//
|
||||
// Return the team field for a debris object
|
||||
//
|
||||
int debris_get_team(object *objp)
|
||||
{
|
||||
Assert( objp->type == OBJ_DEBRIS );
|
||||
@@ -1053,9 +1093,7 @@ int debris_get_team(object *objp)
|
||||
return Debris[objp->instance].team;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in debris physics properties when created, specifically mass and moment of inertia
|
||||
*/
|
||||
// fills in debris physics properties when created, specifically mass and moment of inertia
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs )
|
||||
{
|
||||
float dx, dy, dz, mass;
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef struct debris {
|
||||
vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
|
||||
int arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. -1 is not used
|
||||
int arc_frequency; // Starts at 0, gets bigger
|
||||
int parent_alt_name;
|
||||
char parent_alt_name;
|
||||
float damage_mult;
|
||||
|
||||
} debris;
|
||||
@@ -52,6 +52,7 @@ typedef struct debris {
|
||||
#define DEBRIS_USED (1<<0)
|
||||
#define DEBRIS_EXPIRE (1<<1) // debris can expire (ie hull chunks from small ships)
|
||||
|
||||
|
||||
#define MAX_DEBRIS_PIECES 64
|
||||
|
||||
extern debris Debris[MAX_DEBRIS_PIECES];
|
||||
@@ -63,6 +64,7 @@ struct collision_info_struct;
|
||||
void debris_init();
|
||||
void debris_render( object * obj );
|
||||
void debris_delete( object * obj );
|
||||
void debris_process_pre( object * obj, float frame_time);
|
||||
void debris_process_post( object * obj, float frame_time);
|
||||
object *debris_create( object * source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force );
|
||||
int debris_check_collision( object * obj, object * other_obj, vec3d * hitpos, collision_info_struct *debris_hit_info=NULL );
|
||||
|
||||
+166
-195
@@ -21,6 +21,7 @@
|
||||
#include "io/key.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
|
||||
|
||||
#define MAX_COMMANDS 300
|
||||
@@ -33,35 +34,35 @@ debug_command::debug_command(char *_name, char *_help, void (*_func)() )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( Num_debug_commands >= MAX_COMMANDS ) {
|
||||
if ( Num_debug_commands >= MAX_COMMANDS ) {
|
||||
Int3(); // Too many debug console commands!! Increase MAX_COMMANDS!!
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
int ret = stricmp( Debug_command[i]->name, _name );
|
||||
|
||||
if ( ret == 0) {
|
||||
if ( ret == 0) {
|
||||
Int3(); // This debug console command already exists!!!!
|
||||
return;
|
||||
} else if ( ret > 0 ) {
|
||||
} else if ( ret > 0 ) {
|
||||
break; // Insert it here
|
||||
|
||||
} else if ( ret < 0 ) {
|
||||
} else if ( ret < 0 ) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
if ( i < Num_debug_commands ) {
|
||||
if ( i < Num_debug_commands ) {
|
||||
// Insert it at element i
|
||||
int j;
|
||||
for (j=Num_debug_commands; j>i; j-- ) {
|
||||
for (j=Num_debug_commands; j>i; j-- ) {
|
||||
Debug_command[j] = Debug_command[j-1];
|
||||
}
|
||||
Debug_command[i] = this;
|
||||
Debug_command[i] = this;
|
||||
Num_debug_commands++;
|
||||
} else {
|
||||
Debug_command[Num_debug_commands] = this;
|
||||
Debug_command[Num_debug_commands] = this;
|
||||
Num_debug_commands++;
|
||||
}
|
||||
|
||||
@@ -71,18 +72,17 @@ debug_command::debug_command(char *_name, char *_help, void (*_func)() )
|
||||
}
|
||||
|
||||
// some global variables
|
||||
int Dc_command; // If this is set, then process the command
|
||||
int Dc_help; // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
|
||||
int Dc_status; // If this is set, then print out the current status of the command.
|
||||
char *Dc_arg; // The (lowercased) string value of the argument retrieved from dc_arg
|
||||
char *Dc_arg_org; // Dc_arg before it got converted to lowercase
|
||||
uint Dc_arg_type; // The type of dc_arg.
|
||||
char *Dc_command_line; // The rest of the command line, from the end of the last processed arg on.
|
||||
int Dc_arg_int; // If Dc_arg_type & ARG_INT is set, then this is the value
|
||||
ubyte Dc_arg_ubyte; // If Dc_arg_type & ARG_UBYTE is set, then this is the value
|
||||
float Dc_arg_float; // If Dc_arg_type & ARG_FLOAT is set, then this is the value
|
||||
int Dc_command; // If this is set, then process the command
|
||||
int Dc_help; // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
|
||||
int Dc_status; // If this is set, then print out the current status of the command.
|
||||
char *Dc_arg; // The (lowercased) string value of the argument retrieved from dc_arg
|
||||
char *Dc_arg_org; // Dc_arg before it got converted to lowercase
|
||||
uint Dc_arg_type; // The type of dc_arg.
|
||||
char *Dc_command_line; // The rest of the command line, from the end of the last processed arg on.
|
||||
int Dc_arg_int; // If Dc_arg_type & ARG_INT is set, then this is the value
|
||||
float Dc_arg_float; // If Dc_arg_type & ARG_FLOAT is set, then this is the value
|
||||
|
||||
int scroll_times = 0; // incremented each time display scrolls
|
||||
int scroll_times = 0; // incremented each time display scrolls
|
||||
|
||||
int debug_inited = 0;
|
||||
|
||||
@@ -112,7 +112,7 @@ typedef enum {
|
||||
|
||||
#define MAX_TOKEN_STRING_LENGTH 128
|
||||
|
||||
char scanner_ch;
|
||||
char scanner_ch;
|
||||
TOKEN_CODE scanner_token;
|
||||
|
||||
char scanner_token_string[MAX_TOKEN_STRING_LENGTH];
|
||||
@@ -126,7 +126,7 @@ CHAR_CODE scanner_char_table[256];
|
||||
|
||||
void scanner_get_char()
|
||||
{
|
||||
if ( *scanner_bufferp == '\0' ) {
|
||||
if ( *scanner_bufferp == '\0' ) {
|
||||
scanner_ch = 0;
|
||||
return;
|
||||
}
|
||||
@@ -144,23 +144,26 @@ void scanner_init()
|
||||
scanner_char_table['.'] = DIGIT;
|
||||
scanner_char_table['-'] = DIGIT;
|
||||
scanner_char_table['+'] = DIGIT;
|
||||
|
||||
|
||||
scanner_char_table['_'] = LETTER;
|
||||
scanner_char_table[34] = QUOTE;
|
||||
scanner_char_table[0] = EOF_CODE;
|
||||
|
||||
|
||||
scanner_char_table[':'] = LETTER;
|
||||
scanner_char_table['\\'] = LETTER;
|
||||
|
||||
scanner_ch = 0;
|
||||
}
|
||||
|
||||
|
||||
void scanner_skip_blanks()
|
||||
{
|
||||
while( (scanner_ch ==' ') || (scanner_ch =='\t') )
|
||||
while( (scanner_ch ==' ') || (scanner_ch =='\t') )
|
||||
scanner_get_char();
|
||||
}
|
||||
|
||||
|
||||
void scanner_downshift_word()
|
||||
{
|
||||
int offset = 'a' - 'A';
|
||||
@@ -175,9 +178,10 @@ void scanner_downshift_word()
|
||||
} while (*tp != '\0' );
|
||||
}
|
||||
|
||||
|
||||
void scanner_get_word()
|
||||
{
|
||||
while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
|
||||
while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
|
||||
*scanner_tokenp++ = scanner_ch;
|
||||
scanner_get_char();
|
||||
}
|
||||
@@ -186,12 +190,13 @@ void scanner_get_word()
|
||||
scanner_token = IDENTIFIER;
|
||||
}
|
||||
|
||||
|
||||
void scanner_get_string()
|
||||
{
|
||||
*scanner_tokenp++ = 34;
|
||||
scanner_get_char();
|
||||
|
||||
while(scanner_ch != 34 ) {
|
||||
while(scanner_ch != 34 ) {
|
||||
*scanner_tokenp++ = scanner_ch;
|
||||
scanner_get_char();
|
||||
}
|
||||
@@ -201,18 +206,21 @@ void scanner_get_string()
|
||||
scanner_token = STRING;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void scanner_get_token()
|
||||
{
|
||||
scanner_skip_blanks();
|
||||
scanner_tokenp = scanner_token_string;
|
||||
*scanner_tokenp = 0;
|
||||
|
||||
switch( scanner_char_code(scanner_ch) ) {
|
||||
case QUOTE: scanner_get_string(); break;
|
||||
case EOF_CODE: scanner_token = NO_TOKEN; break;
|
||||
|
||||
switch( scanner_char_code(scanner_ch) ) {
|
||||
case QUOTE: scanner_get_string(); break;
|
||||
case EOF_CODE: scanner_token = NO_TOKEN; break;
|
||||
case DIGIT:
|
||||
case LETTER: scanner_get_word(); break;
|
||||
default:
|
||||
case LETTER: scanner_get_word(); break;
|
||||
default:
|
||||
*scanner_tokenp++ = scanner_ch;
|
||||
*scanner_tokenp = '\0';
|
||||
scanner_get_char();
|
||||
@@ -229,6 +237,7 @@ void scanner_start_command( char * s )
|
||||
scanner_get_char();
|
||||
}
|
||||
|
||||
|
||||
int Dc_debug_on = 0;
|
||||
jmp_buf dc_bad_arg;
|
||||
|
||||
@@ -236,126 +245,98 @@ void dc_get_arg(uint type)
|
||||
{
|
||||
scanner_get_token();
|
||||
|
||||
Dc_command_line = scanner_bufferp;
|
||||
Dc_command_line = scanner_bufferp;
|
||||
Dc_arg_org = scanner_token_string;
|
||||
Dc_arg = scanner_word_string;
|
||||
|
||||
if (Dc_debug_on) {
|
||||
if (Dc_debug_on) {
|
||||
dc_printf( "next arg is '%s', was originally '%s'\n", Dc_arg, Dc_arg_org );
|
||||
dc_printf( "Rest of the command line is '%s'\n", Dc_command_line );
|
||||
}
|
||||
|
||||
if ( scanner_token == NO_TOKEN ) {
|
||||
|
||||
if ( scanner_token == NO_TOKEN ) {
|
||||
Dc_arg_type = ARG_NONE;
|
||||
} else if ( scanner_token == IDENTIFIER ) {
|
||||
} else if ( scanner_token == IDENTIFIER ) {
|
||||
Dc_arg_type = ARG_STRING;
|
||||
} else if ( scanner_token == STRING ) {
|
||||
} else if ( scanner_token == STRING ) {
|
||||
Dc_arg_type = ARG_QUOTE;
|
||||
} else {
|
||||
Dc_arg_type = ARG_STRING;
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_STRING ) {
|
||||
if ( Dc_arg_type & ARG_STRING ) {
|
||||
int i, num_digits, len;
|
||||
|
||||
len = strlen(Dc_arg);
|
||||
num_digits = 0;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if ( scanner_char_table[Dc_arg[i]] == DIGIT ) {
|
||||
num_digits++;
|
||||
}
|
||||
for (i=0; i<len; i++)
|
||||
if ( scanner_char_table[Dc_arg[i]] == DIGIT ) num_digits++;
|
||||
|
||||
if ( num_digits==len ) {
|
||||
Dc_arg_type |= ARG_FLOAT;
|
||||
Dc_arg_float = (float)atof(Dc_arg);
|
||||
if ( !strchr( Dc_arg, '.' )) {
|
||||
Dc_arg_type |= ARG_INT;
|
||||
Dc_arg_int = atoi(Dc_arg);
|
||||
Dc_arg_type |= ARG_UBYTE;
|
||||
Dc_arg_ubyte = (ubyte)atoi(Dc_arg);
|
||||
}
|
||||
} else {
|
||||
if ( (Dc_arg[0] == '0') && (Dc_arg[1] == 'x') ) {
|
||||
char *p;
|
||||
int n;
|
||||
n = strtol(Dc_arg,&p,0);
|
||||
if ( *p == 0 ) {
|
||||
Dc_arg_type |= ARG_INT|ARG_HEX;
|
||||
Dc_arg_int = n;
|
||||
}
|
||||
}
|
||||
if ( num_digits==len ) {
|
||||
Dc_arg_type |= ARG_FLOAT;
|
||||
Dc_arg_float = (float)atof(Dc_arg);
|
||||
if ( !strchr( Dc_arg, '.' )) {
|
||||
Dc_arg_type |= ARG_INT;
|
||||
Dc_arg_int = atoi(Dc_arg);
|
||||
}
|
||||
} else {
|
||||
if ( (Dc_arg[0] == '0') && (Dc_arg[1] == 'x') ) {
|
||||
char *p;
|
||||
int n;
|
||||
n = strtol(Dc_arg,&p,0);
|
||||
if ( *p == 0 ) {
|
||||
Dc_arg_type |= ARG_INT|ARG_HEX;
|
||||
Dc_arg_int = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Dc_debug_on) {
|
||||
if ( Dc_arg_type & ARG_FLOAT ) {
|
||||
if (Dc_debug_on) {
|
||||
if ( Dc_arg_type & ARG_FLOAT )
|
||||
dc_printf( "Found float number! %f\n", Dc_arg_float );
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_INT ) {
|
||||
if ( Dc_arg_type & ARG_INT )
|
||||
dc_printf( "Found int number! %d\n", Dc_arg_int );
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_UBYTE ) {
|
||||
dc_printf( "Found ubyte number! %d\n", Dc_arg_ubyte );
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_HEX ) {
|
||||
if ( Dc_arg_type & ARG_HEX )
|
||||
dc_printf( "Found hex number! 0x%x\n", Dc_arg_int );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "on" ) ) {
|
||||
if ( !stricmp( Dc_arg, "on" ))
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
}
|
||||
if ( !stricmp( Dc_arg, "true" ) ) {
|
||||
if ( !stricmp( Dc_arg, "true" ))
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
}
|
||||
if ( !stricmp( Dc_arg, "off" ) ) {
|
||||
if ( !stricmp( Dc_arg, "off" ))
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
}
|
||||
if ( !stricmp( Dc_arg, "false" ) ) {
|
||||
if ( !stricmp( Dc_arg, "false" ))
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "+" ) ) {
|
||||
if ( !stricmp( Dc_arg, "+" ))
|
||||
Dc_arg_type |= ARG_PLUS;
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "-" ) ) {
|
||||
if ( !stricmp( Dc_arg, "-" ))
|
||||
Dc_arg_type |= ARG_MINUS;
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "," ) ) {
|
||||
if ( !stricmp( Dc_arg, "," ))
|
||||
Dc_arg_type |= ARG_COMMA;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_INT) {
|
||||
if ( Dc_arg_int ) {
|
||||
if ( Dc_arg_type & ARG_INT) {
|
||||
if ( Dc_arg_int )
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
} else {
|
||||
else
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_UBYTE) {
|
||||
if ( Dc_arg_ubyte ) {
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
} else {
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(Dc_arg_type&type) ) {
|
||||
if ( (Dc_arg_type & ARG_NONE) && !(type & ARG_NONE) ) {
|
||||
if ( !(Dc_arg_type&type) ) {
|
||||
if ( (Dc_arg_type & ARG_NONE) && !(type & ARG_NONE))
|
||||
dc_printf( "Error: Not enough parameters.\n" );
|
||||
} else {
|
||||
else
|
||||
dc_printf( "Error: '%s' invalid type\n", Dc_arg );
|
||||
longjmp(dc_bad_arg,1);
|
||||
}
|
||||
longjmp(dc_bad_arg,1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void debug_help();
|
||||
@@ -366,85 +347,80 @@ void debug_do_command(char * command)
|
||||
int i;
|
||||
int mode = 0;
|
||||
|
||||
if ( strlen(command) < 1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strlen(command) < 1 ) return;
|
||||
|
||||
Dc_debug_on = 0;
|
||||
Dc_command_line = command;
|
||||
scanner_start_command(command);
|
||||
|
||||
if (setjmp(dc_bad_arg) ) {
|
||||
if (setjmp(dc_bad_arg) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
dc_get_arg( ARG_ANY );
|
||||
|
||||
if ( !strcmp( Dc_arg, "debug" ) ) {
|
||||
if ( !strcmp( Dc_arg, "debug" ) ) {
|
||||
Dc_debug_on = 1;
|
||||
dc_printf( "Command line: '%s'\n", Dc_command_line );
|
||||
dc_get_arg( ARG_ANY );
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "xyzzy" ) ) {
|
||||
if ( !stricmp( Dc_arg, "xyzzy" ) ) {
|
||||
dc_printf("Nothing happens.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !strcmp( Dc_arg, "?" ) ) {
|
||||
if ( !strcmp( Dc_arg, "?" ) ) {
|
||||
mode = 1;
|
||||
dc_get_arg( ARG_ANY );
|
||||
|
||||
if ( Dc_arg_type&ARG_NONE ) {
|
||||
debug_help();
|
||||
if ( Dc_arg_type&ARG_NONE ) {
|
||||
debug_help();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
|
||||
if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
|
||||
mode = 2;
|
||||
dc_get_arg( ARG_ANY );
|
||||
if ( Dc_arg_type&ARG_NONE ) {
|
||||
debug_help();
|
||||
if ( Dc_arg_type&ARG_NONE ) {
|
||||
debug_help();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( strstr( Dc_command_line, "?" ) ) {
|
||||
if ( strstr( Dc_command_line, "?" ) ) {
|
||||
mode = 2;
|
||||
}
|
||||
|
||||
if ( !(Dc_arg_type&ARG_STRING) ) {
|
||||
if ( !(Dc_arg_type&ARG_STRING) ) {
|
||||
dc_printf( "Invalid keyword '%s'\n", Dc_arg );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Dc_debug_on) {
|
||||
if (Dc_debug_on) {
|
||||
dc_printf( "Searching for command '%s'\n", Dc_arg );
|
||||
}
|
||||
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
if ( !stricmp( Debug_command[i]->name, Dc_arg ) ) {
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
if ( !stricmp( Debug_command[i]->name, Dc_arg )) {
|
||||
|
||||
if (mode==0) {
|
||||
if (Dc_debug_on) {
|
||||
if (mode==0) {
|
||||
if (Dc_debug_on)
|
||||
dc_printf( "Calling function '%s'\n", Dc_arg );
|
||||
}
|
||||
Dc_command = 1;
|
||||
Dc_help = 0;
|
||||
Dc_status = 1;
|
||||
} else if (mode==1) {
|
||||
if (Dc_debug_on) {
|
||||
if (Dc_debug_on)
|
||||
dc_printf( "Checking status for '%s'\n", Dc_arg );
|
||||
}
|
||||
Dc_command = 0;
|
||||
Dc_help = 0;
|
||||
Dc_status = 1;
|
||||
} else {
|
||||
if (Dc_debug_on) {
|
||||
if (Dc_debug_on)
|
||||
dc_printf( "Doing help for '%s'\n", Dc_arg );
|
||||
}
|
||||
Dc_command = 0;
|
||||
Dc_help = 1;
|
||||
Dc_status = 0;
|
||||
@@ -452,9 +428,9 @@ void debug_do_command(char * command)
|
||||
|
||||
(*Debug_command[i]->func)();
|
||||
|
||||
if (mode==0) {
|
||||
if (mode==0) {
|
||||
dc_get_arg(ARG_ANY);
|
||||
if (!(Dc_arg_type&ARG_NONE)) {
|
||||
if (!(Dc_arg_type&ARG_NONE)) {
|
||||
dc_printf( "Ignoring the unused command line tail '%s %s'\n", Dc_arg_org, Dc_command_line );
|
||||
}
|
||||
}
|
||||
@@ -469,7 +445,7 @@ void debug_do_command(char * command)
|
||||
void debug_draw()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
gr_clear();
|
||||
gr_set_font(FONT1);
|
||||
gr_set_color_fast( &Color_bright );
|
||||
@@ -477,12 +453,12 @@ void debug_draw()
|
||||
|
||||
gr_set_color_fast( &Color_normal );
|
||||
|
||||
for (i=0; i<DROWS; i++ ) {
|
||||
for (i=0; i<DROWS; i++ ) {
|
||||
gr_string( 0, i*16+16, debug_text[i] );
|
||||
}
|
||||
|
||||
int t = timer_get_fixed_seconds() / (F1_0/3);
|
||||
if ( t & 1 ) {
|
||||
if ( t & 1 ) {
|
||||
int w,h;
|
||||
char c;
|
||||
|
||||
@@ -490,10 +466,10 @@ void debug_draw()
|
||||
debug_text[debug_y][command_line_pos+1] = 0;
|
||||
|
||||
gr_get_string_size( &w, &h, debug_text[debug_y] );
|
||||
|
||||
|
||||
//gr_string( w, debug_y*16, "_" );
|
||||
gr_rect(w+1,debug_y*16+1+16,2,14);
|
||||
|
||||
|
||||
debug_text[debug_y][command_line_pos+1] = c;
|
||||
}
|
||||
|
||||
@@ -503,18 +479,17 @@ void debug_draw()
|
||||
|
||||
void debug_output( char c )
|
||||
{
|
||||
if ( c == '\t' ) {
|
||||
if ( c == '\t' ) {
|
||||
int next_tab = ((debug_x/28)+1)*28;
|
||||
|
||||
if ( next_tab >= DCOLS-1 ) {
|
||||
if ( next_tab >= DCOLS-1 ) {
|
||||
debug_x=0;
|
||||
debug_y++;
|
||||
scroll_times++;
|
||||
if ( debug_y >= DROWS ) {
|
||||
if ( debug_y >= DROWS ) {
|
||||
int i;
|
||||
for (i=1; i<DROWS; i++ ) {
|
||||
for (i=1; i<DROWS; i++ )
|
||||
strcpy_s( debug_text[i-1], debug_text[i] );
|
||||
}
|
||||
debug_y = DROWS-1;
|
||||
debug_x = 0;
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
@@ -523,30 +498,26 @@ void debug_output( char c )
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ; debug_x < next_tab; ) {
|
||||
for ( ; debug_x < next_tab; )
|
||||
debug_text[debug_y][debug_x++] = ' ';
|
||||
}
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (c == '\n') || (debug_x >= DCOLS-1) ) {
|
||||
if ( (c == '\n') || (debug_x >= DCOLS-1) ) {
|
||||
debug_x=0;
|
||||
debug_y++;
|
||||
scroll_times++;
|
||||
if ( debug_y >= DROWS ) {
|
||||
if ( debug_y >= DROWS ) {
|
||||
int i;
|
||||
for (i=1; i<DROWS; i++ ) {
|
||||
for (i=1; i<DROWS; i++ )
|
||||
strcpy_s( debug_text[i-1], debug_text[i] );
|
||||
}
|
||||
debug_y = DROWS-1;
|
||||
debug_x = 0;
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
}
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
if ( c == '\n' ) {
|
||||
return;
|
||||
}
|
||||
if ( c == '\n' ) return;
|
||||
}
|
||||
|
||||
debug_text[debug_y][debug_x++] = c;
|
||||
@@ -557,72 +528,72 @@ void dc_printf(char *format, ...)
|
||||
{
|
||||
char tmp[DCOLS*DROWS];
|
||||
va_list args;
|
||||
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tmp, format, args);
|
||||
va_end(args);
|
||||
|
||||
char *p = tmp;
|
||||
while( *p != '\0' ) {
|
||||
while( *p != '\0' ) {
|
||||
debug_output(*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void debug_init()
|
||||
{
|
||||
int i;
|
||||
if ( debug_inited ) {
|
||||
return;
|
||||
}
|
||||
if ( debug_inited ) return;
|
||||
|
||||
debug_inited = 1;
|
||||
|
||||
debug_x=0;
|
||||
debug_y=0;
|
||||
|
||||
for (i=0; i<DROWS; i++ ) {
|
||||
for (i=0; i<DROWS; i++ ) {
|
||||
debug_text[i][0] = 0;
|
||||
}
|
||||
|
||||
|
||||
dc_printf("Debug console started.\n" );
|
||||
}
|
||||
|
||||
|
||||
void debug_console( void (*_func)() )
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
scanner_init();
|
||||
|
||||
while( key_inkey() ) {
|
||||
while( key_inkey() ){
|
||||
os_poll();
|
||||
}
|
||||
|
||||
if ( !debug_inited ) {
|
||||
debug_init();
|
||||
}
|
||||
if ( !debug_inited ) debug_init();
|
||||
|
||||
|
||||
debug_draw();
|
||||
|
||||
while (!done) {
|
||||
|
||||
while (!done) {
|
||||
// poll the os
|
||||
os_poll();
|
||||
|
||||
int k = key_inkey();
|
||||
switch( k ) {
|
||||
switch( k ) {
|
||||
|
||||
case KEY_SHIFTED+KEY_ENTER:
|
||||
case KEY_ESC:
|
||||
done=1; break;
|
||||
case KEY_ESC:
|
||||
done=1; break;
|
||||
|
||||
case KEY_BACKSP:
|
||||
if ( command_line_pos > 0 ) {
|
||||
if ( command_line_pos > 0 ) {
|
||||
command_line[--command_line_pos] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_F3:
|
||||
if ( last_oldcommand > -1 ) {
|
||||
if ( last_oldcommand > -1 ) {
|
||||
strcpy_s( command_line, oldcommand_line[last_oldcommand] );
|
||||
command_line_pos = strlen(command_line);
|
||||
command_line[command_line_pos] = 0;
|
||||
@@ -631,11 +602,10 @@ void debug_console( void (*_func)() )
|
||||
|
||||
case KEY_UP:
|
||||
command_scroll--;
|
||||
if (command_scroll<0) {
|
||||
if (command_scroll<0)
|
||||
command_scroll = last_oldcommand;
|
||||
}
|
||||
|
||||
if ( command_scroll > -1 ) {
|
||||
if ( command_scroll > -1 ) {
|
||||
strcpy_s( command_line, oldcommand_line[command_scroll] );
|
||||
command_line_pos = strlen(command_line);
|
||||
command_line[command_line_pos] = 0;
|
||||
@@ -644,44 +614,46 @@ void debug_console( void (*_func)() )
|
||||
|
||||
case KEY_DOWN:
|
||||
command_scroll++;
|
||||
if (command_scroll>last_oldcommand) {
|
||||
if (command_scroll>last_oldcommand)
|
||||
command_scroll = 0;
|
||||
}
|
||||
if (command_scroll>last_oldcommand) {
|
||||
if (command_scroll>last_oldcommand)
|
||||
command_scroll = -1;
|
||||
}
|
||||
if ( command_scroll > -1 ) {
|
||||
if ( command_scroll > -1 ) {
|
||||
strcpy_s( command_line, oldcommand_line[command_scroll] );
|
||||
command_line_pos = strlen(command_line);
|
||||
command_line[command_line_pos] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_ENTER: {
|
||||
case KEY_ENTER: {
|
||||
debug_output( '\n' );
|
||||
debug_draw();
|
||||
|
||||
debug_do_command(command_line);
|
||||
|
||||
int i, found = 0;
|
||||
for (i=0; i<=last_oldcommand; i++ ) {
|
||||
if (!stricmp( oldcommand_line[i], command_line )) {
|
||||
for (i=0; i<=last_oldcommand; i++ ) {
|
||||
if (!stricmp( oldcommand_line[i], command_line )) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if ( !found ) {
|
||||
if ( last_oldcommand < DEBUG_HISTORY-1 ) {
|
||||
if ( !found ) {
|
||||
if ( last_oldcommand < DEBUG_HISTORY-1 ) {
|
||||
last_oldcommand++;
|
||||
strcpy_s( oldcommand_line[last_oldcommand], command_line);
|
||||
} else {
|
||||
int iLoop;
|
||||
for (iLoop=0; iLoop<last_oldcommand; iLoop++ ) {
|
||||
for (iLoop=0; iLoop<last_oldcommand; iLoop++ ) {
|
||||
strcpy_s( oldcommand_line[iLoop], oldcommand_line[iLoop+1] );
|
||||
}
|
||||
strcpy_s( oldcommand_line[last_oldcommand], command_line);
|
||||
}
|
||||
}
|
||||
|
||||
// int i;
|
||||
// for (i=0; i<=last_oldcommand; i++ ) {
|
||||
// dc_printf( "OC %d. %s\n", i, oldcommand_line[i] );
|
||||
// }
|
||||
|
||||
debug_output( '\n' );
|
||||
command_line_pos = 0;
|
||||
command_line[command_line_pos] = 0;
|
||||
@@ -690,7 +662,7 @@ void debug_console( void (*_func)() )
|
||||
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
default: {
|
||||
ubyte c = (ubyte)key_to_ascii(k);
|
||||
if ( c != 255 ) {
|
||||
command_line[command_line_pos++] = c;
|
||||
@@ -703,12 +675,12 @@ void debug_console( void (*_func)() )
|
||||
strcat_s( debug_text[debug_y], command_line );
|
||||
debug_draw();
|
||||
|
||||
if ( _func ) {
|
||||
if ( _func ){
|
||||
_func();
|
||||
}
|
||||
}
|
||||
|
||||
while( key_inkey() ) {
|
||||
while( key_inkey() ){
|
||||
os_poll();
|
||||
}
|
||||
}
|
||||
@@ -717,25 +689,24 @@ void debug_help()
|
||||
{
|
||||
int s, i;
|
||||
|
||||
dc_printf( "Available functions:\n\n" );
|
||||
dc_printf( "Available functions:\n\n" );
|
||||
|
||||
s = scroll_times;
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
dc_printf( " %s - %s\n", Debug_command[i]->name, Debug_command[i]->help );
|
||||
|
||||
if ( scroll_times - s > DROWS - 3 ) {
|
||||
//mprintf(( "Scroll times %d\n", scroll_times - s ));
|
||||
if ( scroll_times - s > DROWS - 3 ) {
|
||||
int k;
|
||||
dc_printf( " Press a key...B for back\n" );
|
||||
debug_draw();
|
||||
k = key_getch();
|
||||
s = scroll_times;
|
||||
if ( k == KEY_B ) {
|
||||
if ( k == KEY_B ) {
|
||||
i -= ((DROWS-3)*2);
|
||||
if ( i <= 0 ) {
|
||||
if ( i <= 0 )
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
debug_draw();
|
||||
}
|
||||
dc_printf( "\n" );
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
#include "dbugfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
|
||||
int dbugfile_counters[MAX_COUNTERS];
|
||||
bool dbugfile_init_var = false;
|
||||
|
||||
char dbugfile_filename[512];
|
||||
|
||||
void dbugfile_output(char *buffer)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FILE *fp = fopen(dbugfile_filename, "a");
|
||||
|
||||
if(fp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(buffer, sizeof(char) * strlen(buffer), 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void dbugfile_init()
|
||||
{
|
||||
// Clear the counters
|
||||
memset(dbugfile_counters, 0, sizeof(int) * MAX_COUNTERS);
|
||||
|
||||
char big_buffer[1000];
|
||||
char temp_buff[512];
|
||||
|
||||
dbugfile_filename[0] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
char path[MAX_PATH];
|
||||
|
||||
GetCurrentDirectory(MAX_PATH, path);
|
||||
|
||||
int path_len = strlen(path);
|
||||
if(path[path_len - 1] != '\\')
|
||||
{
|
||||
path[path_len] = '\\';
|
||||
path[path_len + 1] = '\0';
|
||||
}
|
||||
|
||||
strcpy_s(dbugfile_filename, path);
|
||||
|
||||
#endif
|
||||
|
||||
strcat_s(dbugfile_filename, "DBUG-");
|
||||
strcpy_s(big_buffer, "DBUGFILE Active: ");
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
unsigned long len = 512;
|
||||
GetUserName(temp_buff, &len);
|
||||
|
||||
strcat_s(dbugfile_filename, temp_buff);
|
||||
strcat_s(big_buffer, temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, "-");
|
||||
strcat_s(big_buffer, " ");
|
||||
}
|
||||
#endif
|
||||
|
||||
_tzset();
|
||||
|
||||
// Display operating system-style date and time.
|
||||
_strdate( temp_buff);
|
||||
strcat_s(dbugfile_filename, "D(");
|
||||
strcat_s(dbugfile_filename,temp_buff);
|
||||
strcat_s(big_buffer,temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, ") T(");
|
||||
strcat_s(big_buffer, " ");
|
||||
|
||||
_strtime( temp_buff);
|
||||
strcat_s(dbugfile_filename,temp_buff);
|
||||
strcat_s(big_buffer,temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, ").txt");
|
||||
strcat_s(big_buffer, "\n");
|
||||
|
||||
// Remove invalid slash chars
|
||||
int len = strlen(dbugfile_filename);
|
||||
while(len >= 2)
|
||||
{
|
||||
if(dbugfile_filename[len] == '/' || dbugfile_filename[len] == ':')
|
||||
{
|
||||
dbugfile_filename[len] = '-';
|
||||
}
|
||||
len--;
|
||||
}
|
||||
|
||||
// open file
|
||||
// Uncomment this to see where the file is going
|
||||
//MessageBox(NULL, dbugfile_filename, "das", MB_OK);
|
||||
FILE *fp = fopen(dbugfile_filename, "w");
|
||||
|
||||
if(fp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(big_buffer, sizeof(char) * strlen(big_buffer), 1, fp);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// detect OS type
|
||||
|
||||
OSVERSIONINFO version_info;
|
||||
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
if(GetVersionEx(&version_info) != false)
|
||||
{
|
||||
char *error = "Error in detecting OS version";
|
||||
char *version = error;
|
||||
|
||||
switch(version_info.dwMajorVersion)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
if(version_info.dwMinorVersion == 0)
|
||||
{
|
||||
version = "Windows 95";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 10)
|
||||
{
|
||||
version = "Windows 98";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 90)
|
||||
{
|
||||
version = "Windows Me";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if(version_info.dwMinorVersion == 0)
|
||||
{
|
||||
version = "Windows 2000";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 1)
|
||||
{
|
||||
version = "Windows XP";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *release_type = NULL;
|
||||
#ifdef _DEBUG
|
||||
release_type = "Debug";
|
||||
#else
|
||||
release_type = "Release";
|
||||
#endif
|
||||
sprintf(big_buffer, "OS: %s %s, ", version, release_type);
|
||||
}
|
||||
|
||||
fwrite(big_buffer, sizeof(char) * strlen(big_buffer), 1, fp);
|
||||
|
||||
char exe_name[MAX_PATH];
|
||||
|
||||
GetModuleFileName(NULL, exe_name, MAX_PATH);
|
||||
strcat_s(exe_name, "\n");
|
||||
fwrite(exe_name, sizeof(char) * strlen(exe_name), 1, fp);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
fclose(fp);
|
||||
|
||||
dbugfile_init_var = true;
|
||||
}
|
||||
|
||||
void dbugfile_deinit()
|
||||
{
|
||||
dbugfile_output("Normal end");
|
||||
dbugfile_init_var = false;
|
||||
}
|
||||
|
||||
void dbugfile_sprintf(int line, char *file, const char *format, ...)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
int i = sprintf(buffer, "[%s,%4d] ", ptr, line);
|
||||
|
||||
va_list ap;
|
||||
char *p, *sval;
|
||||
long ival;
|
||||
double dval;
|
||||
|
||||
// Add each extra parameter to string
|
||||
va_start(ap, format);
|
||||
|
||||
for(p = (char *) format; *p; p++)
|
||||
{
|
||||
if(*p != '%')
|
||||
{
|
||||
*(buffer + i) = *p;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
switch(*p)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
ival = va_arg(ap, int);
|
||||
i += sprintf(buffer+i,"%d", ival);
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
ival = va_arg(ap, char);
|
||||
buffer[i] = (char) ival;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
{
|
||||
ival = va_arg(ap, int);
|
||||
i += sprintf(buffer+i,"%x", ival);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
dval = va_arg(ap, double);
|
||||
i += sprintf(buffer+i,"%f", dval);
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
{
|
||||
for(sval = va_arg(ap, char *); *sval; sval++)
|
||||
{
|
||||
*(buffer + i++) = *sval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
i += sprintf(buffer+i,"N/A: %%%c", *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
i += sprintf(buffer + i, "\n");
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_matrix_4x4(int line, char *file, float *matrix, char *text)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(text == NULL)
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
|
||||
sprintf(buffer,"[%s,%4d] Matrix %s:\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n",
|
||||
ptr,line, text,
|
||||
matrix[0],
|
||||
matrix[1],
|
||||
matrix[2],
|
||||
matrix[3],
|
||||
matrix[4],
|
||||
matrix[5],
|
||||
matrix[6],
|
||||
matrix[7],
|
||||
matrix[8],
|
||||
matrix[9],
|
||||
matrix[10],
|
||||
matrix[11],
|
||||
matrix[12],
|
||||
matrix[13],
|
||||
matrix[14],
|
||||
matrix[15]);
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_matrix_3x3(int line, char *file, float *matrix, char *text)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(text == NULL)
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
|
||||
sprintf(buffer,"[%s,%4d] Matrix %s:\n"
|
||||
"%f %f %f\n"
|
||||
"%f %f %f\n"
|
||||
"%f %f %f\n",
|
||||
ptr,line, text,
|
||||
matrix[0],
|
||||
matrix[1],
|
||||
matrix[2],
|
||||
matrix[3],
|
||||
matrix[4],
|
||||
matrix[5],
|
||||
matrix[6],
|
||||
matrix[7],
|
||||
matrix[8]);
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_counter(int line, char *file, int counter_num, char *string)
|
||||
{
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, string);
|
||||
strcat_s(buffer, " %d");
|
||||
|
||||
dbugfile_sprintf(line, file, buffer, dbugfile_counters[counter_num]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
#ifndef _DBUGFILE_HEADER_
|
||||
#define _DBUGFILE_HEADER_
|
||||
|
||||
#define MAX_COUNTERS 10
|
||||
|
||||
void dbugfile_init();
|
||||
void dbugfile_deinit();
|
||||
void dbugfile_sprintf(int line, char *file, const char *format, ...);
|
||||
void dbugfile_print_matrix_3x3(int line, char *file, float *matrix, char *text);
|
||||
void dbugfile_print_matrix_4x4(int line, char *file, float *matrix, char *text);
|
||||
void dbugfile_print_counter(int line, char *file, int counter_num, char *string);
|
||||
|
||||
#ifdef DBUGFILE_ACTIVE
|
||||
|
||||
#define DBUGFILE_INIT() dbugfile_init();
|
||||
#define DBUGFILE_DEINIT() dbugfile_deinit();
|
||||
|
||||
#define DBUGFILE_OUTPUT_0(t) dbugfile_sprintf(__LINE__, __FILE__, t);
|
||||
#define DBUGFILE_OUTPUT_1(t,a) dbugfile_sprintf(__LINE__, __FILE__, t,a);
|
||||
#define DBUGFILE_OUTPUT_2(t,a,b) dbugfile_sprintf(__LINE__, __FILE__, t,a,b);
|
||||
#define DBUGFILE_OUTPUT_3(t,a,b,c) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c);
|
||||
#define DBUGFILE_OUTPUT_4(t,a,b,c,d) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d);
|
||||
#define DBUGFILE_OUTPUT_5(t,a,b,c,d,e) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e);
|
||||
#define DBUGFILE_OUTPUT_6(t,a,b,c,d,e,f) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f);
|
||||
#define DBUGFILE_OUTPUT_7(t,a,b,c,d,e,f,g) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g);
|
||||
#define DBUGFILE_OUTPUT_8(t,a,b,c,d,e,f,g,h) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g,h);
|
||||
#define DBUGFILE_OUTPUT_9(t,a,b,c,d,e,f,g,h,i) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g,h,i);
|
||||
|
||||
#define DBUGFILE_OUTPUT_MATRIX_3X3(m,t) dbugfile_print_matrix_3x3(__LINE__, __FILE__, m,t);
|
||||
#define DBUGFILE_OUTPUT_MATRIX_4X4(m,t) dbugfile_print_matrix_4x4(__LINE__, __FILE__, m,t);
|
||||
|
||||
extern int dbugfile_counters[MAX_COUNTERS];
|
||||
#define DBUGFILE_INC_COUNTER(n) if(n < MAX_COUNTERS) dbugfile_counters[n]++;
|
||||
#define DBUGFILE_DEC_COUNTER(n) if(n < MAX_COUNTERS) dbugfile_counters[n]--;
|
||||
|
||||
#define DBUGFILE_OUTPUT_COUNTER(n,s) dbugfile_print_counter(__LINE__, __FILE__, n, s);
|
||||
|
||||
#else
|
||||
|
||||
#define DBUGFILE_INIT() ;
|
||||
#define DBUGFILE_DEINIT() ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_0(t) ;
|
||||
#define DBUGFILE_OUTPUT_1(t,a) ;
|
||||
#define DBUGFILE_OUTPUT_2(t,a,b) ;
|
||||
#define DBUGFILE_OUTPUT_3(t,a,b,c) ;
|
||||
#define DBUGFILE_OUTPUT_4(t,a,b,c,d) ;
|
||||
#define DBUGFILE_OUTPUT_5(t,a,b,c,d,e) ;
|
||||
#define DBUGFILE_OUTPUT_6(t,a,b,c,d,e,f) ;
|
||||
#define DBUGFILE_OUTPUT_7(t,a,b,c,d,e,f,g) ;
|
||||
#define DBUGFILE_OUTPUT_8(t,a,b,c,d,e,f,g,h) ;
|
||||
#define DBUGFILE_OUTPUT_9(t,a,b,c,d,e,f,g,h,i) ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_MATRIX_3X3(m,t) ;
|
||||
#define DBUGFILE_OUTPUT_MATRIX_4X4(m,t) ;
|
||||
|
||||
#define DBUGFILE_INC_COUNTER(n) ;
|
||||
#define DBUGFILE_DEC_COUNTER(n) ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_COUNTER(n,s) ;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -109,10 +109,10 @@ const float WIDTHF = ((float) WIDTH) * 1.01f;
|
||||
/**
|
||||
* Internal conversion function to convert draw data into bars for the screen
|
||||
*
|
||||
* @param colour Colour index (>=0)
|
||||
* @param xpos X position to start bar on
|
||||
* @param xwidth Width of bar
|
||||
* @param yrow Index of row bar belongs to
|
||||
* @param int colour - colour index (>=0)
|
||||
* @param int xpos - x position to start bar on
|
||||
* @param int xwidth - width of bar
|
||||
* @param int yrow - Index of row bar belongs to
|
||||
*/
|
||||
void timerbar_conv_and_draw(int colour, int xpos, int xwidth, int yrow)
|
||||
{
|
||||
@@ -212,7 +212,7 @@ void timerbar_switch_type(int num)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param (*new_draw_func_ptr)(int colour, float x, float y, float w, float h) Pointer to draw function
|
||||
* @param void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h) - pointer to draw function
|
||||
*
|
||||
* Sets the draw function used to output the timer data, designed to be generic allowing any API
|
||||
* to take advantage of this module. Set to NULL to disable drawing.
|
||||
|
||||
@@ -26,5 +26,13 @@ void timerbar_pop();
|
||||
// This function shouldnt not be used any more or it will break push and pop calls
|
||||
void timerbar_switch_type(int num);
|
||||
|
||||
#define TIMERBAR_SET_DRAW_FUNC(f) if (Cmdline_timerbar) timerbar_set_draw_func(f);
|
||||
#define TIMERBAR_START_FRAME() if (Cmdline_timerbar) timerbar_start_frame();
|
||||
#define TIMERBAR_END_FRAME() if (Cmdline_timerbar) timerbar_end_frame();
|
||||
#define TIMERBAR_SWITCH_TYPE(n) if (Cmdline_timerbar) timerbar_switch_type(n);
|
||||
|
||||
#define TIMERBAR_PUSH(v) if (Cmdline_timerbar) timerbar_push(v);
|
||||
#define TIMERBAR_POP() if (Cmdline_timerbar) timerbar_pop();
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,129 @@
|
||||
//header file for making decals-Bobboau
|
||||
|
||||
|
||||
#ifndef _DECAL_H
|
||||
#define _DECAL_H
|
||||
|
||||
#include "object/object.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
//#include "ship/ship.h"
|
||||
|
||||
#ifdef ENABLE_DECALS
|
||||
|
||||
#define MAX_DECAL_POLY 40
|
||||
#define MAX_DECAL_POLY_POINT 10
|
||||
#define MAX_DECAL_DEFPOINTS 10000
|
||||
#define MAX_DECAL_POINT 10
|
||||
#define MAX_SHIP_DECALS 25
|
||||
#define MAX_GLOBAL_DECAL_POLYS 11000
|
||||
#define QUICKFIND_SUBDIVISION 100
|
||||
#define QUICKFIND_SEGMENT_LENGTH (MAX_GLOBAL_DECAL_POLYS/QUICKFIND_SUBDIVISION)
|
||||
#define MAX_GLOBAL_DECALS 5000
|
||||
|
||||
#define DP_EOF 0
|
||||
#define DP_DEFPOINTS 1
|
||||
#define DP_FLATPOLY 2
|
||||
#define DP_TMAPPOLY 3
|
||||
#define DP_SORTNORM 4
|
||||
#define DP_BOUNDBOX 5
|
||||
|
||||
#endif // ENABLE_DECALS
|
||||
|
||||
struct decal;
|
||||
struct decal_list;
|
||||
struct decal_list_controle;
|
||||
|
||||
struct decal_poly{
|
||||
vec3d norm[3];
|
||||
vertex point[3];
|
||||
decal_poly *next;
|
||||
decal* parent;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct decal{
|
||||
int n_poly;
|
||||
int timestamp; //when this decal was created
|
||||
int burn_time; //how long it takes for the glow texture to fade
|
||||
int vertex_buffer_start; //were is the start of this decal's polys in the vertex buffer
|
||||
decal_poly* poly;
|
||||
decal_poly* add_poly();
|
||||
decal_poly* get_last_poly();
|
||||
void remove_last_poly();
|
||||
decal_list_controle *parent;
|
||||
};
|
||||
|
||||
struct decal_list{
|
||||
decal dec;
|
||||
decal_list *next;
|
||||
};
|
||||
|
||||
struct decal_item{
|
||||
decal_list dec;
|
||||
bool used;
|
||||
};
|
||||
|
||||
struct decal_list_controle{
|
||||
int n_decals;
|
||||
int buffer;
|
||||
int texture;
|
||||
int n_poly;
|
||||
int burn_texture;
|
||||
int glow_texture;
|
||||
bool modifyed;
|
||||
decal_list *d_list;
|
||||
decal_list *end;
|
||||
decal_list *add_new();
|
||||
void trim();
|
||||
void clear();
|
||||
~decal_list_controle();
|
||||
decal_list_controle();
|
||||
};
|
||||
|
||||
struct decal_system{
|
||||
decal_list_controle *decals;
|
||||
int n_decal_textures;
|
||||
bool decals_modified;
|
||||
int max_decals;
|
||||
decal_system():decals(NULL),n_decal_textures(0),decals_modified(false){};
|
||||
};
|
||||
|
||||
|
||||
//this is used to give all the data to the generation data to the functions that make them
|
||||
|
||||
struct decal_point{
|
||||
vec3d pnt;
|
||||
matrix orient;
|
||||
float radius;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_DECALS
|
||||
|
||||
int decal_create(object * obj, decal_point *point, int subobject, int texture, int backfaced_texture = -1, int glow_texture = -1, int burn_texture = -1, int burn_time = 1000);//makes the decal
|
||||
|
||||
int decal_create_simple(object * obj, decal_point *point, int texture);//makes a simple non-clipped decal
|
||||
|
||||
void decal_render_all(object * obj); //renders all decals
|
||||
|
||||
int decal_create_sub(void *model_ptr);
|
||||
|
||||
void clear_decals(decal_system *system);
|
||||
|
||||
void init_decals();
|
||||
|
||||
#else // ENABLE_DECALS
|
||||
|
||||
inline int decal_create(object * obj, decal_point *point, int subobject, int texture, int backfaced_texture = -1, int glow_texture = -1, int burn_texture = -1, int burn_time = 1000)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define decal_create_simple(a, b, c) (0)
|
||||
#define decal_render_all(a)
|
||||
#define decal_create_sub(a) (0);
|
||||
#define clear_decals(a)
|
||||
#define init_decals()
|
||||
|
||||
#endif // ENABLE_DECALS
|
||||
|
||||
#endif // _DECAL_H
|
||||
@@ -0,0 +1,974 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "demo/demo.h"
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "freespace2/freespace.h"
|
||||
#include "object/object.h"
|
||||
#include "io/timer.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "mission/missionmessage.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "ship/shipfx.h"
|
||||
#include "ship/shiphit.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO DEFINES/VARS
|
||||
//
|
||||
|
||||
CFILE *Demo_file = NULL;
|
||||
|
||||
// how often we dump
|
||||
#define DEMO_DEFAULT_FPS 15
|
||||
int Demo_fps = 1000 / DEMO_DEFAULT_FPS;
|
||||
|
||||
// timestamp for frame dumping
|
||||
int Demo_stamp = -1;
|
||||
|
||||
// missiontime
|
||||
float Demo_missiontime = 0.0f;
|
||||
|
||||
// buffer for reading and writing demo stuff
|
||||
#define DEMO_BUF_SIZE 32768
|
||||
char *Demo_buf = NULL;
|
||||
int Demo_buf_pos = 0;
|
||||
|
||||
// # of events posted for this frame
|
||||
int Demo_frame_events = 0;
|
||||
|
||||
// current offset into the demo file - only used for playback
|
||||
int Demo_cur_offset = -1;
|
||||
|
||||
// demo version #
|
||||
#define DEMO_VERSION 2
|
||||
|
||||
// an error reading or writing the demo file
|
||||
int Demo_error = DEMO_ERROR_NONE;
|
||||
|
||||
// all strings read out of the demo file must be no longer than this
|
||||
#define DEMO_STRING_LEN 255
|
||||
|
||||
// macros
|
||||
#define DEMO_DATA_FRAME() do { \
|
||||
if(Demo_file == NULL){\
|
||||
Int3();\
|
||||
DEMO_ERROR(DEMO_ERROR_GENERAL);\
|
||||
break;\
|
||||
}\
|
||||
if(Game_mode & GM_DEMO_RECORD){\
|
||||
if(Demo_buf_pos == 0) {\
|
||||
Int3();\
|
||||
break;\
|
||||
}\
|
||||
if(Demo_frame_events <= 0){\
|
||||
break;\
|
||||
}\
|
||||
if(!cfwrite_ushort((ushort)Demo_buf_pos, Demo_file)){\
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_SPACE);\
|
||||
break;\
|
||||
}\
|
||||
if(!cfwrite(Demo_buf, Demo_buf_pos, 1, Demo_file)){\
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_SPACE);\
|
||||
break;\
|
||||
}\
|
||||
} else if(Game_mode & GM_DEMO_PLAYBACK){\
|
||||
Demo_buf_pos = (int)cfread_ushort(Demo_file);\
|
||||
if(!cfread(Demo_buf, Demo_buf_pos, 1, Demo_file)){\
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
} while(0)
|
||||
#define DEMO_DATA(vl, vl_size) do { if(Demo_buf == NULL){ DEMO_ERROR(DEMO_ERROR_GENERAL); break; } if((Demo_buf_pos + vl_size) >= DEMO_BUF_SIZE){ Int3(); DEMO_ERROR(DEMO_ERROR_FRAMESIZE); break; } if(Game_mode & GM_DEMO_RECORD){ memcpy(Demo_buf + Demo_buf_pos, &vl, vl_size); } else if(Game_mode & GM_DEMO_PLAYBACK){ memcpy(&vl, Demo_buf + Demo_buf_pos, vl_size); } Demo_buf_pos += vl_size; } while(0)
|
||||
#define DEMO_INT(vl) do { DEMO_DATA(vl, sizeof(int)); } while(0)
|
||||
#define DEMO_UINT(vl) do { DEMO_DATA(vl, sizeof(uint)); } while(0)
|
||||
#define DEMO_SHORT(vl) do { DEMO_DATA(vl, sizeof(short)); } while(0)
|
||||
#define DEMO_USHORT(vl) do { DEMO_DATA(vl, sizeof(ushort)); } while(0)
|
||||
#define DEMO_BYTE(vl) do { DEMO_DATA(vl, sizeof(char)); } while(0)
|
||||
#define DEMO_UBYTE(vl) do { DEMO_DATA(vl, sizeof(ubyte)); } while(0)
|
||||
#define DEMO_FLOAT(vl) do { DEMO_DATA(vl, sizeof(float)); } while(0)
|
||||
#define DEMO_VECTOR(vl) do { DEMO_DATA(vl, sizeof(vec3d)); } while(0)
|
||||
#define DEMO_MATRIX(vl) do { DEMO_DATA(vl, sizeof(matrix)); } while(0)
|
||||
#define DEMO_STRING(vl) do { int stlen; if(Game_mode & GM_DEMO_RECORD){ stlen = strlen(vl); if(stlen <= 0){ break; } DEMO_DATA(stlen, sizeof(ushort)); DEMO_DATA(*vl, strlen(vl)); } else { ushort len = 0; DEMO_USHORT(len); DEMO_DATA(*vl, len); vl[len] = '\0'; } } while(0)
|
||||
|
||||
// demo events types
|
||||
#define DE_DUMP 1 // standard object dump
|
||||
#define DE_TRAILER 2 // end of demo trailer
|
||||
#define DE_PRIMARY 3 // primary weapon fired
|
||||
#define DE_UNIQUE_MESSAGE 4 // unique hud message
|
||||
#define DE_BUILTIN_MESSAGE 5 // builtin hud message
|
||||
#define DE_OBJ_CREATE 6 // object create message
|
||||
#define DE_OBJ_WARPIN 7 // ship warpin
|
||||
#define DE_OBJ_WARPOUT 8 // ship warpout
|
||||
#define DE_OBJ_DEPARTED 9 // ship departed
|
||||
#define DE_SHIP_KILL 10 // ship kill
|
||||
|
||||
// call this when posting an error
|
||||
#define DEMO_ERROR(er) do { Demo_error = er; Int3(); } while(0)
|
||||
|
||||
int Demo_make = 0;
|
||||
DCF(demo, "")
|
||||
{
|
||||
Demo_make = !Demo_make;
|
||||
if(Demo_make){
|
||||
dc_printf("Demo will be recorded\n");
|
||||
} else {
|
||||
dc_printf("Demo will NOT be recorded\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO FORWARD DECLARATIONS
|
||||
//
|
||||
|
||||
// write demo header
|
||||
int demo_write_header();
|
||||
|
||||
// read the demo header
|
||||
int demo_read_header();
|
||||
|
||||
// write the demo trailer
|
||||
void demo_write_trailer();
|
||||
|
||||
// do a recording frame
|
||||
void demo_do_recording_frame_start();
|
||||
|
||||
// do a recording frame
|
||||
void demo_do_recording_frame_end();
|
||||
|
||||
// do a playback frame
|
||||
void demo_do_playback_frame();
|
||||
|
||||
// seek through the demo file to the proper location
|
||||
// return 0 on error, 1 on success/continue, 2 if the demo is done
|
||||
int demo_playback_seek();
|
||||
|
||||
// scan through a read in frame of data and apply everything necessary. returns true if the trailer (end of demo) was found
|
||||
int demo_playback_seek_sub(int frame_size);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO FUNCTIONS
|
||||
//
|
||||
|
||||
// do frame for the demo - playback and recording, returns 0 if errors were encountered during frame processing
|
||||
int demo_do_frame_start()
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 1;
|
||||
#else
|
||||
// if we're not doing any demo stuff
|
||||
if(!(Game_mode & GM_DEMO)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// bad
|
||||
if(Demo_file == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure we're not trying to record and playback at the same time
|
||||
Assert( ((Game_mode & GM_DEMO_RECORD) && !(Game_mode & GM_DEMO_PLAYBACK)) || (!(Game_mode & GM_DEMO_RECORD) && (Game_mode & GM_DEMO_PLAYBACK)) );
|
||||
|
||||
// recording
|
||||
if(Game_mode & GM_DEMO_RECORD){
|
||||
demo_do_recording_frame_start();
|
||||
} else {
|
||||
demo_do_playback_frame();
|
||||
}
|
||||
|
||||
// bad bad bad, get mwa
|
||||
if(Demo_error){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// continue
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// do frame for the demo - playback and recording, returns 0 if errors were encountered during frame processing
|
||||
int demo_do_frame_end()
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 1;
|
||||
#else
|
||||
// if we're not doing any demo stuff
|
||||
if(!(Game_mode & GM_DEMO)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// bad
|
||||
if(Demo_file == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure we're not trying to record and playback at the same time
|
||||
Assert( ((Game_mode & GM_DEMO_RECORD) && !(Game_mode & GM_DEMO_PLAYBACK)) || (!(Game_mode & GM_DEMO_RECORD) && (Game_mode & GM_DEMO_PLAYBACK)) );
|
||||
|
||||
// recording. there's nothing to do here for playback
|
||||
if(Game_mode & GM_DEMO_RECORD){
|
||||
demo_do_recording_frame_end();
|
||||
}
|
||||
|
||||
// bad bad bad, get mwa
|
||||
if(Demo_error){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// continue
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// initialize a demo for recording
|
||||
// NOTE : call this after loading the mission and going through the briefing, but _before_ physically moving into the mission
|
||||
int demo_start_record(char *file)
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
char full_name[MAX_FILENAME_LEN] = "";
|
||||
|
||||
// try and allocate the buffer
|
||||
Demo_buf = (char*)vm_malloc(DEMO_BUF_SIZE);
|
||||
if(Demo_buf == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// open the outfile
|
||||
strcpy_s(full_name, file);
|
||||
cf_add_ext(full_name, ".fsd");
|
||||
Demo_file = cfopen(full_name, "wb", CFILE_NORMAL, CF_TYPE_DEMOS);
|
||||
if(Demo_file == NULL){
|
||||
Int3();
|
||||
Demo_error = DEMO_ERROR_DISK_ACCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// no errors
|
||||
Demo_error = DEMO_ERROR_NONE;
|
||||
|
||||
// write the header
|
||||
if(!demo_write_header()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// flag demo mode
|
||||
Game_mode |= GM_DEMO_RECORD;
|
||||
|
||||
// no events yet
|
||||
Demo_frame_events = 0;
|
||||
|
||||
// success
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// initialize a demo for playback - calling this will load up the demo file and move the player into the playback state
|
||||
int demo_start_playback(char *file)
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
char full_name[MAX_FILENAME_LEN] = "";
|
||||
|
||||
// try and allocate the buffer
|
||||
Demo_buf = (char*)vm_malloc(DEMO_BUF_SIZE);
|
||||
if(Demo_buf == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// open the outfile
|
||||
strcpy_s(full_name, file);
|
||||
cf_add_ext(full_name, ".fsd");
|
||||
Demo_file = cfopen(full_name, "rb", CFILE_NORMAL, CF_TYPE_DEMOS);
|
||||
if(Demo_file == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// no errors
|
||||
Demo_error = DEMO_ERROR_NONE;
|
||||
|
||||
// read the header
|
||||
Demo_cur_offset = -1;
|
||||
if(!demo_read_header()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// flag demo mode
|
||||
Game_mode |= GM_DEMO_PLAYBACK;
|
||||
|
||||
// everything is cool, so jump into the mission
|
||||
gameseq_post_event(GS_EVENT_ENTER_GAME);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// finish the demo
|
||||
void demo_close()
|
||||
{
|
||||
#ifdef DEMO_SYSTEM
|
||||
// if we're recording, write the trailer
|
||||
if(Game_mode & GM_DEMO_RECORD){
|
||||
demo_write_trailer();
|
||||
}
|
||||
|
||||
// close the demo file
|
||||
if(Demo_file != NULL){
|
||||
cfclose(Demo_file);
|
||||
Demo_file = NULL;
|
||||
}
|
||||
|
||||
// free the buffer
|
||||
if(Demo_buf != NULL){
|
||||
vm_free(Demo_buf);
|
||||
Demo_buf = NULL;
|
||||
}
|
||||
|
||||
// if we're playing back, go back to the main hall
|
||||
if(Game_mode & GM_DEMO_PLAYBACK){
|
||||
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
||||
}
|
||||
|
||||
// unflag demo mode
|
||||
Game_mode &= ~(GM_DEMO_RECORD | GM_DEMO_PLAYBACK);
|
||||
#endif
|
||||
}
|
||||
|
||||
// if we should run the simulation for this object, or let the demo system handle it
|
||||
int demo_should_sim(object *objp)
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 1;
|
||||
#else
|
||||
// always sim stuff in non-demo mode
|
||||
if(!(Game_mode & GM_DEMO)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// don't sim ships or missiles
|
||||
if((objp->type == OBJ_SHIP) || ((objp->type == OBJ_WEAPON) && (objp->instance >= 0) && (Weapon_info[Weapons[objp->instance].weapon_info_index].subtype == WP_MISSILE))){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// sim everything else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO RECORDING FUNCTIONS
|
||||
//
|
||||
|
||||
// write demo header
|
||||
int demo_write_header()
|
||||
{
|
||||
uint chksum;
|
||||
char *full_name;
|
||||
|
||||
// write demo version #
|
||||
if(!cfwrite_int(DEMO_VERSION, Demo_file)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write mission filename
|
||||
if(!cfwrite_string_len(Game_current_mission_filename, Demo_file)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write mission checksum
|
||||
full_name = cf_add_ext(Game_current_mission_filename, FS_MISSION_FILE_EXT);
|
||||
cf_chksum_long(full_name, &chksum);
|
||||
if(!cfwrite_int(chksum, Demo_file)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
// write the demo trailer
|
||||
void demo_write_trailer()
|
||||
{
|
||||
// start a new chunk
|
||||
demo_do_recording_frame_start();
|
||||
|
||||
// trailer event
|
||||
ubyte frame_type = DE_TRAILER;
|
||||
DEMO_UBYTE(frame_type);
|
||||
|
||||
// 1 event
|
||||
Demo_frame_events++;
|
||||
|
||||
// write frame data to disk
|
||||
DEMO_DATA_FRAME();
|
||||
}
|
||||
|
||||
// start recording frame
|
||||
void demo_do_recording_frame_start()
|
||||
{
|
||||
// if we're not physically doing the mission
|
||||
if(gameseq_get_state() != GS_STATE_GAME_PLAY){
|
||||
return;
|
||||
}
|
||||
|
||||
// add in frametime
|
||||
Demo_missiontime += flFrametime;
|
||||
|
||||
// clear the buffer, set no events, and write the header
|
||||
Demo_buf_pos = 0;
|
||||
Demo_frame_events = 0;
|
||||
|
||||
// missiontime
|
||||
float fl_time = f2fl(Missiontime);
|
||||
DEMO_FLOAT(fl_time);
|
||||
}
|
||||
|
||||
// end recording frame
|
||||
void demo_do_recording_frame_end()
|
||||
{
|
||||
// if we're not physically doing the mission
|
||||
if(gameseq_get_state() != GS_STATE_GAME_PLAY){
|
||||
return;
|
||||
}
|
||||
|
||||
// if its time to dump objects (the last thing we might dump per frame)
|
||||
if((Demo_stamp == -1) || timestamp_elapsed(Demo_stamp)){
|
||||
// post an object dump event
|
||||
demo_POST_object_dump();
|
||||
|
||||
// reset the stamp
|
||||
Demo_stamp = timestamp(Demo_fps);
|
||||
}
|
||||
|
||||
// write all accumulated frame data to disk if necessary
|
||||
DEMO_DATA_FRAME();
|
||||
}
|
||||
|
||||
// post an object dump event
|
||||
void demo_POST_object_dump()
|
||||
{
|
||||
ship_obj *sobjp;
|
||||
object *objp;
|
||||
ushort obj_count;
|
||||
ubyte team;
|
||||
|
||||
// object dump event
|
||||
ubyte event_type = DE_DUMP;
|
||||
DEMO_UBYTE(event_type);
|
||||
|
||||
// go through the ship list and count
|
||||
obj_count = 0;
|
||||
for ( sobjp = GET_FIRST(&Ship_obj_list); sobjp !=END_OF_LIST(&Ship_obj_list); sobjp = GET_NEXT(sobjp) ){
|
||||
// object pointer
|
||||
if(sobjp->objnum < 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
obj_count++;
|
||||
}
|
||||
|
||||
// write out the object count
|
||||
DEMO_USHORT(obj_count);
|
||||
|
||||
// go through the ship list and dump necessary stuff
|
||||
for ( sobjp = GET_FIRST(&Ship_obj_list); sobjp !=END_OF_LIST(&Ship_obj_list); sobjp = GET_NEXT(sobjp) ){
|
||||
// object pointer
|
||||
if(sobjp->objnum < 0){
|
||||
continue;
|
||||
}
|
||||
objp = &Objects[sobjp->objnum];
|
||||
|
||||
// just ships for now
|
||||
DEMO_INT(objp->signature);
|
||||
DEMO_VECTOR(objp->pos);
|
||||
DEMO_MATRIX(objp->orient);
|
||||
DEMO_FLOAT(objp->phys_info.forward_thrust);
|
||||
team = (ubyte)Ships[objp->instance].team;
|
||||
DEMO_UBYTE(team);
|
||||
DEMO_INT(Ships[objp->instance].flags);
|
||||
}
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a primary fired event
|
||||
void demo_POST_primary_fired(object *objp, int banks, int linked)
|
||||
{
|
||||
ubyte fire_info = 0;
|
||||
|
||||
// object dump event
|
||||
ubyte event_type = DE_PRIMARY;
|
||||
DEMO_UBYTE(event_type);
|
||||
|
||||
// object signature
|
||||
DEMO_INT(objp->signature);
|
||||
|
||||
// get fire info
|
||||
fire_info = (ubyte)banks;
|
||||
fire_info &= ~(1<<7);
|
||||
if(linked){
|
||||
fire_info |= (1<<7);
|
||||
}
|
||||
DEMO_UBYTE(fire_info);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a unique message
|
||||
void demo_POST_unique_message(char *id, char *who_from, int m_source, int priority)
|
||||
{
|
||||
// sanity
|
||||
if((id == NULL) || (who_from == NULL) || (strlen(id) <= 0) || (strlen(who_from) <= 0)){
|
||||
return;
|
||||
}
|
||||
|
||||
// write it
|
||||
ubyte event = DE_UNIQUE_MESSAGE;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_STRING(id);
|
||||
DEMO_STRING(who_from);
|
||||
DEMO_INT(m_source);
|
||||
DEMO_INT(priority);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a builtin message
|
||||
void demo_POST_builtin_message(int type, ship *shipp, int priority, int timing)
|
||||
{
|
||||
int sig = 0;
|
||||
|
||||
// write it
|
||||
ubyte event = DE_BUILTIN_MESSAGE;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(type);
|
||||
if(shipp == NULL){
|
||||
sig = -1;
|
||||
} else if(shipp->objnum >= 0){
|
||||
sig = Objects[shipp->objnum].signature;
|
||||
}
|
||||
DEMO_INT(sig);
|
||||
DEMO_INT(priority);
|
||||
DEMO_INT(timing);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post an object create message
|
||||
void demo_POST_obj_create(char *pobj_name, int signature)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_CREATE;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_STRING(pobj_name);
|
||||
DEMO_INT(signature);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a warpin event
|
||||
void demo_POST_warpin(int signature, int ship_flags)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_WARPIN;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(signature);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a warpout event
|
||||
void demo_POST_warpout(int signature, int ship_flags)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_WARPOUT;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(signature);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a departed event
|
||||
void demo_POST_departed(int signature, int ship_flags)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_DEPARTED;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(signature);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a ship kill event
|
||||
void demo_POST_ship_kill(object *objp)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_SHIP_KILL;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(objp->signature);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO PLAYBACK FUNCTIONS
|
||||
//
|
||||
|
||||
// read the demo header
|
||||
int demo_read_header()
|
||||
{
|
||||
int version;
|
||||
uint file_checksum, my_checksum;
|
||||
char *full_name;
|
||||
|
||||
// read the version #
|
||||
version = cfread_int(Demo_file);
|
||||
if(version != DEMO_VERSION){
|
||||
DEMO_ERROR(DEMO_ERROR_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read mission filename
|
||||
cfread_string_len(Game_current_mission_filename, MAX_FILENAME_LEN, Demo_file);
|
||||
|
||||
// get mission checksum
|
||||
file_checksum = cfread_int(Demo_file);
|
||||
full_name = cf_add_ext(Game_current_mission_filename, FS_MISSION_FILE_EXT);
|
||||
if(!cf_chksum_long(full_name, &my_checksum)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
if(file_checksum != my_checksum){
|
||||
DEMO_ERROR(DEMO_ERROR_MISSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get the file offset of this first frame
|
||||
Demo_cur_offset = cftell(Demo_file);
|
||||
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
// do a playback frame
|
||||
void demo_do_playback_frame()
|
||||
{
|
||||
// seek to the best location in the demo file
|
||||
switch(demo_playback_seek()){
|
||||
// error
|
||||
case 0:
|
||||
return;
|
||||
|
||||
// continue
|
||||
case 1:
|
||||
break;
|
||||
|
||||
// found the trailer - this demo is done
|
||||
case 2:
|
||||
demo_close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// seek through the demo file to the proper location
|
||||
// return 0 on error, 1 on success/continue, 2 if the demo is done
|
||||
int demo_playback_seek()
|
||||
{
|
||||
float this_time = 0.0f;
|
||||
int frame_size;
|
||||
int this_offset;
|
||||
int ret = 0;
|
||||
|
||||
// scan until we find something useful
|
||||
while(1){
|
||||
// record the beginning of this chunk
|
||||
this_offset = cftell(Demo_file);
|
||||
|
||||
// read in the data for the next frame
|
||||
DEMO_DATA_FRAME();
|
||||
frame_size = Demo_buf_pos;
|
||||
Demo_buf_pos = 0;
|
||||
|
||||
// check the time
|
||||
DEMO_FLOAT(this_time);
|
||||
|
||||
// ahead of us
|
||||
if(this_time > f2fl(Missiontime)){
|
||||
// success
|
||||
ret = 1;
|
||||
|
||||
// seek back to the beginning of this chunk
|
||||
Demo_cur_offset = this_offset;
|
||||
|
||||
// bust out
|
||||
break;
|
||||
}
|
||||
// we should scan through this chunk
|
||||
else {
|
||||
// returns true if it finds the demo trailer
|
||||
if(demo_playback_seek_sub(frame_size)){
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// seek back to the new frame
|
||||
cfseek(Demo_file, Demo_cur_offset, CF_SEEK_SET);
|
||||
|
||||
// return
|
||||
return ret;
|
||||
}
|
||||
|
||||
// scan through a read in frame of data and apply everything necessary. returns true if the trailer (end of demo) was found
|
||||
int demo_playback_seek_sub(int frame_size)
|
||||
{
|
||||
ubyte event = 0;
|
||||
int idx;
|
||||
|
||||
// apply everything
|
||||
while(Demo_buf_pos < frame_size){
|
||||
// next event
|
||||
DEMO_UBYTE(event);
|
||||
|
||||
// process it
|
||||
switch(event){
|
||||
// oops, trailer. we're done
|
||||
case DE_TRAILER:
|
||||
return 1;
|
||||
|
||||
// object dump
|
||||
case DE_DUMP: {
|
||||
ushort obj_count = 0;
|
||||
int obj_sig = 0;
|
||||
ubyte team = 0;
|
||||
vec3d obj_pos = vmd_zero_vector;
|
||||
matrix obj_orient = vmd_identity_matrix;
|
||||
float obj_fthrust = 0;
|
||||
int ship_index = 0;
|
||||
int ship_flags = 0;
|
||||
|
||||
// get the object count
|
||||
DEMO_USHORT(obj_count);
|
||||
|
||||
// read in all the objects
|
||||
for(idx=0; idx<obj_count; idx++){
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_VECTOR(obj_pos);
|
||||
DEMO_MATRIX(obj_orient);
|
||||
DEMO_FLOAT(obj_fthrust);
|
||||
DEMO_UBYTE(team);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// find our ship object
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
// Assert(ship_index >= 0);
|
||||
if(ship_index >= 0){
|
||||
Objects[Ships[ship_index].objnum].pos = obj_pos;
|
||||
Objects[Ships[ship_index].objnum].orient = obj_orient;
|
||||
Objects[Ships[ship_index].objnum].phys_info.forward_thrust = obj_fthrust;
|
||||
Ships[ship_index].team = team;
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// primary fired
|
||||
case DE_PRIMARY: {
|
||||
int obj_sig = 0 ;
|
||||
ubyte fire_info = 0;
|
||||
int ship_index = -1;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_UBYTE(fire_info);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].weapons.current_primary_bank = (int)(fire_info & ~(1<<7));
|
||||
if(fire_info & (1<<7)){
|
||||
Ships[ship_index].flags |= SF_PRIMARY_LINKED;
|
||||
} else {
|
||||
Ships[ship_index].flags &= ~(SF_PRIMARY_LINKED);
|
||||
}
|
||||
|
||||
// fire
|
||||
ship_fire_primary(&Objects[Ships[ship_index].objnum], 0, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// unique message
|
||||
case DE_UNIQUE_MESSAGE: {
|
||||
char id[255] = "";
|
||||
char who_from[255] = "";
|
||||
int m_source = 0;
|
||||
int priority = 0;
|
||||
|
||||
// read the stuff in
|
||||
DEMO_STRING(id);
|
||||
DEMO_STRING(who_from);
|
||||
DEMO_INT(m_source);
|
||||
DEMO_INT(priority);
|
||||
|
||||
// send the message
|
||||
message_send_unique_to_player(id, who_from, m_source, priority, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
// builtin message
|
||||
case DE_BUILTIN_MESSAGE:{
|
||||
int type = 0;
|
||||
int sig = 0;
|
||||
int ship_index = 0;
|
||||
int priority = 0;
|
||||
int timing = 0;
|
||||
|
||||
// get data and ship
|
||||
DEMO_INT(type);
|
||||
DEMO_INT(sig);
|
||||
DEMO_INT(priority);
|
||||
DEMO_INT(timing);
|
||||
if(sig == -1){
|
||||
// message_send_builtin_to_player(type, NULL, priority, timing, 0, 0);
|
||||
} else {
|
||||
ship_index = ship_get_by_signature(sig);
|
||||
if(ship_index >= 0){
|
||||
// message_send_builtin_to_player(type, &Ships[ship_index], priority, timing, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// obj create
|
||||
case DE_OBJ_CREATE:{
|
||||
char pobj_name[255] = "";
|
||||
int obj_sig = 0;
|
||||
int objnum = 0;
|
||||
p_object *objp = NULL;
|
||||
|
||||
// try and create the ship
|
||||
DEMO_STRING(pobj_name);
|
||||
DEMO_INT(obj_sig);
|
||||
|
||||
objp = mission_parse_get_arrival_ship( pobj_name );
|
||||
if(objp != NULL){
|
||||
objnum = parse_create_object(objp);
|
||||
if(objnum >= 0){
|
||||
Objects[objnum].signature = obj_sig;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// warpin effect
|
||||
case DE_OBJ_WARPIN:{
|
||||
int obj_sig = 0;
|
||||
int ship_flags = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_INT(ship_flags);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
shipfx_warpin_start(&Objects[Ships[ship_index].objnum]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// warpout effect
|
||||
case DE_OBJ_WARPOUT:{
|
||||
int obj_sig = 0;
|
||||
int ship_flags = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_INT(ship_flags);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
shipfx_warpout_start(&Objects[Ships[ship_index].objnum]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// departed
|
||||
case DE_OBJ_DEPARTED:{
|
||||
int obj_sig = 0;
|
||||
int ship_flags = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_INT(ship_flags);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
ship_actually_depart(ship_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// ship kill
|
||||
case DE_SHIP_KILL:{
|
||||
int obj_sig = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Objects[Ships[ship_index].objnum].hull_strength = 0.0f;
|
||||
ship_generic_kill_stuff(&Objects[Ships[ship_index].objnum], 1.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _FS2_DEMO_SYSTEM_HEADER_FILE
|
||||
#define _FS2_DEMO_SYSTEM_HEADER_FILE
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO DEFINES/VARS
|
||||
//
|
||||
|
||||
// compile in the demo system
|
||||
#define DEMO_SYSTEM
|
||||
|
||||
struct object;
|
||||
struct ship;
|
||||
|
||||
// an error reading or writing the demo file
|
||||
#define DEMO_ERROR_NONE 0 // no error
|
||||
#define DEMO_ERROR_GENERAL 1 // general problem
|
||||
#define DEMO_ERROR_FRAMESIZE 2 // frame size was too big (> 32k)
|
||||
#define DEMO_ERROR_DISK_SPACE 3 // out of disk space
|
||||
#define DEMO_ERROR_DISK_ACCESS 4 // problem accessing disk
|
||||
#define DEMO_ERROR_VERSION 5 // bad version #
|
||||
#define DEMO_ERROR_MISSION 6 // different mission file checksums
|
||||
extern int Demo_error;
|
||||
|
||||
extern int Demo_make;
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO FUNCTIONS
|
||||
//
|
||||
|
||||
// do frame for the demo - start for the frame
|
||||
int demo_do_frame_start();
|
||||
|
||||
// do frame for the demo - end for the frame
|
||||
int demo_do_frame_end();
|
||||
|
||||
// initialize a demo for recording
|
||||
// NOTE : call this after loading the mission and going through the briefing, but _before_ physically moving into the mission
|
||||
int demo_start_record(char *file);
|
||||
|
||||
// initialize a demo for playback - calling this will load up the demo file and move the player into the playback state
|
||||
int demo_start_playback(char *file);
|
||||
|
||||
// finish the demo, whether recording or playing back
|
||||
void demo_close();
|
||||
|
||||
// if we should run the simulation for this object, or let the demo system handle it
|
||||
int demo_should_sim(object *objp);
|
||||
|
||||
|
||||
// functions for posting critical events to the demo system ------------------------------------------------------------
|
||||
|
||||
// post an object dump event (only used internally)
|
||||
void demo_POST_object_dump();
|
||||
|
||||
// post a primary fired event
|
||||
void demo_POST_primary_fired(object *objp, int banks, int linked);
|
||||
|
||||
// post a unique message
|
||||
void demo_POST_unique_message(char *id, char *who_from, int m_source, int priority);
|
||||
|
||||
// post a builtin message
|
||||
void demo_POST_builtin_message(int type, ship *shipp, int priority, int timing);
|
||||
|
||||
// post an object create message
|
||||
void demo_POST_obj_create(char *pobj_name, int signature);
|
||||
|
||||
// post a warpin event
|
||||
void demo_POST_warpin(int signature, int ship_flags);
|
||||
|
||||
// post a warpout event
|
||||
void demo_POST_warpout(int signature, int ship_flags);
|
||||
|
||||
// post a departed event
|
||||
void demo_POST_departed(int signature, int ship_flags);
|
||||
|
||||
// post a ship kill event
|
||||
void demo_POST_ship_kill(object *objp);
|
||||
|
||||
#endif
|
||||
+110
-118
@@ -20,7 +20,6 @@
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -48,6 +47,7 @@ fireball_info Fireball_info[MAX_FIREBALL_TYPES];
|
||||
int fireball_used[MAX_FIREBALL_TYPES];
|
||||
|
||||
int Num_fireballs = 0;
|
||||
|
||||
int Num_fireball_types = 0;
|
||||
|
||||
int fireballs_inited = 0;
|
||||
@@ -57,9 +57,7 @@ int Warp_ball_bitmap = -1;
|
||||
|
||||
#define FB_INDEX(fb) (fb-Fireballs)
|
||||
|
||||
/**
|
||||
* Play warp in sound for warp effect
|
||||
*/
|
||||
// play warp in sound for warp effect
|
||||
void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
|
||||
{
|
||||
int sound_index;
|
||||
@@ -89,9 +87,7 @@ void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
|
||||
snd_play_3d(&Snds[sound_index], &fireball_objp->pos, &Eye_position, fireball_objp->radius, NULL, 0, 1.0f, SND_PRIORITY_DOUBLE_INSTANCE, NULL, range_multiplier); // play warp sound effect
|
||||
}
|
||||
|
||||
/**
|
||||
* Play warp out sound for warp effect
|
||||
*/
|
||||
// play warp out sound for warp effect
|
||||
void fireball_play_warphole_close_sound(fireball *fb)
|
||||
{
|
||||
int sound_index;
|
||||
@@ -107,15 +103,14 @@ void fireball_play_warphole_close_sound(fireball *fb)
|
||||
} else if ( fb->flags & FBF_WARP_CAPITAL_SIZE ) {
|
||||
sound_index = SND_CAPITAL_WARP_OUT;
|
||||
} else {
|
||||
// AL 27-3-98: Decided that warphole closing is only required for capital ship sized warp effects.
|
||||
return;
|
||||
}
|
||||
|
||||
snd_play_3d(&Snds[sound_index], &fireball_objp->pos, &Eye_position, fireball_objp->radius); // play warp sound effect
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default colors for each explosion type (original values from object.cpp)
|
||||
*/
|
||||
// set default colors for each explosion type (original values from object.cpp)
|
||||
static void fireball_set_default_color(int idx)
|
||||
{
|
||||
Assert( (idx >= 0) && (idx < MAX_FIREBALL_TYPES) );
|
||||
@@ -152,11 +147,7 @@ static void fireball_set_default_color(int idx)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse fireball tbl
|
||||
*
|
||||
* NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
|
||||
*/
|
||||
// NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
|
||||
void parse_fireball_tbl(char *filename)
|
||||
{
|
||||
int rval;
|
||||
@@ -248,8 +239,7 @@ void parse_fireball_tbl(char *filename)
|
||||
|
||||
void fireball_parse_tbl()
|
||||
{
|
||||
int i = 0, j;
|
||||
SCP_vector<lod_checker>::iterator lod;
|
||||
int i, j;
|
||||
|
||||
memset( &Fireball_info, 0, sizeof(fireball_info) * MAX_FIREBALL_TYPES );
|
||||
|
||||
@@ -261,10 +251,10 @@ void fireball_parse_tbl()
|
||||
|
||||
// we've got our list so pass it off for final checking and loading.
|
||||
// we assume that entries in fireball.tbl are in the correct order
|
||||
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
|
||||
if ( (i < MAX_FIREBALL_TYPES) && (lod->override < 0) ) {
|
||||
strcpy_s( Fireball_info[i].lod[0].filename, lod->filename );
|
||||
Fireball_info[i].lod_count = lod->num_lods;
|
||||
for (i = 0; i < (int)LOD_checker.size(); i++) {
|
||||
if ( (i < MAX_FIREBALL_TYPES) && (LOD_checker[i].override < 0) ) {
|
||||
strcpy_s( Fireball_info[i].lod[0].filename, LOD_checker[i].filename );
|
||||
Fireball_info[i].lod_count = LOD_checker[i].num_lods;
|
||||
Num_fireball_types++;
|
||||
|
||||
if (LOD_color[i].alpha == 255) {
|
||||
@@ -275,24 +265,22 @@ void fireball_parse_tbl()
|
||||
fireball_set_default_color(i);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// having to do this twice is less than optimal, but less error prone too.
|
||||
// this handles (and should only have to handle) TBM related entries
|
||||
i = 0;
|
||||
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
|
||||
for (i = 0; i < (int)LOD_checker.size(); i++) {
|
||||
// try entry replacement
|
||||
if ( (lod->override >= 0) && (lod->override < Num_fireball_types) ) {
|
||||
strcpy_s( Fireball_info[lod->override].lod[0].filename, lod->filename );
|
||||
Fireball_info[lod->override].lod_count = lod->num_lods;
|
||||
if ( (LOD_checker[i].override >= 0) && (LOD_checker[i].override < Num_fireball_types) ) {
|
||||
strcpy_s( Fireball_info[LOD_checker[i].override].lod[0].filename, LOD_checker[i].filename );
|
||||
Fireball_info[LOD_checker[i].override].lod_count = LOD_checker[i].num_lods;
|
||||
|
||||
if (LOD_color[i].alpha == 255) {
|
||||
Fireball_info[lod->override].exp_color[0] = (LOD_color[i].red / 255.0f);
|
||||
Fireball_info[lod->override].exp_color[1] = (LOD_color[i].green / 255.0f);
|
||||
Fireball_info[lod->override].exp_color[2] = (LOD_color[i].blue / 255.0f);
|
||||
Fireball_info[LOD_checker[i].override].exp_color[0] = (LOD_color[i].red / 255.0f);
|
||||
Fireball_info[LOD_checker[i].override].exp_color[1] = (LOD_color[i].green / 255.0f);
|
||||
Fireball_info[LOD_checker[i].override].exp_color[2] = (LOD_color[i].blue / 255.0f);
|
||||
} else {
|
||||
fireball_set_default_color(lod->override);
|
||||
fireball_set_default_color(LOD_checker[i].override);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,6 +323,15 @@ void fireball_load_data()
|
||||
if ( Warp_ball_bitmap == -1 ) {
|
||||
Warp_ball_bitmap = bm_load( NOX("warpball01") );
|
||||
}
|
||||
|
||||
// polymodel Warp_pm;
|
||||
|
||||
}
|
||||
|
||||
void fireball_preload()
|
||||
{
|
||||
// Do nothing. Called before level init, this used to page in warp effect.
|
||||
// Not needed with new BmpMan system.
|
||||
}
|
||||
|
||||
// This will get called at the start of each level.
|
||||
@@ -375,6 +372,8 @@ MONITOR( NumFireballsRend )
|
||||
|
||||
void fireball_render(object * obj)
|
||||
{
|
||||
// if(!Cmdline_nohtl)gr_set_lighting(false,false);
|
||||
|
||||
int num;
|
||||
vertex p;
|
||||
fireball *fb;
|
||||
@@ -389,6 +388,10 @@ void fireball_render(object * obj)
|
||||
if ( Fireballs[num].current_bitmap < 0 )
|
||||
return;
|
||||
|
||||
// gr_set_color( 0, 100, 0 );
|
||||
// g3_draw_sphere_ez( &obj->pos, obj->radius );
|
||||
// return;
|
||||
|
||||
// turn off fogging
|
||||
if(The_mission.flags & MISSION_FLAG_FULLNEB){
|
||||
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
|
||||
@@ -403,24 +406,14 @@ void fireball_render(object * obj)
|
||||
switch( fb->fireball_render_type ) {
|
||||
|
||||
case FIREBALL_MEDIUM_EXPLOSION:
|
||||
batch_add_bitmap (
|
||||
Fireballs[num].current_bitmap,
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
|
||||
&p,
|
||||
fb->orient,
|
||||
obj->radius
|
||||
);
|
||||
gr_set_bitmap(Fireballs[num].current_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.3f );
|
||||
g3_draw_bitmap(&p, fb->orient, obj->radius, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
||||
break;
|
||||
|
||||
case FIREBALL_LARGE_EXPLOSION:
|
||||
// Make the big explosions rotate with the viewer.
|
||||
batch_add_bitmap_rotated (
|
||||
Fireballs[num].current_bitmap,
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
|
||||
&p,
|
||||
(i2fl(fb->orient)*PI)/180.0f,
|
||||
obj->radius
|
||||
);
|
||||
gr_set_bitmap(Fireballs[num].current_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.3f );
|
||||
g3_draw_rotated_bitmap(&p, (i2fl(fb->orient)*PI)/180.0f, obj->radius, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
|
||||
break;
|
||||
|
||||
case FIREBALL_WARP_EFFECT: {
|
||||
@@ -434,11 +427,17 @@ void fireball_render(object * obj)
|
||||
|
||||
if ( t < WARPHOLE_GROW_TIME ) {
|
||||
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
//rad = t*obj->radius/WARPHOLE_GROW_TIME;
|
||||
//mprintf(( "T=%.2f, Rad = %.2f\n", t, rad ));
|
||||
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
|
||||
rad = obj->radius;
|
||||
} else {
|
||||
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
//rad = (fb->total_time - t )*obj->radius/WARPHOLE_GROW_TIME;
|
||||
}
|
||||
//rad = obj->radius;
|
||||
// obj->alt_rad = rad;
|
||||
|
||||
|
||||
warpin_render(obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
|
||||
}
|
||||
@@ -450,10 +449,12 @@ void fireball_render(object * obj)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a fireball.
|
||||
* Called by object_delete() code... do not call directly.
|
||||
*/
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_delete()
|
||||
//
|
||||
// Delete a fireball. Called by object_delete() code... do not call
|
||||
// directly.
|
||||
//
|
||||
void fireball_delete( object * obj )
|
||||
{
|
||||
int num;
|
||||
@@ -469,9 +470,11 @@ void fireball_delete( object * obj )
|
||||
Assert( Num_fireballs >= 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all active fireballs, by calling obj_delete directly.
|
||||
*/
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_delete_all()
|
||||
//
|
||||
// Delete all active fireballs, by calling obj_delete directly.
|
||||
//
|
||||
void fireball_delete_all()
|
||||
{
|
||||
fireball *fb;
|
||||
@@ -561,12 +564,12 @@ int fireball_is_perishable(object * obj)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* There are too many fireballs, so delete the oldest small one
|
||||
* to free up a slot.
|
||||
*
|
||||
* @return The fireball slot freed.
|
||||
*/
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_free_one()
|
||||
//
|
||||
// There are too many fireballs, so delete the oldest small one
|
||||
// to free up a slot. Returns the fireball slot freed.
|
||||
//
|
||||
int fireball_free_one()
|
||||
{
|
||||
fireball *fb;
|
||||
@@ -597,6 +600,12 @@ int fireball_free_one()
|
||||
return oldest_slotnum;
|
||||
}
|
||||
|
||||
// broke fireball_move into fireball_process_pre and fireball_process_post as was done
|
||||
// with all *_move functions on 8/13 by Mike K. and Mark A.
|
||||
void fireball_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}
|
||||
|
||||
int fireball_is_warp(object * obj)
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -662,9 +671,7 @@ void fireball_process_post(object * obj, float frame_time)
|
||||
fireball_set_framenum(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns life left of a fireball in seconds
|
||||
*/
|
||||
// Returns life left of a fireball in seconds
|
||||
float fireball_lifeleft( object *obj )
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -679,9 +686,7 @@ float fireball_lifeleft( object *obj )
|
||||
return fb->total_time - fb->time_elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns life left of a fireball in percent
|
||||
*/
|
||||
// Returns life left of a fireball in percent
|
||||
float fireball_lifeleft_percent( object *obj )
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -693,14 +698,14 @@ float fireball_lifeleft_percent( object *obj )
|
||||
|
||||
fb = &Fireballs[num];
|
||||
|
||||
// Assert((fb->total_time - fb->time_elapsed) / fb->total_time >=0);
|
||||
|
||||
float p = (fb->total_time - fb->time_elapsed) / fb->total_time;
|
||||
if (p < 0)p=0.0f;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine LOD to use
|
||||
*/
|
||||
// determine LOD to use
|
||||
int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
|
||||
{
|
||||
vertex v;
|
||||
@@ -781,9 +786,7 @@ int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
|
||||
return MIN(ret_lod, fd->lod_count - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fireball, return object index.
|
||||
*/
|
||||
// Create a fireball, return object index.
|
||||
int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, int warp_open_sound, int warp_close_sound)
|
||||
{
|
||||
int n, objnum, fb_lod;
|
||||
@@ -808,11 +811,22 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
}
|
||||
|
||||
if ( (Num_fireballs >= MAX_FIREBALLS) || (Num_objects >= MAX_OBJECTS) ) {
|
||||
// who cares if we don't create a spark.
|
||||
// JAS - Should this code be in? Is it better to remove an old spark
|
||||
// and start a new one, or just not start the new one?
|
||||
//if ( fd->type == FIREBALL_TYPE_SMALL ) {
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
//mprintf(( "Out of fireball slots, trying to free one up!\n" ));
|
||||
// out of slots, so free one up.
|
||||
n = fireball_free_one();
|
||||
if ( n < 0 ) {
|
||||
if ( n < 0 ) {
|
||||
// If there's still no free slots, then exit
|
||||
//mprintf(( "ERROR: Couldn't free one up!!\n" ));
|
||||
return -1;
|
||||
} else {
|
||||
//mprintf(( "Freed one up just fine!!\n" ));
|
||||
}
|
||||
} else {
|
||||
for ( n = 0; n < MAX_FIREBALLS; n++ ) {
|
||||
@@ -836,6 +850,11 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
|
||||
// if this is a warpout fireball, never go higher than LOD 1
|
||||
if(fireball_type == FIREBALL_WARP){
|
||||
/*
|
||||
if(fb_lod > 1){
|
||||
fb_lod = 1;
|
||||
}
|
||||
*/
|
||||
fb_lod = MAX_WARP_LOD;
|
||||
}
|
||||
fl = &fd->lod[fb_lod];
|
||||
@@ -903,9 +922,7 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
}
|
||||
|
||||
if ( fb->fireball_render_type == FIREBALL_WARP_EFFECT ) {
|
||||
Assert( warp_lifetime >= 4.0f ); // Warp lifetime must be at least 4 seconds!
|
||||
if ( warp_lifetime < 4.0f )
|
||||
warp_lifetime = 4.0f;
|
||||
Assert( warp_lifetime > 4.0f ); // Warp lifetime must be at least 4 seconds!
|
||||
fb->total_time = warp_lifetime; // in seconds
|
||||
} else {
|
||||
fb->total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
|
||||
@@ -930,9 +947,11 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
return objnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at game shutdown to clean up the fireball system
|
||||
*/
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_close()
|
||||
//
|
||||
// Called at game shutdown to clean up the fireball system
|
||||
//
|
||||
void fireball_close()
|
||||
{
|
||||
if ( !fireballs_inited )
|
||||
@@ -941,6 +960,20 @@ void fireball_close()
|
||||
fireball_delete_all();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_level_close()
|
||||
//
|
||||
// Called when a mission ends... frees up any animations that might
|
||||
// be partially played
|
||||
//
|
||||
void fireball_level_close()
|
||||
{
|
||||
if ( !fireballs_inited )
|
||||
return;
|
||||
|
||||
fireball_delete_all();
|
||||
}
|
||||
|
||||
void fireballs_page_in()
|
||||
{
|
||||
int i, idx;
|
||||
@@ -1009,44 +1042,3 @@ int fireball_ship_explosion_type(ship_info *sip)
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int fireball_asteroid_explosion_type(asteroid_info *aip)
|
||||
{
|
||||
Assert( aip != NULL );
|
||||
|
||||
if (aip->explosion_bitmap_anims.empty())
|
||||
return -1;
|
||||
|
||||
int index = -1;
|
||||
int roid_fireballs = (int)aip->explosion_bitmap_anims.size();
|
||||
|
||||
if (roid_fireballs > 0) {
|
||||
index = aip->explosion_bitmap_anims[rand()%roid_fireballs];
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
float fireball_wormhole_intensity( object *obj )
|
||||
{
|
||||
int num, objnum;
|
||||
fireball *fb;
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
Assertion( Fireballs[num].objnum == objnum, "Basic sanity check. Fireballs[num].objnum (%d) should == objnum (%d)", Fireballs[num].objnum, objnum );
|
||||
|
||||
fb = &Fireballs[num];
|
||||
|
||||
float t = fb->time_elapsed;
|
||||
float rad;
|
||||
|
||||
if ( t < WARPHOLE_GROW_TIME ) {
|
||||
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f);
|
||||
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
|
||||
rad = 1;
|
||||
} else {
|
||||
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f);
|
||||
}
|
||||
return rad;
|
||||
}
|
||||
+21
-25
@@ -16,7 +16,6 @@
|
||||
|
||||
struct object;
|
||||
struct ship_info;
|
||||
struct asteroid_info;
|
||||
|
||||
// values correspond to the fireball render types
|
||||
#define FIREBALL_MEDIUM_EXPLOSION 0
|
||||
@@ -24,15 +23,15 @@ struct asteroid_info;
|
||||
#define FIREBALL_WARP_EFFECT 2
|
||||
|
||||
// these values correspond to the fireball.tbl default entries
|
||||
#define FIREBALL_EXPLOSION_MEDIUM 0 // Used for the 4 little explosions before a ship explodes
|
||||
#define FIREBALL_WARP 1 // Used for the warp in / warp out effect
|
||||
#define FIREBALL_KNOSSOS 2 // Used for the KNOSSOS warp in / warp out effect
|
||||
#define FIREBALL_ASTEROID 3
|
||||
#define FIREBALL_EXPLOSION_LARGE1 4 // Used for the big explosion when a ship breaks into pieces
|
||||
#define FIREBALL_EXPLOSION_LARGE2 5 // Used for the big explosion when a ship breaks into pieces
|
||||
#define FIREBALL_EXPLOSION_MEDIUM 0 // Used for the 4 little explosions before a ship explodes
|
||||
#define FIREBALL_WARP 1 // Used for the warp in / warp out effect
|
||||
#define FIREBALL_KNOSSOS 2 // Used for the KNOSSOS warp in / warp out effect
|
||||
#define FIREBALL_ASTEROID 3
|
||||
#define FIREBALL_EXPLOSION_LARGE1 4 // Used for the big explosion when a ship breaks into pieces
|
||||
#define FIREBALL_EXPLOSION_LARGE2 5 // Used for the big explosion when a ship breaks into pieces
|
||||
|
||||
#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
|
||||
#define NUM_DEFAULT_FIREBALLS 6
|
||||
#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
|
||||
#define NUM_DEFAULT_FIREBALLS 6
|
||||
|
||||
#define FIREBALL_NUM_LARGE_EXPLOSIONS 2
|
||||
|
||||
@@ -42,12 +41,12 @@ extern int Num_fireball_types;
|
||||
// all this moved here by Goober5000 because it makes more sense in the H file
|
||||
typedef struct fireball_lod {
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
int bitmap_id;
|
||||
int num_frames;
|
||||
int fps;
|
||||
int bitmap_id;
|
||||
int num_frames;
|
||||
int fps;
|
||||
} fireball_lod;
|
||||
|
||||
typedef struct fireball_info {
|
||||
typedef struct fireball_info {
|
||||
int lod_count;
|
||||
float exp_color[3];
|
||||
fireball_lod lod[4];
|
||||
@@ -60,24 +59,25 @@ typedef struct fireball_info {
|
||||
#define FBF_WARP_3D (1<<3) // Goober5000
|
||||
#define FBF_WARP_VIA_SEXP (1<<4) // Goober5000
|
||||
|
||||
typedef struct fireball {
|
||||
typedef struct fireball {
|
||||
int objnum; // If -1 this object is unused
|
||||
int fireball_info_index; // Index into Fireball_info array
|
||||
int fireball_render_type;
|
||||
int current_bitmap;
|
||||
int orient; // For fireballs, which orientation. For warps, 0 is warpin, 1 is warpout
|
||||
int flags; // see #define FBF_*
|
||||
char lod; // current LOD
|
||||
float time_elapsed; // in seconds
|
||||
float total_time; // total lifetime of animation in seconds
|
||||
int warp_open_sound_index; // for warp-effect - Goober5000
|
||||
int warp_close_sound_index; // for warp-effect - Goober5000
|
||||
char lod; // current LOD
|
||||
float time_elapsed; // in seconds
|
||||
float total_time; // total lifetime of animation in seconds
|
||||
int warp_open_sound_index; // for warp-effect - Goober5000
|
||||
int warp_close_sound_index; // for warp-effect - Goober5000
|
||||
} fireball;
|
||||
// end move
|
||||
|
||||
void fireball_init();
|
||||
void fireball_render(object * obj);
|
||||
void fireball_delete( object * obj );
|
||||
void fireball_process_pre(object * obj, float frame_time);
|
||||
void fireball_process_post(object * obj, float frame_time);
|
||||
|
||||
// reversed is for warp_in/out effects
|
||||
@@ -86,6 +86,8 @@ void fireball_process_post(object * obj, float frame_time);
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reversed=0, vec3d *velocity=NULL, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=NULL, int low_res=0, int extra_flags=0, int warp_open_sound=-1, int warp_close_sound=-1);
|
||||
void fireball_render_plane(int plane);
|
||||
void fireball_close();
|
||||
void fireball_level_close();
|
||||
void fireball_preload(); // page in warpout effect data
|
||||
|
||||
// Returns 1 if you can remove this fireball
|
||||
int fireball_is_perishable(object * obj);
|
||||
@@ -105,12 +107,6 @@ void fireball_get_color(int idx, float *red, float *green, float *blue);
|
||||
// returns the index of the fireball bitmap for this ship. -1 if there is none.
|
||||
int fireball_ship_explosion_type(ship_info *sip);
|
||||
|
||||
// returns the index of the fireball bitmap for this asteroid. -1 if there is none.
|
||||
int fireball_asteroid_explosion_type(asteroid_info *aip);
|
||||
|
||||
// returns the intensity of a wormhole
|
||||
float fireball_wormhole_intensity( object *obj );
|
||||
|
||||
// internal function to draw warp grid.
|
||||
extern void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d = 0 );
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ void draw_face( vertex *v1, vertex *v2, vertex *v3 )
|
||||
vec3d norm;
|
||||
vertex *vertlist[3];
|
||||
|
||||
vm_vec_perp(&norm,&v1->world, &v2->world, &v3->world);
|
||||
if ( vm_vec_dot(&norm, &v1->world ) >= 0.0 ) {
|
||||
vm_vec_perp(&norm,(vec3d *)&v1->x, (vec3d *)&v2->x, (vec3d *)&v3->x);
|
||||
if ( vm_vec_dot(&norm, (vec3d *)&v1->x ) >= 0.0 ) {
|
||||
vertlist[0] = v3;
|
||||
vertlist[1] = v2;
|
||||
vertlist[2] = v1;
|
||||
@@ -92,7 +92,7 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
|
||||
}
|
||||
|
||||
vecs[4] = center;
|
||||
verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
|
||||
verts[4].u = 0.5f; verts[4].v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
@@ -141,20 +141,11 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
verts[0].texture_position.u = 0.01f;
|
||||
verts[0].texture_position.v = 0.01f;
|
||||
|
||||
verts[1].texture_position.u = 0.99f;
|
||||
verts[1].texture_position.v = 0.01f;
|
||||
|
||||
verts[2].texture_position.u = 0.99f;
|
||||
verts[2].texture_position.v = 0.99f;
|
||||
|
||||
verts[3].texture_position.u = 0.01f;
|
||||
verts[3].texture_position.v = 0.99f;
|
||||
|
||||
verts[4].texture_position.u = 0.5f;
|
||||
verts[4].texture_position.v = 0.5f;
|
||||
verts[0].u = 0.01f; verts[0].v = 0.01f;
|
||||
verts[1].u = 0.99f; verts[1].v = 0.01f;
|
||||
verts[2].u = 0.99f; verts[2].v = 0.99f;
|
||||
verts[3].u = 0.01f; verts[3].v = 0.99f;
|
||||
verts[4].u = 0.5f; verts[4].v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[0], &vecs[0] );
|
||||
|
||||
+406
-406
@@ -1,406 +1,406 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
|
||||
AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AltShipClassDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AltShipClassDlg)
|
||||
m_selected_variable = -1;
|
||||
m_selected_class = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
multi_edit = false;
|
||||
player_ships_only = true;
|
||||
num_string_variables = 0;
|
||||
|
||||
memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
|
||||
memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
|
||||
DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
|
||||
DDX_Control(pDX, IDC_SET_FROM_SHIP_CLASS, m_set_from_ship_class);
|
||||
DDX_Control(pDX, IDC_SET_FROM_VARIABLES, m_set_from_variables);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_VARIABLES, m_selected_variable);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
|
||||
ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
|
||||
ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i, count;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// have we got multiple selected ships?
|
||||
num_selected_ships = 0;
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Fill the variable combo box
|
||||
m_set_from_variables.ResetContent();
|
||||
m_set_from_variables.AddString("Set From Ship Class");
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
|
||||
m_set_from_variables.AddString(buff);
|
||||
string_variable_indices[num_string_variables++] = i;
|
||||
}
|
||||
}
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
if (!num_string_variables) {
|
||||
m_set_from_variables.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// Fill the ship classes combo box
|
||||
m_set_from_ship_class.ResetContent();
|
||||
// Add the default entry if we need one followed by all the ship classes
|
||||
if (num_string_variables) {
|
||||
m_set_from_ship_class.AddString("Set From Variable");
|
||||
}
|
||||
count = 0;
|
||||
for (i=0; i<Num_ship_classes; i++)
|
||||
{
|
||||
if (player_ships_only && !(Ship_info[i].flags & SIF_PLAYER_SHIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ship_class_indices[count++] = i;
|
||||
m_set_from_ship_class.AddString(Ship_info[i].name);
|
||||
}
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild()
|
||||
{
|
||||
int i, j;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
j = m_alt_class_list.GetCount();
|
||||
for ( i=0; i < j ; i++) {
|
||||
m_alt_class_list.DeleteString(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)alt_class_pool.size() ; i++) {
|
||||
// Default classes should be at the end of the list
|
||||
if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
|
||||
// Int3();
|
||||
// TO DO : we should fix this.
|
||||
}
|
||||
|
||||
if (alt_class_pool[i].variable_index != -1) {
|
||||
Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
|
||||
Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
|
||||
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
|
||||
|
||||
// add it to the list
|
||||
m_alt_class_list.AddString(buff);
|
||||
}
|
||||
else {
|
||||
if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
|
||||
m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
|
||||
}
|
||||
else {
|
||||
m_alt_class_list.AddString("Invalid Ship Class");
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++) {
|
||||
Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassAdd()
|
||||
{
|
||||
alt_class new_list_item;
|
||||
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassInsert()
|
||||
{
|
||||
int index;
|
||||
alt_class new_list_item;
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// If nothing is selected just add it
|
||||
if ( index == -1) {
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
}
|
||||
// Stick it in front of the current selection
|
||||
else {
|
||||
alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
|
||||
}
|
||||
|
||||
alt_class_list_rebuild();
|
||||
|
||||
// If we inserted the user will probably want to edit the selection
|
||||
if (index > -1) {
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the currently selected list entry
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Add a string variable to the list
|
||||
if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
|
||||
index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
|
||||
|
||||
Assert (index >= 0);
|
||||
list_item.variable_index = index;
|
||||
list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
|
||||
}
|
||||
// Add a ship class to the list
|
||||
else {
|
||||
index = m_set_from_ship_class.GetCurSel();
|
||||
|
||||
// Correct the index if the first entry isn't actually a ship class
|
||||
if (num_string_variables) {
|
||||
Assert (index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
list_item.variable_index = -1;
|
||||
list_item.ship_class = ship_class_indices[index];
|
||||
}
|
||||
|
||||
// check the default tickbox
|
||||
list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassDelete()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert (index < (int) alt_class_pool.size());
|
||||
alt_class_pool.erase(alt_class_pool.begin()+index);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveUp()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the top
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index-1]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index-1);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveDown()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
int inext = index + 1;
|
||||
|
||||
// Nothing selected or already at the bottom
|
||||
if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[inext]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromShipClass()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
|
||||
m_set_from_variables.SetCurSel(1);
|
||||
}
|
||||
else {
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromVariables()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_variables.GetCurSel() == 0) {
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
m_set_from_ship_class.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelchangeAltClassList()
|
||||
{
|
||||
int i;
|
||||
int variable_selection = 0;
|
||||
int ship_selection = 0;
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Selected nothing
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a variable selected
|
||||
if (alt_class_pool[index].variable_index != -1) {
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
|
||||
variable_selection = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ship selected
|
||||
else {
|
||||
for (i=0; i < MAX_SHIP_CLASSES; i++) {
|
||||
if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
|
||||
ship_selection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have string variables in the mission the first entry on the list won't be a ship
|
||||
if (num_string_variables) {
|
||||
ship_selection++;
|
||||
}
|
||||
}
|
||||
|
||||
m_set_from_variables.SetCurSel(variable_selection);
|
||||
m_set_from_ship_class.SetCurSel(ship_selection);
|
||||
m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnDefaultToClass()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
|
||||
AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AltShipClassDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AltShipClassDlg)
|
||||
m_selected_variable = -1;
|
||||
m_selected_class = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
multi_edit = false;
|
||||
player_ships_only = true;
|
||||
num_string_variables = 0;
|
||||
|
||||
memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
|
||||
memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
|
||||
DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
|
||||
DDX_Control(pDX, IDC_SET_FROM_SHIP_CLASS, m_set_from_ship_class);
|
||||
DDX_Control(pDX, IDC_SET_FROM_VARIABLES, m_set_from_variables);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_VARIABLES, m_selected_variable);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
|
||||
ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
|
||||
ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i, count;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// have we got multiple selected ships?
|
||||
num_selected_ships = 0;
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Fill the variable combo box
|
||||
m_set_from_variables.ResetContent();
|
||||
m_set_from_variables.AddString("Set From Ship Class");
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
|
||||
m_set_from_variables.AddString(buff);
|
||||
string_variable_indices[num_string_variables++] = i;
|
||||
}
|
||||
}
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
if (!num_string_variables) {
|
||||
m_set_from_variables.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// Fill the ship classes combo box
|
||||
m_set_from_ship_class.ResetContent();
|
||||
// Add the default entry if we need one followed by all the ship classes
|
||||
if (num_string_variables) {
|
||||
m_set_from_ship_class.AddString("Set From Variable");
|
||||
}
|
||||
count = 0;
|
||||
for (i=0; i<Num_ship_classes; i++)
|
||||
{
|
||||
if (player_ships_only && !(Ship_info[i].flags & SIF_PLAYER_SHIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ship_class_indices[count++] = i;
|
||||
m_set_from_ship_class.AddString(Ship_info[i].name);
|
||||
}
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild()
|
||||
{
|
||||
int i, j;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
j = m_alt_class_list.GetCount();
|
||||
for ( i=0; i < j ; i++) {
|
||||
m_alt_class_list.DeleteString(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)alt_class_pool.size() ; i++) {
|
||||
// Default classes should be at the end of the list
|
||||
if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
|
||||
// Int3();
|
||||
// TO DO : we should fix this.
|
||||
}
|
||||
|
||||
if (alt_class_pool[i].variable_index != -1) {
|
||||
Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
|
||||
Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
|
||||
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
|
||||
|
||||
// add it to the list
|
||||
m_alt_class_list.AddString(buff);
|
||||
}
|
||||
else {
|
||||
if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
|
||||
m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
|
||||
}
|
||||
else {
|
||||
m_alt_class_list.AddString("Invalid Ship Class");
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++) {
|
||||
Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassAdd()
|
||||
{
|
||||
alt_class new_list_item;
|
||||
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassInsert()
|
||||
{
|
||||
int index;
|
||||
alt_class new_list_item;
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// If nothing is selected just add it
|
||||
if ( index == -1) {
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
}
|
||||
// Stick it in front of the current selection
|
||||
else {
|
||||
alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
|
||||
}
|
||||
|
||||
alt_class_list_rebuild();
|
||||
|
||||
// If we inserted the user will probably want to edit the selection
|
||||
if (index > -1) {
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the currently selected list entry
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Add a string variable to the list
|
||||
if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
|
||||
index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
|
||||
|
||||
Assert (index >= 0);
|
||||
list_item.variable_index = index;
|
||||
list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
|
||||
}
|
||||
// Add a ship class to the list
|
||||
else {
|
||||
index = m_set_from_ship_class.GetCurSel();
|
||||
|
||||
// Correct the index if the first entry isn't actually a ship class
|
||||
if (num_string_variables) {
|
||||
Assert (index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
list_item.variable_index = -1;
|
||||
list_item.ship_class = ship_class_indices[index];
|
||||
}
|
||||
|
||||
// check the default tickbox
|
||||
list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassDelete()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert (index < (int) alt_class_pool.size());
|
||||
alt_class_pool.erase(alt_class_pool.begin()+index);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveUp()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the top
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index-1]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index-1);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveDown()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the bottom
|
||||
if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index++]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromShipClass()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
|
||||
m_set_from_variables.SetCurSel(1);
|
||||
}
|
||||
else {
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromVariables()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_variables.GetCurSel() == 0) {
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
m_set_from_ship_class.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelchangeAltClassList()
|
||||
{
|
||||
int i;
|
||||
int variable_selection = 0;
|
||||
int ship_selection = 0;
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Selected nothing
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a variable selected
|
||||
if (alt_class_pool[index].variable_index != -1) {
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
|
||||
variable_selection = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ship selected
|
||||
else {
|
||||
for (i=0; i < MAX_SHIP_CLASSES; i++) {
|
||||
if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
|
||||
ship_selection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have string variables in the mission the first entry on the list won't be a ship
|
||||
if (num_string_variables) {
|
||||
ship_selection++;
|
||||
}
|
||||
}
|
||||
|
||||
m_set_from_variables.SetCurSel(variable_selection);
|
||||
m_set_from_ship_class.SetCurSel(ship_selection);
|
||||
m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnDefaultToClass()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
#define AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
class AltShipClassDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AltShipClassDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AltShipClassDlg)
|
||||
enum { IDD = IDD_ALT_SHIP_CLASS };
|
||||
CButton m_default_to_class;
|
||||
CListBox m_alt_class_list;
|
||||
CComboBox m_set_from_ship_class;
|
||||
CComboBox m_set_from_variables;
|
||||
int m_selected_variable;
|
||||
int m_selected_class;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AltShipClassDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AltShipClassDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAltClassAdd();
|
||||
afx_msg void OnAltClassInsert();
|
||||
afx_msg void OnAltClassDelete();
|
||||
afx_msg void OnMoveUp();
|
||||
afx_msg void OnMoveDown();
|
||||
afx_msg void OnSelendokSetFromShipClass();
|
||||
afx_msg void OnSelendokSetFromVariables();
|
||||
afx_msg void OnSelchangeAltClassList();
|
||||
afx_msg void OnDefaultToClass();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
|
||||
bool player_ships_only; // Whether we only add player ships to the alt classes or if we can add any ship
|
||||
|
||||
SCP_vector<alt_class> alt_class_pool;
|
||||
int num_string_variables; // Number of string variables in the mission
|
||||
int string_variable_indices[MAX_SEXP_VARIABLES]; // maps string variables to their index in Sexp_variables
|
||||
int ship_class_indices[MAX_SHIP_CLASSES]; // maps ships in the ships combobox to their index in Ship_info
|
||||
|
||||
|
||||
// variables to handle selection of multiple ships
|
||||
bool multi_edit;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild();
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
#define AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
class AltShipClassDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AltShipClassDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AltShipClassDlg)
|
||||
enum { IDD = IDD_ALT_SHIP_CLASS };
|
||||
CButton m_default_to_class;
|
||||
CListBox m_alt_class_list;
|
||||
CComboBox m_set_from_ship_class;
|
||||
CComboBox m_set_from_variables;
|
||||
int m_selected_variable;
|
||||
int m_selected_class;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AltShipClassDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AltShipClassDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAltClassAdd();
|
||||
afx_msg void OnAltClassInsert();
|
||||
afx_msg void OnAltClassDelete();
|
||||
afx_msg void OnMoveUp();
|
||||
afx_msg void OnMoveDown();
|
||||
afx_msg void OnSelendokSetFromShipClass();
|
||||
afx_msg void OnSelendokSetFromVariables();
|
||||
afx_msg void OnSelchangeAltClassList();
|
||||
afx_msg void OnDefaultToClass();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
|
||||
bool player_ships_only; // Whether we only add player ships to the alt classes or if we can add any ship
|
||||
|
||||
SCP_vector<alt_class> alt_class_pool;
|
||||
int num_string_variables; // Number of string variables in the mission
|
||||
int string_variable_indices[MAX_SEXP_VARIABLES]; // maps string variables to their index in Sexp_variables
|
||||
int ship_class_indices[MAX_SHIP_CLASSES]; // maps ships in the ships combobox to their index in Ship_info
|
||||
|
||||
|
||||
// variables to handle selection of multiple ships
|
||||
bool multi_edit;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild();
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
+116
-115
@@ -1,115 +1,116 @@
|
||||
// FictionViewerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
|
||||
FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(FictionViewerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(FictionViewerDlg)
|
||||
m_story_file = _T("");
|
||||
m_font_file = _T("");
|
||||
m_fiction_music = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(FictionViewerDlg)
|
||||
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
|
||||
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
|
||||
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(FictionViewerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(FictionViewerDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg message handlers
|
||||
|
||||
BOOL FictionViewerDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
CComboBox *box;
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FICTION_MUSIC);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++){
|
||||
box->AddString(Spooled_music[i].name);
|
||||
}
|
||||
|
||||
// init variables
|
||||
m_story_file = _T(fiction_file());
|
||||
m_font_file = _T(fiction_font());
|
||||
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// load it up
|
||||
fiction_viewer_reset();
|
||||
fiction_viewer_load((char *)(LPCSTR) m_story_file, (char *)(LPCSTR) m_font_file);
|
||||
|
||||
// set music
|
||||
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
int FictionViewerDlg::query_modified()
|
||||
{
|
||||
return strcmp(m_story_file, fiction_file()) || strcmp(m_font_file, fiction_font()) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
|
||||
}
|
||||
// FictionViewerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
|
||||
FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(FictionViewerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(FictionViewerDlg)
|
||||
m_story_file = _T("");
|
||||
m_font_file = _T("");
|
||||
m_fiction_music = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(FictionViewerDlg)
|
||||
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
|
||||
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
|
||||
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(FictionViewerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(FictionViewerDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg message handlers
|
||||
|
||||
BOOL FictionViewerDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
CComboBox *box;
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FICTION_MUSIC);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++){
|
||||
box->AddString(Spooled_music[i].name);
|
||||
}
|
||||
|
||||
// init variables
|
||||
m_story_file = _T(fiction_file());
|
||||
m_font_file = _T(fiction_font());
|
||||
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// load it up
|
||||
fiction_viewer_reset();
|
||||
fiction_viewer_load((char *)(LPCSTR) m_story_file, (char *)(LPCSTR) m_font_file);
|
||||
|
||||
// set music
|
||||
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
int FictionViewerDlg::query_modified()
|
||||
{
|
||||
return strcmp(m_story_file, fiction_file()) || strcmp(m_font_file, fiction_font()) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
|
||||
}
|
||||
@@ -1,52 +1,52 @@
|
||||
#if !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#define AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FictionViewerDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
class FictionViewerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
FictionViewerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
int query_modified();
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(FictionViewerDlg)
|
||||
enum { IDD = IDD_FICTION_VIEWER };
|
||||
CString m_story_file;
|
||||
CString m_font_file;
|
||||
int m_fiction_music;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(FictionViewerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(FictionViewerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#if !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#define AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FictionViewerDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
class FictionViewerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
FictionViewerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
int query_modified();
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(FictionViewerDlg)
|
||||
enum { IDD = IDD_FICTION_VIEWER };
|
||||
CString m_story_file;
|
||||
CString m_font_file;
|
||||
int m_fiction_music;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(FictionViewerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(FictionViewerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "parse/sexp.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -153,7 +154,7 @@ void CAddVariableDlg::validate_variable_name(int set_focus)
|
||||
|
||||
// Check if any change and not already in list
|
||||
if ( stricmp(temp_name, "<Variable Name>") ) {
|
||||
if ( (strlen(temp_name) > 0) && (get_index_sexp_variable_name(LPCTSTR(temp_name)) == -1) ) { //not already in list and length > 0 { //-V805
|
||||
if ( (strlen(temp_name) > 0) && (get_index_sexp_variable_name(LPCTSTR(temp_name)) == -1) ) { //not already in list and length > 0 {
|
||||
// Goober5000 - replace spaces with hyphens
|
||||
if (strchr(temp_name, ' ') != NULL)
|
||||
{
|
||||
@@ -174,7 +175,7 @@ void CAddVariableDlg::validate_variable_name(int set_focus)
|
||||
m_name_validated = true;
|
||||
} else {
|
||||
// conflicting variable name
|
||||
if (strlen(temp_name) == 0) { //-V805
|
||||
if (strlen(temp_name) == 0) {
|
||||
edit->SetWindowText("<Variable Name>");
|
||||
}
|
||||
m_name_validated = false;
|
||||
@@ -204,7 +205,7 @@ void CAddVariableDlg::validate_data(int set_focus)
|
||||
edit->GetWindowText(temp_data);
|
||||
|
||||
// check for 0 string length
|
||||
if (strlen(temp_data) == 0) { //-V805
|
||||
if (strlen(temp_data) == 0) {
|
||||
m_data_validated = false;
|
||||
} else {
|
||||
if (m_type_number) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "mission/missiongrid.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "species_defs/species_defs.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
+12
-18
@@ -26,6 +26,7 @@
|
||||
#include "mission/missionparse.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -129,8 +130,6 @@ void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Check(pDX, IDC_SKY_FLAG_NO_CULL, m_sky_flag_4);
|
||||
DDX_Check(pDX, IDC_SKY_FLAG_NO_GLOW, m_sky_flag_5);
|
||||
DDX_Check(pDX, IDC_SKY_FLAG_CLAMP, m_sky_flag_6);
|
||||
DDX_Text(pDX, IDC_NEB_FAR_MULTIPLIER, m_neb_far_multi);
|
||||
DDX_Text(pDX, IDC_NEB_NEAR_MULTIPLIER, m_neb_near_multi);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
@@ -212,12 +211,12 @@ void bg_bitmap_dlg::create()
|
||||
m_envmap = _T(The_mission.envmap_name);
|
||||
|
||||
for(i=0; i<MAX_NEB2_BITMAPS; i++){
|
||||
if(strlen(Neb2_bitmap_filenames[i]) > 0){ //-V805
|
||||
if(strlen(Neb2_bitmap_filenames[i]) > 0){
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->AddString(Neb2_bitmap_filenames[i]);
|
||||
}
|
||||
}
|
||||
// if we have a texture selected already
|
||||
if(strlen(Neb2_texture_name) > 0){ //-V805
|
||||
if(strlen(Neb2_texture_name) > 0){
|
||||
m_neb2_texture = ((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SelectString(-1, Neb2_texture_name);
|
||||
if(m_neb2_texture == CB_ERR){
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SetCurSel(0);
|
||||
@@ -230,8 +229,8 @@ void bg_bitmap_dlg::create()
|
||||
// setup lightning storm names
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->ResetContent();
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString("none"));
|
||||
for(size_t j=0; j<Storm_types.size(); j++){
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString(Storm_types[j].name));
|
||||
for(i=0; i<Num_storm_types; i++){
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString(Storm_types[i].name));
|
||||
}
|
||||
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->SelectString(-1, Mission_parse_storm_name);
|
||||
|
||||
@@ -300,9 +299,7 @@ void bg_bitmap_dlg::create()
|
||||
GetDlgItem(IDC_AMBIENT_G_TEXT)->SetWindowText(buf);
|
||||
sprintf(buf, "Blue: %d", m_amb_blue.GetPos());
|
||||
GetDlgItem(IDC_AMBIENT_B_TEXT)->SetWindowText(buf);
|
||||
|
||||
m_neb_near_multi = Neb2_fog_near_mult;
|
||||
m_neb_far_multi = Neb2_fog_far_mult;
|
||||
|
||||
|
||||
UpdateData(FALSE);
|
||||
OnFullNeb();
|
||||
@@ -424,9 +421,6 @@ void bg_bitmap_dlg::OnClose()
|
||||
The_mission.skybox_flags |= MR_FORCE_CLAMP;
|
||||
}
|
||||
|
||||
Neb2_fog_near_mult = m_neb_near_multi;
|
||||
Neb2_fog_far_mult = m_neb_far_multi;
|
||||
|
||||
// close sun data
|
||||
sun_data_close();
|
||||
|
||||
@@ -668,9 +662,9 @@ void bg_bitmap_dlg::sun_data_save_current()
|
||||
|
||||
// store the data
|
||||
strcpy_s(sle->filename, s_name);
|
||||
sle->ang.p = (float) fl_radians(s_pitch);
|
||||
sle->ang.b = (float) fl_radians(s_bank);
|
||||
sle->ang.h = (float) fl_radians(s_heading);
|
||||
sle->ang.p = (float) fl_radian(s_pitch);
|
||||
sle->ang.b = (float) fl_radian(s_bank);
|
||||
sle->ang.h = (float) fl_radian(s_heading);
|
||||
sle->scale_x = (float) s_scale;
|
||||
sle->scale_y = 1.0f;
|
||||
sle->div_x = 1;
|
||||
@@ -832,9 +826,9 @@ void bg_bitmap_dlg::bitmap_data_save_current()
|
||||
|
||||
// store the data
|
||||
strcpy_s(sle->filename, b_name);
|
||||
sle->ang.p = (float) fl_radians(b_pitch);
|
||||
sle->ang.b = (float) fl_radians(b_bank);
|
||||
sle->ang.h = (float) fl_radians(b_heading);
|
||||
sle->ang.p = (float) fl_radian(b_pitch);
|
||||
sle->ang.b = (float) fl_radian(b_bank);
|
||||
sle->ang.h = (float) fl_radian(b_heading);
|
||||
sle->scale_x = (float) b_scale_x;
|
||||
sle->scale_y = (float) b_scale_y;
|
||||
sle->div_x = b_div_x;
|
||||
|
||||
@@ -85,8 +85,6 @@ public:
|
||||
int m_sky_flag_6;
|
||||
CString m_skybox_model;
|
||||
CString m_envmap;
|
||||
float m_neb_near_multi;
|
||||
float m_neb_far_multi;
|
||||
//}}AFX_DATA
|
||||
|
||||
// Overrides
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "localization/localize.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -186,7 +187,7 @@ void briefing_editor_dlg::create()
|
||||
box->AddString(Icon_names[i]);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_TEAM);
|
||||
for (i=0; i<Num_iffs; i++)
|
||||
for (i=0; i<Num_team_names; i++)
|
||||
box->AddString(Iff_info[i].iff_name);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_SHIP_TYPE);
|
||||
@@ -916,7 +917,7 @@ void briefing_editor_dlg::OnMakeIcon()
|
||||
iconp = &Briefing->stages[m_cur_stage].icons[m_cur_icon];
|
||||
ship = waypoint = -1;
|
||||
team = 0;
|
||||
SCP_list<jump_node>::iterator jnp;
|
||||
jump_node *jnp = NULL;
|
||||
|
||||
vm_vec_make(&min, 9e19f, 9e19f, 9e19f);
|
||||
vm_vec_make(&max, -9e19f, -9e19f, -9e19f);
|
||||
@@ -947,10 +948,7 @@ void briefing_editor_dlg::OnMakeIcon()
|
||||
break;
|
||||
|
||||
case OBJ_JUMP_NODE:
|
||||
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
|
||||
if(jnp->get_obj() == ptr)
|
||||
break;
|
||||
}
|
||||
jnp = ptr->jnp;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -991,12 +989,8 @@ void briefing_editor_dlg::OnMakeIcon()
|
||||
if (ship >= 0)
|
||||
name = Ships[ship].ship_name;
|
||||
else if (waypoint >= 0)
|
||||
{
|
||||
waypoint_list *wp_list = find_waypoint_list_with_instance(waypoint);
|
||||
Assert(wp_list != NULL);
|
||||
name = wp_list->get_name();
|
||||
}
|
||||
else if (jnp != Jump_nodes.end())
|
||||
name = Waypoint_lists[waypoint / 65536].name;
|
||||
else if (jnp != NULL)
|
||||
name = jnp->get_name_ptr();
|
||||
else
|
||||
return;
|
||||
@@ -1091,7 +1085,7 @@ void briefing_editor_dlg::OnMakeIcon()
|
||||
}
|
||||
}
|
||||
// jumpnodes
|
||||
else if(jnp != Jump_nodes.end()){
|
||||
else if(jnp != NULL){
|
||||
// find the first navbuoy
|
||||
iconp->ship_class = -1;
|
||||
for (int i = 0; i < Num_ship_classes; i++)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "mission/missiongoals.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -45,9 +46,9 @@ campaign_editor::campaign_editor()
|
||||
m_type = -1;
|
||||
m_num_players = _T("");
|
||||
m_desc = _T("");
|
||||
m_branch_desc = _T("");
|
||||
m_branch_brief_anim = _T("");
|
||||
m_branch_brief_sound = _T("");
|
||||
m_loop_desc = _T("");
|
||||
m_loop_brief_anim = _T("");
|
||||
m_loop_brief_sound = _T("");
|
||||
m_custom_tech_db = FALSE;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
@@ -71,14 +72,14 @@ void campaign_editor::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_CBIndex(pDX, IDC_CAMPAIGN_TYPE, m_type);
|
||||
DDX_Text(pDX, IDC_NUM_PLAYERS, m_num_players);
|
||||
DDX_Text(pDX, IDC_DESC2, m_desc);
|
||||
DDX_Text(pDX, IDC_MISSISON_LOOP_DESC, m_branch_desc);
|
||||
DDX_Text(pDX, IDC_LOOP_BRIEF_ANIM, m_branch_brief_anim);
|
||||
DDX_Text(pDX, IDC_LOOP_BRIEF_SOUND, m_branch_brief_sound);
|
||||
DDX_Text(pDX, IDC_MISSISON_LOOP_DESC, m_loop_desc);
|
||||
DDX_Text(pDX, IDC_LOOP_BRIEF_ANIM, m_loop_brief_anim);
|
||||
DDX_Text(pDX, IDC_LOOP_BRIEF_SOUND, m_loop_brief_sound);
|
||||
DDX_Check(pDX, IDC_CUSTOM_TECH_DB, m_custom_tech_db);
|
||||
//}}AFX_DATA_MAP
|
||||
|
||||
DDV_MaxChars(pDX, m_desc, MISSION_DESC_LENGTH - 1);
|
||||
DDV_MaxChars(pDX, m_branch_desc, MISSION_DESC_LENGTH - 1);
|
||||
DDV_MaxChars(pDX, m_loop_desc, MISSION_DESC_LENGTH - 1);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(campaign_editor, CFormView)
|
||||
@@ -223,10 +224,10 @@ void campaign_editor::initialize( int init_files )
|
||||
m_desc = _T("");
|
||||
}
|
||||
|
||||
m_branch_desc = _T("");
|
||||
m_loop_desc = _T("");
|
||||
|
||||
m_branch_brief_anim = _T("");
|
||||
m_branch_brief_sound = _T("");
|
||||
m_loop_brief_anim = _T("");
|
||||
m_loop_brief_sound = _T("");
|
||||
|
||||
// single player should hide the two dialog items about number of players allowed
|
||||
if ( m_type == CAMPAIGN_TYPE_SINGLE ) {
|
||||
@@ -361,7 +362,7 @@ void campaign_editor::load_tree(int save_first)
|
||||
|
||||
// insert item into tree
|
||||
int image, sel_image;
|
||||
if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
|
||||
if (Links[i].mission_loop) {
|
||||
image = BITMAP_BLUE_DOT;
|
||||
sel_image = BITMAP_GREEN_DOT;
|
||||
} else {
|
||||
@@ -654,76 +655,76 @@ void campaign_editor::save_loop_desc_window()
|
||||
{
|
||||
char buffer[MISSION_DESC_LENGTH];
|
||||
|
||||
// update only if active link and there is a mission has mission loop or fork
|
||||
if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) ) {
|
||||
deconvert_multiline_string(buffer, m_branch_desc, MISSION_DESC_LENGTH);
|
||||
if (Links[Cur_campaign_link].mission_branch_txt) {
|
||||
free(Links[Cur_campaign_link].mission_branch_txt);
|
||||
// update only if active link and there is a mission has mission loop
|
||||
if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop ) {
|
||||
deconvert_multiline_string(buffer, m_loop_desc, MISSION_DESC_LENGTH);
|
||||
if (Links[Cur_campaign_link].mission_loop_txt) {
|
||||
free(Links[Cur_campaign_link].mission_loop_txt);
|
||||
}
|
||||
if (Links[Cur_campaign_link].mission_branch_brief_anim) {
|
||||
free(Links[Cur_campaign_link].mission_branch_brief_anim);
|
||||
if (Links[Cur_campaign_link].mission_loop_brief_anim) {
|
||||
free(Links[Cur_campaign_link].mission_loop_brief_anim);
|
||||
}
|
||||
if (Links[Cur_campaign_link].mission_branch_brief_sound) {
|
||||
free(Links[Cur_campaign_link].mission_branch_brief_sound);
|
||||
if (Links[Cur_campaign_link].mission_loop_brief_sound) {
|
||||
free(Links[Cur_campaign_link].mission_loop_brief_sound);
|
||||
}
|
||||
|
||||
if (strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
|
||||
Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_txt = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_txt = NULL;
|
||||
}
|
||||
|
||||
deconvert_multiline_string(buffer, m_branch_brief_anim, MAX_FILENAME_LEN);
|
||||
deconvert_multiline_string(buffer, m_loop_brief_anim, MAX_FILENAME_LEN);
|
||||
if(strlen(buffer)){
|
||||
Links[Cur_campaign_link].mission_branch_brief_anim = strdup(buffer);
|
||||
Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_brief_anim = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
|
||||
}
|
||||
|
||||
deconvert_multiline_string(buffer, m_branch_brief_sound, MAX_FILENAME_LEN);
|
||||
deconvert_multiline_string(buffer, m_loop_brief_sound, MAX_FILENAME_LEN);
|
||||
if(strlen(buffer)){
|
||||
Links[Cur_campaign_link].mission_branch_brief_sound = strdup(buffer);
|
||||
Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_brief_sound = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void campaign_editor::update_loop_desc_window()
|
||||
{
|
||||
bool enable_branch_desc_window;
|
||||
bool enable_loop_desc_window;
|
||||
|
||||
enable_branch_desc_window = false;
|
||||
if ((Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork)) {
|
||||
enable_branch_desc_window = true;
|
||||
enable_loop_desc_window = false;
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop) {
|
||||
enable_loop_desc_window = true;
|
||||
}
|
||||
|
||||
// maybe enable description window
|
||||
GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(enable_branch_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(enable_branch_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(enable_branch_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(enable_branch_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(enable_branch_desc_window);
|
||||
GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(enable_loop_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(enable_loop_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(enable_loop_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(enable_loop_desc_window);
|
||||
GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(enable_loop_desc_window);
|
||||
|
||||
// set new text
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_txt && enable_branch_desc_window) {
|
||||
m_branch_desc = convert_multiline_string(Links[Cur_campaign_link].mission_branch_txt);
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_txt && enable_loop_desc_window) {
|
||||
m_loop_desc = convert_multiline_string(Links[Cur_campaign_link].mission_loop_txt);
|
||||
} else {
|
||||
m_branch_desc = _T("");
|
||||
m_loop_desc = _T("");
|
||||
}
|
||||
|
||||
// set new text
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_brief_anim && enable_branch_desc_window) {
|
||||
m_branch_brief_anim = convert_multiline_string(Links[Cur_campaign_link].mission_branch_brief_anim);
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_brief_anim && enable_loop_desc_window) {
|
||||
m_loop_brief_anim = convert_multiline_string(Links[Cur_campaign_link].mission_loop_brief_anim);
|
||||
} else {
|
||||
m_branch_brief_anim = _T("");
|
||||
m_loop_brief_anim = _T("");
|
||||
}
|
||||
|
||||
// set new text
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_brief_sound && enable_branch_desc_window) {
|
||||
m_branch_brief_sound = convert_multiline_string(Links[Cur_campaign_link].mission_branch_brief_sound);
|
||||
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_brief_sound && enable_loop_desc_window) {
|
||||
m_loop_brief_sound = convert_multiline_string(Links[Cur_campaign_link].mission_loop_brief_sound);
|
||||
} else {
|
||||
m_branch_brief_sound = _T("");
|
||||
m_loop_brief_sound = _T("");
|
||||
}
|
||||
|
||||
// reset text
|
||||
@@ -737,56 +738,55 @@ void campaign_editor::OnToggleLoop()
|
||||
return;
|
||||
}
|
||||
|
||||
// store mission loop text
|
||||
// store mission looop text
|
||||
UpdateData(TRUE);
|
||||
|
||||
if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) ) {
|
||||
if (Links[Cur_campaign_link].mission_branch_txt) {
|
||||
free(Links[Cur_campaign_link].mission_branch_txt);
|
||||
if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop ) {
|
||||
if (Links[Cur_campaign_link].mission_loop_txt) {
|
||||
free(Links[Cur_campaign_link].mission_loop_txt);
|
||||
}
|
||||
|
||||
if (Links[Cur_campaign_link].mission_branch_brief_anim) {
|
||||
free(Links[Cur_campaign_link].mission_branch_brief_anim);
|
||||
if (Links[Cur_campaign_link].mission_loop_brief_anim) {
|
||||
free(Links[Cur_campaign_link].mission_loop_brief_anim);
|
||||
}
|
||||
|
||||
if (Links[Cur_campaign_link].mission_branch_brief_sound) {
|
||||
free(Links[Cur_campaign_link].mission_branch_brief_sound);
|
||||
if (Links[Cur_campaign_link].mission_loop_brief_sound) {
|
||||
free(Links[Cur_campaign_link].mission_loop_brief_sound);
|
||||
}
|
||||
|
||||
char buffer[MISSION_DESC_LENGTH];
|
||||
|
||||
deconvert_multiline_string(buffer, m_branch_desc, MISSION_DESC_LENGTH);
|
||||
if (m_branch_desc && strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
|
||||
deconvert_multiline_string(buffer, m_loop_desc, MISSION_DESC_LENGTH);
|
||||
if (m_loop_desc && strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_txt = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_txt = NULL;
|
||||
}
|
||||
|
||||
deconvert_multiline_string(buffer, m_branch_brief_anim, MISSION_DESC_LENGTH);
|
||||
if (m_branch_brief_anim && strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_branch_brief_anim = strdup(buffer);
|
||||
deconvert_multiline_string(buffer, m_loop_brief_anim, MISSION_DESC_LENGTH);
|
||||
if (m_loop_brief_anim && strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_brief_anim = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
|
||||
}
|
||||
|
||||
deconvert_multiline_string(buffer, m_branch_brief_sound, MISSION_DESC_LENGTH);
|
||||
if (m_branch_brief_sound && strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_branch_brief_sound = strdup(buffer);
|
||||
deconvert_multiline_string(buffer, m_loop_brief_sound, MISSION_DESC_LENGTH);
|
||||
if (m_loop_brief_sound && strlen(buffer)) {
|
||||
Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_brief_sound = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// toggle to mission_loop setting
|
||||
Links[Cur_campaign_link].is_mission_loop = !Links[Cur_campaign_link].is_mission_loop;
|
||||
Links[Cur_campaign_link].is_mission_fork = false;
|
||||
Links[Cur_campaign_link].mission_loop = !Links[Cur_campaign_link].mission_loop;
|
||||
|
||||
// reset loop desc window (gray if inactive)
|
||||
update_loop_desc_window();
|
||||
|
||||
// set root icon
|
||||
int bitmap1, bitmap2;
|
||||
if (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) {
|
||||
if (Links[Cur_campaign_link].mission_loop) {
|
||||
bitmap2 = BITMAP_GREEN_DOT;
|
||||
bitmap1 = BITMAP_BLUE_DOT;
|
||||
} else {
|
||||
@@ -820,7 +820,7 @@ void campaign_editor::OnBrowseLoopAni()
|
||||
CFileDialog dlg(TRUE, "ani", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Ani Files (*.ani)|*.ani");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_branch_brief_anim = dlg.GetFileName();
|
||||
m_loop_brief_anim = dlg.GetFileName();
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
@@ -842,7 +842,7 @@ void campaign_editor::OnBrowseLoopSound()
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_branch_brief_sound = dlg.GetFileName();
|
||||
m_loop_brief_sound = dlg.GetFileName();
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
@@ -886,7 +886,7 @@ void campaign_editor::OnChangeDebriefingPersona()
|
||||
if (persona < 0 || persona > 0xff)
|
||||
persona = 0;
|
||||
|
||||
Campaign.missions[Cur_campaign_mission].debrief_persona_index = (ubyte) persona;
|
||||
Campaign.missions[Cur_campaign_mission].debrief_persona_index = persona;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ public:
|
||||
int m_type;
|
||||
CString m_num_players;
|
||||
CString m_desc;
|
||||
CString m_branch_desc;
|
||||
CString m_branch_brief_anim;
|
||||
CString m_branch_brief_sound;
|
||||
CString m_loop_desc;
|
||||
CString m_loop_brief_anim;
|
||||
CString m_loop_brief_sound;
|
||||
BOOL m_custom_tech_db;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "mission/missionparse.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mission/missionparse.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -183,14 +184,14 @@ void campaign_tree_view::OnDraw(CDC* pDC)
|
||||
Links[i].p2.x = Elements[t].box.left + Links[i].to_pos * Bx / (Elements[t].to_links + 1);
|
||||
Links[i].p2.y = Elements[t].box.top;
|
||||
|
||||
// if special mission link, select blue pen
|
||||
if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
|
||||
// if mission_loop link, select blue pen
|
||||
if (Links[i].mission_loop) {
|
||||
pDC->SelectObject(&blue_pen);
|
||||
}
|
||||
|
||||
// if active link, select highlight pen (red - normal, green - special)
|
||||
// if active link, select highlight pen (red - normal, green - mission loop)
|
||||
if (i == Cur_campaign_link) {
|
||||
if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
|
||||
if (Links[i].mission_loop) {
|
||||
pDC->SelectObject(&green_pen);
|
||||
} else {
|
||||
pDC->SelectObject(&red_pen);
|
||||
@@ -248,9 +249,9 @@ void stuff_link_with_formula(int *link_idx, int formula, int mission_num)
|
||||
node2 = CAR(node);
|
||||
Links[*link_idx].from = mission_num;
|
||||
Links[*link_idx].sexp = CAR(node2);
|
||||
Links[*link_idx].mission_branch_txt = NULL;
|
||||
Links[*link_idx].mission_branch_brief_anim = NULL;
|
||||
Links[*link_idx].mission_branch_brief_sound = NULL;
|
||||
Links[*link_idx].mission_loop_txt = NULL;
|
||||
Links[*link_idx].mission_loop_brief_anim = NULL;
|
||||
Links[*link_idx].mission_loop_brief_sound = NULL;
|
||||
sexp_mark_persistent(CAR(node2));
|
||||
free_one_sexp(node2);
|
||||
node3 = CADR(node2);
|
||||
@@ -300,20 +301,13 @@ void campaign_tree_view::construct_tree()
|
||||
// do main campaign path
|
||||
stuff_link_with_formula(&link_idx, Campaign.missions[i].formula, i);
|
||||
|
||||
// do special mission path
|
||||
if ( Campaign.missions[i].flags & CMISSION_FLAG_HAS_LOOP ) {
|
||||
// do mission loop path
|
||||
if ( Campaign.missions[i].has_mission_loop ) {
|
||||
stuff_link_with_formula(&link_idx, Campaign.missions[i].mission_loop_formula, i);
|
||||
Links[link_idx-1].mission_branch_txt = Campaign.missions[i].mission_branch_desc;
|
||||
Links[link_idx-1].mission_branch_brief_anim = Campaign.missions[i].mission_branch_brief_anim;
|
||||
Links[link_idx-1].mission_branch_brief_sound = Campaign.missions[i].mission_branch_brief_sound;
|
||||
Links[link_idx-1].is_mission_loop = true;
|
||||
}
|
||||
else if ( Campaign.missions[i].flags & CMISSION_FLAG_HAS_FORK ) {
|
||||
Campaign.missions[i].mission_loop_formula = -1;
|
||||
Links[link_idx-1].mission_branch_txt = Campaign.missions[i].mission_branch_desc;
|
||||
Links[link_idx-1].mission_branch_brief_anim = Campaign.missions[i].mission_branch_brief_anim;
|
||||
Links[link_idx-1].mission_branch_brief_sound = Campaign.missions[i].mission_branch_brief_sound;
|
||||
Links[link_idx-1].is_mission_fork = true;
|
||||
Links[link_idx-1].mission_loop_txt = Campaign.missions[i].mission_loop_desc;
|
||||
Links[link_idx-1].mission_loop_brief_anim = Campaign.missions[i].mission_loop_brief_anim;
|
||||
Links[link_idx-1].mission_loop_brief_sound = Campaign.missions[i].mission_loop_brief_sound;
|
||||
Links[link_idx-1].mission_loop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,45 +511,45 @@ void campaign_tree_view::OnLButtonDown(UINT nFlags, CPoint point)
|
||||
dc.DrawDragRect(Dragging_rect, Last_draw_size, NULL, CSize(0, 0));
|
||||
|
||||
} else {
|
||||
if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork)) {
|
||||
// HACK!! UPDATE mission loop/fork desc before changing selections
|
||||
// save mission loop/fork desc
|
||||
if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop) {
|
||||
// HACK!! UPDATE mission loop desc before changing selections
|
||||
// save mission loop desc
|
||||
char buffer[MISSION_DESC_LENGTH];
|
||||
box = (CEdit *) Campaign_tree_formp->GetDlgItem(IDC_MISSISON_LOOP_DESC);
|
||||
box->GetWindowText(buffer, MISSION_DESC_LENGTH);
|
||||
if (strlen(buffer)) {
|
||||
if (Links[Cur_campaign_link].mission_branch_txt) {
|
||||
free(Links[Cur_campaign_link].mission_branch_txt);
|
||||
if (Links[Cur_campaign_link].mission_loop_txt) {
|
||||
free(Links[Cur_campaign_link].mission_loop_txt);
|
||||
}
|
||||
Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
|
||||
Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_txt = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_txt = NULL;
|
||||
}
|
||||
|
||||
// HACK!! UPDATE mission loop/fork desc before changing selections
|
||||
// save mission loop/fork desc
|
||||
// HACK!! UPDATE mission loop desc before changing selections
|
||||
// save mission loop desc
|
||||
box = (CEdit *) Campaign_tree_formp->GetDlgItem(IDC_LOOP_BRIEF_ANIM);
|
||||
box->GetWindowText(buffer, MISSION_DESC_LENGTH);
|
||||
if (strlen(buffer)) {
|
||||
if (Links[Cur_campaign_link].mission_branch_brief_anim) {
|
||||
free(Links[Cur_campaign_link].mission_branch_brief_anim);
|
||||
if (Links[Cur_campaign_link].mission_loop_brief_anim) {
|
||||
free(Links[Cur_campaign_link].mission_loop_brief_anim);
|
||||
}
|
||||
Links[Cur_campaign_link].mission_branch_brief_anim = strdup(buffer);
|
||||
Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_brief_anim = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
|
||||
}
|
||||
|
||||
// HACK!! UPDATE mission loop/fork desc before changing selections
|
||||
// save mission loop/fork desc
|
||||
// HACK!! UPDATE mission loop desc before changing selections
|
||||
// save mission loop desc
|
||||
box = (CEdit *) Campaign_tree_formp->GetDlgItem(IDC_LOOP_BRIEF_SOUND);
|
||||
box->GetWindowText(buffer, MISSION_DESC_LENGTH);
|
||||
if (strlen(buffer)) {
|
||||
if (Links[Cur_campaign_link].mission_branch_brief_sound) {
|
||||
free(Links[Cur_campaign_link].mission_branch_brief_sound);
|
||||
if (Links[Cur_campaign_link].mission_loop_brief_sound) {
|
||||
free(Links[Cur_campaign_link].mission_loop_brief_sound);
|
||||
}
|
||||
Links[Cur_campaign_link].mission_branch_brief_sound = strdup(buffer);
|
||||
Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
|
||||
} else {
|
||||
Links[Cur_campaign_link].mission_branch_brief_sound = NULL;
|
||||
Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
|
||||
}
|
||||
}
|
||||
Mission_dragging = Cur_campaign_mission = Cur_campaign_link = -1;
|
||||
@@ -751,11 +745,10 @@ int campaign_tree_view::add_link(int from, int to)
|
||||
Links[Total_links].from = from;
|
||||
Links[Total_links].to = to;
|
||||
Links[Total_links].sexp = Locked_sexp_true;
|
||||
Links[Total_links].is_mission_loop = false;
|
||||
Links[Total_links].is_mission_fork = false;
|
||||
Links[Total_links].mission_branch_txt = NULL;
|
||||
Links[Total_links].mission_branch_brief_anim = NULL;
|
||||
Links[Total_links].mission_branch_brief_sound = NULL;
|
||||
Links[Total_links].mission_loop = false;
|
||||
Links[Total_links].mission_loop_txt = NULL;
|
||||
Links[Total_links].mission_loop_brief_anim = NULL;
|
||||
Links[Total_links].mission_loop_brief_sound = NULL;
|
||||
Total_links++;
|
||||
if (from != to) {
|
||||
Elements[from].from_links++;
|
||||
|
||||
@@ -28,11 +28,10 @@ typedef struct campaign_tree_link {
|
||||
int node; // node tracker when link is in sexp tree window
|
||||
int from_pos; // from link drawing offset
|
||||
int to_pos; // to link drawing offset
|
||||
bool is_mission_loop; // whether link leads to mission loop
|
||||
bool is_mission_fork; // whether link leads to mission fork
|
||||
char *mission_branch_txt; // text describing mission loop
|
||||
char *mission_branch_brief_anim; // filename of anim to play in the brief
|
||||
char *mission_branch_brief_sound; // filename of anim to play in the brief
|
||||
bool mission_loop; // whether link leads to mission loop
|
||||
char *mission_loop_txt; // text describing mission loop
|
||||
char *mission_loop_brief_anim; // filename of anim to play in the brief
|
||||
char *mission_loop_brief_sound; // filename of anim to play in the brief
|
||||
CPoint p1; // coordinates of line last draw for link, from p1 to p2
|
||||
CPoint p2;
|
||||
} campaign_tree_link;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "mission/missionparse.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -410,7 +411,7 @@ int campaign_tree_wnd::internal_error(char *msg, ...)
|
||||
|
||||
int campaign_tree_wnd::fred_check_sexp(int sexp, int type, char *msg, ...)
|
||||
{
|
||||
char buf[512], buf2[2048], buf3[MAX_EVENT_SIZE];
|
||||
char buf[512], buf2[2048], buf3[4096];
|
||||
int err = 0, z, faulty_node;
|
||||
va_list args;
|
||||
|
||||
@@ -425,7 +426,7 @@ int campaign_tree_wnd::fred_check_sexp(int sexp, int type, char *msg, ...)
|
||||
if (!z)
|
||||
return 0;
|
||||
|
||||
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, MAX_EVENT_SIZE);
|
||||
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, 2048);
|
||||
sprintf(buf3, "Error in %s: %s\n\nIn sexpression: %s\n\n(Error appears to be: %s)",
|
||||
buf, sexp_error_message(z), buf2, Sexp_nodes[faulty_node].text);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "localization/localize.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "iff_defs/iff_defs.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -119,10 +120,11 @@ void create_wing_dlg::OnOK()
|
||||
}
|
||||
}
|
||||
|
||||
if (find_matching_waypoint_list(const_cast<char *>((const char *) m_name)) != NULL)
|
||||
{
|
||||
MessageBox("This wing name is already being used by a waypoint path");
|
||||
return;
|
||||
for (i=0; i<MAX_WAYPOINT_LISTS; i++) {
|
||||
if (Waypoint_lists[i].count && !stricmp(Waypoint_lists[i].name, m_name)) {
|
||||
MessageBox("This wing name is already being used by a waypoint path");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stricmp(m_name.Left(1), "<")) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -14,17 +14,13 @@
|
||||
#include "DebriefingEditorDlg.h"
|
||||
#include "FREDDoc.h"
|
||||
#include "mission/missionbriefcommon.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "sound/audiostr.h"
|
||||
#include "localization/localize.h"
|
||||
#include "jumpnode/jumpnode.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -40,9 +36,6 @@ debriefing_editor_dlg::debriefing_editor_dlg(CWnd* pParent /*=NULL*/)
|
||||
m_voice = _T("");
|
||||
m_stage_title = _T("");
|
||||
m_rec_text = _T("");
|
||||
m_debriefPass_music = 0;
|
||||
m_debriefAvg_music = 0;
|
||||
m_debriefFail_music = 0;
|
||||
m_current_debriefing = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
@@ -62,9 +55,6 @@ void debriefing_editor_dlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Text(pDX, IDC_VOICE, m_voice);
|
||||
DDX_Text(pDX, IDC_STAGE_TITLE, m_stage_title);
|
||||
DDX_Text(pDX, IDC_REC_TEXT, m_rec_text);
|
||||
DDX_CBIndex(pDX, IDC_SUCCESSFUL_MISSION_TRACK, m_debriefPass_music);
|
||||
DDX_CBIndex(pDX, IDC_DEBRIEFING_TRACK, m_debriefAvg_music);
|
||||
DDX_CBIndex(pDX, IDC_FAILED_MISSION_TRACK, m_debriefFail_music);
|
||||
//}}AFX_DATA_MAP
|
||||
|
||||
DDV_MaxChars(pDX, m_text, MAX_BRIEF_LEN - 1);
|
||||
@@ -126,33 +116,12 @@ BOOL debriefing_editor_dlg::OnInitDialog()
|
||||
CDialog::OnInitDialog();
|
||||
m_play_bm.LoadBitmap(IDB_PLAY);
|
||||
((CButton *) GetDlgItem(IDC_PLAY)) -> SetBitmap(m_play_bm);
|
||||
CComboBox *box;
|
||||
box = (CComboBox *) GetDlgItem(IDC_ICON_IMAGE);
|
||||
|
||||
m_current_debriefing = 0;
|
||||
UpdateData(FALSE);
|
||||
|
||||
Debriefing = &Debriefings[m_current_debriefing];
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_SUCCESSFUL_MISSION_TRACK);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++)
|
||||
box->AddString(Spooled_music[i].name);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_DEBRIEFING_TRACK);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++)
|
||||
box->AddString(Spooled_music[i].name);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FAILED_MISSION_TRACK);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++)
|
||||
box->AddString(Spooled_music[i].name);
|
||||
|
||||
m_debriefPass_music = Mission_music[SCORE_DEBRIEF_SUCCESS] + 1;
|
||||
m_debriefAvg_music = Mission_music[SCORE_DEBRIEF_AVERAGE] + 1;
|
||||
m_debriefFail_music = Mission_music[SCORE_DEBRIEF_FAIL] + 1;
|
||||
|
||||
m_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
|
||||
n = m_tree.select_sexp_node = select_sexp_node;
|
||||
select_sexp_node = -1;
|
||||
@@ -171,7 +140,6 @@ BOOL debriefing_editor_dlg::OnInitDialog()
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
update_data();
|
||||
set_modified();
|
||||
|
||||
@@ -435,11 +403,6 @@ void debriefing_editor_dlg::OnClose()
|
||||
m_voice_id = -1;
|
||||
m_cur_stage = -1;
|
||||
update_data(1);
|
||||
|
||||
Mission_music[SCORE_DEBRIEF_SUCCESS] = m_debriefPass_music - 1;
|
||||
Mission_music[SCORE_DEBRIEF_AVERAGE] = m_debriefAvg_music - 1;
|
||||
Mission_music[SCORE_DEBRIEF_FAIL] = m_debriefFail_music - 1;
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "mission/missionbriefcommon.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// debriefing_editor_dlg dialog
|
||||
@@ -30,9 +29,6 @@ public:
|
||||
CString m_voice;
|
||||
CString m_stage_title;
|
||||
CString m_rec_text;
|
||||
int m_debriefPass_music;
|
||||
int m_debriefAvg_music;
|
||||
int m_debriefFail_music;
|
||||
int m_current_debriefing;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "dialog1.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
+15
-16
@@ -27,6 +27,7 @@
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -281,7 +282,7 @@ void DumpStats::get_background_stats(CString &buffer)
|
||||
}
|
||||
|
||||
// nebula texture
|
||||
if (strlen(Neb2_texture_name) > 0) { //-V805
|
||||
if (strlen(Neb2_texture_name) > 0) {
|
||||
temp.Format("\tNebula texture: %s\r\n", Neb2_texture_name);
|
||||
buffer += temp;
|
||||
}
|
||||
@@ -385,12 +386,11 @@ void DumpStats::get_object_stats(CString &buffer)
|
||||
// Waypoints
|
||||
int total_waypoints = 0;
|
||||
buffer += "\r\nWAYPOINTS\r\n";
|
||||
|
||||
SCP_list<waypoint_list>::iterator ii;
|
||||
for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii) {
|
||||
temp.Format("\tWaypoint: %s, count: %d\r\n", ii->get_name(), ii->get_waypoints().size());
|
||||
for (i=0; i<Num_waypoint_lists; i++) {
|
||||
temp.Format("\tWaypoint: %s, count: %d\r\n", Waypoint_lists[i].name, Waypoint_lists[i].count);
|
||||
buffer += temp;
|
||||
total_waypoints += ii->get_waypoints().size();
|
||||
total_waypoints += Waypoint_lists[i].count;
|
||||
|
||||
}
|
||||
|
||||
if (total_waypoints > 0) {
|
||||
@@ -400,15 +400,13 @@ void DumpStats::get_object_stats(CString &buffer)
|
||||
|
||||
// Jumpnodes
|
||||
buffer += "\r\nJUMPNODES\r\n";
|
||||
|
||||
SCP_list<jump_node>::iterator jnp;
|
||||
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
|
||||
for ( jump_node *jnp = (jump_node *)Jump_nodes.get_first(); !Jump_nodes.is_end(jnp); jnp = (jump_node *)jnp->get_next() ) {
|
||||
temp.Format("\tJumpnode: %s\r\n", jnp->get_name_ptr());
|
||||
buffer += temp;
|
||||
}
|
||||
|
||||
if (Jump_nodes.size() > 0) {
|
||||
temp.Format("\ttotal_jumpnodes: %d\r\n", Jump_nodes.size());
|
||||
if (Jump_nodes.get_num_elements() > 0) {
|
||||
temp.Format("\ttotal_jumpnodes: %d\r\n", Jump_nodes.get_num_elements());
|
||||
buffer += temp;
|
||||
}
|
||||
|
||||
@@ -485,7 +483,7 @@ void DumpStats::get_objectives_and_goals(CString &buffer)
|
||||
|
||||
// goals
|
||||
for (i=0; i<Num_goals; i++) {
|
||||
temp.Format("\tGoal: %s, text: %s", Mission_goals[i].name, Mission_goals[i].message);
|
||||
temp.Format("\tGoal: %s, text: ", Mission_goals[i].name, Mission_goals[i].message);
|
||||
buffer += temp;
|
||||
|
||||
switch(Mission_goals[i].type & GOAL_TYPE_MASK) {
|
||||
@@ -572,14 +570,15 @@ void DumpStats::get_species_ship_breakdown(CString &buffer)
|
||||
{
|
||||
CString temp;
|
||||
int i;
|
||||
int species;
|
||||
uint species;
|
||||
object *objp;
|
||||
ship *shipp;
|
||||
|
||||
buffer += "\r\nSHIP SPECIES BREAKDOWN\r\n";
|
||||
|
||||
|
||||
for (species=0; (uint) species < Species_info.size(); species++) {
|
||||
|
||||
for (species=0; species < Species_info.size(); species++) {
|
||||
buffer += Species_info[species].species_name;
|
||||
buffer += "\r\n";
|
||||
|
||||
@@ -752,7 +751,7 @@ void dump_loadout(ship *shipp, CString &loadout)
|
||||
void DumpStats::get_default_ship_loadouts(CString &buffer)
|
||||
{
|
||||
int i;
|
||||
int species;
|
||||
uint species;
|
||||
object *objp;
|
||||
ship *shipp;
|
||||
CString temp, loadout;
|
||||
@@ -760,7 +759,7 @@ void DumpStats::get_default_ship_loadouts(CString &buffer)
|
||||
buffer += "\r\nSHIP SPECIES BREAKDOWN\r\n";
|
||||
|
||||
|
||||
for (species=0; (uint) species < Species_info.size(); species++) {
|
||||
for (species=0; species < Species_info.size(); species++) {
|
||||
buffer += Species_info[species].species_name;
|
||||
buffer += "\r\n";
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "localization/localize.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -81,17 +82,15 @@ void event_editor::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_CBString(pDX, IDC_WAVE_FILENAME, m_wave_filename);
|
||||
DDX_LBIndex(pDX, IDC_MESSAGE_LIST, m_cur_msg);
|
||||
|
||||
|
||||
// m_team == -1 maps to 2
|
||||
if(m_team == -1){
|
||||
m_team = MAX_TVT_TEAMS;
|
||||
m_team = 2;
|
||||
}
|
||||
|
||||
DDX_CBIndex(pDX, IDC_EVENT_TEAM, m_team);
|
||||
|
||||
// m_message_team == -1 maps to 2
|
||||
if(m_message_team == -1){
|
||||
m_message_team = MAX_TVT_TEAMS;
|
||||
m_message_team = 2;
|
||||
}
|
||||
DDX_CBIndex(pDX, IDC_MESSAGE_TEAM, m_message_team);
|
||||
//}}AFX_DATA_MAP
|
||||
@@ -571,7 +570,7 @@ void event_editor::update_cur_message()
|
||||
m_persona = 0;
|
||||
}
|
||||
|
||||
if(m_messages[m_cur_msg].multi_team >= MAX_TVT_TEAMS){
|
||||
if(m_messages[m_cur_msg].multi_team >= 2){
|
||||
m_message_team = -1;
|
||||
m_messages[m_cur_msg].multi_team = -1;
|
||||
} else {
|
||||
@@ -716,7 +715,6 @@ void event_editor::reset_event(int num, HTREEITEM after)
|
||||
m_events[num].chain_delay = -1;
|
||||
m_events[num].objective_text = NULL;
|
||||
m_events[num].objective_key_text = NULL;
|
||||
m_events[num].team = -1;
|
||||
m_sig[num] = -1;
|
||||
|
||||
m_event_tree.item_index = -1;
|
||||
@@ -1176,7 +1174,7 @@ int event_editor::save_message(int num)
|
||||
// box list.
|
||||
m_messages[num].persona_index = m_persona - 1;
|
||||
|
||||
if(m_message_team >= MAX_TVT_TEAMS){
|
||||
if(m_message_team >= 2){
|
||||
m_messages[num].multi_team = -1;
|
||||
m_message_team = -1;
|
||||
} else {
|
||||
@@ -1229,7 +1227,6 @@ void event_editor::OnDeleteMsg()
|
||||
((CListBox *) GetDlgItem(IDC_MESSAGE_LIST))->DeleteString(m_cur_msg);
|
||||
sprintf(buf, "<%s>", m_messages[m_cur_msg].name);
|
||||
update_sexp_references(m_messages[m_cur_msg].name, buf, OPF_MESSAGE);
|
||||
update_sexp_references(m_messages[m_cur_msg].name, buf, OPF_MESSAGE_OR_STRING);
|
||||
|
||||
m_messages.erase(m_messages.begin() + m_cur_msg);
|
||||
|
||||
@@ -1412,8 +1409,8 @@ void event_editor::OnSelchangeTeam()
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
// If the team isn't valid mark it as such.
|
||||
if((m_team >= MAX_TVT_TEAMS) || (m_team < -1) ){
|
||||
// team == 2, means no team
|
||||
if(m_team == 2){
|
||||
m_team = -1;
|
||||
}
|
||||
|
||||
@@ -1429,8 +1426,8 @@ void event_editor::OnSelchangeMessageTeam()
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
// If the team isn't valid mark it as such.
|
||||
if((m_message_team>= MAX_TVT_TEAMS) || (m_message_team < -1) ) {
|
||||
// team == 2, means no team
|
||||
if(m_message_team == 2){
|
||||
m_message_team = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ BOOL CFolderDialog::SetSelectedFolder( IN LPCTSTR pszPath )
|
||||
|
||||
VOID CFolderDialog::OnInitialized( VOID )
|
||||
{
|
||||
if( ::lstrlen( m_szSelPath ) > 0 ) //-V805
|
||||
if( ::lstrlen( m_szSelPath ) > 0 )
|
||||
SetSelection( m_szSelPath );
|
||||
}
|
||||
|
||||
|
||||
+7
-41
@@ -25,10 +25,9 @@
|
||||
#include "CampaignTreeWnd.h"
|
||||
#include "CampaignTreeView.h"
|
||||
#include "CampaignEditorDlg.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "globalincs/mspdb_callstack.h"
|
||||
|
||||
#include "AFXADV.H"
|
||||
|
||||
#ifdef NDEBUG
|
||||
#ifndef FRED
|
||||
#error macro FRED is not defined when trying to build release Fred. Please define FRED macro in build settings in all Fred projects
|
||||
@@ -36,6 +35,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -80,12 +80,12 @@ window_data Mission_notes_wnd_data;
|
||||
BEGIN_MESSAGE_MAP(CFREDApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CFREDApp)
|
||||
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
|
||||
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code!
|
||||
//}}AFX_MSG_MAP
|
||||
// Standard file based document commands
|
||||
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
|
||||
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
|
||||
// Standard print setup command
|
||||
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
|
||||
END_MESSAGE_MAP()
|
||||
@@ -97,6 +97,7 @@ CFREDApp::CFREDApp()
|
||||
{
|
||||
app_init = 0;
|
||||
|
||||
DBUGFILE_INIT();
|
||||
SCP_mspdbcs_Initialise( );
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -107,6 +108,7 @@ CFREDApp::CFREDApp()
|
||||
CFREDApp::~CFREDApp()
|
||||
{
|
||||
SCP_mspdbcs_Cleanup( );
|
||||
DBUGFILE_DEINIT();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -123,7 +125,7 @@ BOOL CFREDApp::InitInstance()
|
||||
|
||||
|
||||
// disable the debug memory stuff
|
||||
// _CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
|
||||
_CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
|
||||
|
||||
// Standard initialization
|
||||
// If you are not using these features and wish to reduce the size
|
||||
@@ -234,23 +236,9 @@ BOOL CFREDApp::InitInstance()
|
||||
*str_end = '\0';
|
||||
|
||||
|
||||
// Goober5000 - figure out where the FRED file dialog should go
|
||||
if ((m_pRecentFileList != NULL) && (m_pRecentFileList->GetSize() > 0))
|
||||
{
|
||||
// use the most recently opened file to supply the default folder
|
||||
m_sInitialDir = m_pRecentFileList->operator[](0); // lol syntax
|
||||
}
|
||||
else
|
||||
{
|
||||
// use FRED's own directory to search for missions
|
||||
m_sInitialDir = Fred_base_dir;
|
||||
m_sInitialDir += "\\data\\missions";
|
||||
}
|
||||
|
||||
|
||||
// Parse command line for standard shell commands, DDE, file open
|
||||
CCommandLineInfo cmdInfo;
|
||||
ParseCommandLine(cmdInfo);
|
||||
ParseCommandLine(cmdInfo);
|
||||
|
||||
m_nCmdShow = Main_wnd_data.p.showCmd;
|
||||
|
||||
@@ -321,25 +309,6 @@ void CFREDApp::OnAppAbout()
|
||||
aboutDlg.DoModal();
|
||||
}
|
||||
|
||||
// G5K - from http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20155824.html
|
||||
void CFREDApp::OnFileOpen()
|
||||
{
|
||||
// use the initial dir the first time we prompt for a file
|
||||
// name. after a successful open, the file name will be
|
||||
// changed to be the empty string and the default dir
|
||||
// will be supplied by the CFileDialog internal memory
|
||||
if(!DoPromptFileName(m_sInitialDir, AFX_IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
|
||||
{
|
||||
// open cancelled
|
||||
return;
|
||||
}
|
||||
AfxGetApp()->OpenDocumentFile(m_sInitialDir);
|
||||
// if returns NULL, the user has already been alerted
|
||||
|
||||
// now erase the initial dir since we only want to use it once
|
||||
m_sInitialDir.Empty();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CFREDApp commands
|
||||
|
||||
@@ -703,6 +672,3 @@ int CFREDApp::ExitInstance()
|
||||
// Empty functions to make fred link with the sexp_mission_set_subspace
|
||||
void game_start_subspace_ambient_sound() {}
|
||||
void game_stop_subspace_ambient_sound() {}
|
||||
|
||||
// Variables to make fred.ccp more like freespace2.cpp so fred will link
|
||||
float Sun_spot = 0.0f;
|
||||
@@ -52,7 +52,6 @@ typedef struct window_data {
|
||||
class CFREDApp : public CWinApp
|
||||
{
|
||||
int app_init;
|
||||
CString m_sInitialDir;
|
||||
|
||||
public:
|
||||
void record_window_data(window_data *wndd, CWnd *wnd);
|
||||
@@ -76,7 +75,6 @@ public:
|
||||
|
||||
//{{AFX_MSG(CFREDApp)
|
||||
afx_msg void OnAppAbout();
|
||||
afx_msg void OnFileOpen();
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
|
||||
+1231
-707
File diff suppressed because it is too large.
Load diff
@@ -50,6 +50,7 @@
|
||||
extern int Num_objects;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -426,7 +427,7 @@ int CFREDDoc::load_mission(char *pathname, int flags)
|
||||
generate_weaponry_usage_list(i, used_pool);
|
||||
for (j=0; j<Team_data[i].num_weapon_choices; j++) {
|
||||
// The amount used in wings is always set by a static loadout entry so skip any that were set by Sexp variables
|
||||
if ( (!strlen(Team_data[i].weaponry_pool_variable[j])) && (!strlen(Team_data[i].weaponry_amount_variable[j])) ) {
|
||||
if ((Team_data[i].weaponry_pool_variable[j] == -1) && (Team_data[i].weaponry_amount_variable[j] == -1) ) {
|
||||
// convert weaponry_pool to be extras available beyond the current ships weapons
|
||||
Team_data[i].weaponry_count[j] -= used_pool[Team_data[i].weaponry_pool[j]];
|
||||
if (Team_data[i].weaponry_count[j] < 0) {
|
||||
@@ -445,8 +446,8 @@ int CFREDDoc::load_mission(char *pathname, int flags)
|
||||
// add the weapon as a new entry
|
||||
Team_data[i].weaponry_pool[Team_data[i].num_weapon_choices] = j;
|
||||
Team_data[i].weaponry_count[Team_data[i].num_weapon_choices] = used_pool[j];
|
||||
strcpy_s(Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices], "");
|
||||
strcpy_s(Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++], "");
|
||||
Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices] = -1;
|
||||
Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-37
@@ -58,6 +58,7 @@ extern float flFrametime;
|
||||
extern subsys_to_render Render_subsys;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -403,47 +404,44 @@ void process_system_keys(int key)
|
||||
|
||||
void render_waypoints(void)
|
||||
{
|
||||
int i, j;
|
||||
vertex v;
|
||||
waypoint_list *ptr;
|
||||
|
||||
SCP_list<waypoint_list>::iterator ii;
|
||||
SCP_list<waypoint>::iterator jj;
|
||||
|
||||
for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii)
|
||||
for (i=0; i<Num_waypoint_lists; i++)
|
||||
{
|
||||
vec3d *prev_vec = NULL;
|
||||
for (jj = ii->get_waypoints().begin(); jj != ii->get_waypoints().end(); ++jj)
|
||||
ptr = &Waypoint_lists[i];
|
||||
for (j=0; j<ptr->count; j++)
|
||||
{
|
||||
g3_rotate_vertex(&v, jj->get_pos());
|
||||
g3_rotate_vertex(&v, &ptr->waypoints[j]);
|
||||
if (!(v.codes & CC_BEHIND))
|
||||
{
|
||||
if (!(g3_project_vertex(&v) & PF_OVERFLOW))
|
||||
{
|
||||
if (cur_waypoint_list == &(*ii) && cur_waypoint == &(*jj))
|
||||
if (cur_waypoint_list == i && cur_waypoint == j)
|
||||
gr_set_color(255, 255, 255);
|
||||
else if (Objects[jj->get_objnum()].flags & OF_MARKED)
|
||||
else if (Waypoint_lists[i].flags[j] & WL_MARKED)
|
||||
gr_set_color(160, 255, 0);
|
||||
else
|
||||
gr_set_color(160, 96, 0);
|
||||
|
||||
g3_draw_sphere(&v, LOLLIPOP_SIZE);
|
||||
if (prev_vec == NULL)
|
||||
gr_set_color(160, 96, 0);
|
||||
else
|
||||
if (j)
|
||||
gr_set_color(0, 0, 0);
|
||||
else
|
||||
gr_set_color(160, 96, 0);
|
||||
|
||||
g3_draw_sphere(&v, LOLLIPOP_SIZE * 0.66667f);
|
||||
gr_set_color(160, 96, 0);
|
||||
g3_draw_sphere(&v, LOLLIPOP_SIZE * 0.33333f);
|
||||
}
|
||||
}
|
||||
|
||||
render_model_x(jj->get_pos(), The_grid, 1);
|
||||
|
||||
gr_set_color(160, 96, 0);
|
||||
if (prev_vec != NULL)
|
||||
rpd_line(prev_vec, jj->get_pos());
|
||||
prev_vec = jj->get_pos();
|
||||
}
|
||||
|
||||
for (j=0; j<ptr->count; j++)
|
||||
render_model_x(&ptr->waypoints[j], The_grid, 1);
|
||||
|
||||
gr_set_color(160, 96, 0);
|
||||
for (j=1; j<ptr->count; j++)
|
||||
rpd_line(&ptr->waypoints[j-1], &ptr->waypoints[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +584,7 @@ void fredhtl_render_subsystem_bounding_box(subsys_to_render * s2r)
|
||||
g3_rotate_vertex(&text_center, ¢er_pt);
|
||||
g3_project_vertex(&text_center);
|
||||
gr_set_color_fast(&colour_white);
|
||||
gr_string_win( (int)text_center.screen.xyw.x, (int)text_center.screen.xyw.y, buf);
|
||||
gr_string_win( (int)text_center.sx, (int)text_center.sy, buf);
|
||||
}
|
||||
|
||||
void display_active_ship_subsystem()
|
||||
@@ -1004,7 +1002,7 @@ void display_distances()
|
||||
if (!(g3_project_vertex(&v) & PF_OVERFLOW)) {
|
||||
sprintf(buf, "%.1f", vm_vec_dist(&objp->pos, &o2->pos));
|
||||
gr_set_color_fast(&colour_white);
|
||||
gr_string_win((int) v.screen.xyw.x, (int) v.screen.xyw.y, buf);
|
||||
gr_string_win((int) v.sx, (int) v.sy, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1068,10 +1066,9 @@ void display_ship_info()
|
||||
sprintf(buf, "%s\n%s", shipp->ship_name, Ship_info[ship_type].short_name);
|
||||
|
||||
} else if (objp->type == OBJ_WAYPOINT) {
|
||||
int idx;
|
||||
waypoint_list *wp_list = find_waypoint_list_with_instance(objp->instance, &idx);
|
||||
Assert(wp_list != NULL);
|
||||
sprintf(buf, "%s\nWaypoint %d", wp_list->get_name(), idx + 1);
|
||||
sprintf(buf, "%s\nWaypoint %d",
|
||||
Waypoint_lists[objp->instance / 65536].name,
|
||||
(objp->instance & 0xffff) + 1);
|
||||
|
||||
} else if (objp->type == OBJ_POINT) {
|
||||
if (objp->instance == BRIEFING_LOOKAT_POINT_ID)
|
||||
@@ -1103,7 +1100,7 @@ void display_ship_info()
|
||||
else
|
||||
gr_set_color_fast(&colour_white);
|
||||
|
||||
gr_string_win((int) v.screen.xyw.x, (int) v.screen.xyw.y, buf);
|
||||
gr_string_win((int) v.sx, (int) v.sy, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1535,10 +1532,8 @@ void render_frame()
|
||||
pos.xyz.x, pos.xyz.y, pos.xyz.z, a.h, a.p, a.b);
|
||||
|
||||
} else if (Objects[Cursor_over].type == OBJ_WAYPOINT) {
|
||||
int idx;
|
||||
waypoint_list *wp_list = find_waypoint_list_with_instance(inst, &idx);
|
||||
Assert(wp_list != NULL);
|
||||
sprintf(buf, "%s\nWaypoint %d\n( %.1f , %.1f , %.1f ) ", wp_list->get_name(), idx + 1, pos.xyz.x, pos.xyz.y, pos.xyz.z);
|
||||
sprintf(buf, "%s\nWaypoint %d\n( %.1f , %.1f , %.1f ) ",
|
||||
Waypoint_lists[inst / 65536].name, (inst & 0xffff) + 1, pos.xyz.x, pos.xyz.y, pos.xyz.z);
|
||||
|
||||
} else if (Objects[Cursor_over].type == OBJ_POINT) {
|
||||
sprintf(buf, "Briefing icon\n( %.1f , %.1f , %.1f ) ", pos.xyz.x, pos.xyz.y, pos.xyz.z);
|
||||
@@ -1552,8 +1547,8 @@ void render_frame()
|
||||
|
||||
gr_get_string_size(&w, &h, buf);
|
||||
|
||||
x = (int) v.screen.xyw.x;
|
||||
y = (int) v.screen.xyw.y + 20;
|
||||
x = (int) v.sx;
|
||||
y = (int) v.sy + 20;
|
||||
|
||||
gr_set_color_fast(&colour_white);
|
||||
gr_rect(x-7, y-6, w+8, h+7);
|
||||
@@ -1881,7 +1876,6 @@ int object_check_collision(object *objp, vec3d *p0, vec3d *p1, vec3d *hitpos)
|
||||
} else
|
||||
return fvi_ray_sphere(hitpos, p0, p1, &objp->pos, (objp->radius > 0.1f) ? objp->radius : LOLLIPOP_SIZE);
|
||||
|
||||
mc.model_instance_num = -1;
|
||||
mc.orient = &objp->orient; // The object's orient
|
||||
mc.pos = &objp->pos; // The object's position
|
||||
mc.p0 = p0; // Point 1 of ray to check
|
||||
@@ -1959,8 +1953,8 @@ int select_object(int cx, int cy)
|
||||
g3_rotate_vertex(&vt, &ptr->pos);
|
||||
if (!(vt.codes & CC_BEHIND))
|
||||
if (!(g3_project_vertex(&vt) & PF_OVERFLOW)) {
|
||||
hitpos.xyz.x = vt.screen.xyw.x - cx;
|
||||
hitpos.xyz.y = vt.screen.xyw.y - cy;
|
||||
hitpos.xyz.x = vt.sx - cx;
|
||||
hitpos.xyz.y = vt.sy - cy;
|
||||
dist = hitpos.xyz.x * hitpos.xyz.x + hitpos.xyz.y * hitpos.xyz.y;
|
||||
if ((dist < 8) && (dist < best_dist)) {
|
||||
best = OBJ_INDEX(ptr);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "ship/ship.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "network/psnet2.h"
|
||||
#include "network/psnet.h"
|
||||
#include "stats/scoring.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
@@ -188,6 +188,7 @@ int Framerate_delay;
|
||||
void game_start_time(){}
|
||||
void game_stop_time(){}
|
||||
int game_get_default_skill_level(){return 0;}
|
||||
void game_load_palette(){}
|
||||
float FreeSpace_gamma;
|
||||
int set_cdrom_path(int){return 0;}
|
||||
int find_freespace_cd(char*){return 0;}
|
||||
@@ -211,9 +212,11 @@ int last_single_step;
|
||||
void get_version_string_short(char *){}
|
||||
void game_tst_mark(struct object *, struct ship *){}
|
||||
int tst;
|
||||
int game_do_cd_mission_check(char *){return 1;}
|
||||
//int Player_multi_died_check;
|
||||
int Show_framerate = 0;
|
||||
|
||||
void game_feature_not_in_demo_popup() {}
|
||||
void alt_tab_pause(){}
|
||||
|
||||
void game_feature_disabled_popup() {}
|
||||
|
||||
+44
-44
@@ -54,6 +54,7 @@
|
||||
#include "VoiceActingManager.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "sound/audiostr.h"
|
||||
@@ -64,6 +65,7 @@
|
||||
#include "gl/glu.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -675,9 +677,8 @@ int drag_objects()
|
||||
if (objp->flags & OF_MARKED) {
|
||||
vm_vec_add(&objp->pos, &objp->pos, &movement_vector);
|
||||
if (objp->type == OBJ_WAYPOINT) {
|
||||
waypoint *wpt = find_waypoint_with_instance(objp->instance);
|
||||
Assert(wpt != NULL);
|
||||
wpt->set_pos(&objp->pos);
|
||||
Waypoint_lists[objp->instance / 65536].waypoints[objp->instance & 0xffff] =
|
||||
objp->pos;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -902,18 +903,15 @@ void CFREDView::OnLButtonDown(UINT nFlags, CPoint point)
|
||||
{
|
||||
// RT point
|
||||
|
||||
int waypoint_instance = -1;
|
||||
int list = -1;
|
||||
|
||||
if (!Fred_active) {
|
||||
CView::OnLButtonDown(nFlags, point);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cur_waypoint != NULL)
|
||||
{
|
||||
Assert(cur_waypoint_list != NULL);
|
||||
waypoint_instance = Objects[cur_waypoint->get_objnum()].instance;
|
||||
}
|
||||
if (cur_waypoint != -1)
|
||||
list = cur_waypoint_list * 65536 + cur_waypoint;
|
||||
|
||||
marking_box.x1 = point.x;
|
||||
marking_box.y1 = point.y;
|
||||
@@ -928,7 +926,7 @@ void CFREDView::OnLButtonDown(UINT nFlags, CPoint point)
|
||||
if (!Bg_bitmap_dialog) {
|
||||
if (on_object == -1) {
|
||||
Selection_lock = 0; // force off selection lock
|
||||
on_object = create_object_on_grid(waypoint_instance);
|
||||
on_object = create_object_on_grid(list);
|
||||
|
||||
} else
|
||||
Dup_drag = 1;
|
||||
@@ -1312,8 +1310,8 @@ void select_objects()
|
||||
g3_rotate_vertex(&v, &ptr->pos);
|
||||
if (!(v.codes & CC_BEHIND) && valid)
|
||||
if (!(g3_project_vertex(&v) & PF_OVERFLOW)) {
|
||||
x = (int) v.screen.xyw.x;
|
||||
y = (int) v.screen.xyw.y;
|
||||
x = (int) v.sx;
|
||||
y = (int) v.sy;
|
||||
|
||||
if (x >= marking_box.x1 && x <= marking_box.x2 && y >= marking_box.y1 && y <= marking_box.y2) {
|
||||
if (ptr->flags & OF_MARKED)
|
||||
@@ -1394,7 +1392,6 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
|
||||
CMenu menu;
|
||||
int objnum;
|
||||
CPoint local = point;
|
||||
SCP_list<jump_node>::iterator jnp;
|
||||
|
||||
if (button_down) {
|
||||
cancel_drag();
|
||||
@@ -1421,19 +1418,12 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
|
||||
|
||||
else if (Objects[objnum].type == OBJ_JUMP_NODE) {
|
||||
id = ID_EDITORS_WAYPOINT;
|
||||
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
|
||||
if(jnp->get_obj() == &Objects[objnum])
|
||||
break;
|
||||
}
|
||||
str.Format("Edit %s", jnp->get_name_ptr());
|
||||
str.Format("Edit %s", Objects[objnum].jnp->get_name_ptr());
|
||||
|
||||
} else if (Objects[objnum].type == OBJ_WAYPOINT) {
|
||||
int idx;
|
||||
waypoint_list *wp_list = find_waypoint_list_with_instance(Objects[objnum].instance, &idx);
|
||||
Assert(wp_list != NULL);
|
||||
|
||||
id = ID_EDITORS_WAYPOINT;
|
||||
str.Format("Edit %s:%d", wp_list->get_name(), idx + 1);
|
||||
str.Format("Edit %s:%d", Waypoint_lists[Objects[objnum].instance / 65536].name,
|
||||
(Objects[objnum].instance & 0xffff) + 1);
|
||||
|
||||
} else if (Objects[objnum].type == OBJ_POINT) {
|
||||
return;
|
||||
@@ -2457,6 +2447,12 @@ int CFREDView::global_error_check()
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count && Ships[i].weapons.num_secondary_banks > 0){
|
||||
if (error("Player \"%s\" has no secondary weapons. Should have at least 1", Ships[i].ship_name)){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Ships[i].objnum != OBJ_INDEX(ptr)){
|
||||
@@ -2490,7 +2486,7 @@ int CFREDView::global_error_check()
|
||||
}
|
||||
|
||||
// wing squad logo check - Goober5000
|
||||
if (strlen(Wings[wing].wing_squad_filename) > 0) //-V805
|
||||
if (strlen(Wings[wing].wing_squad_filename) > 0)
|
||||
{
|
||||
if (The_mission.game_type & MISSION_TYPE_MULTI)
|
||||
{
|
||||
@@ -2524,18 +2520,17 @@ int CFREDView::global_error_check()
|
||||
}
|
||||
}
|
||||
} else if (ptr->type == OBJ_WAYPOINT) {
|
||||
int waypoint_num;
|
||||
waypoint_list *wp_list = find_waypoint_list_with_instance(i, &waypoint_num);
|
||||
|
||||
if (wp_list == NULL) {
|
||||
j = i / 65536; // waypoint path number
|
||||
z = i & 0xffff; // waypoint number in path
|
||||
if (j < 0 || j >= Num_waypoint_lists){
|
||||
return internal_error("Object references an illegal waypoint path number");
|
||||
}
|
||||
|
||||
if (waypoint_num < 0 || (uint) waypoint_num >= wp_list->get_waypoints().size()) {
|
||||
if (z >= Waypoint_lists[j].count){
|
||||
return internal_error("Object references an illegal waypoint number in path");
|
||||
}
|
||||
|
||||
sprintf(buf, "%s:%d", wp_list->get_name(), waypoint_num + 1);
|
||||
sprintf(buf, "%s:%d", Waypoint_lists[j].name, z + 1);
|
||||
names[obj_count] = new char[strlen(buf) + 1];
|
||||
strcpy(names[obj_count], buf);
|
||||
flags[obj_count] = 1;
|
||||
@@ -2788,18 +2783,18 @@ int CFREDView::global_error_check()
|
||||
return internal_error("Num_wings is incorrect");
|
||||
}
|
||||
|
||||
SCP_list<waypoint_list>::iterator ii;
|
||||
for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii) {
|
||||
for (i=0; i<Num_waypoint_lists; i++) {
|
||||
for (z=0; z<obj_count; z++){
|
||||
if (names[z]){
|
||||
if (!stricmp(names[z], ii->get_name())){
|
||||
if (!stricmp(names[z], Waypoint_lists[i].name)){
|
||||
return internal_error("Waypoint path name is also used by an object (%s)", names[z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; (uint) j < ii->get_waypoints().size(); j++) {
|
||||
sprintf(buf, "%s:%d", ii->get_name(), j + 1);
|
||||
j = Waypoint_lists[i].count;
|
||||
while (j--) {
|
||||
sprintf(buf, "%s:%d", Waypoint_lists[i].name, j + 1);
|
||||
for (z=0; z<obj_count; z++){
|
||||
if (names[z]){
|
||||
if (!stricmp(names[z], buf)){
|
||||
@@ -3277,7 +3272,7 @@ int CFREDView::internal_error(char *msg, ...)
|
||||
|
||||
int CFREDView::fred_check_sexp(int sexp, int type, char *msg, ...)
|
||||
{
|
||||
char buf[512], buf2[2048], buf3[MAX_EVENT_SIZE];
|
||||
char buf[512], buf2[2048], buf3[4096];
|
||||
int err = 0, z, faulty_node;
|
||||
va_list args;
|
||||
|
||||
@@ -3292,7 +3287,7 @@ int CFREDView::fred_check_sexp(int sexp, int type, char *msg, ...)
|
||||
if (!z)
|
||||
return 0;
|
||||
|
||||
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, MAX_EVENT_SIZE);
|
||||
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, 2048);
|
||||
sprintf(buf3, "Error in %s: %s\n\nIn sexpression: %s\n(Error appears to be: %s)",
|
||||
buf, sexp_error_message(z), buf2, Sexp_nodes[faulty_node].text);
|
||||
|
||||
@@ -3401,10 +3396,10 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
|
||||
found = 0;
|
||||
if (flag > 0) {
|
||||
if (*goals[i].target_name == '<')
|
||||
if (*goals[i].ship_name == '<')
|
||||
return "Invalid target";
|
||||
|
||||
if (!stricmp(goals[i].target_name, source))
|
||||
if (!stricmp(goals[i].ship_name, source))
|
||||
if (ship >= 0)
|
||||
return "Target of ship's goal is itself";
|
||||
else
|
||||
@@ -3413,7 +3408,11 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
|
||||
inst = team2 = -1;
|
||||
if (flag == 1) { // target waypoint required
|
||||
if (find_matching_waypoint_list(goals[i].target_name) == NULL)
|
||||
for (j=0; j<Num_waypoint_lists; j++)
|
||||
if (!stricmp(goals[i].ship_name, Waypoint_lists[j].name))
|
||||
found = 1;
|
||||
|
||||
if (!found)
|
||||
return "*Invalid target waypoint path name";
|
||||
|
||||
} else if (flag == 2) { // target ship required
|
||||
@@ -3421,7 +3420,7 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
while (ptr != END_OF_LIST(&obj_used_list)) {
|
||||
if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
|
||||
inst = ptr->instance;
|
||||
if (!stricmp(goals[i].target_name, Ships[inst].ship_name)) {
|
||||
if (!stricmp(goals[i].ship_name, Ships[inst].ship_name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@@ -3442,7 +3441,7 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
|
||||
} else if (flag == 3) { // target wing required
|
||||
for (j=0; j<MAX_WINGS; j++)
|
||||
if (Wings[j].wave_count && !stricmp(Wings[j].name, goals[i].target_name))
|
||||
if (Wings[j].wave_count && !stricmp(Wings[j].name, goals[i].ship_name))
|
||||
break;
|
||||
|
||||
if (j >= MAX_WINGS)
|
||||
@@ -3460,13 +3459,13 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
while (ptr != END_OF_LIST(&obj_used_list)) {
|
||||
if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
|
||||
inst = ptr->instance;
|
||||
if (!stricmp(goals[i].target_name, Ships[inst].ship_name)) {
|
||||
if (!stricmp(goals[i].ship_name, Ships[inst].ship_name)) {
|
||||
found = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (ptr->type == OBJ_WAYPOINT) {
|
||||
if (!stricmp(goals[i].target_name, object_name(OBJ_INDEX(ptr)))) {
|
||||
if (!stricmp(goals[i].ship_name, object_name(OBJ_INDEX(ptr)))) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@@ -4591,6 +4590,7 @@ void CFREDView::OnDestroy()
|
||||
{
|
||||
audiostream_close();
|
||||
snd_close();
|
||||
DBUGFILE_OUTPUT_0("About to gr_close");
|
||||
gr_close();
|
||||
os_set_window(NULL);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "editor.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "globalincs/linklist.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -68,7 +69,7 @@ BOOL InitialShips::OnInitDialog()
|
||||
m_initial_list.AddString( Ship_info[i].name );
|
||||
if ( Campaign.ships_allowed[i] ) {
|
||||
m_initial_list.SetCheck(m_list_count, 1);
|
||||
} else if ( (strlen(Campaign.filename) == 0) && strstr(Ship_info[i].name, "Myrmidon") ) { //-V805
|
||||
} else if ( (strlen(Campaign.filename) == 0) && strstr(Ship_info[i].name, "Myrmidon") ) {
|
||||
m_initial_list.SetCheck(m_list_count, 1);
|
||||
} else {
|
||||
m_initial_list.SetCheck(m_list_count, 0);
|
||||
@@ -102,7 +103,7 @@ BOOL InitialShips::OnInitDialog()
|
||||
int add_weapon = 0;
|
||||
if ( Campaign.weapons_allowed[i] ) {
|
||||
add_weapon = 1;
|
||||
} else if ( strlen(Campaign.filename) == 0 ) { //-V805
|
||||
} else if ( strlen(Campaign.filename) == 0 ) {
|
||||
if ( strstr(Weapon_info[i].name, "Subach")) {
|
||||
add_weapon = 1;
|
||||
} else if ( strstr(Weapon_info[i].name, "Akheton")) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "object/objectdock.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
@@ -43,8 +44,7 @@ initial_status::initial_status(CWnd* pParent /*=NULL*/)
|
||||
m_hull = 0;
|
||||
m_has_shields = FALSE;
|
||||
m_force_shields = FALSE;
|
||||
m_ship_locked = FALSE;
|
||||
m_weapons_locked = FALSE;
|
||||
m_locked = FALSE;
|
||||
m_primaries_locked = FALSE;
|
||||
m_secondaries_locked = FALSE;
|
||||
m_turrets_locked = FALSE;
|
||||
@@ -84,8 +84,7 @@ void initial_status::DoDataExchange(CDataExchange* pDX)
|
||||
DDV_MinMaxInt(pDX, m_damage, 0, 100);
|
||||
DDX_Check(pDX, IDC_HAS_SHIELDS, m_has_shields);
|
||||
DDX_Check(pDX, IDC_FORCE_SHIELDS, m_force_shields);
|
||||
DDX_Check(pDX, IDC_SHIP_LOCKED, m_ship_locked);
|
||||
DDX_Check(pDX, IDC_WEAPONS_LOCKED, m_weapons_locked);
|
||||
DDX_Check(pDX, IDC_LOCKED, m_locked);
|
||||
DDX_Check(pDX, IDC_PRIMARIES_LOCKED, m_primaries_locked);
|
||||
DDX_Check(pDX, IDC_SECONDARIES_LOCKED, m_secondaries_locked);
|
||||
DDX_Check(pDX, IDC_TURRETS_LOCKED, m_turrets_locked);
|
||||
@@ -126,8 +125,7 @@ BEGIN_MESSAGE_MAP(initial_status, CDialog)
|
||||
ON_CBN_SELCHANGE(IDC_DOCKEE_POINT, OnSelchangeDockeePoint)
|
||||
ON_BN_CLICKED(IDC_HAS_SHIELDS, OnHasShields)
|
||||
ON_BN_CLICKED(IDC_FORCE_SHIELDS, OnForceShields)
|
||||
ON_BN_CLICKED(IDC_SHIP_LOCKED, OnShipLocked)
|
||||
ON_BN_CLICKED(IDC_WEAPONS_LOCKED, OnWeaponsLocked)
|
||||
ON_BN_CLICKED(IDC_LOCKED, OnLocked)
|
||||
ON_BN_CLICKED(IDC_PRIMARIES_LOCKED, OnPrimariesLocked)
|
||||
ON_BN_CLICKED(IDC_SECONDARIES_LOCKED, OnSecondariesLocked)
|
||||
ON_BN_CLICKED(IDC_TURRETS_LOCKED, OnTurretsLocked)
|
||||
@@ -188,15 +186,10 @@ BOOL initial_status::OnInitDialog()
|
||||
else
|
||||
m_force_shields = 0;
|
||||
|
||||
if (Ships[m_ship].flags2 & SF2_SHIP_LOCKED)
|
||||
m_ship_locked = 1;
|
||||
if (Ships[m_ship].flags & SF_LOCKED)
|
||||
m_locked = 1;
|
||||
else
|
||||
m_ship_locked = 0;
|
||||
|
||||
if (Ships[m_ship].flags2 & SF2_WEAPONS_LOCKED)
|
||||
m_weapons_locked = 1;
|
||||
else
|
||||
m_weapons_locked = 0;
|
||||
m_locked = 0;
|
||||
|
||||
// Lock primaries
|
||||
if (Ships[m_ship].flags2 & SF2_PRIMARIES_LOCKED) {
|
||||
@@ -260,23 +253,13 @@ BOOL initial_status::OnInitDialog()
|
||||
if (m_force_shields)
|
||||
m_force_shields = 2;
|
||||
}
|
||||
|
||||
if (Ships[get_ship_from_obj(objp)].flags2 & SF2_SHIP_LOCKED) {
|
||||
if (!m_ship_locked)
|
||||
m_ship_locked = 2;
|
||||
if (Ships[get_ship_from_obj(objp)].flags & SF_LOCKED) {
|
||||
if (!m_locked)
|
||||
m_locked = 2;
|
||||
|
||||
} else {
|
||||
if (m_ship_locked)
|
||||
m_ship_locked = 2;
|
||||
}
|
||||
|
||||
if (Ships[get_ship_from_obj(objp)].flags2 & SF2_WEAPONS_LOCKED) {
|
||||
if (!m_weapons_locked)
|
||||
m_weapons_locked = 2;
|
||||
|
||||
} else {
|
||||
if (m_weapons_locked)
|
||||
m_weapons_locked = 2;
|
||||
if (m_locked)
|
||||
m_locked = 2;
|
||||
}
|
||||
|
||||
if (Ships[get_ship_from_obj(objp)].flags2 & SF2_PRIMARIES_LOCKED){
|
||||
@@ -421,15 +404,10 @@ void initial_status::OnOK()
|
||||
Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_FORCE_SHIELDS_ON;
|
||||
}
|
||||
|
||||
if (m_ship_locked == 1)
|
||||
Ships[get_ship_from_obj(objp)].flags2 |= SF2_SHIP_LOCKED;
|
||||
else if (!m_ship_locked)
|
||||
Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_SHIP_LOCKED;
|
||||
|
||||
if (m_weapons_locked == 1)
|
||||
Ships[get_ship_from_obj(objp)].flags2 |= SF2_WEAPONS_LOCKED;
|
||||
else if (!m_weapons_locked)
|
||||
Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_WEAPONS_LOCKED;
|
||||
if (m_locked == 1)
|
||||
Ships[get_ship_from_obj(objp)].flags |= SF_LOCKED;
|
||||
else if (!m_locked)
|
||||
Ships[get_ship_from_obj(objp)].flags &= ~SF_LOCKED;
|
||||
|
||||
if (m_primaries_locked == 1) {
|
||||
Ships[get_ship_from_obj(objp)].flags2 |= SF2_PRIMARIES_LOCKED;
|
||||
@@ -477,15 +455,10 @@ void initial_status::OnOK()
|
||||
else if (!m_force_shields)
|
||||
Ships[m_ship].flags2 &= ~SF2_FORCE_SHIELDS_ON;
|
||||
|
||||
if (m_ship_locked == 1)
|
||||
Ships[m_ship].flags2 |= SF2_SHIP_LOCKED;
|
||||
else if (!m_ship_locked)
|
||||
Ships[m_ship].flags2 &= ~SF2_SHIP_LOCKED;
|
||||
|
||||
if (m_weapons_locked == 1)
|
||||
Ships[m_ship].flags2 |= SF2_WEAPONS_LOCKED;
|
||||
else if (!m_weapons_locked)
|
||||
Ships[m_ship].flags2 &= ~SF2_WEAPONS_LOCKED;
|
||||
if (m_locked == 1)
|
||||
Ships[m_ship].flags |= SF_LOCKED;
|
||||
else if (!m_locked)
|
||||
Ships[m_ship].flags &= ~SF_LOCKED;
|
||||
|
||||
if (m_primaries_locked == 1)
|
||||
Ships[m_ship].flags2 |= SF2_PRIMARIES_LOCKED;
|
||||
@@ -562,24 +535,14 @@ void initial_status::OnForceShields()
|
||||
((CButton *) GetDlgItem(IDC_FORCE_SHIELDS))->SetCheck(m_force_shields);
|
||||
}
|
||||
|
||||
void initial_status::OnShipLocked()
|
||||
void initial_status::OnLocked()
|
||||
{
|
||||
if (m_ship_locked == 1)
|
||||
m_ship_locked = 0;
|
||||
if (m_locked == 1)
|
||||
m_locked = 0;
|
||||
else
|
||||
m_ship_locked = 1;
|
||||
m_locked = 1;
|
||||
|
||||
((CButton *) GetDlgItem(IDC_SHIP_LOCKED))->SetCheck(m_ship_locked);
|
||||
}
|
||||
|
||||
void initial_status::OnWeaponsLocked()
|
||||
{
|
||||
if (m_weapons_locked == 1)
|
||||
m_weapons_locked = 0;
|
||||
else
|
||||
m_weapons_locked = 1;
|
||||
|
||||
((CButton *) GetDlgItem(IDC_WEAPONS_LOCKED))->SetCheck(m_weapons_locked);
|
||||
((CButton *) GetDlgItem(IDC_LOCKED))->SetCheck(m_locked);
|
||||
}
|
||||
|
||||
void initial_status::OnSelchangeSubsys()
|
||||
@@ -610,7 +573,7 @@ void initial_status::change_subsys()
|
||||
MODIFY(ptr -> current_hits, 100.0f - (float) m_damage);
|
||||
|
||||
// update cargo name
|
||||
if (strlen(m_cargo_name) > 0) { //-V805
|
||||
if (strlen(m_cargo_name) > 0) {
|
||||
cargo_index = string_lookup(m_cargo_name, Cargo_names, Num_cargo);
|
||||
if (cargo_index == -1) {
|
||||
if (Num_cargo < MAX_CARGO);
|
||||
@@ -621,7 +584,7 @@ void initial_status::change_subsys()
|
||||
ptr->subsys_cargo_name = cargo_index;
|
||||
}
|
||||
} else {
|
||||
ptr->subsys_cargo_name = 0;
|
||||
ptr->subsys_cargo_name = -1;
|
||||
}
|
||||
set_modified();
|
||||
}
|
||||
@@ -640,7 +603,7 @@ void initial_status::change_subsys()
|
||||
m_damage = 100 - (int) ptr -> current_hits;
|
||||
if ( ship_has_scannable_subsystems && valid_cap_subsys_cargo_list(ptr->system_info->subobj_name) ) {
|
||||
enable_cargo_name = TRUE;
|
||||
if (ptr->subsys_cargo_name > 0) {
|
||||
if (ptr->subsys_cargo_name != -1) {
|
||||
m_cargo_name = Cargo_names[ptr->subsys_cargo_name];
|
||||
} else {
|
||||
m_cargo_name = _T("");
|
||||
|
||||
Loaded 100 of 659 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user