mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
864
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64c9dc8035 | ||
|
|
dedd2675cc | ||
|
|
e84fe6d790 | ||
|
|
9857ae0024 | ||
|
|
261e63e5f8 | ||
|
|
5d46f6c04d | ||
|
|
65a15a5e2e | ||
|
|
5a60516c6c | ||
|
|
19a730d1e2 | ||
|
|
21a5630941 | ||
|
|
b54e6a922d | ||
|
|
e694c912b8 | ||
|
|
dc01529ee6 | ||
|
|
a805967dd5 | ||
|
|
fb1c494671 | ||
|
|
8bf41749cb | ||
|
|
fab0ca5b42 | ||
|
|
514e823ed4 | ||
|
|
04b04ee57a | ||
|
|
99238ea308 | ||
|
|
ef2f939ca3 | ||
|
|
15c3ea8cf3 | ||
|
|
415556e4cb | ||
|
|
55980eac46 | ||
|
|
4ec02c6d3c | ||
|
|
e25ae6472e | ||
|
|
374e1432e6 | ||
|
|
7387e285a3 | ||
|
|
58bf8dd55c | ||
|
|
5e12fd27ba | ||
|
|
1e0307b61d | ||
|
|
1b7e1aecc0 | ||
|
|
4710959a39 | ||
|
|
01ada43c1a | ||
|
|
f63189dbf4 | ||
|
|
911ebf66f3 | ||
|
|
3ee782f7d7 | ||
|
|
e2d1ceef10 | ||
|
|
335be306e7 | ||
|
|
b9c8026e7c | ||
|
|
aded7bb83d | ||
|
|
e471f76e55 | ||
|
|
6e13b68f0f | ||
|
|
0f3837e912 | ||
|
|
04b11e5287 | ||
|
|
f6d9674386 | ||
|
|
65297de89d | ||
|
|
261b1382f3 | ||
|
|
cb93063b38 | ||
|
|
c3d3086ab2 | ||
|
|
0c528cc407 | ||
|
|
3d61e11c46 | ||
|
|
abb234c7ef | ||
|
|
b4869d3e1c | ||
|
|
fda165df72 | ||
|
|
d16027d228 | ||
|
|
075cb7f7b1 | ||
|
|
b087f8d0bb | ||
|
|
753b652768 | ||
|
|
255cb9138e | ||
|
|
12909598bb | ||
|
|
f494fdfef8 | ||
|
|
b05f3d047a | ||
|
|
b6b52c8ad4 | ||
|
|
4b9dca98b5 | ||
|
|
40120210a4 | ||
|
|
b216447ebe | ||
|
|
4b89a0662d | ||
|
|
dd438fb032 | ||
|
|
7db8d3d94a | ||
|
|
18e8d1a8b1 | ||
|
|
005df60d13 | ||
|
|
f4a6d80099 | ||
|
|
8fdf299567 | ||
|
|
ec79947e07 | ||
|
|
89cb83573c | ||
|
|
a8e6d242bc | ||
|
|
3d09f1c523 | ||
|
|
8ed8425998 | ||
|
|
5417c5077f | ||
|
|
da8f890f04 | ||
|
|
e902bd2a93 | ||
|
|
c4ce741093 | ||
|
|
dfe665c398 | ||
|
|
dcdde0189c | ||
|
|
336b0fa9ef | ||
|
|
dab646c183 | ||
|
|
084edcf6e1 | ||
|
|
d0c1a09a1f | ||
|
|
d2affec465 | ||
|
|
f717777f7c | ||
|
|
f3a043668c | ||
|
|
5e50d91dee | ||
|
|
8b36c5bd6d | ||
|
|
181edcb916 | ||
|
|
bbfaf12314 | ||
|
|
4ff88a9e70 | ||
|
|
01b0fb3e5d | ||
|
|
76a8de9cc7 | ||
|
|
106346a1a1 | ||
|
|
30cc25e7ee | ||
|
|
7d442047bf | ||
|
|
b036d1049b | ||
|
|
262c1dd37c | ||
|
|
fb6df00c0f | ||
|
|
98f59f6c8b | ||
|
|
4b3d619d71 | ||
|
|
2c6cb674ee | ||
|
|
65cbbcd31d | ||
|
|
90b70a027a | ||
|
|
d68a225582 | ||
|
|
add1b9aba7 | ||
|
|
9d98120dc8 | ||
|
|
39365af0ce | ||
|
|
eb9ab4c957 | ||
|
|
a1dda42d98 | ||
|
|
fc0bb54541 | ||
|
|
bc0ecc1448 | ||
|
|
6d87070b5f | ||
|
|
373d80684f | ||
|
|
613f761043 | ||
|
|
0f1f2ae2f3 | ||
|
|
6feabed6c2 | ||
|
|
17c73dd526 | ||
|
|
1995414e3a | ||
|
|
62b34a766f | ||
|
|
fff1530e21 | ||
|
|
a4ac56cf7b | ||
|
|
13d4be980f | ||
|
|
44976923a0 | ||
|
|
b5e265d20c | ||
|
|
a9cc12985f | ||
|
|
b0af8dd641 | ||
|
|
a5084fc0fb | ||
|
|
a197ab3091 | ||
|
|
e0ac7eff67 | ||
|
|
3a34bf48bb | ||
|
|
6c0dadb095 | ||
|
|
c03d5dde04 | ||
|
|
6c90a9a07c | ||
|
|
591d19c15a | ||
|
|
b3580f8407 | ||
|
|
32278008a6 | ||
|
|
0a3ec374d9 | ||
|
|
dedb59494c | ||
|
|
1d4bed9485 | ||
|
|
5d9b38e398 | ||
|
|
67ca65ff73 | ||
|
|
09cd4c1ad9 | ||
|
|
1c1c90a7a4 | ||
|
|
dd0f8213a7 | ||
|
|
f8f1d4ac08 | ||
|
|
d0884812ce | ||
|
|
f2d84f3283 | ||
|
|
b2ef36d883 | ||
|
|
92039aa55a | ||
|
|
f1693080a3 | ||
|
|
ca0f5f0515 | ||
|
|
6c4c0493fc | ||
|
|
9bcb844f0b | ||
|
|
d1915ce351 | ||
|
|
31d71cd1d2 | ||
|
|
415f273e07 | ||
|
|
7cd3fbf2ef | ||
|
|
56c871d49d | ||
|
|
d011acdc74 | ||
|
|
daa90a1d31 | ||
|
|
e7037aabb1 | ||
|
|
68d5c461e2 | ||
|
|
15093f3772 | ||
|
|
90e0a6a730 | ||
|
|
008a9a58b5 | ||
|
|
01351fee82 | ||
|
|
1aea32bff4 | ||
|
|
283ae2dcca | ||
|
|
2610817c23 | ||
|
|
c624dc2a9b | ||
|
|
433cfa437e | ||
|
|
bf7075cc6a | ||
|
|
908da6af8c | ||
|
|
0e800d166a | ||
|
|
4978242f11 | ||
|
|
9f9003e05e | ||
|
|
cb88594a81 | ||
|
|
a100ac10e0 | ||
|
|
2180e4a5c7 | ||
|
|
505b3fdb4d | ||
|
|
5a1b975637 | ||
|
|
619a4f02f3 | ||
|
|
4622db3330 | ||
|
|
6e1610b300 | ||
|
|
f7e6d4fb1f | ||
|
|
9ca28ed022 | ||
|
|
da9fe0065e | ||
|
|
436a019cd6 | ||
|
|
1af66f99b1 | ||
|
|
f96579faa6 | ||
|
|
966e364b7c | ||
|
|
2659bbcb25 | ||
|
|
7fc983d4b6 | ||
|
|
55e03513c3 | ||
|
|
be488b0f6a | ||
|
|
a35201c87e | ||
|
|
699c125aa8 | ||
|
|
045efc90a5 | ||
|
|
1b8fd941cf | ||
|
|
10d09ff3d1 | ||
|
|
c659d8f50b | ||
|
|
b466ed13c2 | ||
|
|
3568dfd184 | ||
|
|
1819e1ead6 | ||
|
|
2aeade2140 | ||
|
|
e82ac5f2e1 | ||
|
|
4c9c897094 | ||
|
|
9530163e34 | ||
|
|
cedb6ddc89 | ||
|
|
2085a4da87 | ||
|
|
c53e12f566 | ||
|
|
5d56a96f30 | ||
|
|
aab6ad507a | ||
|
|
50f9747548 | ||
|
|
62f2ff9f7e | ||
|
|
a6bece03cd | ||
|
|
cd045d745f | ||
|
|
52660f8170 | ||
|
|
e4a52bf29d | ||
|
|
ef8aaa498f | ||
|
|
1aa2189dd9 | ||
|
|
abe12ea9ca | ||
|
|
183bfa7e54 | ||
|
|
9cf236972b | ||
|
|
4ab2a0d1af | ||
|
|
09c5e7a21e | ||
|
|
9a69092e50 | ||
|
|
ba590e029d | ||
|
|
020e7c841d | ||
|
|
78922b1428 | ||
|
|
12021bae4c | ||
|
|
14dfa85b36 | ||
|
|
8841ade91d | ||
|
|
4501140263 | ||
|
|
a237b61f5c | ||
|
|
9bd345fcf1 | ||
|
|
8ea4793841 | ||
|
|
2e98e39d71 | ||
|
|
366ce26724 | ||
|
|
45fb2f2189 | ||
|
|
c116a2170a | ||
|
|
0ccf57a648 | ||
|
|
51dc9f37db | ||
|
|
bb87b7c6b8 | ||
|
|
2fa81b72f2 | ||
|
|
6b7e03405a | ||
|
|
d0435336d4 | ||
|
|
ad008469b4 | ||
|
|
b027179525 | ||
|
|
53a0176712 | ||
|
|
7af751fcda | ||
|
|
58a5a94a97 | ||
|
|
7cf6c12bdd | ||
|
|
1b60c99cd8 | ||
|
|
bec0f110b3 | ||
|
|
10cfd130aa | ||
|
|
1664133cf9 | ||
|
|
9baae44f88 | ||
|
|
aefb3efe15 | ||
|
|
e590e0c5ec | ||
|
|
675428455b | ||
|
|
e5d14f09a3 | ||
|
|
4a5a3c4bf6 | ||
|
|
27a058a338 | ||
|
|
15001ef13e | ||
|
|
d9fb4b15b9 | ||
|
|
9efce92739 | ||
|
|
80ef48e959 | ||
|
|
2f3fee1017 | ||
|
|
b5a7b399db | ||
|
|
6884dc10a2 | ||
|
|
3f131e532f | ||
|
|
a4243b6ac5 | ||
|
|
48935df1ac | ||
|
|
9c0c2e16d3 | ||
|
|
ed838bda36 | ||
|
|
d14355349e | ||
|
|
cfe438a40c | ||
|
|
9449cb7216 | ||
|
|
099b35c497 | ||
|
|
c9d903f753 | ||
|
|
82d858c834 | ||
|
|
5f073b943c | ||
|
|
42ab4d6622 | ||
|
|
2f39ad1a2a | ||
|
|
88fe40282f | ||
|
|
4f34c8f764 | ||
|
|
7c1187c46d | ||
|
|
ebdbb35b5f | ||
|
|
9d7f9624c9 | ||
|
|
6c54e22b8c | ||
|
|
f7c8e262a9 | ||
|
|
0cc9741790 | ||
|
|
ee04f5e5c0 | ||
|
|
96c7dbcbb6 | ||
|
|
d0ca7a13de | ||
|
|
b35964c21b | ||
|
|
0f32d30d63 | ||
|
|
2f0bd47bae | ||
|
|
9354b4e528 | ||
|
|
7677f53bdc | ||
|
|
7d2f76b26e | ||
|
|
b29a03e55c | ||
|
|
b30ec50714 | ||
|
|
da15e932a4 | ||
|
|
5c5b2f7442 | ||
|
|
50d2b9ae9b | ||
|
|
658b1e6024 | ||
|
|
ee0aecd193 | ||
|
|
6fc3e909ca | ||
|
|
56508ee06f | ||
|
|
53d16012a7 | ||
|
|
1aa75f7edd | ||
|
|
a7ed006559 | ||
|
|
dd6155a914 | ||
|
|
7647ab45b3 | ||
|
|
8857f0bf65 | ||
|
|
662f5bdc88 | ||
|
|
b01999d2f0 | ||
|
|
a14410b658 | ||
|
|
bb8e5f257f | ||
|
|
f6763b8eaa | ||
|
|
e0bf5f25c5 | ||
|
|
740e20f684 | ||
|
|
e7456b1c43 | ||
|
|
dbc95e47f1 | ||
|
|
1164c1f7ab | ||
|
|
6abfb88b50 | ||
|
|
79c9d90938 | ||
|
|
1cc1dd77df | ||
|
|
af9a49e02c | ||
|
|
a38cc033a5 | ||
|
|
39ab0db17d | ||
|
|
ce8831a49f | ||
|
|
ceb55ef40e | ||
|
|
14965a90b0 | ||
|
|
b7d24781ac | ||
|
|
8e08137e92 | ||
|
|
c908adb515 | ||
|
|
9691112aa3 | ||
|
|
16cb751909 | ||
|
|
ff9ee24bf3 | ||
|
|
7ef65ac239 | ||
|
|
36bd4ca967 | ||
|
|
338828a7c9 | ||
|
|
4da59a7059 | ||
|
|
2521541fdc | ||
|
|
ad95a28767 | ||
|
|
53810a1b76 | ||
|
|
199948f4cc | ||
|
|
f7e5abbee4 | ||
|
|
71e1654e33 | ||
|
|
5bca4ce31b | ||
|
|
7237bec390 | ||
|
|
9b9dfb64e5 | ||
|
|
f8f3b2c9e7 | ||
|
|
a3ec50ee2c | ||
|
|
6a0bdcb8c7 | ||
|
|
b95880ac6b | ||
|
|
e0d7eea877 | ||
|
|
03d4e7b41b | ||
|
|
e79d2934c6 | ||
|
|
aea0422b0a | ||
|
|
ff8572af7d | ||
|
|
475acdf495 | ||
|
|
761e430eba | ||
|
|
a3daa5ff3b | ||
|
|
de3145b479 | ||
|
|
9405a8c1e2 | ||
|
|
9d8d5a3448 | ||
|
|
64e2faacea | ||
|
|
9404744602 | ||
|
|
b72b673efd | ||
|
|
ac732f8136 | ||
|
|
40cb581405 | ||
|
|
ac3b174c27 | ||
|
|
916a09975b | ||
|
|
ddc112141d | ||
|
|
59814715fc | ||
|
|
6da93821b6 | ||
|
|
24905b2638 | ||
|
|
030270f2a8 | ||
|
|
ec03cbc46d | ||
|
|
aff36fce1d | ||
|
|
15e8396c2e | ||
|
|
0ed509ace7 | ||
|
|
3ff70bba49 | ||
|
|
c9273590c2 | ||
|
|
037f784227 | ||
|
|
7b14ead21c | ||
|
|
414a0643dc | ||
|
|
da0037de69 | ||
|
|
9e6ca810c6 | ||
|
|
bbbaa95841 | ||
|
|
94b58a0eac | ||
|
|
28b7d2a716 | ||
|
|
7ec286cf81 | ||
|
|
f22c66fe40 | ||
|
|
d4db6d3e5e | ||
|
|
f2d4fb19cc | ||
|
|
39f45f0f8e | ||
|
|
3e97bd1ce4 | ||
|
|
ba421d8d68 | ||
|
|
91c2731521 | ||
|
|
8d78a6fa67 | ||
|
|
bc64eb6ead | ||
|
|
7bc01f1aaf | ||
|
|
6dbb7b65c2 | ||
|
|
f3dcb14e39 | ||
|
|
3c4a168672 | ||
|
|
cad6587e70 | ||
|
|
1c11efe082 | ||
|
|
26a8b0c62f | ||
|
|
38de6cc5c3 | ||
|
|
d56a2b33bb | ||
|
|
15cad9783b | ||
|
|
d2a5b9a6b9 | ||
|
|
ae1cc30563 | ||
|
|
55e00902e4 | ||
|
|
246900788b | ||
|
|
e40ee6735e | ||
|
|
99b7eea1c2 | ||
|
|
ee3a0e9708 | ||
|
|
fefa022f9a | ||
|
|
4d2d3be017 | ||
|
|
6fdb5c8333 | ||
|
|
f98d9af6b8 | ||
|
|
96887b0a0b | ||
|
|
904c80dc39 | ||
|
|
85b3098f72 | ||
|
|
7539f78024 | ||
|
|
1348a3758c | ||
|
|
3b732fab3b | ||
|
|
59583e8457 | ||
|
|
fb94960327 | ||
|
|
7c64c7ada8 | ||
|
|
ff27f47392 | ||
|
|
6dd131d118 | ||
|
|
2a1767951c | ||
|
|
341c99796e | ||
|
|
91b722ae7d | ||
|
|
9ba23f4357 | ||
|
|
5facef281f | ||
|
|
38f922a22a | ||
|
|
1c72d7c7c3 | ||
|
|
cbfecea816 | ||
|
|
51e60dfa3a | ||
|
|
3bedcbc561 | ||
|
|
c968496bc2 | ||
|
|
66c3dcc5df | ||
|
|
f9d1b75bff | ||
|
|
274c841b64 | ||
|
|
b0f1a79bad | ||
|
|
1506ed4576 | ||
|
|
1a2f24eb66 | ||
|
|
92de065a4f | ||
|
|
b3136d2214 | ||
|
|
440fa97d49 | ||
|
|
778a353728 | ||
|
|
09d2583123 | ||
|
|
4f491f99bd | ||
|
|
802b7aecbb | ||
|
|
f51d8e7de5 | ||
|
|
631d1f2318 | ||
|
|
193f3e3cda | ||
|
|
b70c325d6c | ||
|
|
1cb679b004 | ||
|
|
c73b4b8186 | ||
|
|
164405aecb | ||
|
|
03ca7f9849 | ||
|
|
91cd637f73 | ||
|
|
90e53277ac | ||
|
|
938275b159 | ||
|
|
13ee1b85db | ||
|
|
b16ce3e1f2 | ||
|
|
f4a3cb0a0f | ||
|
|
420c35aba5 | ||
|
|
d9360337a8 | ||
|
|
fca993a805 | ||
|
|
9e4c322740 | ||
|
|
4403762592 | ||
|
|
f7201f7046 | ||
|
|
3536c39466 | ||
|
|
32f1b13426 | ||
|
|
36f80a7355 | ||
|
|
60ee8f6044 | ||
|
|
c76596e044 | ||
|
|
e65ac0202e | ||
|
|
ccb26d6e1a | ||
|
|
bf5b34e80e | ||
|
|
ae10003f72 | ||
|
|
d3ff60f166 | ||
|
|
cb5b0042e0 | ||
|
|
17adb27f4f | ||
|
|
4adea7b1d0 | ||
|
|
a8b0b57925 | ||
|
|
42b7d023ed | ||
|
|
e24d054410 | ||
|
|
3665f9c80d | ||
|
|
eb44c69bcf | ||
|
|
dc8b03f68a | ||
|
|
6f9ddbfd4a | ||
|
|
e0c6eeff25 | ||
|
|
b33ea1169c | ||
|
|
d4242fee13 | ||
|
|
8ff52a5f57 | ||
|
|
ad0c943fed | ||
|
|
0f2cca5c4b | ||
|
|
902d1df362 | ||
|
|
a846582d94 | ||
|
|
71cfdd5f76 | ||
|
|
10cd1b08c9 | ||
|
|
f44e8b46f7 | ||
|
|
c503ef414c | ||
|
|
5d81316c65 | ||
|
|
b710bbcc34 | ||
|
|
408a2156c6 | ||
|
|
01b4fad60a | ||
|
|
e834420b64 | ||
|
|
9f0d8f5c53 | ||
|
|
a195fe2a3f | ||
|
|
cd2953a8c9 | ||
|
|
28b856eb84 | ||
|
|
3bcb1fae90 | ||
|
|
7b1dad27b3 | ||
|
|
9360755de9 | ||
|
|
bc645de98f | ||
|
|
8ba5dd2af3 | ||
|
|
52b0262321 | ||
|
|
81f0690b2d | ||
|
|
239ee80362 | ||
|
|
7a1d701bc7 | ||
|
|
8b0d64f4f1 | ||
|
|
1dd8b21422 | ||
|
|
884ecee601 | ||
|
|
d5f3ec6a4e | ||
|
|
d34bc91738 | ||
|
|
b6ee2a4f82 | ||
|
|
b27fad2e1e | ||
|
|
d7d5107a86 | ||
|
|
f145570958 | ||
|
|
9b3ad06f06 | ||
|
|
deb684d140 | ||
|
|
fb2e235608 | ||
|
|
0d23309a35 | ||
|
|
01d12eafc6 | ||
|
|
950dcfa869 | ||
|
|
02e55270a2 | ||
|
|
3949d6efd0 | ||
|
|
ebdc00a523 | ||
|
|
8ec6c1a67d | ||
|
|
9af2763943 | ||
|
|
5b864af888 | ||
|
|
1c516c2540 | ||
|
|
8186572d15 | ||
|
|
de2fbfb48d | ||
|
|
9430b78326 | ||
|
|
8c0243b821 | ||
|
|
acf10e3bba | ||
|
|
217b5beb99 | ||
|
|
a6bcb0b3e7 | ||
|
|
de16009a35 | ||
|
|
ac2ec50ba4 | ||
|
|
d4b831fa35 | ||
|
|
082977d664 | ||
|
|
4134e985a5 | ||
|
|
cf9095ed6e | ||
|
|
d54301f34a | ||
|
|
e0b689c9bb | ||
|
|
b17794b9ed | ||
|
|
a02ac92043 | ||
|
|
cdb3c02fa2 | ||
|
|
0ca738ff0a | ||
|
|
e84a2e24b8 | ||
|
|
7b2407dd4c | ||
|
|
ecda5d2efa | ||
|
|
166aafc603 | ||
|
|
d79e25ca97 | ||
|
|
c1750c14ef | ||
|
|
34d198d30f | ||
|
|
b0033e2d81 | ||
|
|
cbe140ab76 | ||
|
|
ece636df39 | ||
|
|
471b758539 | ||
|
|
c29aa3e9e3 | ||
|
|
ba6773e0f2 | ||
|
|
32aa4ccbeb | ||
|
|
305a2d5855 | ||
|
|
d47c1c9cab | ||
|
|
baa43c4331 | ||
|
|
1ed5c7d6c7 | ||
|
|
dcf3ecd770 | ||
|
|
4a3e5826ee | ||
|
|
01dd0cf6d3 | ||
|
|
4d018ff477 | ||
|
|
c7748312b8 | ||
|
|
6175b6652b | ||
|
|
6ed629949b | ||
|
|
58a664c6c8 | ||
|
|
dbc4ef06ac | ||
|
|
7c929e83f3 | ||
|
|
b192b094ee | ||
|
|
c29957eb1a | ||
|
|
e405e0e760 | ||
|
|
5702c16c87 | ||
|
|
1a3659ac2a | ||
|
|
32d28c1de3 | ||
|
|
ffc6ca5117 | ||
|
|
8e5280a051 | ||
|
|
043321868c | ||
|
|
9b08bcca19 | ||
|
|
ca4879c4ea | ||
|
|
1358f61e0d | ||
|
|
240fabbdd0 | ||
|
|
594fe17d61 | ||
|
|
047bd9ac3f | ||
|
|
29c9a124cf | ||
|
|
ec6a629cbe | ||
|
|
40f101e51b | ||
|
|
c3076eb0f5 | ||
|
|
f6be711610 | ||
|
|
759d4755a7 | ||
|
|
2649c6a65d | ||
|
|
d491750ad1 | ||
|
|
1d052f7a21 | ||
|
|
6632c806d9 | ||
|
|
8debd63788 | ||
|
|
62cecf0968 | ||
|
|
93f5fd829a | ||
|
|
f76ec55015 | ||
|
|
8ab18d8257 | ||
|
|
7089b795e1 | ||
|
|
a4543e1c64 | ||
|
|
f2ebe77471 | ||
|
|
6f91252eaa | ||
|
|
b9b1793287 | ||
|
|
cc2d2ee49e | ||
|
|
53feaed357 | ||
|
|
c3c6f6232f | ||
|
|
d0abb505fb | ||
|
|
d723c2e5fb | ||
|
|
1170157003 | ||
|
|
6f62889368 | ||
|
|
5d709bb63f | ||
|
|
99d98d8959 | ||
|
|
d617270f54 | ||
|
|
686bbdd585 | ||
|
|
5dd1939e19 | ||
|
|
b9594353e6 | ||
|
|
9eaa57e124 | ||
|
|
b2d33e0c49 | ||
|
|
bf6a49525d | ||
|
|
6003cea608 | ||
|
|
9203064801 | ||
|
|
e8e3952513 | ||
|
|
ea4cf33a15 | ||
|
|
e15b9581d0 | ||
|
|
e755e262d3 | ||
|
|
9d5f957d7c | ||
|
|
618cb53d8e | ||
|
|
bbddd92669 | ||
|
|
dd97133335 | ||
|
|
8da36a8ddd | ||
|
|
6b1fd17141 | ||
|
|
2d9c040b2c | ||
|
|
96275a5b6b | ||
|
|
200e56f4bc | ||
|
|
420809c288 | ||
|
|
9ca5def214 | ||
|
|
553f928558 | ||
|
|
04e24d23f5 | ||
|
|
50ee65a9bb | ||
|
|
9347bf9988 | ||
|
|
9aeec5daf9 | ||
|
|
83bd864198 | ||
|
|
4296118a3e | ||
|
|
2ac9eb8f85 | ||
|
|
b9a110b93f | ||
|
|
77592a98cf | ||
|
|
58f8bf7f5e | ||
|
|
f136b538e5 | ||
|
|
edf95b0f77 | ||
|
|
2b5976a2f8 | ||
|
|
9b63771633 | ||
|
|
097b4940b5 | ||
|
|
c9432fd83f | ||
|
|
a5fd0083e9 | ||
|
|
f04620dd78 | ||
|
|
3dce69c7f8 | ||
|
|
1c59dd7af7 | ||
|
|
801924dbba | ||
|
|
0c147396fd | ||
|
|
6b692e048f | ||
|
|
9a3be4e8f3 | ||
|
|
86592894a7 | ||
|
|
82a4b70080 | ||
|
|
c29dd8e247 | ||
|
|
7892f9d1f6 | ||
|
|
7562b17c5c | ||
|
|
9774840088 | ||
|
|
511d99402a | ||
|
|
ef881c1421 | ||
|
|
f106d752dd | ||
|
|
13dfe103fb | ||
|
|
265f08fc49 | ||
|
|
b1a581487a | ||
|
|
df588a7910 | ||
|
|
a6cfd8137d | ||
|
|
30f27da3c0 | ||
|
|
d5f2d2db88 | ||
|
|
dff718944b | ||
|
|
17e4e28e5f | ||
|
|
44c635addb | ||
|
|
08f653f0fb | ||
|
|
2f9ad571c5 | ||
|
|
8d2749639f | ||
|
|
b8fbbc8f9c | ||
|
|
0cb91d9854 | ||
|
|
14eb67a3e5 | ||
|
|
3beb39f3de | ||
|
|
92c6092b04 | ||
|
|
8c87508b3e | ||
|
|
ef64332199 | ||
|
|
50b8d7ea2a | ||
|
|
0a01d6a4bb | ||
|
|
c5d60b66ea | ||
|
|
90b79cd174 | ||
|
|
a42286877b | ||
|
|
b90e7941cd | ||
|
|
90349360f4 | ||
|
|
e8b032882e | ||
|
|
08b59bc175 | ||
|
|
f58ced4ccc | ||
|
|
0c4922f248 | ||
|
|
29551d1e87 | ||
|
|
9522e2fbba | ||
|
|
926fba9af8 | ||
|
|
791c6885ac | ||
|
|
f2854de962 | ||
|
|
ac9dea08b4 | ||
|
|
d689cd9f6b | ||
|
|
20935be473 | ||
|
|
4b2508ec63 | ||
|
|
e6852a545c | ||
|
|
f482a89ab6 | ||
|
|
ca8fbc977f | ||
|
|
2f0d12e022 | ||
|
|
0bf68d0550 | ||
|
|
5b570b795b | ||
|
|
99bf855bcb | ||
|
|
f20330eb13 | ||
|
|
c9f39f527d | ||
|
|
922d3f5584 | ||
|
|
e00791d79f | ||
|
|
c2138e0fbb | ||
|
|
5c9b21bde9 | ||
|
|
d279ff8421 | ||
|
|
c969d5b4ef | ||
|
|
1f9f692bfd | ||
|
|
0f2daa67f1 | ||
|
|
6fb59c5921 | ||
|
|
b4fcd028f0 | ||
|
|
d2b28598f6 | ||
|
|
2018c5eb3f | ||
|
|
a622bf7e8e | ||
|
|
0e9983d8ef | ||
|
|
c7e72f6f9b | ||
|
|
c8a2e196fe | ||
|
|
92ddebade4 | ||
|
|
d0cbc64bfa | ||
|
|
c29a7a751a | ||
|
|
c6f1934ef6 | ||
|
|
318136b5e0 | ||
|
|
cb7ca8e3f0 | ||
|
|
0c8eaca26d | ||
|
|
b54e6f20af | ||
|
|
e97e91d0ea | ||
|
|
853b4fddeb | ||
|
|
93bf912d98 | ||
|
|
ed0631ce6b | ||
|
|
5c1abef3b6 | ||
|
|
6ddbad120e | ||
|
|
d08247bd83 | ||
|
|
bccaf2a699 | ||
|
|
f796a01756 | ||
|
|
77d2e20dda | ||
|
|
e8d14cdc3f | ||
|
|
1f06e3c2e7 | ||
|
|
268d23cb88 | ||
|
|
5ee98bec89 | ||
|
|
ec89e0dbba | ||
|
|
dbc7a006d2 | ||
|
|
1d4d3f5119 | ||
|
|
e99ef17c43 | ||
|
|
9deaad0477 | ||
|
|
0f9caba58c | ||
|
|
190d222245 | ||
|
|
2dfa7cb8aa | ||
|
|
cfcfb822e3 | ||
|
|
6052f17add | ||
|
|
0d13a2654d | ||
|
|
c9a892a452 | ||
|
|
4399c1c642 | ||
|
|
c9378b4d98 | ||
|
|
0813bf6a95 | ||
|
|
3b21cf5552 | ||
|
|
7a074e2472 | ||
|
|
1ac71f3d5d | ||
|
|
44c381466a | ||
|
|
20ced6370a | ||
|
|
f45101a7dc | ||
|
|
19ad21c88d | ||
|
|
ed06faf99d | ||
|
|
63b0d7bde0 | ||
|
|
bd7e2bd627 | ||
|
|
eb62ad1738 | ||
|
|
3388506cc5 | ||
|
|
fcba4cada4 | ||
|
|
b840fb32d5 | ||
|
|
ca5777adfe | ||
|
|
c87db8a371 | ||
|
|
0b582e91eb | ||
|
|
4ab913d3c8 | ||
|
|
a3599c2621 | ||
|
|
eeb941324e | ||
|
|
3f685dae15 | ||
|
|
c6367345c9 | ||
|
|
e0e497faf0 | ||
|
|
fc4096ddf5 | ||
|
|
391f48f4c8 | ||
|
|
32fde03838 | ||
|
|
d9eba25e04 | ||
|
|
955237e707 | ||
|
|
2436225f7c | ||
|
|
f2a8e7f280 | ||
|
|
e52c78e4ad | ||
|
|
56f81dbc45 | ||
|
|
98e6495be0 | ||
|
|
7e0c7039fc | ||
|
|
fa62be36e1 | ||
|
|
9d6a9f7df7 | ||
|
|
cbbd87587d | ||
|
|
5acf68533c | ||
|
|
9f6a77eb1b | ||
|
|
d9bafea31b | ||
|
|
ae0431cfdd | ||
|
|
14f99808b8 | ||
|
|
350c550ef6 | ||
|
|
052c85eeec | ||
|
|
0921519b90 | ||
|
|
b799e5d64f | ||
|
|
907a14d209 | ||
|
|
35ba652848 | ||
|
|
557ec22d13 | ||
|
|
e00c1a0f1f | ||
|
|
8dae1dd94c | ||
|
|
e409144310 |
No files matched your search
-27
@@ -1,27 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
configure
|
||||
FS2_Open.prj
|
||||
FS2_Open.prj.bak
|
||||
FS2_Open.pws
|
||||
.tm_project.cache
|
||||
config.guess
|
||||
config.cache
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
autom4te*
|
||||
aclocal.m4
|
||||
Freespace2.dsp
|
||||
Freespace2.dsw
|
||||
Freespace2.ncb
|
||||
Freespace2.opt
|
||||
Freespace2.plg
|
||||
Release
|
||||
Debug
|
||||
.DS_Store
|
||||
.deps
|
||||
+332
@@ -380,3 +380,335 @@ AC_DEFUN([AM_PATH_WXCONFIG],
|
||||
AC_SUBST(WX_LIBS_STATIC)
|
||||
AC_SUBST(WX_VERSION)
|
||||
])
|
||||
|
||||
# Configure paths for libogg
|
||||
# Jack Moffitt <[email protected]> 10-21-2000
|
||||
# Shamelessly stolen from Owen Taylor and Manish Singh
|
||||
|
||||
dnl XIPH_PATH_OGG([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libogg, and define OGG_CFLAGS and OGG_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_OGG],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(ogg,[ --with-ogg=PFX Prefix where libogg is installed (optional)], ogg_prefix="$withval", ogg_prefix="")
|
||||
AC_ARG_WITH(ogg-libraries,[ --with-ogg-libraries=DIR Directory where libogg library is installed (optional)], ogg_libraries="$withval", ogg_libraries="")
|
||||
AC_ARG_WITH(ogg-includes,[ --with-ogg-includes=DIR Directory where libogg header files are installed (optional)], ogg_includes="$withval", ogg_includes="")
|
||||
AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run a test Ogg program],, enable_oggtest=yes)
|
||||
|
||||
if test "x$ogg_libraries" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_libraries"
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE" ; then
|
||||
OGG_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OGG_LIBS="$OGG_LIBS -logg"
|
||||
|
||||
if test "x$ogg_includes" != "x" ; then
|
||||
OGG_CFLAGS="-I$ogg_includes"
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_CFLAGS="-I$ogg_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OGG_CFLAGS=""
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for Ogg)
|
||||
no_ogg=""
|
||||
|
||||
|
||||
if test "x$enable_oggtest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Ogg is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.oggtest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
system("touch conf.oggtest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_ogg=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_ogg" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.oggtest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Ogg test program, checking why..."
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <ogg/ogg.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Ogg or finding the wrong"
|
||||
echo "*** version of Ogg. If it is not finding Ogg, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Ogg was incorrectly installed"
|
||||
echo "*** or that you have moved Ogg since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
OGG_CFLAGS=""
|
||||
OGG_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OGG_CFLAGS)
|
||||
AC_SUBST(OGG_LIBS)
|
||||
rm -f conf.oggtest
|
||||
])
|
||||
|
||||
# Configure paths for libvorbis
|
||||
# Jack Moffitt <[email protected]> 10-21-2000
|
||||
# Shamelessly stolen from Owen Taylor and Manish Singh
|
||||
# thomasvs added check for vorbis_bitrate_addblock which is new in rc3
|
||||
|
||||
dnl XIPH_PATH_VORBIS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libvorbis, and define VORBIS_CFLAGS and VORBIS_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_VORBIS],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(vorbis,[ --with-vorbis=PFX Prefix where libvorbis is installed (optional)], vorbis_prefix="$withval", vorbis_prefix="")
|
||||
AC_ARG_WITH(vorbis-libraries,[ --with-vorbis-libraries=DIR Directory where libvorbis library is installed (optional)], vorbis_libraries="$withval", vorbis_libraries="")
|
||||
AC_ARG_WITH(vorbis-includes,[ --with-vorbis-includes=DIR Directory where libvorbis header files are installed (optional)], vorbis_includes="$withval", vorbis_includes="")
|
||||
AC_ARG_ENABLE(vorbistest, [ --disable-vorbistest Do not try to compile and run a test Vorbis program],, enable_vorbistest=yes)
|
||||
|
||||
if test "x$vorbis_libraries" != "x" ; then
|
||||
VORBIS_LIBS="-L$vorbis_libraries"
|
||||
elif test "x$vorbis_prefix" != "x" ; then
|
||||
VORBIS_LIBS="-L$vorbis_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
VORBIS_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
VORBIS_LIBS="$VORBIS_LIBS -lvorbis -lm"
|
||||
VORBISFILE_LIBS="-lvorbisfile"
|
||||
VORBISENC_LIBS="-lvorbisenc"
|
||||
|
||||
if test "x$vorbis_includes" != "x" ; then
|
||||
VORBIS_CFLAGS="-I$vorbis_includes"
|
||||
elif test "x$vorbis_prefix" != "x" ; then
|
||||
VORBIS_CFLAGS="-I$vorbis_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
VORBIS_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for Vorbis)
|
||||
no_vorbis=""
|
||||
|
||||
|
||||
if test "x$enable_vorbistest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $VORBIS_CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $VORBIS_LIBS $VORBISENC_LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Vorbis is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.vorbistest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
vorbis_block vb;
|
||||
vorbis_dsp_state vd;
|
||||
vorbis_info vi;
|
||||
|
||||
vorbis_info_init (&vi);
|
||||
vorbis_encode_init (&vi, 2, 44100, -1, 128000, -1);
|
||||
vorbis_analysis_init (&vd, &vi);
|
||||
vorbis_block_init (&vd, &vb);
|
||||
/* this function was added in 1.0rc3, so this is what we're testing for */
|
||||
vorbis_bitrate_addblock (&vb);
|
||||
|
||||
system("touch conf.vorbistest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_vorbis=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_vorbis" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.vorbistest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Vorbis test program, checking why..."
|
||||
CFLAGS="$CFLAGS $VORBIS_CFLAGS"
|
||||
LIBS="$LIBS $VORBIS_LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <vorbis/codec.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Vorbis or finding the wrong"
|
||||
echo "*** version of Vorbis. If it is not finding Vorbis, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Vorbis was incorrectly installed"
|
||||
echo "*** or that you have moved Vorbis since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
VORBIS_CFLAGS=""
|
||||
VORBIS_LIBS=""
|
||||
VORBISFILE_LIBS=""
|
||||
VORBISENC_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(VORBIS_CFLAGS)
|
||||
AC_SUBST(VORBIS_LIBS)
|
||||
AC_SUBST(VORBISFILE_LIBS)
|
||||
AC_SUBST(VORBISENC_LIBS)
|
||||
rm -f conf.vorbistest
|
||||
])
|
||||
|
||||
dnl XIPH_PATH_THEORA([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libtheora, and define THEORA_CFLAGS and THEORA_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_THEORA],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(theora,[ --with-theora=PFX Prefix where libtheora is installed (optional)], theora_prefix="$withval", theora_prefix="")
|
||||
AC_ARG_WITH(theora-libraries,[ --with-theora-libraries=DIR Directory where libtheora library is installed (optional)], theora_libraries="$withval", theora_libraries="")
|
||||
AC_ARG_WITH(theora-includes,[ --with-theora-includes=DIR Directory where libtheora header files are installed (optional)], theora_includes="$withval", theora_includes="")
|
||||
AC_ARG_ENABLE(theoratest, [ --disable-theoratest Do not try to compile and run a test Theora program],, enable_theoratest=yes)
|
||||
|
||||
if test "x$theora_libraries" != "x" ; then
|
||||
THEORA_LIBS="-L$theora_libraries"
|
||||
elif test "x$theora_prefix" != "x" ; then
|
||||
THEORA_LIBS="-L$theora_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
THEORA_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
THEORA_LIBS="$THEORA_LIBS -ltheora"
|
||||
|
||||
if test "x$theora_includes" != "x" ; then
|
||||
THEORA_CFLAGS="-I$theora_includes"
|
||||
elif test "x$theora_prefix" != "x" ; then
|
||||
THEORA_CFLAGS="-I$theora_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
THEORA_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for Theora)
|
||||
no_theora=""
|
||||
|
||||
|
||||
if test "x$enable_theoratest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $THEORA_CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $THEORA_LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Theora is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.theoratest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <theora/theora.h>
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
theora_info ti;
|
||||
theora_state ts;
|
||||
|
||||
theora_info_init(&ti);
|
||||
|
||||
system("touch conf.theoratest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_theora=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_theora" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.theoratest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Theora test program, checking why..."
|
||||
CFLAGS="$CFLAGS $THEORA_CFLAGS"
|
||||
LIBS="$LIBS $THEORA_LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <vorbis/codec.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Theora or finding the wrong"
|
||||
echo "*** version of Theora. If it is not finding Theora, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Theora was incorrectly installed"
|
||||
echo "*** or that you have moved Theora since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
THEORA_CFLAGS=""
|
||||
THEORA_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(THEORA_CFLAGS)
|
||||
AC_SUBST(THEORA_LIBS)
|
||||
rm -f conf.theoratest
|
||||
])
|
||||
@@ -1,5 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
fs2_open_d
|
||||
fs2_open_r
|
||||
.deps
|
||||
+21
-11
@@ -1,6 +1,6 @@
|
||||
## code/Makefile.am for fs2_open
|
||||
##
|
||||
## $Id: Makefile.am,v 1.31 2006-05-13 06:59:48 taylor Exp $
|
||||
## $Id: Makefile.am,v 1.42 2007-11-22 04:52:30 taylor Exp $
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
@@ -124,8 +124,6 @@ EXTRA_DIST = \
|
||||
fred2/textviewdlg.h \
|
||||
fred2/voiceactingmanager.cpp \
|
||||
fred2/voiceactingmanager.h \
|
||||
fred2/voicefilemanager.cpp \
|
||||
fred2/voicefilemanager.h \
|
||||
fred2/waypointpathdlg.cpp \
|
||||
fred2/waypointpathdlg.h \
|
||||
fred2/weaponeditordlg.cpp \
|
||||
@@ -179,7 +177,9 @@ EXTRA_DIST = \
|
||||
fred2/res/toolbar.bmp \
|
||||
fred2/res/toolbar1.bmp \
|
||||
fred2/res/variable.bmp \
|
||||
wxfred2/res/FRED.ico \
|
||||
sound/phrases.xml \
|
||||
sound/gc.exe \
|
||||
wxfred2/res/fred.ico \
|
||||
wxfred2/wxfred.xrc
|
||||
|
||||
|
||||
@@ -241,12 +241,15 @@ FS2_SOURCES = \
|
||||
cutscene/cutscenes.cpp \
|
||||
cutscene/cutscenes.h \
|
||||
cutscene/decoder16.cpp \
|
||||
cutscene/decoder8.cpp \
|
||||
cutscene/movie.cpp \
|
||||
cutscene/movie.h \
|
||||
cutscene/mve_audio.cpp \
|
||||
cutscene/mvelib.cpp \
|
||||
cutscene/mvelib.h \
|
||||
cutscene/mveplayer.cpp \
|
||||
cutscene/oggplayer.cpp \
|
||||
cutscene/oggplayer.h \
|
||||
ddsutils/ddsutils.cpp \
|
||||
ddsutils/ddsutils.h \
|
||||
debris/debris.cpp \
|
||||
@@ -312,9 +315,8 @@ FS2_SOURCES = \
|
||||
graphics/gropengltexture.h \
|
||||
graphics/gropengltnl.cpp \
|
||||
graphics/gropengltnl.h \
|
||||
graphics/grstub.cpp \
|
||||
graphics/grstub.h \
|
||||
graphics/grzbuffer.cpp \
|
||||
graphics/grzbuffer.h \
|
||||
graphics/line.h \
|
||||
graphics/tmapper.h \
|
||||
hud/hud.cpp \
|
||||
@@ -440,6 +442,8 @@ FS2_SOURCES = \
|
||||
mission/missiontraining.h \
|
||||
missionui/chatbox.cpp \
|
||||
missionui/chatbox.h \
|
||||
missionui/fictionviewer.cpp \
|
||||
missionui/fictionviewer.h \
|
||||
missionui/missionbrief.cpp \
|
||||
missionui/missionbrief.h \
|
||||
missionui/missioncmdbrief.cpp \
|
||||
@@ -464,7 +468,9 @@ FS2_SOURCES = \
|
||||
missionui/redalert.h \
|
||||
model/model.h \
|
||||
model/modelanim.cpp \
|
||||
model/modelanim.h \
|
||||
model/modelcollide.cpp \
|
||||
model/modeldiff.cpp \
|
||||
model/modelinterp.cpp \
|
||||
model/modelsinc.h \
|
||||
model/modeloctant.cpp \
|
||||
@@ -539,6 +545,8 @@ FS2_SOURCES = \
|
||||
object/collideshipship.cpp \
|
||||
object/collideshipweapon.cpp \
|
||||
object/collideweaponweapon.cpp \
|
||||
object/deadobjectdock.cpp \
|
||||
object/deadobjectdock.h \
|
||||
object/objcollide.cpp \
|
||||
object/objcollide.h \
|
||||
object/objectdock.cpp \
|
||||
@@ -546,8 +554,11 @@ FS2_SOURCES = \
|
||||
object/object.cpp \
|
||||
object/object.h \
|
||||
object/objectsort.cpp \
|
||||
object/objectshield.cpp \
|
||||
object/parseobjectdock.cpp \
|
||||
object/parseobjectdock.h \
|
||||
object/waypoint/waypoint.cpp \
|
||||
object/waypoint/waypoint.h \
|
||||
observer/observer.cpp \
|
||||
observer/observer.h \
|
||||
palman/palman.cpp \
|
||||
@@ -716,7 +727,9 @@ SOUND_SOURCES = \
|
||||
sound/fsspeech.cpp \
|
||||
sound/fsspeech.h \
|
||||
sound/speech.cpp \
|
||||
sound/speech.h
|
||||
sound/speech.h \
|
||||
sound/voicerec.cpp \
|
||||
sound/voicerec.h
|
||||
endif
|
||||
|
||||
## Win32-specific sources
|
||||
@@ -739,13 +752,10 @@ WIN32_SOURCES = \
|
||||
graphics/gl/Gl.h \
|
||||
graphics/gl/Glext.h \
|
||||
graphics/gl/wglext.h \
|
||||
graphics/GrD3DParticle.cpp \
|
||||
graphics/GrD3DParticle.h \
|
||||
graphics/GrD3DStateBlock.cpp \
|
||||
graphics/GrD3DStateBlock.h \
|
||||
graphics/grd3d.cpp \
|
||||
graphics/grd3d.h \
|
||||
graphics/grd3dbatch.cpp \
|
||||
graphics/grd3dbatch.h \
|
||||
graphics/grd3dcalls.cpp \
|
||||
graphics/grd3dbmpman.cpp \
|
||||
graphics/grd3dbmpman.h \
|
||||
|
||||
+30
-22
@@ -9,11 +9,35 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Ship/ai.h $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2006-02-25 21:46:59 $
|
||||
* $Revision: 1.19 $
|
||||
* $Date: 2007-08-11 16:52:02 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.18 2007/02/18 06:16:46 Goober5000
|
||||
* revert Bobboau's commits for the past two months; these will be added in later in a less messy/buggy manner
|
||||
*
|
||||
* Revision 1.17 2007/02/11 21:26:34 Goober5000
|
||||
* massive shield infrastructure commit
|
||||
*
|
||||
* Revision 1.16 2007/01/14 14:03:31 bobboau
|
||||
* ok, something aparently went wrong, last time, so I'm commiting again
|
||||
* hopefully it should work this time
|
||||
* damnit WORK!!!
|
||||
*
|
||||
* Revision 1.15 2007/01/07 01:00:18 Goober5000
|
||||
* convert a mission variable to a mission flag
|
||||
*
|
||||
* Revision 1.14 2006/12/28 00:59:18 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.13 2006/06/04 01:01:52 Goober5000
|
||||
* add fighterbay restriction code
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.12 2006/02/25 21:46:59 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 1.11 2006/02/20 02:13:07 Goober5000
|
||||
* added ai-ignore-new which hopefully should fix the ignore bug
|
||||
* --Goober5000
|
||||
@@ -438,20 +462,8 @@ typedef struct ai_goal {
|
||||
|
||||
#define MAX_AI_BEHAVIORS 22 // Number of AIM_xxxx types
|
||||
|
||||
#define MAX_WAYPOINTS_PER_LIST 20
|
||||
#define MAX_WAYPOINT_LISTS 32
|
||||
#define MAX_ENEMY_DISTANCE 2500.0f // maximum distance from which a ship will pursue an enemy.
|
||||
|
||||
// waypoint list flags bitmasks.
|
||||
#define WL_MARKED 0x01
|
||||
|
||||
typedef struct waypoint_list {
|
||||
char name[NAME_LENGTH];
|
||||
int count;
|
||||
char flags[MAX_WAYPOINTS_PER_LIST];
|
||||
vec3d waypoints[MAX_WAYPOINTS_PER_LIST];
|
||||
} waypoint_list;
|
||||
|
||||
#define AI_GOAL_NONE -1
|
||||
|
||||
#define AI_ACTIVE_GOAL_DYNAMIC 999
|
||||
@@ -551,7 +563,7 @@ typedef struct ai_info {
|
||||
int type; //
|
||||
int wing; // Member of what wing? -1 means none.
|
||||
|
||||
int behavior; // AI Class. Doesn't change after initial setting.
|
||||
int behavior; // AI behavior; vestigial field from early development of FS1
|
||||
int mode;
|
||||
int previous_mode;
|
||||
int mode_time; // timestamp at which current mode elapses.
|
||||
@@ -734,7 +746,6 @@ typedef struct ai_info {
|
||||
#define MAX_BURST_DAMAGE 20 // max damage that can be done in BURST_DURATION
|
||||
#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_ship_names;
|
||||
extern char Goal_ship_names[MAX_GOAL_SHIP_NAMES][NAME_LENGTH];
|
||||
|
||||
@@ -782,9 +793,6 @@ int get_wingnum(int objnum);
|
||||
void set_wingnum(int objnum, int wingnum);
|
||||
char *ai_get_goal_ship_name(char *name, int *index);
|
||||
|
||||
extern waypoint_list Waypoint_lists[MAX_WAYPOINT_LISTS];
|
||||
extern int Num_waypoint_lists;
|
||||
|
||||
extern void init_ai_system(void);
|
||||
extern void ai_attack_object(object *attacker, object *attacked, int priority, ship_subsys *ssp);
|
||||
extern void ai_evade_object(object *evader, object *evaded, int priority);
|
||||
@@ -795,7 +803,7 @@ 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, 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_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int quadrant_num, 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);
|
||||
extern void init_ai_object(int objnum);
|
||||
@@ -834,8 +842,8 @@ extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int
|
||||
extern void ai_do_safety(object *objp);
|
||||
|
||||
// used to get path info for fighter bay emerging and departing
|
||||
int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, vec3d *pos, vec3d *fvec);
|
||||
int ai_acquire_depart_path(object *pl_objp, int parent_objnum);
|
||||
int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int path_mask, vec3d *pos, vec3d *fvec);
|
||||
int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int path_mask);
|
||||
|
||||
// used by AiBig.cpp
|
||||
extern void ai_set_positions(object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos);
|
||||
|
||||
+96
-41
@@ -6,11 +6,45 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ai/ai_profiles.cpp $
|
||||
* $Revision: 1.13 $
|
||||
* $Date: 2006-04-20 06:32:00 $
|
||||
* $Revision: 1.22 $
|
||||
* $Date: 2007-09-02 02:10:23 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.21 2007/07/19 03:19:32 turey
|
||||
* Made Backslash's change to dampening tied to an ai_profiles flag, as it does affect
|
||||
* retail behavior, and significantly affects gameplay in the BtRL Demo.
|
||||
* Also, fixed a typo.
|
||||
*
|
||||
* Revision 1.20 2007/07/15 02:45:17 Goober5000
|
||||
* fixed a small bug in the lab
|
||||
* moved WMC's no damage scaling flag to ai_profiles and made it work correctly
|
||||
* removed my old supercap damage scaling change
|
||||
* moved Turey's truefire flag to ai_profiles
|
||||
*
|
||||
* Revision 1.19 2007/02/27 01:44:48 Goober5000
|
||||
* add two features for WCS: specifyable shield/weapon recharge rates, and removal of linked fire penalty
|
||||
*
|
||||
* Revision 1.18 2006/12/28 00:59:18 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.17 2006/09/11 06:49:38 taylor
|
||||
* fixes for stuff_string() bounds checking
|
||||
*
|
||||
* Revision 1.16 2006/07/12 04:59:03 taylor
|
||||
* fix the endless-loop fix ;) (this is what broke shield recharging btw)
|
||||
*
|
||||
* Revision 1.15 2006/07/06 18:19:59 Goober5000
|
||||
* fix dumb endless loop bug
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.14 2006/07/02 03:39:55 Goober5000
|
||||
* remove associated AI flags
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.13 2006/04/20 06:32:00 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.12 2006/03/20 06:25:19 taylor
|
||||
* change wording to ease Goober's ulcer. ;)
|
||||
*
|
||||
@@ -96,33 +130,30 @@ void set_flag(ai_profile_t *profile, char *name, int flag)
|
||||
}
|
||||
}
|
||||
|
||||
void parse_ai_profiles_tbl(char *longname)
|
||||
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;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
{
|
||||
mprintf(("Unable to parse %s! Code = %i.\n", rval, (longname) ? longname : NOX("<default>")));
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default ai_profiles.tbl>", rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (longname == NULL)
|
||||
{
|
||||
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
|
||||
}
|
||||
else
|
||||
{
|
||||
read_file_text(longname);
|
||||
}
|
||||
|
||||
reset_parse();
|
||||
}
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
|
||||
else
|
||||
read_file_text(filename);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
@@ -130,50 +161,65 @@ void parse_ai_profiles_tbl(char *longname)
|
||||
|
||||
// new default?
|
||||
if (optional_string("$Default Profile:"))
|
||||
stuff_string(Default_profile_name, F_NAME, NULL, NAME_LENGTH);
|
||||
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#End","$Profile Name:"))
|
||||
{
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
|
||||
// make sure we're under the limit
|
||||
if (Num_ai_profiles >= MAX_AI_PROFILES)
|
||||
{
|
||||
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES-1);
|
||||
skip_to_string("#End", NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
stuff_string(profile_name, F_NAME, NULL, NAME_LENGTH);
|
||||
stuff_string(profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// see if it exists
|
||||
for (i = 0; i < Num_ai_profiles; i++)
|
||||
{
|
||||
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
|
||||
{
|
||||
previous_profile = &Ai_profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// modular table stuff
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
no_create = true;
|
||||
|
||||
for (i = 0; i < Num_ai_profiles; i++)
|
||||
{
|
||||
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
|
||||
{
|
||||
profile = &Ai_profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// use the previous one if possible,
|
||||
// otherwise continue to use the dummy one
|
||||
if (previous_profile != NULL)
|
||||
profile = previous_profile;
|
||||
}
|
||||
else
|
||||
{
|
||||
profile = &Ai_profiles[Num_ai_profiles];
|
||||
Num_ai_profiles++;
|
||||
// don't create multiple profiles with the same name
|
||||
if (previous_profile != NULL)
|
||||
{
|
||||
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we're under the limit
|
||||
if (Num_ai_profiles >= MAX_AI_PROFILES)
|
||||
{
|
||||
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES-1); // -1 because one is built-in
|
||||
skip_to_string("#End", NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
profile = &Ai_profiles[Num_ai_profiles];
|
||||
Num_ai_profiles++;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize profile if we're not building from a previously parsed one
|
||||
if (!no_create)
|
||||
{
|
||||
// base profile, so zero it out
|
||||
if (Num_ai_profiles == 1)
|
||||
if (profile == &Ai_profiles[0])
|
||||
{
|
||||
memset(profile, 0, sizeof(ai_profile_t));
|
||||
}
|
||||
@@ -268,10 +314,6 @@ void parse_ai_profiles_tbl(char *longname)
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS);
|
||||
|
||||
set_flag(profile, "$ai-chase allows rearm:", AIPF_AI_CHASE_ALLOWS_REARM);
|
||||
|
||||
set_flag(profile, "$ai-chase disables dynamic targeting temporarily:", AIPF_AI_CHASE_DISABLES_DYNAMIC_TARGETING_TEMPORARILY);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION);
|
||||
|
||||
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION);
|
||||
@@ -292,8 +334,21 @@ void parse_ai_profiles_tbl(char *longname)
|
||||
|
||||
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP);
|
||||
|
||||
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING);
|
||||
|
||||
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY);
|
||||
|
||||
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if ( saved_Mp && (saved_Mp == Mp) )
|
||||
Mp++;
|
||||
|
||||
// find next valid option
|
||||
skip_to_start_of_string_either("$", "#");
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-13
@@ -6,11 +6,32 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ai/ai_profiles.h $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2006-04-20 06:32:00 $
|
||||
* $Revision: 1.9 $
|
||||
* $Date: 2007-07-28 22:04:46 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.8 2007/07/19 03:19:32 turey
|
||||
* Made Backslash's change to dampening tied to an ai_profiles flag, as it does affect
|
||||
* retail behavior, and significantly affects gameplay in the BtRL Demo.
|
||||
* Also, fixed a typo.
|
||||
*
|
||||
* Revision 1.7 2007/07/15 02:45:17 Goober5000
|
||||
* fixed a small bug in the lab
|
||||
* moved WMC's no damage scaling flag to ai_profiles and made it work correctly
|
||||
* removed my old supercap damage scaling change
|
||||
* moved Turey's truefire flag to ai_profiles
|
||||
*
|
||||
* Revision 1.6 2007/02/27 01:44:48 Goober5000
|
||||
* add two features for WCS: specifyable shield/weapon recharge rates, and removal of linked fire penalty
|
||||
*
|
||||
* Revision 1.5 2006/07/02 03:39:55 Goober5000
|
||||
* remove associated AI flags
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.4 2006/04/20 06:32:00 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.3 2006/03/20 06:19:03 taylor
|
||||
* add ai_profiles flag to get rid of limit on minimum speed a docked ship can move
|
||||
* (not going to Int3() here from < 0.1 speed by default, a support ship actually hit it)
|
||||
@@ -41,17 +62,19 @@
|
||||
// flags
|
||||
#define AIPF_SMART_SHIELD_MANAGEMENT (1 << 0)
|
||||
#define AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS (1 << 1)
|
||||
#define AIPF_AI_CHASE_DISABLES_DYNAMIC_TARGETING_TEMPORARILY (1 << 2)
|
||||
#define AIPF_AI_CHASE_ALLOWS_REARM (1 << 3)
|
||||
#define AIPF_SMART_PRIMARY_WEAPON_SELECTION (1 << 4)
|
||||
#define AIPF_SMART_SECONDARY_WEAPON_SELECTION (1 << 5)
|
||||
#define AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE (1 << 6)
|
||||
#define AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS (1 << 7)
|
||||
#define AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY (1 << 8)
|
||||
#define AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY (1 << 9)
|
||||
#define AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS (1 << 10)
|
||||
#define AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP (1 << 11)
|
||||
#define AIPF_NO_MIN_DOCK_SPEED_CAP (1 << 12)
|
||||
#define AIPF_SMART_PRIMARY_WEAPON_SELECTION (1 << 2)
|
||||
#define AIPF_SMART_SECONDARY_WEAPON_SELECTION (1 << 3)
|
||||
#define AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE (1 << 4)
|
||||
#define AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS (1 << 5)
|
||||
#define AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY (1 << 6)
|
||||
#define AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY (1 << 7)
|
||||
#define AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS (1 << 8)
|
||||
#define AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP (1 << 9)
|
||||
#define AIPF_NO_MIN_DOCK_SPEED_CAP (1 << 10)
|
||||
#define AIPF_DISABLE_LINKED_FIRE_PENALTY (1 << 11)
|
||||
#define AIPF_DISABLE_WEAPON_DAMAGE_SCALING (1 << 12)
|
||||
#define AIPF_USE_ADDITIVE_WEAPON_VELOCITY (1 << 13)
|
||||
#define AIPF_USE_NEWTONIAN_DAMPENING (1 << 14)
|
||||
|
||||
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
+16
-9
@@ -9,13 +9,19 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Ship/AiBig.cpp $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2006-02-25 21:46:59 $
|
||||
* $Revision: 1.14 $
|
||||
* $Date: 2007-07-15 04:19:24 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* C module for AI code related to large ships
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.13 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 1.12 2006/02/25 21:46:59 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 1.11 2006/01/13 03:30:59 Goober5000
|
||||
* übercommit of custom IFF stuff :)
|
||||
*
|
||||
@@ -491,11 +497,12 @@ void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec,
|
||||
model_octant *octp;
|
||||
polymodel *pm;
|
||||
int i, q, octs[4];
|
||||
ship_info *sip = &Ship_info[Ships[objp->instance].ship_info_index];
|
||||
|
||||
best_point = objp->pos;
|
||||
nearest_dist = weapon_travel_dist;
|
||||
|
||||
model_which_octant_distant_many(attacker_objp_pos, Ships[objp->instance].modelnum, &objp->orient, &objp->pos, &pm, octs);
|
||||
model_which_octant_distant_many(attacker_objp_pos, sip->model_num, &objp->orient, &objp->pos, &pm, octs);
|
||||
|
||||
num_tries = (int) (vm_vec_dist(&objp->pos, attacker_objp_pos)/objp->radius);
|
||||
|
||||
@@ -570,7 +577,7 @@ done_1:
|
||||
}
|
||||
|
||||
mc_info mc;
|
||||
mc.model_num = Ships[objp->instance].modelnum;
|
||||
mc.model_num = sip->model_num;
|
||||
mc.orient = &objp->orient;
|
||||
mc.pos = &objp->pos;
|
||||
mc.p0 = attacker_objp_pos;
|
||||
@@ -772,7 +779,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
int subsys_path_num, subsys_in_sight, checked_sight;
|
||||
float dist;
|
||||
|
||||
pm = model_get( Ships[Pl_objp->instance].modelnum );
|
||||
pm = model_get( Ship_info[Ships[Pl_objp->instance].ship_info_index].model_num );
|
||||
|
||||
// If attacking a subsystem, ensure that we have an unobstructed line of sight... if not, then move
|
||||
// towards path linked to subsystem
|
||||
@@ -787,8 +794,8 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
aip->path_subsystem_next_check = timestamp(1500);
|
||||
|
||||
// get world pos of eye (stored in geye)
|
||||
ep = &(pm->view_positions[0] );
|
||||
model_find_world_point( &geye, &ep->pnt, Ships[Pl_objp->instance].modelnum, 0, &Pl_objp->orient, &Pl_objp->pos );
|
||||
ep = &(pm->view_positions[Ships[Pl_objp->instance].current_viewpoint]);
|
||||
model_find_world_point( &geye, &ep->pnt, pm->id, 0, &Pl_objp->orient, &Pl_objp->pos );
|
||||
|
||||
// get world pos of subsystem
|
||||
vm_vec_unrotate(&gsubpos, &aip->targeted_subsys->system_info->pnt, &En_objp->orient);
|
||||
@@ -1284,7 +1291,7 @@ void ai_big_chase()
|
||||
case SM_ATTACK:
|
||||
case SM_SUPER_ATTACK:
|
||||
case SM_ATTACK_FOREVER:
|
||||
ai_big_chase_attack(aip, sip, &enemy_pos, dist_to_enemy, shipp->modelnum);
|
||||
ai_big_chase_attack(aip, sip, &enemy_pos, dist_to_enemy, sip->model_num);
|
||||
break;
|
||||
|
||||
case SM_EVADE:
|
||||
@@ -1516,7 +1523,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
predicted_enemy_pos=*enemy_pos;
|
||||
} else {
|
||||
vec3d gun_pos, pnt;
|
||||
polymodel *po = model_get( shipp->modelnum );
|
||||
polymodel *po = model_get( Ship_info[shipp->ship_info_index].model_num );
|
||||
float weapon_speed;
|
||||
|
||||
// Compute position of gun in absolute space and use that as fire position.
|
||||
|
||||
+544
-336
File diff suppressed because it is too large.
Load diff
+80
-43
@@ -9,13 +9,38 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Ship/AiGoals.cpp $
|
||||
* $Revision: 1.28 $
|
||||
* $Date: 2006-06-01 04:47:23 $
|
||||
* $Revision: 1.36 $
|
||||
* $Date: 2007-03-22 22:19:30 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* File to deal with manipulating AI goals, etc.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.35 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 1.34 2007/02/10 06:39:43 Goober5000
|
||||
* new feature: shield generators that control whether the shield is up
|
||||
*
|
||||
* Revision 1.33 2007/02/10 04:49:22 Goober5000
|
||||
* prevent the AI from falling into the black hole of disarming a turretless ship
|
||||
*
|
||||
* Revision 1.32 2006/12/28 00:59:18 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.31 2006/11/16 00:52:28 taylor
|
||||
* add some needed wing leader checks to prevent Assert()'s and out-of-bounds problems when the leader is dead/dying (Mantis bug #1134)
|
||||
*
|
||||
* Revision 1.30 2006/11/06 03:38:32 Goober5000
|
||||
* --prevent the ai from "forgetting" that it's attacking a wing (fix for Mantis #1131)
|
||||
* --move AI_CHASE_WING goal check so that it will properly short-circuit when appropriate (discussed in the same bug)
|
||||
*
|
||||
* Revision 1.29 2006/09/08 06:20:14 taylor
|
||||
* fix things that strict compiling balked at (from compiling with -ansi and -pedantic)
|
||||
*
|
||||
* Revision 1.28 2006/06/01 04:47:23 taylor
|
||||
* make sure FORM_ON_WING goal is valid since it works for ships other than player now
|
||||
*
|
||||
* Revision 1.27 2006/05/31 02:08:22 Goober5000
|
||||
* fix compiler warning
|
||||
* --Goober5000
|
||||
@@ -688,6 +713,7 @@
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "object/waypoint/waypoint.h"
|
||||
|
||||
|
||||
// all ai goals dealt with in this code are goals that are specified through
|
||||
@@ -714,7 +740,7 @@
|
||||
|
||||
|
||||
#define AI_GOAL_ACHIEVABLE 1
|
||||
#define AI_GOAL_NOT_ACHIEVABLE 2
|
||||
#define AI_GOAL_NOT_ACHIEVABLE 2
|
||||
#define AI_GOAL_NOT_KNOWN 3
|
||||
#define AI_GOAL_SATISFIED 4
|
||||
|
||||
@@ -724,30 +750,30 @@ char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
|
||||
|
||||
ai_goal_list Ai_goal_names[] =
|
||||
{
|
||||
{ "Attack ship", AI_GOAL_CHASE },
|
||||
{ "Dock", AI_GOAL_DOCK },
|
||||
{ "Waypoints", AI_GOAL_WAYPOINTS },
|
||||
{ "Waypoints once", AI_GOAL_WAYPOINTS_ONCE },
|
||||
{ "Depart", AI_GOAL_WARP },
|
||||
{ "Attack subsys", AI_GOAL_DESTROY_SUBSYSTEM },
|
||||
{ "Form on wing", AI_GOAL_FORM_ON_WING },
|
||||
{ "Undock", AI_GOAL_UNDOCK },
|
||||
{ "Attack wing", AI_GOAL_CHASE_WING },
|
||||
{ "Guard ship", AI_GOAL_GUARD },
|
||||
{ "Disable ship", AI_GOAL_DISABLE_SHIP },
|
||||
{ "Disarm ship", AI_GOAL_DISARM_SHIP },
|
||||
{ "Attack any", AI_GOAL_CHASE_ANY },
|
||||
{ "Ignore ship", AI_GOAL_IGNORE },
|
||||
{ "Ignore ship (new)", AI_GOAL_IGNORE_NEW },
|
||||
{ "Guard wing", AI_GOAL_GUARD_WING },
|
||||
{ "Evade ship", AI_GOAL_EVADE_SHIP },
|
||||
{ "Stay near ship", AI_GOAL_STAY_NEAR_SHIP },
|
||||
{ "keep safe dist", AI_GOAL_KEEP_SAFE_DISTANCE },
|
||||
{ "Rearm ship", AI_GOAL_REARM_REPAIR },
|
||||
{ "Stay still", AI_GOAL_STAY_STILL },
|
||||
{ "Play dead", AI_GOAL_PLAY_DEAD },
|
||||
{ "Attack weapon", AI_GOAL_CHASE_WEAPON },
|
||||
{ "Fly to ship", AI_GOAL_FLY_TO_SHIP },
|
||||
{ "Attack ship", AI_GOAL_CHASE, 0 },
|
||||
{ "Dock", AI_GOAL_DOCK, 0 },
|
||||
{ "Waypoints", AI_GOAL_WAYPOINTS, 0 },
|
||||
{ "Waypoints once", AI_GOAL_WAYPOINTS_ONCE, 0 },
|
||||
{ "Depart", AI_GOAL_WARP, 0 },
|
||||
{ "Attack subsys", AI_GOAL_DESTROY_SUBSYSTEM, 0 },
|
||||
{ "Form on wing", AI_GOAL_FORM_ON_WING, 0 },
|
||||
{ "Undock", AI_GOAL_UNDOCK, 0 },
|
||||
{ "Attack wing", AI_GOAL_CHASE_WING, 0 },
|
||||
{ "Guard ship", AI_GOAL_GUARD, 0 },
|
||||
{ "Disable ship", AI_GOAL_DISABLE_SHIP, 0 },
|
||||
{ "Disarm ship", AI_GOAL_DISARM_SHIP, 0 },
|
||||
{ "Attack any", AI_GOAL_CHASE_ANY, 0 },
|
||||
{ "Ignore ship", AI_GOAL_IGNORE, 0 },
|
||||
{ "Ignore ship (new)", AI_GOAL_IGNORE_NEW, 0 },
|
||||
{ "Guard wing", AI_GOAL_GUARD_WING, 0 },
|
||||
{ "Evade ship", AI_GOAL_EVADE_SHIP, 0 },
|
||||
{ "Stay near ship", AI_GOAL_STAY_NEAR_SHIP, 0 },
|
||||
{ "keep safe dist", AI_GOAL_KEEP_SAFE_DISTANCE, 0 },
|
||||
{ "Rearm ship", AI_GOAL_REARM_REPAIR, 0 },
|
||||
{ "Stay still", AI_GOAL_STAY_STILL, 0 },
|
||||
{ "Play dead", AI_GOAL_PLAY_DEAD, 0 },
|
||||
{ "Attack weapon", AI_GOAL_CHASE_WEAPON, 0 },
|
||||
{ "Fly to ship", AI_GOAL_FLY_TO_SHIP, 0 },
|
||||
};
|
||||
|
||||
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
|
||||
@@ -791,7 +817,7 @@ char *Ai_goal_text(int goal)
|
||||
|
||||
// Avoid compiler warning
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
|
||||
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
|
||||
// Goober5000 - made more generic
|
||||
@@ -800,6 +826,10 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
int j;
|
||||
char *wing_leader;
|
||||
|
||||
// if the wing leader isn't available (ie, dead/departed) then go ahead and bail now
|
||||
if (wingp->ship_index[wingp->special_ship] < 0)
|
||||
return;
|
||||
|
||||
// Goober5000 - the wing leader is now not necessarily the player
|
||||
wing_leader = Ships[wingp->ship_index[wingp->special_ship]].ship_name;
|
||||
|
||||
@@ -1069,6 +1099,8 @@ int ai_get_subsystem_type( char *subsystem )
|
||||
return SUBSYSTEM_GAS_COLLECT;
|
||||
} else if ( !strnicmp(subsystem, NOX("activator"), 9) ) {
|
||||
return SUBSYSTEM_ACTIVATION;
|
||||
} else if ( !strnicmp(subsystem, NOX("shield"), 6) ) {
|
||||
return SUBSYSTEM_SHIELD_GENERATOR;
|
||||
} else { // If unrecognized type, set to engine so artist can continue working...
|
||||
if (!Fred_running) {
|
||||
// Int3(); // illegal subsystem type -- find allender
|
||||
@@ -1183,7 +1215,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
// only check 100 points for sanity's sake
|
||||
while (loop_count < 100)
|
||||
{
|
||||
dock_index = model_find_dock_index(shipp->modelnum, dock_type, dock_index+1);
|
||||
dock_index = model_find_dock_index(Ship_info[shipp->ship_info_index].model_num, dock_type, dock_index+1);
|
||||
|
||||
// not found?
|
||||
if (dock_index == -1)
|
||||
@@ -1216,7 +1248,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
Warning(LOCATION, "Too many iterations while looking for a dockpoint on %s. Either there was a bug or this is an übership.\n", shipp->ship_name);
|
||||
|
||||
// if we're here, just return the first dockpoint
|
||||
return model_find_dock_index(shipp->modelnum, dock_type);
|
||||
return model_find_dock_index(Ship_info[shipp->ship_info_index].model_num, dock_type);
|
||||
}
|
||||
|
||||
// function to fix up dock point references for objects.
|
||||
@@ -1800,13 +1832,9 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// locate a capital ship on the same team:
|
||||
if (ship_get_ship_with_dock_bay(shipp->team) >= 0)
|
||||
{
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
}
|
||||
|
||||
|
||||
@@ -1850,9 +1878,8 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
switch ( aigp->ai_mode )
|
||||
{
|
||||
case AI_GOAL_DOCK:
|
||||
case AI_GOAL_CHASE_WING:
|
||||
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_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
|
||||
@@ -1896,14 +1923,14 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// to guard or ignore a ship, the goal cannot continue if the ship being guarded is either destroyed
|
||||
// or has departed.
|
||||
case AI_GOAL_CHASE:
|
||||
case AI_GOAL_GUARD:
|
||||
case AI_GOAL_IGNORE:
|
||||
case AI_GOAL_IGNORE_NEW:
|
||||
case AI_GOAL_EVADE_SHIP:
|
||||
case AI_GOAL_CHASE:
|
||||
case AI_GOAL_STAY_NEAR_SHIP:
|
||||
case AI_GOAL_REARM_REPAIR:
|
||||
case AI_GOAL_FLY_TO_SHIP:
|
||||
case AI_GOAL_REARM_REPAIR:
|
||||
{
|
||||
// MWA -- 4/22/98. Check for the ship actually being in the mission before
|
||||
// checking departure and destroyed. In multiplayer, since ships can respawn,
|
||||
@@ -1923,6 +1950,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
break;
|
||||
}
|
||||
|
||||
case AI_GOAL_CHASE_WING:
|
||||
case AI_GOAL_GUARD_WING:
|
||||
{
|
||||
status = mission_log_get_time( LOG_WING_DEPARTED, aigp->ship_name, NULL, NULL );
|
||||
@@ -1974,7 +2002,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
sindex = wing_name_lookup( aigp->ship_name );
|
||||
|
||||
if (sindex < 0)
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
|
||||
wing *wingp = &Wings[sindex];
|
||||
|
||||
@@ -2015,6 +2043,14 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000 - before doing anything else, check if this is a disarm goal for an arrived ship...
|
||||
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->ship_name)].subsys_info[SUBSYSTEM_TURRET].num == 0)
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
|
||||
// if the goal is an ignore/disable/disarm goal, then
|
||||
// Goober5000 - see note at PURGE_GOALS_ALL_SHIPS... this is bizarre
|
||||
if ((status == SHIP_STATUS_ARRIVED) && !(aigp->flags & AIGF_GOALS_PURGED))
|
||||
@@ -2036,7 +2072,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// this goal will get removed.
|
||||
if ( (aigp->ai_mode == AI_GOAL_DOCK) && (status == SHIP_STATUS_ARRIVED) ) {
|
||||
if (!(aigp->flags & AIGF_DOCKER_INDEX_VALID)) {
|
||||
modelnum = Ships[objp->instance].modelnum;
|
||||
modelnum = Ship_info[Ships[objp->instance].ship_info_index].model_num;
|
||||
Assert( modelnum >= 0 );
|
||||
index = model_find_dock_name_index(modelnum, aigp->docker.name);
|
||||
aigp->docker.index = index;
|
||||
@@ -2046,7 +2082,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
if (!(aigp->flags & AIGF_DOCKEE_INDEX_VALID)) {
|
||||
sindex = ship_name_lookup(aigp->ship_name);
|
||||
if ( sindex != -1 ) {
|
||||
modelnum = Ships[sindex].modelnum;
|
||||
modelnum = Ship_info[Ships[sindex].ship_info_index].model_num;
|
||||
index = model_find_dock_name_index(modelnum, aigp->dockee.name);
|
||||
aigp->dockee.index = index;
|
||||
aigp->flags |= AIGF_DOCKEE_INDEX_VALID;
|
||||
@@ -2151,13 +2187,14 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
switch ( aigp->ai_mode )
|
||||
{
|
||||
case AI_GOAL_CHASE:
|
||||
case AI_GOAL_CHASE_WING:
|
||||
case AI_GOAL_DOCK:
|
||||
case AI_GOAL_DESTROY_SUBSYSTEM:
|
||||
case AI_GOAL_UNDOCK:
|
||||
case AI_GOAL_GUARD:
|
||||
case AI_GOAL_GUARD_WING:
|
||||
case AI_GOAL_DISABLE_SHIP:
|
||||
case AI_GOAL_DISARM_SHIP:
|
||||
case AI_GOAL_DESTROY_SUBSYSTEM:
|
||||
case AI_GOAL_IGNORE:
|
||||
case AI_GOAL_IGNORE_NEW:
|
||||
case AI_GOAL_EVADE_SHIP:
|
||||
|
||||
+243
-93
@@ -1,12 +1,81 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ai/aiturret.cpp $
|
||||
* $Revision: 1.39 $
|
||||
* $Date: 2006-06-01 04:40:41 $
|
||||
* $Revision: 1.59 $
|
||||
* $Date: 2007-03-22 20:08:49 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Functions for AI control of turrets
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.58 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 1.57 2007/02/18 06:16:46 Goober5000
|
||||
* revert Bobboau's commits for the past two months; these will be added in later in a less messy/buggy manner
|
||||
*
|
||||
* Revision 1.56 2007/02/11 06:19:05 Goober5000
|
||||
* invert the do-collision flag into a don't-do-collision flag, plus fixed a wee lab bug
|
||||
*
|
||||
* Revision 1.55 2007/02/05 08:27:13 wmcoolmon
|
||||
* Couple of commented-out features.
|
||||
*
|
||||
* Revision 1.54 2007/01/22 21:45:10 Goober5000
|
||||
* removed code that isn't used (see Mantis 1219)
|
||||
*
|
||||
* Revision 1.53 2007/01/15 01:37:37 wmcoolmon
|
||||
* Fix CVS & correct various warnings under MSVC 2003
|
||||
*
|
||||
* Revision 1.52 2007/01/14 14:03:31 bobboau
|
||||
* ok, something aparently went wrong, last time, so I'm commiting again
|
||||
* hopefully it should work this time
|
||||
* damnit WORK!!!
|
||||
*
|
||||
* Revision 1.51 2007/01/08 00:50:58 Goober5000
|
||||
* remove WMC's limbo code, per our discussion a few months ago
|
||||
* this will later be handled by copying ship stats using sexps or scripts
|
||||
*
|
||||
* Revision 1.50 2007/01/07 12:36:51 taylor
|
||||
* make fire-on-normal return value a little more obvious
|
||||
* fix the "infinite genius" move I made by breaking turret movements ;)
|
||||
*
|
||||
* Revision 1.49 2006/12/28 00:59:18 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.48 2006/11/06 07:00:05 taylor
|
||||
* fix return values (something that was different between 3_6_9 and HEAD)
|
||||
*
|
||||
* Revision 1.47 2006/11/06 06:32:30 taylor
|
||||
* updated/fixed modelanim code
|
||||
* add ships.tbl subsystem flag ("+fire-down-normals") which will force a turret to fire down it's barrel line (Mantis bug #591)
|
||||
*
|
||||
* Revision 1.46 2006/09/13 03:17:06 taylor
|
||||
* restore MAX_AIFTT_TURRETS to retail level, and add comment as to what it means for the next person that tries to change it
|
||||
*
|
||||
* Revision 1.45 2006/09/11 09:43:35 taylor
|
||||
* revert to retail behavior for turret_should_pick_new_target()
|
||||
* fix out-of-bounds issue
|
||||
*
|
||||
* Revision 1.44 2006/09/08 06:16:18 taylor
|
||||
* fix for Mantis bug #687 (at least until better swarming code can be written, post-3.6.9)
|
||||
* a quick speed/sanity check for turrets to be sure that they actually have a weapon to fire before processing them
|
||||
*
|
||||
* Revision 1.43 2006/09/04 18:06:36 Goober5000
|
||||
* fix macros
|
||||
*
|
||||
* Revision 1.42 2006/09/04 06:13:31 wmcoolmon
|
||||
* Update to allow flak range to be manually overridden, and safeguard against NULL predicted_pos
|
||||
*
|
||||
* Revision 1.41 2006/07/09 01:55:41 Goober5000
|
||||
* consolidate the "for reals" crap into a proper ship flag; also move the limbo flags over to SF2_*; etc.
|
||||
* this should fix Mantis #977
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.40 2006/06/07 04:36:52 wmcoolmon
|
||||
* Fix muzzleflashes for non-flak weapons. Begin commit of limbo code.
|
||||
*
|
||||
* Revision 1.39 2006/06/01 04:40:41 taylor
|
||||
* be sure to to reset ok_to_fire between weapon checks to make sure we don't count something by mistake
|
||||
*
|
||||
* Revision 1.38 2006/04/14 21:13:31 taylor
|
||||
* Grrr! That was still stupid. Just going to revert it to retail and work out that bug it was supposed to fix at a later time.
|
||||
*
|
||||
@@ -145,6 +214,7 @@
|
||||
#include "object/objectdock.h"
|
||||
#include "ai/aiinternal.h" //Included last, so less includes are needed
|
||||
#include "iff_defs/iff_defs.h"
|
||||
#include "weapon/muzzleflash.h"
|
||||
|
||||
// How close a turret has to be point at its target before it
|
||||
// can fire. If the dot of the gun normal and the vector from gun
|
||||
@@ -359,6 +429,17 @@ weapon_info *get_turret_weapon_wip(ship_weapon *swp, int weapon_num)
|
||||
return &Weapon_info[swp->primary_bank_weapons[weapon_num]];
|
||||
}
|
||||
|
||||
int get_turret_weapon_next_fire_stamp(ship_weapon *swp, int weapon_num)
|
||||
{
|
||||
Assert(weapon_num < MAX_SHIP_WEAPONS);
|
||||
Assert(weapon_num >= 0);
|
||||
|
||||
if(weapon_num >= MAX_SHIP_PRIMARY_BANKS)
|
||||
return swp->next_secondary_fire_stamp[weapon_num - MAX_SHIP_PRIMARY_BANKS];
|
||||
else
|
||||
return swp->next_primary_fire_stamp[weapon_num];
|
||||
}
|
||||
|
||||
|
||||
//This function is kinda slow
|
||||
//Returns the longest-ranged weapon on a turret
|
||||
@@ -422,7 +503,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
}
|
||||
|
||||
// don't shoot at ships without collision check
|
||||
if ( !(sip->flags & SIF_DO_COLLISION_CHECK)) {
|
||||
if (sip->flags & SIF_NO_COLLIDE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -914,6 +995,9 @@ void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos,
|
||||
// *gvec: vector fro *gpos to *targetp
|
||||
void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, int use_angles, vec3d *targetp)
|
||||
{
|
||||
Assert(ssp != NULL);
|
||||
Assert(ssp->system_info != NULL);
|
||||
|
||||
vec3d * gun_pos;
|
||||
model_subsystem *tp = ssp->system_info;
|
||||
|
||||
@@ -923,13 +1007,11 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
|
||||
model_find_world_point(gpos, gun_pos, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
|
||||
|
||||
//WMC - use_angles was always 0
|
||||
if (use_angles)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -941,10 +1023,11 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
// Some obscure model thing only John Slagel knows about.
|
||||
// Sets predicted enemy position.
|
||||
// If the turret (*ss) has a subsystem targeted, the subsystem is used as the predicted point.
|
||||
void aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object *objp, object *lep, vec3d *predicted_enemy_pos, vec3d *gvec)
|
||||
int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object *objp, object *lep, vec3d *predicted_enemy_pos, vec3d *gvec)
|
||||
{
|
||||
if (ss->turret_enemy_objnum != -1)
|
||||
{
|
||||
int ret_val = 0;
|
||||
|
||||
if (ss->turret_enemy_objnum != -1) {
|
||||
model_subsystem *tp = ss->system_info;
|
||||
vec3d gun_pos, gun_vec;
|
||||
//float weapon_speed;
|
||||
@@ -955,8 +1038,8 @@ void aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
|
||||
int best_weapon_tidx = turret_select_best_weapon(ss, lep);
|
||||
|
||||
//This turret doesn't have any good weapons
|
||||
if(best_weapon_tidx < 0)
|
||||
return;
|
||||
if (best_weapon_tidx < 0)
|
||||
return 0;
|
||||
|
||||
weapon_info *wip = get_turret_weapon_wip(&ss->weapons, best_weapon_tidx);
|
||||
|
||||
@@ -997,13 +1080,26 @@ void aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
|
||||
//If the dot product is smaller than or equal to the turret's FOV, try and point the gun at it.
|
||||
vec3d v2e;
|
||||
vm_vec_normalized_dir(&v2e, predicted_enemy_pos, &gun_pos);
|
||||
if (vm_vec_dot(&v2e, gvec) > tp->turret_fov) {
|
||||
|
||||
model_rotate_gun(shipp->modelnum, ss->system_info, &Objects[parent_objnum].orient,
|
||||
&ss->submodel_info_1.angs, &ss->submodel_info_2.angs,
|
||||
&Objects[parent_objnum].pos, predicted_enemy_pos);
|
||||
if (vm_vec_dot(&v2e, gvec) > tp->turret_fov) {
|
||||
ret_val = model_rotate_gun(Ship_info[shipp->ship_info_index].model_num,
|
||||
ss->system_info, &Objects[parent_objnum].orient,
|
||||
&ss->submodel_info_1.angs, &ss->submodel_info_2.angs,
|
||||
&Objects[parent_objnum].pos, predicted_enemy_pos);
|
||||
}
|
||||
}
|
||||
|
||||
// by default "ret_val" should be set to 1 for multi-part turrets, and 0 for single-part turrets
|
||||
// but we need to keep retail behavior by default, which means always returning 0 unless a special
|
||||
// flag is used. the "ret_val" stuff is here is needed/wanted at a later date however.
|
||||
//return ret_val;
|
||||
|
||||
// return 0 by default (to preserve retail behavior) but allow for a per-subsystem option
|
||||
// for using the turret normals for firing
|
||||
if (ss->system_info->flags & MSS_FLAG_FIRE_ON_NORMAL)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Determine if subsystem *enemy_subsysp is hittable from objp.
|
||||
@@ -1026,7 +1122,14 @@ float aifft_compute_turret_dot(object *objp, object *enemy_objp, vec3d *abs_gunp
|
||||
|
||||
}
|
||||
|
||||
#define MAX_AIFFT_TURRETS 200
|
||||
// NOTE: Do not change this value unless you understand exactly what it means and what it does.
|
||||
// It refers to how many (non-destroyed) subsystems (and turrets) will be scanned for possible
|
||||
// targetting, per turret, per frame. A higher value will process more systems at once,
|
||||
// but it will be much slower to scan though them. It is not necessary to scan all
|
||||
// non-destroyed subsystem each frame for each turret. Also, "aifft_max_checks" is balanced
|
||||
// against the original value, be sure to account for this discrepancy with any changes.
|
||||
#define MAX_AIFFT_TURRETS 60
|
||||
|
||||
ship_subsys *aifft_list[MAX_AIFFT_TURRETS];
|
||||
float aifft_rank[MAX_AIFFT_TURRETS];
|
||||
int aifft_list_size = 0;
|
||||
@@ -1144,11 +1247,11 @@ int turret_should_pick_new_target(ship_subsys *turret)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if ( turret->turret_enemy_objnum == -1 ) {
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
|
||||
target_type = Objects[turret->turret_enemy_objnum].type;
|
||||
if ( (target_type != OBJ_SHIP) && (target_type != OBJ_ASTEROID) ) {
|
||||
return 1;
|
||||
@@ -1239,7 +1342,7 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
|
||||
}
|
||||
|
||||
// Fire a weapon from a turret
|
||||
void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL)
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
{
|
||||
matrix turret_orient;
|
||||
int weapon_objnum;
|
||||
@@ -1250,20 +1353,16 @@ void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
weapon *wp;
|
||||
object *objp;
|
||||
|
||||
//WMC - Limit firing to firestamp
|
||||
if(!timestamp_elapsed(get_turret_weapon_next_fire_stamp(&turret->weapons, weapon_num)))
|
||||
return false;
|
||||
|
||||
parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
|
||||
parent_ship = &Ships[Objects[parent_objnum].instance];
|
||||
wip = get_turret_weapon_wip(&turret->weapons, weapon_num);
|
||||
int turret_weapon_class = WEAPON_INFO_INDEX(wip);
|
||||
|
||||
if (check_ok_to_fire(parent_objnum, turret->turret_enemy_objnum, wip)) {
|
||||
//WMC - do animation
|
||||
if(!turret->turret_animation_position)
|
||||
{
|
||||
ship_start_animation_type(parent_ship, TRIGGER_TYPE_TURRET_FIRING, turret->system_info->subobj_num, 1);
|
||||
turret->turret_animation_position = true;
|
||||
turret->turret_animation_done_time = ship_get_animation_time_type(parent_ship, TRIGGER_TYPE_TURRET_FIRING, turret->system_info->subobj_num);
|
||||
}
|
||||
|
||||
vm_vector_2_matrix(&turret_orient, turret_fvec, NULL, NULL);
|
||||
turret->turret_last_fire_direction = *turret_fvec;
|
||||
|
||||
@@ -1271,11 +1370,12 @@ void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
turret_set_next_fire_timestamp(weapon_num, wip, turret, parent_aip);
|
||||
|
||||
// if this weapon is a beam weapon, handle it specially
|
||||
if(wip->wi_flags & WIF_BEAM){
|
||||
if (wip->wi_flags & WIF_BEAM) {
|
||||
// if this beam isn't free to fire
|
||||
if (!(turret->weapons.flags & SW_FLAG_BEAM_FREE)) {
|
||||
Int3(); // should never get this far
|
||||
return;
|
||||
//WMC - remove this
|
||||
//Int3(); // should never get this far
|
||||
return false;
|
||||
}
|
||||
beam_fire_info fire_info;
|
||||
|
||||
@@ -1293,20 +1393,21 @@ void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
// fire a beam weapon
|
||||
beam_fire(&fire_info);
|
||||
|
||||
if (parent_ship->cloak_stage == 2)
|
||||
{
|
||||
if (parent_ship->cloak_stage == 2) {
|
||||
beam_weapon_info *bip=&wip->b_info;
|
||||
shipfx_start_cloak(parent_ship,bip->beam_warmup + bip->beam_warmdown + (int)(bip->beam_life*1000.0f) + 1000);
|
||||
}
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
// don't fire swam, but set up swarm info instead
|
||||
else if (wip->wi_flags & WIF_SWARM) {
|
||||
turret_swarm_set_up_info(parent_objnum, turret, wip);
|
||||
|
||||
// don't fire swarm, but set up swarm info
|
||||
if (wip->wi_flags & WIF_SWARM) {
|
||||
turret_swarm_set_up_info(parent_objnum, turret, wip);
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// now do anything else
|
||||
else {
|
||||
for (int i=0; i < wip->shots; i++)
|
||||
{
|
||||
weapon_objnum = weapon_create( turret_pos, &turret_orient, turret_weapon_class, parent_objnum, -1, 1);
|
||||
@@ -1327,11 +1428,20 @@ void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
// show a muzzle flash
|
||||
flak_muzzle_flash(turret_pos, turret_fvec, &Objects[parent_ship->objnum].phys_info, turret_weapon_class);
|
||||
|
||||
// pick a firing range so that it detonates properly
|
||||
flak_pick_range(objp, turret_pos, predicted_pos, ship_get_subsystem_strength(parent_ship, SUBSYSTEM_WEAPONS));
|
||||
if(predicted_pos != NULL)
|
||||
{
|
||||
// pick a firing range so that it detonates properly
|
||||
flak_pick_range(objp, turret_pos, predicted_pos, ship_get_subsystem_strength(parent_ship, SUBSYSTEM_WEAPONS));
|
||||
|
||||
// determine what that range was
|
||||
flak_range = flak_get_range(objp);
|
||||
// determine what that range was
|
||||
flak_range = flak_get_range(objp);
|
||||
}
|
||||
else
|
||||
{
|
||||
flak_set_range(objp, flak_range_override);
|
||||
}
|
||||
} else if(wip->muzzle_flash > -1) {
|
||||
mflash_create(turret_pos, turret_fvec, &Objects[parent_ship->objnum].phys_info, Weapon_info[turret_weapon_class].muzzle_flash);
|
||||
}
|
||||
|
||||
// in multiplayer (and the master), then send a turret fired packet.
|
||||
@@ -1360,6 +1470,11 @@ void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
shipfx_start_cloak(parent_ship,500);
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
turret->turret_animation_done_time = timestamp(100);
|
||||
}
|
||||
}
|
||||
//Not useful -WMC
|
||||
@@ -1368,6 +1483,8 @@ void turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
float wait = 1000.0f * frand_range(0.9f, 1.1f);
|
||||
turret->turret_next_fire_stamp = timestamp((int) wait);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//void turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
|
||||
@@ -1392,10 +1509,11 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
|
||||
// *If it's a non-homer, then use the last fire direction instead of turret orientation to fix inaccuracy
|
||||
// problems with non-homing swarm weapons -Et1
|
||||
if( (The_mission.ai_profile->flags & AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY) && !( Weapon_info[tsi->weapon_class].wi_flags & WIF_HOMING ) )
|
||||
{
|
||||
turret_fvec = tsi->turret->turret_last_fire_direction;
|
||||
}
|
||||
if ( (Weapon_info[tsi->weapon_class].subtype == WP_LASER) || ((The_mission.ai_profile->flags & AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY)
|
||||
&& !(Weapon_info[tsi->weapon_class].wi_flags & WIF_HOMING)) )
|
||||
{
|
||||
turret_fvec = tsi->turret->turret_last_fire_direction;
|
||||
}
|
||||
|
||||
// make turret_orient from turret_fvec -- turret->turret_last_fire_direction
|
||||
vm_vector_2_matrix(&turret_orient, &turret_fvec, NULL, NULL);
|
||||
@@ -1416,7 +1534,8 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
snd_play_3d( &Snds[Weapon_info[tsi->weapon_class].launch_snd], &turret_pos, &View_position );
|
||||
}
|
||||
}
|
||||
|
||||
if(Weapon_info[tsi->weapon_class].muzzle_flash > -1)
|
||||
mflash_create(&turret_pos, &turret_fvec, &Objects[tsi->parent_objnum].phys_info, Weapon_info[tsi->weapon_class].muzzle_flash);
|
||||
// in multiplayer (and the master), then send a turret fired packet.
|
||||
if ( MULTIPLAYER_MASTER && (weapon_objnum != -1) ) {
|
||||
int subsys_index;
|
||||
@@ -1444,28 +1563,15 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
object *lep; // Last enemy pointer
|
||||
model_subsystem *tp = ss->system_info;
|
||||
ship_weapon *swp = &ss->weapons;
|
||||
vec3d predicted_enemy_pos;
|
||||
vec3d predicted_enemy_pos = vmd_zero_vector;
|
||||
object *objp;
|
||||
//ai_info *aip;
|
||||
|
||||
if(ss->turret_animation_position) {
|
||||
if(ss->turret_animation_done_time <= timestamp())
|
||||
{
|
||||
ship_start_animation_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num, -1);
|
||||
ss->turret_animation_position = false;
|
||||
ss->turret_animation_done_time = ship_get_animation_time_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num);
|
||||
}
|
||||
}
|
||||
|
||||
if(ss->turret_animation_done_time > timestamp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Ai_firing_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ss->current_hits < 0.0f) {
|
||||
if (ss->current_hits <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1478,14 +1584,52 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
return;
|
||||
}
|
||||
|
||||
// check if there is any available weapon to fire
|
||||
int weap_check;
|
||||
bool valid_weap = false;
|
||||
for (weap_check = 0; (weap_check < swp->num_primary_banks) && !valid_weap; weap_check++) {
|
||||
if (swp->primary_bank_weapons[weap_check] >= 0)
|
||||
valid_weap = true;
|
||||
}
|
||||
|
||||
if (!valid_weap) {
|
||||
for (weap_check = 0; (weap_check < ss->weapons.num_secondary_banks) && !valid_weap; weap_check++) {
|
||||
if (ss->weapons.secondary_bank_weapons[weap_check] >= 0)
|
||||
valid_weap = true;
|
||||
}
|
||||
|
||||
if (!valid_weap)
|
||||
return;
|
||||
}
|
||||
|
||||
// If beam weapon, check beam free
|
||||
if ( all_turret_weapons_have_flags(swp, WIF_BEAM) && !(swp->flags & SW_FLAG_BEAM_FREE) ) {
|
||||
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;
|
||||
// setup a reversal (closing) timestamp at 1 second
|
||||
// (NOTE: this will probably get changed by other parts of the code (swarming, beams, etc) to be
|
||||
// a more accurate time, but we need to give it a long enough time for the other parts of the code
|
||||
// to change the timestamp before it gets acted upon - taylor)
|
||||
ss->turret_animation_done_time = timestamp(1000);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Assert((parent_objnum >= 0) && (parent_objnum < MAX_OBJECTS));
|
||||
objp = &Objects[parent_objnum];
|
||||
lep = &Objects[ss->turret_enemy_objnum];
|
||||
Assert(objp->type == OBJ_SHIP);
|
||||
Assert( shipp->objnum == parent_objnum );
|
||||
|
||||
@@ -1497,6 +1641,11 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
ss->turret_enemy_objnum = -1;
|
||||
lep = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
lep = &Objects[ss->turret_enemy_objnum];
|
||||
}
|
||||
|
||||
|
||||
//aip = &Ai_info[Ships[objp->instance].ai_index];
|
||||
|
||||
@@ -1505,17 +1654,15 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
ship_get_global_turret_info(&Objects[parent_objnum], tp, &gpos, &gvec);
|
||||
|
||||
// Rotate the turret even if time hasn't elapsed, since it needs to turn to face its target.
|
||||
aifft_rotate_turret(shipp, parent_objnum, ss, objp, lep, &predicted_enemy_pos, &gvec);
|
||||
int use_angles = aifft_rotate_turret(shipp, parent_objnum, ss, objp, lep, &predicted_enemy_pos, &gvec);
|
||||
|
||||
if ( !timestamp_elapsed(ss->turret_next_fire_stamp)){
|
||||
// static int i=1;
|
||||
// mprintf(("turret timestamp hasn't elapsed: %d!\n", i));
|
||||
if ( !timestamp_elapsed(ss->turret_next_fire_stamp) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't try to fire beyond weapon_limit_range
|
||||
//WMC - OTC
|
||||
//weapon_firing_range = min(Weapon_info[tp->turret_weapon_type].lifetime * Weapon_info[tp->turret_weapon_type].max_speed, Weapon_info[tp->turret_weapon_type].weapon_range);
|
||||
//weapon_firing_range = MIN(Weapon_info[tp->turret_weapon_type].lifetime * Weapon_info[tp->turret_weapon_type].max_speed, Weapon_info[tp->turret_weapon_type].weapon_range);
|
||||
|
||||
//WMC - build a list of valid weapons. Fire spawns if there are any.
|
||||
float dist_to_enemy = 0.0f;
|
||||
@@ -1531,6 +1678,10 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
int secnum = 0;
|
||||
for(i = 0; i < (MAX_SHIP_WEAPONS); i++)
|
||||
{
|
||||
//WMC - Only fire more than once if we have multiple guns flag set.
|
||||
if(num_valid > 0 && !(ss->flags & MSS_FLAG_USE_MULTIPLE_GUNS))
|
||||
break;
|
||||
|
||||
if(i < MAX_SHIP_PRIMARY_BANKS)
|
||||
{
|
||||
if(i >= swp->num_primary_banks)
|
||||
@@ -1716,31 +1867,30 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
return;
|
||||
}
|
||||
|
||||
//This can't happen. See above code
|
||||
//Assert(ss->turret_enemy_objnum != -1);
|
||||
|
||||
float dot = vm_vec_dot(&v2e, &gvec);
|
||||
|
||||
// Ok, the turret is lined up... now line up a particular gun.
|
||||
bool ok_to_fire = false;
|
||||
bool something_was_ok_to_fire=false;
|
||||
vec3d tv2e; //so flak can get their jitter without screwing up other guns
|
||||
|
||||
if (dot > tp->turret_fov ) {
|
||||
// We're ready to fire... now get down to specifics, like where is the
|
||||
// actual gun point and normal, not just the one for whole turret.
|
||||
//WMC - use_angles was always 0
|
||||
ship_get_global_turret_gun_info(&Objects[parent_objnum], ss, &gpos, &gvec, 0, &predicted_enemy_pos);
|
||||
ss->turret_next_fire_pos++;
|
||||
|
||||
// Fire in the direction the turret is facing, not right at the target regardless of turret dir.
|
||||
vm_vec_sub(&v2e, &predicted_enemy_pos, &gpos);
|
||||
dist_to_enemy = vm_vec_normalize(&v2e);
|
||||
dot = vm_vec_dot(&v2e, &gvec);
|
||||
|
||||
for(i = 0; i < num_valid; i++)
|
||||
{
|
||||
wip = get_turret_weapon_wip(&ss->weapons, valid_weapons[i]);
|
||||
//This can't happen. See above code
|
||||
//Assert(ss->turret_enemy_objnum != -1);
|
||||
|
||||
float dot = vm_vec_dot(&v2e, &gvec);
|
||||
|
||||
// Ok, the turret is lined up... now line up a particular gun.
|
||||
bool ok_to_fire = false;
|
||||
bool something_was_ok_to_fire=false;
|
||||
vec3d tv2e; //so flak can get their jitter without screwing up other guns
|
||||
|
||||
if (dot > tp->turret_fov ) {
|
||||
// We're ready to fire... now get down to specifics, like where is the
|
||||
// actual gun point and normal, not just the one for whole turret.
|
||||
ship_get_global_turret_gun_info(&Objects[parent_objnum], ss, &gpos, &gvec, use_angles, &predicted_enemy_pos);
|
||||
ss->turret_next_fire_pos++;
|
||||
|
||||
// Fire in the direction the turret is facing, not right at the target regardless of turret dir.
|
||||
vm_vec_sub(&v2e, &predicted_enemy_pos, &gpos);
|
||||
dist_to_enemy = vm_vec_normalize(&v2e);
|
||||
dot = vm_vec_dot(&v2e, &gvec);
|
||||
|
||||
for(i = 0; i < num_valid; i++)
|
||||
{
|
||||
wip = get_turret_weapon_wip(&ss->weapons, valid_weapons[i]);
|
||||
tv2e = v2e;
|
||||
|
||||
// make sure to reset this for current weapon
|
||||
|
||||
+14
-5
@@ -9,13 +9,22 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Anim/AnimPlay.cpp $
|
||||
* $Revision: 2.19 $
|
||||
* $Date: 2006-03-21 00:27:27 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.22 $
|
||||
* $Date: 2006-12-28 00:59:19 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* C module for playing back anim files
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.21 2006/09/11 06:45:39 taylor
|
||||
* various small compiler warning and strict compiling fixes
|
||||
*
|
||||
* Revision 2.20 2006/06/27 05:07:48 taylor
|
||||
* fix various compiler warnings and things that Valgrind complained about
|
||||
*
|
||||
* Revision 2.19 2006/03/21 00:27:27 taylor
|
||||
* some minor cleanup
|
||||
*
|
||||
* Revision 2.18 2005/11/13 06:39:38 taylor
|
||||
* remove Cmdline_cache_ani support, it only worked if not in a VP and only on streaming ani so it was pretty much useless
|
||||
*
|
||||
@@ -374,7 +383,7 @@ void anim_render_one(int screen_id, anim_instance *ani, float frametime)
|
||||
}
|
||||
}
|
||||
|
||||
MONITOR(NumANIPlayed);
|
||||
MONITOR(NumANIPlayed)
|
||||
|
||||
// Setup an anim_play_struct for passing into anim_play(). Will fill in default values, which you
|
||||
// can then change before calling anim_play().
|
||||
@@ -462,6 +471,7 @@ anim_instance *anim_play(anim_play_struct *aps)
|
||||
}
|
||||
instance->frame = (ubyte *) vm_malloc(instance->parent->width * instance->parent->height * 2);
|
||||
Assert( instance->frame != NULL );
|
||||
memset( instance->frame, 0, instance->parent->width * instance->parent->height * 2 );
|
||||
instance->time_elapsed = 0.0f;
|
||||
instance->stop_at = aps->stop_at;
|
||||
instance->x = aps->x;
|
||||
@@ -939,7 +949,6 @@ void anim_read_header(anim *ptr, CFILE *fp)
|
||||
}
|
||||
|
||||
ptr->height = cfread_short(fp);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// get size of ani compared to power of 2
|
||||
int r, floor_pow;
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Anim/AnimPlay.h $
|
||||
* $Revision: 2.6 $
|
||||
* $Date: 2005-07-13 02:50:48 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.7 $
|
||||
* $Date: 2006-09-08 06:20:14 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Header file for playing back anim files
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.6 2005/07/13 02:50:48 Goober5000
|
||||
* remove PreProcDefine #includes in FS2
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.5 2005/04/05 05:53:14 taylor
|
||||
* s/vector/vec3d/g, better support for different compilers (Jens Granseuer)
|
||||
*
|
||||
@@ -149,7 +153,7 @@ enum
|
||||
{
|
||||
PAGE_FROM_MEM = 0,
|
||||
PAGE_FROM_DISK = 1,
|
||||
PAGE_FROM_DISK_FORCED = 2,
|
||||
PAGE_FROM_DISK_FORCED = 2
|
||||
};
|
||||
|
||||
extern int Anim_paused;
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Anim/PackUnpack.cpp $
|
||||
* $Revision: 2.13 $
|
||||
* $Date: 2006-03-21 00:27:27 $
|
||||
* $Revision: 2.14 $
|
||||
* $Date: 2006-06-27 05:07:48 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Code for handling packing and unpacking in Hoffoss's RLE format, used for
|
||||
@@ -18,6 +18,9 @@
|
||||
* utilizing an Anim), and getting getting frames of the Anim.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.13 2006/03/21 00:27:27 taylor
|
||||
* some minor cleanup
|
||||
*
|
||||
* Revision 2.12 2006/01/22 19:57:35 wmcoolmon
|
||||
* 0...1...2...4?
|
||||
*
|
||||
@@ -266,7 +269,9 @@ anim_instance *init_anim_instance(anim *ptr, int bpp)
|
||||
inst->stop_now = FALSE;
|
||||
inst->aa_color = NULL;
|
||||
|
||||
inst->frame = (ubyte *) vm_malloc(inst->parent->width * inst->parent->height * (bpp/8));
|
||||
inst->frame = (ubyte *) vm_malloc(inst->parent->width * inst->parent->height * (bpp >> 3));
|
||||
Assert( inst->frame != NULL );
|
||||
memset( inst->frame, 0, inst->parent->width * inst->parent->height * (bpp >> 3) );
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
+147
-94
@@ -9,13 +9,57 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Asteroid/Asteroid.cpp $
|
||||
* $Revision: 2.35 $
|
||||
* $Date: 2006-05-13 07:02:27 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.47 $
|
||||
* $Date: 2007-11-23 23:49:32 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* C module for asteroid code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.46 2007/09/02 02:10:24 Goober5000
|
||||
* added fixes for #1415 and #1483, made sure every read_file_text had a corresponding setjmp, and sync'd the parse error messages between HEAD and stable
|
||||
*
|
||||
* Revision 2.45 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 2.44 2007/02/11 09:37:18 taylor
|
||||
* dd VALID_FNAME() macro and put it around a few places (more to come)
|
||||
* clean out some old variables
|
||||
* move CLAMP() macro from opengl header to global header
|
||||
* update COUNT_ESTIMATE to match new bmpman changes
|
||||
*
|
||||
* Revision 2.43 2007/01/15 08:05:47 wmcoolmon
|
||||
* Maintain "fileless fs2" capability; change ScriptingVariables library to HookVariables(hv)
|
||||
*
|
||||
* Revision 2.42 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.41 2006/11/16 00:53:12 taylor
|
||||
* various bits of little cleanup
|
||||
* get rid of some more compiler warnings
|
||||
*
|
||||
* Revision 2.40 2006/09/11 06:49:38 taylor
|
||||
* fixes for stuff_string() bounds checking
|
||||
*
|
||||
* Revision 2.39 2006/09/11 06:08:08 taylor
|
||||
* make Species_info[] and Asteroid_info[] dynamic
|
||||
*
|
||||
* Revision 2.38 2006/08/20 00:51:05 taylor
|
||||
* maybe optimize the (PI/2), (PI*2) and (RAND_MAX/2) stuff a little bit
|
||||
*
|
||||
* Revision 2.37 2006/07/06 04:06:03 Goober5000
|
||||
* 1) complete (almost) changeover to reorganized texture mapping system
|
||||
* 2) finally fix texture animation; textures now animate at the correct speed
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.36 2006/07/04 07:42:48 Goober5000
|
||||
* --in preparation for fixing an annoying animated texture bug, reorganize the various texture structs and glow point structs and clarify several parts of the texture code :P
|
||||
* --this breaks animated glow maps, and animated regular maps still aren't fixed, but these will be remedied shortly
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.35 2006/05/13 07:02:27 taylor
|
||||
* add lazy (ie, faster) checking of asteroid collisions for time-to-impact
|
||||
*
|
||||
* Revision 2.34 2006/01/26 03:23:29 Goober5000
|
||||
* pare down the pragmas some more
|
||||
* --Goober5000
|
||||
@@ -414,6 +458,9 @@
|
||||
#include "network/multiutil.h"
|
||||
#include "network/multimsgs.h"
|
||||
#include "network/multi.h"
|
||||
#include "parse/scripting.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
//WMC - we want asteroid ability with demo!!
|
||||
@@ -434,11 +481,10 @@ int Num_asteroids = 0;
|
||||
int Asteroid_throw_objnum = -1; // Object index of ship to throw asteroids at.
|
||||
int Next_asteroid_throw;
|
||||
|
||||
asteroid_info Asteroid_info[MAX_DEBRIS_TYPES];
|
||||
std::vector<asteroid_info> Asteroid_info;
|
||||
asteroid Asteroids[MAX_ASTEROIDS];
|
||||
asteroid_field Asteroid_field;
|
||||
|
||||
static int Num_debris_types;
|
||||
|
||||
static int Asteroid_impact_explosion_ani;
|
||||
static float Asteroid_impact_explosion_radius;
|
||||
@@ -513,7 +559,7 @@ float asteroid_cap_speed(int asteroid_info_index, float speed)
|
||||
{
|
||||
float max, double_max;
|
||||
|
||||
Assert( asteroid_info_index < Num_debris_types );
|
||||
Assert( asteroid_info_index < (int)Asteroid_info.size() );
|
||||
|
||||
max = Asteroid_info[asteroid_info_index].max_speed;
|
||||
double_max = max * 2;
|
||||
@@ -618,7 +664,7 @@ object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((asteroid_type < 0) || (asteroid_type >= ((Num_species + 1) * NUM_DEBRIS_SIZES))) {
|
||||
if((asteroid_type < 0) || (asteroid_type >= (((int)Species_info.size() + 1) * NUM_DEBRIS_SIZES))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -664,9 +710,9 @@ object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroi
|
||||
|
||||
inner_bound_pos_fixup(asfieldp, &pos);
|
||||
// vm_set_identity(&orient);
|
||||
angs.p = frand() * 2*PI;
|
||||
angs.b = frand() * 2*PI;
|
||||
angs.h = frand() * 2*PI;
|
||||
angs.p = frand() * PI2;
|
||||
angs.b = frand() * PI2;
|
||||
angs.h = frand() * PI2;
|
||||
} else {
|
||||
signature = multi_assign_network_signature( MULTI_SIG_ASTEROID );
|
||||
rand_base = signature;
|
||||
@@ -677,9 +723,9 @@ object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroi
|
||||
|
||||
inner_bound_pos_fixup(asfieldp, &pos);
|
||||
// vm_set_identity(&orient);
|
||||
angs.p = static_randf( rand_base++ ) * 2*PI;
|
||||
angs.b = static_randf( rand_base++ ) * 2*PI;
|
||||
angs.h = static_randf( rand_base++ ) * 2*PI;
|
||||
angs.p = static_randf( rand_base++ ) * PI2;
|
||||
angs.b = static_randf( rand_base++ ) * PI2;
|
||||
angs.h = static_randf( rand_base++ ) * PI2;
|
||||
}
|
||||
|
||||
vm_angles_2_matrix(&orient, &angs);
|
||||
@@ -809,10 +855,10 @@ void asteroid_load(int asteroid_info_index, int asteroid_subtype)
|
||||
asteroid_info *asip;
|
||||
// int pof_index;
|
||||
|
||||
Assert( asteroid_info_index < Num_debris_types );
|
||||
Assert( asteroid_info_index < (int)Asteroid_info.size() );
|
||||
Assert( asteroid_subtype < NUM_DEBRIS_POFS );
|
||||
|
||||
if ( (asteroid_info_index >= Num_debris_types) || (asteroid_subtype >= NUM_DEBRIS_POFS) ) {
|
||||
if ( (asteroid_info_index >= (int)Asteroid_info.size()) || (asteroid_subtype >= NUM_DEBRIS_POFS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -828,9 +874,8 @@ void asteroid_load(int asteroid_info_index, int asteroid_subtype)
|
||||
// pof_index = 0;
|
||||
// }
|
||||
|
||||
if ( !strlen(asip->pof_files[asteroid_subtype]) || !stricmp(asip->pof_files[asteroid_subtype], NOX("none")) ) {
|
||||
if ( !VALID_FNAME(asip->pof_files[asteroid_subtype]) )
|
||||
return;
|
||||
}
|
||||
|
||||
asip->model_num[asteroid_subtype] = model_load( asip->pof_files[asteroid_subtype], 0, NULL );
|
||||
|
||||
@@ -1335,7 +1380,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
int mc_ret_val = 0;
|
||||
|
||||
if ( asteroid_hit_info->heavy == ship_obj ) { // ship is heavier, so asteroid is sphere. Check sphere collision against ship poly model
|
||||
mc.model_num = Ships[ship_obj->instance].modelnum; // Fill in the model to check
|
||||
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 = pasteroid->radius;
|
||||
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
|
||||
@@ -1366,7 +1411,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
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(Ships[heavy_obj->instance].modelnum);
|
||||
pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num);
|
||||
|
||||
// turn off all rotating submodels and test for collision
|
||||
int i;
|
||||
@@ -1460,7 +1505,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
mc.model_num = Asteroid_info[Asteroids[num].asteroid_type].model_num[asteroid_subtype]; // Fill in the model to check
|
||||
model_clear_instance( mc.model_num );
|
||||
mc.orient = &pasteroid->orient; // The object's orient
|
||||
mc.radius = model_get_core_radius( Ships[ship_obj->instance].modelnum );
|
||||
mc.radius = model_get_core_radius(Ship_info[Ships[ship_obj->instance].ship_info_index].model_num);
|
||||
|
||||
// check for collision between asteroid model and ship sphere
|
||||
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
|
||||
@@ -1803,51 +1848,56 @@ void asteroid_maybe_break_up(object *asteroid_obj)
|
||||
if ( timestamp_elapsed(asp->final_death_time) ) {
|
||||
vec3d relvec, vfh, tvec;
|
||||
|
||||
asteroid_obj->flags |= OF_SHOULD_BE_DEAD;
|
||||
Script_system.SetHookObject("Self", asteroid_obj);
|
||||
if(!Script_system.IsConditionOverride(CHA_DEATH, asteroid_obj))
|
||||
{
|
||||
asteroid_obj->flags |= OF_SHOULD_BE_DEAD;
|
||||
|
||||
// multiplayer clients won't go through the following code. asteroid_sub_create will send
|
||||
// a create packet to the client in the above named function
|
||||
if ( !MULTIPLAYER_CLIENT ) {
|
||||
// if this isn't true it's just debris, and debris doesn't break up
|
||||
if (asp->asteroid_type <= ASTEROID_TYPE_LARGE)
|
||||
{
|
||||
switch (asp->asteroid_type) {
|
||||
case ASTEROID_TYPE_SMALL:
|
||||
break;
|
||||
case ASTEROID_TYPE_MEDIUM:
|
||||
asc_get_relvec(&relvec, asteroid_obj, &asp->death_hit_pos);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &relvec);
|
||||
|
||||
vm_vec_normalized_dir(&vfh, &asteroid_obj->pos, &asp->death_hit_pos);
|
||||
vm_vec_copy_scale(&tvec, &vfh, 2.0f);
|
||||
vm_vec_sub2(&tvec, &relvec);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &tvec);
|
||||
// multiplayer clients won't go through the following code. asteroid_sub_create will send
|
||||
// a create packet to the client in the above named function
|
||||
if ( !MULTIPLAYER_CLIENT ) {
|
||||
// if this isn't true it's just debris, and debris doesn't break up
|
||||
if (asp->asteroid_type <= ASTEROID_TYPE_LARGE)
|
||||
{
|
||||
switch (asp->asteroid_type) {
|
||||
case ASTEROID_TYPE_SMALL:
|
||||
break;
|
||||
case ASTEROID_TYPE_MEDIUM:
|
||||
asc_get_relvec(&relvec, asteroid_obj, &asp->death_hit_pos);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &relvec);
|
||||
|
||||
break;
|
||||
case ASTEROID_TYPE_LARGE:
|
||||
asc_get_relvec(&relvec, asteroid_obj, &asp->death_hit_pos);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_MEDIUM, &relvec);
|
||||
|
||||
vm_vec_normalized_dir(&vfh, &asteroid_obj->pos, &asp->death_hit_pos);
|
||||
vm_vec_copy_scale(&tvec, &vfh, 2.0f);
|
||||
vm_vec_sub2(&tvec, &relvec);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_MEDIUM, &tvec);
|
||||
vm_vec_normalized_dir(&vfh, &asteroid_obj->pos, &asp->death_hit_pos);
|
||||
vm_vec_copy_scale(&tvec, &vfh, 2.0f);
|
||||
vm_vec_sub2(&tvec, &relvec);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &tvec);
|
||||
|
||||
break;
|
||||
case ASTEROID_TYPE_LARGE:
|
||||
asc_get_relvec(&relvec, asteroid_obj, &asp->death_hit_pos);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_MEDIUM, &relvec);
|
||||
|
||||
vm_vec_normalized_dir(&vfh, &asteroid_obj->pos, &asp->death_hit_pos);
|
||||
vm_vec_copy_scale(&tvec, &vfh, 2.0f);
|
||||
vm_vec_sub2(&tvec, &relvec);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_MEDIUM, &tvec);
|
||||
|
||||
while (frand() > 0.6f) {
|
||||
vec3d rvec, tvec2;
|
||||
vm_vec_rand_vec_quick(&rvec);
|
||||
vm_vec_scale_add(&tvec2, &vfh, &rvec, 0.75f);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &tvec2);
|
||||
}
|
||||
break;
|
||||
while (frand() > 0.6f) {
|
||||
vec3d rvec, tvec2;
|
||||
vm_vec_rand_vec_quick(&rvec);
|
||||
vm_vec_scale_add(&tvec2, &vfh, &rvec, 0.75f);
|
||||
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &tvec2);
|
||||
}
|
||||
break;
|
||||
|
||||
default: // this isn't going to happen.. really
|
||||
break;
|
||||
default: // this isn't going to happen.. really
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
asp->final_death_time = timestamp(-1);
|
||||
}
|
||||
|
||||
asp->final_death_time = timestamp(-1);
|
||||
Script_system.RunCondition(CHA_DEATH, '\0', NULL, asteroid_obj);
|
||||
Script_system.RemHookVar("Self");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1890,7 +1940,7 @@ void asteroid_test_collide(object *asteroid_obj, object *ship_obj, mc_info *mc,
|
||||
|
||||
ship_model_start(ship_obj);
|
||||
|
||||
mc->model_num = Ships[ship_obj->instance].modelnum; // Fill in the model to check
|
||||
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 orientation
|
||||
mc->pos = &ship_obj->pos; // The object's position
|
||||
mc->p0 = &asteroid_obj->pos; // Point 1 of ray to check
|
||||
@@ -2055,17 +2105,17 @@ float asteroid_time_to_impact(object *asteroid_objp)
|
||||
void asteroid_parse_section(asteroid_info *asip)
|
||||
{
|
||||
required_string("$Name:");
|
||||
stuff_string(asip->name, F_NAME, NULL);
|
||||
stuff_string(asip->name, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string( "$POF file1:" );
|
||||
stuff_string(asip->pof_files[0], F_NAME, NULL);
|
||||
stuff_string(asip->pof_files[0], F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
required_string( "$POF file2:" );
|
||||
stuff_string(asip->pof_files[1], F_NAME, NULL);
|
||||
stuff_string(asip->pof_files[1], F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if ( (stristr(asip->name,"Asteroid") != NULL) ) {
|
||||
required_string( "$POF file3:" );
|
||||
stuff_string(asip->pof_files[2], F_NAME, NULL);
|
||||
stuff_string(asip->pof_files[2], F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
|
||||
asip->num_detail_levels = 0;
|
||||
@@ -2076,6 +2126,12 @@ void asteroid_parse_section(asteroid_info *asip)
|
||||
required_string("$Max Speed:");
|
||||
stuff_float(&asip->max_speed);
|
||||
|
||||
if(optional_string("$Damage Type:")) {
|
||||
char buf[NAME_LENGTH];
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
asip->damage_type_idx = damage_type_add(buf);
|
||||
}
|
||||
|
||||
required_string("$Expl inner rad:");
|
||||
stuff_float(&asip->inner_rad);
|
||||
|
||||
@@ -2092,54 +2148,48 @@ void asteroid_parse_section(asteroid_info *asip)
|
||||
stuff_float(&asip->initial_asteroid_strength);
|
||||
}
|
||||
|
||||
extern int Num_species;
|
||||
// read in data from asteroid.tbl into Asteroid_info[] array
|
||||
void asteroid_parse_tbl()
|
||||
{
|
||||
char impact_ani_file[FILESPEC_LENGTH];
|
||||
int asteroid_tally[MAX_SPECIES+1];
|
||||
asteroid_info *asip;
|
||||
int i;
|
||||
char impact_ani_file[MAX_FILENAME_LEN];
|
||||
int *asteroid_tally = NULL;
|
||||
int i, rval;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "asteroid.tbl", rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("asteroid.tbl");
|
||||
reset_parse();
|
||||
|
||||
required_string("#Asteroid Types");
|
||||
|
||||
Num_debris_types = 0;
|
||||
asteroid_tally = new int[Species_info.size() + 1];
|
||||
|
||||
memset(asteroid_tally, 0, sizeof(int) * (MAX_SPECIES+1));
|
||||
memset(Asteroid_info, 0, sizeof(asteroid_info) * MAX_DEBRIS_TYPES);
|
||||
memset(asteroid_tally, 0, sizeof(int) * (Species_info.size()+1));
|
||||
|
||||
|
||||
while (required_string_either("#End","$Name:"))
|
||||
{
|
||||
Assert( Num_debris_types < MAX_DEBRIS_TYPES );
|
||||
asteroid_info new_asteroid;
|
||||
|
||||
if (Num_debris_types >= MAX_DEBRIS_TYPES)
|
||||
continue;
|
||||
|
||||
|
||||
asip = &Asteroid_info[Num_debris_types];
|
||||
|
||||
memset(asip, 0, sizeof(asteroid_info));
|
||||
|
||||
for (i = 0; i < NUM_DEBRIS_POFS; i++) {
|
||||
asip->model_num[i] = -1;
|
||||
}
|
||||
|
||||
asteroid_parse_section( asip );
|
||||
for (i = 0; i < NUM_DEBRIS_POFS; i++)
|
||||
new_asteroid.model_num[i] = -1;
|
||||
|
||||
asteroid_parse_section( &new_asteroid );
|
||||
|
||||
Assert( Species_info.size() );
|
||||
// sanity check for debris type sizes
|
||||
for (i = Num_species; i >= 0; i--) {
|
||||
for (i = Species_info.size(); i >= 0; i--) {
|
||||
// must remain in proper order
|
||||
// 0 - generic debris types
|
||||
// > 0 - species specific debris types
|
||||
if ( (i == 0) || stristr(asip->name, Species_info[i-1].species_name) ) {
|
||||
if ( (i == 0) || stristr(new_asteroid.name, Species_info[i-1].species_name) ) {
|
||||
Assert( asteroid_tally[i] < NUM_DEBRIS_SIZES );
|
||||
|
||||
if ( asteroid_tally[i] >= NUM_DEBRIS_SIZES ) {
|
||||
@@ -2150,7 +2200,7 @@ void asteroid_parse_tbl()
|
||||
|
||||
// we're safe to continue
|
||||
asteroid_tally[i]++;
|
||||
Num_debris_types++;
|
||||
Asteroid_info.push_back( new_asteroid );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2160,9 +2210,9 @@ void asteroid_parse_tbl()
|
||||
|
||||
Asteroid_impact_explosion_ani = -1;
|
||||
required_string("$Impact Explosion:");
|
||||
stuff_string(impact_ani_file, F_NAME, NULL);
|
||||
if ( stricmp(impact_ani_file,NOX("none")))
|
||||
{
|
||||
stuff_string(impact_ani_file, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if ( VALID_FNAME(impact_ani_file) ) {
|
||||
int num_frames;
|
||||
Asteroid_impact_explosion_ani = bm_load_animation( impact_ani_file, &num_frames, NULL, 1);
|
||||
}
|
||||
@@ -2175,10 +2225,10 @@ void asteroid_parse_tbl()
|
||||
|
||||
|
||||
// check for any missing info
|
||||
char errormsg[70 + (MAX_SPECIES * (NAME_LENGTH+1))];
|
||||
char *errormsg = new char[75 + (Species_info.size() * (NAME_LENGTH))];
|
||||
bool species_missing = false;
|
||||
strcpy(errormsg, "The following species are missing debris types in asteroids.tbl:\n");
|
||||
for (i = 0; i < Num_species; i++)
|
||||
for (i = 0; i < (int)Species_info.size(); i++)
|
||||
{
|
||||
int idx = (i+1); // offset from generic asteroids at 0..NUM_DEBRIS_SIZES
|
||||
|
||||
@@ -2195,6 +2245,9 @@ void asteroid_parse_tbl()
|
||||
{
|
||||
Error(LOCATION, errormsg);
|
||||
}
|
||||
|
||||
delete[] asteroid_tally;
|
||||
delete[] errormsg;
|
||||
}
|
||||
|
||||
// Return number of asteroids expected to collide with a ship.
|
||||
@@ -2396,7 +2449,7 @@ void asteroid_page_in()
|
||||
|
||||
// Page in textures
|
||||
for (j=0; j<asip->modelp[k]->n_textures; j++ ) {
|
||||
int bitmap_num = asip->modelp[k]->original_textures[j];
|
||||
int bitmap_num = asip->modelp[k]->maps[j].base_map.original_texture;
|
||||
|
||||
if ( bitmap_num > -1 ) {
|
||||
bm_page_in_texture( bitmap_num );
|
||||
|
||||
@@ -9,13 +9,27 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Asteroid/Asteroid.h $
|
||||
* $Revision: 2.12 $
|
||||
* $Date: 2005-09-25 20:31:42 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.16 $
|
||||
* $Date: 2007-11-23 23:49:32 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Header file for asteroids
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.15 2006/11/16 00:53:12 taylor
|
||||
* various bits of little cleanup
|
||||
* get rid of some more compiler warnings
|
||||
*
|
||||
* Revision 2.14 2006/09/11 06:49:38 taylor
|
||||
* fixes for stuff_string() bounds checking
|
||||
*
|
||||
* Revision 2.13 2006/09/11 06:08:08 taylor
|
||||
* make Species_info[] and Asteroid_info[] dynamic
|
||||
*
|
||||
* Revision 2.12 2005/09/25 20:31:42 Goober5000
|
||||
* okay; everything should be good to go
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.11 2005/09/25 08:25:14 Goober5000
|
||||
* Okay, everything should now work again. :p Still have to do a little more with the asteroids.
|
||||
* --Goober5000
|
||||
@@ -164,6 +178,8 @@
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h" // for NAME_LENGTH
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct object;
|
||||
struct polymodel;
|
||||
struct collision_info_struct;
|
||||
@@ -179,7 +195,8 @@ struct collision_info_struct;
|
||||
|
||||
// This is for the asteroid types plus DEBRIS_X_Y
|
||||
// (X is each species and Y is SMALL, MEDIUM, and LARGE)
|
||||
#define MAX_DEBRIS_TYPES ((MAX_SPECIES + 1) * NUM_DEBRIS_SIZES)
|
||||
// 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
|
||||
@@ -198,10 +215,11 @@ extern asteroid_obj Asteroid_obj_list;
|
||||
|
||||
typedef struct asteroid_info {
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
char pof_files[NUM_DEBRIS_POFS][NAME_LENGTH]; // POF files to load/associate with ship
|
||||
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
|
||||
@@ -209,6 +227,8 @@ typedef struct asteroid_info {
|
||||
float initial_asteroid_strength; // starting strength of asteroid
|
||||
polymodel *modelp[NUM_DEBRIS_POFS];
|
||||
int model_num[NUM_DEBRIS_POFS];
|
||||
|
||||
asteroid_info() { memset(this, 0, sizeof(asteroid_info)); damage_type_idx = -1; };
|
||||
} asteroid_info;
|
||||
|
||||
|
||||
@@ -255,7 +275,7 @@ typedef struct asteroid_field {
|
||||
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]; // one of the debris type defines above
|
||||
} asteroid_field;
|
||||
|
||||
extern asteroid_info Asteroid_info[MAX_DEBRIS_TYPES];
|
||||
extern std::vector<asteroid_info> Asteroid_info;
|
||||
extern asteroid Asteroids[MAX_ASTEROIDS];
|
||||
extern asteroid_field Asteroid_field;
|
||||
|
||||
|
||||
+602
-79
@@ -4,11 +4,62 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Autopilot/Autopilot.cpp $
|
||||
* $Revision: 1.23 $
|
||||
* $Date: 2006-02-25 21:42:31 $
|
||||
* $Revision: 1.40 $
|
||||
* $Date: 2007-09-02 02:10:24 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.39 2007/08/04 22:30:01 Goober5000
|
||||
* fix case-sensitive #include (Linux)
|
||||
*
|
||||
* Revision 1.38 2007/08/03 01:35:48 Goober5000
|
||||
* fix warning
|
||||
*
|
||||
* Revision 1.37 2007/07/25 20:44:49 Kazan
|
||||
* I <3 making stupid bugs (return camera to normal when not using cutscene bars)
|
||||
*
|
||||
* Revision 1.36 2007/07/25 14:50:44 Kazan
|
||||
* two-part autopilot warp, add +No_Cutscene_Bars optional flag to autopilot.tbl
|
||||
*
|
||||
* Revision 1.35 2007/07/24 20:30:36 Kazan
|
||||
* oops
|
||||
*
|
||||
* Revision 1.34 2007/07/24 20:17:36 Kazan
|
||||
* Make asteroid/debris fields interrupt autopilot, add "hazards near" message to autopilot.tbl, add use-nav-cinematics sexp, fix mantis #1441
|
||||
*
|
||||
* Revision 1.33 2007/07/24 13:04:10 Kazan
|
||||
* Resolve Mantis 1281
|
||||
*
|
||||
* Revision 1.32 2007/07/23 15:35:40 Kazan
|
||||
* typo correction in autopilot.tbl
|
||||
*
|
||||
* Revision 1.31 2007/07/23 15:16:47 Kazan
|
||||
* Autopilot upgrades as described, MSVC2005 project fixes
|
||||
*
|
||||
* Revision 1.30 2007/03/22 22:14:55 taylor
|
||||
* get rid of non-standard itoa(), make use of the proper sprintf() instead
|
||||
*
|
||||
* Revision 1.29 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.28 2006/11/03 18:45:11 Kazan
|
||||
* prevent autopilot initialization while player is gliding
|
||||
*
|
||||
* Revision 1.27 2006/09/04 09:21:55 Backslash
|
||||
* Turn off gliding upon activating autopilot
|
||||
*
|
||||
* Revision 1.26 2006/09/04 06:06:38 wmcoolmon
|
||||
* Cover-up a bloody annoying warning
|
||||
*
|
||||
* Revision 1.25 2006/07/27 19:17:59 Kazan
|
||||
* Lock player primaries during autopilot
|
||||
*
|
||||
* Revision 1.24 2006/07/26 03:46:04 Kazan
|
||||
* Resolve Mantis #1011
|
||||
*
|
||||
* Revision 1.23 2006/02/25 21:42:31 Goober5000
|
||||
* fixes from last commit
|
||||
*
|
||||
* Revision 1.22 2005/08/23 09:18:08 Goober5000
|
||||
* ensure init/reset of goals works cleanly
|
||||
* --Goober5000
|
||||
@@ -95,22 +146,44 @@
|
||||
#include "ai/aigoals.h"
|
||||
#include "ship/ship.h"
|
||||
#include "object/object.h"
|
||||
#include "object/objcollide.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "freespace2/freespace.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "iff_defs/iff_defs.h"
|
||||
|
||||
|
||||
#include "object/waypoint/waypoint.h"
|
||||
#include "sound/audiostr.h"
|
||||
#include "mission/missiontraining.h"
|
||||
#include "mission/missionmessage.h"
|
||||
#include "io/timer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "globalincs/def_files.h"
|
||||
#include "localization/localize.h"
|
||||
#include "camera/camera.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
|
||||
// Extern functions/variables
|
||||
extern int Player_use_ai;
|
||||
|
||||
extern int get_wing_index(object *objp, int wingnum);
|
||||
extern object * get_wing_leader(int wingnum);
|
||||
|
||||
// Module variables
|
||||
bool AutoPilotEngaged;
|
||||
bool UseCutsceneBars;
|
||||
int CurrentNav;
|
||||
float ramp_bias;
|
||||
NavPoint Navs[MAX_NAVPOINTS];
|
||||
NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
int audio_handle;
|
||||
int NavLinkDistance;
|
||||
|
||||
// time offsets for autonav events
|
||||
int LockAPConv;
|
||||
int EndAPCinematic;
|
||||
bool CinematicStarted;
|
||||
vec3d cameraPos;
|
||||
|
||||
// used for ramping time compression;
|
||||
int start_dist;
|
||||
@@ -183,7 +256,7 @@ vec3d *NavPoint::GetPosition()
|
||||
char* NavPoint::GetInteralName()
|
||||
{
|
||||
char *NavName;
|
||||
char strtmp[3];
|
||||
char strtmp[33];
|
||||
|
||||
if (flags & NP_WAYPOINT)
|
||||
{
|
||||
@@ -192,7 +265,8 @@ char* NavPoint::GetInteralName()
|
||||
strcpy(NavName, ((waypoint_list*)target_obj)->name);
|
||||
|
||||
strcat(NavName, ":");
|
||||
strcat(NavName, itoa(waypoint_num, strtmp, 10));
|
||||
sprintf(strtmp, "%d", waypoint_num);
|
||||
strcat(NavName, strtmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -205,19 +279,33 @@ char* NavPoint::GetInteralName()
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Tell us is autopilot is allow
|
||||
// Tell us if autopilot is allowed
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within X distance
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilot()
|
||||
bool CanAutopilot(bool send_msg)
|
||||
{
|
||||
if (CurrentNav == -1)
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
|
||||
return false;
|
||||
|
||||
// dunno what this is for, but Kazan used it
|
||||
}
|
||||
|
||||
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(&Player_obj->pos, Navs[CurrentNav].GetPosition()) < 1000)
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
|
||||
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))
|
||||
@@ -227,7 +315,67 @@ bool CanAutopilot()
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj)))
|
||||
{
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 1000)
|
||||
// Cannot autopilot if enemy within 5,000 meters
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 5000)
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
|
||||
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(&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)))
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -241,6 +389,8 @@ bool CanAutopilot()
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Lock time compression -WMC
|
||||
// * Turn off gliding -Backslash
|
||||
// * Lock primary/secondary weapons
|
||||
// * 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
|
||||
void StartAutopilot()
|
||||
@@ -250,13 +400,30 @@ void StartAutopilot()
|
||||
|
||||
AutoPilotEngaged = true;
|
||||
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
LockAPConv = timestamp(); // lock convergence instantly
|
||||
else
|
||||
LockAPConv = timestamp(3000); // 3 seconds before we lock convergence
|
||||
Player_use_ai = 1;
|
||||
set_time_compression(1);
|
||||
lock_time_compression(true);
|
||||
|
||||
// determine speed cap
|
||||
int i,j;
|
||||
int i,j, wcount=1;
|
||||
float speed_cap = 1000000.0; // 1m is a safe starting point
|
||||
float radius = Player_obj->radius;
|
||||
|
||||
// vars for usage w/ cinematic
|
||||
vec3d pos, norm1, perp, tpos, rpos = Player_obj->pos, zero;
|
||||
memset(&zero, 0, sizeof(vec3d));
|
||||
|
||||
|
||||
// instantly turn player toward tpos
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
|
||||
vm_vector_2_matrix(&Player_obj->orient, &norm1, NULL, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
@@ -266,20 +433,20 @@ void StartAutopilot()
|
||||
)
|
||||
)
|
||||
{
|
||||
if (speed_cap > Ship_info[Ships[i].ship_info_index].max_vel.xyz.z)
|
||||
speed_cap = Ship_info[Ships[i].ship_info_index].max_vel.xyz.z;
|
||||
if (speed_cap > vm_vec_mag(&Ship_info[Ships[i].ship_info_index].max_vel))
|
||||
speed_cap = vm_vec_mag(&Ship_info[Ships[i].ship_info_index].max_vel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
|
||||
speed_cap = 0.90f * speed_cap;
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
speed_cap = 0.90f * speed_cap;
|
||||
ramp_bias = speed_cap/50.0f;
|
||||
|
||||
// assign ship goals
|
||||
// when assigning goals to individual ships only do so if Ships[shipnum].wingnum != -1
|
||||
// we will assign wing goals below
|
||||
|
||||
|
||||
for (i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
@@ -289,6 +456,73 @@ void StartAutopilot()
|
||||
)
|
||||
)
|
||||
{
|
||||
// turn off glide
|
||||
if (object_get_gliding(&Objects[Ships[i].objnum]))
|
||||
object_set_gliding(&Objects[Ships[i].objnum], false);
|
||||
|
||||
// check for bigger radius for usage later
|
||||
/*if (!vm_vec_cmp(&rpos, &Player_obj->pos))
|
||||
// want to make sure rpos isn't player pos - we can worry about it being largest object's later
|
||||
{
|
||||
rpos = Objects[Ships[i].objnum].pos;
|
||||
}*/
|
||||
|
||||
if (Objects[Ships[i].objnum].radius > radius)
|
||||
{
|
||||
rpos = Objects[Ships[i].objnum].pos;
|
||||
radius = Objects[Ships[i].objnum].radius;
|
||||
}
|
||||
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{// instantly turn the ship to match the direction player is looking
|
||||
//vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
|
||||
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
|
||||
}
|
||||
|
||||
// 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
|
||||
&& Player_obj != &Objects[Ships[i].objnum]) //only if not player object
|
||||
{
|
||||
ai_info *aip = aip = &Ai_info[Ships[i].ai_index];
|
||||
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
|
||||
vec3d goal_point;
|
||||
object *leader_objp = get_wing_leader(wingnum);
|
||||
|
||||
if (leader_objp != &Objects[Ships[i].objnum])
|
||||
{
|
||||
// not leader.. get our position relative to leader
|
||||
get_absolute_wing_pos(&goal_point, leader_objp, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ai_clear_wing_goals(wingnum);
|
||||
switch (wcount % 2)
|
||||
{
|
||||
case 1: // back-left
|
||||
vm_vec_sub(&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*float((wcount+1)/2)); // 166m is supposedly the optimal range according to tolwyn
|
||||
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
|
||||
break;
|
||||
|
||||
default: //back-right
|
||||
case 0:
|
||||
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*float(wcount/2));
|
||||
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
|
||||
break;
|
||||
}
|
||||
wcount++;
|
||||
|
||||
}
|
||||
Objects[Ships[i].objnum].pos = goal_point;
|
||||
}
|
||||
// lock primary and secondary weapons
|
||||
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]);
|
||||
@@ -296,18 +530,16 @@ void StartAutopilot()
|
||||
|
||||
|
||||
// if they're not part of a wing set their goal
|
||||
if (Ships[i].wingnum == -1)
|
||||
{
|
||||
if (Ships[i].wingnum == -1 || The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, -1, ((waypoint_list*)Navs[CurrentNav].target_obj)->name, &Ai_info[Ships[i].ai_index] );
|
||||
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_WING, 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
|
||||
{
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_FLY_TO_SHIP, -1, ((ship*)Navs[CurrentNav].target_obj)->ship_name, &Ai_info[Ships[i].ai_index] );
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_FLY_TO_SHIP, 0, ((ship*)Navs[CurrentNav].target_obj)->ship_name, &Ai_info[Ships[i].ai_index] );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -315,37 +547,39 @@ void StartAutopilot()
|
||||
}
|
||||
|
||||
// assign wing goals
|
||||
for (i = 0; i < MAX_WINGS; i++)
|
||||
if (!(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS))
|
||||
{
|
||||
if (Wings[i].flags & WF_NAV_CARRY )
|
||||
{
|
||||
//ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );
|
||||
for (i = 0; i < MAX_WINGS; i++)
|
||||
{
|
||||
if (Wings[i].flags & WF_NAV_CARRY )
|
||||
{
|
||||
//ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );
|
||||
|
||||
//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_STAY_NEAR_SHIP, 0, target_shipname, wingnum );
|
||||
//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, target_shipname, wingnum );
|
||||
//ai_clear_ship_goals( &(Ai_info[Ships[num].ai_index]) );
|
||||
|
||||
ai_clear_wing_goals( i );
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_STAY_NEAR_SHIP, 0, target_shipname, wingnum );
|
||||
//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, target_shipname, wingnum );
|
||||
//ai_clear_ship_goals( &(Ai_info[Ships[num].ai_index]) );
|
||||
|
||||
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, AIF_FORMATION_WING, ((waypoint_list*)Navs[CurrentNav].target_obj)->name, i );
|
||||
|
||||
|
||||
// "fix up" the goal
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
ai_clear_wing_goals( i );
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
if (Wings[i].ai_goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
|
||||
Wings[i].ai_goals[j].ai_mode == AIM_WAYPOINTS )
|
||||
|
||||
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++)
|
||||
{
|
||||
autopilot_ai_waypoint_goal_fixup(&(Wings[i].ai_goals[j]));
|
||||
if (Wings[i].ai_goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
|
||||
Wings[i].ai_goals[j].ai_mode == AIM_WAYPOINTS )
|
||||
{
|
||||
autopilot_ai_waypoint_goal_fixup(&(Wings[i].ai_goals[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_FLY_TO_SHIP, AIF_FORMATION_WING, ((ship*)Navs[CurrentNav].target_obj)->ship_name, i );
|
||||
else
|
||||
{
|
||||
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_FLY_TO_SHIP, 0, ((ship*)Navs[CurrentNav].target_obj)->ship_name, i );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,9 +605,75 @@ void StartAutopilot()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start_dist = DistanceTo(CurrentNav);
|
||||
|
||||
// ----------------------------- setup cinematic -----------------------------
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
|
||||
tpos = *Navs[CurrentNav].GetPosition();
|
||||
// determine distance toward nav at which camera will be
|
||||
vm_vec_sub(&pos, &tpos, &Player_obj->pos);
|
||||
vm_vec_normalize(&pos);
|
||||
norm1 = pos;
|
||||
vm_vec_scale(&pos, 5.0f*speed_cap);
|
||||
vm_vec_add(&pos, &pos, &Player_obj->pos);
|
||||
|
||||
switch (myrand()%16)
|
||||
// 8 different ways of getting perp points
|
||||
{
|
||||
|
||||
case 1: // down
|
||||
case 9:
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 2: // up
|
||||
case 10:
|
||||
perp = Player_obj->orient.vec.uvec;
|
||||
break;
|
||||
|
||||
case 3: // left
|
||||
case 11:
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
break;
|
||||
|
||||
case 4: // up-left
|
||||
case 12:
|
||||
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:
|
||||
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:
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 7: // down-right
|
||||
case 15:
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0: // right
|
||||
case 8:
|
||||
perp = Player_obj->orient.vec.rvec;
|
||||
break;
|
||||
|
||||
}
|
||||
vm_vec_normalize(&perp);
|
||||
vm_vec_scale(&perp, 2*radius);
|
||||
vm_vec_add(&cameraPos, &pos, &perp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -401,6 +701,16 @@ void EndAutoPilot()
|
||||
Player_use_ai = 0;
|
||||
//Clear AI Goals
|
||||
|
||||
if (CinematicStarted) // clear cinematic if we need to
|
||||
{
|
||||
if (UseCutsceneBars)
|
||||
{
|
||||
Cutscene_bar_flags &= ~CUB_CUTSCENE;
|
||||
}
|
||||
cam_reset_camera();
|
||||
CinematicStarted = false;
|
||||
}
|
||||
|
||||
// assign ship goals
|
||||
// when assigning goals to individual ships only do so if Ships[shipnum].wingnum != -1
|
||||
// we will assign wing goals below
|
||||
@@ -416,47 +726,99 @@ void EndAutoPilot()
|
||||
)
|
||||
)
|
||||
{
|
||||
//unlock their weaponry
|
||||
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
|
||||
|
||||
ai_clear_ship_goals( &(Ai_info[Ships[i].ai_index]) );
|
||||
if (Ships[i].wingnum != -1)
|
||||
ai_clear_wing_goals( Ships[i].wingnum );
|
||||
|
||||
// old "dumb" routine
|
||||
//ai_clear_ship_goals( &(Ai_info[Ships[i].ai_index]) );
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
{
|
||||
if (Ai_info[Ships[i].ai_index].goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
|
||||
Ai_info[Ships[i].ai_index].goals[j].ai_mode == AI_GOAL_FLY_TO_SHIP ||
|
||||
Ai_info[Ships[i].ai_index].goals[j].ai_mode == AIM_WAYPOINTS ||
|
||||
Ai_info[Ships[i].ai_index].goals[j].ai_mode == AIM_FLY_TO_SHIP)
|
||||
{
|
||||
ai_remove_ship_goal( &(Ai_info[Ships[i].ai_index]), j );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assign wing goals
|
||||
for (i = 0; i < MAX_WINGS; i++)
|
||||
|
||||
if (!(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS))
|
||||
{
|
||||
if (Wings[i].flags & WF_NAV_CARRY )
|
||||
for (i = 0; i < MAX_WINGS; i++)
|
||||
{
|
||||
// old "dumb" routine
|
||||
//ai_clear_wing_goals( i );
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
if (Wings[i].flags & WF_NAV_CARRY )
|
||||
{
|
||||
if (Wings[i].ai_goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
|
||||
Wings[i].ai_goals[j].ai_mode == AI_GOAL_FLY_TO_SHIP ||
|
||||
Wings[i].ai_goals[j].ai_mode == AIM_WAYPOINTS ||
|
||||
Wings[i].ai_goals[j].ai_mode == AIM_FLY_TO_SHIP)
|
||||
// old "dumb" routine
|
||||
//ai_clear_wing_goals( i );
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
{
|
||||
Wings[i].ai_goals[j].ai_mode = AI_GOAL_NONE;
|
||||
Wings[i].ai_goals[j].signature = -1;
|
||||
Wings[i].ai_goals[j].priority = -1;
|
||||
Wings[i].ai_goals[j].flags = 0;
|
||||
if (Wings[i].ai_goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
|
||||
Wings[i].ai_goals[j].ai_mode == AI_GOAL_FLY_TO_SHIP ||
|
||||
Wings[i].ai_goals[j].ai_mode == AIM_WAYPOINTS ||
|
||||
Wings[i].ai_goals[j].ai_mode == AIM_FLY_TO_SHIP)
|
||||
{
|
||||
Wings[i].ai_goals[j].ai_mode = AI_GOAL_NONE;
|
||||
Wings[i].ai_goals[j].signature = -1;
|
||||
Wings[i].ai_goals[j].priority = -1;
|
||||
Wings[i].ai_goals[j].flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************************************
|
||||
|
||||
camera* nav_get_set_camera()
|
||||
{
|
||||
static camid nav_camera;
|
||||
if(!nav_camera.isValid())
|
||||
{
|
||||
nav_camera = cam_create("Nav camera");
|
||||
}
|
||||
|
||||
cam_set_camera(nav_camera);
|
||||
|
||||
return nav_camera.getCamera();
|
||||
}
|
||||
|
||||
void nav_warp(bool prewarp=false)
|
||||
{
|
||||
// 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);
|
||||
vm_vec_scale(&pos, 250.0f); // we move by increments of 250
|
||||
|
||||
while (CanAutopilotPos(tpos))
|
||||
{
|
||||
vm_vec_add(&tpos, &tpos, &pos);
|
||||
}
|
||||
vm_vec_sub(&targetPos, &tpos, &Player_obj->pos); //targetPos is actually a projection in a the direction toward the nav
|
||||
|
||||
if (prewarp)
|
||||
{
|
||||
vm_vec_scale(&targetPos, 0.5);
|
||||
vm_vec_add(&cameraPos, &cameraPos, &targetPos);
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
)
|
||||
{
|
||||
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
|
||||
}
|
||||
}
|
||||
|
||||
// retime all collision pairs
|
||||
obj_all_collisions_retime();
|
||||
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Checks for changes every NPS_TICKRATE milliseconds
|
||||
// Checks:
|
||||
@@ -465,13 +827,52 @@ void EndAutoPilot()
|
||||
void NavSystem_Do()
|
||||
{
|
||||
static unsigned int last_update = 0;
|
||||
|
||||
if (clock () - last_update > NPS_TICKRATE)
|
||||
{
|
||||
if (AutoPilotEngaged)
|
||||
if (Autopilot_AutoDiable())
|
||||
EndAutoPilot();
|
||||
{
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
camera *cam = nav_get_set_camera();
|
||||
if (CinematicStarted)
|
||||
{
|
||||
// update our cinematic and possibly perform warp
|
||||
if(cam != NULL)
|
||||
cam->set_rotation_facing(&Player_obj->pos);
|
||||
|
||||
if (timestamp() >= EndAPCinematic || Autopilot_AutoDiable())
|
||||
{
|
||||
nav_warp();
|
||||
EndAutoPilot();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// start cinematic
|
||||
if (UseCutsceneBars)
|
||||
{
|
||||
Cutscene_bar_flags |= CUB_CUTSCENE;
|
||||
Cutscene_bar_flags &= ~CUB_GRADUAL;
|
||||
}
|
||||
nav_warp(true);
|
||||
|
||||
if(cam != NULL)
|
||||
{
|
||||
cam->set_position(&cameraPos);
|
||||
cam->set_rotation_facing(&Player_obj->pos);
|
||||
}
|
||||
EndAPCinematic = timestamp(10000); // 10 seconds before end of cinematic
|
||||
CinematicStarted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Autopilot_AutoDiable())
|
||||
EndAutoPilot();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// check if a NavPoints target has left, delete it if so
|
||||
int i;
|
||||
|
||||
@@ -495,8 +896,8 @@ void NavSystem_Do()
|
||||
}
|
||||
}
|
||||
|
||||
// ramp time compression
|
||||
if (AutoPilotEngaged)
|
||||
// ramp time compression - only if not using cinematics
|
||||
if (AutoPilotEngaged && !(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS))
|
||||
{
|
||||
int dstfrm_start = start_dist - DistanceTo(CurrentNav);
|
||||
|
||||
@@ -534,8 +935,63 @@ void NavSystem_Do()
|
||||
set_time_compression(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// autopilot linking
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
|
||||
{
|
||||
object *other_objp = &Objects[Ships[i].objnum];
|
||||
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < (NavLinkDistance + other_objp->radius))
|
||||
{
|
||||
Ships[i].flags2 &= ~SF2_NAVPOINT_NEEDSLINK;
|
||||
Ships[i].flags2 |= SF2_NAVPOINT_CARRY;
|
||||
|
||||
send_autopilot_msgID(NP_MSG_MISC_LINKED);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// ********************************************************************************************
|
||||
|
||||
void send_autopilot_msgID(int msgid)
|
||||
{
|
||||
if (msgid < 0 || msgid > NP_NUM_MESSAGES)
|
||||
return;
|
||||
|
||||
send_autopilot_msg(NavMsgs[msgid].message, NavMsgs[msgid].filename);
|
||||
}
|
||||
// ********************************************************************************************
|
||||
|
||||
void send_autopilot_msg(char *msg, char *snd)
|
||||
{
|
||||
// setup
|
||||
if (audio_handle != -1)
|
||||
{
|
||||
audiostream_close_file(audio_handle, 0);
|
||||
audio_handle = -1;
|
||||
}
|
||||
|
||||
if (strlen(msg) != 0 && strcmp(msg, "none"))
|
||||
change_message("autopilot builtin message", msg, -1, 0);
|
||||
|
||||
// load sound
|
||||
if (snd != NULL || strlen(snd) == 0 || !strcmp(snd, "none"))
|
||||
{
|
||||
audio_handle = audiostream_open(snd, ASF_MENUMUSIC );
|
||||
}
|
||||
|
||||
// send/play
|
||||
if (audio_handle != -1)
|
||||
{
|
||||
audiostream_play(audio_handle, Master_event_music_volume, 0);
|
||||
}
|
||||
|
||||
if (strlen(msg) != 0 && strcmp(msg, "none"))
|
||||
message_training_queue("autopilot builtin message", timestamp(0), 5); // display message for five seconds
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Inits the Nav System
|
||||
@@ -544,8 +1000,73 @@ void NavSystem_Init()
|
||||
memset((char *)&Navs, 0, sizeof(Navs));
|
||||
AutoPilotEngaged = false;
|
||||
CurrentNav = -1;
|
||||
audio_handle = -1;
|
||||
CinematicStarted = false;
|
||||
UseCutsceneBars = true;
|
||||
|
||||
// defaults... can be tabled or bound to mission later
|
||||
if (cf_exists_full("autopilot.tbl", CF_TYPE_TABLES))
|
||||
parse_autopilot_table("autopilot.tbl");
|
||||
else
|
||||
parse_autopilot_table(NULL);
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
|
||||
void parse_autopilot_table(char *filename)
|
||||
{
|
||||
int rval;
|
||||
std::vector<std::string> lines;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default autopilot.tbl>"));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("autopilot.tbl"));
|
||||
else
|
||||
read_file_text(filename);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
required_string("#Autopilot");
|
||||
|
||||
// autopilot link distance
|
||||
required_string("$Link Distance:");
|
||||
stuff_int(&NavLinkDistance);
|
||||
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Cutscene_Bars"))
|
||||
UseCutsceneBars = false;
|
||||
|
||||
// No Nav selected message
|
||||
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]);
|
||||
|
||||
required_string("+Msg:");
|
||||
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
|
||||
|
||||
required_string("+Snd File:");
|
||||
stuff_string(NavMsgs[i].filename, F_NAME, 256);
|
||||
}
|
||||
|
||||
|
||||
required_string("#END");
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************************************
|
||||
// Finds a Nav point by name
|
||||
int FindNav(char *Nav)
|
||||
@@ -811,7 +1332,9 @@ unsigned int DistanceTo(int nav)
|
||||
if (nav > MAX_NAVPOINTS && nav < 0)
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
return vm_vec_dist_quick(&Player_obj->pos, Navs[nav].GetPosition());
|
||||
//WMC - Get rid of this bloody warning. Yes, we're casting to a uint.
|
||||
//Deal with it.
|
||||
return (uint)vm_vec_dist_quick(&Player_obj->pos, Navs[nav].GetPosition());
|
||||
}
|
||||
|
||||
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
@@ -4,11 +4,20 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Autopilot/Autopilot.h $
|
||||
* $Revision: 1.9 $
|
||||
* $Date: 2006-02-25 21:42:31 $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2007-09-02 02:10:24 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.11 2007/07/24 20:17:36 Kazan
|
||||
* Make asteroid/debris fields interrupt autopilot, add "hazards near" message to autopilot.tbl, add use-nav-cinematics sexp, fix mantis #1441
|
||||
*
|
||||
* Revision 1.10 2007/07/23 15:16:48 Kazan
|
||||
* Autopilot upgrades as described, MSVC2005 project fixes
|
||||
*
|
||||
* Revision 1.9 2006/02/25 21:42:31 Goober5000
|
||||
* fixes from last commit
|
||||
*
|
||||
* Revision 1.8 2005/07/13 02:50:49 Goober5000
|
||||
* remove PreProcDefine #includes in FS2
|
||||
* --Goober5000
|
||||
@@ -45,7 +54,7 @@
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
// milliseconds between updates
|
||||
#define NPS_TICKRATE 250
|
||||
#define NPS_TICKRATE 125
|
||||
|
||||
#define MAX_NAVPOINTS 8
|
||||
|
||||
@@ -70,9 +79,26 @@ struct NavPoint
|
||||
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
|
||||
|
||||
struct NavMessage
|
||||
{
|
||||
char message[256];
|
||||
char filename[256]; // can be ""
|
||||
};
|
||||
|
||||
extern bool AutoPilotEngaged;
|
||||
extern int CurrentNav;
|
||||
extern NavPoint Navs[MAX_NAVPOINTS];
|
||||
extern NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
extern int LockAPConv;
|
||||
|
||||
// Cycles through the NavPoint List
|
||||
bool Sel_NextNav();
|
||||
@@ -83,7 +109,8 @@ bool Sel_NextNav();
|
||||
// * Nav point selected
|
||||
// * No enemies within 5,000 meters
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilot();
|
||||
bool CanAutopilot(bool send_msg=false);
|
||||
bool CanAutopilotPos(vec3d targetPos);
|
||||
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
@@ -117,6 +144,9 @@ void NavSystem_Do();
|
||||
// Inits the Nav System
|
||||
void NavSystem_Init();
|
||||
|
||||
// parse autopilot.tbl
|
||||
void parse_autopilot_table(char *filename);
|
||||
|
||||
// Finds a Nav point by name
|
||||
int FindNav(char *Nav);
|
||||
|
||||
@@ -152,5 +182,8 @@ unsigned int DistanceTo(int nav);
|
||||
|
||||
bool IsVisited(char *nav);
|
||||
bool IsVisited(int nav);
|
||||
|
||||
void send_autopilot_msg(char *msg, char *snd=NULL);
|
||||
void send_autopilot_msgID(int msgid);
|
||||
#endif
|
||||
|
||||
@@ -9,13 +9,19 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/bmpman/bm_internal.h $
|
||||
* $Revision: 2.6 $
|
||||
* $Date: 2006-05-27 17:20:48 $
|
||||
* $Revision: 2.7 $
|
||||
* $Date: 2007-01-10 01:40:06 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* bmpman info that's internal to bmpman related files only
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.6 2006/05/27 17:20:48 taylor
|
||||
* clean up BM_TYPE_* stuff so it's a little easier to tell what is what
|
||||
* bm_load_sub_fast() doesn't need to lowercase filenames, so don't
|
||||
* byte-swap 16-bit DDS on big endian (they still don't look right though)
|
||||
* update bm_has_alpha_channel() to be less dumb
|
||||
*
|
||||
* Revision 2.5 2006/05/13 07:29:51 taylor
|
||||
* OpenGL envmap support
|
||||
* newer OpenGL extension support
|
||||
@@ -73,10 +79,6 @@
|
||||
#include "bmpman/bmpman.h"
|
||||
|
||||
|
||||
// keep this defined to use per-ship nondarkening pixels
|
||||
#define BMPMAN_SPECIAL_NONDARK
|
||||
|
||||
|
||||
// no-type ( used in: bm_bitmaps[i].type )
|
||||
#define BM_TYPE_NONE 0
|
||||
// in-memory type ( used in: bm_bitmaps[i].type )
|
||||
@@ -181,4 +183,3 @@ void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, uby
|
||||
#endif // BMPMAN_INTERNAL
|
||||
|
||||
#endif // __BM_INTERNAL_H__
|
||||
|
||||
+345
-541
File diff suppressed because it is too large.
Load diff
+44
-32
@@ -10,13 +10,41 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Bmpman/BmpMan.h $
|
||||
*
|
||||
* $Revision: 2.37 $
|
||||
* $Date: 2006-05-27 17:20:48 $
|
||||
* $Revision: 2.44 $
|
||||
* $Date: 2007-03-22 20:13:23 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Prototypes for Bitmap Manager functions
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.43 2007/01/10 01:40:07 taylor
|
||||
* remove the non-dark stuff, it only works on PCX files and stuff to use it has already been ripped out
|
||||
* per earlier discussions: remove -jpgtga and -pcx32, set image load order to DDS->TGA->JPG->PCX
|
||||
* some debug log cleanup
|
||||
* remove bitmap data from system memory once it's in API memory
|
||||
*
|
||||
* Revision 2.42 2007/01/07 12:32:06 taylor
|
||||
* fix bm_page_in_texture() so that it will load all frames of an animation (caused slowdowns in-game with it)
|
||||
*
|
||||
* Revision 2.41 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.40 2006/07/05 23:41:43 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 2.39 2006/07/05 23:35:42 Goober5000
|
||||
* cvs comment tweaks
|
||||
*
|
||||
* Revision 2.38 2006/06/27 04:52:50 taylor
|
||||
* fix various things that Valgrind complained about
|
||||
* comp_type for DDS images will always be set to something, an 'uncompressed' type at the least
|
||||
*
|
||||
* Revision 2.37 2006/05/27 17:20:48 taylor
|
||||
* clean up BM_TYPE_* stuff so it's a little easier to tell what is what
|
||||
* bm_load_sub_fast() doesn't need to lowercase filenames, so don't
|
||||
* byte-swap 16-bit DDS on big endian (they still don't look right though)
|
||||
* update bm_has_alpha_channel() to be less dumb
|
||||
*
|
||||
* Revision 2.36 2006/05/13 07:29:51 taylor
|
||||
* OpenGL envmap support
|
||||
* newer OpenGL extension support
|
||||
@@ -213,7 +241,8 @@
|
||||
* The big DX/main line merge. This has been uploaded to the main CVS since I can't manage to get it to upload to the DX branch. Apologies to all who may be affected adversely, but I'll work to debug it as fast as I can.
|
||||
*
|
||||
* Revision 2.3 2003/01/19 01:07:41 bobboau
|
||||
* redid the way glowmaps are handeled, you now must set the global int GLOWMAP (no longer an array) before you render a poly that uses a glow map then set GLOWMAP to -1 when you're done with, fixed a few other misc bugs it
|
||||
* redid the way glow maps are handled; you now must set a global variable before you render a poly that uses a glow map, then set it to -1 when you're done with it
|
||||
* fixed a few other misc bugs too
|
||||
*
|
||||
* Revision 2.2 2003/01/18 19:55:16 phreak
|
||||
* fixed around the bmpman system to now accept compressed textures
|
||||
@@ -436,27 +465,20 @@
|
||||
// -- Taylor
|
||||
|
||||
|
||||
// 16 bit pixel formats
|
||||
#define BM_PIXEL_FORMAT_ARGB 0 // for glide - can assume certain things, like 1555 LFB writes, whee!
|
||||
#define BM_PIXEL_FORMAT_D3D 1 // d3d - card dependant. booo!
|
||||
#define BM_PIXEL_FORMAT_ARGB_D3D 2 // this card has nice 1555 textures like Glide - ahhhhh!
|
||||
|
||||
|
||||
#define BMP_AABITMAP (1<<0) // antialiased bitmap
|
||||
#define BMP_TEX_XPARENT (1<<1) // transparent texture
|
||||
#define BMP_TEX_NONDARK (1<<2) // nondarkening texture
|
||||
#define BMP_TEX_OTHER (1<<3) // so we can identify all "normal" textures
|
||||
#define BMP_TEX_DXT1 (1<<4) // dxt1 compressed 8r8g8b1a (24bit)
|
||||
#define BMP_TEX_DXT3 (1<<5) // dxt3 compressed 8r8g8b4a (32bit)
|
||||
#define BMP_TEX_DXT5 (1<<6) // dxt5 compressed 8r8g8b8a (32bit)
|
||||
#define BMP_TEX_CUBEMAP (1<<7) // a texture made for cubic environment map
|
||||
#define BMP_TEX_OTHER (1<<2) // so we can identify all "normal" textures
|
||||
#define BMP_TEX_DXT1 (1<<3) // dxt1 compressed 8r8g8b1a (24bit)
|
||||
#define BMP_TEX_DXT3 (1<<4) // dxt3 compressed 8r8g8b4a (32bit)
|
||||
#define BMP_TEX_DXT5 (1<<5) // dxt5 compressed 8r8g8b8a (32bit)
|
||||
#define BMP_TEX_CUBEMAP (1<<6) // a texture made for cubic environment map
|
||||
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
|
||||
|
||||
//compressed texture types
|
||||
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 )
|
||||
|
||||
//non compressed textures
|
||||
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_NONDARK | BMP_TEX_OTHER )
|
||||
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER )
|
||||
|
||||
// any texture type
|
||||
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP )
|
||||
@@ -477,8 +499,6 @@ typedef struct bitmap {
|
||||
} bitmap;
|
||||
|
||||
|
||||
extern int bm_inited;
|
||||
|
||||
extern int Bm_paging;
|
||||
|
||||
void bm_init();
|
||||
@@ -493,11 +513,6 @@ void *bm_malloc(int n, int size);
|
||||
|
||||
void bm_update_memory_used(int n, int size);
|
||||
|
||||
// 16 bit pixel formats
|
||||
extern int Bm_pixel_format;
|
||||
|
||||
#define BYTES_PER_PIXEL(x) ((x+7)/8)
|
||||
|
||||
// how many bytes of textures are used.
|
||||
extern int bm_texture_ram;
|
||||
|
||||
@@ -520,7 +535,7 @@ int bm_load_duplicate(char *filename);
|
||||
// On success, it returns the bitmap number. You cannot
|
||||
// free that RAM until bm_release is called on that bitmap.
|
||||
// See example at bottom of this file
|
||||
int bm_create( int bpp, int w, int h, void * data, int flags = 0);
|
||||
int bm_create( int bpp, int w, int h, void *data = NULL, int flags = 0);
|
||||
|
||||
// Frees up a bitmap's data, but bitmap number 'n' can
|
||||
// still be used, it will just have to be paged in next
|
||||
@@ -556,6 +571,9 @@ extern uint bm_get_signature( int bitmapnum);
|
||||
// Unlocks a bitmap
|
||||
extern void bm_unlock( int bitmapnum );
|
||||
|
||||
//WMC - Needed this for scripting
|
||||
extern int bm_is_valid(int handle);
|
||||
|
||||
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
|
||||
//WMC - Returns -1 on failure, handle or first frame handle on success.
|
||||
int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, int *nframes=NULL, int *fps=NULL );
|
||||
@@ -635,11 +653,7 @@ void bm_page_in_stop();
|
||||
|
||||
// Marks a texture as being used for this level
|
||||
// If num_frames is passed, assume this is an animation
|
||||
void bm_page_in_texture( int bitmapnum, int num_frames=1 );
|
||||
|
||||
// Marks a texture as being used for this level
|
||||
// If num_frames is passed, assume this is an animation
|
||||
void bm_page_in_nondarkening_texture( int bitmap, int num_frames=1 );
|
||||
void bm_page_in_texture( int bitmapnum, int num_frames = 0 );
|
||||
|
||||
// marks a texture as being a transparent textyre used for this level
|
||||
// Marks a texture as being used for this level
|
||||
@@ -668,8 +682,6 @@ void BM_SELECT_ALPHA_TEX_FORMAT();
|
||||
// set the rgba components of a pixel, any of the parameters can be NULL
|
||||
extern void (*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
extern void (*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_d3d(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
@@ -678,7 +690,7 @@ void bm_set_components_argb_d3d_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *
|
||||
// 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);
|
||||
|
||||
extern int GLOWMAP; //this holds a reference to a map that is a fully lit version of it's index -Bobboau
|
||||
extern int GLOWMAP; //this holds a reference to a map that is a fully lit version of its index -Bobboau
|
||||
extern int SPECMAP; //this holds a reference to a map that is for specular mapping -Bobboau
|
||||
extern int ENVMAP; //this holds a reference to a map that is for environment mapping -Bobboau
|
||||
extern int BUMPMAP; //blah blah bumpmapping
|
||||
|
||||
+629
-240
File diff suppressed because it is too large.
Load diff
+96
-26
@@ -1,61 +1,126 @@
|
||||
|
||||
|
||||
#ifndef _CAMERA_H
|
||||
#define _CAMERA_H
|
||||
|
||||
#include "graphics/2d.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "physics/physics.h" //for avd
|
||||
#include "object/object.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define CAM_STATIONARY_FOV (1<<0)
|
||||
#define CAM_STATIONARY_ORI (1<<1)
|
||||
#define CAM_STATIONARY_POS (1<<2)
|
||||
#define CAM_DEFAULT_FLAGS 0
|
||||
|
||||
class camera
|
||||
{
|
||||
private:
|
||||
friend class avd_camera;
|
||||
protected:
|
||||
char name[NAME_LENGTH];
|
||||
int sig;
|
||||
int flags;
|
||||
|
||||
vec3d position;
|
||||
vec3d *desired_position; //NULL unless we're trying to move somewhere
|
||||
vec3d translation_velocity;
|
||||
vec3d translation_vel_limit;
|
||||
vec3d translation_acc_limit;
|
||||
object_h object_self;
|
||||
int object_self_submodel;
|
||||
|
||||
matrix orientation;
|
||||
matrix *desired_orientation; //NULL unless we're trying to point somewhere
|
||||
vec3d rotation_rate;
|
||||
vec3d rotation_vel_limit;
|
||||
vec3d rotation_acc_limit;
|
||||
object_h object_target;
|
||||
int object_target_submodel;
|
||||
|
||||
void (*func_custom_position)(camera *cam, vec3d *pos);
|
||||
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;
|
||||
|
||||
float c_fov;
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
camera(char *in_name=NULL);
|
||||
camera(char *in_name=NULL, int in_signature=-1);
|
||||
~camera();
|
||||
void clear();
|
||||
void reset();
|
||||
|
||||
//Set'
|
||||
void set_name(char *in_name);
|
||||
|
||||
void set_object_self(object *objp, int n_object_self_submodel = -1);
|
||||
void set_object_target(object *objp, int n_object_target_submodel = -1);
|
||||
|
||||
void set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *pos));
|
||||
void set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *ori));
|
||||
|
||||
void set_fov(float in_fov, float in_fov_time = 0.0f, float in_fov_acceleration_time = 0.0f);
|
||||
|
||||
void set_position(vec3d *in_position = NULL, float in_translation_time = 0.0f, float in_translation_acceleration_time = 0.0f);
|
||||
void set_translation_velocity(vec3d *in_velocity);
|
||||
void set_translation_velocity(vec3d *in_velocity, float in_acceleration_time = 0.0f);
|
||||
|
||||
void set_rotation(matrix *in_orientation = NULL, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f);
|
||||
void set_rotation(angles *in_angles, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f);
|
||||
void set_rotation_facing(vec3d *in_target, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f);
|
||||
void set_rotation_velocity(vec3d *in_rotation_rate);
|
||||
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time = 0.0f);
|
||||
|
||||
//Get
|
||||
//These return values should never ever be changed, I do this in the interest of speed.
|
||||
char *get_name() {return name;}
|
||||
vec3d *get_position() {return &position;}
|
||||
matrix *get_orientation() {return &orientation;}
|
||||
int get_signature() {return sig;}
|
||||
object *get_object_self();
|
||||
object *get_object_target();
|
||||
float get_fov();
|
||||
void get_info(vec3d *position, matrix *orientation);
|
||||
|
||||
//Is
|
||||
bool is_empty(){return sig < 0;}
|
||||
|
||||
//Do
|
||||
void do_frame(float in_frametime);
|
||||
};
|
||||
|
||||
class warp_camera
|
||||
{
|
||||
private:
|
||||
float c_time;
|
||||
float c_damping;
|
||||
|
||||
vec3d c_vel;
|
||||
vec3d c_desired_vel;
|
||||
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
warp_camera();
|
||||
warp_camera(object *objp);
|
||||
void reset();
|
||||
|
||||
void set_position(vec3d *in_pos);
|
||||
void set_rotation(matrix *in_ori);
|
||||
void set_velocity(vec3d *in_vel, bool instantaneous);
|
||||
|
||||
void do_frame(float in_frametime);
|
||||
|
||||
void get_info(vec3d *position, matrix *orientation);
|
||||
};
|
||||
|
||||
extern warp_camera Warp_camera;
|
||||
|
||||
class subtitle
|
||||
{
|
||||
private:
|
||||
void clone(const subtitle &sub);
|
||||
|
||||
std::vector<std::string> text_lines;
|
||||
int text_pos[2];
|
||||
float text_pos[2];
|
||||
|
||||
float display_time;
|
||||
float fade_time;
|
||||
@@ -84,16 +149,21 @@ public:
|
||||
|
||||
//Some global stuff
|
||||
extern std::vector<subtitle> Subtitles;
|
||||
extern std::vector<camera> Cameras;
|
||||
//Preset cameras
|
||||
extern camera* Free_camera;
|
||||
extern camera* Current_camera;
|
||||
extern float VIEWER_ZOOM_DEFAULT;
|
||||
|
||||
//Helpful functions
|
||||
void cameras_init();
|
||||
void cameras_close();
|
||||
void cameras_do_frame(float frametime);
|
||||
int cameras_lookup(char *name);
|
||||
void cam_init();
|
||||
void cam_close();
|
||||
void cam_do_frame(float frametime);
|
||||
camid cam_create(char *n_name=NULL, vec3d *n_pos=NULL, matrix *n_ori=NULL, object *n_object=NULL, int n_submodel_parent=-1);
|
||||
camid cam_create(char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_object=NULL, int n_submodel_parent=-1);
|
||||
void cam_delete(camid cid);
|
||||
bool cam_set_camera(camid cid);
|
||||
void cam_reset_camera();
|
||||
camid cam_lookup(char *name);
|
||||
camid cam_get_camera(uint index);
|
||||
camid cam_get_current();
|
||||
uint cam_get_num();
|
||||
|
||||
void subtitles_init();
|
||||
void subtitles_close();
|
||||
|
||||
+285
-83
@@ -9,13 +9,45 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/CFile/cfile.cpp $
|
||||
* $Revision: 2.40 $
|
||||
* $Date: 2006-04-20 06:32:00 $
|
||||
* $Revision: 2.47 $
|
||||
* $Date: 2007-11-21 07:28:37 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Utilities for operating on files
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.46 2007/04/11 18:24:27 taylor
|
||||
* cleanup of chksum stuff (works properly on 64-bit systems now)
|
||||
* add chksum support for VPs, both a startup in debug builds, and via cmdline option (-verify_vps)
|
||||
* little cleanup in cmdline.cpp (get rid of the remaining "fix bugs" crap)
|
||||
*
|
||||
* Revision 2.45 2007/03/22 20:22:24 taylor
|
||||
* a little better error handling for cf_exists_full()
|
||||
* add a cf_exists_full_ext() which can find a series of extensions and returns true if any of them exist
|
||||
* use cf_exists_full_ext() for eventmusic file checks (to check for ogg and wav)
|
||||
* get rid of SPM hack, it's wrong (just commented out for now though)
|
||||
* fix a bunch of bugs in cf_find_file_location_ext():
|
||||
* - try to handle files with multiple periods a bit better (for the wav files like: blah_1.5.wav)
|
||||
* - load issue with finding incorrect files by mistake
|
||||
* - prevent finding different file types in various paths/roots
|
||||
*
|
||||
* Revision 2.44 2007/02/11 09:31:11 taylor
|
||||
* some CFILE cleanup and slight directory order reorg
|
||||
* add cfopen_special() for quickly opening files that have already been found with cf_find_file_location_ext()
|
||||
* remove NO_SOUND
|
||||
*
|
||||
* Revision 2.43 2007/01/07 12:32:38 taylor
|
||||
* remove avi and mpg from supported extensions
|
||||
*
|
||||
* Revision 2.42 2006/08/15 00:25:23 Backslash
|
||||
* add .ogg to the list of recognized movie file extensions
|
||||
*
|
||||
* Revision 2.41 2006/07/28 02:34:52 taylor
|
||||
* don't lowercase the dir for chdir on non-Win32 since it could be, and probably is, case sensitive
|
||||
*
|
||||
* Revision 2.40 2006/04/20 06:32:00 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 2.39 2006/04/16 05:28:10 taylor
|
||||
* extra safety check when creating a default path string, filename is optional be we need to available if root0 is missing (CFILE not initted yet)
|
||||
* fix that crazy compiler<->constructor<->linker<->server.txt deal caused by some bad code and a freaky link thing in freespace.cpp
|
||||
@@ -364,45 +396,45 @@ char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
|
||||
// Please make sure extensions are all lower-case, or we'll break unix compatibility
|
||||
//
|
||||
cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
// What type this is Path Extensions Parent type
|
||||
{ CF_TYPE_INVALID, NULL, NULL, CF_TYPE_INVALID },
|
||||
// What type this is Path Extensions Parent type
|
||||
{ CF_TYPE_INVALID, NULL, NULL, CF_TYPE_INVALID },
|
||||
// Root must be index 1!!
|
||||
{ CF_TYPE_ROOT, "", ".mve .avi .mpg", 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 .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_TEXT, "data" DIR_SEPARATOR_STR "text", ".txt .net", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MODELS, "data" DIR_SEPARATOR_STR "models", ".pof", CF_TYPE_DATA },
|
||||
{ CF_TYPE_TABLES, "data" DIR_SEPARATOR_STR "tables", ".tbl .tbm", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SOUNDS, "data" DIR_SEPARATOR_STR "sounds", ".wav .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SOUNDS_8B22K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "8b22k", ".wav .ogg", CF_TYPE_SOUNDS },
|
||||
{ CF_TYPE_SOUNDS_16B11K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "16b11k", ".wav .ogg", CF_TYPE_SOUNDS },
|
||||
{ CF_TYPE_VOICE, "data" DIR_SEPARATOR_STR "voice", "", CF_TYPE_DATA },
|
||||
{ CF_TYPE_VOICE_BRIEFINGS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "briefing", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_CMD_BRIEF, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "command_briefings", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_DEBRIEFINGS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "debriefing", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_PERSONAS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "personas", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_SPECIAL, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "special", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_TRAINING, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "training", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_MUSIC, "data" DIR_SEPARATOR_STR "music", ".wav .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MOVIES, "data" DIR_SEPARATOR_STR "movies", ".mve .msb .avi .mpg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FONT, "data" DIR_SEPARATOR_STR "fonts", ".vf", CF_TYPE_DATA },
|
||||
{ CF_TYPE_EFFECTS, "data" DIR_SEPARATOR_STR "effects", ".ani .eff .pcx .neb .tga .jpg .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_HUD, "data" DIR_SEPARATOR_STR "hud", ".ani .pcx .tga", CF_TYPE_DATA },
|
||||
{ CF_TYPE_PLAYER_MAIN, "data" DIR_SEPARATOR_STR "players", "", CF_TYPE_DATA },
|
||||
{ CF_TYPE_PLAYER_IMAGES_MAIN, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "images", ".pcx", CF_TYPE_PLAYER_MAIN },
|
||||
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .ibx", CF_TYPE_DATA }, //clr=cached color
|
||||
{ CF_TYPE_PLAYERS, "data" DIR_SEPARATOR_STR "players", ".hcf", CF_TYPE_DATA },
|
||||
{ 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_DATA },
|
||||
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .fs2 .txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_CONFIG, "data" DIR_SEPARATOR_STR "config", ".cfg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SQUAD_IMAGES_MAIN, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx", CF_TYPE_DATA },
|
||||
{ CF_TYPE_DEMOS, "data" DIR_SEPARATOR_STR "demos", ".fsd", CF_TYPE_DATA },
|
||||
{ CF_TYPE_CBANIMS, "data" DIR_SEPARATOR_STR "cbanims", ".ani", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".ani", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
|
||||
{ CF_TYPE_ROOT, "", ".mve .ogg", 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 .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 },
|
||||
{ CF_TYPE_TABLES, "data" DIR_SEPARATOR_STR "tables", ".tbl .tbm", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SOUNDS, "data" DIR_SEPARATOR_STR "sounds", ".wav .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SOUNDS_8B22K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "8b22k", ".wav .ogg", CF_TYPE_SOUNDS },
|
||||
{ CF_TYPE_SOUNDS_16B11K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "16b11k", ".wav .ogg", CF_TYPE_SOUNDS },
|
||||
{ CF_TYPE_VOICE, "data" DIR_SEPARATOR_STR "voice", "", CF_TYPE_DATA },
|
||||
{ CF_TYPE_VOICE_BRIEFINGS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "briefing", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_CMD_BRIEF, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "command_briefings", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_DEBRIEFINGS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "debriefing", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_PERSONAS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "personas", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_SPECIAL, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "special", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_TRAINING, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "training", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_MUSIC, "data" DIR_SEPARATOR_STR "music", ".wav .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MOVIES, "data" DIR_SEPARATOR_STR "movies", ".mve .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FONT, "data" DIR_SEPARATOR_STR "fonts", ".vf .ttf", CF_TYPE_DATA },
|
||||
{ CF_TYPE_EFFECTS, "data" DIR_SEPARATOR_STR "effects", ".ani .eff .pcx .neb .tga .jpg .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_HUD, "data" DIR_SEPARATOR_STR "hud", ".ani .pcx .tga .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_PLAYERS, "data" DIR_SEPARATOR_STR "players", ".hcf", CF_TYPE_DATA },
|
||||
{ CF_TYPE_PLAYER_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "images", ".pcx .dds", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .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 .ibx", CF_TYPE_DATA }, //clr=cached color
|
||||
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .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 },
|
||||
{ CF_TYPE_DEMOS, "data" DIR_SEPARATOR_STR "demos", ".fsd", CF_TYPE_DATA },
|
||||
{ CF_TYPE_CBANIMS, "data" DIR_SEPARATOR_STR "cbanims", ".ani", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".ani", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
|
||||
};
|
||||
|
||||
|
||||
@@ -524,12 +556,12 @@ int cfile_init(char *exe_dir, char *cdrom_dir)
|
||||
Cfile_block_list[i].type = CFILE_BLOCK_UNUSED;
|
||||
}
|
||||
|
||||
Cfile_cdrom_dir = cdrom_dir;
|
||||
cf_build_secondary_filelist(Cfile_cdrom_dir);
|
||||
|
||||
// 32 bit CRC table init
|
||||
cf_chksum_long_init();
|
||||
|
||||
Cfile_cdrom_dir = cdrom_dir;
|
||||
cf_build_secondary_filelist(Cfile_cdrom_dir);
|
||||
|
||||
atexit( cfile_close );
|
||||
}
|
||||
|
||||
@@ -545,14 +577,15 @@ void cfile_refresh()
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// Changes to a drive if valid.. 1=A, 2=B, etc
|
||||
// If flag, then changes to it.
|
||||
// Returns 0 if not-valid, 1 if valid.
|
||||
int cfile_chdrive( int DriveNum, int flag )
|
||||
{
|
||||
int n, org;
|
||||
int Valid = 0;
|
||||
#ifdef _WIN32
|
||||
int n, org;
|
||||
|
||||
org = -1;
|
||||
if (!flag)
|
||||
@@ -567,10 +600,11 @@ int cfile_chdrive( int DriveNum, int flag )
|
||||
|
||||
if ( (!flag) && (n != org) )
|
||||
_chdrive( org );
|
||||
#endif // _WIN32
|
||||
|
||||
return Valid;
|
||||
|
||||
}
|
||||
#endif // ifdef WIN32
|
||||
|
||||
// push current directory on a 'stack' (so we can restore it) and change the directory
|
||||
int cfile_push_chdir(int type)
|
||||
@@ -591,9 +625,10 @@ int cfile_push_chdir(int type)
|
||||
strncpy(Cfile_stack[Cfile_stack_pos++], OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN-1);
|
||||
|
||||
cf_create_default_path_string( dir, sizeof(dir)-1, type, NULL );
|
||||
_strlwr(dir);
|
||||
|
||||
#ifdef _WIN32
|
||||
_strlwr(dir);
|
||||
|
||||
char *Drive = strchr(dir, ':');
|
||||
|
||||
if (Drive) {
|
||||
@@ -614,9 +649,7 @@ int cfile_push_chdir(int type)
|
||||
// This chdir might get a critical error!
|
||||
e = _chdir( Path );
|
||||
if (e) {
|
||||
#ifdef _WIN32
|
||||
cfile_chdrive( OriginalDirectory[0] - 'a' + 1, 1 );
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -632,9 +665,10 @@ int cfile_chdir(char *dir)
|
||||
char NoDir[] = "\\.";
|
||||
|
||||
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN-1);
|
||||
_strlwr(dir);
|
||||
|
||||
#ifdef _WIN32
|
||||
_strlwr(dir);
|
||||
|
||||
char *Drive = strchr(dir, ':');
|
||||
if (Drive) {
|
||||
if (!cfile_chdrive( *(Drive - 1) - 'a' + 1, 1))
|
||||
@@ -654,9 +688,7 @@ int cfile_chdir(char *dir)
|
||||
// This chdir might get a critical error!
|
||||
e = _chdir( Path );
|
||||
if (e) {
|
||||
#ifdef _WIN32
|
||||
cfile_chdrive( OriginalDirectory[0] - 'a' + 1, 1 );
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -827,9 +859,24 @@ int cf_exists(char *filename, int dir_type)
|
||||
// Checks both the file system and the VPs.
|
||||
int cf_exists_full(char *filename, int dir_type)
|
||||
{
|
||||
if ( (filename == NULL) || !strlen(filename) )
|
||||
return 0;
|
||||
|
||||
return cf_find_file_location(filename, dir_type, 0, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
// same as the above, but with extension check
|
||||
int cf_exists_full_ext(char *filename, int dir_type, const int num_ext, const char **ext_list)
|
||||
{
|
||||
if ( (filename == NULL) || !strlen(filename) )
|
||||
return 0;
|
||||
|
||||
if ( (num_ext <= 0) || (ext_list == NULL) )
|
||||
return 0;
|
||||
|
||||
return (cf_find_file_location_ext(filename, num_ext, ext_list, dir_type, 0, NULL, NULL, NULL) != -1);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void cf_attrib(char *filename, int set, int clear, int dir_type)
|
||||
{
|
||||
@@ -1040,6 +1087,96 @@ CFILE *cfopen(char *file_path, char *mode, int type, int dir_type, bool localize
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// cfopen_ext()
|
||||
//
|
||||
// parameters: *filepath ==> name of file to open (may be path+name)
|
||||
// *mode ==> specifies how file should be opened (eg "rb" for read binary)
|
||||
// passing NULL to mode deletes the file if it exists and returns NULL
|
||||
|
||||
// dir_type => override extension check, value is one of CF_TYPE* #defines
|
||||
//
|
||||
// returns: success ==> address of CFILE structure
|
||||
// error ==> NULL
|
||||
//
|
||||
CFILE *cfopen_special(char *file_path, char *mode, const int size, const int offset, int dir_type)
|
||||
{
|
||||
if ( !cfile_inited) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Assert( file_path && strlen(file_path) );
|
||||
Assert( mode != NULL );
|
||||
Assert( offset >= 0 );
|
||||
|
||||
// cfopen_special() only supports reading files, not creating them
|
||||
if ( strchr(mode, 'w') ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// "file_path" should already be a fully qualified path, so just try to open it
|
||||
FILE *fp = fopen( file_path, "rb" );
|
||||
|
||||
if ( !fp )
|
||||
return NULL;
|
||||
|
||||
if ( offset ) {
|
||||
// it's in a pack file
|
||||
return cf_open_packed_cfblock(fp, dir_type, offset, size);
|
||||
} else {
|
||||
// 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(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;*/
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ctmpfile()
|
||||
@@ -1704,16 +1841,16 @@ int cfputs(char *str, CFILE *cfile)
|
||||
|
||||
// CRC code for mission validation. given to us by Kevin Bentley on 7/20/98. Some sort of
|
||||
// checksumming code that he wrote a while ago.
|
||||
#define CRC32_POLYNOMIAL 0xEDB88320L
|
||||
unsigned long CRCTable[256];
|
||||
#define CRC32_POLYNOMIAL 0xEDB88320
|
||||
uint CRCTable[256];
|
||||
|
||||
#define CF_CHKSUM_SAMPLE_SIZE 512
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
ushort cf_add_chksum_short(ushort seed, char *buffer, int size)
|
||||
ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size)
|
||||
{
|
||||
ubyte * ptr = (ubyte *)buffer;
|
||||
unsigned int sum1,sum2;
|
||||
ubyte *ptr = buffer;
|
||||
uint sum1, sum2;
|
||||
|
||||
sum1 = sum2 = (int)(seed);
|
||||
|
||||
@@ -1724,51 +1861,48 @@ ushort cf_add_chksum_short(ushort seed, char *buffer, int size)
|
||||
}
|
||||
sum2 %= 255;
|
||||
|
||||
return (unsigned short)((sum1<<8)+ sum2);
|
||||
return (ushort)((sum1 << 8) + sum2);
|
||||
}
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
unsigned long cf_add_chksum_long(unsigned long seed, char *buffer, int size)
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size)
|
||||
{
|
||||
unsigned long crc;
|
||||
unsigned char *p;
|
||||
unsigned long temp1;
|
||||
unsigned long temp2;
|
||||
uint crc;
|
||||
ubyte *p;
|
||||
|
||||
p = (unsigned char*)buffer;
|
||||
p = buffer;
|
||||
crc = seed;
|
||||
|
||||
while (size--!=0){
|
||||
temp1 = (crc>>8)&0x00FFFFFFL;
|
||||
temp2 = CRCTable[((int)crc^*p++)&0xff];
|
||||
crc = temp1^temp2;
|
||||
}
|
||||
|
||||
while (size--)
|
||||
crc = (crc >> 8) ^ CRCTable[(crc ^ *p++) & 0xff];
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
void cf_chksum_long_init()
|
||||
{
|
||||
int i,j;
|
||||
unsigned long crc;
|
||||
int i, j;
|
||||
uint crc;
|
||||
|
||||
for( i=0;i<=255;i++) {
|
||||
crc=i;
|
||||
for(j=8;j>0;j--) {
|
||||
if(crc&1)
|
||||
crc=(crc>>1)^CRC32_POLYNOMIAL;
|
||||
for (i = 0; i < 256; i++) {
|
||||
crc = i;
|
||||
|
||||
for (j = 8; j > 0; j--) {
|
||||
if (crc & 1)
|
||||
crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
|
||||
else
|
||||
crc>>=1;
|
||||
crc >>= 1;
|
||||
}
|
||||
CRCTable[i]=crc;
|
||||
}
|
||||
|
||||
CRCTable[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
// single function convenient to use for both short and long checksums
|
||||
// NOTE : only one of chk_short or chk_long must be non-NULL (indicating which checksum to perform)
|
||||
int cf_chksum_do(CFILE *cfile, ushort *chk_short, uint *chk_long, int max_size)
|
||||
{
|
||||
char cf_buffer[CF_CHKSUM_SAMPLE_SIZE];
|
||||
ubyte cf_buffer[CF_CHKSUM_SAMPLE_SIZE];
|
||||
int is_long;
|
||||
int cf_len = 0;
|
||||
int cf_total;
|
||||
@@ -1810,9 +1944,9 @@ int cf_chksum_do(CFILE *cfile, ushort *chk_short, uint *chk_long, int max_size)
|
||||
if(cf_len > 0){
|
||||
// do the proper short or long checksum
|
||||
if(is_long){
|
||||
*chk_long = (uint)cf_add_chksum_long(*chk_long, cf_buffer, cf_len);
|
||||
*chk_long = cf_add_chksum_long(*chk_long, cf_buffer, cf_len);
|
||||
} else {
|
||||
*chk_short = (ushort)cf_add_chksum_short(*chk_short, cf_buffer, cf_len);
|
||||
*chk_short = cf_add_chksum_short(*chk_short, cf_buffer, cf_len);
|
||||
}
|
||||
}
|
||||
} while((cf_len > 0) && (cf_total < max_size));
|
||||
@@ -1820,6 +1954,74 @@ int cf_chksum_do(CFILE *cfile, ushort *chk_short, uint *chk_long, int max_size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get the chksum of a pack file (VP)
|
||||
int cf_chksum_pack(char *filename, uint *chk_long, bool full)
|
||||
{
|
||||
const int safe_size = 2097152; // 2 Meg
|
||||
const int header_offset = 32; // skip 32bytes for header (header is currently smaller than this though)
|
||||
|
||||
ubyte cf_buffer[CF_CHKSUM_SAMPLE_SIZE];
|
||||
int cf_len = 0;
|
||||
int cf_total;
|
||||
int read_size;
|
||||
int max_size;
|
||||
|
||||
if (chk_long == NULL) {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
*chk_long = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*chk_long = 0;
|
||||
|
||||
// get the max size
|
||||
fseek(fp, 0, SEEK_END);
|
||||
max_size = ftell(fp);
|
||||
|
||||
// maybe do a chksum of the entire file
|
||||
if (full) {
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
}
|
||||
// othewise it's only a partial check
|
||||
else {
|
||||
CLAMP(max_size, 0, safe_size);
|
||||
|
||||
Assert( max_size > header_offset );
|
||||
max_size -= header_offset;
|
||||
|
||||
fseek(fp, -(max_size), SEEK_END);
|
||||
}
|
||||
|
||||
cf_total = 0;
|
||||
|
||||
do {
|
||||
// determine how much we want to read
|
||||
if ( (max_size - cf_total) >= CF_CHKSUM_SAMPLE_SIZE )
|
||||
read_size = CF_CHKSUM_SAMPLE_SIZE;
|
||||
else
|
||||
read_size = max_size - cf_total;
|
||||
|
||||
// read in some buffer
|
||||
cf_len = fread(cf_buffer, 1, read_size, fp);
|
||||
|
||||
// total we've read so far
|
||||
cf_total += cf_len;
|
||||
|
||||
// add the checksum
|
||||
if (cf_len > 0)
|
||||
*chk_long = cf_add_chksum_long((*chk_long), cf_buffer, cf_len);
|
||||
} while ( (cf_len > 0) && (cf_total < max_size) );
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// get the 2 byte checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_short(char *filename, ushort *chksum, int max_size, int cf_type)
|
||||
{
|
||||
|
||||
+86
-36
@@ -9,13 +9,41 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/CFile/cfile.h $
|
||||
* $Revision: 2.17 $
|
||||
* $Date: 2006-02-13 00:20:45 $
|
||||
* $Revision: 2.22 $
|
||||
* $Date: 2007-11-21 07:28:37 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* <insert description of file here>
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.21 2007/04/11 18:24:27 taylor
|
||||
* cleanup of chksum stuff (works properly on 64-bit systems now)
|
||||
* add chksum support for VPs, both a startup in debug builds, and via cmdline option (-verify_vps)
|
||||
* little cleanup in cmdline.cpp (get rid of the remaining "fix bugs" crap)
|
||||
*
|
||||
* Revision 2.20 2007/03/22 20:22:24 taylor
|
||||
* a little better error handling for cf_exists_full()
|
||||
* add a cf_exists_full_ext() which can find a series of extensions and returns true if any of them exist
|
||||
* use cf_exists_full_ext() for eventmusic file checks (to check for ogg and wav)
|
||||
* get rid of SPM hack, it's wrong (just commented out for now though)
|
||||
* fix a bunch of bugs in cf_find_file_location_ext():
|
||||
* - try to handle files with multiple periods a bit better (for the wav files like: blah_1.5.wav)
|
||||
* - load issue with finding incorrect files by mistake
|
||||
* - prevent finding different file types in various paths/roots
|
||||
*
|
||||
* Revision 2.19 2007/02/11 09:31:11 taylor
|
||||
* some CFILE cleanup and slight directory order reorg
|
||||
* add cfopen_special() for quickly opening files that have already been found with cf_find_file_location_ext()
|
||||
* remove NO_SOUND
|
||||
*
|
||||
* Revision 2.18 2006/09/11 05:49:05 taylor
|
||||
* various small cleanup and speedup changes
|
||||
* add a cf_find_file_location_ext() function, which you can pass a filename and a list of extensions and it will search for all of them at once
|
||||
*
|
||||
* Revision 2.17 2006/02/13 00:20:45 Goober5000
|
||||
* more tweaks, plus clarification of checks for the existence of files
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.16 2006/01/17 02:33:20 wmcoolmon
|
||||
* data/scripts directory
|
||||
*
|
||||
@@ -431,40 +459,40 @@ typedef struct {
|
||||
#define CF_TYPE_DATA 2
|
||||
#define CF_TYPE_MAPS 3
|
||||
#define CF_TYPE_TEXT 4
|
||||
#define CF_TYPE_MISSIONS 5
|
||||
#define CF_TYPE_MODELS 6
|
||||
#define CF_TYPE_TABLES 7
|
||||
#define CF_TYPE_SOUNDS 8
|
||||
#define CF_TYPE_SOUNDS_8B22K 9
|
||||
#define CF_TYPE_SOUNDS_16B11K 10
|
||||
#define CF_TYPE_VOICE 11
|
||||
#define CF_TYPE_VOICE_BRIEFINGS 12
|
||||
#define CF_TYPE_VOICE_CMD_BRIEF 13
|
||||
#define CF_TYPE_VOICE_DEBRIEFINGS 14
|
||||
#define CF_TYPE_VOICE_PERSONAS 15
|
||||
#define CF_TYPE_VOICE_SPECIAL 16
|
||||
#define CF_TYPE_VOICE_TRAINING 17
|
||||
#define CF_TYPE_MUSIC 18
|
||||
#define CF_TYPE_MOVIES 19
|
||||
#define CF_TYPE_INTERFACE 20
|
||||
#define CF_TYPE_FONT 21
|
||||
#define CF_TYPE_EFFECTS 22
|
||||
#define CF_TYPE_HUD 23
|
||||
#define CF_TYPE_PLAYER_MAIN 24
|
||||
#define CF_TYPE_PLAYER_IMAGES_MAIN 25
|
||||
#define CF_TYPE_CACHE 26
|
||||
#define CF_TYPE_PLAYERS 27
|
||||
#define CF_TYPE_SINGLE_PLAYERS 28
|
||||
#define CF_TYPE_MULTI_PLAYERS 29
|
||||
#define CF_TYPE_MULTI_CACHE 30
|
||||
#define CF_TYPE_MODELS 5
|
||||
#define CF_TYPE_TABLES 6
|
||||
#define CF_TYPE_SOUNDS 7
|
||||
#define CF_TYPE_SOUNDS_8B22K 8
|
||||
#define CF_TYPE_SOUNDS_16B11K 9
|
||||
#define CF_TYPE_VOICE 10
|
||||
#define CF_TYPE_VOICE_BRIEFINGS 11
|
||||
#define CF_TYPE_VOICE_CMD_BRIEF 12
|
||||
#define CF_TYPE_VOICE_DEBRIEFINGS 13
|
||||
#define CF_TYPE_VOICE_PERSONAS 14
|
||||
#define CF_TYPE_VOICE_SPECIAL 15
|
||||
#define CF_TYPE_VOICE_TRAINING 16
|
||||
#define CF_TYPE_MUSIC 17
|
||||
#define CF_TYPE_MOVIES 18
|
||||
#define CF_TYPE_INTERFACE 19
|
||||
#define CF_TYPE_FONT 20
|
||||
#define CF_TYPE_EFFECTS 21
|
||||
#define CF_TYPE_HUD 22
|
||||
#define CF_TYPE_PLAYERS 23
|
||||
#define CF_TYPE_PLAYER_IMAGES 24
|
||||
#define CF_TYPE_SQUAD_IMAGES 25
|
||||
#define CF_TYPE_SINGLE_PLAYERS 26
|
||||
#define CF_TYPE_MULTI_PLAYERS 27
|
||||
#define CF_TYPE_CACHE 28
|
||||
#define CF_TYPE_MULTI_CACHE 29
|
||||
#define CF_TYPE_MISSIONS 30
|
||||
#define CF_TYPE_CONFIG 31
|
||||
#define CF_TYPE_SQUAD_IMAGES_MAIN 32
|
||||
#define CF_TYPE_DEMOS 33
|
||||
#define CF_TYPE_CBANIMS 34
|
||||
#define CF_TYPE_INTEL_ANIMS 35
|
||||
#define CF_TYPE_SCRIPTS 36
|
||||
#define CF_TYPE_DEMOS 32
|
||||
#define CF_TYPE_CBANIMS 33
|
||||
#define CF_TYPE_INTEL_ANIMS 34
|
||||
#define CF_TYPE_SCRIPTS 35
|
||||
#define CF_TYPE_FICTION 36
|
||||
|
||||
#define CF_MAX_PATH_TYPES 37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
#define CF_MAX_PATH_TYPES 37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
|
||||
// TRUE if type is specified and valid
|
||||
@@ -512,6 +540,10 @@ int cf_get_dir_type(CFILE *cfile);
|
||||
// default path. If mode is NULL, delete the file.
|
||||
CFILE *cfopen(char *filename, char *mode, int type = CFILE_NORMAL, int dir_type = CF_TYPE_ANY, bool localize = false);
|
||||
|
||||
// like cfopen(), but it accepts a fully qualified path only (ie, the result of a cf_find_file_location() call)
|
||||
// NOTE: only supports reading files!!
|
||||
CFILE *cfopen_special(char *file_path, char *mode, const int size, const int offset, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
// Flush the open file buffer
|
||||
int cflush(CFILE *cfile);
|
||||
|
||||
@@ -533,6 +565,8 @@ int cf_exists(char *filename, int dir_type);
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks both the file system and the VPs.
|
||||
int cf_exists_full(char *filename, int dir_type);
|
||||
// check num_ext worth of ext_list extensions
|
||||
int cf_exists_full_ext(char *filename, int dir_type, const int num_ext, const char **ext_list);
|
||||
|
||||
// ctmpfile() opens a temporary file stream. File is deleted automatically when closed
|
||||
CFILE *ctmpfile();
|
||||
@@ -591,13 +625,15 @@ int cf_chksum_long(char *filename, uint *chksum, int max_size = -1, int cf_type
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_long(CFILE *file, uint *chksum, int max_size = -1);
|
||||
|
||||
int cf_chksum_pack(char *filename, uint *chk_long, bool full = false);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
ushort cf_add_chksum_short(ushort seed, char *buffer, int size);
|
||||
ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size);
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
unsigned long cf_add_chksum_long(unsigned long seed, char *buffer, int size);
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
@@ -672,6 +708,20 @@ void cf_sort_filenames( int n, char **list, int sort, file_list_info *info = NUL
|
||||
// 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 = false);
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files. Searches all locations in order for first filename using ext filter list.
|
||||
// Input: filename - Filename & extension
|
||||
// ext_num - number of extensions to look for
|
||||
// ext_list - extension filter list
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string length that should be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (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 = 0, char *pack_filename = NULL, int *size = NULL, int *offset = NULL, bool localize = false);
|
||||
|
||||
// Functions to change directories
|
||||
int cfile_chdir(char *dir);
|
||||
|
||||
|
||||
@@ -9,14 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/CFile/CfileArchive.cpp $
|
||||
* $Revision: 2.7 $
|
||||
* $Date: 2005-07-24 18:31:17 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.8 $
|
||||
* $Date: 2006-12-28 00:59:19 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Low-level code for reading data out of large archive files or normal files. All
|
||||
* reads/seeks come through here.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.7 2005/07/24 18:31:17 taylor
|
||||
* little 64-bit strangeness (longs are 64-bit here rather than 32)
|
||||
*
|
||||
* Revision 2.6 2004/07/26 20:47:25 Kazan
|
||||
* remove MCD complete
|
||||
*
|
||||
@@ -112,6 +115,7 @@
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "cfile/cfilearchive.h"
|
||||
#include "luaconf.h"
|
||||
|
||||
|
||||
|
||||
@@ -308,3 +312,29 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
|
||||
}
|
||||
|
||||
int cfread_lua_number(double *buf, CFILE *cfile)
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
Assert(buf != NULL);
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
|
||||
Cfile_block *cb;
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// cfread() not supported for memory-mapped files
|
||||
Assert( !cb->data );
|
||||
Assert(cb->fp != NULL);
|
||||
|
||||
long orig_pos = ftell(cb->fp);
|
||||
int items_read = fscanf(cb->fp, LUA_NUMBER_SCAN, buf);
|
||||
cb->raw_position += ftell(cb->fp)-orig_pos;
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int tmp_offset;
|
||||
tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return items_read;
|
||||
|
||||
}
|
||||
@@ -9,13 +9,19 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/CFile/CfileList.cpp $
|
||||
* $Revision: 2.6 $
|
||||
* $Date: 2005-01-31 23:27:51 $
|
||||
* $Revision: 2.8 $
|
||||
* $Date: 2007-05-20 02:51:08 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Code for doing directory lists and sorts
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.7 2006/08/20 00:45:10 taylor
|
||||
* "byte" was the same as "ubyte", but since "byte" has to be an extra #define on everything but Windows, lets just get rid of it
|
||||
*
|
||||
* Revision 2.6 2005/01/31 23:27:51 taylor
|
||||
* merge with Linux/OSX tree - p0131-2
|
||||
*
|
||||
* Revision 2.5 2004/07/26 20:47:25 Kazan
|
||||
* remove MCD complete
|
||||
*
|
||||
@@ -161,14 +167,22 @@ void cf_sort_filenames( int n, char **list, int sort, file_list_info *info )
|
||||
} else if (sort == CF_SORT_REVERSE) {
|
||||
incr = n / 2;
|
||||
char buffer[MAX_FILENAME_LEN];
|
||||
file_list_info tt_tmp;
|
||||
|
||||
for (i = 0; i < incr; i++) {
|
||||
t = list[n - 1 - i];
|
||||
|
||||
if ( stricmp(list[i], t) > 0 ) {
|
||||
if (list[i] != t) {
|
||||
strcpy(buffer, list[i]);
|
||||
strcpy(list[i], t);
|
||||
strcpy(t, buffer);
|
||||
|
||||
if (info) {
|
||||
tt = info[n - 1 - i];
|
||||
tt_tmp = info[i];
|
||||
info[i] = tt;
|
||||
tt = tt_tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +378,7 @@ int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
|
||||
while(1) {
|
||||
|
||||
byte count;
|
||||
ubyte count;
|
||||
|
||||
if ( cfread( &count, 1, 1, cfile ) != 1 ) {
|
||||
break;
|
||||
@@ -377,7 +391,7 @@ int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
if ( count > 0 ) {
|
||||
if ( run_span ) {
|
||||
// RLE'd data
|
||||
byte c;
|
||||
ubyte c;
|
||||
if ( cfread( &c, 1, 1, cfile ) != 1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
+501
-102
@@ -9,8 +9,8 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/CFile/CfileSystem.cpp $
|
||||
* $Revision: 2.34 $
|
||||
* $Date: 2006-04-16 05:28:10 $
|
||||
* $Revision: 2.41 $
|
||||
* $Date: 2007-05-28 19:45:14 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Functions to keep track of and find files that can exist
|
||||
@@ -20,6 +20,39 @@
|
||||
* all those locations, inherently enforcing precedence orders.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.40 2007/04/11 18:24:27 taylor
|
||||
* cleanup of chksum stuff (works properly on 64-bit systems now)
|
||||
* add chksum support for VPs, both a startup in debug builds, and via cmdline option (-verify_vps)
|
||||
* little cleanup in cmdline.cpp (get rid of the remaining "fix bugs" crap)
|
||||
*
|
||||
* Revision 2.39 2007/03/22 20:22:24 taylor
|
||||
* a little better error handling for cf_exists_full()
|
||||
* add a cf_exists_full_ext() which can find a series of extensions and returns true if any of them exist
|
||||
* use cf_exists_full_ext() for eventmusic file checks (to check for ogg and wav)
|
||||
* get rid of SPM hack, it's wrong (just commented out for now though)
|
||||
* fix a bunch of bugs in cf_find_file_location_ext():
|
||||
* - try to handle files with multiple periods a bit better (for the wav files like: blah_1.5.wav)
|
||||
* - load issue with finding incorrect files by mistake
|
||||
* - prevent finding different file types in various paths/roots
|
||||
*
|
||||
* Revision 2.38 2007/02/09 23:57:24 taylor
|
||||
* add the number of files that CFILE is going to try and use in each root to the debug info
|
||||
* optimizations for cf_find_file_location_ext()
|
||||
*
|
||||
* Revision 2.37 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.36 2006/09/11 05:49:05 taylor
|
||||
* various small cleanup and speedup changes
|
||||
* add a cf_find_file_location_ext() function, which you can pass a filename and a list of extensions and it will search for all of them at once
|
||||
*
|
||||
* Revision 2.35 2006/07/28 02:36:07 taylor
|
||||
* include CF_TYPE_PLAYERS in special pilot path consideration, prevents moddirs from always getting and empty data/players/
|
||||
*
|
||||
* Revision 2.34 2006/04/16 05:28:10 taylor
|
||||
* extra safety check when creating a default path string, filename is optional be we need to available if root0 is missing (CFILE not initted yet)
|
||||
* fix that crazy compiler<->constructor<->linker<->server.txt deal caused by some bad code and a freaky link thing in freespace.cpp
|
||||
*
|
||||
* Revision 2.33 2005/12/28 22:06:47 taylor
|
||||
* fix up cf_find_file_location() and related elements so that it's safer (based on WMC's work, but actually safe this time ;))
|
||||
*
|
||||
@@ -220,10 +253,13 @@
|
||||
* $NoKeywords: $
|
||||
*/
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
@@ -465,30 +501,29 @@ void cf_build_pack_list( cf_root *root )
|
||||
|
||||
// determine how many packfiles there are
|
||||
temp_root_count = cf_get_packfile_count(root);
|
||||
if(temp_root_count <= 0){
|
||||
|
||||
if (temp_root_count <= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate a temporary array of temporary roots so we can easily sort them
|
||||
temp_roots_sort = (cf_root_sort*)vm_malloc(sizeof(cf_root_sort) * temp_root_count);
|
||||
if(temp_roots_sort == NULL){
|
||||
|
||||
if (temp_roots_sort == NULL) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
// now just setup all the root info
|
||||
root_index = 0;
|
||||
for (i=CF_TYPE_ROOT; i<CF_MAX_PATH_TYPES; i++ ) {
|
||||
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
|
||||
strcpy( filespec, root->path );
|
||||
|
||||
if(strlen(Pathtypes[i].path)) {
|
||||
if ( strlen(Pathtypes[i].path) ) {
|
||||
strcat( filespec, Pathtypes[i].path );
|
||||
if ( filespec[strlen(filespec)-1] != DIR_SEPARATOR_CHAR ) {
|
||||
strcat( filespec, DIR_SEPARATOR_STR );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( filespec[strlen(filespec)-1] != DIR_SEPARATOR_CHAR )
|
||||
strcat( filespec, DIR_SEPARATOR_STR );
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
strcat( filespec, "*.vp" );
|
||||
@@ -528,15 +563,19 @@ void cf_build_pack_list( cf_root *root )
|
||||
#elif defined SCP_UNIX
|
||||
strcat( filespec, "*.[vV][pP]" );
|
||||
glob_t globinfo;
|
||||
|
||||
memset(&globinfo, 0, sizeof(globinfo));
|
||||
|
||||
int status = glob(filespec, 0, NULL, &globinfo);
|
||||
|
||||
if (status == 0) {
|
||||
for (unsigned int j = 0; j < globinfo.gl_pathc; j++) {
|
||||
for (uint j = 0; j < globinfo.gl_pathc; j++) {
|
||||
// Determine if this is a regular file
|
||||
struct stat statbuf;
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
stat(globinfo.gl_pathv[j], &statbuf);
|
||||
if (S_ISREG(statbuf.st_mode)) {
|
||||
|
||||
if ( S_ISREG(statbuf.st_mode) ) {
|
||||
Assert(root_index < temp_root_count);
|
||||
|
||||
// get a temp pointer
|
||||
@@ -548,23 +587,30 @@ void cf_build_pack_list( cf_root *root )
|
||||
rptr_sort->cf_type = i;
|
||||
}
|
||||
}
|
||||
|
||||
globfree(&globinfo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// these should always be the same
|
||||
Assert(root_index == temp_root_count);
|
||||
|
||||
// sort tht roots
|
||||
qsort(temp_roots_sort, temp_root_count, sizeof(cf_root_sort), cf_packfile_sort_func);
|
||||
// sort the roots
|
||||
qsort(temp_roots_sort, temp_root_count, sizeof(cf_root_sort), cf_packfile_sort_func);
|
||||
|
||||
// now insert them all into the real root list properly
|
||||
cf_root *new_root;
|
||||
for(i=0; i<temp_root_count; i++){
|
||||
for (i = 0; i < temp_root_count; i++) {
|
||||
new_root = cf_create_root();
|
||||
strcpy( new_root->path, root->path );
|
||||
|
||||
#ifndef NDEBUG
|
||||
uint chksum = 0;
|
||||
cf_chksum_pack(temp_roots_sort[i].path, &chksum);
|
||||
mprintf(("Found root pack '%s' with a checksum of 0x%08x\n", temp_roots_sort[i].path, chksum));
|
||||
#endif
|
||||
|
||||
// mwa -- 4/2/98 put in the next 2 lines because the path name needs to be there
|
||||
// to find the files.
|
||||
strcpy(new_root->path, temp_roots_sort[i].path);
|
||||
@@ -724,10 +770,11 @@ int is_ext_in_list( char *ext_list, char *ext )
|
||||
void cf_search_root_path(int root_index)
|
||||
{
|
||||
int i;
|
||||
int num_files = 0;
|
||||
|
||||
cf_root *root = cf_get_root(root_index);
|
||||
|
||||
mprintf(( "Searching root '%s'\n", root->path ));
|
||||
mprintf(( "Searching root '%s' ... ", root->path ));
|
||||
|
||||
char search_path[CF_MAX_PATHNAME_LENGTH];
|
||||
|
||||
@@ -772,8 +819,8 @@ void cf_search_root_path(int root_index)
|
||||
file->size = find.size;
|
||||
file->pack_offset = 0; // Mark as a non-packed file
|
||||
|
||||
num_files++;
|
||||
//mprintf(( "Found file '%s'\n", file->name_ext ));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -822,6 +869,7 @@ void cf_search_root_path(int root_index)
|
||||
|
||||
file->pack_offset = 0; // Mark as a non-packed file
|
||||
|
||||
num_files++;
|
||||
//mprintf(( "Found file '%s'\n", file->name_ext ));
|
||||
}
|
||||
}
|
||||
@@ -831,6 +879,8 @@ void cf_search_root_path(int root_index)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mprintf(( "%i files\n", num_files ));
|
||||
}
|
||||
|
||||
|
||||
@@ -849,11 +899,11 @@ typedef struct VP_FILE {
|
||||
} VP_FILE;
|
||||
|
||||
void cf_search_root_pack(int root_index)
|
||||
{
|
||||
{
|
||||
int num_files = 0;
|
||||
cf_root *root = cf_get_root(root_index);
|
||||
|
||||
Assert( root != NULL );
|
||||
mprintf(( "Searching root pack '%s'\n", root->path ));
|
||||
|
||||
// Open data
|
||||
FILE *fp = fopen( root->path, "rb" );
|
||||
@@ -862,6 +912,8 @@ void cf_search_root_pack(int root_index)
|
||||
return;
|
||||
}
|
||||
|
||||
mprintf(( "Searching root pack '%s' ... ", root->path ));
|
||||
|
||||
VP_FILE_HEADER VP_header;
|
||||
|
||||
Assert( sizeof(VP_header) == 16 );
|
||||
@@ -923,6 +975,8 @@ void cf_search_root_pack(int root_index)
|
||||
file->write_time = (time_t)find.write_time;
|
||||
file->size = find.size;
|
||||
file->pack_offset = find.offset; // Mark as a packed file
|
||||
|
||||
num_files++;
|
||||
//mprintf(( "Found pack file '%s'\n", file->name_ext ));
|
||||
}
|
||||
}
|
||||
@@ -930,8 +984,10 @@ void cf_search_root_pack(int root_index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
|
||||
mprintf(( "%i files\n", num_files ));
|
||||
}
|
||||
|
||||
|
||||
@@ -1020,12 +1076,15 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
{
|
||||
int i;
|
||||
int cfs_slow_search = 0;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
Assert(filespec && strlen(filespec));
|
||||
#if defined WIN32
|
||||
long findhandle;
|
||||
_finddata_t findstruct;
|
||||
#endif
|
||||
|
||||
if ( pack_filename != NULL ) {
|
||||
Assert( max_out > 1 );
|
||||
}
|
||||
Assert( (filespec != NULL) && (strlen(filespec) > 0) );
|
||||
Assert( (pack_filename == NULL) || (max_out > 1) );
|
||||
|
||||
// see if we have something other than just a filename
|
||||
// our current rules say that any file that specifies a direct
|
||||
@@ -1059,23 +1118,19 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
|
||||
if ( CF_TYPE_SPECIFIED(pathtype) ) {
|
||||
search_order[num_search_dirs++] = pathtype;
|
||||
}
|
||||
|
||||
for (i=CF_TYPE_ROOT; i<CF_MAX_PATH_TYPES; i++) {
|
||||
if ( i != pathtype ) {
|
||||
search_order[num_search_dirs++] = i;
|
||||
} else {
|
||||
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
|
||||
if (i != pathtype)
|
||||
search_order[num_search_dirs++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined WIN32
|
||||
long findhandle;
|
||||
_finddata_t findstruct;
|
||||
#endif
|
||||
memset( longname, 0, sizeof(longname) );
|
||||
|
||||
|
||||
for (i=0; i<num_search_dirs; i++ ) {
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
switch (search_order[i]) {
|
||||
switch (search_order[i])
|
||||
{
|
||||
case CF_TYPE_ROOT:
|
||||
case CF_TYPE_DATA:
|
||||
case CF_TYPE_SINGLE_PLAYERS:
|
||||
@@ -1087,7 +1142,8 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
break;
|
||||
|
||||
default:
|
||||
cfs_slow_search = 0;
|
||||
// always hit the disk if we are looking in only one path
|
||||
cfs_slow_search = (num_search_dirs == 1) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1095,120 +1151,112 @@ 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
|
||||
if(!Cmdline_safeloading)
|
||||
{
|
||||
if (!Cmdline_safeloading) {
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if ( size ) {
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
}
|
||||
|
||||
_findclose(findhandle);
|
||||
|
||||
if ( offset ) *offset = 0;
|
||||
if ( pack_filename ) {
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
if (pack_filename)
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
};
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
FILE *fp = fopen(longname, "rb" );
|
||||
if(fp) {
|
||||
if( size ) {
|
||||
|
||||
if (fp) {
|
||||
if (size)
|
||||
*size = filelength( fileno(fp) );
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(offset) *offset = 0;
|
||||
if( pack_filename ) {
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
if (pack_filename)
|
||||
strncpy(pack_filename, longname, max_out);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#elif defined SCP_UNIX
|
||||
FILE *fp = fopen(longname, "rb" );
|
||||
if (fp) {
|
||||
if ( size ) {
|
||||
struct stat statbuf;
|
||||
fstat(fileno(fp), &statbuf);
|
||||
*size = statbuf.st_size;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if ( offset ) *offset = 0;
|
||||
if ( pack_filename ) {
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Search the pak files and CD-ROM.
|
||||
|
||||
for (i=0; i<Num_files; i++ ) {
|
||||
cf_file * f = cf_get_file(i);
|
||||
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) ) {
|
||||
if ( (pathtype != CF_TYPE_ANY) && (pathtype != f->pathtype_index) )
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (localize) {
|
||||
// create localized filespec
|
||||
char filespec_tmp[MAX_PATH_LEN] = { 0 };
|
||||
strncpy(filespec_tmp, filespec, MAX_PATH_LEN - 1);
|
||||
strncpy(longname, filespec, MAX_PATH_LEN - 1);
|
||||
|
||||
if(lcl_add_dir_to_path_with_filename(filespec_tmp, MAX_PATH_LEN - 1))
|
||||
{
|
||||
if ( !stricmp(filespec_tmp, f->name_ext) ) {
|
||||
if ( size ) *size = f->size;
|
||||
if ( offset ) *offset = f->pack_offset;
|
||||
if ( pack_filename ) {
|
||||
cf_root * r = cf_get_root(f->root_index);
|
||||
if ( lcl_add_dir_to_path_with_filename(longname, MAX_PATH_LEN - 1) ) {
|
||||
if ( !stricmp(longname, f->name_ext) ) {
|
||||
if (size)
|
||||
*size = f->size;
|
||||
|
||||
if (offset)
|
||||
*offset = f->pack_offset;
|
||||
|
||||
if (pack_filename) {
|
||||
cf_root *r = cf_get_root(f->root_index);
|
||||
|
||||
strncpy( pack_filename, r->path, max_out );
|
||||
if ( f->pack_offset < 1 ) {
|
||||
|
||||
if (f->pack_offset < 1) {
|
||||
SAFE_STRCAT( pack_filename, Pathtypes[f->pathtype_index].path, max_out );
|
||||
if ( pack_filename[strlen(pack_filename)-1] != DIR_SEPARATOR_CHAR ) {
|
||||
|
||||
if ( pack_filename[strlen(pack_filename)-1] != DIR_SEPARATOR_CHAR )
|
||||
SAFE_STRCAT( pack_filename, DIR_SEPARATOR_STR, max_out );
|
||||
}
|
||||
|
||||
SAFE_STRCAT( pack_filename, f->name_ext, max_out );
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// file either not localized or localized version not found
|
||||
if ( !stricmp(filespec, f->name_ext) ) {
|
||||
if ( size ) *size = f->size;
|
||||
if ( offset ) *offset = f->pack_offset;
|
||||
if ( pack_filename ) {
|
||||
cf_root * r = cf_get_root(f->root_index);
|
||||
if ( !stricmp(filespec, f->name_ext) ) {
|
||||
if (size)
|
||||
*size = f->size;
|
||||
|
||||
if (offset)
|
||||
*offset = f->pack_offset;
|
||||
|
||||
if (pack_filename) {
|
||||
cf_root *r = cf_get_root(f->root_index);
|
||||
|
||||
strcpy( pack_filename, r->path );
|
||||
if ( f->pack_offset < 1 ) {
|
||||
|
||||
if(strlen(Pathtypes[f->pathtype_index].path)){
|
||||
if (f->pack_offset < 1) {
|
||||
if ( strlen(Pathtypes[f->pathtype_index].path) ) {
|
||||
SAFE_STRCAT( pack_filename, Pathtypes[f->pathtype_index].path, max_out );
|
||||
if ( pack_filename[strlen(pack_filename)-1] != DIR_SEPARATOR_CHAR ) {
|
||||
|
||||
if ( pack_filename[strlen(pack_filename)-1] != DIR_SEPARATOR_CHAR )
|
||||
SAFE_STRCAT( pack_filename, DIR_SEPARATOR_STR, max_out );
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_STRCAT( pack_filename, f->name_ext, max_out );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1216,6 +1264,302 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- from parselo.cpp --
|
||||
extern char *stristr(const char *str, const char *substr);
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files. Searches all locations in order for first filename using filter list.
|
||||
// Input: filename - Filename & extension
|
||||
// ext_num - number of extensions to look for
|
||||
// ext_list - extension filter list
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string length that should be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (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 )
|
||||
{
|
||||
int i, cur_ext;
|
||||
int cfs_slow_search = 0;
|
||||
char longname[MAX_PATH_LEN];
|
||||
char filespec[MAX_FILENAME_LEN];
|
||||
|
||||
#if defined WIN32
|
||||
long findhandle;
|
||||
_finddata_t findstruct;
|
||||
#endif
|
||||
|
||||
Assert( (filename != NULL) && (strlen(filename) < MAX_FILENAME_LEN) );
|
||||
Assert( (ext_list != NULL) && (ext_num > 1) ); // if we are searching for just one ext
|
||||
// then this is the wrong function to use
|
||||
Assert( (pack_filename == NULL) || (max_out > 1) );
|
||||
|
||||
|
||||
// if we have a full path already then fail. this function if for searching via filter only!
|
||||
#ifdef SCP_UNIX
|
||||
if ( strpbrk(filename, "/") ) { // do we have a full path already?
|
||||
#else
|
||||
if ( strpbrk(filename,"/\\:") ) { // do we have a full path already?
|
||||
#endif
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Search the hard drive for files first.
|
||||
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 (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
|
||||
search_order[num_search_dirs++] = i;
|
||||
}
|
||||
|
||||
memset( longname, 0, sizeof(longname) );
|
||||
memset( filespec, 0, sizeof(filespec) );
|
||||
|
||||
// strip any existing extension
|
||||
strncpy(filespec, filename, MAX_FILENAME_LEN-1);
|
||||
|
||||
for (i = 0; i < num_search_dirs; i++) {
|
||||
// always hit the disk if we are looking in only one path
|
||||
if (num_search_dirs == 1) {
|
||||
cfs_slow_search = 1;
|
||||
}
|
||||
// otherwise hit based on a directory type
|
||||
else {
|
||||
switch (search_order[i])
|
||||
{
|
||||
case CF_TYPE_ROOT:
|
||||
case CF_TYPE_DATA:
|
||||
case CF_TYPE_SINGLE_PLAYERS:
|
||||
case CF_TYPE_MULTI_PLAYERS:
|
||||
case CF_TYPE_MULTI_CACHE:
|
||||
case CF_TYPE_MISSIONS:
|
||||
case CF_TYPE_CACHE:
|
||||
cfs_slow_search = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !cfs_slow_search )
|
||||
continue;
|
||||
|
||||
for (cur_ext = 0; cur_ext < ext_num; cur_ext++) {
|
||||
// strip any extension and add the one we want to check for
|
||||
// (NOTE: to be fully retail compatible, we need to support multiple periods for something like *_1.5.wav,
|
||||
// which means that we need to strip a length of >2 only, assuming that all valid ext are at least 2 chars)
|
||||
char *p = strrchr(filespec, '.');
|
||||
if ( p && (strlen(p) > 2) )
|
||||
(*p) = 0;
|
||||
|
||||
SAFE_STRCAT( filespec, ext_list[cur_ext], sizeof(filespec)-1 );
|
||||
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
|
||||
|
||||
#if defined _WIN32
|
||||
if (!Cmdline_safeloading) {
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
|
||||
_findclose(findhandle);
|
||||
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
if (pack_filename)
|
||||
strncpy( pack_filename, longname, max_out );
|
||||
|
||||
return cur_ext;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
FILE *fp = fopen(longname, "rb" );
|
||||
|
||||
if (fp) {
|
||||
if (size)
|
||||
*size = filelength( fileno(fp) );
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
if (pack_filename)
|
||||
strncpy(pack_filename, longname, max_out);
|
||||
|
||||
return cur_ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search the pak files and CD-ROM.
|
||||
|
||||
// first off, make sure that we don't have an extension
|
||||
// (NOTE: to be fully retail compatible, we need to support multiple periods for something like *_1.5.wav,
|
||||
// which means that we need to strip a length of >2 only, assuming that all valid ext are at least 2 chars)
|
||||
char *p = strrchr(filespec, '.');
|
||||
if ( p && (strlen(p) > 2) )
|
||||
(*p) = 0;
|
||||
|
||||
// go ahead and get our length, which is used to test with later
|
||||
int filespec_len = strlen(filespec);
|
||||
|
||||
// get total legnth, with extension, which is iused to test with later
|
||||
// (FIXME: this assumes that everything in ext_list[] is the same length!)
|
||||
uint filespec_len_big = filespec_len + strlen(ext_list[0]);
|
||||
|
||||
std::vector<int> file_list_index;
|
||||
int last_root_index = -1;
|
||||
int last_path_index = -1;
|
||||
|
||||
// next, run though and pick out base matches
|
||||
for (i = 0; i < Num_files; i++) {
|
||||
cf_file *f = cf_get_file(i);
|
||||
|
||||
// ... only search paths that we're supposed to
|
||||
if ( (pathtype != CF_TYPE_ANY) && (pathtype != f->pathtype_index) )
|
||||
continue;
|
||||
|
||||
// ... check that our names are the same length (accounting for the missing extension on our own name)
|
||||
if ( strlen(f->name_ext) != filespec_len_big )
|
||||
continue;
|
||||
|
||||
// ... check that we match the base filename
|
||||
if ( strnicmp(f->name_ext, filespec, filespec_len) )
|
||||
continue;
|
||||
|
||||
// ... make sure that it's one of our supported types
|
||||
bool found_one = false;
|
||||
for (cur_ext = 0; cur_ext < ext_num; cur_ext++) {
|
||||
if ( stristr(f->name_ext, ext_list[cur_ext]) ) {
|
||||
found_one = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found_one )
|
||||
continue;
|
||||
|
||||
// ... we check based on location, so if location changes after the first find then bail
|
||||
if (last_root_index < 0) {
|
||||
last_root_index = f->root_index;
|
||||
last_path_index = f->pathtype_index;
|
||||
} else {
|
||||
if (f->root_index != last_root_index)
|
||||
break;
|
||||
|
||||
if (f->pathtype_index != last_path_index)
|
||||
break;
|
||||
}
|
||||
|
||||
// ok, we have a good base match, so add it to our cache
|
||||
file_list_index.push_back( i );
|
||||
}
|
||||
|
||||
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 (i = 0; i < file_list_size; i++) {
|
||||
cf_file *f = cf_get_file( file_list_index[i] );
|
||||
|
||||
SAFE_STRCAT( filespec, ext_list[cur_ext], sizeof(filespec)-1 );
|
||||
|
||||
if (localize) {
|
||||
// create localized filespec
|
||||
strncpy(longname, filespec, MAX_PATH_LEN - 1);
|
||||
|
||||
if ( lcl_add_dir_to_path_with_filename(longname, MAX_PATH_LEN - 1) ) {
|
||||
if ( !stricmp(longname, f->name_ext) ) {
|
||||
if (size)
|
||||
*size = f->size;
|
||||
|
||||
if (offset)
|
||||
*offset = f->pack_offset;
|
||||
|
||||
if (pack_filename) {
|
||||
cf_root *r = cf_get_root(f->root_index);
|
||||
|
||||
strncpy( pack_filename, r->path, max_out );
|
||||
|
||||
if (f->pack_offset < 1) {
|
||||
SAFE_STRCAT( pack_filename, Pathtypes[f->pathtype_index].path, max_out );
|
||||
|
||||
if ( pack_filename[strlen(pack_filename)-1] != DIR_SEPARATOR_CHAR )
|
||||
SAFE_STRCAT( pack_filename, DIR_SEPARATOR_STR, max_out );
|
||||
|
||||
SAFE_STRCAT( pack_filename, f->name_ext, max_out );
|
||||
}
|
||||
}
|
||||
|
||||
// found it, so cleanup and return
|
||||
file_list_index.clear();
|
||||
|
||||
return cur_ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// file either not localized or localized version not found
|
||||
if ( !stricmp(filespec, f->name_ext) ) {
|
||||
if (size)
|
||||
*size = f->size;
|
||||
|
||||
if (offset)
|
||||
*offset = f->pack_offset;
|
||||
|
||||
if (pack_filename) {
|
||||
cf_root *r = cf_get_root(f->root_index);
|
||||
|
||||
strcpy( pack_filename, r->path );
|
||||
|
||||
if (f->pack_offset < 1) {
|
||||
|
||||
if ( strlen(Pathtypes[f->pathtype_index].path) ) {
|
||||
SAFE_STRCAT( pack_filename, Pathtypes[f->pathtype_index].path, max_out );
|
||||
|
||||
if ( pack_filename[strlen(pack_filename)-1] != DIR_SEPARATOR_CHAR )
|
||||
SAFE_STRCAT( pack_filename, DIR_SEPARATOR_STR, max_out );
|
||||
}
|
||||
|
||||
SAFE_STRCAT( pack_filename, f->name_ext, max_out );
|
||||
}
|
||||
}
|
||||
|
||||
// found it, so cleanup and return
|
||||
file_list_index.clear();
|
||||
|
||||
return cur_ext;
|
||||
}
|
||||
|
||||
// ok, we're still here, so strip off the extension again in order to
|
||||
// prepare for the next run
|
||||
char *p = strrchr(filespec, '.');
|
||||
if ( p && (strlen(p) > 2) )
|
||||
(*p) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Bail:
|
||||
// didn't find anything, bail...
|
||||
file_list_index.clear();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Returns true if filename matches filespec, else zero if not
|
||||
int cf_matches_spec(char *filespec, char *filename)
|
||||
@@ -1499,7 +1843,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
// Search the default directories
|
||||
#if defined _WIN32
|
||||
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, filter );
|
||||
mprintf(("cf_get_file_list_preallocated looking for type=%d, filter=\"%s\"\n",
|
||||
mprintf(("CFILE: cf_get_file_list_preallocated looking for type=%d, filter=\"%s\"\n",
|
||||
pathtype, filter));
|
||||
|
||||
int find_handle;
|
||||
@@ -1513,6 +1857,9 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
|
||||
if (!(find.attrib & _A_SUBDIR)) {
|
||||
|
||||
if ( strlen(find.name) >= MAX_FILENAME_LEN )
|
||||
continue;
|
||||
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(find.name) ) {
|
||||
|
||||
strncpy(arr[num_files], find.name, MAX_FILENAME_LEN - 1 );
|
||||
@@ -1563,6 +1910,10 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( strlen(dir->d_name) >= MAX_FILENAME_LEN ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(dir->d_name) ) {
|
||||
|
||||
strncpy(arr[num_files], dir->d_name, MAX_FILENAME_LEN - 1 );
|
||||
@@ -1670,7 +2021,7 @@ int cf_create_default_path_string( char *path, uint path_max, int pathtype, char
|
||||
Assert(CF_TYPE_SPECIFIED(pathtype));
|
||||
|
||||
// force a specific directory to search for player files
|
||||
if ( (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
|
||||
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
|
||||
strncpy(path, Pilot_file_path, path_max);
|
||||
} else {
|
||||
strncpy(path, root->path, path_max);
|
||||
@@ -1718,3 +2069,51 @@ int cf_create_default_path_string( char *path, uint path_max, int pathtype, char
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cfile_spew_pack_file_crcs()
|
||||
{
|
||||
int i;
|
||||
char out_path[CFILE_ROOT_DIRECTORY_LEN+MAX_FILENAME_LEN];
|
||||
char datetime[45];
|
||||
uint chksum = 0;
|
||||
time_t my_time;
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
sprintf(out_path, "%s%svp_crcs.txt", Cfile_user_dir, DIR_SEPARATOR_STR);
|
||||
#else
|
||||
sprintf(out_path, "%s%svp_crcs.txt", Cfile_root_dir, DIR_SEPARATOR_STR);
|
||||
#endif
|
||||
|
||||
FILE *out = fopen(out_path, "w");
|
||||
|
||||
if (out == NULL) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
my_time = time(NULL);
|
||||
|
||||
memset( datetime, 0, sizeof(datetime) );
|
||||
snprintf(datetime, sizeof(datetime)-1, "%s", ctime(&my_time));
|
||||
// ctime() adds a newline char, so we have to strip it off
|
||||
datetime[strlen(datetime)-1] = '\0';
|
||||
|
||||
fprintf(out, "Pack file CRC log (%s) ... \n", datetime);
|
||||
fprintf(out, "-------------------------------------------------------------------------------\n");
|
||||
|
||||
for (i = 0; i < Num_roots; i++) {
|
||||
cf_root *cur_root = cf_get_root(i);
|
||||
|
||||
if (cur_root->roottype != CF_ROOTTYPE_PACK)
|
||||
continue;
|
||||
|
||||
chksum = 0;
|
||||
cf_chksum_pack(cur_root->path, &chksum, true);
|
||||
|
||||
fprintf(out, " %s -- 0x%x\n", cur_root->path, chksum);
|
||||
}
|
||||
|
||||
fprintf(out, "-------------------------------------------------------------------------------\n");
|
||||
|
||||
fclose(out);
|
||||
}
|
||||
@@ -9,13 +9,16 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Cfilearchiver/CfileArchiver.cpp $
|
||||
* $Revision: 2.4 $
|
||||
* $Date: 2005-11-13 06:38:04 $
|
||||
* $Revision: 2.5 $
|
||||
* $Date: 2007-05-11 03:09:09 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Program to create an archive file for use with cfile stuff
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.4 2005/11/13 06:38:04 taylor
|
||||
* never did port this stupid thing to PPC
|
||||
*
|
||||
* Revision 2.3 2005/09/08 00:09:31 taylor
|
||||
* fix building/linking of command line tools under Linux/OSX
|
||||
* add tools as targets to OSX project file
|
||||
@@ -134,6 +137,8 @@ int write_index(char *hf, char *df)
|
||||
fclose(h);
|
||||
fclose(d);
|
||||
|
||||
unlink(hf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+225
-198
@@ -9,11 +9,77 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Cmdline/cmdline.cpp $
|
||||
* $Revision: 2.140 $
|
||||
* $Date: 2006-05-27 17:18:56 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.158 $
|
||||
* $Date: 2008-01-19 00:27:41 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.157 2007/08/17 03:29:44 Goober5000
|
||||
* generalize the way radar ranges are handled (inspired by Shade's fix)
|
||||
*
|
||||
* Revision 2.156 2007/07/29 03:11:01 Goober5000
|
||||
* allow embedded dashes in command-line options
|
||||
*
|
||||
* Revision 2.155 2007/06/24 18:04:23 karajorma
|
||||
* Fix an issue with single character command line arguments
|
||||
*
|
||||
* Revision 2.154 2007/05/28 19:46:30 taylor
|
||||
* oops! the exit() was supposed to come /after/ the last printf() :)
|
||||
*
|
||||
* Revision 2.153 2007/05/25 13:58:02 taylor
|
||||
* make Linux just verbally ignore invalid cmdline options rather than it being fatal
|
||||
*
|
||||
* Revision 2.152 2007/04/17 17:26:35 karajorma
|
||||
* Remove the -fredhtl command line.
|
||||
*
|
||||
* Revision 2.151 2007/04/11 18:24:27 taylor
|
||||
* cleanup of chksum stuff (works properly on 64-bit systems now)
|
||||
* add chksum support for VPs, both a startup in debug builds, and via cmdline option (-verify_vps)
|
||||
* little cleanup in cmdline.cpp (get rid of the remaining "fix bugs" crap)
|
||||
*
|
||||
* Revision 2.150 2007/03/22 20:55:53 taylor
|
||||
* forgot to remove -jpgtga from Launcher options previously
|
||||
* get rid of -fixbugs and -nocrash crap
|
||||
*
|
||||
* Revision 2.149 2007/01/10 01:40:43 taylor
|
||||
* little bit of cleanup
|
||||
* per earlier discussions: remove -jpgtga and -pcx32
|
||||
*
|
||||
* Revision 2.148 2006/11/16 00:50:00 taylor
|
||||
* clean up some cmdline options which were/weren't FSO only
|
||||
* add back the "-32bit" option, for retail compatibility (doesn't do anything, it's just there to avoid the unknown option message)
|
||||
* add "-debug_window" to turn on the Windows-only extra debug output window (it's off by default now, only logging to file instead)
|
||||
*
|
||||
* Revision 2.147 2006/09/11 05:31:11 taylor
|
||||
* minor spelling/grammer fixes
|
||||
*
|
||||
* Revision 2.146 2006/09/08 06:20:14 taylor
|
||||
* fix things that strict compiling balked at (from compiling with -ansi and -pedantic)
|
||||
*
|
||||
* Revision 2.145 2006/07/28 02:37:08 taylor
|
||||
* switch from Assert() to basic error fixage for end-of-string white space check
|
||||
*
|
||||
* Revision 2.144 2006/07/25 16:26:24 taylor
|
||||
* support for cmdline option stacking (a per option setting) so that things like "-mod derelict -mod mediavp" will end up as "-mod derelict,mediavp" to the game
|
||||
* fix bug where white space chars didn't get dropped from the end of a option string like they were supposed to
|
||||
* allow for something like "-ambient_factor 100 -ambient_factor 70" to use the proper value, the last one specified, rather than just accept the first instance
|
||||
*
|
||||
* Revision 2.143 2006/07/08 18:11:33 taylor
|
||||
* remove -allslev
|
||||
* make CTRL-SHIFT-S hotkey work in mission simulator (it's a toggle, so you can turn it on or off while on the screen)
|
||||
* fix a bug where blank lines would show up in the campaign list for branch/alternate type missions that are otherwise marked as not completed
|
||||
*
|
||||
* Revision 2.142 2006/06/27 04:55:53 taylor
|
||||
* add -disable_fbo to troubleshoot crappy ATI drivers
|
||||
* remove the temporary -alpha_alpha_blend option
|
||||
* tack on an extra byte to the flags.lch file so that the launcher can easily detect if it's an OpenAL build or not
|
||||
*
|
||||
* Revision 2.141 2006/06/15 00:37:11 taylor
|
||||
* remove previous attempts at the Y bug fix, it's now back to the retail code for that
|
||||
*
|
||||
* Revision 2.140 2006/05/27 17:18:56 taylor
|
||||
* d'oh! that was supposed to be off by default!
|
||||
*
|
||||
* Revision 2.139 2006/05/27 17:17:57 taylor
|
||||
* few things:
|
||||
* - comment out that -fixbugs and -nocrash crap, that's just stupid
|
||||
@@ -345,10 +411,6 @@
|
||||
* and glow points,
|
||||
* and other stuff
|
||||
*
|
||||
* Revision 2.56 2004/02/20 21:58:07 randomtiger
|
||||
* Added * to - conversion for start mission code to allow launcher missions with '-' in them.
|
||||
* Currently the parsing code counts that as a flag and messes it up.
|
||||
*
|
||||
* Revision 2.55 2004/02/20 21:45:40 randomtiger
|
||||
* Removed some uneeded code between NO_DIRECT3D and added gr_zbias call, ogl is set to a stub func.
|
||||
* Changed -htl param to -nohtl. Fixed some badly named functions to match convention.
|
||||
@@ -814,6 +876,7 @@
|
||||
#include "parse/sexp.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "camera/camera.h" //VIEWER_ZOOM_DEFAULT
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
@@ -837,10 +900,11 @@ public:
|
||||
cmdline_parm *next, *prev;
|
||||
char *name; // name of parameter, must start with '-' char
|
||||
char *help; // help text for this parameter
|
||||
bool stacks; // whether this arg stacks with each use or is replaced by newest use (should only be used for strings!!)
|
||||
char *args; // string value for parameter arguements (NULL if no arguements)
|
||||
int name_found; // true if parameter on command line, otherwise false
|
||||
|
||||
cmdline_parm(char *name, char *help);
|
||||
cmdline_parm(char *name, char *help, bool stacks = false);
|
||||
~cmdline_parm();
|
||||
int found();
|
||||
int get_int();
|
||||
@@ -852,7 +916,6 @@ static cmdline_parm Parm_list(NULL, NULL);
|
||||
static int Parm_list_inited = 0;
|
||||
|
||||
|
||||
extern float VIEWER_ZOOM_DEFAULT;
|
||||
extern float Viewer_zoom;
|
||||
extern int Show_framerate; // from freespace.cpp
|
||||
|
||||
@@ -870,7 +933,7 @@ enum
|
||||
|
||||
// Combos
|
||||
EASY_MEM_ALL_ON = EASY_ALL_ON | EASY_MEM_ON,
|
||||
EASY_DEFAULT_MEM = EASY_DEFAULT | EASY_MEM_OFF,
|
||||
EASY_DEFAULT_MEM = EASY_DEFAULT | EASY_MEM_OFF
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -907,8 +970,7 @@ Flag exe_params[] =
|
||||
{
|
||||
{ "-spec", "Enable specular", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
|
||||
{ "-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 evironment maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
|
||||
{ "-jpgtga", "Enable jpg,tga textures", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-jpgtga", },
|
||||
{ "-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, EASY_MEM_ALL_ON, 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",},
|
||||
{ "-2d_poof", "Stops fog intersect hull", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-2d_poof", },
|
||||
@@ -942,21 +1004,19 @@ Flag exe_params[] =
|
||||
{ "-multilog", "", false, 0, EASY_DEFAULT, "Multi", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-multilog", },
|
||||
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multi", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
|
||||
{ "-mpnoreturn", "Disables flight deck option", true, 0, EASY_DEFAULT, "Multi", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
|
||||
//#ifdef WIN32
|
||||
// { "-fixbugs", "Fix bugs", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
// { "-nocrash", "Disable crashing", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
//#endif
|
||||
{ "-oldfire", "", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-oldfire", },
|
||||
|
||||
{ "-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", },
|
||||
{ "-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", },
|
||||
{ "-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", false, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-d3d_bad_tsys", },
|
||||
{ "-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", "", },
|
||||
|
||||
{ "-alpha_env", "Use specular alpha for env mapping", true, 0, EASY_DEFAULT_MEM, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-alpha_env", },
|
||||
{ "-ingame_join", "Allows ingame joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
@@ -977,6 +1037,7 @@ Flag exe_params[] =
|
||||
{ "-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", "", },
|
||||
#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
|
||||
@@ -1003,7 +1064,7 @@ 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
|
||||
cmdline_parm timeout("-timeout", NULL); // Cmdline_timeout
|
||||
cmdline_parm window("-window", NULL); // Cmdline_window
|
||||
cmdline_parm bit32_arg("-32bit", NULL); // (only here for retail compatibility reasons, doesn't actually do anything)
|
||||
|
||||
char *Cmdline_connect_addr = NULL;
|
||||
char *Cmdline_game_name = NULL;
|
||||
@@ -1026,7 +1087,6 @@ int Cmdline_spew_pof_info = 0;
|
||||
int Cmdline_start_netgame = 0;
|
||||
int Cmdline_timeout = -1;
|
||||
int Cmdline_use_last_pilot = 0;
|
||||
int Cmdline_window = 0;
|
||||
|
||||
|
||||
// FSO options -------------------------------------------------
|
||||
@@ -1045,18 +1105,15 @@ cmdline_parm ambient_factor_arg("-ambient_factor", NULL); // Cmdline_ambient_fac
|
||||
cmdline_parm cell_arg("-cell", NULL); // Cmdline_cell
|
||||
cmdline_parm decals("-decals", NULL); // Cmdline_decals
|
||||
cmdline_parm env("-env", NULL); // Cmdline_env
|
||||
cmdline_parm jpgtga_arg("-jpgtga", NULL); // Cmdline_jpgtga
|
||||
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_noglow -- use Bobs glow code
|
||||
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
|
||||
cmdline_parm noscalevid_arg("-noscalevid", NULL); // Cmdline_noscalevid -- disable video scaling that fits to window
|
||||
cmdline_parm spec_arg("-spec", NULL); // Cmdline_nospec -- use specular highlighting -Sticks
|
||||
cmdline_parm pcx32_arg("-pcx32", NULL); // Cmdline_pcx32
|
||||
cmdline_parm noemissive_arg("-no_emissive_light", NULL); // Cmdline_no_emissive -- don't use emissive light in OGL
|
||||
cmdline_parm spec_scale_arg("-spec_scale", NULL); // Cmdline_spec_scale -- TEMPORARY - REMOVEME!!!
|
||||
cmdline_parm env_scale_arg("-env_scale", NULL); // Cmdline_env_scale -- TEMPORARY - REMOVEME!!!
|
||||
cmdline_parm alpha_alpha_blend_arg("-alpha_alpha_blend", NULL); // Cmdline_alpha_alpha_blend -- TEMPORARY - REMOVEME!!!
|
||||
|
||||
float Cmdline_clip_dist = Default_min_draw_distance;
|
||||
float Cmdline_fov = 0.75f;
|
||||
@@ -1069,16 +1126,13 @@ int Cmdline_ambient_factor = 128;
|
||||
int Cmdline_cell = 0;
|
||||
int Cmdline_decals = 0;
|
||||
int Cmdline_env = 0;
|
||||
int Cmdline_jpgtga = 0;
|
||||
int Cmdline_mipmap = 0;
|
||||
int Cmdline_missile_lighting = 0;
|
||||
int Cmdline_noglow = 1;
|
||||
int Cmdline_nomotiondebris = 0;
|
||||
int Cmdline_noscalevid = 0;
|
||||
int Cmdline_nospec = 1;
|
||||
int Cmdline_pcx32 = 0;
|
||||
int Cmdline_no_emissive = 0;
|
||||
int Cmdline_alpha_alpha_blend = 0; // TEMPORARY - REMOVEME!!!
|
||||
|
||||
// Game Speed related
|
||||
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL); // Cmdline_cache_bitmaps
|
||||
@@ -1097,7 +1151,6 @@ cmdline_parm dualscanlines_arg("-dualscanlines", NULL); // Cmdline_dualscanlines
|
||||
cmdline_parm orb_radar("-orbradar", NULL); // Cmdline_orb_radar
|
||||
cmdline_parm rearm_timer_arg("-rearm_timer", NULL); // Cmdline_rearm_timer
|
||||
cmdline_parm targetinfo_arg("-targetinfo", NULL); // Cmdline_targetinfo -- Adds ship name/class to right of target box -C
|
||||
cmdline_parm Radar_Range_Clamp("-radar_reduce", NULL);
|
||||
|
||||
int Cmdline_ballistic_gauge = 0; // WMCoolmon's gauge thingy
|
||||
int Cmdline_dualscanlines = 0;
|
||||
@@ -1124,7 +1177,7 @@ int Cmdline_snd_preload = 0; // preload game sounds during mission load
|
||||
int Cmdline_voice_recognition = 0;
|
||||
|
||||
// MOD related
|
||||
cmdline_parm mod_arg("-mod", NULL); // Cmdline_mod -- DTP modsupport
|
||||
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
|
||||
cmdline_parm tbp("-tbp", NULL); // Cmdline_tbp -- TBP warp effects -Et1
|
||||
cmdline_parm wcsaga("-wcsaga", NULL); // Cmdline_wcsaga
|
||||
|
||||
@@ -1147,7 +1200,7 @@ int Cmdline_SpewTable_CRCs = 0;
|
||||
|
||||
// Troubleshooting
|
||||
cmdline_parm d3d_lesstmem_arg("-d3d_bad_tsys", NULL); // Cmdline_d3d_lesstmem
|
||||
cmdline_parm fred2_htl_arg("-fredhtl", NULL); // Cmdline_FRED2_htl
|
||||
//cmdline_parm fred2_htl_arg("-fredhtl", NULL); // Cmdline_FRED2_htl
|
||||
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
|
||||
@@ -1155,10 +1208,11 @@ cmdline_parm nomovies_arg("-nomovies", NULL); // Cmdline_nomovies -- Allows vi
|
||||
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 ybugfix_arg("-y_bug_fix", NULL); // Cmdline_ybugfix -- Temporary... REMOVEME LATER!!
|
||||
cmdline_parm no_fbo_arg("-disable_fbo", NULL); // Cmdline_no_fbo
|
||||
cmdline_parm verify_vps_arg("-verify_vps", NULL); // Cmdline_verify_vps
|
||||
|
||||
int Cmdline_d3d_lesstmem = 0;
|
||||
int Cmdline_FRED2_htl = 0; // turn HTL on in fred - Kazan
|
||||
//int Cmdline_FRED2_htl = 0; // turn HTL on in fred - Kazan
|
||||
int Cmdline_load_all_weapons = 0;
|
||||
int Cmdline_nohtl = 0;
|
||||
int Cmdline_noibx = 0;
|
||||
@@ -1166,11 +1220,11 @@ 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_ybugfix = 0; // Temporary... REMOVEME LATER!!
|
||||
int Cmdline_no_fbo = 0;
|
||||
int Cmdline_verify_vps = 0;
|
||||
|
||||
// Developer/Testing related
|
||||
cmdline_parm start_mission_arg("-start_mission", NULL); // Cmdline_start_mission
|
||||
cmdline_parm allslev_arg("-allslev", NULL); // Cmdline_allslev -- Give access to all single player missions
|
||||
cmdline_parm dis_collisions("-dis_collisions", NULL); // Cmdline_dis_collisions
|
||||
cmdline_parm dis_weapons("-dis_weapons", NULL); // Cmdline_dis_weapons
|
||||
cmdline_parm noparseerrors_arg("-noparseerrors", NULL); // Cmdline_noparseerrors -- turns off parsing errors -C
|
||||
@@ -1181,12 +1235,13 @@ 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("-window", NULL); // Cmdline_window
|
||||
#ifdef SCP_UNIX
|
||||
cmdline_parm no_grab("-nograb", NULL); // Cmdline_no_grab
|
||||
#endif
|
||||
|
||||
char *Cmdline_start_mission = NULL;
|
||||
int Cmdline_allslev = 0;
|
||||
int Cmdline_dis_collisions = 0;
|
||||
int Cmdline_dis_weapons = 0;
|
||||
int Cmdline_noparseerrors = 0;
|
||||
@@ -1196,6 +1251,8 @@ 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;
|
||||
#ifdef SCP_UNIX
|
||||
int Cmdline_no_grab = 0;
|
||||
#endif
|
||||
@@ -1205,13 +1262,6 @@ cmdline_parm get_flags_arg("-get_flags", NULL);
|
||||
cmdline_parm output_sexp_arg("-output_sexps", NULL); //WMC - outputs all SEXPs to sexps.html
|
||||
cmdline_parm output_scripting_arg("-output_scripting", NULL); //WMC
|
||||
|
||||
// Totally useless crap...
|
||||
/*#ifdef WIN32
|
||||
cmdline_parm fix_bugs("-fixbugs", NULL);
|
||||
cmdline_parm disable_crashing("-nocrash", NULL);
|
||||
#endif*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -1257,7 +1307,12 @@ char *drop_extra_chars(char *str)
|
||||
while (str[s] && is_extra_space(str[s]))
|
||||
s++;
|
||||
|
||||
e = strlen(str);
|
||||
e = strlen(str) - 1; // we already account for NULL later on, so the -1 is here to make
|
||||
// sure we do our math without taking it into consideration
|
||||
|
||||
if (e < 0)
|
||||
e = 0;
|
||||
|
||||
while (e > s) {
|
||||
if (!is_extra_space(str[e])){
|
||||
break;
|
||||
@@ -1266,7 +1321,7 @@ char *drop_extra_chars(char *str)
|
||||
e--;
|
||||
}
|
||||
|
||||
if (e > s){
|
||||
if (e >= s && e !=0 ){
|
||||
memmove(str, str + s, e - s + 1);
|
||||
}
|
||||
|
||||
@@ -1281,29 +1336,52 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
|
||||
char buffer[1024];
|
||||
memset(buffer, 0, 1024);
|
||||
char *dest = buffer;
|
||||
char *saved_args = NULL;
|
||||
|
||||
cmdline += strlen(parm->name);
|
||||
|
||||
while ((*cmdline != 0) && (*cmdline != '-')) {
|
||||
while ((*cmdline != '\0') && strncmp(cmdline, " -", 2)) {
|
||||
*dest++ = *cmdline++;
|
||||
}
|
||||
|
||||
drop_extra_chars(buffer);
|
||||
|
||||
// mwa 9/14/98 -- made it so that newer command line arguments found will overwrite
|
||||
// the old arguments
|
||||
// Assert(parm->args == NULL);
|
||||
// mwa 9/14/98 -- made it so that newer command line arguments found will overwrite the old arguments
|
||||
// taylor 7/25/06 -- made it so that you can stack newer arguments if that option should support stacking
|
||||
|
||||
if ( parm->args != NULL ) {
|
||||
delete( parm->args );
|
||||
if (parm->stacks) {
|
||||
saved_args = parm->args;
|
||||
} else {
|
||||
delete[] parm->args;
|
||||
}
|
||||
|
||||
parm->args = NULL;
|
||||
}
|
||||
|
||||
int size = strlen(buffer) + 1;
|
||||
|
||||
if (saved_args != NULL)
|
||||
size += (strlen(saved_args) + 1); // an ',' is used as a separator when combining, so be sure to account for it
|
||||
|
||||
if (size > 0) {
|
||||
parm->args = new char[size];
|
||||
memset(parm->args, 0, size);
|
||||
strcpy(parm->args, buffer);
|
||||
|
||||
if (saved_args != NULL) {
|
||||
// saved args go first, then new arg
|
||||
strcpy(parm->args, saved_args);
|
||||
// add a separator too, so that we can tell the args apart
|
||||
strcat(parm->args, ",");
|
||||
// now the new arg
|
||||
strcat(parm->args, buffer);
|
||||
} else {
|
||||
strcpy(parm->args, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (saved_args != NULL)
|
||||
delete[] saved_args;
|
||||
}
|
||||
|
||||
|
||||
@@ -1313,27 +1391,40 @@ void os_parse_parms(char *cmdline)
|
||||
{
|
||||
// locate command line parameters
|
||||
cmdline_parm *parmp;
|
||||
char *cmdline_offset;
|
||||
char *cmdline_offset = NULL;
|
||||
size_t get_new_offset = 0;
|
||||
|
||||
for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
|
||||
// while going through the cmdline make sure to grab only the option that we are looking
|
||||
// for but if one similar then keep searching for the exact match
|
||||
for (parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
|
||||
// continue processing every option on the line to make sure that we account for every listing of each option
|
||||
do {
|
||||
cmdline_offset = strstr(cmdline + get_new_offset, parmp->name);
|
||||
// while going through the cmdline make sure to grab only the option that we are
|
||||
// looking for, but if one similar then keep searching for the exact match
|
||||
while (true) {
|
||||
cmdline_offset = strstr(cmdline + get_new_offset, parmp->name);
|
||||
|
||||
if ( !cmdline_offset )
|
||||
break;
|
||||
|
||||
if (cmdline_offset && (*(cmdline_offset + strlen(parmp->name))) && !is_extra_space(*(cmdline_offset + 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) + strlen(parmp->name));
|
||||
} else {
|
||||
get_new_offset = 0;
|
||||
}
|
||||
} while ( get_new_offset );
|
||||
|
||||
if (cmdline_offset) {
|
||||
parmp->name_found = 1;
|
||||
parm_stuff_args(parmp, cmdline_offset);
|
||||
}
|
||||
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
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdline_offset) {
|
||||
parmp->name_found = 1;
|
||||
parm_stuff_args(parmp, cmdline_offset);
|
||||
}
|
||||
} while (cmdline_offset);
|
||||
|
||||
// reset the offset for the next param that we will look for
|
||||
get_new_offset = 0;
|
||||
cmdline_offset = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1379,11 +1470,11 @@ void os_validate_parms(char *cmdline)
|
||||
if (result != kCFUserNotificationDefaultResponse)
|
||||
exit(0);
|
||||
#else
|
||||
// if we got a -help, --help, or -h then show the help text, otherwise show unknown option
|
||||
if ( !stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") ) {
|
||||
// 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, "-?") ) {
|
||||
printf("FS2 Open: The Source Code Project, version %i.%i.%i\n", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
|
||||
printf("Website: http://scp.indiegames.us\n");
|
||||
printf("Mantis (bug reporting): http://lore.maxgaming.net/~scp/mantis/\n\n");
|
||||
printf("Mantis (bug reporting): http://scp.indiegames.us/mantis/\n\n");
|
||||
printf("Usage: fs2_open [options]\n");
|
||||
|
||||
// not the prettiest thing but the job gets done
|
||||
@@ -1394,11 +1485,12 @@ void os_validate_parms(char *cmdline)
|
||||
printf(" [ %s ]%*s- %s\n", exe_params[p].name, (STR_SIZE - sp - 1), NOX(" "), exe_params[p].desc);
|
||||
p++;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
exit(0);
|
||||
} else {
|
||||
printf("Unrecognized command line parameter \"%s\". Exiting...\n", token);
|
||||
printf("Unrecognized command line parameter \"%s\". Ignoring...\n", token);
|
||||
}
|
||||
printf("\n");
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1500,10 +1592,11 @@ void os_init_cmdline(char *cmdline)
|
||||
// arg constructor
|
||||
// name_ - name of the parameter, must start with '-' character
|
||||
// help_ - help text for this parameter
|
||||
cmdline_parm::cmdline_parm(char *name_, char *help_)
|
||||
cmdline_parm::cmdline_parm(char *name_, char *help_, bool stacks_)
|
||||
{
|
||||
name = name_;
|
||||
help = help_;
|
||||
stacks = stacks_;
|
||||
args = NULL;
|
||||
name_found = 0;
|
||||
|
||||
@@ -1582,7 +1675,22 @@ void output_sexp_html(int sexp_idx, FILE *fp)
|
||||
int cmdline_parm::get_int()
|
||||
{
|
||||
Assert(args);
|
||||
return atoi(args);
|
||||
int offset = 0;
|
||||
|
||||
if (stacks) {
|
||||
// first off, DON'T STACK NON-STRINGS!!
|
||||
Int3();
|
||||
|
||||
// secondly, we still need to get it right for the users sake...
|
||||
char *moron = strstr(args, ",");
|
||||
|
||||
if ( moron && ((strlen(moron) + 1) < strlen(args)) ) {
|
||||
// we get the last arg, since it's the newest one
|
||||
offset = strlen(args) - strlen(moron) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return atoi(args+offset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1590,7 +1698,22 @@ int cmdline_parm::get_int()
|
||||
float cmdline_parm::get_float()
|
||||
{
|
||||
Assert(args);
|
||||
return (float)atof(args);
|
||||
int offset = 0;
|
||||
|
||||
if (stacks) {
|
||||
// first off, DON'T STACK NON-STRINGS!!
|
||||
Int3();
|
||||
|
||||
// secondly, we still need to get it right for the users sake
|
||||
char *moron = strstr(args, ",");
|
||||
|
||||
if ( moron && ((strlen(moron) + 1) < strlen(args)) ) {
|
||||
// we get the last arg, since it's the newest one
|
||||
offset = strlen(args) - strlen(moron) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (float)atof(args+offset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1627,21 +1750,15 @@ bool SetCmdlineParams()
|
||||
Cmdline_voice_recognition = 1;
|
||||
}
|
||||
|
||||
if (Radar_Range_Clamp.found())
|
||||
{
|
||||
if (Radar_Range_Clamp.get_float() > 0.0f)
|
||||
Radar_ranges[RR_MAX_RANGES-1] = Radar_Range_Clamp.get_float();
|
||||
}
|
||||
|
||||
if (nowarn_arg.found())
|
||||
{
|
||||
Cmdline_nowarn = 1;
|
||||
}
|
||||
|
||||
/* karajorma - let's just use -nohtl instead
|
||||
if (fred2_htl_arg.found())
|
||||
{
|
||||
Cmdline_FRED2_htl = 1;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (timerbar_arg.found()) {
|
||||
Cmdline_timerbar = 1;
|
||||
@@ -1771,10 +1888,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_start_netgame = 1;
|
||||
}
|
||||
|
||||
if (allslev_arg.found() ) {
|
||||
Cmdline_allslev = 1;
|
||||
}
|
||||
|
||||
if(dualscanlines_arg.found() ) {
|
||||
Cmdline_dualscanlines = 1;
|
||||
}
|
||||
@@ -1916,11 +2029,6 @@ bool SetCmdlineParams()
|
||||
}
|
||||
}
|
||||
|
||||
// TEMPORARY - REMOVEME!!!
|
||||
if ( alpha_alpha_blend_arg.found() ) {
|
||||
Cmdline_alpha_alpha_blend = 1;
|
||||
}
|
||||
|
||||
// specular comand lines
|
||||
if ( spec_exp_arg.found() ) {
|
||||
specular_exponent_value = spec_exp_arg.get_float();
|
||||
@@ -1952,11 +2060,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_nohtl = 1;
|
||||
}
|
||||
|
||||
if( jpgtga_arg.found() )
|
||||
{
|
||||
Cmdline_jpgtga = 1;
|
||||
}
|
||||
|
||||
if( no_set_gamma_arg.found() )
|
||||
{
|
||||
Cmdline_no_set_gamma = 1;
|
||||
@@ -1974,66 +2077,32 @@ bool SetCmdlineParams()
|
||||
}
|
||||
#endif
|
||||
|
||||
if(pcx32_arg.found() )
|
||||
{
|
||||
Cmdline_pcx32 = 1;
|
||||
}
|
||||
|
||||
if ( img2dds_arg.found() ) {
|
||||
if ( img2dds_arg.found() )
|
||||
Cmdline_img2dds = 1;
|
||||
// we also can use -jpgtga without the bad memory usage
|
||||
Cmdline_jpgtga = 1;
|
||||
}
|
||||
|
||||
if(glow_arg.found() )
|
||||
{
|
||||
if ( glow_arg.found() )
|
||||
Cmdline_noglow = 0;
|
||||
}
|
||||
|
||||
if(query_speech_arg.found() )
|
||||
{
|
||||
if ( query_speech_arg.found() )
|
||||
Cmdline_query_speech = 1;
|
||||
}
|
||||
|
||||
if(ship_choice_3d_arg.found() )
|
||||
{
|
||||
if ( ship_choice_3d_arg.found() )
|
||||
Cmdline_ship_choice_3d = 1;
|
||||
}
|
||||
|
||||
if(show_mem_usage_arg.found()) {
|
||||
if ( show_mem_usage_arg.found() )
|
||||
Cmdline_show_mem_usage = 1;
|
||||
}
|
||||
|
||||
if(ingamejoin_arg.found())
|
||||
{
|
||||
if (ingamejoin_arg.found() )
|
||||
Cmdline_ingamejoin = 1;
|
||||
}
|
||||
|
||||
if(start_mission_arg.found())
|
||||
{
|
||||
if ( start_mission_arg.found() ) {
|
||||
Cmdline_start_mission = start_mission_arg.str();
|
||||
|
||||
if(Cmdline_start_mission != NULL && strlen(Cmdline_start_mission) > 0)
|
||||
{
|
||||
char *temp = Cmdline_start_mission;
|
||||
|
||||
while(*temp)
|
||||
{
|
||||
if(*temp == '*')
|
||||
*temp = '-';
|
||||
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ambient_factor_arg.found())
|
||||
{
|
||||
if ( ambient_factor_arg.found() )
|
||||
Cmdline_ambient_factor = ambient_factor_arg.get_int();
|
||||
}
|
||||
|
||||
if(get_flags_arg.found())
|
||||
{
|
||||
if ( get_flags_arg.found() ) {
|
||||
mprintf(("I got to get_flags_arg.found()!!\n"));
|
||||
FILE *fp = fopen("flags.lch","w");
|
||||
|
||||
@@ -2059,17 +2128,20 @@ bool SetCmdlineParams()
|
||||
fwrite(&num_flags, sizeof(int), 1, fp);
|
||||
fwrite(&exe_params, sizeof(exe_params), 1, fp);
|
||||
|
||||
#ifdef USE_OPENAL
|
||||
// for cheap and bastardly OpenAL check hack
|
||||
char openal = 0;
|
||||
fwrite(&openal, 1, 1, fp);
|
||||
#endif
|
||||
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(output_scripting_arg.found())
|
||||
{
|
||||
if ( output_scripting_arg.found() )
|
||||
Output_scripting_meta = true;
|
||||
}
|
||||
|
||||
if(output_sexp_arg.found())
|
||||
{
|
||||
if (output_sexp_arg.found() ) {
|
||||
extern int Num_op_menus;
|
||||
extern int Num_submenus;
|
||||
|
||||
@@ -2206,13 +2278,12 @@ bool SetCmdlineParams()
|
||||
Cmdline_noibx = 1;
|
||||
}
|
||||
|
||||
if ( noemissive_arg.found() ) {
|
||||
Cmdline_no_emissive = 1;
|
||||
if ( no_fbo_arg.found() ) {
|
||||
Cmdline_no_fbo = 1;
|
||||
}
|
||||
|
||||
// Temporary... REMOVEME LATER!!
|
||||
if ( ybugfix_arg.found() ) {
|
||||
Cmdline_ybugfix = 1;
|
||||
if ( noemissive_arg.found() ) {
|
||||
Cmdline_no_emissive = 1;
|
||||
}
|
||||
|
||||
if ( ogl_spec_arg.found() ) {
|
||||
@@ -2225,64 +2296,20 @@ bool SetCmdlineParams()
|
||||
Cmdline_ogl_spec = 128.0f;
|
||||
}
|
||||
|
||||
if (rearm_timer_arg.found())
|
||||
{
|
||||
if ( rearm_timer_arg.found() )
|
||||
Cmdline_rearm_timer = 1;
|
||||
}
|
||||
|
||||
if (missile_lighting_arg.found())
|
||||
{
|
||||
if ( missile_lighting_arg.found() )
|
||||
Cmdline_missile_lighting = 1;
|
||||
}
|
||||
|
||||
if (save_render_targets_arg.found()) {
|
||||
if ( save_render_targets_arg.found() )
|
||||
Cmdline_save_render_targets = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//#ifdef WIN32
|
||||
extern uint os_get_window();
|
||||
if( fix_bugs.found() )
|
||||
{
|
||||
MessageBox((HWND)os_get_window(), "Could not get lock on RAID controller, driver may be too old. Auto-bugfixing is disabled", "FS2_Open Warning", MB_ICONWARNING);
|
||||
}
|
||||
if ( debug_window_arg.found() )
|
||||
Cmdline_debug_window = 1;
|
||||
|
||||
if( disable_crashing.found())
|
||||
{
|
||||
if(IDRETRY == MessageBox((HWND)os_get_window(), "Error: A CTD bug occured before fs2_open could initialize the anti-crashing subsystem. FS2_Open will now crash. Press retry to try to initialize the subsystem again, or cancel to give up and crash", "FS2_Open Error", MB_ICONWARNING | MB_RETRYCANCEL))
|
||||
{
|
||||
MessageBox((HWND)os_get_window(), "Sorry, it didn't really work. FS2_Open still won't start, but it will close unexpectedly. Press OK to continue closing unexpectedly.", "FS2_Open Error", MB_ICONWARNING);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*char Filepath[1024];
|
||||
char* Filename;
|
||||
GetModuleFileName(hInst, Filepath, sizeof(Filepath));
|
||||
Filename = strrchr(Filepath, '\\');
|
||||
if(Filename == NULL)
|
||||
{
|
||||
Filename = strrchr(Filepath, '/');
|
||||
if(Filename == NULL)
|
||||
{
|
||||
Filename = strrchr(Filepath, ':');
|
||||
if(Filename == NULL)
|
||||
{
|
||||
Filename = Filepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
strcat(Filename, " - Application Error");*/
|
||||
char Filename[128];
|
||||
strcpy(Filename, "fs2_open.exe - Application Error");
|
||||
|
||||
if(IDCANCEL == MessageBox((HWND)os_get_window(), "The instruction at \"0x00001337\" referenced memory at \"0x00000000\". The memory could not be \"read\"\n\nClick on OK to terminate the program\nClick on CANCEL to debug the program", Filename, MB_ICONERROR | MB_OKCANCEL))
|
||||
{
|
||||
MessageBox((HWND)os_get_window(), "What!? Debug something yourself? No, what you want to do is send an error report to Microsoft.", "Error", MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if ( verify_vps_arg.found() )
|
||||
Cmdline_verify_vps = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+39
-6
@@ -11,11 +11,45 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Cmdline/cmdline.h $
|
||||
|
||||
* $Revision: 2.89 $
|
||||
* $Date: 2006-05-27 17:17:57 $
|
||||
* $Revision: 2.95 $
|
||||
* $Date: 2007-04-11 18:24:27 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.94 2007/01/10 01:40:43 taylor
|
||||
* little bit of cleanup
|
||||
* per earlier discussions: remove -jpgtga and -pcx32
|
||||
*
|
||||
* Revision 2.93 2006/11/16 00:50:00 taylor
|
||||
* clean up some cmdline options which were/weren't FSO only
|
||||
* add back the "-32bit" option, for retail compatibility (doesn't do anything, it's just there to avoid the unknown option message)
|
||||
* add "-debug_window" to turn on the Windows-only extra debug output window (it's off by default now, only logging to file instead)
|
||||
*
|
||||
* Revision 2.92 2006/07/08 18:11:33 taylor
|
||||
* remove -allslev
|
||||
* make CTRL-SHIFT-S hotkey work in mission simulator (it's a toggle, so you can turn it on or off while on the screen)
|
||||
* fix a bug where blank lines would show up in the campaign list for branch/alternate type missions that are otherwise marked as not completed
|
||||
*
|
||||
* Revision 2.91 2006/06/27 04:55:53 taylor
|
||||
* add -disable_fbo to troubleshoot crappy ATI drivers
|
||||
* remove the temporary -alpha_alpha_blend option
|
||||
* tack on an extra byte to the flags.lch file so that the launcher can easily detect if it's an OpenAL build or not
|
||||
*
|
||||
* Revision 2.90 2006/06/15 00:37:11 taylor
|
||||
* remove previous attempts at the Y bug fix, it's now back to the retail code for that
|
||||
*
|
||||
* Revision 2.89 2006/05/27 17:17:57 taylor
|
||||
* few things:
|
||||
* - comment out that -fixbugs and -nocrash crap, that's just stupid
|
||||
* - move -env off of the experimental list (since it's working pretty well in OGL)
|
||||
* - remove -nobeampierce
|
||||
* - remove -max_subdivide (didn't do anything)
|
||||
* - remove -rt (didn't do anything, and per-coder cmdline options should never be in CVS)
|
||||
* - move -cache_bitmaps to game speed rather than graphics
|
||||
* - add options for env and spec map scaling for envmaps (temporary, to be removed before official 3.6.8)
|
||||
* - add option for new alpha blend mode so that artists can still test with it but not mess up normal users with the bad MediaVPs
|
||||
* - remove -d3d_particle (it's obsolete now)
|
||||
*
|
||||
* Revision 2.88 2006/05/13 07:29:51 taylor
|
||||
* OpenGL envmap support
|
||||
* newer OpenGL extension support
|
||||
@@ -613,14 +647,12 @@ extern int Cmdline_ambient_factor;
|
||||
extern int Cmdline_cell;
|
||||
extern int Cmdline_decals;
|
||||
extern int Cmdline_env;
|
||||
extern int Cmdline_jpgtga;
|
||||
extern int Cmdline_mipmap;
|
||||
extern int Cmdline_missile_lighting;
|
||||
extern int Cmdline_noglow;
|
||||
extern int Cmdline_nomotiondebris;
|
||||
extern int Cmdline_noscalevid; // disables fit-to-window for movies - taylor
|
||||
extern int Cmdline_nospec;
|
||||
extern int Cmdline_pcx32;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
@@ -667,11 +699,11 @@ 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_ybugfix; // Temporary... REMOVEME LATER!!
|
||||
extern int Cmdline_no_fbo;
|
||||
extern int Cmdline_verify_vps;
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
extern int Cmdline_allslev;
|
||||
extern int Cmdline_dis_collisions;
|
||||
extern int Cmdline_dis_weapons;
|
||||
extern int Cmdline_noparseerrors;
|
||||
@@ -681,6 +713,7 @@ 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;
|
||||
#ifdef SCP_UNIX
|
||||
extern int Cmdline_no_grab;
|
||||
#endif
|
||||
|
||||
@@ -9,13 +9,23 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ControlConfig/ControlsConfig.cpp $
|
||||
* $Revision: 2.18 $
|
||||
* $Date: 2005-10-10 17:14:30 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.20 $
|
||||
* $Date: 2007-11-23 23:08:32 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* C module for keyboard, joystick and mouse configuration
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.19 2007/06/04 00:04:21 Backslash
|
||||
* Backslash's HEAD-only controls commit:
|
||||
* -Lateral thruster axes
|
||||
* -Slide_when_pressed
|
||||
* -Placeholders for glide_when_pressed and more controls, to give us a little breathing room while we wait for the real pilot file code
|
||||
*
|
||||
* Revision 2.18 2005/10/10 17:14:30 taylor
|
||||
* remove NO_NETWORK
|
||||
* fix controlconfig so that axes can be set to joystick/mouse using the mouse (required when no joystick attached)
|
||||
*
|
||||
* Revision 2.17 2005/07/22 10:18:37 Goober5000
|
||||
* CVS header tweaks
|
||||
* --Goober5000
|
||||
@@ -504,8 +514,8 @@ config_item Control_config_backup[CCFG_MAX];
|
||||
int Axis_map_to[] = { JOY_X_AXIS, JOY_Y_AXIS, JOY_RX_AXIS, JOY_Z_AXIS, -1 };
|
||||
int Axis_map_to_defaults[] = { JOY_X_AXIS, JOY_Y_AXIS, JOY_RX_AXIS, JOY_Z_AXIS, -1 };
|
||||
#else
|
||||
int Axis_map_to[] = { JOY_X_AXIS, JOY_Y_AXIS, JOY_RX_AXIS, -1, -1 };
|
||||
int Axis_map_to_defaults[] = { JOY_X_AXIS, JOY_Y_AXIS, JOY_RX_AXIS, -1, -1 };
|
||||
int Axis_map_to[NUM_JOY_AXIS_ACTIONS] = { JOY_X_AXIS, JOY_Y_AXIS, JOY_RX_AXIS, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
||||
int Axis_map_to_defaults[NUM_JOY_AXIS_ACTIONS] = { JOY_X_AXIS, JOY_Y_AXIS, JOY_RX_AXIS, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
||||
#endif
|
||||
|
||||
// all this stuff is localized/externalized
|
||||
@@ -1698,6 +1708,8 @@ void control_config_init()
|
||||
Joy_axis_action_text[2] = vm_strdup(XSTR("Bank Axis", 1018));
|
||||
Joy_axis_action_text[3] = vm_strdup(XSTR("Absolute Throttle Axis", 1019));
|
||||
Joy_axis_action_text[4] = vm_strdup(XSTR("Relative Throttle Axis", 1020));
|
||||
Joy_axis_action_text[5] = vm_strdup("Horizontal Lateral (Slide) Axis");
|
||||
Joy_axis_action_text[6] = vm_strdup("Vertical Lateral (Slide) Axis");
|
||||
Joy_axis_text[0] = vm_strdup(XSTR("Joystick/Mouse X Axis", 1021));
|
||||
Joy_axis_text[1] = vm_strdup(XSTR("Joystick/Mouse Y Axis", 1022));
|
||||
Joy_axis_text[2] = vm_strdup(XSTR("Joystick Z Axis", 1023));
|
||||
@@ -1866,8 +1878,8 @@ void control_config_do_frame(float frametime)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Cc_lines[Selected_line].cc_index == BANK_WHEN_PRESSED) // a special hack just for Mike K.
|
||||
if ( (Last_key >= 0) && (k <= 0) && !keyd_pressed[Last_key] )
|
||||
if (Cc_lines[Selected_line].cc_index == BANK_WHEN_PRESSED || Cc_lines[Selected_line].cc_index == SLIDE_WHEN_PRESSED || Cc_lines[Selected_line].cc_index == GLIDE_WHEN_PRESSED) // a special hack just for Mike K.
|
||||
if ( (Last_key >= 0) && (k <= 0) && !keyd_pressed[Last_key] ) //Backslash - ok it's not just for Mike K. any more :-P but seriously, this is so we can bind such controls to Shift or Alt. Does this actually get used?
|
||||
k = Last_key;
|
||||
|
||||
if ((k > 0) && !Config_allowed[k & KEY_MASK]) {
|
||||
@@ -2543,43 +2555,28 @@ int check_control(int id, int key)
|
||||
}
|
||||
|
||||
// get heading, pitch, bank, throttle abs. and throttle rel. values.
|
||||
void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr)
|
||||
void control_get_axes_readings(int *axis)
|
||||
{
|
||||
int axes_values[JOY_NUM_AXES];
|
||||
|
||||
joystick_read_raw_axis(JOY_NUM_AXES, axes_values);
|
||||
|
||||
// joy_get_scaled_reading will return a value represents the joystick pos from -1 to +1 (fixed point)
|
||||
*h = 0;
|
||||
if (Axis_map_to[0] >= 0)
|
||||
*h = joy_get_scaled_reading(axes_values[Axis_map_to[0]], Axis_map_to[0]);
|
||||
|
||||
*p = 0;
|
||||
if (Axis_map_to[1] >= 0)
|
||||
*p = joy_get_scaled_reading(axes_values[Axis_map_to[1]], Axis_map_to[1]);
|
||||
|
||||
*b = 0;
|
||||
if (Axis_map_to[2] >= 0)
|
||||
*b = joy_get_scaled_reading(axes_values[Axis_map_to[2]], Axis_map_to[2]);
|
||||
|
||||
*ta = 0;
|
||||
if (Axis_map_to[3] >= 0)
|
||||
*ta = joy_get_unscaled_reading(axes_values[Axis_map_to[3]], Axis_map_to[3]);
|
||||
|
||||
*tr = 0;
|
||||
if (Axis_map_to[4] >= 0)
|
||||
*tr = joy_get_scaled_reading(axes_values[Axis_map_to[4]], Axis_map_to[4]);
|
||||
|
||||
if (Invert_axis[0])
|
||||
*h = -(*h);
|
||||
if (Invert_axis[1])
|
||||
*p = -(*p);
|
||||
if (Invert_axis[2])
|
||||
*b = -(*b);
|
||||
if (Invert_axis[3])
|
||||
*ta = F1_0 - *ta;
|
||||
if (Invert_axis[4])
|
||||
*tr = -(*tr);
|
||||
for (int i = 0; i < NUM_JOY_AXIS_ACTIONS; i++) {
|
||||
if (Axis_map_to[i] >= 0) {
|
||||
if (i == 3) {
|
||||
//Backslash -- this is to handle the absolute throttle.
|
||||
//I hate this hardcoding! but what can we do but follow precedent? Corrections welcome.
|
||||
axis[i] = joy_get_unscaled_reading(axes_values[Axis_map_to[i]], Axis_map_to[i]);
|
||||
if (Invert_axis[i])
|
||||
axis[i] = F1_0 - axis[i];
|
||||
} else {
|
||||
axis[i] = joy_get_scaled_reading(axes_values[Axis_map_to[i]], Axis_map_to[i]);
|
||||
if (Invert_axis[i])
|
||||
axis[i] = -(axis[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,13 +9,28 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ControlConfig/ControlsConfig.h $
|
||||
* $Revision: 2.15 $
|
||||
* $Date: 2006-02-25 21:46:59 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.19 $
|
||||
* $Date: 2007-12-22 09:36:17 $
|
||||
* $Author: Backslash $
|
||||
*
|
||||
* Header file for keyboard, joystick and mouse configuration
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.18 2007/06/04 00:04:21 Backslash
|
||||
* Backslash's HEAD-only controls commit:
|
||||
* -Lateral thruster axes
|
||||
* -Slide_when_pressed
|
||||
* -Placeholders for glide_when_pressed and more controls, to give us a little breathing room while we wait for the real pilot file code
|
||||
*
|
||||
* Revision 2.17 2006/08/01 04:26:02 Kazan
|
||||
* commented out glide_while_pressed changes until taylor deems them safe
|
||||
*
|
||||
* Revision 2.16 2006/07/31 23:57:48 Kazan
|
||||
* glide while pressed
|
||||
*
|
||||
* Revision 2.15 2006/02/25 21:46:59 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 2.14 2005/10/11 05:24:33 wmcoolmon
|
||||
* Gliding
|
||||
*
|
||||
@@ -326,13 +341,15 @@
|
||||
#define JOY_RY_AXIS 4
|
||||
#define JOY_RZ_AXIS 5
|
||||
|
||||
#define NUM_JOY_AXIS_ACTIONS 5
|
||||
#define NUM_JOY_AXIS_ACTIONS 12 //5
|
||||
|
||||
#define JOY_HEADING_AXIS 0
|
||||
#define JOY_PITCH_AXIS 1
|
||||
#define JOY_BANK_AXIS 2
|
||||
#define JOY_ABS_THROTTLE_AXIS 3
|
||||
#define JOY_REL_THROTTLE_AXIS 4
|
||||
#define JOY_SIDEWAYS_AXIS 5
|
||||
#define JOY_VERTICAL_AXIS 6
|
||||
|
||||
// --------------------------------------------------
|
||||
// different types of controls that can be assigned
|
||||
@@ -462,8 +479,10 @@ typedef struct config_item {
|
||||
|
||||
#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
|
||||
//#define SHOW_DAMAGE_POPUP 83 // AL: this binding should be removing next time the controls are reorganized
|
||||
|
||||
#define SLIDE_WHEN_PRESSED 83
|
||||
//Backslash -- this was a convenient place for Slide When Pressed, since Show Damage Popup isn't used
|
||||
#define BANK_WHEN_PRESSED 84
|
||||
#define SHOW_NAVMAP 85
|
||||
#define ADD_REMOVE_ESCORT 86
|
||||
@@ -513,9 +532,14 @@ typedef struct config_item {
|
||||
|
||||
//Gliding
|
||||
#define TOGGLE_GLIDING 117
|
||||
#define GLIDE_WHEN_PRESSED 118
|
||||
#define VIEW_UP 119
|
||||
#define VIEW_DOWN 120
|
||||
#define VIEW_LEFT 121
|
||||
#define VIEW_RIGHT 122
|
||||
|
||||
// this should be the total number of control action defines above (or last define + 1)
|
||||
#define CCFG_MAX 118
|
||||
#define CCFG_MAX 128 //118
|
||||
|
||||
extern int Failed_key_index;
|
||||
extern int Invert_heading;
|
||||
@@ -548,7 +572,7 @@ char *translate_key(char *key);
|
||||
char *textify_scancode(int code);
|
||||
float check_control_timef(int id);
|
||||
int check_control(int id, int key = -1);
|
||||
void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr);
|
||||
void control_get_axes_readings(int *axis);
|
||||
void control_used(int id);
|
||||
void control_config_clear();
|
||||
void clear_key_binding(short key);
|
||||
|
||||
@@ -9,13 +9,35 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ControlConfig/ControlsConfigCommon.cpp $
|
||||
* $Revision: 2.14 $
|
||||
* $Date: 2006-02-25 21:46:59 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.20 $
|
||||
* $Date: 2007-12-22 09:36:16 $
|
||||
* $Author: Backslash $
|
||||
*
|
||||
* C module for keyboard, joystick and mouse configuration common stuff (between Fred and FreeSpace)
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.19 2007/06/04 00:04:21 Backslash
|
||||
* Backslash's HEAD-only controls commit:
|
||||
* -Lateral thruster axes
|
||||
* -Slide_when_pressed
|
||||
* -Placeholders for glide_when_pressed and more controls, to give us a little breathing room while we wait for the real pilot file code
|
||||
*
|
||||
* Revision 2.18 2006/08/01 04:26:02 Kazan
|
||||
* commented out glide_while_pressed changes until taylor deems them safe
|
||||
*
|
||||
* Revision 2.17 2006/08/01 01:56:44 Goober5000
|
||||
* proper phrase case
|
||||
*
|
||||
* Revision 2.16 2006/07/31 23:57:48 Kazan
|
||||
* glide while pressed
|
||||
*
|
||||
* Revision 2.15 2006/07/20 01:51:17 Goober5000
|
||||
* tweak control text
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.14 2006/02/25 21:46:59 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 2.13 2005/10/11 05:24:33 wmcoolmon
|
||||
* Gliding
|
||||
*
|
||||
@@ -440,8 +462,8 @@ int Alt_is_modifier;
|
||||
|
||||
int Axis_enabled[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
|
||||
int Axis_enabled_defaults[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
|
||||
int Invert_axis[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
int Invert_axis[NUM_JOY_AXIS_ACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int Invert_axis_defaults[NUM_JOY_AXIS_ACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
// arrays which hold the key mappings. The array index represents a key-independent action.
|
||||
//
|
||||
@@ -458,13 +480,13 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle" },
|
||||
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker" },
|
||||
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission" },
|
||||
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Auto-Targeting" },
|
||||
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting" },
|
||||
|
||||
// targeting a ship's subsystem
|
||||
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle" },
|
||||
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem" },
|
||||
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem" },
|
||||
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Auto-Targeting of Subsystems" },
|
||||
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems" },
|
||||
|
||||
// matching speed
|
||||
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed" },
|
||||
@@ -501,15 +523,15 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target" },
|
||||
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target" },
|
||||
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target" },
|
||||
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack my Subsystem" },
|
||||
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem" },
|
||||
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target" },
|
||||
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy" },
|
||||
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on my Wing" },
|
||||
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore my Target" },
|
||||
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect my Target" },
|
||||
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover me" },
|
||||
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to base" },
|
||||
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm me" },
|
||||
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing" },
|
||||
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target" },
|
||||
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target" },
|
||||
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me" },
|
||||
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base" },
|
||||
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me" },
|
||||
|
||||
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship" },
|
||||
|
||||
@@ -517,7 +539,7 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View" },
|
||||
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View"},
|
||||
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock"},
|
||||
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View" }, // (Swifty) No longer used
|
||||
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View" },
|
||||
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS },
|
||||
@@ -542,17 +564,19 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy" },
|
||||
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings" },
|
||||
|
||||
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shield" },
|
||||
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields" },
|
||||
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield" },
|
||||
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield" },
|
||||
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield" },
|
||||
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield" },
|
||||
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield" },
|
||||
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser" },
|
||||
{ -1, -1, -1, true, "Show Damage Popup Window" },
|
||||
// { -1, -1, -1, true, "Show Damage Popup Window" },
|
||||
|
||||
{ -1, -1, SHIP_TAB, false, "Slide When Pressed", CC_TYPE_CONTINUOUS },
|
||||
//Backslash -- this was a convenient place for Slide When Pressed, as Show Damage Popup isn't used
|
||||
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS },
|
||||
{ -1, -1, -1, true, "Show NavMap" },
|
||||
{ -1, -1, -1, true, "Show Nav Map" },
|
||||
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort" },
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List" },
|
||||
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship" },
|
||||
@@ -560,7 +584,7 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
|
||||
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo" },
|
||||
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo" },
|
||||
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship In Area" },
|
||||
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area" },
|
||||
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret" },
|
||||
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret" },
|
||||
|
||||
@@ -572,15 +596,15 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer zoom to target"},
|
||||
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target"},
|
||||
|
||||
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase time compression" },
|
||||
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease time compression" },
|
||||
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression" },
|
||||
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression" },
|
||||
|
||||
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle high HUD contrast" },
|
||||
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast" },
|
||||
|
||||
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle network info"},
|
||||
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self destruct"},
|
||||
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info"},
|
||||
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct"},
|
||||
|
||||
// Misc
|
||||
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD"},
|
||||
@@ -588,15 +612,27 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Targetbox"},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Top-down View"},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Track targeted object", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View"},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Top-Down View"},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View"}, // (Swifty) Toggle for VM_TRACK
|
||||
|
||||
// Auto Navigation Systen
|
||||
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot"},
|
||||
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points"},
|
||||
|
||||
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle gliding"},
|
||||
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding"},
|
||||
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS},
|
||||
// (Swifty) The four new free looking commands.
|
||||
{ -1, -1, COMPUTER_TAB, false, "Free Look Up", CC_TYPE_CONTINUOUS},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Free Look Down", CC_TYPE_CONTINUOUS},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Free Look Left", CC_TYPE_CONTINUOUS},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Free Look Right", CC_TYPE_CONTINUOUS},
|
||||
|
||||
{ -1, -1, -1, false, "MultiTarget Wing" },
|
||||
{ -1, -1, -1, false, "Placeholder" },
|
||||
{ -1, -1, -1, false, "Placeholder" },
|
||||
{ -1, -1, -1, false, "Placeholder" },
|
||||
{ -1, -1, -1, false, "Placeholder" },
|
||||
|
||||
{ -1, -1, -1, false, "" }
|
||||
};
|
||||
|
||||
+60
-19
@@ -9,16 +9,32 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Cutscene/Cutscenes.cpp $
|
||||
* $Revision: 2.18 $
|
||||
* $Date: 2006-05-09 09:21:15 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.18 $
|
||||
* $Date: 2006-05-09 09:21:15 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.23 $
|
||||
* $Date: 2007-09-02 02:10:24 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.23 $
|
||||
* $Date: 2007-09-02 02:10:24 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Code for the cutscenes viewer screen
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.22 2007/03/22 20:53:43 taylor
|
||||
* give a better msg when movies can't play because they are user-disabled with the cmdline option
|
||||
*
|
||||
* Revision 2.21 2007/02/09 23:58:52 taylor
|
||||
* add the "show all" hotkey to the cutscene viewer
|
||||
*
|
||||
* Revision 2.20 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.19 2006/09/11 06:49:38 taylor
|
||||
* fixes for stuff_string() bounds checking
|
||||
*
|
||||
* Revision 2.18 2006/05/09 09:21:15 taylor
|
||||
* fix incorrect button locations, it matches the correct layout of the other techroom screens now
|
||||
* (thought Backslash was going to fix this, but I got tired of waiting. :))
|
||||
*
|
||||
* Revision 2.17 2005/07/02 19:42:14 taylor
|
||||
* ton of non-standard resolution fixes
|
||||
*
|
||||
@@ -242,6 +258,9 @@
|
||||
#include "parse/parselo.h"
|
||||
|
||||
|
||||
extern int Cmdline_nomovies;
|
||||
|
||||
|
||||
char *Cutscene_bitmap_name[GR_NUM_RESOLUTIONS] = {
|
||||
"ViewFootage",
|
||||
"2_ViewFootage"
|
||||
@@ -251,46 +270,52 @@ char *Cutscene_mask_name[GR_NUM_RESOLUTIONS] = {
|
||||
"2_ViewFootage-m"
|
||||
};
|
||||
|
||||
int Num_cutscenes;
|
||||
int Num_cutscenes = 0;
|
||||
int Cutscenes_viewable;
|
||||
int Description_index;
|
||||
cutscene_info Cutscenes[MAX_CUTSCENES];
|
||||
|
||||
//extern int All_movies_enabled; // If set, all movies may be viewed. Keyed off cheat code.
|
||||
void cutsceen_close(){
|
||||
void cutscene_close(){
|
||||
for(int i = 0; i<MAX_CUTSCENES; i++)
|
||||
if(Cutscenes[i].description)vm_free(Cutscenes[i].description);
|
||||
{
|
||||
if(Cutscenes[i].description != NULL) {
|
||||
vm_free(Cutscenes[i].description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialization stuff for cutscenes
|
||||
void cutscene_init()
|
||||
{
|
||||
atexit(cutsceen_close);
|
||||
atexit(cutscene_close);
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
Error(LOCATION, "Error parsing 'rank.tbl'\r\nError code = %i.\r\n", rval);
|
||||
}
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "cutscenes.tbl", rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("cutscenes.tbl");
|
||||
reset_parse();
|
||||
|
||||
// parse in all the rank names
|
||||
// parse in all the cutscenes
|
||||
Num_cutscenes = 0;
|
||||
skip_to_string("#Cutscenes");
|
||||
ignore_white_space();
|
||||
while ( required_string_either("#End", "$Filename:") ) {
|
||||
Assert ( Num_cutscenes < MAX_CUTSCENES );
|
||||
required_string("$Filename:");
|
||||
stuff_string( Cutscenes[Num_cutscenes].filename, F_PATHNAME, NULL );
|
||||
stuff_string( Cutscenes[Num_cutscenes].filename, F_PATHNAME, MAX_FILENAME_LEN );
|
||||
required_string("$Name:");
|
||||
stuff_string( Cutscenes[Num_cutscenes].name, F_NAME, NULL );
|
||||
stuff_string( Cutscenes[Num_cutscenes].name, F_NAME, NAME_LENGTH );
|
||||
required_string("$Description:");
|
||||
stuff_string(buf, F_MULTITEXT, NULL);
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
Cutscenes[Num_cutscenes].description = vm_strdup(buf);
|
||||
@@ -548,7 +573,11 @@ void cutscenes_screen_play()
|
||||
if ( !rval ) {
|
||||
char str[256];
|
||||
|
||||
sprintf(str, XSTR( "Unable to play movie %s.", 204), Cutscenes[which_cutscene].name );
|
||||
if (Cmdline_nomovies)
|
||||
sprintf(str, XSTR("Movies are currently disabled.", -1));
|
||||
else
|
||||
sprintf(str, XSTR("Unable to play movie %s.", 204), Cutscenes[which_cutscene].name);
|
||||
|
||||
popup(0, 1, POPUP_OK, str );
|
||||
}
|
||||
|
||||
@@ -764,6 +793,18 @@ void cutscenes_screen_do_frame()
|
||||
case KEY_F2: // goto options screen
|
||||
gameseq_post_event(GS_EVENT_OPTIONS_MENU);
|
||||
break;
|
||||
|
||||
// the "show-all" hotkey
|
||||
case KEY_CTRLED | KEY_SHIFTED | KEY_S:
|
||||
{
|
||||
Num_files = 0;
|
||||
for (i = 0; i < Num_cutscenes; i++) {
|
||||
Cutscene_list[Num_files] = i;
|
||||
Num_files++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
for (i=0; i<NUM_BUTTONS; i++){
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Cutscene/Cutscenes.h $
|
||||
* $Revision: 2.4 $
|
||||
* $Date: 2005-07-13 02:50:50 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.5 $
|
||||
* $Date: 2006-12-28 00:59:19 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Code for the cutscenes viewer screen
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.4 2005/07/13 02:50:50 Goober5000
|
||||
* remove PreProcDefine #includes in FS2
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.3 2004/08/11 05:06:20 Kazan
|
||||
* added preprocdefines.h to prevent what happened with fred -- make sure to make all fred2 headers include this file as the _first_ include -- i have already modified fs2 files to do this
|
||||
*
|
||||
@@ -77,6 +81,7 @@ typedef struct cutscene_info
|
||||
char name[NAME_LENGTH];
|
||||
char *description;
|
||||
int cd;
|
||||
cutscene_info(){memset(this, 0, sizeof(cutscene_info));}
|
||||
} cutscene_info;
|
||||
|
||||
extern cutscene_info Cutscenes[MAX_CUTSCENES];
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/src/cutscene/decoder16.cpp $
|
||||
* $Revision: 2.1 $
|
||||
* $Date: 2006-05-13 06:59:48 $
|
||||
* $Revision: 2.2 $
|
||||
* $Date: 2006-08-20 00:44:36 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* decoder for 16-bit MVE image data
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.1 2006/05/13 06:59:48 taylor
|
||||
* MVE player (audio only works with OpenAL builds!)
|
||||
*
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*
|
||||
@@ -60,23 +63,9 @@ void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, un
|
||||
op = (*pMap) & 0xf;
|
||||
dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
|
||||
|
||||
/*
|
||||
if ((ushort *)pFrame < backBuf1)
|
||||
fprintf(stderr, "danger! pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
|
||||
else if ((ushort *)pFrame >= backBuf1 + g_width*g_height)
|
||||
fprintf(stderr, "danger! pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
|
||||
*/
|
||||
|
||||
op = ((*pMap) >> 4) & 0xf;
|
||||
dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
|
||||
|
||||
/*
|
||||
if ((ushort *)pFrame < backBuf1)
|
||||
fprintf(stderr, "danger! pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
|
||||
else if ((ushort *)pFrame >= backBuf1 + g_width*g_height)
|
||||
fprintf(stderr, "danger! pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
|
||||
*/
|
||||
|
||||
pMap++;
|
||||
mapRemain--;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/src/cutscene/decoder8.cpp $
|
||||
* $Revision: 2.1 $
|
||||
* $Date: 2006-08-20 00:44:36 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* decoder for 8-bit MVE image data
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
|
||||
extern int g_width, g_height;
|
||||
extern void *g_vBackBuf1, *g_vBackBuf2;
|
||||
|
||||
static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb);
|
||||
|
||||
void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
|
||||
{
|
||||
int i, j;
|
||||
int xb, yb;
|
||||
|
||||
xb = g_width >> 3;
|
||||
yb = g_height >> 3;
|
||||
|
||||
for (j = 0; j < yb; j++) {
|
||||
for (i = 0; i < (xb / 2); i++) {
|
||||
dispatchDecoder8(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
|
||||
|
||||
dispatchDecoder8(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
|
||||
|
||||
pMap++;
|
||||
mapRemain--;
|
||||
}
|
||||
|
||||
pFrame += 7*g_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void relClose(int i, int *x, int *y)
|
||||
{
|
||||
int ma, mi;
|
||||
|
||||
ma = i >> 4;
|
||||
mi = i & 0xf;
|
||||
|
||||
*x = mi - 8;
|
||||
*y = ma - 8;
|
||||
}
|
||||
|
||||
static void relFar(int i, int sign, int *x, int *y)
|
||||
{
|
||||
if (i < 56) {
|
||||
*x = sign * (8 + (i % 7));
|
||||
*y = sign * (i / 7);
|
||||
} else {
|
||||
*x = sign * (-14 + (i - 56) % 29);
|
||||
*y = sign * (8 + (i - 56) / 29);
|
||||
}
|
||||
}
|
||||
|
||||
/* copies an 8x8 block from pSrc to pDest.
|
||||
pDest and pSrc are both g_width bytes wide */
|
||||
static void copyFrame(ubyte *pDest, ubyte *pSrc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(pDest, pSrc, 8);
|
||||
pDest += g_width;
|
||||
pSrc += g_width;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next eight bytes with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0 and pat1
|
||||
static void patternRow4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
|
||||
{
|
||||
ushort mask = 0x0003;
|
||||
ushort shift = 0;
|
||||
ushort pattern = (pat1 << 8) | pat0;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pattern) >> shift];
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next four 2x2 pixel blocks with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0.
|
||||
static void patternRow4Pixels2(ubyte *pFrame, ubyte pat0, ubyte *p)
|
||||
{
|
||||
ubyte mask = 0x03;
|
||||
ubyte shift = 0;
|
||||
ubyte pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next four 2x1 pixel blocks with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat.
|
||||
static void patternRow4Pixels2x1(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte mask = 0x03;
|
||||
ubyte shift = 0;
|
||||
ubyte pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next 4x4 pixel block with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0, pat1, pat2, and pat3.
|
||||
static void patternQuadrant4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte pat2, ubyte pat3, ubyte *p)
|
||||
{
|
||||
unsigned long mask = 0x00000003UL;
|
||||
int shift=0;
|
||||
int i;
|
||||
unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) >> shift];
|
||||
|
||||
if ( (i & 3) == 3 )
|
||||
pFrame += g_width;
|
||||
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// fills the next 8 pixels with either p[0] or p[1], depending on pattern
|
||||
static void patternRow2Pixels(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte mask=0x01;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pat) ? 1 : 0];
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// fills the next four 2 x 2 pixel boxes with either p[0] or p[1], depending on pattern
|
||||
static void patternRow2Pixels2(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte pel;
|
||||
ubyte mask=0x1;
|
||||
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
|
||||
pFrame[0] = pel; // upper-left
|
||||
pFrame[1] = pel; // upper-right
|
||||
pFrame[g_width + 0] = pel; // lower-left
|
||||
pFrame[g_width + 1] = pel; // lower-right
|
||||
pFrame += 2;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// fills pixels in the next 4 x 4 pixel boxes with either p[0] or p[1], depending on pat0 and pat1.
|
||||
static void patternQuadrant2Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
|
||||
{
|
||||
ubyte pel;
|
||||
ushort mask = 0x0001;
|
||||
int i, j;
|
||||
ushort pat = (pat1 << 8) | pat0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
pel = p[(pat & mask) ? 1 : 0];
|
||||
|
||||
pFrame[j + i * g_width] = pel;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb)
|
||||
{
|
||||
ubyte p[4];
|
||||
ubyte pat[16];
|
||||
int i, j, k;
|
||||
int x, y;
|
||||
|
||||
switch(codeType) {
|
||||
case 0x0:
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1));
|
||||
*pFrame += 8;
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
*pFrame += 8;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
relFar(*(*pData)++, 1, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
*pDataRemain--;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
relFar(*(*pData)++, -1, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
*pDataRemain--;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
relClose(*(*pData)++, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
*pDataRemain--;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
x = (signed char)*(*pData)++;
|
||||
y = (signed char)*(*pData)++;
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
for (i = 0; i < 2; i++) {
|
||||
*pFrame += 16;
|
||||
|
||||
if (++*curXb == (g_width >> 3)) {
|
||||
*pFrame += 7*g_width;
|
||||
*curXb = 0;
|
||||
|
||||
if (++*curYb == (g_height >> 3))
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
|
||||
if (p[0] <= p[1]) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
patternRow2Pixels(*pFrame, *(*pData)++, p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 2; i++) {
|
||||
patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
|
||||
*pFrame += 2*g_width;
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
// four quadrant case
|
||||
for (i = 0; i < 4; i++) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
// alternate between moving down and moving up and right
|
||||
if (i & 1)
|
||||
*pFrame += 4 - 4*g_width; // up and right
|
||||
else
|
||||
*pFrame += 4*g_width; // down
|
||||
}
|
||||
} else if ( (*pData)[6] <= (*pData)[7] ) {
|
||||
// split horizontal
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i & 1) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
// split vertical
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i & 3) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
}
|
||||
|
||||
patternRow2Pixels(*pFrame, *(*pData)++, p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
if ( (*pData)[2] <= (*pData)[3] ) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
} else {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame -= (6*g_width - 8);
|
||||
}
|
||||
} else {
|
||||
if ( (*pData)[2] <= (*pData)[3] ) {
|
||||
// draw 2x1 strips
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels2x1(*pFrame, pat[0], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
} else {
|
||||
// draw 1x2 strips
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
pat[2] = *(*pData)++;
|
||||
pat[3] = *(*pData)++;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
if ( (*pData)[12] <= (*pData)[13] ) {
|
||||
// split vertical
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i&1) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
pat[2] = *(*pData)++;
|
||||
pat[3] = *(*pData)++;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
// split horizontal
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i&3) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(*pFrame, *pData, 8);
|
||||
*pFrame += g_width;
|
||||
*pData += 8;
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
(*pFrame)[2*k] = (*pData)[k];
|
||||
(*pFrame)[2*k+1] = (*pData)[k];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xd:
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
(*pFrame)[k*g_width+j] = (*pData)[0];
|
||||
(*pFrame)[k*g_width+j+4] = (*pData)[1];
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame += 4*g_width;
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
for (i = 0; i < 8; i++) {
|
||||
memset(*pFrame, **pData, 8);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
(*pData)++;
|
||||
*pDataRemain--;
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*pFrame)[j] = (*pData)[(i+j)&1];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
+121
-200
@@ -9,13 +9,47 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/cutscene/movie.cpp $
|
||||
* $Revision: 2.31 $
|
||||
* $Date: 2006-05-27 17:13:22 $
|
||||
* $Revision: 2.40 $
|
||||
* $Date: 2007-01-07 12:29:43 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* movie player code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.39 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.38 2006/11/16 00:50:38 taylor
|
||||
* clean up AVI movie stuff a bit:
|
||||
* - use the default black brush for clearing the screen, it's a little less stupid this way
|
||||
* - have the AVI player send messages back to the game rather than trying to poll for that extra crap
|
||||
* - remove the only DivX6 fix, there is better addressed by newer window handling code
|
||||
*
|
||||
* Revision 2.37 2006/09/11 05:54:37 taylor
|
||||
* switch to using cf_find_file_location_ext() when looking for movies
|
||||
*
|
||||
* Revision 2.36 2006/09/09 21:28:19 taylor
|
||||
* be sure to reset color and clear color before MVE playback (fix for Mantis bug #1041)
|
||||
*
|
||||
* Revision 2.35 2006/08/20 00:44:36 taylor
|
||||
* add decoder for 8-bit MVEs
|
||||
* a basic fix for finding AVIs over MVEs, for mod dir stuff (this needs some CFILE support added to be a true fix, it's on the TODO list)
|
||||
* little bits of cleanup for old/unused code
|
||||
* make sure MVE filenames are correct in mvelib
|
||||
*
|
||||
* Revision 2.34 2006/08/15 00:26:07 Backslash
|
||||
* add .ogg to the list of recognized movie file extensions
|
||||
*
|
||||
* Revision 2.33 2006/07/13 22:15:02 taylor
|
||||
* handle non-MVE movies a bit better in OpenGL (don't get freaky with the window, don't lose input, etc.)
|
||||
* some cleanup to OpenGL window handling, to fix min/max/full issues, and try to make shutdown a little nicer
|
||||
*
|
||||
* Revision 2.32 2006/06/27 05:07:48 taylor
|
||||
* fix various compiler warnings and things that Valgrind complained about
|
||||
*
|
||||
* Revision 2.31 2006/05/27 17:13:22 taylor
|
||||
* add NO_DIRECT3D support
|
||||
*
|
||||
* Revision 2.30 2006/05/13 06:59:48 taylor
|
||||
* MVE player (audio only works with OpenAL builds!)
|
||||
*
|
||||
@@ -59,37 +93,30 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "directx/dx8show.h"
|
||||
#include "graphics/grd3dinternal.h"
|
||||
#endif
|
||||
|
||||
#include "graphics/2d.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "cutscene/movie.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
|
||||
#include "freespace2/freespace.h" // for Game_mode, etc.
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "cutscene/oggplayer.h"
|
||||
#include "menuui/mainhallmenu.h"
|
||||
|
||||
extern int Game_mode;
|
||||
|
||||
|
||||
#define MOVIE_NONE -1
|
||||
#define MOVIE_OGG 0
|
||||
#define MOVIE_MVE 1
|
||||
|
||||
// This module links freespace movie calls to the actual API calls the play the movie.
|
||||
// This module handles all the different requires of OS and gfx API and finding the file to play
|
||||
|
||||
void process_messages()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MSG msg;
|
||||
while(PeekMessage(&msg, (HWND) os_get_window(), 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// filename - file to search for
|
||||
// out_name - output, full path to file
|
||||
@@ -98,40 +125,30 @@ int movie_find(char *filename, char *out_name)
|
||||
{
|
||||
char full_path[MAX_PATH];
|
||||
char tmp_name[MAX_PATH];
|
||||
char search_name[MAX_PATH];
|
||||
int i, size, offset = 0;
|
||||
int size, offset = 0;
|
||||
const int NUM_EXT = 2;
|
||||
const char *movie_ext[NUM_EXT] = { ".avi", ".mpg" };
|
||||
const char *movie_ext[NUM_EXT] = { ".ogg", ".mve" };
|
||||
|
||||
if (out_name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (out_name == NULL)
|
||||
return MOVIE_NONE;
|
||||
|
||||
|
||||
memset( full_path, 0, sizeof(full_path) );
|
||||
memset( tmp_name, 0, sizeof(tmp_name) );
|
||||
|
||||
// remove extension
|
||||
strcpy( tmp_name, filename );
|
||||
char *p = strchr( tmp_name, '.' );
|
||||
if ( p ) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_EXT; i++) {
|
||||
strcpy( search_name, tmp_name );
|
||||
strcat( search_name, movie_ext[i] );
|
||||
char *p = strchr(tmp_name, '.');
|
||||
if ( p ) *p = 0;
|
||||
|
||||
// try and find the file
|
||||
if ( cf_find_file_location(search_name, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0) ) {
|
||||
// if it's not in a packfile then we're done
|
||||
if (offset == 0) {
|
||||
strcpy( out_name, full_path );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// clear old string
|
||||
strcpy( search_name, "" );
|
||||
}
|
||||
int rc = cf_find_file_location_ext(tmp_name, NUM_EXT, movie_ext, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0);
|
||||
|
||||
return 0;
|
||||
if (rc == MOVIE_NONE)
|
||||
return MOVIE_NONE;
|
||||
|
||||
strcpy( out_name, full_path );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Play one movie
|
||||
@@ -146,181 +163,85 @@ bool movie_play(char *name)
|
||||
|
||||
extern int Mouse_hidden;
|
||||
extern int Is_standalone;
|
||||
if(Is_standalone) return false;
|
||||
if(Cmdline_nomovies) return false;
|
||||
//Commented this out since we have dnoshowvid -WMC
|
||||
//if(Cmdline_window) return false;
|
||||
|
||||
if (Cmdline_nomovies || Is_standalone)
|
||||
return false;
|
||||
|
||||
|
||||
char full_name[MAX_PATH];
|
||||
int rc = 0;
|
||||
|
||||
// first off, check for a MVE
|
||||
MVESTREAM *movie = NULL;
|
||||
|
||||
movie = mve_open(name);
|
||||
|
||||
if (movie) {
|
||||
// kill all background sounds
|
||||
main_hall_pause();
|
||||
|
||||
// clear the screen and hide the mouse cursor
|
||||
Mouse_hidden++;
|
||||
gr_reset_clip();
|
||||
gr_zbuffer_clear(0);
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
|
||||
// ready to play...
|
||||
mve_init(movie);
|
||||
mve_play(movie);
|
||||
|
||||
// ... done playing, close the mve and show the cursor again
|
||||
mve_shutdown();
|
||||
mve_close(movie);
|
||||
Mouse_hidden--;
|
||||
|
||||
main_hall_unpause();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// no MVE version so move on to AVI/MPG searching
|
||||
|
||||
#ifdef _WIN32
|
||||
rc = movie_find(name, full_name);
|
||||
|
||||
if (!rc) {
|
||||
DBUGFILE_OUTPUT_1("MOVIE ERROR: Cant open movie file %s", name);
|
||||
if (rc == MOVIE_NONE) {
|
||||
mprintf(("MOVIE ERROR: Unable to open movie file '%s' in any supported format.\n", name));
|
||||
return false;
|
||||
} else {
|
||||
DBUGFILE_OUTPUT_1("About to play: %s", full_name);
|
||||
}
|
||||
|
||||
process_messages();
|
||||
// kill all background sounds
|
||||
main_hall_pause();
|
||||
|
||||
#ifndef NO_DIRECT3D
|
||||
// This is a bit of a hack but it works nicely
|
||||
if(gr_screen.mode == GR_DIRECT3D)
|
||||
{
|
||||
GlobalD3DVars::D3D_activate = 0;
|
||||
GlobalD3DVars::lpD3DDevice->EndScene();
|
||||
GlobalD3DVars::lpD3DDevice->Present(NULL,NULL,NULL,NULL);
|
||||
d3d_lost_device();
|
||||
}
|
||||
#endif
|
||||
|
||||
// reset the gr_* stuff before trying to play a movie
|
||||
// clear the screen and hide the mouse cursor
|
||||
Mouse_hidden++;
|
||||
gr_reset_clip();
|
||||
gr_set_color(255, 255, 255);
|
||||
gr_set_clear_color(0, 0, 0);
|
||||
gr_zbuffer_clear(0);
|
||||
// clear first buffer
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
// clear second buffer (may not be one, but that's ok)
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
// clear third buffer (may not be one, but that's ok)
|
||||
gr_clear();
|
||||
gr_zbuffer_clear(1);
|
||||
gr_flip(); // cycle in the clear'd buffer
|
||||
|
||||
// This clears the screen
|
||||
InvalidateRect((HWND) os_get_window(), NULL, TRUE);
|
||||
PAINTSTRUCT paint_info;
|
||||
HDC clear_hdc = BeginPaint((HWND) os_get_window(),&paint_info);
|
||||
if (rc == MOVIE_OGG) {
|
||||
if (gr_screen.mode == GR_DIRECT3D) {
|
||||
mprintf(("MOVIE ERROR: Theora movies are not currently supported in Direct3D mode!\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(clear_hdc)
|
||||
{
|
||||
THEORAFILE *movie_ogg = theora_open(name);
|
||||
|
||||
POINT points[4] = {
|
||||
{0,0},
|
||||
{gr_screen.max_w,0},
|
||||
{gr_screen.max_w, gr_screen.max_h},
|
||||
{0, gr_screen.max_h}};
|
||||
|
||||
HBRUSH hBrush = CreateSolidBrush(0x00000000);
|
||||
HBRUSH hOldBrush = (HBRUSH)SelectObject(clear_hdc, hBrush);
|
||||
SelectObject(clear_hdc, hBrush);
|
||||
|
||||
Polygon(clear_hdc, points, 4);
|
||||
|
||||
SelectObject(clear_hdc, hOldBrush);
|
||||
DeleteObject(hBrush);
|
||||
|
||||
EndPaint((HWND) os_get_window(),&paint_info);
|
||||
if (movie_ogg) {
|
||||
// start playing ...
|
||||
theora_play(movie_ogg);
|
||||
|
||||
// ... done playing, close the movie
|
||||
theora_close(movie_ogg);
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
return false;
|
||||
}
|
||||
} else if (rc == MOVIE_MVE) {
|
||||
MVESTREAM *movie_mve = mve_open(name);
|
||||
|
||||
if (movie_mve) {
|
||||
// start playing ...
|
||||
mve_init(movie_mve);
|
||||
mve_play(movie_mve);
|
||||
|
||||
// ... done playing, close the movie
|
||||
mve_shutdown();
|
||||
mve_close(movie_mve);
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
process_messages();
|
||||
|
||||
if(OpenClip((HWND) os_get_window(), full_name))
|
||||
{
|
||||
|
||||
do
|
||||
{
|
||||
// Give system threads time to run (and don't sample user input madly)
|
||||
Sleep(100);
|
||||
|
||||
MSG msg;
|
||||
while(PeekMessage(&msg, (HWND) os_get_window(), 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
|
||||
|
||||
if(msg.message == WM_ERASEBKGND)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PassMsgToVideoWindow((HWND) os_get_window(), msg.message, msg.wParam, msg.lParam);
|
||||
|
||||
if(msg.message == WM_PAINT)
|
||||
{
|
||||
}
|
||||
|
||||
if(msg.message != WM_KEYDOWN)
|
||||
{
|
||||
// DefWindowProc((HWND) os_get_window(), msg.message, msg.wParam, msg.lParam);
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(msg.wParam )
|
||||
{
|
||||
// Quits movie if escape, space or return is pressed
|
||||
case VK_ESCAPE:
|
||||
case VK_SPACE:
|
||||
case VK_RETURN:
|
||||
{
|
||||
// Terminate movie playback early
|
||||
CloseClip((HWND) os_get_window());
|
||||
#ifndef NO_DIRECT3D
|
||||
if (gr_screen.mode == GR_DIRECT3D) {
|
||||
GlobalD3DVars::D3D_activate = 1;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Stream bit of the movie then handle windows messages
|
||||
while(dx8show_stream_movie() == false);
|
||||
|
||||
}
|
||||
|
||||
// We finished playing the movie
|
||||
CloseClip((HWND) os_get_window());
|
||||
|
||||
#ifndef NO_DIRECT3D
|
||||
if (gr_screen.mode == GR_DIRECT3D) {
|
||||
GlobalD3DVars::D3D_activate = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
STUB_FUNCTION;
|
||||
|
||||
#endif
|
||||
// show the mouse cursor again, and unpause the mainhall music
|
||||
Mouse_hidden--;
|
||||
main_hall_unpause();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool movie_play_two(char *name1, char *name2)
|
||||
void movie_play_two(char *name1, char *name2)
|
||||
{
|
||||
bool result1 = movie_play(name1);
|
||||
process_messages();
|
||||
bool result2 = movie_play(name2);
|
||||
|
||||
return result1 && result2;
|
||||
if ( movie_play(name1) )
|
||||
movie_play(name2);
|
||||
}
|
||||
+22
-1
@@ -1,8 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/cutscene/movie.h $
|
||||
* $Revision: 2.7 $
|
||||
* $Date: 2007-01-07 12:29:43 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* movie player header
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*/
|
||||
|
||||
#ifndef _MOVIE_HEADER_FILE
|
||||
#define _MOVIE_HEADER_FILE
|
||||
|
||||
bool movie_play(char *name);
|
||||
bool movie_play_two(char *name1, char *name2);
|
||||
void movie_play_two(char *name1, char *name2);
|
||||
|
||||
#endif
|
||||
@@ -1,12 +1,15 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/src/cutscene/mve_audio.cpp $
|
||||
* $Revision: 2.1 $
|
||||
* $Date: 2006-05-13 06:59:48 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.2 $
|
||||
* $Date: 2007-01-15 01:37:37 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Handles compressed audio data in MVE files
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.1 2006/05/13 06:59:48 taylor
|
||||
* MVE player (audio only works with OpenAL builds!)
|
||||
*
|
||||
* Revision 1.2 2005/03/29 07:50:34 taylor
|
||||
* Update to newest movie code with much better video support and audio support from
|
||||
* Pierre Willenbrock. Movies are enabled always now (no longer a build option)
|
||||
@@ -49,7 +52,7 @@ static int getWord(unsigned char **fin)
|
||||
|
||||
static void sendWord(short **fout, int nOffset)
|
||||
{
|
||||
*(*fout)++ = nOffset;
|
||||
*(*fout)++ = (short)nOffset;
|
||||
}
|
||||
|
||||
static void processSwath(short *fout, unsigned char *data, int swath, int *offsets)
|
||||
@@ -62,7 +65,7 @@ static void processSwath(short *fout, unsigned char *data, int swath, int *offse
|
||||
}
|
||||
}
|
||||
|
||||
void mveaudio_uncompress(short *buffer, unsigned char *data, int length)
|
||||
void mveaudio_uncompress(short *buffer, unsigned char *data)
|
||||
{
|
||||
int nCurOffsets[2];
|
||||
int swath;
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/src/cutscene/mvelib.cpp $
|
||||
* $Revision: 2.1 $
|
||||
* $Date: 2006-05-13 06:59:48 $
|
||||
* $Revision: 2.2 $
|
||||
* $Date: 2006-08-20 00:44:36 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* main lib for using MVEs
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.1 2006/05/13 06:59:48 taylor
|
||||
* MVE player (audio only works with OpenAL builds!)
|
||||
*
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*
|
||||
@@ -71,6 +74,11 @@ MVEFILE *mvefile_open(char *filename)
|
||||
// lower case filename for checking
|
||||
strncpy(lower_name, filename, strlen(filename)+1);
|
||||
strlwr(lower_name);
|
||||
|
||||
char *p = strchr( lower_name, '.' );
|
||||
if ( p ) *p = 0;
|
||||
|
||||
SAFE_STRCAT( lower_name, ".mve", sizeof(lower_name) );
|
||||
|
||||
// NOTE: CF_TYPE *must* be ANY to get movies off of the CDs
|
||||
// assume lower case filename for *nix
|
||||
|
||||
+164
-91
@@ -1,12 +1,29 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/cutscene/mveplayer.cpp $
|
||||
* $Revision: 2.1 $
|
||||
* $Date: 2006-05-13 06:59:48 $
|
||||
* $Revision: 2.5 $
|
||||
* $Date: 2007-02-10 00:02:18 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* MVE movie playing routines
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.4 2007/01/15 01:37:37 wmcoolmon
|
||||
* Fix CVS & correct various warnings under MSVC 2003
|
||||
*
|
||||
* Revision 2.3 2007/01/07 12:29:43 taylor
|
||||
* add Theora player
|
||||
* remove DirectShow support from movie player
|
||||
* fix triple-buffer page flipping problem (Mantis bug #1190)
|
||||
*
|
||||
* Revision 2.2 2006/08/20 00:44:36 taylor
|
||||
* add decoder for 8-bit MVEs
|
||||
* a basic fix for finding AVIs over MVEs, for mod dir stuff (this needs some CFILE support added to be a true fix, it's on the TODO list)
|
||||
* little bits of cleanup for old/unused code
|
||||
* make sure MVE filenames are correct in mvelib
|
||||
*
|
||||
* Revision 2.1 2006/05/13 06:59:48 taylor
|
||||
* MVE player (audio only works with OpenAL builds!)
|
||||
*
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*/
|
||||
@@ -19,6 +36,7 @@
|
||||
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
@@ -38,8 +56,6 @@ extern int Cmdline_noscalevid;
|
||||
static int mve_playing;
|
||||
|
||||
// timer variables
|
||||
static int g_spdFactorNum = 0;
|
||||
static int g_spdFactorDenom = 10;
|
||||
static int micro_frame_delay = 0;
|
||||
static int timer_started = 0;
|
||||
#ifdef SCP_UNIX
|
||||
@@ -50,8 +66,6 @@ static int timer_expire;
|
||||
|
||||
// audio variables
|
||||
#define MVE_AUDIO_BUFFERS 64 // total buffers to interact with stream
|
||||
static int mve_audio_buffer_curpos = 0;
|
||||
static int mve_audio_buffer_head = 0;
|
||||
static int mve_audio_buffer_tail = 0;
|
||||
static int mve_audio_playing = 0;
|
||||
static int mve_audio_canplay = 0;
|
||||
@@ -66,7 +80,6 @@ typedef struct MVE_AUDIO_T {
|
||||
int bytes_per_sec;
|
||||
int channels;
|
||||
int bitsize;
|
||||
ALuint audio_data[MVE_AUDIO_BUFFERS];
|
||||
ALuint source_id;
|
||||
ALuint audio_buffer[MVE_AUDIO_BUFFERS];
|
||||
} mve_audio_t;
|
||||
@@ -74,7 +87,7 @@ typedef struct MVE_AUDIO_T {
|
||||
mve_audio_t *mas; // mve_audio_stream
|
||||
|
||||
// audio decompressor
|
||||
extern void mveaudio_uncompress(short *buffer, unsigned char *data, int length);
|
||||
extern void mveaudio_uncompress(short *buffer, unsigned char *data);
|
||||
#endif // USE_OPENAL
|
||||
|
||||
// video variables
|
||||
@@ -83,11 +96,16 @@ void *g_vBuffers = NULL;
|
||||
void *g_vBackBuf1, *g_vBackBuf2;
|
||||
ushort *pixelbuf = NULL;
|
||||
static GLuint GLtex = 0;
|
||||
static GLint gl_screenYH = 0;
|
||||
static GLint gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
static GLfloat gl_screenV = 0;
|
||||
static int g_screenWidth, g_screenHeight;
|
||||
static int g_screenX, g_screenY;
|
||||
static int g_truecolor = 0;
|
||||
static ubyte g_palette[768];
|
||||
static ubyte *g_pCurMap=NULL;
|
||||
static int g_nMapLength=0;
|
||||
static ubyte *g_pCurMap = NULL;
|
||||
static int g_nMapLength = 0;
|
||||
static int videobuf_created, video_inited;
|
||||
static int hp2, wp2;
|
||||
static uint mve_video_skiptimer = 0;
|
||||
@@ -95,9 +113,11 @@ static int mve_scale_video = 0;
|
||||
|
||||
// video externs from API graphics functions
|
||||
extern void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out);
|
||||
extern GLenum GL_previous_texture_target;
|
||||
|
||||
// the decoder
|
||||
// the decoders
|
||||
extern void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
|
||||
extern void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
|
||||
|
||||
|
||||
/*************************
|
||||
@@ -114,16 +134,10 @@ void mve_end_movie()
|
||||
|
||||
int mve_timer_create(ubyte *data)
|
||||
{
|
||||
longlong temp;
|
||||
int rate = mve_get_int(data);
|
||||
int subd = mve_get_short(data+4);
|
||||
|
||||
micro_frame_delay = mve_get_int(data) * (int)mve_get_short(data+4);
|
||||
|
||||
if (g_spdFactorNum != 0) {
|
||||
temp = micro_frame_delay;
|
||||
temp *= g_spdFactorNum;
|
||||
temp /= g_spdFactorDenom;
|
||||
micro_frame_delay = (int)temp;
|
||||
}
|
||||
micro_frame_delay = rate * subd;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -293,7 +307,6 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
|
||||
memset(mas->audio_buffer, 0, MVE_AUDIO_BUFFERS * sizeof(ALuint));
|
||||
#endif // USE_OPENAL
|
||||
|
||||
mve_audio_buffer_head = 0;
|
||||
mve_audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_created = 1;
|
||||
@@ -333,6 +346,7 @@ static void mve_audio_stop()
|
||||
OpenAL_ErrorPrint( alSourceStop(mas->source_id) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &p) );
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, p, mas->audio_buffer) );
|
||||
OpenAL_ErrorPrint( alDeleteSources(1, &mas->source_id) );
|
||||
|
||||
for (int i = 0; i < MVE_AUDIO_BUFFERS; i++) {
|
||||
// make sure that the buffer is real before trying to delete, it could crash for some otherwise
|
||||
@@ -341,8 +355,6 @@ static void mve_audio_stop()
|
||||
}
|
||||
}
|
||||
|
||||
OpenAL_ErrorPrint( alDeleteSources(1, &mas->source_id) );
|
||||
|
||||
if (mas != NULL) {
|
||||
vm_free(mas);
|
||||
mas = NULL;
|
||||
@@ -367,12 +379,8 @@ 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) );
|
||||
|
||||
if (++mve_audio_buffer_head == MVE_AUDIO_BUFFERS)
|
||||
mve_audio_buffer_head = 0;
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return 0 );
|
||||
|
||||
@@ -394,7 +402,7 @@ int mve_audio_data(ubyte major, ubyte *data)
|
||||
nsamp += 4;
|
||||
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
mveaudio_uncompress(buf, data, -1); /* XXX */
|
||||
mveaudio_uncompress(buf, data); /* XXX */
|
||||
} else {
|
||||
nsamp -= 8;
|
||||
data += 8;
|
||||
@@ -447,13 +455,13 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
short count, truecolor;
|
||||
w = mve_get_short(data);
|
||||
h = mve_get_short(data+2);
|
||||
|
||||
|
||||
if (minor > 0) {
|
||||
count = mve_get_short(data+4);
|
||||
} else {
|
||||
count = 1;
|
||||
}
|
||||
|
||||
|
||||
if (minor > 1) {
|
||||
truecolor = mve_get_short(data+6);
|
||||
} else {
|
||||
@@ -471,41 +479,122 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
|
||||
if (truecolor)
|
||||
g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
|
||||
else
|
||||
g_vBackBuf2 = (ubyte *)g_vBackBuf1 + (g_width * g_height);
|
||||
|
||||
memset(g_vBackBuf1, 0, g_width * g_height * 4);
|
||||
|
||||
g_truecolor = truecolor;
|
||||
videobuf_created = 1;
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
GLfloat scale_by = 1.0f;
|
||||
|
||||
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)
|
||||
scale_by = (float)gr_screen.max_h / (float)g_height;
|
||||
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)) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glScalef( scale_by, scale_by, 1.0f );
|
||||
mve_scale_video = 1;
|
||||
}
|
||||
|
||||
if (mve_scale_video) {
|
||||
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_width) / 2);
|
||||
g_screenY = ((fl2i(gr_screen.max_h / scale_by + 0.5f) - g_height) / 2);
|
||||
} else {
|
||||
// centers on 1024x768, fills on 640x480
|
||||
g_screenX = ((gr_screen.max_w - g_width) / 2);
|
||||
g_screenY = ((gr_screen.max_h - g_height) / 2);
|
||||
}
|
||||
|
||||
// set additional values for screen width/height and UV coords
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
gl_screenYH = g_screenY + g_height;
|
||||
gl_screenXW = g_screenX + g_width;
|
||||
|
||||
if (GL_texture_target == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
gl_screenU = (GLfloat)g_width;
|
||||
gl_screenV = (GLfloat)g_height;
|
||||
} else {
|
||||
gl_screenU = i2fl(g_width) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_height) / i2fl(hp2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mve_convert_and_draw()
|
||||
{
|
||||
ushort *pDests;
|
||||
ushort *pSrcs;
|
||||
ushort *pSrcs = NULL;
|
||||
ushort *pixels = (ushort *)g_vBackBuf1;
|
||||
int x, y;
|
||||
|
||||
pSrcs = pixels;
|
||||
ubyte *pSrcs8 = NULL;
|
||||
ubyte *pixels8 = (ubyte *)g_vBackBuf1;
|
||||
ubyte r, g, b;
|
||||
ushort bit_16;
|
||||
|
||||
if (g_truecolor)
|
||||
pSrcs = pixels;
|
||||
else
|
||||
pSrcs8 = pixels8;
|
||||
|
||||
pDests = pixelbuf;
|
||||
|
||||
if (g_screenWidth > g_width) {
|
||||
pDests += ((g_screenWidth - g_width) / 2) / 2;
|
||||
}
|
||||
if (g_screenHeight > g_height) {
|
||||
pDests += ((g_screenHeight - g_height) / 2) * g_screenWidth;
|
||||
if (gr_screen.mode != GR_OPENGL) {
|
||||
if (g_screenWidth > g_width)
|
||||
pDests += ((g_screenWidth - g_width) / 2) / 2;
|
||||
|
||||
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++) {
|
||||
pDests[x] = (1<<15)|*pSrcs;
|
||||
if (g_truecolor) {
|
||||
Assert( pSrcs != NULL );
|
||||
|
||||
pSrcs++;
|
||||
pDests[x] = (1<<15)|*pSrcs;
|
||||
pSrcs++;
|
||||
} else {
|
||||
Assert( pSrcs8 != NULL );
|
||||
|
||||
// grab rgb color
|
||||
r = (g_palette[(*pSrcs8)*3] / 2);
|
||||
g = (g_palette[(*pSrcs8)*3 + 1] / 2);
|
||||
b = (g_palette[(*pSrcs8)*3 + 2] / 2);
|
||||
|
||||
// stuff the color
|
||||
bit_16 = (ushort)(r << Gr_t_red.shift);
|
||||
bit_16 |= (ushort)(g << Gr_t_green.shift);
|
||||
bit_16 |= (ushort)(b << Gr_t_blue.shift);
|
||||
bit_16 |= (ushort)(Gr_t_alpha.mask);
|
||||
|
||||
// stuff the pixel
|
||||
pDests[x] = (1<<15)|bit_16;
|
||||
|
||||
pSrcs8++;
|
||||
}
|
||||
}
|
||||
|
||||
pDests += g_screenWidth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mve_video_display()
|
||||
@@ -525,26 +614,23 @@ void mve_video_display()
|
||||
mve_video_skiptimer = 0;
|
||||
}
|
||||
|
||||
// because of something freaky in the Windows version, we need to clear the color buffer each frame
|
||||
gr_clear();
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
glBindTexture(GL_TEXTURE_2D, GLtex);
|
||||
glBindTexture(GL_texture_target, GLtex);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixelbuf);
|
||||
glTexSubImage2D(GL_texture_target, 0, 0, 0, g_width, g_height, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixelbuf);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(g_screenX, g_screenY);
|
||||
|
||||
glTexCoord2f(0, i2fl(g_screenHeight)/i2fl(hp2));
|
||||
glVertex2i(g_screenX, g_screenY+g_screenHeight);
|
||||
glTexCoord2f(0, gl_screenV);
|
||||
glVertex2i(g_screenX, gl_screenYH);
|
||||
|
||||
glTexCoord2f(i2fl(g_screenWidth)/i2fl(wp2), i2fl(g_screenHeight)/i2fl(hp2));
|
||||
glVertex2i(g_screenX+g_screenWidth, g_screenY+g_screenHeight);
|
||||
glTexCoord2f(gl_screenU, gl_screenV);
|
||||
glVertex2i(gl_screenXW, gl_screenYH);
|
||||
|
||||
glTexCoord2f(i2fl(g_screenWidth)/i2fl(wp2), 0);
|
||||
glVertex2i(g_screenX+g_screenWidth, g_screenY);
|
||||
glTexCoord2f(gl_screenU, 0);
|
||||
glVertex2i(gl_screenXW, g_screenY);
|
||||
glEnd();
|
||||
} else {
|
||||
// DDOI - This is probably really fricking slow
|
||||
@@ -575,7 +661,6 @@ void mve_video_display()
|
||||
}
|
||||
|
||||
//mprintf(("mve frame took this long: %.6f\n", f2fl(t2-t1) / 1000.0f));
|
||||
|
||||
}
|
||||
|
||||
int mve_video_init(ubyte *data)
|
||||
@@ -588,8 +673,11 @@ int mve_video_init(ubyte *data)
|
||||
width = mve_get_short(data);
|
||||
height = mve_get_short(data+2);
|
||||
|
||||
g_screenWidth = width;
|
||||
g_screenHeight = height;
|
||||
|
||||
// DDOI - Allocate RGB565 pixel buffer
|
||||
pixelbuf = (ushort *)vm_malloc(width * height * 2);
|
||||
pixelbuf = (ushort *)vm_malloc(g_screenWidth * g_screenHeight * 2);
|
||||
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
@@ -597,12 +685,13 @@ int mve_video_init(ubyte *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(pixelbuf, 0, width * height * 2);
|
||||
|
||||
g_screenWidth = width;
|
||||
g_screenHeight = height;
|
||||
memset(pixelbuf, 0, g_screenWidth * g_screenHeight * 2);
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
// set the appropriate texture target
|
||||
if ( Is_Extension_Enabled(OGL_ARB_TEXTURE_RECTANGLE) && !Is_Extension_Enabled(OGL_ARB_TEXTURE_NON_POWER_OF_TWO) )
|
||||
opengl_set_texture_target( GL_TEXTURE_RECTANGLE_ARB );
|
||||
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
glGenTextures(1, &GLtex);
|
||||
@@ -621,29 +710,22 @@ int mve_video_init(ubyte *data)
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, GLtex);
|
||||
glBindTexture(GL_texture_target, GLtex);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
float scale_by = (float)gr_screen.max_w / (float)g_screenWidth;
|
||||
|
||||
// don't bother setting anything if we aren't going to need it
|
||||
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glScalef( scale_by, scale_by, 1.0f );
|
||||
mve_scale_video = 1;
|
||||
}
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_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_TEXTURE_2D, 0, GL_RGB5_A1, wp2, hp2, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
||||
glTexImage2D(GL_texture_target, 0, GL_RGB5_A1, wp2, hp2, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
||||
|
||||
// set our color so that we can make sure that it's correct
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
#ifndef NO_DIRECT3D
|
||||
else if (gr_screen.mode == GR_DIRECT3D) {
|
||||
@@ -651,14 +733,6 @@ int mve_video_init(ubyte *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mve_scale_video) {
|
||||
g_screenX = g_screenY = 0;
|
||||
} else {
|
||||
// centers on 1024x768, fills on 640x480
|
||||
g_screenX = ((gr_screen.max_w - g_screenWidth) / 2);
|
||||
g_screenY = ((gr_screen.max_h - g_screenHeight) / 2);
|
||||
}
|
||||
|
||||
memset(g_palette, 0, 768);
|
||||
|
||||
video_inited = 1;
|
||||
@@ -702,7 +776,10 @@ void mve_video_data(ubyte *data, int len)
|
||||
g_vBackBuf2 = temp;
|
||||
}
|
||||
|
||||
decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
if (g_truecolor)
|
||||
decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
else
|
||||
decodeFrame8((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
}
|
||||
|
||||
void mve_end_chunk()
|
||||
@@ -713,8 +790,6 @@ void mve_end_chunk()
|
||||
void mve_init(MVESTREAM *mve)
|
||||
{
|
||||
// reset to default values
|
||||
mve_audio_buffer_curpos = 0;
|
||||
mve_audio_buffer_head = 0;
|
||||
mve_audio_buffer_tail = 0;
|
||||
mve_audio_playing = 0;
|
||||
mve_audio_canplay = 0;
|
||||
@@ -754,16 +829,14 @@ void mve_shutdown()
|
||||
if (mve_scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
opengl_switch_arb(-1, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_texture_target, 0);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
GLtex = 0;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
opengl_switch_arb(-1, 0);
|
||||
opengl_set_texture_target();
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
|
||||
@@ -0,0 +1,978 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/cutscene/oggplayer.cpp $
|
||||
* $Revision: 2.5 $
|
||||
* $Date: 2007-04-11 14:50:01 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* movie player code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.4 2007/03/22 20:23:42 taylor
|
||||
* fix stupidness that screwed up RGB values (Mantis #1307)
|
||||
*
|
||||
* Revision 2.3 2007/02/10 00:02:18 taylor
|
||||
* make sure that our color is getting set properly (should properly fix the red/green tint problem, Mantis #1041)
|
||||
* slight optimization for Theora YUV->RGB converter
|
||||
*
|
||||
* Revision 2.2 2007/01/14 10:26:37 wmcoolmon
|
||||
* Attempt to remove various warnings under MSVC 2003, mostly related to casting, but also some instances of inaccessible code.
|
||||
*
|
||||
* Revision 2.1 2007/01/07 12:29:43 taylor
|
||||
* add Theora player
|
||||
* remove DirectShow support from movie player
|
||||
* fix triple-buffer page flipping problem (Mantis bug #1190)
|
||||
*
|
||||
* Revision 1.0 2006/12/25 21:44:11 taylor
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*
|
||||
*/
|
||||
|
||||
// This player code is based largely on the player example in the libtheora package
|
||||
// and so they get a fair bit of credit for this code, even if in ideas/comments only
|
||||
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "io/key.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "sound/sound.h"
|
||||
#include "sound/ds.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cutscene/oggplayer.h"
|
||||
#include "io/timer.h"
|
||||
|
||||
#include "theora/theora.h"
|
||||
#include "vorbis/codec.h"
|
||||
|
||||
|
||||
extern int Cmdline_noscalevid;
|
||||
|
||||
static int hp2, wp2;
|
||||
static int video_inited = 0;
|
||||
static int scale_video = 0;
|
||||
static int playing = 1;
|
||||
static ubyte *pixelbuf = NULL;
|
||||
static uint g_screenWidth = 0;
|
||||
static uint g_screenHeight = 0;
|
||||
static int g_screenX = 0;
|
||||
static int g_screenY = 0;
|
||||
|
||||
static GLuint GLtex = 0;
|
||||
static GLint gl_screenYH = 0;
|
||||
static GLint gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
static GLfloat gl_screenV = 0;
|
||||
|
||||
// video externs from API graphics functions
|
||||
extern void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out);
|
||||
|
||||
static int timer_started = 0;
|
||||
static longlong base_time = -1;
|
||||
#ifdef SCP_UNIX
|
||||
static struct timeval timer_expire = { 0, 0 };
|
||||
#else
|
||||
static int timer_expire;
|
||||
#endif
|
||||
|
||||
static int audio_inited = 0;
|
||||
static int audio_buffer_tail = 0;
|
||||
static ALuint audio_sid = 0;
|
||||
#define OGG_AUDIO_BUFFERS 15
|
||||
static ALuint audio_buffers[OGG_AUDIO_BUFFERS];
|
||||
|
||||
// single audio fragment audio buffering
|
||||
static int audiobuf_fill = 0;
|
||||
static short *audiobuf = NULL;
|
||||
static longlong audiobuf_granulepos = 0; // time position of last sample
|
||||
static int audiofd_fragsize = 0;
|
||||
|
||||
// single frame video buffering
|
||||
static longlong videobuf_granulepos = -1;
|
||||
static double videobuf_time = 0;
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utility items
|
||||
//
|
||||
|
||||
// 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, 4096);
|
||||
int bytes = cfread(buffer, 1, 4096, movie->cfp);
|
||||
|
||||
ogg_sync_wrote(&movie->osyncstate, bytes);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
// helper: push a page into the appropriate steam
|
||||
// this can be done blindly; a stream won't accept a page that doesn't belong to it
|
||||
static void OGG_queue_page(THEORAFILE *movie)
|
||||
{
|
||||
Assert( movie->theora_p );
|
||||
|
||||
ogg_stream_pagein(&movie->t_osstate, &movie->opage);
|
||||
|
||||
if (movie->vorbis_p)
|
||||
ogg_stream_pagein(&movie->v_osstate, &movie->opage);
|
||||
}
|
||||
|
||||
// get relative time since beginning playback, compensating for A/V drift
|
||||
static double OGG_get_time()
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
longlong now;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
now = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
if (base_time == -1)
|
||||
base_time = now;
|
||||
|
||||
return (now - base_time) * 0.001;
|
||||
#else
|
||||
if (base_time == -1)
|
||||
base_time = timer_get_milliseconds();
|
||||
|
||||
return (timer_get_milliseconds() - base_time) * 0.001;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void OGG_timer_init()
|
||||
{
|
||||
#if SCP_UNIX
|
||||
int nsec = 0;
|
||||
|
||||
gettimeofday(&timer_expire, NULL);
|
||||
|
||||
timer_expire.tv_usec += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
timer_expire = timer_get_microseconds();
|
||||
timer_expire += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
#endif
|
||||
|
||||
timer_started = 1;
|
||||
}
|
||||
|
||||
static void OGG_timer_do_wait()
|
||||
{
|
||||
if (!timer_started)
|
||||
OGG_timer_init();
|
||||
|
||||
#if SCP_UNIX
|
||||
int nsec = 0;
|
||||
struct timespec ts, tsRem;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
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) )
|
||||
goto end;
|
||||
|
||||
ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
|
||||
ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
|
||||
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1000000000UL;
|
||||
--ts.tv_sec;
|
||||
}
|
||||
|
||||
if ( (nanosleep(&ts, &tsRem) == -1) && (errno == EINTR) ) {
|
||||
// so we got an error that was a signal interupt, try to sleep again with remainder of time
|
||||
if ( (nanosleep(&tsRem, NULL) == -1) && (errno == EINTR) ) {
|
||||
mprintf(("MVE: Timer error! Aborting movie playback!\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
timer_expire.tv_usec += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
|
||||
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)
|
||||
goto end;
|
||||
|
||||
ts = timer_expire - tv;
|
||||
|
||||
ts2 = ts/1000;
|
||||
|
||||
Sleep(ts2);
|
||||
|
||||
end:
|
||||
timer_expire += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// End Utility items
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// That wonderful Audio
|
||||
//
|
||||
|
||||
static void OGG_audio_init(vorbis_info *vinfo)
|
||||
{
|
||||
if (audio_inited)
|
||||
return;
|
||||
|
||||
Assert( vinfo != NULL );
|
||||
|
||||
audio_inited = 1;
|
||||
|
||||
OpenAL_ErrorCheck( alGenSources(1, &audio_sid), return );
|
||||
OpenAL_ErrorPrint( alSourcef(audio_sid, AL_GAIN, 1.0f) );
|
||||
|
||||
memset( &audio_buffers, 0, sizeof(ALuint) * OGG_AUDIO_BUFFERS );
|
||||
|
||||
audiofd_fragsize = (((vinfo->channels * 16) / 8) * vinfo->rate);
|
||||
|
||||
audiobuf = (short *) vm_malloc(audiofd_fragsize);
|
||||
}
|
||||
|
||||
static void OGG_audio_close()
|
||||
{
|
||||
if ( !audio_inited )
|
||||
return;
|
||||
|
||||
audio_inited = 0;
|
||||
|
||||
ALint p = 0;
|
||||
|
||||
OpenAL_ErrorPrint( alSourceStop(audio_sid) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(audio_sid, AL_BUFFERS_PROCESSED, &p) );
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(audio_sid, p, audio_buffers) );
|
||||
OpenAL_ErrorPrint( alDeleteSources(1, &audio_sid) );
|
||||
|
||||
for (int i = 0; i < OGG_AUDIO_BUFFERS; i++) {
|
||||
// make sure that the buffer is real before trying to delete, it could crash for some otherwise
|
||||
if ( (audio_buffers[i] != 0) && alIsBuffer(audio_buffers[i]) ) {
|
||||
OpenAL_ErrorPrint( alDeleteBuffers(1, &audio_buffers[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
audio_sid = 0;
|
||||
audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_fill = 0;
|
||||
audiobuf_granulepos = 0;
|
||||
audiofd_fragsize = 0;
|
||||
|
||||
if (audiobuf != NULL) {
|
||||
vm_free(audiobuf);
|
||||
audiobuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void OGG_audio_write(vorbis_info *vorbis, bool *ready)
|
||||
{
|
||||
ALint status, queued, processed = 0;
|
||||
ALuint bid = 0;
|
||||
|
||||
if ( !audio_inited || !(*ready) )
|
||||
return;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_BUFFERS_PROCESSED, &processed), return );
|
||||
|
||||
while (processed-- > 2)
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(audio_sid, 1, &bid) );
|
||||
|
||||
if ( !(*ready) )
|
||||
return;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_BUFFERS_QUEUED, &queued), return );
|
||||
|
||||
if ( audiobuf_fill && (queued < OGG_AUDIO_BUFFERS) ) {
|
||||
if ( !audio_buffers[audio_buffer_tail] )
|
||||
OpenAL_ErrorCheck( alGenBuffers(1, &audio_buffers[audio_buffer_tail]), return );
|
||||
|
||||
ALenum format = (vorbis->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
|
||||
|
||||
OpenAL_ErrorCheck( alBufferData(audio_buffers[audio_buffer_tail], format, audiobuf, audiobuf_fill, vorbis->rate), return );
|
||||
|
||||
OpenAL_ErrorCheck( alSourceQueueBuffers(audio_sid, 1, &audio_buffers[audio_buffer_tail]), return );
|
||||
|
||||
if (++audio_buffer_tail == OGG_AUDIO_BUFFERS)
|
||||
audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_fill = 0;
|
||||
*ready = false;
|
||||
} else {
|
||||
// mprintf(("Theora WARN: Buffer overrun: Queue full\n"));
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_SOURCE_STATE, &status), return );
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_BUFFERS_QUEUED, &queued), return );
|
||||
|
||||
if ( (status != AL_PLAYING) && (queued > 0) )
|
||||
OpenAL_ErrorPrint( alSourcePlay(audio_sid) );
|
||||
}
|
||||
|
||||
//
|
||||
// End Audio stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Video related stuff
|
||||
//
|
||||
|
||||
static void OGG_video_init(theora_info *tinfo)
|
||||
{
|
||||
float scale_by = 0.0f;
|
||||
|
||||
if (video_inited)
|
||||
return;
|
||||
|
||||
Assert( tinfo != NULL );
|
||||
|
||||
g_screenWidth = tinfo->frame_width;
|
||||
g_screenHeight = tinfo->frame_height;
|
||||
|
||||
|
||||
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 (gr_screen.mode == GR_OPENGL) {
|
||||
// set the appropriate texture target
|
||||
if ( Is_Extension_Enabled(OGL_ARB_TEXTURE_RECTANGLE) && !Is_Extension_Enabled(OGL_ARB_TEXTURE_NON_POWER_OF_TWO) )
|
||||
opengl_set_texture_target( GL_TEXTURE_RECTANGLE_ARB );
|
||||
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// disable everything but what we need
|
||||
opengl_switch_arb(-1, 0);
|
||||
opengl_switch_arb(0, 1);
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
|
||||
glBindTexture(GL_texture_target, GLtex);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_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);
|
||||
|
||||
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
|
||||
float movie_ratio = (float)g_screenWidth / (float)g_screenHeight;
|
||||
|
||||
if (screen_ratio > movie_ratio)
|
||||
scale_by = (float)gr_screen.max_h / (float)g_screenHeight;
|
||||
else
|
||||
scale_by = (float)gr_screen.max_w / (float)g_screenWidth;
|
||||
|
||||
// don't bother setting anything if we aren't going to need it
|
||||
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glScalef( scale_by, scale_by, -1.0f );
|
||||
scale_video = 1;
|
||||
}
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_texture_target, 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
// set our color so that we can make sure that it's correct
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
#ifndef NO_DIRECT3D
|
||||
else if (gr_screen.mode == GR_DIRECT3D) {
|
||||
// TODO: is there a fast way to do frames in D3D too?
|
||||
}
|
||||
#endif
|
||||
|
||||
if (scale_video) {
|
||||
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_screenWidth) / 2);
|
||||
g_screenY = ((fl2i(gr_screen.max_h / scale_by + 0.5f) - g_screenHeight) / 2);
|
||||
} else {
|
||||
// centers on 1024x768, fills on 640x480
|
||||
g_screenX = ((gr_screen.max_w - g_screenWidth) / 2);
|
||||
g_screenY = ((gr_screen.max_h - g_screenHeight) / 2);
|
||||
}
|
||||
|
||||
// set additional values for screen width/height and UV coords
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
gl_screenYH = g_screenY + g_screenHeight;
|
||||
gl_screenXW = g_screenX + g_screenWidth;
|
||||
|
||||
if (GL_texture_target == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
gl_screenU = (GLfloat)wp2;
|
||||
gl_screenV = (GLfloat)hp2;
|
||||
} else {
|
||||
gl_screenU = i2fl(g_screenWidth) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_screenHeight) / i2fl(hp2);
|
||||
}
|
||||
}
|
||||
|
||||
video_inited = 1;
|
||||
}
|
||||
|
||||
static void OGG_video_close()
|
||||
{
|
||||
if (!video_inited)
|
||||
return;
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
if (scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
opengl_switch_arb(-1, 0);
|
||||
|
||||
glBindTexture(GL_texture_target, 0);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
GLtex = 0;
|
||||
|
||||
opengl_set_texture_target();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
vm_free(pixelbuf);
|
||||
pixelbuf = NULL;
|
||||
}
|
||||
|
||||
video_inited = 0;
|
||||
scale_video = 0;
|
||||
pixelbuf = NULL;
|
||||
g_screenWidth = 0;
|
||||
g_screenHeight = 0;
|
||||
g_screenX = 0;
|
||||
g_screenY = 0;
|
||||
|
||||
GLtex = 0;
|
||||
gl_screenYH = 0;
|
||||
gl_screenXW = 0;
|
||||
gl_screenU = 0;
|
||||
gl_screenV = 0;
|
||||
}
|
||||
|
||||
static void convert_YUV_to_RGB(yuv_buffer *yuv)
|
||||
{
|
||||
int Y1, Y2, U, V;
|
||||
int R = 0, G = 0, B = 0;
|
||||
int C, D, E;
|
||||
uint x, y;
|
||||
uint width_2 = g_screenWidth/2;
|
||||
|
||||
ubyte *pix = &pixelbuf[0];
|
||||
|
||||
ubyte *y_ptr = (ubyte *)yuv->y;
|
||||
ubyte *u_ptr = (ubyte *)yuv->u;
|
||||
ubyte *v_ptr = (ubyte *)yuv->v;
|
||||
|
||||
for (y = 0; y < g_screenHeight; y++) {
|
||||
for (x = 0; x < width_2; x++) {
|
||||
// we need two pixels of Y
|
||||
Y1 = *y_ptr; y_ptr++;
|
||||
Y2 = *y_ptr; y_ptr++;
|
||||
|
||||
// only one pixel of U and V (half the size of Y)
|
||||
U = u_ptr[x];
|
||||
V = v_ptr[x];
|
||||
|
||||
D = (U - 128);
|
||||
E = (V - 128);
|
||||
|
||||
// first pixel
|
||||
C = (Y1 - 16) * 298;
|
||||
|
||||
R = ((C + 409 * E + 128) >> 8);
|
||||
G = ((C - 100 * D - 208 * E + 128) >> 8);
|
||||
B = ((C + 516 * D + 128) >> 8);
|
||||
|
||||
CLAMP(R, 0, 255);
|
||||
CLAMP(G, 0, 255);
|
||||
CLAMP(B, 0, 255);
|
||||
|
||||
*pix++ = (ubyte)B;
|
||||
*pix++ = (ubyte)G;
|
||||
*pix++ = (ubyte)R;
|
||||
|
||||
// second pixel (U and V values are resused)
|
||||
C = (Y2 - 16) * 298;
|
||||
|
||||
R = ((C + 409 * E + 128) >> 8);
|
||||
G = ((C - 100 * D - 208 * E + 128) >> 8);
|
||||
B = ((C + 516 * D + 128) >> 8);
|
||||
|
||||
CLAMP(R, 0, 255);
|
||||
CLAMP(G, 0, 255);
|
||||
CLAMP(B, 0, 255);
|
||||
|
||||
*pix++ = (ubyte)B;
|
||||
*pix++ = (ubyte)G;
|
||||
*pix++ = (ubyte)R;
|
||||
}
|
||||
|
||||
y_ptr += (yuv->y_stride - yuv->y_width);
|
||||
|
||||
// u and v have to be done every other row (it's a 2x2 block)
|
||||
if (y % 2) {
|
||||
u_ptr += yuv->uv_stride;
|
||||
v_ptr += yuv->uv_stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void OGG_video_draw(theora_state *tstate)
|
||||
{
|
||||
yuv_buffer yuv;
|
||||
|
||||
theora_decode_YUVout(tstate, &yuv);
|
||||
convert_YUV_to_RGB(&yuv);
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
glBindTexture(GL_texture_target, GLtex);
|
||||
|
||||
glTexSubImage2D(GL_texture_target, 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(g_screenX, g_screenY);
|
||||
|
||||
glTexCoord2f(0, gl_screenV);
|
||||
glVertex2i(g_screenX, gl_screenYH);
|
||||
|
||||
glTexCoord2f(gl_screenU, gl_screenV);
|
||||
glVertex2i(gl_screenXW, gl_screenYH);
|
||||
|
||||
glTexCoord2f(gl_screenU, 0);
|
||||
glVertex2i(gl_screenXW, g_screenY);
|
||||
glEnd();
|
||||
} else {
|
||||
// TODO: FIXME!!!!
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
os_poll();
|
||||
|
||||
int k = key_inkey();
|
||||
switch (k) {
|
||||
case KEY_ESC:
|
||||
case KEY_ENTER:
|
||||
case KEY_SPACEBAR:
|
||||
playing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End Video related stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// The global stuff...
|
||||
//
|
||||
|
||||
// close out a theora movie and free it's memory
|
||||
void theora_close(THEORAFILE *movie)
|
||||
{
|
||||
Assert( movie != NULL );
|
||||
|
||||
timer_started = 0;
|
||||
base_time = -1;
|
||||
|
||||
videobuf_granulepos = -1;
|
||||
videobuf_time = 0;
|
||||
|
||||
if (movie->vorbis_p) {
|
||||
ogg_stream_clear(&movie->v_osstate);
|
||||
|
||||
vorbis_block_clear(&movie->vblock);
|
||||
vorbis_dsp_clear(&movie->vstate);
|
||||
vorbis_comment_clear(&movie->vcomment);
|
||||
vorbis_info_clear(&movie->vinfo);
|
||||
}
|
||||
|
||||
if (movie->theora_p) {
|
||||
ogg_stream_clear(&movie->t_osstate);
|
||||
|
||||
theora_clear(&movie->tstate);
|
||||
theora_comment_clear(&movie->tcomment);
|
||||
theora_info_clear(&movie->tinfo);
|
||||
}
|
||||
|
||||
ogg_sync_clear(&movie->osyncstate);
|
||||
|
||||
// free the stream
|
||||
if (movie->cfp)
|
||||
cfclose(movie->cfp);
|
||||
|
||||
// free the struct
|
||||
vm_free(movie);
|
||||
|
||||
playing = 1;
|
||||
}
|
||||
|
||||
// opens a theora file, verifies we can use it, initializes everything needed
|
||||
// to decode and use the file
|
||||
THEORAFILE *theora_open(char *filename)
|
||||
{
|
||||
char lower_name[MAX_FILENAME_LEN];
|
||||
THEORAFILE *movie;
|
||||
int stateflag = 0;
|
||||
|
||||
|
||||
// create the file
|
||||
movie = (THEORAFILE *) vm_malloc_q( sizeof(THEORAFILE) );
|
||||
|
||||
if (movie == NULL)
|
||||
return NULL;
|
||||
|
||||
memset( movie, 0, sizeof(THEORAFILE) );
|
||||
|
||||
// lower case filename for checking
|
||||
memset( lower_name, 0, sizeof(lower_name) );
|
||||
strncpy( lower_name, filename, strlen(filename) );
|
||||
strlwr(lower_name);
|
||||
|
||||
char *p = strchr( lower_name, '.' );
|
||||
if ( p ) *p = 0;
|
||||
|
||||
SAFE_STRCAT( lower_name, ".ogg", sizeof(lower_name) );
|
||||
|
||||
// NOTE: Because the .ogg extension is used for both movies and sounds, we have to
|
||||
// be a bit more specific about our search locations, so we look only in the
|
||||
// two places that Theora movies might exist.
|
||||
movie->cfp = cfopen(lower_name, "rb", CFILE_NORMAL, CF_TYPE_ROOT);
|
||||
|
||||
if (movie->cfp == NULL)
|
||||
movie->cfp = cfopen(lower_name, "rb", CFILE_NORMAL, CF_TYPE_MOVIES);
|
||||
|
||||
if (movie->cfp == NULL) {
|
||||
mprintf(("Theora ERROR: Unable to find and open movie file named '%s'\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// start up Ogg stream synchronization layer
|
||||
ogg_sync_init(&movie->osyncstate);
|
||||
|
||||
// init supporting Vorbis structures needed in header parsing
|
||||
vorbis_info_init(&movie->vinfo);
|
||||
vorbis_comment_init(&movie->vcomment);
|
||||
|
||||
// init supporting Theora structures needed in header parsing
|
||||
theora_comment_init(&movie->tcomment);
|
||||
theora_info_init(&movie->tinfo);
|
||||
|
||||
// ogg file open so parse the headers
|
||||
// we are only interested in Vorbis/Theora streams
|
||||
while ( !stateflag ) {
|
||||
int ret = OGG_buffer_data(movie);
|
||||
|
||||
if (ret == 0)
|
||||
break;
|
||||
|
||||
while (ogg_sync_pageout(&movie->osyncstate, &movie->opage) > 0) {
|
||||
ogg_stream_state test;
|
||||
|
||||
// is this a mandated initial header? If not, stop parsing
|
||||
if ( !ogg_page_bos(&movie->opage) ) {
|
||||
// don't leak the page; get it into the appropriate stream
|
||||
OGG_queue_page(movie);
|
||||
stateflag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ogg_stream_init(&test, ogg_page_serialno(&movie->opage));
|
||||
ogg_stream_pagein(&test, &movie->opage);
|
||||
ogg_stream_packetout(&test, &movie->opacket);
|
||||
|
||||
// identify the codec: try theora
|
||||
if ( !movie->theora_p && (theora_decode_header(&movie->tinfo, &movie->tcomment, &movie->opacket) >= 0) ) {
|
||||
// it is theora
|
||||
memcpy( &movie->t_osstate, &test, sizeof(test) );
|
||||
movie->theora_p = 1;
|
||||
} else if ( !movie->vorbis_p && (vorbis_synthesis_headerin(&movie->vinfo, &movie->vcomment, &movie->opacket) >= 0) ) {
|
||||
// it is vorbis
|
||||
memcpy( &movie->v_osstate, &test, sizeof(test) );
|
||||
movie->vorbis_p = 1;
|
||||
} else {
|
||||
// whatever it is, we don't care about it
|
||||
ogg_stream_clear(&test);
|
||||
}
|
||||
}
|
||||
// fall through to non-bos page parsing
|
||||
}
|
||||
|
||||
// if we don't have usable video then bail out now
|
||||
if ( !movie->theora_p ) {
|
||||
mprintf(("Theora ERROR: Unable to find video data in '%s'\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// go ahead and do some audio stream error checking...
|
||||
if ( (movie->vinfo.channels < 0) || (movie->vinfo.channels > 2) ) {
|
||||
mprintf(("Theora ERROR: Unsupported number of audio channels!\n"));
|
||||
movie->vorbis_p = 0;
|
||||
}
|
||||
|
||||
// if we don't have usable audio then close out it's partial setup and just use the video
|
||||
if ( !Sound_enabled || !movie->vorbis_p ) {
|
||||
vorbis_info_clear(&movie->vinfo);
|
||||
vorbis_comment_clear(&movie->vcomment);
|
||||
movie->vorbis_p = 0;
|
||||
}
|
||||
|
||||
// we're expecting more header packets.
|
||||
while ( (movie->theora_p < 3) || (movie->vorbis_p && (movie->vorbis_p < 3)) ) {
|
||||
int ret;
|
||||
|
||||
// look for further theora headers
|
||||
while ( (movie->theora_p < 3) && (ret = ogg_stream_packetout(&movie->t_osstate, &movie->opacket)) ){
|
||||
if ( (ret < 0) || theora_decode_header(&movie->tinfo, &movie->tcomment, &movie->opacket) ) {
|
||||
mprintf(("Theora ERROR: Error parsing Theora stream headers on '%s'! Corrupt stream?\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (++movie->theora_p == 3)
|
||||
break;
|
||||
}
|
||||
|
||||
// look for more vorbis header packets
|
||||
while ( movie->vorbis_p && (movie->vorbis_p < 3) && (ret = ogg_stream_packetout(&movie->v_osstate, &movie->opacket)) ) {
|
||||
if ( (ret < 0) || vorbis_synthesis_headerin(&movie->vinfo, &movie->vcomment, &movie->opacket) ) {
|
||||
mprintf(("Theora ERROR: Error parsing Vorbis stream headers on '%s'! Corrupt stream?\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (++movie->vorbis_p == 3)
|
||||
break;
|
||||
}
|
||||
|
||||
// The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec
|
||||
|
||||
if ( ogg_sync_pageout(&movie->osyncstate, &movie->opage) > 0 ) {
|
||||
OGG_queue_page(movie); // demux into the appropriate stream
|
||||
} else {
|
||||
int ret = OGG_buffer_data(movie); // someone needs more data
|
||||
|
||||
if ( ret == 0 ) {
|
||||
mprintf(("Theora ERROR: End of file while searching for codec headers in '%s'!\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize video decoder
|
||||
theora_decode_init(&movie->tstate, &movie->tinfo);
|
||||
|
||||
// and now for video stream error checking...
|
||||
if (movie->tinfo.pixelformat != OC_PF_420) {
|
||||
mprintf(("Theora ERROR: Only the yuv420p chroma is supported!\n"));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (movie->tinfo.offset_x || movie->tinfo.offset_y) {
|
||||
mprintf(("Theora ERROR: Player does not support frame offsets!\n"));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if ( (movie->tinfo.frame_width > 640) || (movie->tinfo.frame_height > 480) ) {
|
||||
mprintf(("Theora ERROR: Movies must be no larger than 640x480!\n"));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// initialize audio decoder, if there is audio
|
||||
if (movie->vorbis_p) {
|
||||
vorbis_synthesis_init(&movie->vstate, &movie->vinfo);
|
||||
vorbis_block_init(&movie->vstate, &movie->vblock);
|
||||
}
|
||||
|
||||
return movie;
|
||||
|
||||
|
||||
Error:
|
||||
theora_close(movie);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// play that funky music... err, movie!
|
||||
void theora_play(THEORAFILE *movie)
|
||||
{
|
||||
int i, j;
|
||||
bool stateflag = false;
|
||||
bool videobuf_ready = false;
|
||||
bool audiobuf_ready = false;
|
||||
double last_time = 0.0; // for frame skipper
|
||||
|
||||
if ( (movie == NULL) || !movie->theora_p )
|
||||
return;
|
||||
|
||||
// open audio
|
||||
if (movie->vorbis_p)
|
||||
OGG_audio_init(&movie->vinfo);
|
||||
|
||||
// open video
|
||||
OGG_video_init(&movie->tinfo);
|
||||
|
||||
// on to the main decode loop. We assume in this example that audio
|
||||
// and video start roughly together, and don't begin playback until
|
||||
// we have a start frame for both. This is not necessarily a valid
|
||||
// assumption in Ogg A/V streams! It will always be true of the
|
||||
// example_encoder (and most streams) though.
|
||||
|
||||
while (playing) {
|
||||
// we want a video and audio frame ready to go at all times. If
|
||||
// we have to buffer incoming, buffer the compressed data (ie, let
|
||||
// ogg do the buffering)
|
||||
while ( movie->vorbis_p && !audiobuf_ready ) {
|
||||
int ret;
|
||||
float **pcm;
|
||||
|
||||
// if there's pending, decoded audio, grab it
|
||||
if ( (ret = vorbis_synthesis_pcmout(&movie->vstate, &pcm)) > 0 ) {
|
||||
int count = (audiobuf_fill / 2);
|
||||
int maxsamples = (audiofd_fragsize - audiobuf_fill) / 2 / movie->vinfo.channels;
|
||||
|
||||
for (i = 0; (i < ret) && (i < maxsamples); i++) {
|
||||
for (j = 0; j < movie->vinfo.channels; j++) {
|
||||
int val = fl2i(pcm[j][i] * 32767.0f + 0.5f);
|
||||
|
||||
if (val > 32767)
|
||||
val = 32767;
|
||||
|
||||
if (val < -32768)
|
||||
val = -32768;
|
||||
|
||||
audiobuf[count++] = (short)val;
|
||||
}
|
||||
}
|
||||
|
||||
vorbis_synthesis_read(&movie->vstate, i);
|
||||
|
||||
audiobuf_fill += (i * movie->vinfo.channels * 2);
|
||||
|
||||
if (audiobuf_fill == audiofd_fragsize)
|
||||
audiobuf_ready = true;
|
||||
|
||||
if (movie->vstate.granulepos >= 0)
|
||||
audiobuf_granulepos = movie->vstate.granulepos - ret + i;
|
||||
else
|
||||
audiobuf_granulepos += i;
|
||||
} else {
|
||||
// no pending audio; is there a pending packet to decode?
|
||||
if ( ogg_stream_packetout(&movie->v_osstate, &movie->opacket) > 0 ) {
|
||||
if ( vorbis_synthesis(&movie->vblock, &movie->opacket) == 0 )
|
||||
vorbis_synthesis_blockin(&movie->vstate, &movie->vblock);
|
||||
}
|
||||
// we need more data; break out to suck in another page
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ( !videobuf_ready ) {
|
||||
// theora is one in, one out...
|
||||
if ( ogg_stream_packetout(&movie->t_osstate, &movie->opacket) <= 0 )
|
||||
break;
|
||||
|
||||
theora_decode_packetin(&movie->tstate, &movie->opacket);
|
||||
|
||||
videobuf_time = theora_granule_time(&movie->tstate, movie->tstate.granulepos);
|
||||
|
||||
double now_time = OGG_get_time();
|
||||
double delay = videobuf_time - OGG_get_time();
|
||||
|
||||
// if we are running slow then skip the frame, otherwise to go into ready mode
|
||||
if ( (delay >= 0.0) || (now_time - last_time >= 1.0) )
|
||||
videobuf_ready = true;
|
||||
}
|
||||
|
||||
if ( !videobuf_ready && (movie->vorbis_p && !audiobuf_ready) && cfeof(movie->cfp) )
|
||||
break;
|
||||
|
||||
if ( !videobuf_ready || (movie->vorbis_p && !audiobuf_ready) ) {
|
||||
// no data yet for somebody. Grab another page
|
||||
OGG_buffer_data(movie);
|
||||
|
||||
while (ogg_sync_pageout(&movie->osyncstate, &movie->opage) > 0)
|
||||
OGG_queue_page(movie);
|
||||
}
|
||||
|
||||
// If playback has begun, top audio buffer off immediately.
|
||||
if ( stateflag )
|
||||
OGG_audio_write(&movie->vinfo, &audiobuf_ready);
|
||||
|
||||
// are we at or past time for this video frame?
|
||||
if ( stateflag && videobuf_ready && (videobuf_time <= OGG_get_time()) ) {
|
||||
OGG_video_draw(&movie->tstate);
|
||||
last_time = OGG_get_time();
|
||||
videobuf_ready = false;
|
||||
}
|
||||
|
||||
// if our buffers either don't exist or are ready to go, we can begin playback
|
||||
if ( videobuf_ready && (audiobuf_ready || !movie->vorbis_p) )
|
||||
stateflag = true;
|
||||
|
||||
// bail if we run into eof
|
||||
// if ( cfeof(movie->cfp) )
|
||||
// break;
|
||||
|
||||
if (videobuf_ready)
|
||||
OGG_timer_do_wait();
|
||||
}
|
||||
|
||||
// tear it all down
|
||||
OGG_audio_close();
|
||||
OGG_video_close();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* $Logfile: /Freespace2/src/cutscene/oggplayer.h $
|
||||
* $Revision: 2.1 $
|
||||
* $Date: 2007-01-07 12:29:43 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* main lib for using Theora movies
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.1.2.1 2006/12/25 21:44:11 taylor
|
||||
* initial OGG Theora movie support (likely to be rewritten at least in large part)
|
||||
*
|
||||
*
|
||||
* $NoKeywords: $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OGGPLAYER_H
|
||||
#define _OGGPLAYER_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "theora/theora.h"
|
||||
#include "vorbis/codec.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
// structure for maintaining info on a THEORAFILE stream
|
||||
typedef struct THEORAFILE
|
||||
{
|
||||
CFILE *cfp;
|
||||
ubyte theora_p;
|
||||
ubyte vorbis_p;
|
||||
|
||||
ogg_sync_state osyncstate;
|
||||
ogg_page opage;
|
||||
ogg_packet opacket;
|
||||
ogg_stream_state v_osstate;
|
||||
ogg_stream_state t_osstate;
|
||||
|
||||
theora_info tinfo;
|
||||
theora_comment tcomment;
|
||||
theora_state tstate;
|
||||
|
||||
vorbis_info vinfo;
|
||||
vorbis_dsp_state vstate;
|
||||
vorbis_block vblock;
|
||||
vorbis_comment vcomment;
|
||||
} THEORAFILE;
|
||||
|
||||
void theora_play(THEORAFILE *movie);
|
||||
THEORAFILE *theora_open(char *filename);
|
||||
void theora_close(THEORAFILE *movie);
|
||||
|
||||
#endif
|
||||
@@ -493,7 +493,7 @@ const char *dds_error_string(int code)
|
||||
return "Cubemaps must have all 6 faces";
|
||||
|
||||
default:
|
||||
return "Abort, retry, fail?";
|
||||
break;
|
||||
}
|
||||
|
||||
//get a warning otherwise
|
||||
|
||||
+183
-93
@@ -9,13 +9,46 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Debris/Debris.cpp $
|
||||
* $Revision: 2.23 $
|
||||
* $Date: 2006-01-26 03:23:29 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.32 $
|
||||
* $Date: 2007-03-22 21:55:01 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Code for the pieces of exploding object debris.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.31 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 2.30 2007/02/11 09:22:29 taylor
|
||||
* remove NO_SOUND
|
||||
* fix debris recycling
|
||||
*
|
||||
* Revision 2.29 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.28 2006/09/11 06:45:39 taylor
|
||||
* various small compiler warning and strict compiling fixes
|
||||
*
|
||||
* Revision 2.27 2006/09/11 06:08:08 taylor
|
||||
* make Species_info[] and Asteroid_info[] dynamic
|
||||
*
|
||||
* Revision 2.26 2006/08/20 00:46:02 taylor
|
||||
* an int wrap-around issue could (and was) make debris not have electrical arcs (or lighting or sounds) since it would always fail this check
|
||||
*
|
||||
* Revision 2.25 2006/07/06 04:06:03 Goober5000
|
||||
* 1) complete (almost) changeover to reorganized texture mapping system
|
||||
* 2) finally fix texture animation; textures now animate at the correct speed
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.24 2006/07/04 07:42:48 Goober5000
|
||||
* --in preparation for fixing an annoying animated texture bug, reorganize the various texture structs and glow point structs and clarify several parts of the texture code :P
|
||||
* --this breaks animated glow maps, and animated regular maps still aren't fixed, but these will be remedied shortly
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.23 2006/01/26 03:23:29 Goober5000
|
||||
* pare down the pragmas some more
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.22 2005/12/29 08:08:33 wmcoolmon
|
||||
* Codebase commit, most notably including objecttypes.tbl
|
||||
*
|
||||
@@ -407,7 +440,7 @@ void debris_init()
|
||||
// Page in debris bitmaps at level load
|
||||
void debris_page_in()
|
||||
{
|
||||
int i;
|
||||
uint i;
|
||||
|
||||
Debris_model = model_load( NOX("debris01.pof"), 0, NULL );
|
||||
if (Debris_model >= 0) {
|
||||
@@ -418,25 +451,25 @@ void debris_page_in()
|
||||
|
||||
Debris_vaporize_model = model_load( NOX("debris02.pof"), 0, NULL );
|
||||
|
||||
for (i=0; i<Num_species; i++ )
|
||||
for (i=0; i<Species_info.size(); i++ )
|
||||
{
|
||||
species_info *species = &Species_info[i];
|
||||
|
||||
nprintf(( "Paging", "Paging in debris texture '%s'\n", species->debris_texture.filename));
|
||||
|
||||
species->debris_texture.bitmap = bm_load(species->debris_texture.filename);
|
||||
if (species->debris_texture.bitmap < 0)
|
||||
species->debris_texture.bitmap_id = bm_load(species->debris_texture.filename);
|
||||
if (species->debris_texture.bitmap_id < 0)
|
||||
{
|
||||
Warning( LOCATION, "Couldn't load species %s debris\ntexture, '%s'\n", species->species_name, species->debris_texture.filename);
|
||||
}
|
||||
|
||||
bm_page_in_texture(species->debris_texture.bitmap);
|
||||
bm_page_in_texture(species->debris_texture.bitmap_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MONITOR(NumSmallDebrisRend);
|
||||
MONITOR(NumHullDebrisRend);
|
||||
MONITOR(NumSmallDebrisRend)
|
||||
MONITOR(NumHullDebrisRend)
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_render()
|
||||
@@ -464,8 +497,8 @@ void debris_render(object * obj)
|
||||
pm = model_get( db->model_num );
|
||||
|
||||
if ( pm && (pm->n_textures == 1) ) {
|
||||
swapped = pm->textures[0];
|
||||
pm->textures[0] = Species_info[db->species].debris_texture.bitmap;
|
||||
swapped = pm->maps[0].base_map.texture;
|
||||
pm->maps[0].base_map.texture = Species_info[db->species].debris_texture.bitmap_id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +522,7 @@ void debris_render(object * obj)
|
||||
}
|
||||
|
||||
if ((swapped!=-1) && pm) {
|
||||
pm->textures[0] = swapped;
|
||||
pm->maps[0].base_map.texture = swapped;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,16 +571,23 @@ void maybe_delete_debris(debris *db)
|
||||
{
|
||||
object *objp;
|
||||
|
||||
if (timestamp_elapsed(db->next_distance_check)) {
|
||||
if (!(Game_mode & GM_MULTIPLAYER)) { // In single player game, just check against player.
|
||||
if (timestamp_elapsed(db->next_distance_check) && timestamp_elapsed(db->must_survive_until))
|
||||
{
|
||||
if (!(Game_mode & GM_MULTIPLAYER))
|
||||
{ // In single player game, just check against player.
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[db->objnum].pos) > MAX_DEBRIS_DIST)
|
||||
db->lifeleft = 0.1f;
|
||||
else
|
||||
db->next_distance_check = timestamp(DEBRIS_DISTANCE_CHECK_TIME);
|
||||
} else {
|
||||
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
|
||||
if (objp->flags & OF_PLAYER_SHIP) {
|
||||
if (vm_vec_dist_quick(&objp->pos, &Objects[db->objnum].pos) < MAX_DEBRIS_DIST) {
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) )
|
||||
{
|
||||
if (objp->flags & OF_PLAYER_SHIP)
|
||||
{
|
||||
if (vm_vec_dist_quick(&objp->pos, &Objects[db->objnum].pos) < MAX_DEBRIS_DIST)
|
||||
{
|
||||
db->next_distance_check = timestamp(DEBRIS_DISTANCE_CHECK_TIME);
|
||||
return;
|
||||
}
|
||||
@@ -564,8 +604,8 @@ void debris_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}
|
||||
|
||||
MONITOR(NumSmallDebris);
|
||||
MONITOR(NumHullDebris);
|
||||
MONITOR(NumSmallDebris)
|
||||
MONITOR(NumHullDebris)
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_process_post()
|
||||
@@ -590,9 +630,7 @@ void debris_process_post(object * obj, float frame_time)
|
||||
radar_plot_object( obj );
|
||||
|
||||
if ( timestamp_elapsed(db->sound_delay) ) {
|
||||
#ifndef NO_SOUND
|
||||
obj_snd_assign(objnum, SND_DEBRIS, &vmd_zero_vector, 0);
|
||||
#endif
|
||||
db->sound_delay = 0;
|
||||
}
|
||||
} else {
|
||||
@@ -756,13 +794,16 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
ship *shipp;
|
||||
debris *db;
|
||||
polymodel *pm;
|
||||
physics_info *pi;
|
||||
int vaporize;
|
||||
ship_info *sip = NULL;
|
||||
|
||||
parent_objnum = OBJ_INDEX(source_obj);
|
||||
|
||||
Assert( (source_obj->type == OBJ_SHIP ) || (source_obj->type == OBJ_GHOST));
|
||||
Assert( source_obj->instance >= 0 && source_obj->instance < MAX_SHIPS );
|
||||
shipp = &Ships[source_obj->instance];
|
||||
sip = &Ship_info[shipp->ship_info_index];
|
||||
vaporize = (shipp->flags &SF_VAPORIZE);
|
||||
|
||||
if ( !hull_flag ) {
|
||||
@@ -790,26 +831,58 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
break;
|
||||
}
|
||||
|
||||
if ( n == MAX_DEBRIS_PIECES ) {
|
||||
if (n == MAX_DEBRIS_PIECES) {
|
||||
n = debris_find_oldest();
|
||||
|
||||
if (n >= 0)
|
||||
debris_start_death_roll(&Objects[Debris[n].objnum], &Debris[n]);
|
||||
|
||||
nprintf(("Warning","Frame %i: Could not create debris, no more slots left\n", Framecount));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
db = &Debris[n];
|
||||
|
||||
// Create Debris piece n!
|
||||
if ( hull_flag ) {
|
||||
if (rand() < RAND_MAX/6) // Make some pieces blow up shortly after explosion.
|
||||
db->lifeleft = 2.0f * ((float) myrand()/(float) RAND_MAX) + 0.5f;
|
||||
else
|
||||
db->lifeleft = -1.0f; // large hull pieces stay around forever
|
||||
} else {
|
||||
db->lifeleft = (i2fl(myrand())/i2fl(RAND_MAX))*2.0f+0.1f;
|
||||
//WMC - We must survive until now, at least.
|
||||
db->must_survive_until = timestamp();
|
||||
|
||||
if(hull_flag && sip->debris_min_lifetime >= 0.0f && sip->debris_max_lifetime >= 0.0f)
|
||||
{
|
||||
db->lifeleft = (( sip->debris_max_lifetime - sip->debris_min_lifetime ) * frand()) + sip->debris_min_lifetime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create Debris piece n!
|
||||
if ( hull_flag ) {
|
||||
if (rand() < RAND_MAX/6) // Make some pieces blow up shortly after explosion.
|
||||
db->lifeleft = 2.0f * ((float) myrand()/(float) RAND_MAX) + 0.5f;
|
||||
else
|
||||
db->lifeleft = -1.0f; // large hull pieces stay around forever
|
||||
} else {
|
||||
db->lifeleft = (i2fl(myrand())/i2fl(RAND_MAX))*2.0f+0.1f;
|
||||
}
|
||||
|
||||
// increase lifetime for vaporized debris
|
||||
if (vaporize) {
|
||||
db->lifeleft *= 3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// increase lifetime for vaporized debris
|
||||
if (vaporize) {
|
||||
db->lifeleft *= 3.0f;
|
||||
//WMC - Oh noes, we may need to change lifeleft
|
||||
if(hull_flag)
|
||||
{
|
||||
if(sip->debris_min_lifetime >= 0.0f)
|
||||
{
|
||||
db->must_survive_until = timestamp(fl2i(sip->debris_min_lifetime * 1000.0f));
|
||||
if(db->lifeleft < sip->debris_min_lifetime)
|
||||
db->lifeleft = sip->debris_min_lifetime;
|
||||
}
|
||||
|
||||
if(sip->debris_max_lifetime >= 0.0f)
|
||||
{
|
||||
if(db->lifeleft > sip->debris_max_lifetime)
|
||||
db->lifeleft = sip->debris_max_lifetime;
|
||||
}
|
||||
}
|
||||
db->flags |= DEBRIS_USED;
|
||||
db->is_hull = hull_flag;
|
||||
@@ -829,7 +902,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
|
||||
if ( db->is_hull ) {
|
||||
// Only make 1/2 of the pieces have arcs
|
||||
if ( myrand() < RAND_MAX*2/3 ) {
|
||||
if ( myrand() < RAND_MAX_2 ) {
|
||||
db->arc_frequency = 1000;
|
||||
} else {
|
||||
db->arc_frequency = 0;
|
||||
@@ -868,6 +941,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
db->objnum = objnum;
|
||||
|
||||
obj = &Objects[objnum];
|
||||
pi = &obj->phys_info;
|
||||
|
||||
// assign the network signature. The signature will be 0 for non-hull pieces, but since that
|
||||
// is our invalid signature, it should be okay.
|
||||
@@ -946,48 +1020,10 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_crossprod ( &vel_from_rotvel, &world_rotvel, &to_center );
|
||||
vm_vec_scale ( &vel_from_rotvel, DEBRIS_ROTVEL_SCALE);
|
||||
|
||||
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
|
||||
vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
|
||||
vm_vec_add (&pi->vel, &radial_vel, &source_obj->phys_info.vel);
|
||||
vm_vec_add2(&pi->vel, &vel_from_rotvel);
|
||||
|
||||
#ifdef DEBRIS_SPEED_DEBUG
|
||||
// check that debris is not created with too high a velocity
|
||||
if (hull_flag)
|
||||
{
|
||||
int ship_type = Ship_info[Ships[source_obj->instance].ship_info_index].class_type;
|
||||
if(ship_type > -1)
|
||||
{
|
||||
if(vm_vec_mag_squared(&obj->phys_info.vel) > Ship_types[ship_type].debris_max_speed) {
|
||||
float scale = Ship_types[ship_type].debris_max_speed / vm_vec_mag(&obj->phys_info.vel);
|
||||
vm_vec_scale(&obj->phys_info.vel, scale);
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (ship_info_flag & (SIF_SMALL_SHIP | SIF_NOT_FLYABLE | SIF_HARMLESS))
|
||||
{
|
||||
if (vm_vec_mag_squared(&obj->phys_info.vel) > MAX_SPEED_SMALL_DEBRIS*MAX_SPEED_SMALL_DEBRIS) {
|
||||
float scale = MAX_SPEED_SMALL_DEBRIS / vm_vec_mag(&obj->phys_info.vel);
|
||||
vm_vec_scale(&obj->phys_info.vel, scale);
|
||||
}
|
||||
} else if (ship_info_flag & SIF_BIG_SHIP) {
|
||||
if (vm_vec_mag_squared(&obj->phys_info.vel) > MAX_SPEED_BIG_DEBRIS*MAX_SPEED_BIG_DEBRIS) {
|
||||
float scale = MAX_SPEED_BIG_DEBRIS / vm_vec_mag(&obj->phys_info.vel);
|
||||
vm_vec_scale(&obj->phys_info.vel, scale);
|
||||
}
|
||||
} else if (ship_info_flag & SIF_HUGE_SHIP) {
|
||||
if (vm_vec_mag_squared(&obj->phys_info.vel) > MAX_SPEED_CAPITAL_DEBRIS*MAX_SPEED_CAPITAL_DEBRIS) {
|
||||
float scale = MAX_SPEED_CAPITAL_DEBRIS / vm_vec_mag(&obj->phys_info.vel);
|
||||
vm_vec_scale(&obj->phys_info.vel, scale);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(LOCATION, "Ship does not have a type!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// vm_vec_scale_add(&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel, frand()/2.0f + 0.5f);
|
||||
// vm_vec_scale_add(&pi->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
|
||||
@@ -1000,26 +1036,81 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_rand_vec_quick(&rotvel);
|
||||
vm_vec_scale(&rotvel, scale);
|
||||
|
||||
obj->phys_info.flags |= PF_DEAD_DAMP;
|
||||
obj->phys_info.rotvel = rotvel;
|
||||
pi->flags |= PF_DEAD_DAMP;
|
||||
pi->rotvel = rotvel;
|
||||
check_rotvel_limit( &obj->phys_info );
|
||||
|
||||
// check that debris is not created with too high a velocity
|
||||
if (hull_flag)
|
||||
{
|
||||
if(sip->debris_min_speed >= 0.0f && sip->debris_max_speed >= 0.0f)
|
||||
{
|
||||
float debris_speed = (( sip->debris_max_speed - sip->debris_min_speed ) * frand()) + sip->debris_min_speed;
|
||||
float scale = debris_speed / vm_vec_mag(&pi->vel);
|
||||
vm_vec_scale(&pi->vel, scale);
|
||||
}
|
||||
else if(sip->debris_min_speed >= 0.0f)
|
||||
{
|
||||
float curspeed = vm_vec_mag(&pi->vel);
|
||||
if(curspeed < sip->debris_min_speed)
|
||||
{
|
||||
float scale = sip->debris_min_speed / curspeed;
|
||||
vm_vec_scale(&pi->vel, scale);
|
||||
}
|
||||
}
|
||||
else if(sip->debris_max_speed >= 0.0f)
|
||||
{
|
||||
float curspeed = vm_vec_mag(&pi->vel);
|
||||
if(curspeed > sip->debris_max_speed)
|
||||
{
|
||||
float scale = sip->debris_max_speed / curspeed;
|
||||
vm_vec_scale(&pi->vel, scale);
|
||||
}
|
||||
}
|
||||
|
||||
//WMC - Rotational velocity user cap
|
||||
if(sip->debris_min_rotspeed >= 0.0f && sip->debris_max_rotspeed >= 0.0f)
|
||||
{
|
||||
float debris_rotspeed = (( sip->debris_max_rotspeed - sip->debris_min_rotspeed ) * frand()) + sip->debris_min_rotspeed;
|
||||
float scale = debris_rotspeed / vm_vec_mag(&pi->rotvel);
|
||||
vm_vec_scale(&pi->rotvel, scale);
|
||||
}
|
||||
else if(sip->debris_min_rotspeed >= 0.0f)
|
||||
{
|
||||
float curspeed = vm_vec_mag(&pi->rotvel);
|
||||
if(curspeed < sip->debris_min_rotspeed)
|
||||
{
|
||||
float scale = sip->debris_min_rotspeed / curspeed;
|
||||
vm_vec_scale(&pi->rotvel, scale);
|
||||
}
|
||||
}
|
||||
else if(sip->debris_max_rotspeed >= 0.0f)
|
||||
{
|
||||
float curspeed = vm_vec_mag(&pi->rotvel);
|
||||
if(curspeed > sip->debris_max_rotspeed)
|
||||
{
|
||||
float scale = sip->debris_max_rotspeed / curspeed;
|
||||
vm_vec_scale(&pi->rotvel, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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.flags |= (PF_REDUCED_DAMP | PF_DEAD_DAMP); // set damping equal for all axis and not changable
|
||||
pi->rotdamp = 10000.0f;
|
||||
pi->side_slip_time_const = 10000.0f;
|
||||
pi->flags |= (PF_REDUCED_DAMP | PF_DEAD_DAMP); // set damping equal for all axis and not changable
|
||||
|
||||
vm_vec_zero(&obj->phys_info.max_vel); // make so he can't turn on his own VOLITION anymore.
|
||||
vm_vec_zero(&obj->phys_info.max_rotvel); // make so he can't change speed on his own VOLITION anymore.
|
||||
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) );
|
||||
Assert( !vm_is_vec_nan(&pi->vel) );
|
||||
|
||||
// if ( hull_flag ) {
|
||||
// vm_vec_zero(&obj->phys_info.vel);
|
||||
// vm_vec_zero(&obj->phys_info.rotvel);
|
||||
// vm_vec_zero(&pi->vel);
|
||||
// vm_vec_zero(&pi->rotvel);
|
||||
// }
|
||||
|
||||
return obj;
|
||||
@@ -1060,7 +1151,8 @@ void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float dama
|
||||
pe.max_vel = 10.0f; // How fast the fastest particle can move
|
||||
pe.min_life = 0.25f; // How long the particles live
|
||||
pe.max_life = 0.75f; // How long the particles live
|
||||
particle_emit( &pe, PARTICLE_FIRE, 0 );
|
||||
pe.texture_id = particle_get_fire_id();
|
||||
particle_emit( &pe );
|
||||
}
|
||||
|
||||
// multiplayer clients bail here
|
||||
@@ -1162,7 +1254,7 @@ 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_num = Ships[ship_obj->instance].modelnum; // Fill in the model to check
|
||||
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;
|
||||
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
|
||||
@@ -1193,7 +1285,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
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(Ships[heavy_obj->instance].modelnum);
|
||||
pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num);
|
||||
|
||||
// turn off all rotating submodels and test for collision
|
||||
int i;
|
||||
@@ -1288,7 +1380,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
mc.submodel_num = Debris[num].submodel_num;
|
||||
model_clear_instance( mc.model_num );
|
||||
mc.orient = &pdebris->orient; // The object's orient
|
||||
mc.radius = model_get_core_radius( Ships[ship_obj->instance].modelnum );
|
||||
mc.radius = model_get_core_radius(Ship_info[Ships[ship_obj->instance].ship_info_index].model_num);
|
||||
|
||||
// check for collision between debris model and ship sphere
|
||||
mc.flags = (MC_CHECK_MODEL | MC_SUBMODEL | MC_CHECK_SPHERELINE);
|
||||
@@ -1375,5 +1467,3 @@ void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs
|
||||
pi->I_body_inv.vec.fvec.xyz.y = 0.0f;
|
||||
pi->I_body_inv.vec.fvec.xyz.z = 12.0f / (pi->mass * (dx*dx + dy*dy));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Debris/Debris.h $
|
||||
* $Revision: 2.5 $
|
||||
* $Date: 2005-07-13 02:50:51 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.6 $
|
||||
* $Date: 2006-12-28 00:59:19 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Code for the pieces of exploding object debris.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.5 2005/07/13 02:50:51 Goober5000
|
||||
* remove PreProcDefine #includes in FS2
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.4 2005/04/28 05:29:29 wmcoolmon
|
||||
* Removed FS2_DEMO defines that looked like they wouldn't cause the universe to collapse
|
||||
*
|
||||
@@ -173,6 +177,7 @@ typedef struct debris {
|
||||
int team; // Team of the ship where the debris came from
|
||||
int objnum; // What object this is linked to
|
||||
float lifeleft; // When 0 or less object dies
|
||||
int must_survive_until; //WMC - timestamp of earliest point that it can be murthered.
|
||||
int model_num; // What model this uses
|
||||
int submodel_num; // What submodel this uses
|
||||
int next_fireball; // When to start a fireball
|
||||
|
||||
@@ -9,13 +9,19 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/DebugConsole/Console.cpp $
|
||||
* $Revision: 2.6 $
|
||||
* $Date: 2005-04-25 00:07:22 $
|
||||
* $Author: wmcoolmon $
|
||||
* $Revision: 2.8 $
|
||||
* $Date: 2007-02-18 21:26:50 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Routines for managing the debug console window.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.7 2006/09/08 06:20:14 taylor
|
||||
* fix things that strict compiling balked at (from compiling with -ansi and -pedantic)
|
||||
*
|
||||
* Revision 2.6 2005/04/25 00:07:22 wmcoolmon
|
||||
* Bumped console printing buffer size so people can play with the neb2 command
|
||||
*
|
||||
* Revision 2.5 2004/07/26 20:47:27 Kazan
|
||||
* remove MCD complete
|
||||
*
|
||||
@@ -213,11 +219,11 @@ int command_scroll = 0;
|
||||
|
||||
///=========================== SCANNER =======================
|
||||
typedef enum {
|
||||
LETTER, QUOTE, SPECIAL, EOF_CODE, DIGIT,
|
||||
LETTER, QUOTE, SPECIAL, EOF_CODE, DIGIT
|
||||
} CHAR_CODE;
|
||||
|
||||
typedef enum {
|
||||
NO_TOKEN, IDENTIFIER, NUMBER, STRING,
|
||||
NO_TOKEN, IDENTIFIER, NUMBER, STRING
|
||||
} TOKEN_CODE;
|
||||
|
||||
|
||||
@@ -476,6 +482,11 @@ void debug_do_command(char * command)
|
||||
dc_get_arg( ARG_ANY );
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "xyzzy" ) ) {
|
||||
dc_printf("Nothing happens.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !strcmp( Dc_arg, "?" ) ) {
|
||||
mode = 1;
|
||||
dc_get_arg( ARG_ANY );
|
||||
|
||||
+13
-4
@@ -9,12 +9,21 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Demo/Demo.cpp $
|
||||
* $Revision: 2.8 $
|
||||
* $Date: 2005-05-12 17:49:11 $
|
||||
* $Author: taylor $
|
||||
* $Revision: 2.11 $
|
||||
* $Date: 2007-09-02 18:53:22 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.10 2006/07/09 01:55:41 Goober5000
|
||||
* consolidate the "for reals" crap into a proper ship flag; also move the limbo flags over to SF2_*; etc.
|
||||
* this should fix Mantis #977
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.8 2005/05/12 17:49:11 taylor
|
||||
* use vm_malloc(), vm_free(), vm_realloc(), vm_strdup() rather than system named macros
|
||||
* fixes various problems and is past time to make the switch
|
||||
*
|
||||
* Revision 2.7 2005/04/05 05:53:15 taylor
|
||||
* s/vector/vec3d/g, better support for different compilers (Jens Granseuer)
|
||||
*
|
||||
@@ -1001,7 +1010,7 @@ int demo_playback_seek_sub(int frame_size)
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
ship_departed(ship_index);
|
||||
ship_actually_depart(ship_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+6
-2
@@ -9,12 +9,16 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Demo/Demo.h $
|
||||
* $Revision: 2.2 $
|
||||
* $Date: 2005-07-13 02:50:51 $
|
||||
* $Revision: 2.4 $
|
||||
* $Date: 2006-07-09 01:55:41 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.2 2005/07/13 02:50:51 Goober5000
|
||||
* remove PreProcDefine #includes in FS2
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.1 2004/08/11 05:06:21 Kazan
|
||||
* added preprocdefines.h to prevent what happened with fred -- make sure to make all fred2 headers include this file as the _first_ include -- i have already modified fs2 files to do this
|
||||
*
|
||||
|
||||
@@ -1,346 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <dshow.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "osapi/osapi.h"
|
||||
#include "directx/dx8show.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "graphics/2d.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <tchar.h>
|
||||
//#include <atlbase.h> // No dependecy on ATL!!!
|
||||
|
||||
|
||||
|
||||
enum PLAYSTATE {Stopped, Paused, Running, Init};
|
||||
void Msg(TCHAR *szFormat, ...);
|
||||
|
||||
// Local
|
||||
HRESULT InitPlayerWindow(HWND ghApp);
|
||||
HRESULT InitVideoWindow(HWND ghApp, long w, long h);
|
||||
bool HandleGraphEvent(void);
|
||||
void CheckVisibility(void);
|
||||
void CloseInterfaces(void);
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#define VOLUME_FULL 0L
|
||||
#define VOLUME_SILENCE -10000L
|
||||
|
||||
#define WM_GRAPHNOTIFY WM_USER
|
||||
|
||||
char error_buffer[512];
|
||||
char *ParseDShowError(HRESULT hr)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
AMGetErrorText(hr, error_buffer, 512);
|
||||
return error_buffer;
|
||||
#else
|
||||
return "DShow error";
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Macros
|
||||
//
|
||||
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
|
||||
|
||||
#define JIF(x) if (FAILED(hr=(x))) \
|
||||
{Msg(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) " (%s) " TEXT("\n"), hr, ParseDShowError(hr)); return hr;}
|
||||
|
||||
#define LIF(x) if (FAILED(hr=(x))) \
|
||||
{Msg(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr);}
|
||||
|
||||
//
|
||||
// Global data
|
||||
//
|
||||
BOOL g_bAudioOnly=FALSE;
|
||||
LONG g_lVolume=VOLUME_FULL;
|
||||
DWORD g_dwGraphRegister=0;
|
||||
PLAYSTATE g_psCurrent=Stopped;
|
||||
|
||||
// DirectShow interfaces
|
||||
IGraphBuilder *pGB = NULL;
|
||||
IMediaControl *pMC = NULL;
|
||||
IMediaEventEx *pME = NULL;
|
||||
IVideoWindow *pVW = NULL;
|
||||
IBasicAudio *pBA = NULL;
|
||||
IBasicVideo *pBV = NULL;
|
||||
IMediaSeeking *pMS = NULL;
|
||||
IMediaPosition *pMP = NULL;
|
||||
|
||||
void PassMsgToVideoWindow(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (pVW)
|
||||
pVW->NotifyOwnerMessage((long) hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void SetCurrentState(PLAYSTATE state)
|
||||
{
|
||||
g_psCurrent = state;
|
||||
}
|
||||
|
||||
PLAYSTATE GetCurrentState()
|
||||
{
|
||||
return g_psCurrent;
|
||||
}
|
||||
|
||||
BOOL IsAudioOnly()
|
||||
{
|
||||
return g_bAudioOnly;
|
||||
}
|
||||
|
||||
HRESULT PlayMovieInWindow(HWND ghApp, LPTSTR szFile)
|
||||
{
|
||||
// USES_CONVERSION;
|
||||
WCHAR wFile[MAX_PATH];
|
||||
HRESULT hr;
|
||||
|
||||
// Clear open dialog remnants before calling RenderFile()
|
||||
UpdateWindow(ghApp);
|
||||
|
||||
// Convert filename to wide character string
|
||||
// wcscpy(wFile, T2W(szFile)); // requires ATL
|
||||
swprintf(wFile, L"%S", szFile); // Uses libc to convert instead
|
||||
|
||||
// Get the interface for DirectShow's GraphBuilder
|
||||
JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IGraphBuilder, (void **)&pGB));
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
HRESULT load_attempt = pGB->RenderFile(wFile, NULL);
|
||||
|
||||
// f%#$ing DivX6...
|
||||
SetForegroundWindow(ghApp);
|
||||
|
||||
// Have the graph builder construct its the appropriate graph automatically
|
||||
if(FAILED(load_attempt))
|
||||
{
|
||||
return load_attempt;
|
||||
}
|
||||
|
||||
// QueryInterface for DirectShow interfaces
|
||||
JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC));
|
||||
JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME));
|
||||
JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS));
|
||||
JIF(pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP));
|
||||
|
||||
// Query for video interfaces, which may not be relevant for audio files
|
||||
JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW));
|
||||
JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV));
|
||||
|
||||
// Query for audio interfaces, which may not be relevant for video-only files
|
||||
JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA));
|
||||
|
||||
// Is this an audio-only file (no video component)?
|
||||
CheckVisibility();
|
||||
|
||||
// Have the graph signal event via window callbacks for performance
|
||||
JIF(pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0));
|
||||
|
||||
long width, height;
|
||||
pBV->get_VideoWidth(&width);
|
||||
pBV->get_VideoHeight(&height);
|
||||
|
||||
// JIF(InitVideoWindow(ghApp,width, height));
|
||||
|
||||
if (!g_bAudioOnly)
|
||||
{
|
||||
JIF(pVW->put_Owner((OAHWND)ghApp));
|
||||
JIF(pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE));
|
||||
JIF(InitVideoWindow(ghApp, width, height));
|
||||
JIF(pVW->SetWindowForeground(OATRUE));
|
||||
}
|
||||
|
||||
// Run the graph to play the media file
|
||||
JIF(pMC->Run());
|
||||
g_psCurrent=Running;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
extern int Cmdline_window;
|
||||
extern int Cmdline_noscalevid;
|
||||
HRESULT InitVideoWindow(HWND ghApp, long video_w, long video_h)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
RECT rect;
|
||||
|
||||
GetClientRect(ghApp, &rect);
|
||||
|
||||
int screen_w = rect.right;
|
||||
int screen_h = rect.bottom;
|
||||
|
||||
int video_rescale_w;
|
||||
int video_rescale_h;
|
||||
|
||||
if (Cmdline_noscalevid && (video_w < screen_w) && (video_h < screen_h)) {
|
||||
video_rescale_w = video_w;
|
||||
video_rescale_h = video_h;
|
||||
} else {
|
||||
video_rescale_w = (video_w * screen_w) / video_w;
|
||||
video_rescale_h = (video_rescale_w * video_h) / video_w;
|
||||
}
|
||||
|
||||
int extra_w = (screen_w - video_rescale_w) / 2;
|
||||
int extra_h = (screen_h - video_rescale_h) / 2;
|
||||
|
||||
if (Cmdline_window)
|
||||
{
|
||||
rect.right += GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
|
||||
rect.bottom += 2 * GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
|
||||
}
|
||||
|
||||
if(SetWindowPos(ghApp, 0, 0, 0, rect.right, rect.bottom, SWP_NOMOVE | SWP_NOOWNERZORDER) == FALSE) {
|
||||
|
||||
MessageBox(ghApp,"Failed SetWindowPos","Error", MB_OK);
|
||||
}
|
||||
|
||||
JIF(pVW->SetWindowPosition(extra_w, extra_h, video_rescale_w, video_rescale_h));
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CheckVisibility(void)
|
||||
{
|
||||
long lVisible;
|
||||
HRESULT hr;
|
||||
|
||||
if ((!pVW) || (!pBV))
|
||||
{
|
||||
// Audio-only files have no video interfaces. This might also
|
||||
// be a file whose video component uses an unknown video codec.
|
||||
g_bAudioOnly = TRUE;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear the global flag
|
||||
g_bAudioOnly = FALSE;
|
||||
}
|
||||
|
||||
hr = pVW->get_Visible(&lVisible);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
|
||||
// If this is an audio-only clip, get_Visible() won't work.
|
||||
//
|
||||
// Also, if this video is encoded with an unsupported codec,
|
||||
// we won't see any video, although the audio will work if it is
|
||||
// of a supported format.
|
||||
//
|
||||
if (hr == E_NOINTERFACE)
|
||||
{
|
||||
g_bAudioOnly = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg(TEXT("Failed(%08lx) in pVW->get_Visible()!\r\n"), hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenClip(HWND ghApp, char *g_szFileName)
|
||||
{
|
||||
// Reset status variables
|
||||
g_psCurrent = Stopped;
|
||||
g_lVolume = VOLUME_FULL;
|
||||
|
||||
// Start playing the media file
|
||||
HRESULT hr = PlayMovieInWindow(ghApp, g_szFileName);
|
||||
|
||||
// If we couldn't play the clip, clean up
|
||||
if (FAILED(hr)) {
|
||||
CloseClip(ghApp);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloseClip(HWND ghApp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// Stop media playback
|
||||
if(pMC)
|
||||
hr = pMC->Stop();
|
||||
|
||||
// Clear global flags
|
||||
g_psCurrent = Stopped;
|
||||
g_bAudioOnly = TRUE;
|
||||
|
||||
// Free DirectShow interfaces
|
||||
CloseInterfaces();
|
||||
|
||||
// No current media state
|
||||
g_psCurrent = Init;
|
||||
}
|
||||
|
||||
|
||||
void CloseInterfaces(void)
|
||||
{
|
||||
// Relinquish ownership (IMPORTANT!) after hiding video window
|
||||
if(pVW)
|
||||
pVW->put_Visible(OAFALSE);
|
||||
|
||||
// Disable event callbacks
|
||||
if (pME)
|
||||
pME->SetNotifyWindow((OAHWND)NULL, 0, 0);
|
||||
|
||||
// Release and zero DirectShow interfaces
|
||||
SAFE_RELEASE(pME);
|
||||
SAFE_RELEASE(pMS);
|
||||
SAFE_RELEASE(pMP);
|
||||
SAFE_RELEASE(pMC);
|
||||
SAFE_RELEASE(pBA);
|
||||
SAFE_RELEASE(pBV);
|
||||
SAFE_RELEASE(pVW);
|
||||
SAFE_RELEASE(pGB);
|
||||
}
|
||||
|
||||
void Msg(TCHAR *szFormat, ...)
|
||||
{
|
||||
TCHAR szBuffer[512]; // Large buffer for very long filenames (like HTTP)
|
||||
|
||||
// Format the input string
|
||||
va_list pArgs;
|
||||
va_start(pArgs, szFormat);
|
||||
_vstprintf(szBuffer, szFormat, pArgs);
|
||||
va_end(pArgs);
|
||||
|
||||
// Display a message box with the formatted string
|
||||
MessageBox(NULL, szBuffer, TEXT("PlayWnd Sample"), MB_OK);
|
||||
}
|
||||
|
||||
// returns true when finished
|
||||
bool dx8show_stream_movie(void)
|
||||
{
|
||||
LONG evCode, evParam1, evParam2;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
// Make sure that we don't access the media event interface
|
||||
// after it has already been released.
|
||||
if (!pME) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Process all queued events
|
||||
while(SUCCEEDED(pME->GetEvent(&evCode, &evParam1,&evParam2, 0))) {
|
||||
// Free memory associated with callback, since we're not using it
|
||||
hr = pME->FreeEventParams(evCode, evParam1, evParam2);
|
||||
|
||||
// If this is the end of the clip, reset to beginning
|
||||
if(EC_COMPLETE == evCode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
#ifndef _DX8SHOW_HEADER_FILE
|
||||
#define _DX8SHOW_HEADER_FILE
|
||||
|
||||
bool OpenClip(HWND ghApp, char *g_szFileName);
|
||||
void CloseClip(HWND ghApp);
|
||||
bool dx8show_stream_movie(void);
|
||||
void PassMsgToVideoWindow(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/ExceptionHandler/ExceptionHandler.cpp $
|
||||
* $Revision: 2.10 $
|
||||
* $Date: 2006-01-26 03:23:29 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.11 $
|
||||
* $Date: 2006-11-16 00:51:04 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Main file for dealing with exception handling
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.10 2006/01/26 03:23:29 Goober5000
|
||||
* pare down the pragmas some more
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.9 2006/01/20 07:10:33 Goober5000
|
||||
* reordered #include files to quash Microsoft warnings
|
||||
* --Goober5000
|
||||
@@ -558,7 +562,10 @@ int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const char *Message)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (safe_string[0])
|
||||
hprintf(LogFile, "Last safe point: %s\r\n", safe_string);
|
||||
#endif
|
||||
|
||||
RecordModuleList(LogFile);
|
||||
|
||||
@@ -566,7 +573,6 @@ int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const char *Message)
|
||||
// Return the magic value which tells Win32 that this handler didn't
|
||||
// actually handle the exception - so that things will proceed as per
|
||||
// normal.
|
||||
if(safe_string[0])hprintf(LogFile, "\nlast safe point \n%s\n",safe_string);
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
+191
-56
@@ -9,13 +9,29 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fireball/FireBalls.cpp $
|
||||
* $Revision: 2.33 $
|
||||
* $Date: 2006-02-25 21:46:59 $
|
||||
* $Revision: 2.38 $
|
||||
* $Date: 2007-09-02 02:10:24 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Code to move, render and otherwise deal with fireballs.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.37 2007/07/28 21:31:10 Goober5000
|
||||
* this should really be capitalized
|
||||
*
|
||||
* Revision 2.36 2007/02/11 18:19:41 taylor
|
||||
* support for tbl specified fireball explosion color ("$Light color:")
|
||||
*
|
||||
* Revision 2.35 2006/12/28 00:59:19 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 2.34 2006/09/11 06:48:40 taylor
|
||||
* fixes for stuff_string() bounds checking
|
||||
* stict compiler build fixes
|
||||
*
|
||||
* Revision 2.33 2006/02/25 21:46:59 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 2.32 2006/02/13 00:20:45 Goober5000
|
||||
* more tweaks, plus clarification of checks for the existence of files
|
||||
* --Goober5000
|
||||
@@ -484,6 +500,8 @@
|
||||
// make use of the LOD checker for tbl/tbm parsing (from weapons.cpp)
|
||||
extern std::vector<lod_checker> LOD_checker;
|
||||
|
||||
static std::vector<color> LOD_color;
|
||||
|
||||
int Warp_model;
|
||||
int Knossos_warp_ani_used;
|
||||
|
||||
@@ -563,22 +581,62 @@ void fireball_play_warphole_close_sound(fireball *fb)
|
||||
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)
|
||||
static void fireball_set_default_color(int idx)
|
||||
{
|
||||
Assert( (idx >= 0) && (idx < MAX_FIREBALL_TYPES) );
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case FIREBALL_EXPLOSION_LARGE1:
|
||||
case FIREBALL_EXPLOSION_LARGE2:
|
||||
case FIREBALL_EXPLOSION_MEDIUM:
|
||||
case FIREBALL_ASTEROID:
|
||||
Fireball_info[idx].exp_color[0] = 1.0f;
|
||||
Fireball_info[idx].exp_color[1] = 0.5f;
|
||||
Fireball_info[idx].exp_color[2] = 0.125f;
|
||||
break;
|
||||
|
||||
case FIREBALL_WARP_EFFECT:
|
||||
Fireball_info[idx].exp_color[0] = 0.75f;
|
||||
Fireball_info[idx].exp_color[1] = 0.75f;
|
||||
Fireball_info[idx].exp_color[2] = 1.0f;
|
||||
break;
|
||||
|
||||
|
||||
case FIREBALL_KNOSSOS_EFFECT:
|
||||
Fireball_info[idx].exp_color[0] = 0.75f;
|
||||
Fireball_info[idx].exp_color[1] = 1.0f;
|
||||
Fireball_info[idx].exp_color[2] = 0.75f;
|
||||
break;
|
||||
|
||||
default:
|
||||
Fireball_info[idx].exp_color[0] = 1.0f;
|
||||
Fireball_info[idx].exp_color[1] = 1.0f;
|
||||
Fireball_info[idx].exp_color[2] = 1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 *longname)
|
||||
void parse_fireball_tbl(char *filename)
|
||||
{
|
||||
int rval;
|
||||
lod_checker lod_check;
|
||||
color fb_color;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("Unable to parse %s! Code = %i.\n", rval, longname));
|
||||
} else {
|
||||
read_file_text(longname);
|
||||
reset_parse();
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Start");
|
||||
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
@@ -586,7 +644,7 @@ void parse_fireball_tbl(char *longname)
|
||||
|
||||
// base filename
|
||||
required_string("$Name:");
|
||||
stuff_string(lod_check.filename, F_NAME, NULL);
|
||||
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
lod_check.override = -1;
|
||||
|
||||
@@ -619,8 +677,27 @@ void parse_fireball_tbl(char *longname)
|
||||
lod_check.num_lods = MAX_FIREBALL_LOD;
|
||||
}
|
||||
|
||||
// check for particular lighting color
|
||||
if ( optional_string("$Light color:") ) {
|
||||
int r, g, b;
|
||||
|
||||
stuff_int(&r);
|
||||
stuff_int(&g);
|
||||
stuff_int(&b);
|
||||
|
||||
CLAMP(r, 0, 255);
|
||||
CLAMP(g, 0, 255);
|
||||
CLAMP(b, 0, 255);
|
||||
|
||||
gr_init_color(&fb_color, r, g, b);
|
||||
} else {
|
||||
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
|
||||
memset( &fb_color, 0, sizeof(color) );
|
||||
}
|
||||
|
||||
// we may use one filename for multiple entries so we'll have to handle dupes post parse
|
||||
LOD_checker.push_back(lod_check);
|
||||
LOD_color.push_back(fb_color);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
@@ -647,6 +724,14 @@ void fireball_parse_tbl()
|
||||
if ( (i < MAX_FIREBALL_TYPES) && (LOD_checker[i].override < 0) ) {
|
||||
strcpy( Fireball_info[i].lod[0].filename, LOD_checker[i].filename );
|
||||
Fireball_info[i].lod_count = LOD_checker[i].num_lods;
|
||||
|
||||
if (LOD_color[i].alpha == 255) {
|
||||
Fireball_info[i].exp_color[0] = (LOD_color[i].red / 255.0f);
|
||||
Fireball_info[i].exp_color[1] = (LOD_color[i].green / 255.0f);
|
||||
Fireball_info[i].exp_color[2] = (LOD_color[i].blue / 255.0f);
|
||||
} else {
|
||||
fireball_set_default_color(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,6 +742,14 @@ void fireball_parse_tbl()
|
||||
if ( (LOD_checker[i].override >= 0) && (LOD_checker[i].override < MAX_FIREBALL_TYPES) ) {
|
||||
strcpy( 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_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_checker[i].override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,9 +778,11 @@ void fireball_load_data()
|
||||
if ( (i == FIREBALL_WARP_EFFECT) && (idx > MAX_WARP_LOD) )
|
||||
continue;
|
||||
|
||||
fd->lod[idx].num_frames = 0;
|
||||
fd->lod[idx].fps = 0;
|
||||
fd->lod[idx].bitmap_id = bm_load_animation( fd->lod[idx].filename, &fd->lod[idx].num_frames, &fd->lod[idx].fps, 1 );
|
||||
if ( fd->lod[idx].bitmap_id < 0 ) {
|
||||
Error(LOCATION, "Could not load %s anim file\n", fd->lod[idx].filename);
|
||||
Warning(LOCATION, "Could not load %s anim file\n", fd->lod[idx].filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,7 +838,7 @@ void fireball_init()
|
||||
mprintf((" %d\n", Warp_model));
|
||||
}
|
||||
|
||||
MONITOR( NumFireballsRend );
|
||||
MONITOR( NumFireballsRend )
|
||||
|
||||
void fireball_render(object * obj)
|
||||
{
|
||||
@@ -892,34 +987,51 @@ void fireball_set_framenum(int num)
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fb->fireball_info_index == FIREBALL_WARP_EFFECT || fb->fireball_info_index == FIREBALL_KNOSSOS_EFFECT ) {
|
||||
float total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
|
||||
if ( fb->fireball_info_index == FIREBALL_WARP_EFFECT || fb->fireball_info_index == FIREBALL_KNOSSOS_EFFECT )
|
||||
{
|
||||
if(fl->bitmap_id > 0)
|
||||
{
|
||||
float total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
|
||||
|
||||
framenum = fl2i(fb->time_elapsed * fl->num_frames / total_time + 0.5);
|
||||
framenum = fl2i(fb->time_elapsed * fl->num_frames / total_time + 0.5);
|
||||
|
||||
if ( framenum < 0 ) framenum = 0;
|
||||
if ( framenum < 0 ) framenum = 0;
|
||||
|
||||
framenum = framenum % fl->num_frames;
|
||||
framenum = framenum % fl->num_frames;
|
||||
|
||||
if ( fb->orient ) {
|
||||
// warp out effect plays backwards
|
||||
framenum = fl->num_frames-framenum-1;
|
||||
fb->current_bitmap = fl->bitmap_id + framenum;
|
||||
} else {
|
||||
if ( fb->orient ) {
|
||||
// warp out effect plays backwards
|
||||
framenum = fl->num_frames-framenum-1;
|
||||
fb->current_bitmap = fl->bitmap_id + framenum;
|
||||
} else {
|
||||
fb->current_bitmap = fl->bitmap_id + framenum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fb->current_bitmap = fl->bitmap_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fl->bitmap_id > -1)
|
||||
{
|
||||
framenum = fl2i(fb->time_elapsed / fb->total_time * fl->num_frames + 0.5);
|
||||
|
||||
// ensure we don't go past the number of frames of animation
|
||||
if ( framenum > (fl->num_frames-1) ) {
|
||||
framenum = (fl->num_frames-1);
|
||||
Objects[fb->objnum].flags |= OF_SHOULD_BE_DEAD;
|
||||
}
|
||||
|
||||
if ( framenum < 0 ) framenum = 0;
|
||||
fb->current_bitmap = fl->bitmap_id + framenum;
|
||||
}
|
||||
} else {
|
||||
|
||||
framenum = fl2i(fb->time_elapsed / fb->total_time * fl->num_frames + 0.5);
|
||||
|
||||
// ensure we don't go past the number of frames of animation
|
||||
if ( framenum > (fl->num_frames-1) ) {
|
||||
framenum = (fl->num_frames-1);
|
||||
else
|
||||
{
|
||||
Objects[fb->objnum].flags |= OF_SHOULD_BE_DEAD;
|
||||
fb->current_bitmap = -1;
|
||||
}
|
||||
|
||||
if ( framenum < 0 ) framenum = 0;
|
||||
fb->current_bitmap = fl->bitmap_id + framenum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,7 +1142,7 @@ void fireball_maybe_play_warp_close_sound(fireball *fb)
|
||||
}
|
||||
}
|
||||
|
||||
MONITOR( NumFireballs );
|
||||
MONITOR( NumFireballs )
|
||||
|
||||
void fireball_process_post(object * obj, float frame_time)
|
||||
{
|
||||
@@ -1131,29 +1243,32 @@ int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
|
||||
}
|
||||
}
|
||||
|
||||
if(!g3_get_bitmap_dims(fd->lod[0].bitmap_id, &v, size, &x, &y, &w, &h, &bm_size)) {
|
||||
if (Detail.hardware_textures == 4) {
|
||||
// straight LOD
|
||||
if(w <= bm_size/8){
|
||||
ret_lod = 3;
|
||||
} else if(w <= bm_size/2){
|
||||
ret_lod = 2;
|
||||
} else if(w <= (1.56*bm_size)){
|
||||
ret_lod = 1;
|
||||
if(fd->lod[0].bitmap_id > -1)
|
||||
{
|
||||
if(!g3_get_bitmap_dims(fd->lod[0].bitmap_id, &v, size, &x, &y, &w, &h, &bm_size)) {
|
||||
if (Detail.hardware_textures == 4) {
|
||||
// straight LOD
|
||||
if(w <= bm_size/8){
|
||||
ret_lod = 3;
|
||||
} else if(w <= bm_size/2){
|
||||
ret_lod = 2;
|
||||
} else if(w <= (1.56*bm_size)){
|
||||
ret_lod = 1;
|
||||
} else {
|
||||
ret_lod = 0;
|
||||
}
|
||||
} else {
|
||||
ret_lod = 0;
|
||||
}
|
||||
} else {
|
||||
// less aggressive LOD for lower detail settings
|
||||
if(w <= bm_size/8){
|
||||
ret_lod = 3;
|
||||
} else if(w <= bm_size/3){
|
||||
ret_lod = 2;
|
||||
} else if(w <= (1.2*bm_size)){
|
||||
ret_lod = 1;
|
||||
} else {
|
||||
ret_lod = 0;
|
||||
}
|
||||
// less aggressive LOD for lower detail settings
|
||||
if(w <= bm_size/8){
|
||||
ret_lod = 3;
|
||||
} else if(w <= bm_size/3){
|
||||
ret_lod = 2;
|
||||
} else if(w <= (1.2*bm_size)){
|
||||
ret_lod = 1;
|
||||
} else {
|
||||
ret_lod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,7 +1310,7 @@ int fireball_create( vec3d * pos, int fireball_type, int parent_obj, float size,
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Num_fireballs >= MAX_FIREBALLS) || (num_objects >= MAX_OBJECTS) ) {
|
||||
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?
|
||||
@@ -1379,12 +1494,32 @@ void fireballs_page_in()
|
||||
if ( (i == FIREBALL_WARP_EFFECT) && (idx > MAX_WARP_LOD) )
|
||||
continue;
|
||||
|
||||
bm_page_in_texture( fd->lod[idx].bitmap_id, fd->lod[idx].num_frames );
|
||||
if(fd->lod[idx].bitmap_id > -1)
|
||||
bm_page_in_texture( fd->lod[idx].bitmap_id, fd->lod[idx].num_frames );
|
||||
}
|
||||
}
|
||||
|
||||
bm_page_in_texture( Warp_glow_bitmap );
|
||||
|
||||
bm_page_in_texture( Warp_ball_bitmap );
|
||||
}
|
||||
|
||||
void fireball_get_color(int idx, float *red, float *green, float *blue)
|
||||
{
|
||||
Assert( red && blue && green );
|
||||
|
||||
if ( (idx < 0) || (idx >= MAX_FIREBALL_TYPES) ) {
|
||||
Int3();
|
||||
|
||||
*red = 1.0f;
|
||||
*green = 1.0f;
|
||||
*blue = 1.0f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fireball_info *fbi = &Fireball_info[idx];
|
||||
|
||||
*red = fbi->exp_color[0];
|
||||
*green = fbi->exp_color[1];
|
||||
*blue = fbi->exp_color[2];
|
||||
}
|
||||
@@ -9,13 +9,20 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fireball/FireBalls.h $
|
||||
* $Revision: 2.14 $
|
||||
* $Date: 2005-07-13 02:50:52 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 2.16 $
|
||||
* $Date: 2007-11-22 05:02:44 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Prototypes for fireball functions
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.15 2007/02/11 18:19:41 taylor
|
||||
* support for tbl specified fireball explosion color ("$Light color:")
|
||||
*
|
||||
* Revision 2.14 2005/07/13 02:50:52 Goober5000
|
||||
* remove PreProcDefine #includes in FS2
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 2.13 2005/04/05 05:53:15 taylor
|
||||
* s/vector/vec3d/g, better support for different compilers (Jens Granseuer)
|
||||
*
|
||||
@@ -237,7 +244,8 @@ typedef struct fireball_lod {
|
||||
} fireball_lod;
|
||||
|
||||
typedef struct fireball_info {
|
||||
int lod_count;
|
||||
int lod_count;
|
||||
float exp_color[3];
|
||||
fireball_lod lod[4];
|
||||
} fireball_info;
|
||||
|
||||
@@ -289,10 +297,11 @@ float fireball_lifeleft( object *obj );
|
||||
// Returns life left of a fireball in percent
|
||||
float fireball_lifeleft_percent( object *obj );
|
||||
|
||||
// returns the lighting color (in [0...1] range) to use for explosion
|
||||
void fireball_get_color(int idx, float *red, float *green, float *blue);
|
||||
|
||||
// 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 );
|
||||
extern int Warp_glow_bitmap; // Internal
|
||||
extern int Warp_ball_bitmap; // Internal
|
||||
|
||||
extern int Warp_model;
|
||||
|
||||
|
||||
+95
-142
@@ -9,13 +9,35 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fireball/WarpInEffect.cpp $
|
||||
* $Revision: 2.32 $
|
||||
* $Date: 2006-03-31 10:20:01 $
|
||||
* $Author: wmcoolmon $
|
||||
* $Revision: 2.37 $
|
||||
* $Date: 2007-11-22 05:02:44 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Code for rendering the warp in effects for ships
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 2.36 2006/11/16 01:10:47 taylor
|
||||
* do no culling on the warp effect model_render call properly (doesn't appear to break anything now that it actually set to not cull)
|
||||
*
|
||||
* Revision 2.35 2006/11/06 06:33:48 taylor
|
||||
* more cleanup of warp_global crap
|
||||
* scale render/detail box limits with detail level setting
|
||||
* make sure that we reset culling and zbuffer after each model buffer that gets rendered
|
||||
*
|
||||
* Revision 2.34 2006/11/06 06:19:17 taylor
|
||||
* rename set_warp_globals() to model_set_warp_globals()
|
||||
* remove two old/unused MR flags (MR_ALWAYS_REDRAW, used for caching that doesn't work; MR_SHOW_DAMAGE, didn't do anything)
|
||||
* add MR_FULL_DETAIL to render an object regardless of render/detail box setting
|
||||
* change "model_current_LOD" to a global "Interp_detail_level" and the static "Interp_detail_level" to "Interp_detail_level_locked", a bit more descriptive
|
||||
* minor bits of cleanup
|
||||
* change a couple of vm_vec_scale_add2() calls to just vm_vec_add2() calls in ship.cpp, since that was the final result anyway
|
||||
*
|
||||
* Revision 2.33 2006/07/21 16:04:46 taylor
|
||||
* little cleanup
|
||||
*
|
||||
* Revision 2.32 2006/03/31 10:20:01 wmcoolmon
|
||||
* Prelim. BSG warpin effect stuff
|
||||
*
|
||||
* Revision 2.31 2005/09/21 03:55:32 Goober5000
|
||||
* add option for warp flash; mess with the cmdlines a bit
|
||||
* --Goober5000
|
||||
@@ -254,29 +276,21 @@
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "model/model.h"
|
||||
#include "ship/ship.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
|
||||
|
||||
extern int Warp_model;
|
||||
extern int Cmdline_nohtl;
|
||||
extern int Cmdline_3dwarp;
|
||||
extern int Cmdline_warp_flash;
|
||||
extern int Warp_glow_bitmap;
|
||||
extern int Warp_ball_bitmap;
|
||||
|
||||
|
||||
DCF(norm,"normalize a zero length vector")
|
||||
{
|
||||
if ( Dc_command ) {
|
||||
vec3d tmp = vmd_zero_vector;
|
||||
vm_vec_normalize(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_face( vertex *v1, vertex *v2, vertex *v3 )
|
||||
{
|
||||
vec3d norm;
|
||||
vertex *vertlist[3];
|
||||
|
||||
vm_vec_perp(&norm,(vec3d *)&v1->x,(vec3d *)&v2->x,(vec3d *)&v3->x);
|
||||
if ( vm_vec_dot(&norm,(vec3d *)&v1->x ) >= 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;
|
||||
@@ -290,149 +304,76 @@ void draw_face( vertex *v1, vertex *v2, vertex *v3 )
|
||||
|
||||
}
|
||||
|
||||
#define wSTUFF_VERTICES() do { verts[0]->u = 0.5f; verts[0]->v = 0.0f; verts[1]->u = 1.0f; verts[1]->v = 0.0f; verts[2]->u = 1.0f; verts[2]->v = 1.0f; verts[3]->u = 0.5f; verts[3]->v = 1.0f; } while(0);
|
||||
#define wR_VERTICES() do { g3_rotate_vertex(verts[0], &bottom1); g3_rotate_vertex(verts[1], &bottom2); g3_rotate_vertex(verts[2], &top2); g3_rotate_vertex(verts[3], &top1); } while(0);
|
||||
#define wP_VERTICES() do { for(idx=0; idx<4; idx++){ g3_project_vertex(verts[idx]); } } while(0);
|
||||
|
||||
void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
{
|
||||
static flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
|
||||
|
||||
int i;
|
||||
|
||||
vec3d center;
|
||||
vec3d vecs[5];
|
||||
vertex verts[5];
|
||||
int saved_gr_zbuffering = gr_zbuffer_get();
|
||||
|
||||
// gr_zbuffering = 0;
|
||||
|
||||
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
vec3d center;
|
||||
gr_zbuffer_set(GR_ZBUFF_READ);
|
||||
|
||||
vm_vec_scale_add( ¢er, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
|
||||
|
||||
// Warp_Map = texture_bitmap_num;//sets the warp map, and thus sets the interp flag for this being a warpin effect
|
||||
vec3d vecs[5];
|
||||
vertex verts[5];
|
||||
|
||||
vecs[4] = center; //this is for the warp glow-Bobboau
|
||||
verts[4].u = 0.5f; verts[4].v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
if ( Warp_glow_bitmap != -1 ) {
|
||||
gr_set_bitmap( Warp_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, (The_mission.flags & MISSION_FLAG_FULLNEB)?(1.0f - neb2_get_fog_intensity(obj)):1.0f );
|
||||
|
||||
if (Warp_glow_bitmap >= 0) {
|
||||
float r = radius;
|
||||
bool render_it = (Cmdline_warp_flash == 1);
|
||||
|
||||
int render_it;
|
||||
|
||||
#define OUT_PERCENT1 0.80f
|
||||
#define OUT_PERCENT2 0.90f
|
||||
|
||||
#define IN_PERCENT1 0.10f
|
||||
#define IN_PERCENT2 0.20f
|
||||
|
||||
if ( life_percent < IN_PERCENT1 ) {
|
||||
// do nothing
|
||||
render_it = 1;
|
||||
} else if ( life_percent < IN_PERCENT2 ) {
|
||||
r *= ( life_percent-IN_PERCENT1 ) / (IN_PERCENT2-IN_PERCENT1);
|
||||
render_it = 1;
|
||||
} else if ( life_percent < OUT_PERCENT1 ) {
|
||||
// do nothing
|
||||
render_it = 1;
|
||||
} else if ( life_percent < OUT_PERCENT2 ) {
|
||||
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2-OUT_PERCENT1);
|
||||
render_it = 1;
|
||||
} else {
|
||||
// do nothing
|
||||
render_it = 1;
|
||||
if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
|
||||
r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
|
||||
render_it = true;
|
||||
} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
|
||||
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
|
||||
render_it = true;
|
||||
}
|
||||
|
||||
if (render_it) {
|
||||
int saved_gr_zbuffering = gr_zbuffer_get();
|
||||
gr_zbuffer_set(GR_ZBUFF_READ);
|
||||
|
||||
if (render_it) {
|
||||
// Add in noise
|
||||
//float Noise[NOISE_NUM_FRAMES] = {
|
||||
int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
|
||||
|
||||
r *= (0.40f + Noise[noise_frame]*0.30f);
|
||||
r *= (0.40f + Noise[noise_frame] * 0.30f);
|
||||
|
||||
// Bobboau's warp thingie, toggled by cmdline
|
||||
if (Cmdline_warp_flash)
|
||||
{
|
||||
r += (float)pow((2.0f*life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
|
||||
if (Cmdline_warp_flash) {
|
||||
r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
|
||||
}
|
||||
|
||||
|
||||
vecs[4] = center;
|
||||
verts[4].u = 0.5f; verts[4].v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
|
||||
gr_set_bitmap( Warp_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha );
|
||||
|
||||
g3_draw_bitmap( &verts[4], 0, r, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
||||
gr_zbuffer_set(saved_gr_zbuffering);
|
||||
}
|
||||
}
|
||||
|
||||
if((Warp_model >= 0) && (warp_3d || Cmdline_3dwarp))
|
||||
{
|
||||
float model_Interp_scale_xyz = radius / 20.0f;
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
float scale = radius / 25.0f;
|
||||
model_set_warp_globals(scale, scale, scale, texture_bitmap_num, (radius/max_radius) );
|
||||
|
||||
set_warp_globals(model_Interp_scale_xyz, model_Interp_scale_xyz, model_Interp_scale_xyz, texture_bitmap_num, (radius/max_radius) );
|
||||
|
||||
float dist = vm_vec_dist_quick( pos, &Eye_position );
|
||||
|
||||
model_set_detail_level((int)(dist / (radius * 10.0f)));
|
||||
gr_set_cull(0);
|
||||
model_render( Warp_model, orient, pos, MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING);
|
||||
gr_set_cull(1);
|
||||
|
||||
// Warp_Map = -1;//un sets the warp map
|
||||
model_render( Warp_model, orient, pos, MR_LOCK_DETAIL | MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL );
|
||||
|
||||
set_warp_globals(1.0f, 1.0f, 1.0f, -1, -1.0f);
|
||||
model_set_warp_globals();
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
/*
|
||||
//this is that half done effect that was pissing people off-Bobboau
|
||||
|
||||
gr_set_cull(0);
|
||||
|
||||
matrix m;
|
||||
vec3d ray_dir;
|
||||
vm_vector_2_matrix(&m, &orient->vec.fvec, NULL, NULL);//this is the beam things that will come outof the point-Bobboau
|
||||
float angle = ANG_TO_RAD(135.0f);
|
||||
if(life_percent < 0.2f){
|
||||
angle = ANG_TO_RAD(135.0f * (life_percent * 5.0f));
|
||||
}
|
||||
for(int idx=0; idx<1; idx++){
|
||||
vm_vec_random_cone(&ray_dir, &orient->vec.fvec, angle, &m);
|
||||
mprintf(( "ray direction %f %f %f, orentation %f %f %f, angle %f\n",ray_dir.xyz.x, ray_dir.xyz.y, ray_dir.xyz.z, orient->vec.fvec.xyz.x, orient->vec.fvec.xyz.y, orient->vec.fvec.xyz.z, angle));
|
||||
vec3d p_temp = *pos;
|
||||
vm_vec_scale_add(&p_temp, pos, &ray_dir, (max_radius * 10 * frand_range(0.75f, 0.9f)));
|
||||
mprintf(( "end %f %f %f",p_temp.xyz.x, p_temp.xyz.y, p_temp.xyz.z));
|
||||
|
||||
vertex h1[4]; // halves of a beam section
|
||||
vertex *verts[4] = { &h1[0], &h1[1], &h1[2], &h1[3] };
|
||||
vec3d top1, bottom1, top2, bottom2;
|
||||
|
||||
beam_calc_facing_pts(&top1, &bottom1, &ray_dir, pos, 1.0f, 1.0f);
|
||||
beam_calc_facing_pts(&top2, &bottom2, &ray_dir, &p_temp, 1.0f, 1.0f);
|
||||
|
||||
mprintf(( "top1 %f %f %f, botom1 %f %f %f, \n",top1.xyz.x, top1.xyz.y, top1.xyz.z, bottom1.xyz.x, bottom1.xyz.y, bottom1.xyz.z));
|
||||
mprintf(( "top2 %f %f %f, botom2 %f %f %f, \n",top2.xyz.x, top2.xyz.y, top2.xyz.z, bottom2.xyz.x, bottom2.xyz.y, bottom2.xyz.z));
|
||||
wR_VERTICES(); // rotate and project the vertices
|
||||
wP_VERTICES();
|
||||
wSTUFF_VERTICES(); // stuff the beam with creamy goodness (texture coords)
|
||||
|
||||
gr_set_bitmap(Warp_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
|
||||
g3_draw_poly( 4, verts, TMAP_FLAG_TILED | TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT); // added TMAP_FLAG_TILED flag for beam texture tileing -Bobboau
|
||||
}
|
||||
|
||||
gr_set_cull(1);
|
||||
*/
|
||||
|
||||
|
||||
}else{
|
||||
gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
||||
|
||||
vm_vec_scale_add( &vecs[0], ¢er, &orient->vec.uvec, radius );
|
||||
@@ -451,22 +392,28 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
for (i=0; i<5; i++ ) {
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[i], &vecs[i] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[i], &vecs[i] );
|
||||
}
|
||||
}
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[0], &vecs[0] );
|
||||
g3_rotate_vertex( &verts[1], &vecs[1] );
|
||||
g3_rotate_vertex( &verts[2], &vecs[2] );
|
||||
g3_rotate_vertex( &verts[3], &vecs[3] );
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[0], &vecs[0] );
|
||||
g3_transfer_vertex( &verts[1], &vecs[1] );
|
||||
g3_transfer_vertex( &verts[2], &vecs[2] );
|
||||
g3_transfer_vertex( &verts[3], &vecs[3] );
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
gr_set_cull(0); // fixes rendering problem in D3D - taylor
|
||||
draw_face( &verts[0], &verts[4], &verts[1] );
|
||||
@@ -476,15 +423,21 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
|
||||
gr_set_cull(1);
|
||||
}
|
||||
|
||||
if ( Warp_ball_bitmap > -1 ){
|
||||
g3_start_instance_matrix(pos,orient, true);
|
||||
gr_set_bitmap(Warp_ball_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
|
||||
float adg = (2.0f*life_percent) - 1.0f;
|
||||
float pct= (float)(pow(adg,4.0f)-pow(adg,128.0f))*4.0f;
|
||||
if(pct > 0.00001f)
|
||||
warp_ball.render(max_radius*pct/2.0f,adg*adg,adg*adg*6.0f);
|
||||
if (Warp_ball_bitmap > -1) {
|
||||
flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
|
||||
float adg = (2.0f * life_percent) - 1.0f;
|
||||
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
|
||||
|
||||
if (pct > 0.00001f) {
|
||||
g3_start_instance_matrix(pos, orient, true);
|
||||
|
||||
gr_set_bitmap(Warp_ball_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
|
||||
|
||||
warp_ball.render(max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
|
||||
g3_done_instance(true);
|
||||
}
|
||||
}
|
||||
|
||||
gr_zbuffer_set( saved_gr_zbuffering );
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ BEGIN_MESSAGE_MAP(CAddVariableDlg, CDialog)
|
||||
ON_BN_CLICKED(IDC_TYPE_STRING, OnTypeString)
|
||||
ON_BN_CLICKED(IDC_TYPE_CAMPAIGN_PERSISTENT, OnTypeCampaignPersistent)
|
||||
ON_BN_CLICKED(IDC_TYPE_PLAYER_PERSISTENT, OnTypePlayerPersistent)
|
||||
ON_BN_CLICKED(IDC_TYPE_NETWORK_VARIABLE, OnTypeNetworkVariable)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
@@ -115,6 +116,7 @@ BOOL CAddVariableDlg::OnInitDialog()
|
||||
m_type_number = true;
|
||||
m_type_campaign_persistent = false;
|
||||
m_type_player_persistent = false;
|
||||
m_type_network_variable = false;
|
||||
set_variable_type();
|
||||
|
||||
m_name_validated = false;
|
||||
@@ -264,6 +266,12 @@ void CAddVariableDlg::OnTypeCampaignPersistent()
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
void CAddVariableDlg::OnTypeNetworkVariable()
|
||||
{
|
||||
m_type_network_variable = ((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->GetCheck() ? true : false;
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
// Set type check boxes
|
||||
void CAddVariableDlg::set_variable_type()
|
||||
{
|
||||
@@ -276,4 +284,5 @@ void CAddVariableDlg::set_variable_type()
|
||||
|
||||
((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->SetCheck(m_type_campaign_persistent);
|
||||
((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->SetCheck(m_type_player_persistent);
|
||||
((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->SetCheck(m_type_network_variable);
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
bool m_type_number;
|
||||
bool m_type_campaign_persistent;
|
||||
bool m_type_player_persistent;
|
||||
bool m_type_network_variable;
|
||||
bool m_create;
|
||||
int m_sexp_var_index;
|
||||
//}}AFX_DATA
|
||||
@@ -61,6 +62,7 @@ protected:
|
||||
afx_msg void OnTypeString();
|
||||
afx_msg void OnTypePlayerPersistent();
|
||||
afx_msg void OnTypeCampaignPersistent();
|
||||
afx_msg void OnTypeNetworkVariable();
|
||||
afx_msg void set_variable_type();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
@@ -0,0 +1,473 @@
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "FREDDoc.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)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
multi_edit = false;
|
||||
|
||||
for (int i=0; i < MAX_ALT_CLASS_1; i++)
|
||||
{
|
||||
type1_radio_button_selection[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ASCT1_CLASS_RADIO1, OnASCT1ClassRadio)
|
||||
ON_BN_CLICKED(IDC_ASCT1_VARIABLES_RADIO1, OnASCT1VariablesRadio)
|
||||
ON_BN_CLICKED(IDC_ASCT1_CLASS_RADIO2, OnAsct1ClassRadio2)
|
||||
ON_BN_CLICKED(IDC_ASCT1_CLASS_RADIO3, OnAsct1ClassRadio3)
|
||||
ON_BN_CLICKED(IDC_ASCT1_VARIABLES_RADIO2, OnAsct1VariablesRadio2)
|
||||
ON_BN_CLICKED(IDC_ASCT1_VARIABLES_RADIO3, OnAsct1VariablesRadio3)
|
||||
ON_BN_CLICKED(IDC_ASCT2_CLASS_RADIO1, OnAsct2ClassRadio1)
|
||||
ON_BN_CLICKED(IDC_ASCT2_VARIABLES_RADIO1, OnAsct2VariablesRadio1)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// Set up pointers to all the controls to make things easier later
|
||||
type1_class_selections[0] = (CComboBox *) GetDlgItem(IDC_ASCT1_CLASS_COMBO1);
|
||||
type1_class_selections[1] = (CComboBox *) GetDlgItem(IDC_ASCT1_CLASS_COMBO2);
|
||||
type1_class_selections[2] = (CComboBox *) GetDlgItem(IDC_ASCT1_CLASS_COMBO3);
|
||||
|
||||
type1_variable_selections[0] = (CComboBox *) GetDlgItem(IDC_ASCT1_VARIABLES_COMBO1);
|
||||
type1_variable_selections[1] = (CComboBox *) GetDlgItem(IDC_ASCT1_VARIABLES_COMBO2);
|
||||
type1_variable_selections[2] = (CComboBox *) GetDlgItem(IDC_ASCT1_VARIABLES_COMBO3);
|
||||
|
||||
type1_class_radio_button[0] = IDC_ASCT1_CLASS_RADIO1;
|
||||
type1_class_radio_button[1] = IDC_ASCT1_CLASS_RADIO2;
|
||||
type1_class_radio_button[2] = IDC_ASCT1_CLASS_RADIO3;
|
||||
|
||||
type1_variable_radio_button[0] = IDC_ASCT1_VARIABLES_RADIO1;
|
||||
type1_variable_radio_button[1] = IDC_ASCT1_VARIABLES_RADIO2;
|
||||
type1_variable_radio_button[2] = IDC_ASCT1_VARIABLES_RADIO3;
|
||||
|
||||
type2_class_selections[0] = (CComboBox *) GetDlgItem(IDC_ASCT2_CLASS_COMBO1);
|
||||
|
||||
type2_variable_selections[0] = (CComboBox *) GetDlgItem(IDC_ASCT2_VARIABLES_COMBO1);
|
||||
|
||||
type2_class_radio_button[0] = IDC_ASCT2_CLASS_RADIO1;
|
||||
|
||||
type2_variable_radio_button[0] = IDC_ASCT2_VARIABLES_RADIO1;
|
||||
|
||||
// get 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);
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Set up the ship and variable combo boxes.
|
||||
|
||||
// Type 1
|
||||
for (i=0; i < MAX_ALT_CLASS_1; i++)
|
||||
{
|
||||
SetupType1ComboBoxes(type1_class_selections[i], type1_variable_selections[i], i);
|
||||
// Setup the type 1 radio buttons
|
||||
|
||||
switch (type1_radio_button_selection[i])
|
||||
{
|
||||
case 0:
|
||||
CheckDlgButton(type1_class_radio_button[i], 1);
|
||||
break;
|
||||
case 1:
|
||||
CheckDlgButton(type1_variable_radio_button[i], 1);
|
||||
break;
|
||||
default:
|
||||
CheckDlgButton(type1_class_radio_button[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Type 2
|
||||
for (i=0; i < MAX_ALT_CLASS_2; i++)
|
||||
{
|
||||
SetupType2ComboBoxes(type2_class_selections[i], type2_variable_selections[i], i);
|
||||
// Setup the type 2 radio buttons
|
||||
|
||||
switch (type2_radio_button_selection[i])
|
||||
{
|
||||
case 0:
|
||||
CheckDlgButton(type2_class_radio_button[i], 1);
|
||||
break;
|
||||
case 1:
|
||||
CheckDlgButton(type2_variable_radio_button[i], 1);
|
||||
break;
|
||||
default:
|
||||
CheckDlgButton(type2_class_radio_button[i], 1);
|
||||
}
|
||||
}
|
||||
DisableComponents();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
// Fills the combo box with the list of ships and an entry to select no ship.
|
||||
void AltShipClassDlg::FillClassComboBox(CComboBox *ptr)
|
||||
{
|
||||
ptr->ResetContent();
|
||||
// Add the default entry followed by all the ship classes
|
||||
ptr->AddString("None");
|
||||
for (int i=0; i<Num_ship_classes; i++)
|
||||
{
|
||||
ptr->AddString(Ship_info[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the position in the variables combo box that a supplied string variable will have
|
||||
int AltShipClassDlg::GetStringVariableIndex(int alt_variable_index)
|
||||
{
|
||||
// If it's -1 then this wasn't set by a sexp_variable in the first place
|
||||
if (alt_variable_index != -1)
|
||||
{
|
||||
// Loop through Sexp_variables until we have found the one corresponding to the argument
|
||||
int count = 0;
|
||||
for (int i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
if (i == alt_variable_index)
|
||||
{
|
||||
return count + ALT_SHIP_CLASS_COMBO_OFFSET;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
// Shouldn't ever get here
|
||||
Assert (false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return alt_variable_index + ALT_SHIP_CLASS_COMBO_OFFSET;
|
||||
}
|
||||
|
||||
// Returns the Sexp_variables index of the selected item
|
||||
int AltShipClassDlg::GetVariableIndexFromControl(CComboBox *variable_ptr)
|
||||
{
|
||||
char selection[TOKEN_LENGTH];
|
||||
int result = variable_ptr->GetLBText(variable_ptr->GetCurSel(), selection);
|
||||
if (!(strcmp(selection, "None")) || (result == CB_ERR))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return get_index_sexp_variable_name(selection);
|
||||
}
|
||||
|
||||
// Fills the combo box with the list of string variables and entry to select none
|
||||
void AltShipClassDlg::FillVariableComboBox(CComboBox *ptr)
|
||||
{
|
||||
ptr->ResetContent();
|
||||
ptr->AddString("None");
|
||||
for (int k=0; k < MAX_SEXP_VARIABLES; k++)
|
||||
{
|
||||
if (Sexp_variables[k].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
ptr->AddString(Sexp_variables[k].variable_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::SetupType1ComboBoxes(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index)
|
||||
{
|
||||
FillClassComboBox(class_ptr);
|
||||
FillVariableComboBox(variable_ptr);
|
||||
|
||||
// Get the data from the first ship
|
||||
|
||||
bool all_the_same = true;
|
||||
int first_alt_class = Ships[m_selected_ships[0]].alt_class_one[alt_class_index];
|
||||
int first_alt_variable = Ships[m_selected_ships[0]].alt_class_one_variable[alt_class_index];
|
||||
|
||||
// If we have multiple ships selected we'll need to check if they have the same alt class before we display anything
|
||||
if (multi_edit)
|
||||
{
|
||||
// Start at 1 not 0 as we have already read in the data for the first ship
|
||||
for (int j=1; j < num_selected_ships; j++)
|
||||
{
|
||||
if (first_alt_class != Ships[m_selected_ships[j]].alt_class_one[alt_class_index] ||
|
||||
first_alt_variable != Ships[m_selected_ships[j]].alt_class_one_variable[alt_class_index])
|
||||
{
|
||||
all_the_same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all the selected ships have the same entry already or we only have one ship we set the combo boxes to
|
||||
// display the selected value. Otherwise we set nothing and leave it showing no entry.
|
||||
if (all_the_same)
|
||||
{
|
||||
if (first_alt_variable > -1)
|
||||
{
|
||||
// Set the Radio Button to select the variable combo
|
||||
type1_radio_button_selection[alt_class_index] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the Radio Button to select the class combo
|
||||
type1_radio_button_selection[alt_class_index] = 0;
|
||||
}
|
||||
|
||||
class_ptr->SetCurSel( first_alt_class + ALT_SHIP_CLASS_COMBO_OFFSET); // Offset because we added the "none" entry
|
||||
|
||||
variable_ptr->SetCurSel(GetStringVariableIndex(first_alt_variable));
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::SetupType2ComboBoxes(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index)
|
||||
{
|
||||
FillClassComboBox(class_ptr);
|
||||
FillVariableComboBox(variable_ptr);
|
||||
|
||||
// Get the data from the first ship
|
||||
|
||||
bool all_the_same = true;
|
||||
int first_alt_class = Ships[m_selected_ships[0]].alt_class_two[alt_class_index];
|
||||
int first_alt_variable = Ships[m_selected_ships[0]].alt_class_two_variable[alt_class_index];
|
||||
|
||||
// If we have multiple ships selected we'll need to check if they have the same alt class before we display anything
|
||||
if (multi_edit)
|
||||
{
|
||||
// Start at 1 not 0 as we have already read in the data for the first ship
|
||||
for (int j=1; j < num_selected_ships; j++)
|
||||
{
|
||||
if (first_alt_class != Ships[m_selected_ships[j]].alt_class_two[alt_class_index] ||
|
||||
first_alt_variable != Ships[m_selected_ships[j]].alt_class_two_variable[alt_class_index])
|
||||
{
|
||||
all_the_same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all the selected ships have the same entry already or we only have one ship we set the combo boxes to
|
||||
// display the selected value. Otherwise we set nothing and leave it showing no entry.
|
||||
if (all_the_same)
|
||||
{
|
||||
if (first_alt_variable > -1)
|
||||
{
|
||||
// Set the Radio Button to select the variable combo
|
||||
type2_radio_button_selection[alt_class_index] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the Radio Button to select the class combo
|
||||
type2_radio_button_selection[alt_class_index] = 0;
|
||||
}
|
||||
|
||||
class_ptr->SetCurSel( first_alt_class + ALT_SHIP_CLASS_COMBO_OFFSET); // Offset because we added the "none" entry
|
||||
|
||||
variable_ptr->SetCurSel(GetStringVariableIndex(first_alt_variable));
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::DisableComponents()
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < MAX_ALT_CLASS_1; i++)
|
||||
{
|
||||
if (type1_radio_button_selection[i])
|
||||
{
|
||||
type1_class_selections[i]->EnableWindow(FALSE);
|
||||
type1_variable_selections[i]->EnableWindow(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
type1_class_selections[i]->EnableWindow(TRUE);
|
||||
type1_variable_selections[i]->EnableWindow(FALSE);
|
||||
}
|
||||
}
|
||||
for (i=0; i < MAX_ALT_CLASS_2; i++)
|
||||
{
|
||||
if (type2_radio_button_selection[i])
|
||||
{
|
||||
type2_class_selections[i]->EnableWindow(FALSE);
|
||||
type2_variable_selections[i]->EnableWindow(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
type2_class_selections[i]->EnableWindow(TRUE);
|
||||
type2_variable_selections[i]->EnableWindow(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// Don't need any extra cleanup here yet
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::WriteType1DataToShip(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index)
|
||||
{
|
||||
// Ship Class
|
||||
if (type1_radio_button_selection[alt_class_index] == 0)
|
||||
{
|
||||
int selected_ship_class = class_ptr->GetCurSel() - ALT_SHIP_CLASS_COMBO_OFFSET;
|
||||
for (int i=0; i < num_selected_ships; i++)
|
||||
{
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_one[alt_class_index], selected_ship_class);
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_one_variable[alt_class_index], -1);
|
||||
}
|
||||
}
|
||||
// Variable
|
||||
else
|
||||
{
|
||||
int selected_ship_index = GetVariableIndexFromControl(variable_ptr);
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++)
|
||||
{
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_one[alt_class_index], -1);
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_one_variable[alt_class_index], selected_ship_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::WriteType2DataToShip(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index)
|
||||
{
|
||||
// Ship Class
|
||||
if (type2_radio_button_selection[alt_class_index] == 0)
|
||||
{
|
||||
int selected_ship_class = class_ptr->GetCurSel() - ALT_SHIP_CLASS_COMBO_OFFSET;
|
||||
for (int i=0; i < num_selected_ships; i++)
|
||||
{
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_two[alt_class_index], selected_ship_class);
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_two_variable[alt_class_index], -1);
|
||||
}
|
||||
}
|
||||
// Variable
|
||||
else
|
||||
{
|
||||
int selected_ship_index = GetVariableIndexFromControl(variable_ptr);
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++)
|
||||
{
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_two[alt_class_index], -1);
|
||||
MODIFY (Ships[m_selected_ships[i]].alt_class_two_variable[alt_class_index], selected_ship_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
int i;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
// Read the selection from the ship and variable combo boxes.
|
||||
for (i=0; i < MAX_ALT_CLASS_1; i++)
|
||||
{
|
||||
WriteType1DataToShip(type1_class_selections[i], type1_variable_selections[i], i);
|
||||
}
|
||||
|
||||
for (i=0; i < MAX_ALT_CLASS_2; i++)
|
||||
{
|
||||
WriteType2DataToShip(type2_class_selections[i], type2_variable_selections[i], i);
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::OnASCT1ClassRadio()
|
||||
{
|
||||
type1_radio_button_selection[0] = 0;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAsct1ClassRadio2()
|
||||
{
|
||||
type1_radio_button_selection[1] = 0;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAsct1ClassRadio3()
|
||||
{
|
||||
type1_radio_button_selection[2] = 0;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnASCT1VariablesRadio()
|
||||
{
|
||||
type1_radio_button_selection[0] = 1;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAsct1VariablesRadio2()
|
||||
{
|
||||
type1_radio_button_selection[1] = 1;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAsct1VariablesRadio3()
|
||||
{
|
||||
type1_radio_button_selection[2] = 1;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAsct2ClassRadio1()
|
||||
{
|
||||
type2_radio_button_selection[0] = 0;
|
||||
DisableComponents();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAsct2VariablesRadio1()
|
||||
{
|
||||
type2_radio_button_selection[0] = 1;
|
||||
DisableComponents();
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// AltShipClassDlg.h
|
||||
// Karajorma
|
||||
#if !defined(AFX_ALTSHIPCLASSDLG_H__90E85121_BB19_4E95_A46F_C8AD22CD80A6__INCLUDED_)
|
||||
#define AFX_ALTSHIPCLASSDLG_H__90E85121_BB19_4E95_A46F_C8AD22CD80A6__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
#define ALT_SHIP_CLASS_COMBO_OFFSET 1
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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 };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
private:
|
||||
|
||||
|
||||
CComboBox *type1_class_selections[MAX_ALT_CLASS_1];
|
||||
CComboBox *type1_variable_selections[MAX_ALT_CLASS_1];
|
||||
CComboBox *type2_class_selections[MAX_ALT_CLASS_2];
|
||||
CComboBox *type2_variable_selections[MAX_ALT_CLASS_2];
|
||||
|
||||
int type1_radio_button_selection[MAX_ALT_CLASS_1];
|
||||
int type1_class_radio_button[MAX_ALT_CLASS_1];
|
||||
int type1_variable_radio_button[MAX_ALT_CLASS_1];
|
||||
|
||||
int type2_radio_button_selection[MAX_ALT_CLASS_2];
|
||||
int type2_class_radio_button[MAX_ALT_CLASS_2];
|
||||
int type2_variable_radio_button[MAX_ALT_CLASS_2];
|
||||
|
||||
bool multi_edit;
|
||||
// int m_ASCT1_group_one ;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void DisableComponents();
|
||||
|
||||
int GetVariableIndexFromControl(CComboBox *variable_ptr);
|
||||
int GetStringVariableIndex(int sexp_variable_index);
|
||||
|
||||
void FillClassComboBox(CComboBox *ptr);
|
||||
void FillVariableComboBox(CComboBox *ptr);
|
||||
void SetupType1ComboBoxes(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index);
|
||||
void SetupType2ComboBoxes(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index);
|
||||
|
||||
void WriteType1DataToShip(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index);
|
||||
void WriteType2DataToShip(CComboBox *class_ptr, CComboBox *variable_ptr, int alt_class_index);
|
||||
|
||||
|
||||
|
||||
// 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)
|
||||
afx_msg void OnASCT1ClassRadio();
|
||||
afx_msg void OnASCT1VariablesRadio();
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAsct1ClassRadio2();
|
||||
afx_msg void OnAsct1ClassRadio3();
|
||||
afx_msg void OnAsct1VariablesRadio2();
|
||||
afx_msg void OnAsct1VariablesRadio3();
|
||||
afx_msg void OnAsct2ClassRadio1();
|
||||
afx_msg void OnAsct2VariablesRadio1();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ALTSHIPCLASSDLG_H__90E85121_BB19_4E95_A46F_C8AD22CD80A6__INCLUDED_)
|
||||
@@ -434,7 +434,8 @@ void asteroid_editor::update_init()
|
||||
m_box_max_z.Format("%.1f", a_field[cur_field].inner_max_bound.xyz.z);
|
||||
|
||||
// set up combo boxes
|
||||
int i, j, k, index, box_index;
|
||||
uint i;
|
||||
int j, k, index, box_index;
|
||||
|
||||
// add "None" to each box
|
||||
for (k = 0; k < MAX_ACTIVE_DEBRIS_TYPES; k++)
|
||||
@@ -448,13 +449,13 @@ void asteroid_editor::update_init()
|
||||
char *debris_size[NUM_DEBRIS_SIZES] = { "Small", "Medium", "Large" };
|
||||
|
||||
// each species
|
||||
for (i = 0; i < Num_species; i++)
|
||||
for (i = 0; i < Species_info.size(); i++)
|
||||
{
|
||||
// each size
|
||||
for (j = 0; j < NUM_DEBRIS_SIZES; j++)
|
||||
{
|
||||
name = CString(Species_info[i].species_name) + " " + debris_size[j];
|
||||
index = ((i * NUM_DEBRIS_SIZES) + j);
|
||||
index = NUM_DEBRIS_SIZES + ((i * NUM_DEBRIS_SIZES) + j);
|
||||
|
||||
// each box
|
||||
for (k = 0; k < MAX_ACTIVE_DEBRIS_TYPES; k++)
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
// BackgroundChooser.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "BackgroundChooser.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundChooser dialog
|
||||
|
||||
|
||||
BackgroundChooser::BackgroundChooser(int numBackgrounds)
|
||||
: CDialog(BackgroundChooser::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(BackgroundChooser)
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_numBackgrounds = numBackgrounds;
|
||||
m_chosenBackground = -1;
|
||||
}
|
||||
|
||||
|
||||
void BackgroundChooser::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(BackgroundChooser)
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(BackgroundChooser, CDialog)
|
||||
//{{AFX_MSG_MAP(BackgroundChooser)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundChooser message handlers
|
||||
|
||||
BOOL BackgroundChooser::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < m_numBackgrounds; i++)
|
||||
{
|
||||
char temp[NAME_LENGTH];
|
||||
sprintf(temp, "Background %d", i + 1);
|
||||
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND))->AddString(temp);
|
||||
}
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND))->SetCurSel(0);
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BackgroundChooser::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
m_chosenBackground = ((CComboBox*) GetDlgItem(IDC_BACKGROUND))->GetCurSel();
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void BackgroundChooser::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void BackgroundChooser::OnClose()
|
||||
{
|
||||
OnCancel();
|
||||
}
|
||||
|
||||
int BackgroundChooser::GetChosenBackground()
|
||||
{
|
||||
return m_chosenBackground;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#if !defined(_BACKGROUND_CHOOSER_H_)
|
||||
#define _BACKGROUND_CHOOSER_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// BackgroundChooser.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundChooser dialog
|
||||
|
||||
class BackgroundChooser : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
BackgroundChooser(int numBackgrounds); // standard constructor
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
int GetChosenBackground();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(BackgroundChooser)
|
||||
enum { IDD = IDD_BACKGROUND_CHOOSER};
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(BackgroundChooser)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
int m_numBackgrounds;
|
||||
int m_chosenBackground;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(BackgroundChooser)
|
||||
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(_BACKGROUND_CHOOSER_H_)
|
||||
+400
-192
@@ -9,13 +9,44 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/BgBitmapDlg.cpp $
|
||||
* $Revision: 1.5 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2007-09-02 02:10:24 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Background space images manager dialog
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.11 2006/12/28 00:59:20 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.10 2006/11/24 22:46:25 Goober5000
|
||||
* FRED again updates backgrounds while the user is editing them
|
||||
*
|
||||
* Revision 1.9 2006/11/16 00:51:43 taylor
|
||||
* clean up skybox model selection and usage to work better with FRED
|
||||
* make sure to go ahead and set the skybox model when it's set/changed in FRED
|
||||
* go ahead and load/set the envmap when it's set/changed in FRED
|
||||
* get rid of extra envmap image types, only DDS is actually supported (not sure what the hell I was thinking there)
|
||||
*
|
||||
* Revision 1.8 2006/11/06 05:54:13 taylor
|
||||
* add envmap selection to background editor
|
||||
* change skybox selection to be a text entry or browse instead of only text entry
|
||||
* allow envmap selected in background editor to be used by FRED
|
||||
* make texture replacement work in FRED for ships (Mantis bug #1068)
|
||||
*
|
||||
* Revision 1.7 2006/08/06 18:47:29 Goober5000
|
||||
* add the multiple background feature
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.6 2006/07/20 21:43:05 karajorma
|
||||
* Fix for Mantis 996
|
||||
*
|
||||
* Revision 1.5.2.1 2006/07/20 21:15:11 karajorma
|
||||
* Fix for Mantis 996
|
||||
*
|
||||
* Revision 1.5 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.4 2006/02/25 21:46:59 Goober5000
|
||||
* spelling
|
||||
*
|
||||
@@ -179,6 +210,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "FRED.h"
|
||||
#include "BgBitmapDlg.h"
|
||||
#include "backgroundchooser.h"
|
||||
#include "starfield/starfield.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "FREDView.h"
|
||||
@@ -202,7 +234,9 @@ static char THIS_FILE[] = __FILE__;
|
||||
bg_bitmap_dlg::bg_bitmap_dlg(CWnd* pParent) : CDialog(bg_bitmap_dlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(bg_bitmap_dlg)
|
||||
m_neb_intensity = _T("");
|
||||
m_neb_intensity = _T("");
|
||||
m_skybox_model = _T("");
|
||||
m_envmap = _T("");
|
||||
m_nebula_color = -1;
|
||||
m_nebula_index = -1;
|
||||
m_bank = 0;
|
||||
@@ -271,8 +305,7 @@ void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Text(pDX, IDC_SBITMAP_B, b_bank);
|
||||
DDV_MinMaxInt(pDX, b_bank, 0, 359);
|
||||
DDX_Text(pDX, IDC_SBITMAP_H, b_heading);
|
||||
DDV_MinMaxInt(pDX, b_heading, 0, 359);
|
||||
DDX_Text(pDX, IDC_SBITMAP_SCALE_X, b_scale_x);
|
||||
DDV_MinMaxInt(pDX, b_heading, 0, 359); DDX_Text(pDX, IDC_SBITMAP_SCALE_X, b_scale_x);
|
||||
DDV_MinMaxFloat(pDX, b_scale_x, .001f, 18.0f);
|
||||
DDX_Text(pDX, IDC_SBITMAP_SCALE_Y, b_scale_y);
|
||||
DDV_MinMaxFloat(pDX, b_scale_y, .001f, 18.0f);
|
||||
@@ -281,6 +314,7 @@ void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Text(pDX, IDC_SBITMAP_DIV_Y, b_div_y);
|
||||
DDV_MinMaxInt(pDX, b_div_y, 1, 5);
|
||||
DDX_Text(pDX, IDC_SKYBOX_FNAME, m_skybox_model);
|
||||
DDX_Text(pDX, IDC_ENVMAP, m_envmap);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
@@ -317,6 +351,10 @@ BEGIN_MESSAGE_MAP(bg_bitmap_dlg, CDialog)
|
||||
ON_EN_KILLFOCUS(IDC_SUN1_B, OnKillfocusSun1B)
|
||||
ON_EN_KILLFOCUS(IDC_SUN1_SCALE, OnKillfocusSun1Scale)
|
||||
ON_BN_CLICKED(IDC_IMPORT_BACKGROUND, OnImportBackground)
|
||||
ON_BN_CLICKED(IDC_SWAP_BACKGROUND, OnSwapBackground)
|
||||
ON_CBN_SELCHANGE(IDC_BACKGROUND_NUM, OnBackgroundDropdownChange)
|
||||
ON_BN_CLICKED(IDC_SKYBOX_MODEL, OnSkyboxBrowse)
|
||||
ON_BN_CLICKED(IDC_ENVMAP_BROWSE, OnEnvmapBrowse)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
@@ -353,7 +391,9 @@ void bg_bitmap_dlg::create()
|
||||
GetDlgItem(IDC_POOF3)->SetWindowText(Neb2_poof_filenames[3]);
|
||||
GetDlgItem(IDC_POOF4)->SetWindowText(Neb2_poof_filenames[4]);
|
||||
GetDlgItem(IDC_POOF5)->SetWindowText(Neb2_poof_filenames[5]);
|
||||
GetDlgItem(IDC_SKYBOX_FNAME)->SetWindowText(The_mission.skybox_model);
|
||||
|
||||
m_skybox_model = _T(The_mission.skybox_model);
|
||||
m_envmap = _T(The_mission.envmap_name);
|
||||
|
||||
for(i=0; i<MAX_NEB2_BITMAPS; i++){
|
||||
if(strlen(Neb2_bitmap_filenames[i]) > 0){
|
||||
@@ -409,6 +449,18 @@ void bg_bitmap_dlg::create()
|
||||
m_toggle_trails = (The_mission.flags & MISSION_FLAG_TOGGLE_SHIP_TRAILS) ? 1 : 0;
|
||||
((CButton*)GetDlgItem(IDC_NEB_TOGGLE_TRAILS))->SetCheck(m_toggle_trails);
|
||||
|
||||
// setup background numbering
|
||||
for (i = 0; i < MAX_BACKGROUNDS; i++)
|
||||
{
|
||||
char temp[NAME_LENGTH];
|
||||
sprintf(temp, "Background %d", i + 1);
|
||||
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND_NUM))->AddString(temp);
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND_SWAP_NUM))->AddString(temp);
|
||||
}
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND_NUM))->SetCurSel(0);
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND_SWAP_NUM))->SetCurSel(0);
|
||||
|
||||
// setup sun and sunglow controls
|
||||
sun_data_init();
|
||||
|
||||
@@ -417,8 +469,6 @@ void bg_bitmap_dlg::create()
|
||||
|
||||
// determine if subspace is active
|
||||
m_subspace = (The_mission.flags & MISSION_FLAG_SUBSPACE) ? 1 : 0;
|
||||
|
||||
m_skybox_model=The_mission.skybox_model;
|
||||
|
||||
m_amb_red.SetRange(1,255);
|
||||
m_amb_green.SetRange(1,255);
|
||||
@@ -500,8 +550,7 @@ void bg_bitmap_dlg::OnClose()
|
||||
// init the nebula
|
||||
neb2_level_init();
|
||||
} else {
|
||||
The_mission.flags &= ~MISSION_FLAG_FULLNEB;
|
||||
Nebula_index = m_nebula_index - 1;
|
||||
The_mission.flags &= ~MISSION_FLAG_FULLNEB; Nebula_index = m_nebula_index - 1;
|
||||
Neb2_awacs = -1.0f;
|
||||
strcpy(Neb2_texture_name, "");
|
||||
}
|
||||
@@ -531,7 +580,8 @@ void bg_bitmap_dlg::OnClose()
|
||||
The_mission.flags &= ~MISSION_FLAG_SUBSPACE;
|
||||
}
|
||||
|
||||
string_copy(The_mission.skybox_model,m_skybox_model,NAME_LENGTH,1);
|
||||
string_copy(The_mission.skybox_model, m_skybox_model, NAME_LENGTH, 1);
|
||||
string_copy(The_mission.envmap_name, m_envmap, NAME_LENGTH, 1);
|
||||
|
||||
// close sun data
|
||||
sun_data_close();
|
||||
@@ -539,6 +589,11 @@ void bg_bitmap_dlg::OnClose()
|
||||
// close bitmap data
|
||||
bitmap_data_close();
|
||||
|
||||
// reset the background
|
||||
stars_pack_backgrounds();
|
||||
stars_load_first_valid_background();
|
||||
|
||||
// close window stuff
|
||||
theApp.record_window_data(&Bg_wnd_data, this);
|
||||
delete Bg_bitmap_dialog;
|
||||
Bg_bitmap_dialog = NULL;
|
||||
@@ -722,24 +777,30 @@ void bg_bitmap_dlg::build_nebfile_list()
|
||||
void bg_bitmap_dlg::sun_data_init()
|
||||
{
|
||||
int idx;
|
||||
CListBox *clb;
|
||||
uint idx2;
|
||||
CComboBox *ccb = (CComboBox*) GetDlgItem(IDC_SUN1);
|
||||
CListBox *clb = (CListBox*) GetDlgItem(IDC_SUN1_LIST);
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
|
||||
// add all suns to the drop down
|
||||
for (idx = 0; idx < stars_get_num_entries(true, true); idx++) {
|
||||
((CComboBox*)GetDlgItem(IDC_SUN1))->AddString(stars_get_name_FRED(idx, true));
|
||||
}
|
||||
|
||||
//clear instances if necessary
|
||||
clb = (CListBox*)GetDlgItem(IDC_SUN1_LIST);
|
||||
// clear if necessary
|
||||
ccb->ResetContent();
|
||||
clb->ResetContent();
|
||||
|
||||
// add all suns to the drop down
|
||||
for (idx = 0; idx < stars_get_num_entries(true, true); idx++)
|
||||
{
|
||||
ccb->AddString(stars_get_name_FRED(idx, true));
|
||||
}
|
||||
|
||||
// add all suns by bitmap filename to the list
|
||||
for (idx = 0; idx < stars_get_num_suns(); idx++) {
|
||||
clb->AddString( stars_get_sun_name(idx) );
|
||||
for (idx2 = 0; idx2 < background->suns.size(); idx2++)
|
||||
{
|
||||
clb->AddString(background->suns[idx2].filename);
|
||||
}
|
||||
|
||||
// if we have at least one item, select it
|
||||
if (stars_get_num_suns() > 0) {
|
||||
if (background->suns.size() > 0)
|
||||
{
|
||||
clb->SetCurSel(0);
|
||||
OnSunChange();
|
||||
}
|
||||
@@ -753,126 +814,126 @@ void bg_bitmap_dlg::sun_data_close()
|
||||
|
||||
void bg_bitmap_dlg::sun_data_save_current()
|
||||
{
|
||||
starfield_bitmap_instance sbi;
|
||||
|
||||
// if we have an active item
|
||||
if(s_index >= 0){
|
||||
if (s_index >= 0)
|
||||
{
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
starfield_list_entry *sle = &background->suns[s_index];
|
||||
|
||||
// read out of the controls
|
||||
UpdateData(TRUE);
|
||||
|
||||
// store the data
|
||||
memset( &sbi, 0, sizeof(starfield_bitmap_instance) );
|
||||
sbi.scale_x = (float)s_scale;
|
||||
sbi.scale_y = 1.0f;
|
||||
sbi.div_x = 1;
|
||||
sbi.div_y = 1;
|
||||
sbi.ang.p = (float)fl_radian(s_pitch);
|
||||
sbi.ang.b = (float)fl_radian(s_bank);
|
||||
sbi.ang.h = (float)fl_radian(s_heading);
|
||||
|
||||
stars_modify_instance_FRED( s_index, (LPCTSTR)s_name, &sbi, true );
|
||||
strcpy(sle->filename, s_name);
|
||||
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;
|
||||
sle->div_y = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnSunChange()
|
||||
{
|
||||
int drop_index;
|
||||
starfield_bitmap_instance *sbi = NULL;
|
||||
|
||||
// save the current sun
|
||||
sun_data_save_current();
|
||||
|
||||
// select the new one
|
||||
s_index = ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->GetCurSel();
|
||||
s_index = ((CListBox*) GetDlgItem(IDC_SUN1_LIST))->GetCurSel();
|
||||
|
||||
// setup data
|
||||
if (s_index >= 0) {
|
||||
sbi = stars_get_instance(s_index, true);
|
||||
Assert( sbi != NULL );
|
||||
Assert( sbi->star_bitmap_index >= 0 );
|
||||
if (s_index >= 0)
|
||||
{
|
||||
int drop_index;
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
starfield_list_entry *sle = &background->suns[s_index];
|
||||
|
||||
s_pitch = (int)(fl_degrees(sbi->ang.p) + delta);
|
||||
s_bank = (int)(fl_degrees(sbi->ang.b) + delta);
|
||||
s_heading = (int)(fl_degrees(sbi->ang.h) + delta);
|
||||
s_scale = sbi->scale_x;
|
||||
s_name = CString( stars_get_name_FRED(sbi->star_bitmap_index, true) );
|
||||
s_name = CString(sle->filename);
|
||||
s_pitch = (int) (fl_degrees(sle->ang.p) + delta);
|
||||
s_bank = (int) (fl_degrees(sle->ang.b) + delta);
|
||||
s_heading = (int) (fl_degrees(sle->ang.h) + delta);
|
||||
s_scale = sle->scale_x;
|
||||
|
||||
// stuff back into the controls
|
||||
UpdateData(FALSE);
|
||||
|
||||
// select the proper item from the dropdown
|
||||
drop_index = ((CComboBox*)GetDlgItem(IDC_SUN1))->FindString( -1, stars_get_name_FRED(sbi->star_bitmap_index, true) );
|
||||
Assert(drop_index != CB_ERR);
|
||||
if(drop_index != CB_ERR){
|
||||
((CComboBox*)GetDlgItem(IDC_SUN1))->SetCurSel(drop_index);
|
||||
}
|
||||
drop_index = ((CComboBox*) GetDlgItem(IDC_SUN1))->FindString(-1, sle->filename);
|
||||
if(drop_index != CB_ERR)
|
||||
((CComboBox*) GetDlgItem(IDC_SUN1))->SetCurSel(drop_index);
|
||||
}
|
||||
|
||||
// refresh the background
|
||||
stars_load_background(get_active_background());
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnAddSun()
|
||||
{
|
||||
starfield_bitmap_instance sbi;
|
||||
starfield_list_entry sle;
|
||||
|
||||
// save any current
|
||||
sun_data_save_current();
|
||||
|
||||
memset( &sbi, 0, sizeof(starfield_bitmap_instance) );
|
||||
|
||||
// select the first sun by default
|
||||
sbi.star_bitmap_index = 0;
|
||||
strcpy(sle.filename, stars_get_name_FRED(0, true));
|
||||
|
||||
sbi.scale_x = 1.0f;
|
||||
sbi.scale_y = 1.0f;
|
||||
sbi.div_x = 1;
|
||||
sbi.div_y = 1;
|
||||
sbi.ang.p = 0;
|
||||
sbi.ang.b = 0;
|
||||
sbi.ang.h = 0;
|
||||
sle.ang.p = 0;
|
||||
sle.ang.b = 0;
|
||||
sle.ang.h = 0;
|
||||
sle.scale_x = 1.0f;
|
||||
sle.scale_y = 1.0f;
|
||||
sle.div_x = 1;
|
||||
sle.div_y = 1;
|
||||
|
||||
stars_add_sun_instance( (char*)stars_get_name_FRED(0, true), &sbi );
|
||||
Backgrounds[get_active_background()].suns.push_back(sle);
|
||||
|
||||
// add to the listbox and select it
|
||||
int add_index = ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->AddString( stars_get_name_FRED(0, true) );
|
||||
((CListBox*)GetDlgItem(IDC_SUN1_LIST))->SetCurSel(add_index);
|
||||
int add_index = ((CListBox*) GetDlgItem(IDC_SUN1_LIST))->AddString(sle.filename);
|
||||
((CListBox*) GetDlgItem(IDC_SUN1_LIST))->SetCurSel(add_index);
|
||||
|
||||
// call the OnSunChange function to setup all relvant data in the class
|
||||
// call the OnSunChange function to setup all relevant data in the class
|
||||
OnSunChange();
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnDelSun()
|
||||
{
|
||||
// if we don't have an active item
|
||||
if(s_index < 0){
|
||||
if(s_index < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// remove the item from the list
|
||||
((CListBox*)GetDlgItem(IDC_SUN1_LIST))->DeleteString(s_index);
|
||||
((CListBox*) GetDlgItem(IDC_SUN1_LIST))->DeleteString(s_index);
|
||||
|
||||
// remove it from the instance list
|
||||
stars_delete_instance_FRED(s_index, true);
|
||||
// remove it from the list
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
background->suns.erase(background->suns.begin() + s_index);
|
||||
|
||||
// no item selected, let the message handler assign a new one
|
||||
s_index = -1;
|
||||
|
||||
// refresh the background
|
||||
stars_load_background(get_active_background());
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnSunDropdownChange()
|
||||
{
|
||||
// if we have no active sun, do nothing
|
||||
if(s_index < 0){
|
||||
if (s_index < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
int new_index = ((CComboBox*)GetDlgItem(IDC_SUN1))->GetCurSel();
|
||||
int new_index = ((CComboBox*) GetDlgItem(IDC_SUN1))->GetCurSel();
|
||||
Assert(new_index != CB_ERR);
|
||||
|
||||
// get the new string
|
||||
if(new_index != CB_ERR){
|
||||
((CComboBox*)GetDlgItem(IDC_SUN1))->GetLBText(new_index, s_name);
|
||||
if(new_index != CB_ERR)
|
||||
{
|
||||
((CComboBox*) GetDlgItem(IDC_SUN1))->GetLBText(new_index, s_name);
|
||||
|
||||
// change the name of the string in the listbox
|
||||
((CListBox*)GetDlgItem(IDC_SUN1_LIST))->DeleteString(s_index);
|
||||
((CListBox*)GetDlgItem(IDC_SUN1_LIST))->InsertString(s_index, (const char*)s_name);
|
||||
((CListBox*) GetDlgItem(IDC_SUN1_LIST))->DeleteString(s_index);
|
||||
((CListBox*) GetDlgItem(IDC_SUN1_LIST))->InsertString(s_index, (const char*) s_name);
|
||||
|
||||
OnSunChange();
|
||||
}
|
||||
@@ -881,24 +942,30 @@ void bg_bitmap_dlg::OnSunDropdownChange()
|
||||
void bg_bitmap_dlg::bitmap_data_init()
|
||||
{
|
||||
int idx;
|
||||
CListBox* clb;
|
||||
|
||||
// add all bitmaps to the drop down
|
||||
for (idx = 0; idx < stars_get_num_entries(false, true); idx++) {
|
||||
((CComboBox*)GetDlgItem(IDC_SBITMAP))->AddString(stars_get_name_FRED(idx, false));
|
||||
}
|
||||
|
||||
clb = (CListBox*)GetDlgItem(IDC_SBITMAP_LIST);
|
||||
uint idx2;
|
||||
CComboBox *ccb = (CComboBox*) GetDlgItem(IDC_SBITMAP);
|
||||
CListBox *clb = (CListBox*) GetDlgItem(IDC_SBITMAP_LIST);
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
|
||||
// clear if necessary
|
||||
ccb->ResetContent();
|
||||
clb->ResetContent();
|
||||
|
||||
// add all bitmaps to the drop down
|
||||
for (idx = 0; idx < stars_get_num_entries(false, true); idx++)
|
||||
{
|
||||
ccb->AddString(stars_get_name_FRED(idx, false));
|
||||
}
|
||||
|
||||
// add all bitmaps by bitmap filename to the list
|
||||
for (idx = 0; idx < stars_get_num_bitmaps(); idx++) {
|
||||
clb->AddString( stars_get_bitmap_name(idx) );
|
||||
for (idx2 = 0; idx2 < background->bitmaps.size(); idx2++)
|
||||
{
|
||||
clb->AddString(background->bitmaps[idx2].filename);
|
||||
}
|
||||
|
||||
// if we have at least one item, select it
|
||||
if (stars_get_num_bitmaps() > 0) {
|
||||
if (background->bitmaps.size() > 0)
|
||||
{
|
||||
clb->SetCurSel(0);
|
||||
OnBitmapChange();
|
||||
}
|
||||
@@ -906,135 +973,138 @@ void bg_bitmap_dlg::bitmap_data_init()
|
||||
|
||||
void bg_bitmap_dlg::bitmap_data_close()
|
||||
{
|
||||
// if there is an active sun, save it
|
||||
// if there is an active bitmap, save it
|
||||
bitmap_data_save_current();
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::bitmap_data_save_current()
|
||||
{
|
||||
starfield_bitmap_instance sbi;
|
||||
|
||||
// if we have an active item
|
||||
if (b_index >= 0) {
|
||||
if (b_index >= 0)
|
||||
{
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
starfield_list_entry *sle = &background->bitmaps[b_index];
|
||||
|
||||
// read out of the controls
|
||||
UpdateData(TRUE);
|
||||
|
||||
// store the data
|
||||
memset( &sbi, 0, sizeof(starfield_bitmap_instance) );
|
||||
sbi.scale_x = (float)b_scale_x;
|
||||
sbi.scale_y = (float)b_scale_y;
|
||||
sbi.div_x = b_div_x;
|
||||
sbi.div_y = b_div_y;
|
||||
sbi.ang.p = (float)fl_radian(b_pitch);
|
||||
sbi.ang.b = (float)fl_radian(b_bank);
|
||||
sbi.ang.h = (float)fl_radian(b_heading);
|
||||
|
||||
stars_modify_instance_FRED( b_index, (LPCTSTR)b_name, &sbi, false );
|
||||
strcpy(sle->filename, b_name);
|
||||
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;
|
||||
sle->div_y = b_div_y;
|
||||
}
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnBitmapChange()
|
||||
{
|
||||
int drop_index;
|
||||
starfield_bitmap_instance *sbi = NULL;
|
||||
|
||||
// save the current bitmap
|
||||
bitmap_data_save_current();
|
||||
|
||||
// select the new one
|
||||
b_index = ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->GetCurSel();
|
||||
b_index = ((CListBox*) GetDlgItem(IDC_SBITMAP_LIST))->GetCurSel();
|
||||
|
||||
// setup data
|
||||
if (b_index >= 0) {
|
||||
sbi = stars_get_instance(b_index, false);
|
||||
Assert( sbi != NULL );
|
||||
Assert( sbi->star_bitmap_index >= 0 );
|
||||
if (b_index >= 0)
|
||||
{
|
||||
int drop_index;
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
starfield_list_entry *sle = &background->bitmaps[b_index];
|
||||
|
||||
b_pitch = (int)(fl_degrees(sbi->ang.p) + delta);
|
||||
b_bank = (int)(fl_degrees(sbi->ang.b) + delta);
|
||||
b_heading = (int)(fl_degrees(sbi->ang.h) + delta);
|
||||
b_scale_x = sbi->scale_x;
|
||||
b_scale_y = sbi->scale_y;
|
||||
b_div_x = sbi->div_x;
|
||||
b_div_y = sbi->div_y;
|
||||
b_name = CString( stars_get_name_FRED(sbi->star_bitmap_index, false) );
|
||||
b_name = CString(sle->filename);
|
||||
b_pitch = (int) (fl_degrees(sle->ang.p) + delta);
|
||||
b_bank = (int) (fl_degrees(sle->ang.b) + delta);
|
||||
b_heading = (int) (fl_degrees(sle->ang.h) + delta);
|
||||
b_scale_x = sle->scale_x;
|
||||
b_scale_y = sle->scale_y;
|
||||
b_div_x = sle->div_x;
|
||||
b_div_y = sle->div_y;
|
||||
|
||||
// stuff back into the controls
|
||||
UpdateData(FALSE);
|
||||
|
||||
// select the proper item from the dropdown
|
||||
drop_index = ((CComboBox*)GetDlgItem(IDC_SBITMAP))->FindString( -1, stars_get_name_FRED(sbi->star_bitmap_index, false) );
|
||||
Assert(drop_index != CB_ERR);
|
||||
if(drop_index != CB_ERR){
|
||||
((CComboBox*)GetDlgItem(IDC_SBITMAP))->SetCurSel(drop_index);
|
||||
}
|
||||
drop_index = ((CComboBox*) GetDlgItem(IDC_SBITMAP))->FindString(-1, sle->filename);
|
||||
if(drop_index != CB_ERR)
|
||||
((CComboBox*) GetDlgItem(IDC_SBITMAP))->SetCurSel(drop_index);
|
||||
}
|
||||
|
||||
// refresh the background
|
||||
stars_load_background(get_active_background());
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnAddBitmap()
|
||||
{
|
||||
starfield_bitmap_instance sbi;
|
||||
starfield_list_entry sle;
|
||||
|
||||
// save any current
|
||||
bitmap_data_save_current();
|
||||
|
||||
memset( &sbi, 0, sizeof(starfield_bitmap_instance) );
|
||||
|
||||
// select the first bitmap by default
|
||||
sbi.star_bitmap_index = 0;
|
||||
strcpy(sle.filename, stars_get_name_FRED(0, false));
|
||||
|
||||
sbi.scale_x = 1.0f;
|
||||
sbi.scale_y = 1.0f;
|
||||
sbi.div_x = 1;
|
||||
sbi.div_y = 1;
|
||||
sbi.ang.p = 0;
|
||||
sbi.ang.b = 0;
|
||||
sbi.ang.h = 0;
|
||||
sle.ang.p = 0;
|
||||
sle.ang.b = 0;
|
||||
sle.ang.h = 0;
|
||||
sle.scale_x = 1.0f;
|
||||
sle.scale_y = 1.0f;
|
||||
sle.div_x = 1;
|
||||
sle.div_y = 1;
|
||||
|
||||
stars_add_bitmap_instance( (char*)stars_get_name_FRED(0, false), &sbi );
|
||||
Backgrounds[get_active_background()].bitmaps.push_back(sle);
|
||||
|
||||
// add to the listbox and select it
|
||||
int add_index = ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->AddString( stars_get_name_FRED(0, false) );
|
||||
((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->SetCurSel(add_index);
|
||||
|
||||
// call the OnBitmapChange function to setup all relvant data in the class
|
||||
int add_index = ((CListBox*) GetDlgItem(IDC_SBITMAP_LIST))->AddString(sle.filename);
|
||||
((CListBox*) GetDlgItem(IDC_SBITMAP_LIST))->SetCurSel(add_index);
|
||||
|
||||
// call the OnBitmapChange function to setup all relevant data in the class
|
||||
OnBitmapChange();
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnDelBitmap()
|
||||
{
|
||||
// if we don't have an active item
|
||||
if(b_index < 0){
|
||||
if(b_index < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// remove it from the instance list
|
||||
stars_delete_instance_FRED(b_index, false);
|
||||
// remove the item from the list
|
||||
((CListBox*) GetDlgItem(IDC_SBITMAP_LIST))->DeleteString(b_index);
|
||||
|
||||
// remove it from the list
|
||||
background_t *background = &Backgrounds[get_active_background()];
|
||||
background->bitmaps.erase(background->bitmaps.begin() + b_index);
|
||||
|
||||
// no item selected, let the message handler assign a new one
|
||||
b_index = -1;
|
||||
|
||||
// refresh the background
|
||||
stars_load_background(get_active_background());
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnBitmapDropdownChange()
|
||||
{
|
||||
// if we have no active bitmap, do nothing
|
||||
if(b_index < 0){
|
||||
if (b_index < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
int new_index = ((CComboBox*)GetDlgItem(IDC_SBITMAP))->GetCurSel();
|
||||
int new_index = ((CComboBox*) GetDlgItem(IDC_SBITMAP))->GetCurSel();
|
||||
Assert(new_index != CB_ERR);
|
||||
|
||||
// get the new string
|
||||
if(new_index != CB_ERR){
|
||||
((CComboBox*)GetDlgItem(IDC_SBITMAP))->GetLBText(new_index, b_name);
|
||||
if(new_index != CB_ERR)
|
||||
{
|
||||
((CComboBox*) GetDlgItem(IDC_SBITMAP))->GetLBText(new_index, b_name);
|
||||
|
||||
// change the name of the string in the listbox
|
||||
((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->DeleteString(b_index);
|
||||
((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->InsertString(b_index, (const char*)b_name);
|
||||
((CListBox*) GetDlgItem(IDC_SBITMAP_LIST))->DeleteString(b_index);
|
||||
((CListBox*) GetDlgItem(IDC_SBITMAP_LIST))->InsertString(b_index, (const char*) b_name);
|
||||
|
||||
OnBitmapChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::get_data_spinner(NM_UPDOWN* pUD, int id, int *var, int min, int max)
|
||||
@@ -1211,7 +1281,7 @@ void bg_bitmap_dlg::OnDeltaposSun1PSpin(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
if (s_index < 0) return;
|
||||
pNMUpDown->iDelta *= -1;
|
||||
//G5K - why? pNMUpDown->iDelta *= -1;
|
||||
get_data_spinner(pNMUpDown, IDC_SUN1_P, &s_pitch, 0, 359);
|
||||
OnSunChange();
|
||||
*pResult = 0;
|
||||
@@ -1222,7 +1292,7 @@ void bg_bitmap_dlg::OnDeltaposSun1BSpin(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
if (s_index < 0) return;
|
||||
pNMUpDown->iDelta *= -1;
|
||||
//G5K - why? pNMUpDown->iDelta *= -1;
|
||||
get_data_spinner(pNMUpDown, IDC_SUN1_B, &s_bank, 0, 359);
|
||||
OnSunChange();
|
||||
*pResult = 0;
|
||||
@@ -1233,7 +1303,7 @@ void bg_bitmap_dlg::OnDeltaposSun1HSpin(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
if (s_index < 0) return;
|
||||
pNMUpDown->iDelta *= -1;
|
||||
//G5K - why? pNMUpDown->iDelta *= -1;
|
||||
get_data_spinner(pNMUpDown, IDC_SUN1_H, &s_heading, 0, 359);
|
||||
OnSunChange();
|
||||
*pResult = 0;
|
||||
@@ -1268,57 +1338,195 @@ void bg_bitmap_dlg::OnKillfocusSun1Scale()
|
||||
}
|
||||
|
||||
|
||||
extern void parse_bitmaps(mission *pm);
|
||||
extern void parse_one_background(background_t *background);
|
||||
|
||||
void bg_bitmap_dlg::OnImportBackground()
|
||||
{
|
||||
CFileDialog cfd(TRUE, ".fs2", NULL, 0, "FreeSpace2 Missions (*.fs2)|*.fs2||\0");
|
||||
char filename[256], error_str[1024];
|
||||
int rval;
|
||||
|
||||
int rval, temp, count;
|
||||
char *saved_mp;
|
||||
|
||||
//warn on pressing the button
|
||||
if (MessageBox("This action will erase any nebulae and suns already placed. Continue?", "Fred2", MB_ICONWARNING | MB_YESNO) == IDNO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//check if cancel was pressed
|
||||
if (cfd.DoModal() == IDCANCEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(filename, cfd.GetPathName());
|
||||
|
||||
if (rval = setjmp(parse_abort))
|
||||
{
|
||||
nprintf(("Error", "Error abort! Code = %i.", rval));
|
||||
sprintf(error_str, "Could not open file: %s", filename);
|
||||
MessageBox(error_str, "Unable to import mission background", MB_ICONERROR | MB_OK);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reset the starfield structures
|
||||
stars_pre_level_init();
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("BGBITMAPDLG: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
sprintf(error_str, "Could not parse file: %s", filename);
|
||||
|
||||
//parse in the new file
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
|
||||
if (skip_to_start_of_string("#Background bitmaps"))
|
||||
{
|
||||
parse_bitmaps(&The_mission);
|
||||
}
|
||||
else return;
|
||||
|
||||
//reinitialize the dialog
|
||||
sun_data_init();
|
||||
bitmap_data_init();
|
||||
OnFullNeb();
|
||||
|
||||
OnBitmapChange();
|
||||
OnSunChange();
|
||||
MessageBox(error_str, "Unable to import mission background!", MB_ICONERROR | MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
// parse in the new file
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
|
||||
if (!skip_to_start_of_string("#Background bitmaps"))
|
||||
return;
|
||||
|
||||
// skip beginning stuff
|
||||
required_string("#Background bitmaps");
|
||||
required_string("$Num stars:");
|
||||
stuff_int(&temp);
|
||||
required_string("$Ambient light level:");
|
||||
stuff_int(&temp);
|
||||
|
||||
saved_mp = Mp;
|
||||
|
||||
// see if we have more than one background in this mission
|
||||
count = 0;
|
||||
while(skip_to_string("$Bitmap List:"))
|
||||
count++;
|
||||
|
||||
Mp = saved_mp;
|
||||
|
||||
// pick one (if count is 0, it's retail with just one background)
|
||||
if (count > 1)
|
||||
{
|
||||
int i, which;
|
||||
|
||||
BackgroundChooser dlg(count);
|
||||
if (dlg.DoModal() == IDCANCEL)
|
||||
return;
|
||||
|
||||
which = dlg.GetChosenBackground();
|
||||
|
||||
for (i = 0; i < which + 1; i++)
|
||||
skip_to_string("$Bitmap List:");
|
||||
}
|
||||
|
||||
// now parse the background we've selected
|
||||
parse_one_background(&Backgrounds[get_active_background()]);
|
||||
|
||||
reinitialize_lists();
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::reinitialize_lists()
|
||||
{
|
||||
b_index = -1;
|
||||
s_index = -1;
|
||||
|
||||
// repopulate
|
||||
sun_data_init();
|
||||
bitmap_data_init();
|
||||
|
||||
// refresh the background
|
||||
stars_load_background(get_active_background());
|
||||
}
|
||||
|
||||
int bg_bitmap_dlg::get_active_background()
|
||||
{
|
||||
// find out which background we're editing
|
||||
int idx = ((CComboBox *) GetDlgItem(IDC_BACKGROUND_NUM))->GetCurSel();
|
||||
if (idx < 0 || idx >= MAX_BACKGROUNDS)
|
||||
idx = 0;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int bg_bitmap_dlg::get_swap_background()
|
||||
{
|
||||
// find out which background we're swapping
|
||||
int idx = ((CComboBox *) GetDlgItem(IDC_BACKGROUND_SWAP_NUM))->GetCurSel();
|
||||
if (idx < 0 || idx >= MAX_BACKGROUNDS)
|
||||
idx = 0;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnBackgroundDropdownChange()
|
||||
{
|
||||
reinitialize_lists();
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnSwapBackground()
|
||||
{
|
||||
int idx1 = get_active_background();
|
||||
int idx2 = get_swap_background();
|
||||
|
||||
// don't swap if they're the same
|
||||
if (idx1 == idx2)
|
||||
{
|
||||
MessageBox("Cannot swap a background with itself.", "FRED2", MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
// swap
|
||||
stars_swap_backgrounds(idx1, idx2);
|
||||
|
||||
// refresh dialog
|
||||
reinitialize_lists();
|
||||
}
|
||||
|
||||
|
||||
char *Model_file_ext = "Model Files (*.pof)|*.pof|"
|
||||
"|";
|
||||
|
||||
char *Image_file_ext = "DDS Files (*.dds)|*.dds|"
|
||||
"|";
|
||||
|
||||
void bg_bitmap_dlg::OnSkyboxBrowse()
|
||||
{
|
||||
CString filename;
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
// get list of
|
||||
z = cfile_push_chdir(CF_TYPE_DATA);
|
||||
CFileDialog dlg(TRUE, NULL, filename, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, Model_file_ext);
|
||||
|
||||
// if we have a result
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_skybox_model = dlg.GetFileName();
|
||||
// } else {
|
||||
// m_skybox_model = _T("");
|
||||
}
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
// restore directory
|
||||
if ( !z )
|
||||
cfile_pop_dir();
|
||||
|
||||
// load/display new skybox model (if one was selected)
|
||||
stars_set_background_model( (char*)(LPCTSTR)m_skybox_model, NULL );
|
||||
}
|
||||
|
||||
void bg_bitmap_dlg::OnEnvmapBrowse()
|
||||
{
|
||||
CString filename;
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
ENVMAP = -1;
|
||||
|
||||
// get list of
|
||||
z = cfile_push_chdir(CF_TYPE_DATA);
|
||||
CFileDialog dlg(TRUE, NULL, filename, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, Image_file_ext);
|
||||
|
||||
// if we have a result
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_envmap = dlg.GetFileName();
|
||||
// } else {
|
||||
// m_envmap = _T("");
|
||||
}
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
// restore directory
|
||||
if ( !z )
|
||||
cfile_pop_dir();
|
||||
|
||||
// set the new envmap
|
||||
ENVMAP = bm_load( (char*)(LPCTSTR)m_envmap );
|
||||
}
|
||||
@@ -9,13 +9,20 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/BgBitmapDlg.h $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2006-11-06 05:54:13 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* Background space images manager dialog
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.3 2006/08/06 18:47:29 Goober5000
|
||||
* add the multiple background feature
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.2 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -201,6 +208,7 @@ public:
|
||||
int b_div_y;
|
||||
int b_index;
|
||||
CString m_skybox_model;
|
||||
CString m_envmap;
|
||||
//}}AFX_DATA
|
||||
|
||||
// Overrides
|
||||
@@ -215,6 +223,10 @@ protected:
|
||||
// clear and build the nebula filename list appropriately
|
||||
void build_nebfile_list();
|
||||
|
||||
int get_active_background();
|
||||
int get_swap_background();
|
||||
void reinitialize_lists();
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(bg_bitmap_dlg)
|
||||
afx_msg void OnClose();
|
||||
@@ -250,6 +262,10 @@ protected:
|
||||
afx_msg void OnKillfocusSun1B();
|
||||
afx_msg void OnKillfocusSun1Scale();
|
||||
afx_msg void OnImportBackground();
|
||||
afx_msg void OnSwapBackground();
|
||||
afx_msg void OnBackgroundDropdownChange();
|
||||
afx_msg void OnSkyboxBrowse();
|
||||
afx_msg void OnEnvmapBrowse();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
|
||||
@@ -9,13 +9,20 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/BriefingEditorDlg.cpp $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2006-05-30 02:13:22 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.6 $
|
||||
* $Date: 2007-04-08 08:37:37 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* Briefing editor dialog box class.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.5 2007/03/07 22:43:24 karajorma
|
||||
* Make .ogg voice files selectable in FRED.
|
||||
*
|
||||
* Revision 1.4 2006/05/30 02:13:22 Goober5000
|
||||
* add substitute music boxes to FRED, and reset music properly when mission is cleared
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.3 2006/02/04 07:05:03 Goober5000
|
||||
* fixed several IFF bugs in FRED (plus one or two other bugs)
|
||||
* --Goober5000
|
||||
@@ -903,7 +910,7 @@ void briefing_editor_dlg::OnBrowse()
|
||||
z = cfile_push_chdir(CF_TYPE_VOICE_BRIEFINGS);
|
||||
|
||||
CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Wave Files (*.wav)|*.wav||");
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_voice = dlg.GetFileName();
|
||||
@@ -1504,7 +1511,7 @@ void briefing_editor_dlg::OnPlay()
|
||||
GetDlgItem(IDC_VOICE)->GetWindowText(m_voice);
|
||||
|
||||
int size, offset;
|
||||
cf_find_file_location((char *) (LPCSTR) m_voice, m_voice.GetLength(), CF_TYPE_ANY, path, &size, &offset );
|
||||
cf_find_file_location((char *) (LPCSTR) m_voice, CF_TYPE_ANY, m_voice.GetLength(), path, &size, &offset );
|
||||
|
||||
PlaySound(path, NULL, SND_ASYNC | SND_FILENAME);
|
||||
}
|
||||
|
||||
@@ -31,42 +31,8 @@ static char THIS_FILE[] = __FILE__;
|
||||
int Cur_campaign_mission = -1;
|
||||
int Cur_campaign_link = -1;
|
||||
|
||||
// determine the node number that would be allocated without actually allocating it yet.
|
||||
int campaign_sexp_tree::get_new_node_position()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_SEXP_TREE_SIZE; i++){
|
||||
if (nodes[i].type == SEXPT_UNUSED){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// construct tree nodes for an sexp, adding them to the list and returning first node
|
||||
int campaign_sexp_tree::load_sub_tree(int index)
|
||||
{
|
||||
int cur;
|
||||
|
||||
if (index < 0) {
|
||||
cur = allocate_node(-1);
|
||||
set_node(cur, (SEXPT_OPERATOR | SEXPT_VALID), "do-nothing"); // setup a default tree if none
|
||||
return cur;
|
||||
}
|
||||
|
||||
// assumption: first token is an operator. I require this because it would cause problems
|
||||
// with child/parent relations otherwise, and it should be this way anyway, since the
|
||||
// return type of the whole sexp is boolean, and only operators can satisfy this.
|
||||
Assert(Sexp_nodes[index].subtype == SEXP_ATOM_OPERATOR);
|
||||
cur = get_new_node_position();
|
||||
load_branch(index, -1);
|
||||
return cur;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// campaign_editor
|
||||
// campaign_editor dialog
|
||||
|
||||
IMPLEMENT_DYNCREATE(campaign_editor, CFormView)
|
||||
|
||||
@@ -217,7 +183,7 @@ void campaign_editor::load_campaign()
|
||||
if (!strlen(Campaign.filename))
|
||||
strcpy(Campaign.filename, BUILTIN_CAMPAIGN);
|
||||
|
||||
if (mission_campaign_load(Campaign.filename, 0)) {
|
||||
if (mission_campaign_load(Campaign.filename, NULL, 0)) {
|
||||
MessageBox("Couldn't open Campaign file!", "Error");
|
||||
Campaign_wnd->OnCpgnFileNew();
|
||||
return;
|
||||
@@ -383,7 +349,7 @@ void campaign_editor::load_tree(int save_first)
|
||||
|
||||
for (i=0; i<Total_links; i++) {
|
||||
if (Links[i].from == Cur_campaign_mission) {
|
||||
Links[i].node = m_tree.load_sub_tree(Links[i].sexp);
|
||||
Links[i].node = m_tree.load_sub_tree(Links[i].sexp, true, "do-nothing");
|
||||
m_num_links++;
|
||||
|
||||
if (Links[i].from == Links[i].to) {
|
||||
@@ -872,7 +838,8 @@ void campaign_editor::OnBrowseLoopSound()
|
||||
|
||||
// switch directories
|
||||
pushed_dir = cfile_push_chdir(CF_TYPE_VOICE_CMD_BRIEF);
|
||||
CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Wave Files (*.wav)|*.wav||");
|
||||
CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_loop_brief_sound = dlg.GetFileName();
|
||||
@@ -916,7 +883,8 @@ void campaign_editor::OnChangeDebriefingPersona()
|
||||
GetDlgItem(IDC_DEBRIEFING_PERSONA)->GetWindowText(str);
|
||||
persona = atoi(str);
|
||||
|
||||
if (persona < 0) persona = 0;
|
||||
if (persona < 0 || persona > 0xff)
|
||||
persona = 0;
|
||||
|
||||
Campaign.missions[Cur_campaign_mission].debrief_persona_index = persona;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
|
||||
class campaign_sexp_tree : public sexp_tree
|
||||
{
|
||||
public:
|
||||
int load_sub_tree(int index);
|
||||
int get_new_node_position();
|
||||
};
|
||||
|
||||
class campaign_editor : public CFormView
|
||||
|
||||
@@ -59,7 +59,7 @@ void campaign_filelist_box::initialize()
|
||||
|
||||
i=0;
|
||||
|
||||
do
|
||||
while (i < num_files)
|
||||
{
|
||||
// make a call to get the mission info for this mission. Passing a misison as the second
|
||||
// parameter will prevent The_mission from getting overwritten.
|
||||
@@ -75,8 +75,7 @@ void campaign_filelist_box::initialize()
|
||||
AddString(mission_filenames[i]);
|
||||
|
||||
i++;
|
||||
} while (i < num_files);
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<Campaign.num_missions; i++) {
|
||||
|
||||
+18
-5
@@ -9,13 +9,23 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/CmdBrief.cpp $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2007-04-08 08:37:37 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* Command Briefing Editor
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.3 2007/03/07 22:43:24 karajorma
|
||||
* Make .ogg voice files selectable in FRED.
|
||||
*
|
||||
* Revision 1.2 2006/11/06 05:49:02 taylor
|
||||
* fix the cmdbrief editor deleting the wrong stage (Mantis bug #1115)
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.3 2005/10/22 05:54:48 wmcoolmon
|
||||
* Fixed cf_find_file_location
|
||||
*
|
||||
@@ -258,6 +268,7 @@ void cmd_brief_dlg::OnInsertStage()
|
||||
Cur_cmd_brief->num_stages++;
|
||||
copy_stage(z, z + 1);
|
||||
m_cur_stage = z;
|
||||
m_last_stage = -1;
|
||||
update_data(0);
|
||||
}
|
||||
|
||||
@@ -280,6 +291,8 @@ void cmd_brief_dlg::OnDeleteStage()
|
||||
|
||||
Cur_cmd_brief->num_stages--;
|
||||
m_cur_stage = z;
|
||||
m_last_stage = -1;
|
||||
|
||||
if (m_cur_stage >= Cur_cmd_brief->num_stages)
|
||||
m_cur_stage = Cur_cmd_brief->num_stages - 1;
|
||||
|
||||
@@ -326,7 +339,7 @@ void cmd_brief_dlg::OnBrowseWave()
|
||||
UpdateData(TRUE);
|
||||
z = cfile_push_chdir(CF_TYPE_VOICE_CMD_BRIEF);
|
||||
CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Wave Files (*.wav)|*.wav||");
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_wave_filename = dlg.GetFileName();
|
||||
@@ -349,7 +362,7 @@ void cmd_brief_dlg::OnPlay()
|
||||
GetDlgItem(IDC_WAVE_FILENAME)->GetWindowText(m_wave_filename);
|
||||
|
||||
int size, offset;
|
||||
cf_find_file_location((char *) (LPCSTR) m_wave_filename, m_wave_filename.GetLength(), CF_TYPE_ANY, path, &size, &offset );
|
||||
cf_find_file_location((char *) (LPCSTR) m_wave_filename, CF_TYPE_ANY, m_wave_filename.GetLength(), path, &size, &offset );
|
||||
|
||||
PlaySound(path, NULL, SND_ASYNC | SND_FILENAME);
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "object/object.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "object/waypoint/waypoint.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
|
||||
@@ -9,13 +9,25 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/DebriefingEditorDlg.cpp $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-01-26 04:01:58 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.6 $
|
||||
* $Date: 2007-04-08 08:37:37 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* Debriefing editor dialog. Used to edit mission debriefings of course.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.5 2007/03/07 22:43:24 karajorma
|
||||
* Make .ogg voice files selectable in FRED.
|
||||
*
|
||||
* Revision 1.4 2006/09/20 05:02:41 taylor
|
||||
* properly fix the new_recommendation_text FRED problem, plus some real cleanup for that code in general, and some memory leak fixes
|
||||
*
|
||||
* Revision 1.3 2006/09/14 23:29:47 taylor
|
||||
* add default recommendation text for debriefing, it's either this or making sure that it's nul
|
||||
*
|
||||
* Revision 1.2 2006/01/26 04:01:58 Goober5000
|
||||
* spelling
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -352,7 +364,7 @@ void debriefing_editor_dlg::OnBrowse()
|
||||
z = cfile_push_chdir(CF_TYPE_VOICE_DEBRIEFINGS);
|
||||
|
||||
CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Wave Files (*.wav)|*.wav||");
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_voice = dlg.GetFileName();
|
||||
@@ -518,7 +530,7 @@ void debriefing_editor_dlg::OnPlay()
|
||||
GetDlgItem(IDC_VOICE)->GetWindowText(m_voice);
|
||||
|
||||
int size, offset;
|
||||
cf_find_file_location((char *) (LPCSTR) m_voice, m_voice.GetLength(), CF_TYPE_ANY, path, &size, &offset );
|
||||
cf_find_file_location((char *) (LPCSTR) m_voice, CF_TYPE_ANY, m_voice.GetLength(), path, &size, &offset );
|
||||
|
||||
PlaySound(path, NULL, SND_ASYNC | SND_FILENAME);
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "asteroid/asteroid.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "object/waypoint/waypoint.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
@@ -244,9 +245,9 @@ void DumpStats::get_background_stats(CString &buffer)
|
||||
|
||||
// species
|
||||
temp.Format("\t\tSpecies: ");
|
||||
for (i=0; i<Num_species; i++) {
|
||||
if (Asteroid_field.field_debris_type[i] >= 0) {
|
||||
temp += CString(Species_info[(Asteroid_field.field_debris_type[i] / NUM_DEBRIS_SIZES) - 1].species_name) + " ";
|
||||
for (uint species=0; species<Species_info.size(); species++) {
|
||||
if (Asteroid_field.field_debris_type[species] >= 0) {
|
||||
temp += CString(Species_info[(Asteroid_field.field_debris_type[species] / NUM_DEBRIS_SIZES) - 1].species_name) + " ";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,6 +310,7 @@ void DumpStats::get_object_stats(CString &buffer)
|
||||
int obj_type_count[MAX_OBJECT_TYPES];
|
||||
CString temp;
|
||||
int num_small_ships, num_big_ships, num_huge_ships;
|
||||
int i;
|
||||
|
||||
memset(obj_type_count,0, sizeof(obj_type_count));
|
||||
num_small_ships = num_big_ships = num_huge_ships= 0;
|
||||
@@ -336,7 +338,7 @@ void DumpStats::get_object_stats(CString &buffer)
|
||||
// not counting num_waves (for wings)
|
||||
obj_type_count[OBJ_SHIP] += obj_type_count[OBJ_START];
|
||||
|
||||
for (int i=0; i<MAX_OBJECT_TYPES; i++) {
|
||||
for (i=0; i<MAX_OBJECT_TYPES; i++) {
|
||||
if (obj_type_count[i] > 0) {
|
||||
switch(i) {
|
||||
case OBJ_SHIP:
|
||||
@@ -414,7 +416,7 @@ void DumpStats::get_object_stats(CString &buffer)
|
||||
buffer += "\r\nWINGS\r\n";
|
||||
for (i=0; i<MAX_WINGS; i++) {
|
||||
if (Wings[i].wave_count > 0) {
|
||||
temp.Format("\tWing Name: %s, num_ships: %d, num_waves: %d\r\n", Wings[i].name, Wings[i].wave_count, Wings[i].num_waves);
|
||||
temp.Format("\tWing Name: %s, wave_count: %d, num_waves: %d\r\n", Wings[i].name, Wings[i].wave_count, Wings[i].num_waves);
|
||||
buffer += temp;
|
||||
|
||||
num_counted_wings++;
|
||||
@@ -567,7 +569,8 @@ void DumpStats::get_messaging_info(CString &buffer)
|
||||
void DumpStats::get_species_ship_breakdown(CString &buffer)
|
||||
{
|
||||
CString temp;
|
||||
int i, species;
|
||||
uint species;
|
||||
int i;
|
||||
object *objp;
|
||||
ship *shipp;
|
||||
|
||||
@@ -575,7 +578,7 @@ void DumpStats::get_species_ship_breakdown(CString &buffer)
|
||||
|
||||
|
||||
|
||||
for (species=0; species < Num_species; species++) {
|
||||
for (species=0; species < Species_info.size(); species++) {
|
||||
buffer += Species_info[species].species_name;
|
||||
buffer += "\r\n";
|
||||
|
||||
@@ -747,7 +750,8 @@ void dump_loadout(ship *shipp, CString &loadout)
|
||||
|
||||
void DumpStats::get_default_ship_loadouts(CString &buffer)
|
||||
{
|
||||
int i, species;
|
||||
uint species;
|
||||
int i;
|
||||
object *objp;
|
||||
ship *shipp;
|
||||
CString temp, loadout;
|
||||
@@ -755,7 +759,7 @@ void DumpStats::get_default_ship_loadouts(CString &buffer)
|
||||
buffer += "\r\nSHIP SPECIES BREAKDOWN\r\n";
|
||||
|
||||
|
||||
for (species=0; species < Num_species; species++) {
|
||||
for (species=0; species < Species_info.size(); species++) {
|
||||
buffer += Species_info[species].species_name;
|
||||
buffer += "\r\n";
|
||||
|
||||
|
||||
+58
-50
@@ -9,13 +9,37 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/fred2/EventEditor.cpp $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-04-30 16:39:43 $
|
||||
* $Author: phreak $
|
||||
* $Revision: 1.9 $
|
||||
* $Date: 2007-11-23 23:05:39 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Event editor dialog box class and event tree class
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.8 2007/09/02 20:07:43 Goober5000
|
||||
* fix for 1471
|
||||
*
|
||||
* Revision 1.7 2007/09/02 02:10:24 Goober5000
|
||||
* added fixes for #1415 and #1483, made sure every read_file_text had a corresponding setjmp, and sync'd the parse error messages between HEAD and stable
|
||||
*
|
||||
* Revision 1.6 2007/03/07 22:43:24 karajorma
|
||||
* Make .ogg voice files selectable in FRED.
|
||||
*
|
||||
* Revision 1.5 2007/02/15 02:03:55 phreak
|
||||
* Apparently Visual C++ 2005 follows standard syntax rules.
|
||||
*
|
||||
* Revision 1.4 2007/02/11 09:37:18 taylor
|
||||
* dd VALID_FNAME() macro and put it around a few places (more to come)
|
||||
* clean out some old variables
|
||||
* move CLAMP() macro from opengl header to global header
|
||||
* update COUNT_ESTIMATE to match new bmpman changes
|
||||
*
|
||||
* Revision 1.3 2006/10/09 05:25:18 Goober5000
|
||||
* make sexp nodes dynamic
|
||||
*
|
||||
* Revision 1.2 2006/04/30 16:39:43 phreak
|
||||
* You can now preview sounds again in the event editor.
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -173,38 +197,6 @@ static char THIS_FILE[] = __FILE__;
|
||||
|
||||
event_editor *Event_editor_dlg = NULL; // global reference needed by event tree class
|
||||
|
||||
// determine the node number that would be allocated without actually allocating it yet.
|
||||
int sexp_event_tree::get_new_node_position()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_SEXP_TREE_SIZE; i++)
|
||||
if (nodes[i].type == SEXPT_UNUSED)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// construct tree nodes for an sexp, adding them to the list and returning first node
|
||||
int sexp_event_tree::load_sub_tree(int index)
|
||||
{
|
||||
int cur;
|
||||
|
||||
if (index < 0) {
|
||||
cur = allocate_node(-1);
|
||||
set_node(cur, SEXPT_OPERATOR, "do-nothing"); // setup a default tree if none
|
||||
return cur;
|
||||
}
|
||||
|
||||
// assumption: first token is an operator. I require this because it would cause problems
|
||||
// with child/parent relations otherwise, and it should be this way anyway, since the
|
||||
// return type of the whole sexp is boolean, and only operators can satisfy this.
|
||||
Assert(Sexp_nodes[index].subtype == SEXP_ATOM_OPERATOR);
|
||||
cur = get_new_node_position();
|
||||
load_branch(index, -1);
|
||||
return cur;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// event_editor dialog
|
||||
|
||||
@@ -473,7 +465,7 @@ void event_editor::load_tree()
|
||||
strcpy(m_events[i].name, "<Unnamed>");
|
||||
}
|
||||
|
||||
m_events[i].formula = m_event_tree.load_sub_tree(Mission_events[i].formula);
|
||||
m_events[i].formula = m_event_tree.load_sub_tree(Mission_events[i].formula, false, "do-nothing");
|
||||
|
||||
// we must check for the case of the repeat count being 0. This would happen if the repeat
|
||||
// count is not specified in a mission
|
||||
@@ -768,7 +760,7 @@ void event_editor::update_cur_message()
|
||||
|
||||
int event_editor::handler(int code, int node, char *str)
|
||||
{
|
||||
int i;
|
||||
int i, index;
|
||||
|
||||
switch (code) {
|
||||
case ROOT_DELETED:
|
||||
@@ -777,6 +769,7 @@ int event_editor::handler(int code, int node, char *str)
|
||||
break;
|
||||
|
||||
Assert(i < m_num_events);
|
||||
index = i;
|
||||
while (i < m_num_events - 1) {
|
||||
m_events[i] = m_events[i + 1];
|
||||
m_sig[i] = m_sig[i + 1];
|
||||
@@ -785,6 +778,10 @@ int event_editor::handler(int code, int node, char *str)
|
||||
|
||||
m_num_events--;
|
||||
GetDlgItem(IDC_BUTTON_NEW_EVENT)->EnableWindow(TRUE);
|
||||
|
||||
cur_event = index;
|
||||
update_cur_event();
|
||||
|
||||
return node;
|
||||
|
||||
case ROOT_RENAMED:
|
||||
@@ -825,18 +822,26 @@ void event_editor::OnInsert()
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=m_num_events; i>cur_event; i--) {
|
||||
m_events[i] = m_events[i - 1];
|
||||
m_sig[i] = m_sig[i - 1];
|
||||
if(cur_event < 0 || m_num_events == 0)
|
||||
{
|
||||
//There are no events yet, so just create one
|
||||
reset_event(m_num_events++, TVI_LAST);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=m_num_events; i>cur_event; i--) {
|
||||
m_events[i] = m_events[i - 1];
|
||||
m_sig[i] = m_sig[i - 1];
|
||||
}
|
||||
|
||||
if (cur_event){
|
||||
reset_event(cur_event, get_event_handle(cur_event - 1));
|
||||
} else {
|
||||
reset_event(cur_event, TVI_FIRST);
|
||||
if (cur_event){
|
||||
reset_event(cur_event, get_event_handle(cur_event - 1));
|
||||
} else {
|
||||
reset_event(cur_event, TVI_FIRST);
|
||||
}
|
||||
|
||||
m_num_events++;
|
||||
}
|
||||
|
||||
m_num_events++;
|
||||
}
|
||||
|
||||
HTREEITEM event_editor::get_event_handle(int num)
|
||||
@@ -1085,6 +1090,8 @@ void event_editor::update_cur_event()
|
||||
GetDlgItem(IDC_OBJ_TEXT) -> EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_OBJ_KEY_TEXT) -> EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EVENT_TEAM)->EnableWindow(FALSE);
|
||||
|
||||
UpdateData(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1132,6 +1139,7 @@ void event_editor::update_cur_event()
|
||||
if ( The_mission.game_type & MISSION_TYPE_MULTI_TEAMS ){
|
||||
GetDlgItem(IDC_EVENT_TEAM)->EnableWindow(TRUE);
|
||||
}
|
||||
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
@@ -1225,7 +1233,7 @@ void event_editor::OnChained()
|
||||
|
||||
void event_editor::OnSelchangeMessageList()
|
||||
{
|
||||
static flag = 0;
|
||||
static int flag = 0;
|
||||
|
||||
if (flag)
|
||||
return;
|
||||
@@ -1279,7 +1287,7 @@ int event_editor::save_message(int num)
|
||||
}
|
||||
|
||||
ptr = (char *) (LPCTSTR) m_avi_filename;
|
||||
if (!ptr || !strlen(ptr) || !stricmp(ptr, "none") || !stricmp(ptr, "<none>")){
|
||||
if ( !ptr || !VALID_FNAME(ptr) ) {
|
||||
m_messages[num].avi_info.name = NULL;
|
||||
} else {
|
||||
m_messages[num].avi_info.name = strdup(ptr);
|
||||
@@ -1290,7 +1298,7 @@ int event_editor::save_message(int num)
|
||||
}
|
||||
|
||||
ptr = (char *) (LPCTSTR) m_wave_filename;
|
||||
if (!ptr || !strlen(ptr) || !stricmp(ptr, "none") || !stricmp(ptr, "<none>")){
|
||||
if ( !ptr || !VALID_FNAME(ptr) ) {
|
||||
m_messages[num].wave_info.name = NULL;
|
||||
} else {
|
||||
m_messages[num].wave_info.name = strdup(ptr);
|
||||
@@ -1411,7 +1419,7 @@ void event_editor::OnBrowseWave()
|
||||
z = cfile_push_chdir(CF_TYPE_VOICE_SPECIAL);
|
||||
|
||||
CFileDialog dlg(TRUE, "wav", m_wave_filename, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Wave Files (*.wav)|*.wav||");
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_wave_filename = dlg.GetFileName();
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/EventEditor.h $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-10-09 05:25:18 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Event editor dialog box class and event tree class (used for dialog)
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.4 2005/07/13 02:40:50 Goober5000
|
||||
* remove PreProcDefine #includes in FRED
|
||||
* --Goober5000
|
||||
@@ -147,11 +151,8 @@
|
||||
|
||||
#define MAX_SEARCH_MESSAGE_DEPTH 5 // maximum search number of event nodes with message text
|
||||
|
||||
class sexp_event_tree : public sexp_tree
|
||||
class event_sexp_tree : public sexp_tree
|
||||
{
|
||||
public:
|
||||
int load_sub_tree(int index);
|
||||
int get_new_node_position();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -185,7 +186,7 @@ public:
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(event_editor)
|
||||
enum { IDD = IDD_EVENT_EDITOR };
|
||||
sexp_event_tree m_event_tree;
|
||||
event_sexp_tree m_event_tree;
|
||||
UINT m_repeat_count;
|
||||
UINT m_interval;
|
||||
int m_event_score;
|
||||
|
||||
+12
-7
@@ -9,15 +9,21 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/FRED.cpp $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2006-11-16 00:53:12 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* FRED.cpp : Defines the class behaviors for the application.
|
||||
* Global editor dialog box classes are instantiated here, initializes the
|
||||
* application (MFC level at least), processes the INI file.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.3 2006/10/08 02:05:38 Goober5000
|
||||
* fix forum links
|
||||
*
|
||||
* Revision 1.2 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -301,7 +307,6 @@ int Update_window = 1;
|
||||
HCURSOR h_cursor_move, h_cursor_rotate;
|
||||
|
||||
// Goober5000 - needed to restore compatibility with the changes in fs2_open
|
||||
float VIEWER_ZOOM_DEFAULT = 0.75f;
|
||||
int Show_cpu = 0;
|
||||
|
||||
CWnd *Prev_window;
|
||||
@@ -352,9 +357,9 @@ CFREDApp::CFREDApp()
|
||||
|
||||
DBUGFILE_INIT();
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifndef NDEBUG
|
||||
outwnd_init();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
CFREDApp::~CFREDApp()
|
||||
@@ -893,7 +898,7 @@ void CAboutDlg::OnBug()
|
||||
|
||||
void CAboutDlg::OnForums()
|
||||
{
|
||||
char *path = "http://dynamic4.gamespy.com/~freespace/forums/";
|
||||
char *path = "http://www.hard-light.net/forums/";
|
||||
|
||||
char buffer[MAX_PATH];
|
||||
sprintf(buffer,"explorer.exe \"%s\"", path);
|
||||
|
||||
+22
-7
@@ -9,8 +9,8 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/FRED.h $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 2007-09-03 01:02:49 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* FRED.h : main header file for the FRED application
|
||||
@@ -18,6 +18,13 @@
|
||||
* application (MFC level at least), processes the INI file.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.2 2007/02/11 21:26:34 Goober5000
|
||||
* massive shield infrastructure commit
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.5 2005/07/13 02:40:50 Goober5000
|
||||
* remove PreProcDefine #includes in FRED
|
||||
* --Goober5000
|
||||
@@ -139,13 +146,21 @@
|
||||
#include "BriefingEditorDlg.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
#define MODIFY(a, b) do { \
|
||||
if (a != (b)) { \
|
||||
a = (b); \
|
||||
set_modified(); \
|
||||
} \
|
||||
#define MODIFY(a, b) do { \
|
||||
if (a != (b)) { \
|
||||
a = (b); \
|
||||
set_modified(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define MODIFY_SHIELDS(objp, strength) do { \
|
||||
if ((int) shield_get_strength(objp) != (int) strength) { \
|
||||
shield_set_strength(objp, strength); \
|
||||
set_modified(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define F_RENDER_SHIP_MODELS 0x01
|
||||
#define F_RENDER_SHIP_ICONS 0x02
|
||||
|
||||
|
||||
+426
-247
File diff suppressed because it is too large.
Load diff
+99
-31
@@ -9,8 +9,8 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/FREDDoc.cpp $
|
||||
* $Revision: 1.6 $
|
||||
* $Date: 2006-02-11 02:58:23 $
|
||||
* $Revision: 1.15 $
|
||||
* $Date: 2008-01-17 07:44:42 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* FREDDoc.cpp : implementation of the CFREDDoc class
|
||||
@@ -19,6 +19,35 @@
|
||||
* mainly. Most of the MFC related stuff is handled in FredView.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.14 2007/12/15 07:41:13 karajorma
|
||||
* Unbreak FRED compiling
|
||||
*
|
||||
* Revision 1.13 2007/11/23 23:05:40 wmcoolmon
|
||||
* Updated event editor with minihelp box and numbered icons
|
||||
*
|
||||
* Revision 1.12 2007/09/02 02:10:24 Goober5000
|
||||
* added fixes for #1415 and #1483, made sure every read_file_text had a corresponding setjmp, and sync'd the parse error messages between HEAD and stable
|
||||
*
|
||||
* Revision 1.11 2007/07/28 21:31:10 Goober5000
|
||||
* this should really be capitalized
|
||||
*
|
||||
* Revision 1.10 2006/10/08 08:04:52 Goober5000
|
||||
* bah
|
||||
*
|
||||
* Revision 1.9 2006/10/08 05:21:44 Goober5000
|
||||
* nitpick
|
||||
*
|
||||
* Revision 1.8 2006/10/01 00:53:58 Goober5000
|
||||
* fix crlf
|
||||
*
|
||||
* Revision 1.7 2006/07/10 21:48:33 taylor
|
||||
* fix undo system
|
||||
* restore the two autosave points that got removed for some reason (yes, these are needed for things to work properly)
|
||||
*
|
||||
* Revision 1.6 2006/02/11 02:58:23 Goober5000
|
||||
* yet more various and sundry fixes
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.5 2006/02/11 00:13:55 Goober5000
|
||||
* more FS1 import goodness
|
||||
* --Goober5000
|
||||
@@ -336,6 +365,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "FRED.h"
|
||||
#include <stdlib.h>
|
||||
//#include <atlbase.h>
|
||||
//#include <atlconv.h>
|
||||
|
||||
#include "FREDDoc.h"
|
||||
#include "FREDView.h"
|
||||
@@ -347,6 +378,8 @@
|
||||
#include "ai/ai.h"
|
||||
#include "ai/ailocal.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
#include "cfile/cfilesystem.h"
|
||||
#include "ship/ship.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "mission/missiongoals.h"
|
||||
@@ -363,8 +396,9 @@
|
||||
#include "localization/fhash.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "starfield/starfield.h"
|
||||
#include "localization/localize.h"
|
||||
|
||||
extern int num_objects;
|
||||
extern int Num_objects;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
@@ -412,7 +446,8 @@ int Local_modified = 0;
|
||||
int Undo_available = 0;
|
||||
int Undo_count = 0;
|
||||
|
||||
extern int Fred_found_unknown_ship_during_parsing;
|
||||
extern int Num_unknown_ship_classes;
|
||||
extern int Num_unknown_weapon_classes;
|
||||
|
||||
CFREDDoc::CFREDDoc()
|
||||
{
|
||||
@@ -492,7 +527,7 @@ BOOL CFREDDoc::OnOpenDocument(LPCTSTR pathname)
|
||||
}
|
||||
|
||||
Fred_view_wnd->global_error_check();
|
||||
//autosave("nothing");
|
||||
autosave("nothing");
|
||||
Undo_count = 0;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -566,8 +601,10 @@ int CFREDDoc::check_undo()
|
||||
if (!Undo_count)
|
||||
return 0;
|
||||
|
||||
strcpy(name, MISSION_BACKUP_NAME);
|
||||
strcat(name, ".002");
|
||||
|
||||
cf_create_default_path_string(name, sizeof(name) - 1, CF_TYPE_MISSIONS);
|
||||
SAFE_STRCAT(name, MISSION_BACKUP_NAME, (sizeof(name) - 1));
|
||||
SAFE_STRCAT(name, ".002", (sizeof(name) - 1));
|
||||
fp = fopen(name, "r");
|
||||
if (!fp)
|
||||
return 0;
|
||||
@@ -579,9 +616,6 @@ int CFREDDoc::check_undo()
|
||||
|
||||
int CFREDDoc::autosave(char *desc)
|
||||
{
|
||||
// DISABLE AUTOSAVE!!!
|
||||
//return 0;
|
||||
|
||||
int i;
|
||||
CFred_mission_save save;
|
||||
CWaitCursor wait;
|
||||
@@ -616,8 +650,10 @@ int CFREDDoc::autoload()
|
||||
int i, r, len;
|
||||
FILE *fp;
|
||||
|
||||
strcpy(name, MISSION_BACKUP_NAME);
|
||||
strcat(name, ".002");
|
||||
|
||||
cf_create_default_path_string(name, sizeof(name) - 1, CF_TYPE_MISSIONS);
|
||||
SAFE_STRCAT(name, MISSION_BACKUP_NAME, (sizeof(name) - 1));
|
||||
SAFE_STRCAT(name, ".002", (sizeof(name) - 1));
|
||||
fp = fopen(name, "r");
|
||||
if (!fp)
|
||||
return 0;
|
||||
@@ -667,7 +703,6 @@ int CFREDDoc::load_mission(char *pathname, int flags)
|
||||
|
||||
clear_mission();
|
||||
|
||||
Fred_found_unknown_ship_during_parsing = 0;
|
||||
if (parse_main(pathname, flags))
|
||||
{
|
||||
if (flags & MPF_IMPORT_FSM)
|
||||
@@ -684,7 +719,7 @@ int CFREDDoc::load_mission(char *pathname, int flags)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(Fred_found_unknown_ship_during_parsing)
|
||||
if ((Num_unknown_ship_classes > 0) || (Num_unknown_weapon_classes > 0))
|
||||
{
|
||||
if (flags & MPF_IMPORT_FSM)
|
||||
{
|
||||
@@ -697,7 +732,6 @@ int CFREDDoc::load_mission(char *pathname, int flags)
|
||||
Fred_view_wnd->MessageBox("Fred encountered unknown ship/weapon classes when parsing the mission file. This may be due to mission disk data you do not have.");
|
||||
}
|
||||
}
|
||||
Fred_found_unknown_ship_during_parsing = 0;
|
||||
|
||||
for (i=0; i<Num_waypoint_lists; i++) {
|
||||
wptr = &Waypoint_lists[i];
|
||||
@@ -973,12 +1007,6 @@ void set_modified(BOOL arg)
|
||||
FREDDoc_ptr->SetModifiedFlag(arg);
|
||||
}
|
||||
|
||||
// call this if an unknown ship class was discovered during parsing. Sets up a warning message for players
|
||||
void fred_notify_unknown_ship_during_parse()
|
||||
{
|
||||
Fred_found_unknown_ship_during_parsing = 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Below is old, obsolete code, kept around just in case it might be found
|
||||
@@ -986,7 +1014,7 @@ void fred_notify_unknown_ship_during_parse()
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
/*
|
||||
#define SerializeFloat(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(float)); else fp->Read(&f, sizeof(float))
|
||||
#define SerializeInt(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(int)); else fp->Read(&f, sizeof(int))
|
||||
|
||||
@@ -1093,7 +1121,7 @@ void cfile_serialize(XFILE *fp, int flag)
|
||||
|
||||
if (flag == 0) {
|
||||
num_ships = 0;
|
||||
num_objects = 0;
|
||||
Num_objects = 0;
|
||||
}
|
||||
|
||||
SerializeInt(fp, flag, highest_object_index);
|
||||
@@ -1102,7 +1130,7 @@ void cfile_serialize(XFILE *fp, int flag)
|
||||
SerializeObject(fp, flag, &Objects[i]);
|
||||
if (flag == 0)
|
||||
if (Objects[i].type != OBJ_NONE)
|
||||
num_objects++;
|
||||
Num_objects++;
|
||||
}
|
||||
|
||||
// Read/write ships
|
||||
@@ -1151,7 +1179,7 @@ void cfile_serialize_editor(XFILE *fp, int flag)
|
||||
SerializeGrid(fp, flag, The_grid);
|
||||
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
// Goober5000
|
||||
void CFREDDoc::OnFileImportFSM()
|
||||
@@ -1198,10 +1226,37 @@ void CFREDDoc::OnFileImportFSM()
|
||||
return;
|
||||
|
||||
// get location to save to
|
||||
#if ( _MFC_VER >= 0x0700 )
|
||||
char dest_directory[MAX_PATH];
|
||||
|
||||
//ITEMIDLIST fs2_mission_pidl = {0};
|
||||
|
||||
//SHParseDisplayName(A2CW(fs2_mission_path), NULL, fs2_mission_pidl, 0, 0);
|
||||
|
||||
BROWSEINFO bi;
|
||||
bi.hwndOwner = theApp.GetMainWnd()->GetSafeHwnd();
|
||||
//bi.pidlRoot = &fs2_mission_pidl;
|
||||
bi.pidlRoot = NULL;
|
||||
bi.pszDisplayName = dest_directory;
|
||||
bi.lpszTitle = "Select a location to save in";
|
||||
bi.ulFlags = 0;
|
||||
bi.lpfn = NULL;
|
||||
bi.lParam = NULL;
|
||||
bi.iImage = NULL;
|
||||
|
||||
LPCITEMIDLIST ret_val = SHBrowseForFolder(&bi);
|
||||
|
||||
if(ret_val == NULL)
|
||||
return;
|
||||
|
||||
SHGetPathFromIDList(ret_val, dest_directory);
|
||||
#else
|
||||
CFolderDialog dlgFolder(_T("Select a location to save in"), fs2_mission_path, NULL);
|
||||
if(dlgFolder.DoModal() != IDOK)
|
||||
return;
|
||||
|
||||
const char *dest_directory = dlgFolder.GetFolderPath();
|
||||
#endif
|
||||
// clean things up first
|
||||
if (Briefing_dialog)
|
||||
Briefing_dialog->icon_select(-1);
|
||||
@@ -1257,7 +1312,7 @@ void CFREDDoc::OnFileImportFSM()
|
||||
strcpy(Mission_filename, filename);
|
||||
|
||||
// get new path
|
||||
strcpy(dest_path, dlgFolder.GetFolderPath());
|
||||
strcpy(dest_path, dest_directory);
|
||||
strcat(dest_path, "\\");
|
||||
strcat(dest_path, filename);
|
||||
|
||||
@@ -1278,7 +1333,7 @@ void CFREDDoc::OnFileImportFSM()
|
||||
// success
|
||||
}
|
||||
|
||||
clear_mission();
|
||||
create_new_mission();
|
||||
|
||||
MessageBox(NULL, "Import complete. Please check the destination folder to verify all missions were imported successfully.", "Status", MB_OK);
|
||||
}
|
||||
@@ -1287,12 +1342,14 @@ void restore_default_weapons(char *ships_tbl);
|
||||
|
||||
void CFREDDoc::OnFileImportWeapons()
|
||||
{
|
||||
int rval;
|
||||
CString ships_tbl_mfc;
|
||||
char ships_tbl[MAX_PATH_LEN];
|
||||
char *ships_tbl_text;
|
||||
char *ships_tbl_text_raw;
|
||||
char *ch;
|
||||
char temp[MAX_PATH_LEN];
|
||||
char error_str[1024];
|
||||
|
||||
// set up import dialog
|
||||
CFileDialog dlg(TRUE, "tbl", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "FreeSpace Tables (*.tbl)|*.tbl|All files (*.*)|*.*||");
|
||||
@@ -1319,9 +1376,7 @@ void CFREDDoc::OnFileImportWeapons()
|
||||
}
|
||||
|
||||
if (!strlen(ships_tbl_mfc))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(ships_tbl, ships_tbl_mfc);
|
||||
|
||||
@@ -1337,18 +1392,31 @@ void CFREDDoc::OnFileImportWeapons()
|
||||
return;
|
||||
}
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("FREDDOC: Unable to parse '%s'! Error code = %i.\n", ships_tbl, rval));
|
||||
sprintf(error_str, "Could not parse file: %s", ships_tbl);
|
||||
|
||||
MessageBox(NULL, error_str, "Unable to import weapon loadouts!", MB_ICONERROR | MB_OK);
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
// load the other table and convert, freeing memory after use
|
||||
read_file_text(ships_tbl, CF_TYPE_ANY, ships_tbl_text, ships_tbl_text_raw);
|
||||
free(ships_tbl_text_raw);
|
||||
restore_default_weapons(ships_tbl_text);
|
||||
free(ships_tbl_text);
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
|
||||
// we haven't saved it yet
|
||||
set_modified(TRUE);
|
||||
|
||||
// error check and notify
|
||||
if (!Fred_view_wnd->global_error_check())
|
||||
{
|
||||
Fred_view_wnd->MessageBox("Weapon loadouts successfully imported with no errors.", "Woohoo!");
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/FREDDoc.h $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-01-31 01:53:36 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 2006-12-28 00:59:20 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* FREDDoc.h : interface of the CFREDDoc class
|
||||
* Document class for document/view architechure, which we don't really use in
|
||||
@@ -19,6 +19,10 @@
|
||||
* mainly. Most of the MFC related stuff is handled in FredView.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.2 2006/01/31 01:53:36 Goober5000
|
||||
* update FSM import for FSPort v3.0
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -105,6 +109,7 @@
|
||||
|
||||
#include "ai/ailocal.h"
|
||||
#include "MissionSave.h"
|
||||
#include "object/waypoint/waypoint.h"
|
||||
|
||||
#define MISSION_BACKUP_NAME "Backup"
|
||||
|
||||
|
||||
+52
-20
@@ -9,14 +9,38 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/fred2/FredRender.cpp $
|
||||
* $Revision: 1.5 $
|
||||
* $Date: 2006-05-16 12:45:20 $
|
||||
* $Author: karajorma $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2008-01-05 02:33:41 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Handles rendering the scene in the window for Fred. Also handles several other
|
||||
* miscellaneous tasks.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.11 2007/12/30 18:30:28 karajorma
|
||||
* Catch-up update. This stuff is all in 3.6.9 but somehow missed being added to HEAD.
|
||||
*
|
||||
* Revision 1.10 2007/07/28 04:43:39 Goober5000
|
||||
* a couple of tweaks
|
||||
*
|
||||
* Revision 1.9 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 1.8 2006/12/28 00:59:20 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.7 2006/11/06 05:58:05 taylor
|
||||
* add a "Render full detail" view option to render models at their full detail for the LOD (for render/detail boxes, Mantis bug #1121)
|
||||
*
|
||||
* Revision 1.6 2006/11/06 05:54:13 taylor
|
||||
* add envmap selection to background editor
|
||||
* change skybox selection to be a text entry or browse instead of only text entry
|
||||
* allow envmap selected in background editor to be used by FRED
|
||||
* make texture replacement work in FRED for ships (Mantis bug #1068)
|
||||
*
|
||||
* Revision 1.5 2006/05/16 12:45:20 karajorma
|
||||
* Fix the lack of a background in FRED
|
||||
*
|
||||
* Revision 1.4 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
@@ -375,8 +399,8 @@ int Editing_mode = 1;
|
||||
int Control_mode = 0;
|
||||
int last_x=0, last_y=0;
|
||||
int Show_grid = 1;
|
||||
int Show_outlines = 0;
|
||||
int Show_stars = 0;
|
||||
int Show_outlines = 1;
|
||||
int Show_stars = 1;
|
||||
int Show_grid_positions = 1;
|
||||
int Show_coordinates = 0;
|
||||
int Show_distances = 0;
|
||||
@@ -396,7 +420,7 @@ int Fixed_briefing_size = 1;
|
||||
|
||||
fix lasttime = 0;
|
||||
vec3d my_pos = {0.0f, 0.0f, -5.0f};
|
||||
vec3d view_pos, eye_pos, Viewer_pos, Last_eye_pos = { 0.0f };
|
||||
vec3d view_pos, eye_pos, Last_eye_pos = { 0.0f };
|
||||
vec3d Last_control_pos = { 0.0f };
|
||||
vec3d Grid_center;
|
||||
vec3d Constraint = { 1.0f, 0.0f, 1.0f };
|
||||
@@ -791,7 +815,7 @@ void fredhtl_render_subsystem_bounding_box(subsys_to_render * s2r)
|
||||
{
|
||||
|
||||
vertex text_center;
|
||||
polymodel *pm = model_get(Ships[s2r->ship_obj->instance].modelnum);
|
||||
polymodel *pm = model_get(Ship_info[Ships[s2r->ship_obj->instance].ship_info_index].model_num);
|
||||
int subobj_num = s2r->cur_subsys->system_info->subobj_num;
|
||||
bsp_info *bsp = &pm->submodel[subobj_num];
|
||||
char buf[256];
|
||||
@@ -944,6 +968,10 @@ void render_models(void)
|
||||
|
||||
render_count = 0;
|
||||
|
||||
if ( (ENVMAP == -1) && strlen(The_mission.envmap_name) ) {
|
||||
ENVMAP = bm_load(The_mission.envmap_name);
|
||||
}
|
||||
|
||||
bool f=false;
|
||||
if (Cmdline_nohtl)
|
||||
{
|
||||
@@ -999,7 +1027,7 @@ void render_one_model_nohtl(object *objp)
|
||||
if ((objp->type == OBJ_START) && !Show_starts)
|
||||
return;
|
||||
|
||||
if (objp->type == OBJ_SHIP) {
|
||||
if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
|
||||
if (!Show_ships)
|
||||
return;
|
||||
|
||||
@@ -1047,15 +1075,15 @@ void render_one_model_nohtl(object *objp)
|
||||
|
||||
z = objp->instance;
|
||||
|
||||
model_clear_instance( Ships[z].modelnum );
|
||||
model_clear_instance( Ship_info[Ships[z].ship_info_index].model_num );
|
||||
|
||||
// if (!viewpoint || OBJ_INDEX(objp) != cur_object_index)
|
||||
{
|
||||
if (Fred_outline) {
|
||||
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
model_render(Ships[z].modelnum, &objp->orient, &objp->pos, j | MR_SHOW_OUTLINE);
|
||||
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j | MR_SHOW_OUTLINE, -1, -1, Ships[z].replacement_textures);
|
||||
} else {
|
||||
model_render(Ships[z].modelnum, &objp->orient, &objp->pos, j);
|
||||
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j, -1, -1, Ships[z].replacement_textures);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1128,7 +1156,7 @@ void render_one_model_htl(object *objp)
|
||||
if ((objp->type == OBJ_START) && !Show_starts)
|
||||
return;
|
||||
|
||||
if (objp->type == OBJ_SHIP) {
|
||||
if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
|
||||
if (!Show_ships)
|
||||
return;
|
||||
|
||||
@@ -1177,20 +1205,24 @@ void render_one_model_htl(object *objp)
|
||||
|
||||
z = objp->instance;
|
||||
|
||||
model_clear_instance( Ships[z].modelnum );
|
||||
model_clear_instance( Ship_info[Ships[z].ship_info_index].model_num );
|
||||
|
||||
if(!Lighting_on) {
|
||||
j |= MR_NO_LIGHTING;
|
||||
gr_set_lighting(false,false);
|
||||
}
|
||||
|
||||
if (FullDetail) {
|
||||
j |= MR_FULL_DETAIL;
|
||||
}
|
||||
|
||||
if (Fred_outline) {
|
||||
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
j |= MR_SHOW_OUTLINE;
|
||||
}
|
||||
|
||||
g3_done_instance(0);
|
||||
model_render(Ships[z].modelnum, &objp->orient, &objp->pos, j);
|
||||
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j, -1, -1, Ships[z].replacement_textures);
|
||||
} else {
|
||||
int r = 0, g = 0, b = 0;
|
||||
|
||||
@@ -1322,7 +1354,7 @@ void display_ship_info()
|
||||
if ((objp->type == OBJ_START) && !Show_starts)
|
||||
render = 0;
|
||||
|
||||
if (objp->type == OBJ_SHIP) {
|
||||
if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
|
||||
if (!Show_ships)
|
||||
render = 0;
|
||||
|
||||
@@ -1772,7 +1804,7 @@ void render_frame()
|
||||
light_reset();
|
||||
|
||||
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
|
||||
Viewer_pos = eye_pos; // for starfield code
|
||||
//Viewer_pos = eye_pos; // for starfield code
|
||||
|
||||
fred_enable_htl();
|
||||
if ( Bg_bitmap_dialog ) {
|
||||
@@ -2143,7 +2175,7 @@ int object_check_collision(object *objp, vec3d *p0, vec3d *p1, vec3d *hitpos)
|
||||
if ((objp->type == OBJ_START) && !Show_starts)
|
||||
return 0;
|
||||
|
||||
if (objp->type == OBJ_SHIP) {
|
||||
if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
|
||||
if (!Show_ships)
|
||||
return 0;
|
||||
|
||||
@@ -2155,10 +2187,10 @@ int object_check_collision(object *objp, vec3d *p0, vec3d *p1, vec3d *hitpos)
|
||||
return 0;
|
||||
|
||||
if ((Show_ship_models || Show_outlines) && (objp->type == OBJ_SHIP)) {
|
||||
mc.model_num = Ships[objp->instance].modelnum; // Fill in the model to check
|
||||
mc.model_num = Ship_info[Ships[objp->instance].ship_info_index].model_num; // Fill in the model to check
|
||||
|
||||
} else if ((Show_ship_models || Show_outlines) && (objp->type == OBJ_START)) {
|
||||
mc.model_num = Ships[objp->instance].modelnum; // Fill in the model to check
|
||||
mc.model_num = Ship_info[Ships[objp->instance].ship_info_index].model_num; // Fill in the model to check
|
||||
|
||||
} else
|
||||
return fvi_ray_sphere(hitpos, p0, p1, &objp->pos, (objp->radius > 0.1f) ? objp->radius : LOLLIPOP_SIZE);
|
||||
@@ -2293,7 +2325,7 @@ void render_compass(void)
|
||||
draw_compass_arrow(&v);
|
||||
|
||||
g3_end_frame(); // ** Accounted for
|
||||
|
||||
gr_reset_clip();
|
||||
}
|
||||
|
||||
void draw_compass_arrow(vec3d *v0)
|
||||
|
||||
+27
-18
@@ -9,9 +9,9 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/FredStubs.cpp $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.7 $
|
||||
* $Date: 2007-09-29 14:29:59 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* Bogus C file for functions and variable stubs that Fred needs because it
|
||||
* includes some libraries that makes functions calls to other libraries that FRED
|
||||
@@ -20,6 +20,18 @@
|
||||
* to each other.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.6 2007/02/11 09:37:18 taylor
|
||||
* dd VALID_FNAME() macro and put it around a few places (more to come)
|
||||
* clean out some old variables
|
||||
* move CLAMP() macro from opengl header to global header
|
||||
* update COUNT_ESTIMATE to match new bmpman changes
|
||||
*
|
||||
* Revision 1.5 2006/07/14 03:50:31 taylor
|
||||
* add missing stub for game_get_overall_frametime()
|
||||
*
|
||||
* Revision 1.4 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.3 2006/03/18 21:23:38 taylor
|
||||
* add framerate var since it's contained in freespace.cpp and that's not used in a FRED2 compile
|
||||
*
|
||||
@@ -628,7 +640,7 @@ void send_ship_kill_packet(struct object *,struct object *,float,unsigned char)
|
||||
void send_debris_create_packet( object *objp, ushort net_sig, int model_num, vec3d pos) {}
|
||||
|
||||
int Game_subspace_effect;
|
||||
void big_explosion_flash(float x) {};
|
||||
void big_explosion_flash(float x) {}
|
||||
|
||||
int game_do_cd_check(char *) {return 0;}
|
||||
|
||||
@@ -640,11 +652,9 @@ int game_cd_changed(void) {return 0;}
|
||||
int Interface_framerate;
|
||||
void game_set_view_clip(){}
|
||||
float Viewer_zoom;
|
||||
int Pofview_running = 0;
|
||||
|
||||
int Warpout_forced = 0;
|
||||
float Warpout_time;
|
||||
vec3d Camera_pos;
|
||||
vec3d Dead_player_last_vel;
|
||||
int game_start_mission(){return 0;}
|
||||
int Game_weapons_tbl_valid;
|
||||
@@ -683,11 +693,9 @@ 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() {}
|
||||
int Nebedit_running = 0;
|
||||
void alt_tab_pause(){}
|
||||
|
||||
void game_feature_disabled_popup() {}
|
||||
@@ -698,15 +706,16 @@ void game_unpause() {}
|
||||
//Time stuff
|
||||
bool Time_compression_locked;
|
||||
float flRealframetime;
|
||||
void lock_time_compression(bool is_locked){};
|
||||
void change_time_compression(float multiplier){};
|
||||
void set_time_compression(float multiplier, float change_time){};
|
||||
void lock_time_compression(bool is_locked){}
|
||||
void change_time_compression(float multiplier){}
|
||||
void set_time_compression(float multiplier, float change_time){}
|
||||
fix game_get_overall_frametime() { return 0; }
|
||||
|
||||
//WMC
|
||||
void game_level_init(int seed){};
|
||||
void game_post_level_init(){};
|
||||
void game_render_frame_setup(vec3d *eye_pos, matrix *eye_orient){};
|
||||
void game_render_frame(vec3d *eye_pos, matrix *eye_orient){};
|
||||
void game_simulation_frame(){};
|
||||
void game_update_missiontime(){};
|
||||
void game_render_post_frame(){};
|
||||
void game_level_init(int seed){}
|
||||
void game_post_level_init(){}
|
||||
camid game_render_frame_setup(){return camid();}
|
||||
void game_render_frame(camid cid){}
|
||||
void game_simulation_frame(){}
|
||||
void game_update_missiontime(){}
|
||||
void game_render_post_frame(){}
|
||||
+72
-23
@@ -9,9 +9,9 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/FREDView.cpp $
|
||||
* $Revision: 1.6 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.17 $
|
||||
* $Date: 2007-12-08 20:02:16 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* View class for a document/view architechure design program, which we don't
|
||||
* want or need, but MFC forces us to use. This is the main place we handle
|
||||
@@ -19,6 +19,40 @@
|
||||
* There is also a lot of our code in here related to these things.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.16 2007/07/28 21:31:10 Goober5000
|
||||
* this should really be capitalized
|
||||
*
|
||||
* Revision 1.15 2007/07/28 04:43:40 Goober5000
|
||||
* a couple of tweaks
|
||||
*
|
||||
* Revision 1.14 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 1.13 2007/02/15 02:03:56 phreak
|
||||
* Apparently Visual C++ 2005 follows standard syntax rules.
|
||||
*
|
||||
* Revision 1.12 2006/11/06 05:58:05 taylor
|
||||
* add a "Render full detail" view option to render models at their full detail for the LOD (for render/detail boxes, Mantis bug #1121)
|
||||
*
|
||||
* Revision 1.11 2006/10/09 05:25:18 Goober5000
|
||||
* make sexp nodes dynamic
|
||||
*
|
||||
* Revision 1.10 2006/09/29 06:38:28 Goober5000
|
||||
* merge voice file manager into voice acting manager, plus make a few tweaks to it
|
||||
*
|
||||
* Revision 1.9 2006/09/11 06:08:08 taylor
|
||||
* make Species_info[] and Asteroid_info[] dynamic
|
||||
*
|
||||
* Revision 1.8 2006/09/02 20:07:34 Goober5000
|
||||
* remove unnecessary warning
|
||||
*
|
||||
* Revision 1.7 2006/06/27 02:48:41 Goober5000
|
||||
* slight optimization
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.6 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.5 2006/02/20 02:13:07 Goober5000
|
||||
* added ai-ignore-new which hopefully should fix the ignore bug
|
||||
* --Goober5000
|
||||
@@ -649,6 +683,7 @@ int Show_compass = 1;
|
||||
int Show_dock_points = 0;
|
||||
int Show_paths_fred = 0;
|
||||
int Lighting_on = 0;
|
||||
int FullDetail = 0;
|
||||
int Selection_lock = 0;
|
||||
int viewpoint = 0;
|
||||
int view_obj;
|
||||
@@ -875,10 +910,10 @@ BEGIN_MESSAGE_MAP(CFREDView, CView)
|
||||
ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
|
||||
ON_COMMAND(ID_AA_GRIDLINES, OnAaGridlines)
|
||||
ON_UPDATE_COMMAND_UI(ID_AA_GRIDLINES, OnUpdateAaGridlines)
|
||||
ON_COMMAND(ID_CMD_BRIEF, OnCmdBrief)
|
||||
ON_COMMAND(ID_EDITORS_CMD_BRIEF, OnCmdBrief)
|
||||
ON_COMMAND(ID_DISABLE_UNDO, OnDisableUndo)
|
||||
ON_UPDATE_COMMAND_UI(ID_DISABLE_UNDO, OnUpdateDisableUndo)
|
||||
ON_UPDATE_COMMAND_UI(ID_CMD_BRIEF, OnUpdateCmdBrief)
|
||||
ON_UPDATE_COMMAND_UI(ID_EDITORS_CMD_BRIEF, OnUpdateCmdBrief)
|
||||
ON_COMMAND(ID_NEXT_SUBSYS, OnNextSubsys)
|
||||
ON_COMMAND(ID_PREV_SUBSYS, OnPrevSubsys)
|
||||
ON_COMMAND(ID_CANCEL_SUBSYS, OnCancelSubsys)
|
||||
@@ -894,12 +929,14 @@ BEGIN_MESSAGE_MAP(CFREDView, CView)
|
||||
ON_COMMAND(ID_FORMAT_FS1_RETAIL, OnFormatFs1Retail)
|
||||
ON_UPDATE_COMMAND_UI(ID_FORMAT_FS1_RETAIL, OnUpdateFormatFs1Retail)
|
||||
ON_COMMAND(ID_EDITORS_SET_GLOBAL_SHIP_FLAGS, OnEditorsSetGlobalShipFlags)
|
||||
ON_COMMAND(ID_EDITORS_VOICE_MANAGER, OnEditorsVoiceManager)
|
||||
ON_COMMAND(ID_EDITORS_VOICE, OnEditorsVoiceManager)
|
||||
ON_WM_DESTROY()
|
||||
ON_WM_CREATE()
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_COMMAND(ID_VIEW_LIGHTING, OnViewLighting)
|
||||
ON_UPDATE_COMMAND_UI(ID_VIEW_LIGHTING, OnUpdateViewLighting)
|
||||
ON_COMMAND(ID_VIEW_FULL_DETAIL, OnViewFullDetail)
|
||||
ON_UPDATE_COMMAND_UI(ID_VIEW_FULL_DETAIL, OnUpdateViewFullDetail)
|
||||
//}}AFX_MSG_MAP
|
||||
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
|
||||
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
|
||||
@@ -1849,7 +1886,7 @@ void select_objects()
|
||||
break;
|
||||
|
||||
case OBJ_START:
|
||||
if (!Show_starts)
|
||||
if (!Show_starts || !Show_ships)
|
||||
valid = 0;
|
||||
break;
|
||||
|
||||
@@ -1999,7 +2036,8 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
|
||||
if (menu.LoadMenu(IDR_MENU_EDIT_POPUP)) {
|
||||
int i;
|
||||
CMenu* pPopup = menu.GetSubMenu(0);
|
||||
CMenu shipPopup, player_submenu, species_submenu[MAX_SPECIES];
|
||||
CMenu shipPopup, player_submenu;
|
||||
CMenu *species_submenu = new CMenu[Species_info.size()];
|
||||
ASSERT(pPopup != NULL);
|
||||
|
||||
// create a popup menu based on the ship models read in ship.cpp.
|
||||
@@ -2007,7 +2045,7 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
|
||||
shipPopup.AppendMenu(MF_STRING | MF_ENABLED, SHIP_TYPES + Id_select_type_waypoint, "Waypoint");
|
||||
shipPopup.AppendMenu(MF_STRING | MF_ENABLED, SHIP_TYPES + Id_select_type_start, "Player Start");
|
||||
shipPopup.AppendMenu(MF_STRING | MF_ENABLED, SHIP_TYPES + Id_select_type_jump_node, "Jump Node");
|
||||
for (i=0; i<Num_species; i++) {
|
||||
for (i=0; i<(int)Species_info.size(); i++) {
|
||||
species_submenu[i].CreatePopupMenu();
|
||||
shipPopup.AppendMenu(MF_STRING | MF_POPUP | MF_ENABLED,
|
||||
(UINT) species_submenu[i].m_hMenu, Species_info[i].species_name);
|
||||
@@ -2191,7 +2229,7 @@ void CFREDView::OnMiscStatistics()
|
||||
"Number of Objects: %d\n"
|
||||
"Number of Ships: %d\n"
|
||||
"Number of Wings: %d\n",
|
||||
num_objects, ship_get_num_ships(), Num_wings);
|
||||
Num_objects, ship_get_num_ships(), Num_wings);
|
||||
|
||||
MessageBox(buf, "FRED Statistics");
|
||||
}
|
||||
@@ -3120,8 +3158,8 @@ int CFREDView::global_error_check()
|
||||
return internal_error("Total number of player ships is incorrect");
|
||||
}
|
||||
|
||||
if (obj_count != num_objects){
|
||||
return internal_error("num_objects is incorrect");
|
||||
if (obj_count != Num_objects){
|
||||
return internal_error("Num_objects is incorrect");
|
||||
}
|
||||
|
||||
count = 0;
|
||||
@@ -3197,13 +3235,13 @@ int CFREDView::global_error_check()
|
||||
return internal_error("Docking illegal between \"%s\" and \"%s\" (initially docked)", Ships[i].ship_name, Ships[ship].ship_name);
|
||||
}
|
||||
|
||||
z = get_docking_list(Ships[i].modelnum);
|
||||
point = dock_find_dockpoint_used_by_object(&Objects[Ships[i].objnum], dock_ptr->docked_objp);
|
||||
z = get_docking_list(Ship_info[Ships[i].ship_info_index].model_num);
|
||||
point = dock_ptr->dockpoint_used;
|
||||
if (point < 0 || point >= z){
|
||||
internal_error("Invalid docker point (\"%s\" initially docked with \"%s\")", Ships[i].ship_name, Ships[ship].ship_name);
|
||||
}
|
||||
|
||||
z = get_docking_list(Ships[ship].modelnum);
|
||||
z = get_docking_list(Ship_info[Ships[ship].ship_info_index].model_num);
|
||||
point = dock_find_dockpoint_used_by_object(dock_ptr->docked_objp, &Objects[Ships[i].objnum]);
|
||||
if (point < 0 || point >= z){
|
||||
internal_error("Invalid dockee point (\"%s\" initially docked with \"%s\")", Ships[i].ship_name, Ships[ship].ship_name);
|
||||
@@ -3491,6 +3529,7 @@ int CFREDView::global_error_check()
|
||||
}
|
||||
}
|
||||
|
||||
/* Goober5000 - this is not necessary
|
||||
// make sure that these ignored orders are the same for all starting wings of the player
|
||||
if ( starting_wing ) {
|
||||
if ( starting_orders == -1 ) {
|
||||
@@ -3503,6 +3542,7 @@ int CFREDView::global_error_check()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//This should never ever be a problem -WMC
|
||||
@@ -4055,7 +4095,7 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
if (!ship_docking_valid(ship, inst))
|
||||
return "Docking illegal between given ship types";
|
||||
|
||||
model1 = Ships[ship].modelnum;
|
||||
model1 = Ship_info[Ships[ship].ship_info_index].model_num;
|
||||
num = get_docking_list(model1);
|
||||
for (j=0; j<num; j++) {
|
||||
Assert(Docking_bay_list[j]);
|
||||
@@ -4065,7 +4105,7 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
|
||||
}
|
||||
}
|
||||
|
||||
model2 = Ships[inst].modelnum;
|
||||
model2 = Ship_info[Ships[inst].ship_info_index].model_num;
|
||||
num = get_docking_list(model2);
|
||||
for (j=0; j<num; j++) {
|
||||
Assert(Docking_bay_list[j]);
|
||||
@@ -4140,7 +4180,7 @@ void fred_check_message_personas()
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < MAX_SEXP_NODES; i++ ) {
|
||||
for (i = 0; i < Num_sexp_nodes; i++ ) {
|
||||
if ( Sexp_nodes[i].type == SEXP_NOT_USED )
|
||||
continue;
|
||||
|
||||
@@ -4284,14 +4324,14 @@ void CFREDView::OnRunFreeSpace()
|
||||
si.cbReserved2 = 0;
|
||||
si.lpReserved2 = NULL;
|
||||
|
||||
r = CreateProcess("..\\..\\start_fs2.bat", NULL, NULL, NULL, FALSE, 0, NULL, "./", &si, &pi);
|
||||
r = CreateProcess("start_fs2.bat", NULL, NULL, NULL, FALSE, 0, NULL, "./", &si, &pi);
|
||||
|
||||
if (!r) {
|
||||
r = CreateProcess("..\\..\\fs2_open.exe", NULL, NULL, NULL, FALSE, 0, NULL, "./", &si, &pi);
|
||||
r = CreateProcess("fs2_open.exe", NULL, NULL, NULL, FALSE, 0, NULL, "./", &si, &pi);
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
r = CreateProcess("..\\..\\fs2_open_r.exe", NULL, NULL, NULL, FALSE, 0, NULL, "./", &si, &pi);
|
||||
r = CreateProcess("fs2_open_r.exe", NULL, NULL, NULL, FALSE, 0, NULL, "./", &si, &pi);
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
@@ -4614,7 +4654,7 @@ void CFREDView::OnInitialUpdate()
|
||||
|
||||
// not the default time -- check against the current time
|
||||
memcpy( &expire_time, ptr, sizeof(expire_time) );
|
||||
time( (long *)¤t_time );
|
||||
time( (time_t*)¤t_time );
|
||||
if ( current_time > expire_time )
|
||||
expire_game = EXPIRE_BAD_TIME;
|
||||
}
|
||||
@@ -5135,6 +5175,16 @@ void CFREDView::OnUpdateViewLighting(CCmdUI* pCmdUI)
|
||||
pCmdUI->SetCheck(Lighting_on);
|
||||
}
|
||||
|
||||
void CFREDView::OnViewFullDetail()
|
||||
{
|
||||
FullDetail = !FullDetail;
|
||||
}
|
||||
|
||||
void CFREDView::OnUpdateViewFullDetail(CCmdUI *pCmdUI)
|
||||
{
|
||||
pCmdUI->SetCheck(FullDetail);
|
||||
}
|
||||
|
||||
BOOL CFREDView::DestroyWindow()
|
||||
{
|
||||
// TODO: Add your specialized code here and/or call the base class
|
||||
@@ -5240,4 +5290,3 @@ void CFREDView::OnUpdateShowIFF9(CCmdUI* pCmdUI)
|
||||
{
|
||||
OnUpdateShowIFF(9, pCmdUI);
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/fred2/FREDView.h $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 2006-11-06 05:58:05 $
|
||||
* $Author: taylor $
|
||||
*
|
||||
* View class for a document/view architechure design program, which we don't
|
||||
* want or need, but MFC forces us to use. This is the main place we handle
|
||||
@@ -19,6 +19,9 @@
|
||||
* There is also a lot of our code in here related to these things.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.2 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -554,6 +557,8 @@ protected:
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg void OnViewLighting();
|
||||
afx_msg void OnUpdateViewLighting(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewFullDetail();
|
||||
afx_msg void OnUpdateViewFullDetail(CCmdUI *pCmdUI);
|
||||
//}}AFX_MSG
|
||||
afx_msg void OnGroup(UINT nID);
|
||||
afx_msg void OnSetGroup(UINT nID);
|
||||
@@ -595,6 +600,7 @@ extern int Show_ship_models;
|
||||
extern int Show_ship_info;
|
||||
extern int Show_dock_points;
|
||||
extern int Lighting_on;
|
||||
extern int FullDetail;
|
||||
extern int Show_paths_fred;
|
||||
extern int Selection_lock;
|
||||
extern int Cursor_over;
|
||||
|
||||
+9
-4
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/Grid.cpp $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-12-28 00:59:20 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Grid dialog box created by Mike. Probably will never be used again.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.3 2005/04/13 20:11:06 chhogg
|
||||
* Changed vector to vec3d for Fred.
|
||||
*
|
||||
@@ -134,7 +138,8 @@ void GridOrient(vec3d *forward, vec3d *right)
|
||||
nrows, ncols,
|
||||
square_size);
|
||||
|
||||
physics_init(&The_grid->physics);
|
||||
//WMC - Tentative change, not needed?
|
||||
//physics_init(&The_grid->physics);
|
||||
}
|
||||
|
||||
void CGrid::OnGridXyPlane()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Management.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "object/objectshield.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
@@ -28,7 +29,7 @@ static char THIS_FILE[] = __FILE__;
|
||||
// non-class function prototypes, bah
|
||||
void initial_status_mark_dock_leader_helper(object *objp, dock_function_info *infop);
|
||||
void initial_status_unmark_dock_handled_flag(object *objp, dock_function_info *infop);
|
||||
void reset_arrival_to_false(int shipnum);
|
||||
void reset_arrival_to_false(int shipnum, bool reset_wing);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -144,7 +145,7 @@ BOOL initial_status::OnInitDialog()
|
||||
// initialize dockpoint stuff
|
||||
if (!m_multi_edit)
|
||||
{
|
||||
num_dock_points = model_get_num_dock_points(Ships[m_ship].modelnum);
|
||||
num_dock_points = model_get_num_dock_points(Ship_info[Ships[m_ship].ship_info_index].model_num);
|
||||
dockpoint_array = new dockpoint_information[num_dock_points];
|
||||
objp = &Objects[Ships[m_ship].objnum];
|
||||
for (int i = 0; i < num_dock_points; i++)
|
||||
@@ -165,7 +166,7 @@ BOOL initial_status::OnInitDialog()
|
||||
|
||||
vflag = sflag = hflag = 0;
|
||||
m_velocity = (int) Objects[cur_object_index].phys_info.speed;
|
||||
m_shields = (int) Objects[cur_object_index].shield_quadrant[0];
|
||||
m_shields = (int) shield_get_strength(&Objects[cur_object_index]);
|
||||
m_hull = (int) Objects[cur_object_index].hull_strength;
|
||||
if (Objects[cur_object_index].flags & OF_NO_SHIELDS)
|
||||
m_has_shields = 0;
|
||||
@@ -203,7 +204,7 @@ BOOL initial_status::OnInitDialog()
|
||||
if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
|
||||
if (objp->phys_info.speed != m_velocity)
|
||||
vflag = 1;
|
||||
if ((int) objp->shield_quadrant[0] != m_shields)
|
||||
if ((int) shield_get_strength(objp) != m_shields)
|
||||
sflag = 1;
|
||||
if ((int) objp->hull_strength != m_hull)
|
||||
hflag = 1;
|
||||
@@ -261,7 +262,7 @@ BOOL initial_status::OnInitDialog()
|
||||
{
|
||||
for (int dockpoint = 0; dockpoint < num_dock_points; dockpoint++)
|
||||
{
|
||||
z = lstDockerPoints->AddString(model_get_dock_name(Ships[m_ship].modelnum, dockpoint));
|
||||
z = lstDockerPoints->AddString(model_get_dock_name(Ship_info[Ships[m_ship].ship_info_index].model_num, dockpoint));
|
||||
lstDockerPoints->SetItemData(z, dockpoint);
|
||||
}
|
||||
|
||||
@@ -315,7 +316,7 @@ void initial_status::OnOK()
|
||||
MODIFY(objp->phys_info.speed, (float) m_velocity);
|
||||
|
||||
if (sflag)
|
||||
MODIFY(objp->shield_quadrant[0], (float) m_shields);
|
||||
MODIFY_SHIELDS(objp, m_shields);
|
||||
|
||||
if (hflag)
|
||||
MODIFY(objp->hull_strength, (float) m_hull);
|
||||
@@ -355,7 +356,7 @@ void initial_status::OnOK()
|
||||
|
||||
} else {
|
||||
MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
|
||||
MODIFY(Objects[cur_object_index].shield_quadrant[0], (float) m_shields);
|
||||
MODIFY_SHIELDS(&Objects[cur_object_index], m_shields);
|
||||
MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);
|
||||
if (m_has_shields)
|
||||
Objects[cur_object_index].flags &= ~OF_NO_SHIELDS;
|
||||
@@ -509,7 +510,7 @@ void initial_status::change_docker_point(bool store_selection)
|
||||
else
|
||||
{
|
||||
// populate with all possible dockees
|
||||
list_dockees(model_get_dock_index_type(Ships[m_ship].modelnum, cur_docker_point));
|
||||
list_dockees(model_get_dock_index_type(Ship_info[Ships[m_ship].ship_info_index].model_num, cur_docker_point));
|
||||
|
||||
// see if there's a dockee here
|
||||
if (dockpoint_array[cur_docker_point].dockee_shipnum >= 0)
|
||||
@@ -571,7 +572,7 @@ void initial_status::change_dockee(bool store_selection)
|
||||
if (dockpoint_array[cur_docker_point].dockee_point >= 0)
|
||||
{
|
||||
// select the dockpoint
|
||||
cboDockeePoints->SelectString(-1, model_get_dock_name(Ships[cur_dockee].modelnum, dockpoint_array[cur_docker_point].dockee_point));
|
||||
cboDockeePoints->SelectString(-1, model_get_dock_name(Ship_info[Ships[cur_dockee].ship_info_index].model_num, dockpoint_array[cur_docker_point].dockee_point));
|
||||
change_dockee_point(false);
|
||||
}
|
||||
// there might not be any dockpoints available
|
||||
@@ -676,7 +677,7 @@ void initial_status::list_dockees(int dock_types)
|
||||
continue;
|
||||
|
||||
// dock types must match
|
||||
if (!(model_get_dock_types(Ships[ship].modelnum) & dock_types))
|
||||
if (!(model_get_dock_types(Ship_info[Ships[ship].ship_info_index].model_num) & dock_types))
|
||||
continue;
|
||||
|
||||
// add to list
|
||||
@@ -703,10 +704,10 @@ void initial_status::list_dockee_points(int shipnum)
|
||||
return;
|
||||
|
||||
// get the required dock type(s)
|
||||
int dock_type = model_get_dock_index_type(shipp->modelnum, cur_docker_point);
|
||||
int dock_type = model_get_dock_index_type(Ship_info[shipp->ship_info_index].model_num, cur_docker_point);
|
||||
|
||||
// populate with the right kind of dockee points
|
||||
for (int i = 0; i < model_get_num_dock_points(other_shipp->modelnum); i++)
|
||||
for (int i = 0; i < model_get_num_dock_points(Ship_info[other_shipp->ship_info_index].model_num); i++)
|
||||
{
|
||||
// make sure this dockpoint is not occupied by someone else
|
||||
object *docked_objp = dock_find_object_at_dockpoint(&Objects[other_shipp->objnum], i);
|
||||
@@ -714,11 +715,11 @@ void initial_status::list_dockee_points(int shipnum)
|
||||
continue;
|
||||
|
||||
// make sure its type matches
|
||||
if (!(model_get_dock_index_type(other_shipp->modelnum, i) & dock_type))
|
||||
if (!(model_get_dock_index_type(Ship_info[other_shipp->ship_info_index].model_num, i) & dock_type))
|
||||
continue;
|
||||
|
||||
// add to list
|
||||
z = cboDockeePoints->AddString(model_get_dock_name(other_shipp->modelnum, i));
|
||||
z = cboDockeePoints->AddString(model_get_dock_name(Ship_info[other_shipp->ship_info_index].model_num, i));
|
||||
cboDockeePoints->SetItemData(z, i);
|
||||
}
|
||||
}
|
||||
@@ -813,11 +814,12 @@ void initial_status::undock(object *objp1, object *objp2)
|
||||
// check to see if one of these ships has an arrival cue of false. If so, then
|
||||
// reset it back to default value of true. be sure to correctly update before
|
||||
// and after setting data.
|
||||
// Goober5000 - but don't reset it if it's part of a wing!
|
||||
Ship_editor_dialog.update_data(1);
|
||||
|
||||
if ( Ships[ship_num].arrival_cue == Locked_sexp_false ) {
|
||||
if ( Ships[ship_num].arrival_cue == Locked_sexp_false && Ships[ship_num].wingnum < 0 ) {
|
||||
Ships[ship_num].arrival_cue = Locked_sexp_true;
|
||||
} else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false ) {
|
||||
} else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false && Ships[other_ship_num].wingnum < 0 ) {
|
||||
Ships[other_ship_num].arrival_cue = Locked_sexp_true;
|
||||
}
|
||||
|
||||
@@ -858,13 +860,13 @@ void initial_status_mark_dock_leader_helper(object *objp, dock_function_info *in
|
||||
if (ship_class_compare(shipp->ship_info_index, leader_shipp->ship_info_index) < 0)
|
||||
{
|
||||
// set my arrival cue to false
|
||||
reset_arrival_to_false(SHIP_INDEX(shipp));
|
||||
reset_arrival_to_false(SHIP_INDEX(shipp), true);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, unmark the existing leader and set his arrival cue to false
|
||||
leader_shipp->flags &= ~SF_DOCK_LEADER;
|
||||
reset_arrival_to_false(SHIP_INDEX(leader_shipp));
|
||||
reset_arrival_to_false(SHIP_INDEX(leader_shipp), true);
|
||||
}
|
||||
|
||||
// mark and save me as the leader
|
||||
@@ -879,21 +881,53 @@ void initial_status_unmark_dock_handled_flag(object *objp, dock_function_info *i
|
||||
objp->flags &= ~OF_DOCKED_ALREADY_HANDLED;
|
||||
}
|
||||
|
||||
bool set_cue_to_false(int *cue)
|
||||
{
|
||||
// if the cue is not false, make it false. Be sure to set all ship editor dialog functions
|
||||
// to update data before and after we modify the cue.
|
||||
if (*cue != Locked_sexp_false)
|
||||
{
|
||||
Ship_editor_dialog.update_data(1);
|
||||
|
||||
free_sexp2(*cue);
|
||||
*cue = Locked_sexp_false;
|
||||
|
||||
Ship_editor_dialog.initialize_data(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// function to set the arrival cue of a ship to false
|
||||
void reset_arrival_to_false( int shipnum )
|
||||
void reset_arrival_to_false(int shipnum, bool reset_wing)
|
||||
{
|
||||
char buf[256];
|
||||
ship *shipp = &Ships[shipnum];
|
||||
|
||||
// if the cue is not false, make it false. Be sure to all ship editor dialog functions
|
||||
// to update date before and after we modify the cue.
|
||||
if ( Ships[shipnum].arrival_cue != Locked_sexp_false ) {
|
||||
Ship_editor_dialog.update_data(1);
|
||||
free_sexp2(Ships[shipnum].arrival_cue);
|
||||
Ships[shipnum].arrival_cue = Locked_sexp_false;
|
||||
Ship_editor_dialog.initialize_data(1);
|
||||
sprintf(buf, "Setting arrival cue of ship %s\nto false for initial docking purposes.", Ships[shipnum].ship_name);
|
||||
// falsify the ship cue
|
||||
if (set_cue_to_false(&shipp->arrival_cue))
|
||||
{
|
||||
sprintf(buf, "Setting arrival cue of ship %s\nto false for initial docking purposes.", shipp->ship_name);
|
||||
MessageBox(NULL, buf, "", MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
|
||||
// falsify the wing cue and all ships in that wing
|
||||
if (reset_wing && shipp->wingnum >= 0)
|
||||
{
|
||||
int i;
|
||||
wing *wingp = &Wings[shipp->wingnum];
|
||||
|
||||
if (set_cue_to_false(&wingp->arrival_cue))
|
||||
{
|
||||
sprintf(buf, "Setting arrival cue of wing %s\nto false for initial docking purposes.", wingp->name);
|
||||
MessageBox(NULL, buf, "", MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
|
||||
for (i = 0; i < wingp->wave_count; i++)
|
||||
reset_arrival_to_false(wingp->ship_index[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
void initial_status::OnPrimariesLocked()
|
||||
|
||||
+284
-175
@@ -9,9 +9,9 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/Management.cpp $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2006-05-30 02:13:22 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.44 $
|
||||
* $Date: 2007-12-19 10:54:26 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* This file handles the management of Objects, Ships, Wings, etc. Basically
|
||||
* all the little structures we have that usually inter-relate that need to
|
||||
@@ -19,6 +19,115 @@
|
||||
* function.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.43 2007/12/15 09:41:43 wmcoolmon
|
||||
* Maybe-catch an interesting crash upon attempting to revert a mission with no cargo.
|
||||
*
|
||||
* Revision 1.42 2007/12/15 09:12:56 wmcoolmon
|
||||
* Handle missing ship model files more gracefully
|
||||
*
|
||||
* Revision 1.41 2007/11/22 04:30:55 taylor
|
||||
* be sure that we hide the game's mouse cursor (Mantis #1401)
|
||||
*
|
||||
* Revision 1.40 2007/11/21 07:28:37 Goober5000
|
||||
* add Wing Commander Saga's fiction viewer
|
||||
*
|
||||
* Revision 1.39 2007/09/03 01:02:49 Goober5000
|
||||
* fix for 1376
|
||||
*
|
||||
* Revision 1.38 2007/09/02 02:10:25 Goober5000
|
||||
* added fixes for #1415 and #1483, made sure every read_file_text had a corresponding setjmp, and sync'd the parse error messages between HEAD and stable
|
||||
*
|
||||
* Revision 1.37 2007/07/28 21:31:11 Goober5000
|
||||
* this should really be capitalized
|
||||
*
|
||||
* Revision 1.36 2007/07/28 04:43:40 Goober5000
|
||||
* a couple of tweaks
|
||||
*
|
||||
* Revision 1.35 2007/04/17 17:26:35 karajorma
|
||||
* Remove the -fredhtl command line.
|
||||
*
|
||||
* Revision 1.34 2007/03/22 22:19:30 taylor
|
||||
* add back special "var" setting for flag_def_list and convert some of the lists to use it (more on the way)
|
||||
*
|
||||
* Revision 1.33 2007/02/20 04:20:10 Goober5000
|
||||
* the great big duplicate model removal commit
|
||||
*
|
||||
* Revision 1.32 2007/02/18 06:16:46 Goober5000
|
||||
* revert Bobboau's commits for the past two months; these will be added in later in a less messy/buggy manner
|
||||
*
|
||||
* Revision 1.31 2007/02/11 21:26:34 Goober5000
|
||||
* massive shield infrastructure commit
|
||||
*
|
||||
* Revision 1.30 2007/02/08 07:39:32 Goober5000
|
||||
* fix two bugs:
|
||||
* --default ship flags in the iff_defs table were not correctly translated from parse flags to ship/object flags
|
||||
* --ships were created with default allowed comm orders regardless of which team they were on
|
||||
*
|
||||
* Revision 1.29 2007/01/14 14:03:32 bobboau
|
||||
* ok, something aparently went wrong, last time, so I'm commiting again
|
||||
* hopefully it should work this time
|
||||
* damnit WORK!!!
|
||||
*
|
||||
* Revision 1.28 2007/01/10 01:41:27 taylor
|
||||
* remove -jpgtga, set 32-bit mode as default (the OGL code will automatically fallback to 16-bit is needed)
|
||||
*
|
||||
* Revision 1.27 2007/01/07 00:01:28 Goober5000
|
||||
* add a feature for specifying the source of Command messages
|
||||
*
|
||||
* Revision 1.26 2006/12/28 00:59:20 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.25 2006/12/08 19:18:52 Goober5000
|
||||
* fix Mantis #1163
|
||||
*
|
||||
* Revision 1.24 2006/11/16 00:53:31 taylor
|
||||
* various bits of little cleanup
|
||||
* add the debug cmdline printer to FRED, so that we can make use of that info in the FRED-debug case too
|
||||
*
|
||||
* Revision 1.23 2006/11/06 05:58:57 taylor
|
||||
* fix compiler problem due to change in parse_init() function
|
||||
* fix dos EOL chars
|
||||
*
|
||||
* Revision 1.22 2006/11/06 05:54:13 taylor
|
||||
* add envmap selection to background editor
|
||||
* change skybox selection to be a text entry or browse instead of only text entry
|
||||
* allow envmap selected in background editor to be used by FRED
|
||||
* make texture replacement work in FRED for ships (Mantis bug #1068)
|
||||
*
|
||||
* Revision 1.21 2006/10/06 13:41:35 Goober5000
|
||||
* <nelson> Ha, ha! </nelson>
|
||||
*
|
||||
* Revision 1.20 2006/10/06 09:54:57 taylor
|
||||
* make sure that the armor stuff gets initted (should fix Mantis bug #1080)
|
||||
*
|
||||
* Revision 1.19 2006/10/01 03:22:58 Goober5000
|
||||
* find message sender too
|
||||
*
|
||||
* Revision 1.18 2006/10/01 01:12:32 Goober5000
|
||||
* enhanced voice acting manager, now with script generator :)
|
||||
*
|
||||
* Revision 1.17 2006/09/11 06:08:08 taylor
|
||||
* make Species_info[] and Asteroid_info[] dynamic
|
||||
*
|
||||
* Revision 1.16 2006/08/06 18:47:29 Goober5000
|
||||
* add the multiple background feature
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.15 2006/07/10 21:48:33 taylor
|
||||
* fix undo system
|
||||
* restore the two autosave points that got removed for some reason (yes, these are needed for things to work properly)
|
||||
*
|
||||
* Revision 1.14 2006/07/08 19:35:52 Goober5000
|
||||
* iff defs should allow specification of both flag fields
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.13 2006/06/02 09:39:11 karajorma
|
||||
* Added Team Loadout from variables and alt ship classes changes
|
||||
*
|
||||
* Revision 1.12 2006/05/30 02:13:22 Goober5000
|
||||
* add substitute music boxes to FRED, and reset music properly when mission is cleared
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.11 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
@@ -499,8 +608,13 @@
|
||||
#include "graphics/font.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "object/objectshield.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "iff_defs/iff_defs.h"
|
||||
#include "parse/scripting.h"
|
||||
#include "object/waypoint/waypoint.h"
|
||||
#include "menuui/techmenu.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
|
||||
#include <direct.h>
|
||||
#include "cmdline/cmdline.h"
|
||||
@@ -539,24 +653,24 @@ bool Show_iff[MAX_IFFS];
|
||||
CCriticalSection CS_cur_object_index;
|
||||
|
||||
ai_goal_list Ai_goal_list[] = {
|
||||
"Waypoints", AI_GOAL_WAYPOINTS,
|
||||
"Waypoints once", AI_GOAL_WAYPOINTS_ONCE,
|
||||
"Warp", AI_GOAL_WARP,
|
||||
"Destroy subsystem", AI_GOAL_DESTROY_SUBSYSTEM,
|
||||
"Attack", AI_GOAL_CHASE | AI_GOAL_CHASE_WING,
|
||||
"Dock", AI_GOAL_DOCK,
|
||||
"Undock", AI_GOAL_UNDOCK,
|
||||
"Guard", AI_GOAL_GUARD | AI_GOAL_GUARD_WING,
|
||||
"Attack any ship", AI_GOAL_CHASE_ANY,
|
||||
"Disable ship", AI_GOAL_DISABLE_SHIP,
|
||||
"Disarm ship", AI_GOAL_DISARM_SHIP,
|
||||
"Evade ship", AI_GOAL_EVADE_SHIP,
|
||||
"Ignore ship", AI_GOAL_IGNORE,
|
||||
"Ignore ship (new)", AI_GOAL_IGNORE_NEW,
|
||||
"Stay near ship", AI_GOAL_STAY_NEAR_SHIP,
|
||||
"Keep safe distance", AI_GOAL_KEEP_SAFE_DISTANCE,
|
||||
"Stay still", AI_GOAL_STAY_STILL,
|
||||
"Play dead", AI_GOAL_PLAY_DEAD,
|
||||
{ "Waypoints", AI_GOAL_WAYPOINTS, 0 },
|
||||
{ "Waypoints once", AI_GOAL_WAYPOINTS_ONCE, 0 },
|
||||
{ "Warp", AI_GOAL_WARP, 0 },
|
||||
{ "Destroy subsystem", AI_GOAL_DESTROY_SUBSYSTEM, 0 },
|
||||
{ "Attack", AI_GOAL_CHASE | AI_GOAL_CHASE_WING, 0 },
|
||||
{ "Dock", AI_GOAL_DOCK, 0 },
|
||||
{ "Undock", AI_GOAL_UNDOCK, 0 },
|
||||
{ "Guard", AI_GOAL_GUARD | AI_GOAL_GUARD_WING, 0 },
|
||||
{ "Attack any ship", AI_GOAL_CHASE_ANY, 0 },
|
||||
{ "Disable ship", AI_GOAL_DISABLE_SHIP, 0 },
|
||||
{ "Disarm ship", AI_GOAL_DISARM_SHIP, 0 },
|
||||
{ "Evade ship", AI_GOAL_EVADE_SHIP, 0 },
|
||||
{ "Ignore ship", AI_GOAL_IGNORE, 0 },
|
||||
{ "Ignore ship (new)", AI_GOAL_IGNORE_NEW, 0 },
|
||||
{ "Stay near ship", AI_GOAL_STAY_NEAR_SHIP, 0 },
|
||||
{ "Keep safe distance", AI_GOAL_KEEP_SAFE_DISTANCE, 0 },
|
||||
{ "Stay still", AI_GOAL_STAY_STILL, 0 },
|
||||
{ "Play dead", AI_GOAL_PLAY_DEAD, 0 }
|
||||
};
|
||||
|
||||
int Ai_goal_list_size = sizeof(Ai_goal_list) / sizeof(ai_goal_list);
|
||||
@@ -564,7 +678,6 @@ int Ai_goal_list_size = sizeof(Ai_goal_list) / sizeof(ai_goal_list);
|
||||
// internal function prototypes
|
||||
void set_cur_indices(int obj);
|
||||
int common_object_delete(int obj);
|
||||
int create_waypoint(vec3d *pos, int list);
|
||||
int create_ship(matrix *orient, vec3d *pos, int ship_type);
|
||||
int query_ship_name_duplicate(int ship);
|
||||
char *reg_read_string( char *section, char *name, char *default_value );
|
||||
@@ -665,15 +778,16 @@ void parse_medal_tbl()
|
||||
{
|
||||
int rval, num_medals;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
Error(LOCATION, "Error parsing '%s'\r\nError code = %i.\r\n", "medals.tbl", rval);
|
||||
}
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
read_file_text("medals.tbl");
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "medals.tbl", rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("medals.tbl");
|
||||
reset_parse();
|
||||
|
||||
// parse in all the rank names
|
||||
@@ -717,19 +831,25 @@ void parse_medal_tbl()
|
||||
}
|
||||
*/
|
||||
|
||||
void parse_init();
|
||||
void parse_init(bool basic = false);
|
||||
void brief_init_colors();
|
||||
|
||||
void fred_preload_all_briefing_icons()
|
||||
{
|
||||
int i,j;
|
||||
for (i = 0; i < Num_species; i++)
|
||||
uint i;
|
||||
int j;
|
||||
for (i = 0; i < Species_info.size(); i++)
|
||||
{
|
||||
for (j = 0; j < MAX_BRIEF_ICONS; j++)
|
||||
{
|
||||
generic_anim_load(&Species_info[i].icon_bitmaps[j]);
|
||||
hud_anim_load(&Species_info[i].icon_fade_anims[j]);
|
||||
hud_anim_load(&Species_info[i].icon_highlight_anims[j]);
|
||||
if(strlen(Species_info[i].icon_bitmaps[j].filename))
|
||||
generic_anim_load(&Species_info[i].icon_bitmaps[j]);
|
||||
|
||||
if(strlen(Species_info[i].icon_fade_anims[j].filename))
|
||||
hud_anim_load(&Species_info[i].icon_fade_anims[j]);
|
||||
|
||||
if(strlen(Species_info[i].icon_highlight_anims[j].filename))
|
||||
hud_anim_load(&Species_info[i].icon_highlight_anims[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,6 +878,11 @@ bool fred_init()
|
||||
// this should enable mods - Kazan
|
||||
fred2_parse_cmdline(__argc, __argv);
|
||||
|
||||
#ifndef NDEBUG
|
||||
extern void cmdline_debug_print_cmdline();
|
||||
cmdline_debug_print_cmdline();
|
||||
#endif
|
||||
|
||||
// d'oh
|
||||
DBUGFILE_OUTPUT_0("About to cfile_init");
|
||||
if(cfile_init(Fred_exe_dir)){
|
||||
@@ -774,9 +899,9 @@ bool fred_init()
|
||||
extern int Xstr_inited;
|
||||
Xstr_inited = 1;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifndef NDEBUG
|
||||
load_filter_info();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//CFREDView *window = CFREDView::GetView();
|
||||
//HWND hwndApp = window->GetSafeHwnd();
|
||||
@@ -793,14 +918,14 @@ bool fred_init()
|
||||
Cmdline_nohtl = result != IDYES;
|
||||
*/
|
||||
|
||||
Cmdline_nohtl = Cmdline_FRED2_htl == 0;
|
||||
|
||||
/* - HTL is now on by default so the warning is redundant - Karajorma
|
||||
if (Cmdline_nohtl)
|
||||
{
|
||||
MessageBox(NULL, "You are not running in HTL mode for FRED. Although HTL mode isn't required, there may be some crashes"
|
||||
" when trying to render the new high polygon models. To enable HTL mode, create a shortcut to FRED, right-click into properties"
|
||||
" and add \"-fredhtl\" to the end of the string in the \"target\" box.", "FRED2", MB_ICONWARNING | MB_OK);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Not ready for this yet
|
||||
@@ -808,20 +933,22 @@ bool fred_init()
|
||||
// Cmdline_noglow = 1;
|
||||
Cmdline_window = 1;
|
||||
DBUGFILE_OUTPUT_0("About to gr_init");
|
||||
if (Cmdline_jpgtga) {
|
||||
gr_init(GR_640, GR_OPENGL, 32, 640, 480);
|
||||
} else {
|
||||
gr_init(GR_640, GR_OPENGL, 16, 640, 480);
|
||||
}
|
||||
|
||||
|
||||
gr_init(GR_640, GR_OPENGL, 32, 640, 480);
|
||||
|
||||
Mouse_hidden = 1;
|
||||
|
||||
DBUGFILE_OUTPUT_0("About to init everything");
|
||||
//WMC - init scripting
|
||||
script_init();
|
||||
gr_font_init(); // loads up all fonts
|
||||
// Fred_font = gr_init_font("font01.vf");
|
||||
gr_set_gamma(3.0f);
|
||||
|
||||
sprintf(palette_filename, "gamepalette%d-%02d", 1, 1);
|
||||
mprintf(("Loading palette %s\n", palette_filename));
|
||||
palette_load_table(palette_filename);
|
||||
//WMC - I dunnit. It doesn't look like this was even used.
|
||||
//palette_load_table(palette_filename);
|
||||
|
||||
key_init();
|
||||
mouse_init();
|
||||
@@ -833,6 +960,17 @@ bool fred_init()
|
||||
for (i = 0; i < MAX_IFFS; i++)
|
||||
Show_iff[i] = true;
|
||||
|
||||
// Goober5000
|
||||
strcpy(Voice_abbrev_briefing, "");
|
||||
strcpy(Voice_abbrev_campaign, "");
|
||||
strcpy(Voice_abbrev_command_briefing, "");
|
||||
strcpy(Voice_abbrev_debriefing, "");
|
||||
strcpy(Voice_abbrev_message, "");
|
||||
strcpy(Voice_abbrev_mission, "");
|
||||
Voice_no_replace_filenames = false;
|
||||
strcpy(Voice_script_entry_format, "Sender: $sender\r\nPersona: $persona\r\nFile: $filename\r\nMessage: $message");
|
||||
Voice_export_selection = 0;
|
||||
|
||||
hud_init_comm_orders(); // Goober5000
|
||||
|
||||
gamesnd_parse_soundstbl(); // needs to be loaded after species stuff but before interface/weapon/ship stuff - taylor
|
||||
@@ -841,10 +979,12 @@ bool fred_init()
|
||||
model_free_all(); // Free all existing models
|
||||
ai_init();
|
||||
ai_profiles_init();
|
||||
armor_init();
|
||||
weapon_init();
|
||||
parse_medal_tbl(); // get medal names for sexpression usage
|
||||
ship_init();
|
||||
parse_init();
|
||||
techroom_intel_init();
|
||||
|
||||
// initialize and activate external string hash table
|
||||
// make sure to do here so that we don't parse the table files into the hash table - waste of space
|
||||
@@ -858,6 +998,7 @@ bool fred_init()
|
||||
brief_parse_icon_tbl();
|
||||
fred_preload_all_briefing_icons(); //phreak. This needs to be done or else the briefing icons won't show up
|
||||
event_music_init();
|
||||
fiction_viewer_reset();
|
||||
cmd_brief_reset();
|
||||
Show_waypoints = TRUE;
|
||||
Campaign.filename[0] = 0; // indicate initialized state
|
||||
@@ -916,7 +1057,7 @@ int create_object_on_grid(int list)
|
||||
mark_object(obj);
|
||||
FREDDoc_ptr->autosave("object create");
|
||||
|
||||
} else if (obj == -1)
|
||||
} else if (obj == -1 && ship_get_num_ships() >= MAX_SHIPS)
|
||||
Fred_main_wnd->MessageBox("Maximum ship limit reached. Can't add any more ships.");
|
||||
}
|
||||
|
||||
@@ -939,7 +1080,7 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
|
||||
getcwd(pwd, 128); // get the present working dir - probably <fs2path>[/modpapth]/data/missions/
|
||||
|
||||
|
||||
int obj, ship, z1, z2;
|
||||
int obj, z1, z2;
|
||||
float temp_max_hull_strength;
|
||||
ship_info *sip;
|
||||
|
||||
@@ -956,51 +1097,65 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
|
||||
|
||||
Objects[obj].phys_info.speed = 33.0f;
|
||||
|
||||
ship = Objects[obj].instance;
|
||||
sip = &Ship_info[Ships[ship].ship_info_index];
|
||||
ship *shipp = &Ships[Objects[obj].instance];
|
||||
sip = &Ship_info[shipp->ship_info_index];
|
||||
|
||||
if (query_ship_name_duplicate(ship))
|
||||
fix_ship_name(ship);
|
||||
if (query_ship_name_duplicate(Objects[obj].instance))
|
||||
fix_ship_name(Objects[obj].instance);
|
||||
|
||||
// default stuff according to species and IFF
|
||||
Ships[ship].team = Species_info[Ship_info[Ships[ship].ship_info_index].species].default_iff;
|
||||
Ships[ship].flags = Iff_info[Ships[ship].team].default_ship_flags;
|
||||
shipp->team = Species_info[Ship_info[shipp->ship_info_index].species].default_iff;
|
||||
resolve_parse_flags(&Objects[obj], Iff_info[shipp->team].default_parse_flags, Iff_info[shipp->team].default_parse_flags2);
|
||||
|
||||
// default shield setting
|
||||
z1 = Shield_sys_teams[Ships[ship].team];
|
||||
z1 = Shield_sys_teams[shipp->team];
|
||||
z2 = Shield_sys_types[ship_type];
|
||||
if (((z1 == 1) && z2) || (z2 == 1))
|
||||
Objects[obj].flags |= OF_NO_SHIELDS;
|
||||
|
||||
// orders
|
||||
// Goober5000 - just do this by default; you can't issue orders
|
||||
// to ships not on your team anyway
|
||||
//if ( Ships[ship].team == TEAM_FRIENDLY )
|
||||
// set orders according to whether the ship is on the player ship's team
|
||||
{
|
||||
// if this ship is not a small ship, then make the orders be the default orders without
|
||||
// the depart item
|
||||
if (!(sip->flags & SIF_SMALL_SHIP))
|
||||
object *temp_objp;
|
||||
ship *temp_shipp = NULL;
|
||||
|
||||
// find the first player ship
|
||||
for (temp_objp = GET_FIRST(&obj_used_list); temp_objp != END_OF_LIST(&obj_used_list); temp_objp = GET_NEXT(temp_objp))
|
||||
{
|
||||
Ships[ship].orders_accepted = ship_get_default_orders_accepted( sip );
|
||||
Ships[ship].orders_accepted &= ~DEPART_ITEM;
|
||||
if (temp_objp->type == OBJ_START)
|
||||
{
|
||||
temp_shipp = &Ships[temp_objp->instance];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set orders if teams match, or if player couldn't be found
|
||||
if (temp_shipp == NULL || shipp->team == temp_shipp->team)
|
||||
{
|
||||
// if this ship is not a small ship, then make the orders be the default orders without
|
||||
// the depart item
|
||||
if (!(sip->flags & SIF_SMALL_SHIP))
|
||||
{
|
||||
shipp->orders_accepted = ship_get_default_orders_accepted( sip );
|
||||
shipp->orders_accepted &= ~DEPART_ITEM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shipp->orders_accepted = 0;
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// Ships[ship].orders_accepted = 0;
|
||||
//}
|
||||
|
||||
// calc kamikaze stuff
|
||||
if (Ships[ship].special_hitpoint_index != -1)
|
||||
if (shipp->special_hitpoint_index != -1)
|
||||
{
|
||||
temp_max_hull_strength = (float) atoi(Sexp_variables[Ships[ship].special_hitpoint_index+HULL_STRENGTH].text);
|
||||
temp_max_hull_strength = (float) atoi(Sexp_variables[shipp->special_hitpoint_index+HULL_STRENGTH].text);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_max_hull_strength = sip->max_hull_strength;
|
||||
}
|
||||
|
||||
Ai_info[Ships[ship].ai_index].kamikaze_damage = min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
|
||||
Ai_info[shipp->ai_index].kamikaze_damage = min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
|
||||
|
||||
return obj;
|
||||
}
|
||||
@@ -1073,7 +1228,7 @@ int dup_object(object *objp)
|
||||
objp1->phys_info.speed = objp2->phys_info.speed;
|
||||
objp1->phys_info.fspeed = objp2->phys_info.fspeed;
|
||||
objp1->hull_strength = objp2->hull_strength;
|
||||
objp1->shield_quadrant[0] = objp2->shield_quadrant[0];
|
||||
shield_set_strength(objp1, shield_get_strength(objp2));
|
||||
|
||||
subp1 = GET_FIRST(&Ships[n].subsys_list);
|
||||
subp2 = GET_FIRST(&Ships[inst].subsys_list);
|
||||
@@ -1097,8 +1252,12 @@ int dup_object(object *objp)
|
||||
}
|
||||
|
||||
} else if (objp->type == OBJ_WAYPOINT) {
|
||||
obj = create_waypoint(&objp->pos, list);
|
||||
list = Objects[obj].instance;
|
||||
obj = waypoint_create(&objp->pos, list);
|
||||
if(obj > -1)
|
||||
{
|
||||
list = Objects[obj].instance;
|
||||
set_modified();
|
||||
}
|
||||
}
|
||||
|
||||
if (obj == -1)
|
||||
@@ -1115,8 +1274,7 @@ int create_object(vec3d *pos, int list)
|
||||
int obj, n;
|
||||
|
||||
if (cur_model_index == Id_select_type_waypoint)
|
||||
obj = create_waypoint(pos, list);
|
||||
|
||||
obj = waypoint_create(pos, list);
|
||||
else if (cur_model_index == Id_select_type_start) {
|
||||
if (Player_starts >= MAX_PLAYERS) {
|
||||
Fred_main_wnd->MessageBox("Unable to create new player start point.\n"
|
||||
@@ -1182,97 +1340,11 @@ int create_player(int num, vec3d *pos, matrix *orient, int type, int init)
|
||||
return obj;
|
||||
}
|
||||
|
||||
int query_waypoint_path_name_duplicate(int list)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<Num_waypoint_lists; i++)
|
||||
if (i != list)
|
||||
if (!stricmp(Waypoint_lists[i].name, Waypoint_lists[list].name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void get_unique_waypoint_path_name(int list)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
sprintf(Waypoint_lists[list].name, "Waypoint path %d", list + 1);
|
||||
while (query_waypoint_path_name_duplicate(list)) {
|
||||
sprintf(Waypoint_lists[list].name, "Waypoint path U%d", i++);
|
||||
}
|
||||
}
|
||||
|
||||
int create_waypoint(vec3d *pos, int list)
|
||||
{
|
||||
int i, obj, index = 0;
|
||||
object *ptr;
|
||||
|
||||
if (list == -1) { // find a new list to start.
|
||||
for (list=0; list<MAX_WAYPOINT_LISTS; list++){
|
||||
if (!Waypoint_lists[list].count) {
|
||||
get_unique_waypoint_path_name(list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
index = (list & 0xffff) + 1;
|
||||
list /= 65536;
|
||||
}
|
||||
|
||||
if (list == MAX_WAYPOINT_LISTS) {
|
||||
Fred_main_wnd->MessageBox("Unable to create new waypoint path. You\n"
|
||||
"have reached the maximum limit.", NULL, MB_OK | MB_ICONEXCLAMATION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Assert((list >= 0) && (list < MAX_WAYPOINT_LISTS)); // illegal index or out of lists.
|
||||
if (Waypoint_lists[list].count >= MAX_WAYPOINTS_PER_LIST) {
|
||||
Fred_main_wnd->MessageBox("Unable to create new waypoint. You have\n"
|
||||
"reached the maximum limit on waypoints per list.", NULL, MB_OK | MB_ICONEXCLAMATION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Waypoint_lists[list].count > index) {
|
||||
i = Waypoint_lists[list].count;
|
||||
while (i > index) {
|
||||
Waypoint_lists[list].waypoints[i] = Waypoint_lists[list].waypoints[i - 1];
|
||||
Waypoint_lists[list].flags[i] = Waypoint_lists[list].flags[i - 1];
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = GET_FIRST(&obj_used_list);
|
||||
while (ptr != END_OF_LIST(&obj_used_list)) {
|
||||
Assert(ptr->type != OBJ_NONE);
|
||||
if (ptr->type == OBJ_WAYPOINT) {
|
||||
i = ptr->instance;
|
||||
if ((i / 65536 == list) && ((i & 0xffff) >= index)){
|
||||
ptr->instance++;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = GET_NEXT(ptr);
|
||||
}
|
||||
|
||||
Waypoint_lists[list].count++;
|
||||
Waypoint_lists[list].flags[index] = 0;
|
||||
Waypoint_lists[list].waypoints[index] = *pos;
|
||||
if (list >= Num_waypoint_lists){
|
||||
Num_waypoint_lists = list + 1;
|
||||
}
|
||||
|
||||
obj = obj_create(OBJ_WAYPOINT, -1, list * 65536 + index, NULL, pos, 0.0f, OF_RENDERS);
|
||||
set_modified();
|
||||
return obj;
|
||||
}
|
||||
|
||||
void create_new_mission()
|
||||
{
|
||||
reset_mission();
|
||||
*Mission_filename = 0;
|
||||
//FREDDoc_ptr->autosave("nothing");
|
||||
FREDDoc_ptr->autosave("nothing");
|
||||
Undo_count = 0;
|
||||
}
|
||||
|
||||
@@ -1296,6 +1368,7 @@ void clear_mission()
|
||||
extern void allocate_mission_text(int size);
|
||||
allocate_mission_text( MISSION_TEXT_SIZE );
|
||||
|
||||
fiction_viewer_reset();
|
||||
cmd_brief_reset();
|
||||
mission_event_shutdown();
|
||||
|
||||
@@ -1370,9 +1443,6 @@ void clear_mission()
|
||||
Player_starts = 0;
|
||||
Num_teams = 1;
|
||||
|
||||
// reset background bitmaps and suns
|
||||
stars_pre_level_init();
|
||||
|
||||
// reset alternate name stuff
|
||||
for(i=0; i<MAX_SHIPS; i++){
|
||||
strcpy(Fred_alt_names[i], "");
|
||||
@@ -1382,10 +1452,13 @@ void clear_mission()
|
||||
// of ships for all teams
|
||||
for (i=0; i<MAX_TVT_TEAMS; i++) {
|
||||
count = 0;
|
||||
char empty[TOKEN_LENGTH] = "";
|
||||
for ( j = 0; j < MAX_SHIP_CLASSES; j++ ) {
|
||||
if (Ship_info[j].flags & SIF_DEFAULT_PLAYER_SHIP) {
|
||||
Team_data[i].ship_list[count] = j;
|
||||
Team_data[i].ship_count[count++] = 5;
|
||||
strcpy(Team_data[i].ship_list_variables[count], empty);
|
||||
Team_data[i].ship_count[count] = 5;
|
||||
strcpy(Team_data[i].ship_count_variables[count++], empty);
|
||||
}
|
||||
}
|
||||
Team_data[i].number_choices = count;
|
||||
@@ -1423,9 +1496,15 @@ void clear_mission()
|
||||
// alternate ship type names
|
||||
mission_parse_reset_alt();
|
||||
|
||||
strcpy(Cargo_names[0], "Nothing");
|
||||
if(Cargo_names[0] != NULL)
|
||||
{
|
||||
//WMC - Is this really needed?
|
||||
strcpy(Cargo_names[0], "Nothing");
|
||||
}
|
||||
Num_cargo = 1;
|
||||
set_physics_controls();
|
||||
|
||||
// reset background bitmaps and suns
|
||||
stars_pre_level_init();
|
||||
Nebula_index = 0;
|
||||
Mission_palette = 1;
|
||||
@@ -1443,6 +1522,10 @@ void clear_mission()
|
||||
|
||||
The_mission.contrail_threshold = CONTRAIL_THRESHOLD_DEFAULT;
|
||||
|
||||
// Goober5000
|
||||
The_mission.command_persona = Default_command_persona;
|
||||
strcpy(The_mission.command_sender, DEFAULT_COMMAND);
|
||||
|
||||
// Goober5000: reset ALL mission flags, not just nebula!
|
||||
The_mission.flags = 0;
|
||||
The_mission.support_ships.max_support_ships = -1; // negative means infinite
|
||||
@@ -1456,10 +1539,15 @@ void clear_mission()
|
||||
strcpy(palette_filename, "gamepalette1-01");
|
||||
// sprintf( palette_filename, "gamepalette%d-%02d", 1, Mission_palette+1 );
|
||||
mprintf(( "Loading palette %s\n", palette_filename ));
|
||||
palette_load_table(palette_filename);
|
||||
//WMC - I dunnit. It doesn't look like this is really used?
|
||||
//palette_load_table(palette_filename);
|
||||
|
||||
strcpy(The_mission.loading_screen[GR_640],"");
|
||||
strcpy(The_mission.loading_screen[GR_1024],"");
|
||||
strcpy(The_mission.skybox_model, "");
|
||||
strcpy(The_mission.envmap_name, "");
|
||||
|
||||
ENVMAP = -1;
|
||||
|
||||
set_modified(FALSE);
|
||||
Update_window = 1;
|
||||
@@ -1586,7 +1674,7 @@ void set_cur_indices(int obj)
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj == -1 || !num_objects) {
|
||||
if (obj == -1 || !Num_objects) {
|
||||
cur_object_index = cur_ship = cur_wing = cur_waypoint_list = cur_waypoint = -1;
|
||||
return;
|
||||
}
|
||||
@@ -2372,7 +2460,7 @@ void correct_marking()
|
||||
break;
|
||||
|
||||
case OBJ_START:
|
||||
if (!Show_starts)
|
||||
if (!Show_starts || !Show_ships)
|
||||
unmark_object(OBJ_INDEX(ptr));
|
||||
break;
|
||||
|
||||
@@ -2397,7 +2485,7 @@ void set_valid_dock_points(int ship, int type, CComboBox *box)
|
||||
{
|
||||
int i, z, num, model;
|
||||
|
||||
model = Ships[ship].modelnum;
|
||||
model = Ship_info[Ships[ship].ship_info_index].model_num;
|
||||
num = model_get_num_dock_points(model);
|
||||
for (i=0; i<num; i++)
|
||||
if (model_get_dock_index_type(model, i) & type) {
|
||||
@@ -2851,6 +2939,20 @@ int query_whole_wing_marked(int wing)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void generate_ship_usage_list(int *arr, int wing)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (wing < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
i = Wings[wing].wave_count;
|
||||
while (i--) {
|
||||
arr[Ships[Wings[wing].ship_index[i]].ship_info_index]++;
|
||||
}
|
||||
}
|
||||
|
||||
void generate_weaponry_usage_list(int *arr, int wing)
|
||||
{
|
||||
int i, j;
|
||||
@@ -2878,11 +2980,18 @@ void generate_weaponry_usage_list(int *arr)
|
||||
|
||||
for (i=0; i<MAX_WEAPON_TYPES; i++)
|
||||
arr[i] = 0;
|
||||
|
||||
if (The_mission.game_type & MISSION_TYPE_MULTI_TEAMS) {
|
||||
for (i=0; i<MAX_TVT_WINGS; i++) {
|
||||
generate_weaponry_usage_list(arr, TVT_wings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000 - I have no idea why :V: did things this way (or even what exactly they're doing);
|
||||
// I'm guessing Zeta needs to be accounted for somewhere but I'm not sure how to do that
|
||||
for (i=0; i<MAX_STARTING_WINGS; i++)
|
||||
generate_weaponry_usage_list(arr, Starting_wings[i]);
|
||||
else {
|
||||
for (i=0; i<MAX_STARTING_WINGS; i++) {
|
||||
generate_weaponry_usage_list(arr, Starting_wings[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jump_node *jumpnode_get_by_name(CString& name)
|
||||
@@ -2933,7 +3042,7 @@ void management_add_ships_to_combo( CComboBox *box, int flags )
|
||||
polymodel *pm;
|
||||
|
||||
// determine if this ship has a docking bay
|
||||
pm = model_get( Ships[objp->instance].modelnum );
|
||||
pm = model_get( Ship_info[Ships[objp->instance].ship_info_index].model_num );
|
||||
Assert( pm );
|
||||
if ( pm->ship_bay && (pm->ship_bay->num_paths > 0) ) {
|
||||
id = box->AddString(Ships[get_ship_from_obj(objp)].ship_name);
|
||||
|
||||
+23
-3
@@ -9,9 +9,9 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/Management.h $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2007-12-19 10:54:26 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* This file handles the management of Objects, Ships, Wings, etc. Basically
|
||||
* all the little structures we have that usually inter-relate that need to
|
||||
@@ -19,6 +19,12 @@
|
||||
* function.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.3 2006/10/01 01:12:32 Goober5000
|
||||
* enhanced voice acting manager, now with script generator :)
|
||||
*
|
||||
* Revision 1.2 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
@@ -331,6 +337,17 @@ extern char *Docking_bay_list[];
|
||||
extern char Fred_exe_dir[512];
|
||||
extern char Fred_base_dir[512];
|
||||
|
||||
// Goober5000 - for voice acting manager
|
||||
extern char Voice_abbrev_briefing[NAME_LENGTH];
|
||||
extern char Voice_abbrev_campaign[NAME_LENGTH];
|
||||
extern char Voice_abbrev_command_briefing[NAME_LENGTH];
|
||||
extern char Voice_abbrev_debriefing[NAME_LENGTH];
|
||||
extern char Voice_abbrev_message[NAME_LENGTH];
|
||||
extern char Voice_abbrev_mission[NAME_LENGTH];
|
||||
extern bool Voice_no_replace_filenames;
|
||||
extern char Voice_script_entry_format[NOTES_LENGTH];
|
||||
extern int Voice_export_selection;
|
||||
|
||||
// Goober5000
|
||||
extern bool Show_iff[];
|
||||
|
||||
@@ -395,6 +412,9 @@ void object_moved(object *ptr);
|
||||
int invalidate_references(char *name, int type);
|
||||
int query_whole_wing_marked(int wing);
|
||||
void generate_weaponry_usage_list(int *arr);
|
||||
void generate_weaponry_usage_list(int *arr, int wing);
|
||||
void generate_ship_usage_list(int *arr, int wing);
|
||||
|
||||
jump_node *jumpnode_get_by_name(CString& name);
|
||||
|
||||
// function and defines to use when adding ships to combo boxes
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/MessageEditorDlg.cpp $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2007-07-15 04:45:42 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Old message editor dialog box handling code. This was designed a LONG time ago
|
||||
@@ -18,6 +18,16 @@
|
||||
* only around just in case it might be useful.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.3 2007/03/07 22:43:24 karajorma
|
||||
* Make .ogg voice files selectable in FRED.
|
||||
*
|
||||
* Revision 1.2 2007/02/15 02:03:56 phreak
|
||||
* Apparently Visual C++ 2005 follows standard syntax rules.
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.4 2005/01/29 05:40:27 Goober5000
|
||||
* regular docking should work again in FRED now (multiple docking still isn't done yet)
|
||||
* --Goober5000
|
||||
@@ -423,7 +433,7 @@ int CMessageEditorDlg::find_event()
|
||||
|| get_operator_const(CTEXT(node)) == OP_WHEN_ARGUMENT || get_operator_const(CTEXT(node)) == OP_EVERY_TIME_ARGUMENT )
|
||||
{
|
||||
// Goober5000 - the bool part of the when-argument conditional starts at the second, not first, argument
|
||||
if (get_operator_const(CTEXT(node)) == OP_WHEN_ARGUMENT)
|
||||
if (get_operator_const(CTEXT(node)) == OP_WHEN_ARGUMENT || get_operator_const(CTEXT(node)) == OP_EVERY_TIME_ARGUMENT)
|
||||
node = CDR(node);
|
||||
|
||||
node = CDR(node);
|
||||
@@ -456,7 +466,7 @@ int CMessageEditorDlg::find_event()
|
||||
void CMessageEditorDlg::OnSelchangeMessageList()
|
||||
{
|
||||
int old = m_cur_msg;
|
||||
static flag = 0;
|
||||
static int flag = 0;
|
||||
|
||||
if (flag)
|
||||
return;
|
||||
@@ -673,7 +683,7 @@ void CMessageEditorDlg::OnBrowseWave()
|
||||
|
||||
UpdateData(TRUE);
|
||||
CFileDialog dlg(TRUE, "wav", m_wave_filename, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Wave Files (*.wav)|*.wav||");
|
||||
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
|
||||
|
||||
if (dlg.DoModal() == IDOK)
|
||||
{
|
||||
|
||||
@@ -9,13 +9,20 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/fred2/MissionGoalsDlg.cpp $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 2007-09-02 02:10:25 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Mission goals editor dialog box handling code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.2 2006/10/09 05:25:18 Goober5000
|
||||
* make sexp nodes dynamic
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.2 2002/08/15 01:06:34 penguin
|
||||
* Include filename reorg (to coordinate w/ fs2_open)
|
||||
*
|
||||
@@ -179,38 +186,6 @@ CMissionGoalsDlg *Goal_editor_dlg; // global reference needed by sexp_tree class
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// sexp_goal_tree class member functions
|
||||
|
||||
// determine the node number that would be allocated without actually allocating it yet.
|
||||
int sexp_goal_tree::get_new_node_position()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_SEXP_TREE_SIZE; i++)
|
||||
if (nodes[i].type == SEXPT_UNUSED)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// construct tree nodes for an sexp, adding them to the list and returning first node
|
||||
int sexp_goal_tree::load_sub_tree(int index)
|
||||
{
|
||||
int cur;
|
||||
|
||||
if (index < 0) {
|
||||
cur = allocate_node(-1);
|
||||
set_node(cur, (SEXPT_OPERATOR | SEXPT_VALID), "true"); // setup a default tree if none
|
||||
return cur;
|
||||
}
|
||||
|
||||
// assumption: first token is an operator. I require this because it would cause problems
|
||||
// with child/parent relations otherwise, and it should be this way anyway, since the
|
||||
// return type of the whole sexp is boolean, and only operators can satisfy this.
|
||||
Assert(Sexp_nodes[index].subtype == SEXP_ATOM_OPERATOR);
|
||||
cur = get_new_node_position();
|
||||
load_branch(index, -1);
|
||||
return cur;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMissionGoalsDlg dialog class member functions
|
||||
|
||||
@@ -318,7 +293,7 @@ void CMissionGoalsDlg::load_tree()
|
||||
if (!(*m_goals[i].name))
|
||||
strcpy(m_goals[i].name, "<unnamed>");
|
||||
|
||||
m_goals[i].formula = m_goals_tree.load_sub_tree(Mission_goals[i].formula);
|
||||
m_goals[i].formula = m_goals_tree.load_sub_tree(Mission_goals[i].formula, true, "true");
|
||||
}
|
||||
|
||||
m_goals_tree.post_load();
|
||||
@@ -397,6 +372,8 @@ void CMissionGoalsDlg::update_cur_goal()
|
||||
GetDlgItem(IDC_GOAL_SCORE)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_NO_MUSIC)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_OBJ_TEAM)->EnableWindow(FALSE);
|
||||
|
||||
UpdateData(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -431,6 +408,8 @@ void CMissionGoalsDlg::update_cur_goal()
|
||||
if ( The_mission.game_type & MISSION_TYPE_MULTI_TEAMS ){
|
||||
GetDlgItem(IDC_OBJ_TEAM)->EnableWindow(TRUE);
|
||||
}
|
||||
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
// handler for context menu (i.e. a right mouse button click).
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/MissionGoalsDlg.h $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-10-09 05:25:18 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Mission goals editor dialog box handling code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.4 2005/07/13 02:40:50 Goober5000
|
||||
* remove PreProcDefine #includes in FRED
|
||||
* --Goober5000
|
||||
@@ -104,11 +108,8 @@
|
||||
#define OPERAND 0x01
|
||||
#define EDITABLE 0x02
|
||||
|
||||
class sexp_goal_tree : public sexp_tree
|
||||
class goal_sexp_tree : public sexp_tree
|
||||
{
|
||||
public:
|
||||
int load_sub_tree(int index);
|
||||
int get_new_node_position();
|
||||
};
|
||||
|
||||
class CMissionGoalsDlg : public CDialog
|
||||
@@ -132,7 +133,7 @@ public:
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMissionGoalsDlg)
|
||||
enum { IDD = IDD_MISSION_GOALS };
|
||||
sexp_goal_tree m_goals_tree;
|
||||
goal_sexp_tree m_goals_tree;
|
||||
CString m_goal_desc;
|
||||
int m_goal_type;
|
||||
int m_display_goal_types;
|
||||
|
||||
@@ -9,13 +9,31 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/MissionNotesDlg.cpp $
|
||||
* $Revision: 1.7 $
|
||||
* $Date: 2006-05-30 02:13:22 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.12 $
|
||||
* $Date: 2007-07-23 15:16:48 $
|
||||
* $Author: Kazan $
|
||||
*
|
||||
* Mission notes editor dialog box handling code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.11 2007/02/11 09:31:11 taylor
|
||||
* some CFILE cleanup and slight directory order reorg
|
||||
* add cfopen_special() for quickly opening files that have already been found with cf_find_file_location_ext()
|
||||
* remove NO_SOUND
|
||||
*
|
||||
* Revision 1.10 2007/01/07 01:00:18 Goober5000
|
||||
* convert a mission variable to a mission flag
|
||||
*
|
||||
* Revision 1.9 2007/01/07 00:01:28 Goober5000
|
||||
* add a feature for specifying the source of Command messages
|
||||
*
|
||||
* Revision 1.8 2006/07/30 20:01:56 Kazan
|
||||
* resolve 1018 and an interface problem in fred2's ship editor
|
||||
*
|
||||
* Revision 1.7 2006/05/30 02:13:22 Goober5000
|
||||
* add substitute music boxes to FRED, and reset music properly when mission is cleared
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.6 2006/05/30 01:36:24 Goober5000
|
||||
* add AI Profile box to FRED
|
||||
* --Goober5000
|
||||
@@ -248,6 +266,7 @@
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "mission/missionmessage.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
@@ -279,6 +298,8 @@ CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNo
|
||||
m_ai_profile = -1;
|
||||
m_event_music = -1;
|
||||
m_substitute_event_music = _T("");
|
||||
m_command_persona = -1;
|
||||
m_command_sender = _T("");
|
||||
m_full_war = FALSE;
|
||||
m_red_alert = FALSE;
|
||||
m_scramble = FALSE;
|
||||
@@ -292,8 +313,10 @@ CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNo
|
||||
m_toggle_trails = FALSE;
|
||||
m_support_repairs_hull = FALSE;
|
||||
m_beam_free_all_by_default = FALSE;
|
||||
m_player_start_using_ai = FALSE;
|
||||
m_no_briefing = FALSE;
|
||||
m_no_debriefing = FALSE;
|
||||
m_autpilot_cinematics = FALSE;
|
||||
m_max_hull_repair_val = 0.0f;
|
||||
m_max_subsys_repair_val = 100.0f;
|
||||
m_contrail_threshold = CONTRAIL_THRESHOLD_DEFAULT;
|
||||
@@ -319,6 +342,8 @@ void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_CBIndex(pDX, IDC_AI_PROFILE, m_ai_profile);
|
||||
DDX_CBIndex(pDX, IDC_EVENT_MUSIC, m_event_music);
|
||||
DDX_Text(pDX, IDC_SUBSTITUTE_EVENT_MUSIC, m_substitute_event_music);
|
||||
DDX_CBIndex(pDX, IDC_COMMAND_PERSONA, m_command_persona);
|
||||
DDX_Text(pDX, IDC_COMMAND_SENDER, m_command_sender);
|
||||
DDX_Check(pDX, IDC_FULL_WAR, m_full_war);
|
||||
DDX_Check(pDX, IDC_RED_ALERT, m_red_alert);
|
||||
DDX_Check(pDX, IDC_SCRAMBLE, m_scramble);
|
||||
@@ -333,8 +358,10 @@ void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Check(pDX, IDC_SPECS_TOGGLE_TRAILS, m_toggle_trails);
|
||||
DDX_Check(pDX, IDC_SUPPORT_REPAIRS_HULL, m_support_repairs_hull);
|
||||
DDX_Check(pDX, IDC_BEAM_FREE_ALL_BY_DEFAULT, m_beam_free_all_by_default);
|
||||
DDX_Check(pDX, IDC_PLAYER_START_AI, m_player_start_using_ai);
|
||||
DDX_Check(pDX, IDC_NO_BRIEFING, m_no_briefing);
|
||||
DDX_Check(pDX, IDC_NO_DEBRIEFING, m_no_debriefing);
|
||||
DDX_Check(pDX, IDC_USE_AUTOPILOT_CINEMATICS, m_autpilot_cinematics);
|
||||
DDX_Text(pDX, IDC_MAX_HULL_REPAIR_VAL, m_max_hull_repair_val);
|
||||
DDV_MinMaxFloat(pDX, m_max_hull_repair_val, 0, 100);
|
||||
DDX_Text(pDX, IDC_MAX_SUBSYS_REPAIR_VAL, m_max_subsys_repair_val);
|
||||
@@ -383,9 +410,6 @@ int CMissionNotesDlg::query_modified()
|
||||
if (Current_soundtrack_num != m_event_music - 1){
|
||||
return 1;
|
||||
}
|
||||
if (Mission_all_attack != m_full_war){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
*/
|
||||
@@ -451,6 +475,13 @@ void CMissionNotesDlg::OnOK()
|
||||
The_mission.flags &= ~MISSION_FLAG_SCRAMBLE;
|
||||
}
|
||||
|
||||
// set attack all
|
||||
if ( m_full_war ) {
|
||||
The_mission.flags |= MISSION_FLAG_ALL_ATTACK;
|
||||
} else {
|
||||
The_mission.flags &= ~MISSION_FLAG_ALL_ATTACK;
|
||||
}
|
||||
|
||||
// set flags for dock trees
|
||||
if ( m_daisy_chained_docking ) {
|
||||
The_mission.flags |= MISSION_FLAG_ALLOW_DOCK_TREES;
|
||||
@@ -516,6 +547,13 @@ void CMissionNotesDlg::OnOK()
|
||||
The_mission.flags &= ~MISSION_FLAG_BEAM_FREE_ALL_BY_DEFAULT;
|
||||
}
|
||||
|
||||
// set player AI by default
|
||||
if ( m_player_start_using_ai ) {
|
||||
The_mission.flags |= MISSION_FLAG_PLAYER_START_AI;
|
||||
} else {
|
||||
The_mission.flags &= ~MISSION_FLAG_PLAYER_START_AI;
|
||||
}
|
||||
|
||||
// set briefing
|
||||
if ( m_no_briefing ) {
|
||||
The_mission.flags |= MISSION_FLAG_NO_BRIEFING;
|
||||
@@ -530,6 +568,13 @@ void CMissionNotesDlg::OnOK()
|
||||
The_mission.flags &= ~MISSION_FLAG_NO_DEBRIEFING;
|
||||
}
|
||||
|
||||
// set autopilot cinematics
|
||||
if ( m_autpilot_cinematics ) {
|
||||
The_mission.flags |= MISSION_FLAG_USE_AP_CINEMATICS;
|
||||
} else {
|
||||
The_mission.flags &= ~MISSION_FLAG_USE_AP_CINEMATICS;
|
||||
}
|
||||
|
||||
if ( flags != The_mission.flags ){
|
||||
set_modified();
|
||||
}
|
||||
@@ -555,10 +600,11 @@ void CMissionNotesDlg::OnOK()
|
||||
MODIFY(Current_soundtrack_num, m_event_music - 1);
|
||||
strcpy(The_mission.substitute_event_music_name, m_substitute_event_music);
|
||||
|
||||
MODIFY(Mission_all_attack, m_full_war);
|
||||
if (query_modified()){
|
||||
set_modified();
|
||||
}
|
||||
MODIFY(The_mission.command_persona, ((CComboBox *) GetDlgItem(IDC_COMMAND_PERSONA))->GetItemData(m_command_persona));
|
||||
if (m_command_sender.GetAt(0) == '#')
|
||||
strcpy(The_mission.command_sender, m_command_sender.Mid(1));
|
||||
else
|
||||
strcpy(The_mission.command_sender, m_command_sender);
|
||||
|
||||
theApp.record_window_data(&Mission_notes_wnd_data, this);
|
||||
|
||||
@@ -579,7 +625,7 @@ void CMissionNotesDlg::OnCancel()
|
||||
|
||||
BOOL CMissionNotesDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
int i, box_index = 0, mission_command_persona_box_index = -1;
|
||||
CComboBox *box;
|
||||
CEdit *edit;
|
||||
|
||||
@@ -596,6 +642,7 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
m_mission_desc_orig = m_mission_desc = convert_multiline_string(The_mission.mission_desc);
|
||||
m_red_alert = (The_mission.flags & MISSION_FLAG_RED_ALERT) ? 1 : 0;
|
||||
m_scramble = (The_mission.flags & MISSION_FLAG_SCRAMBLE) ? 1 : 0;
|
||||
m_full_war = (The_mission.flags & MISSION_FLAG_ALL_ATTACK) ? 1 : 0;
|
||||
m_daisy_chained_docking = (The_mission.flags & MISSION_FLAG_ALLOW_DOCK_TREES) ? 1 : 0;
|
||||
m_disallow_support = (The_mission.support_ships.max_support_ships == 0) ? 1 : 0;
|
||||
m_no_promotion = (The_mission.flags & MISSION_FLAG_NO_PROMOTION) ? 1 : 0;
|
||||
@@ -605,8 +652,11 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
m_toggle_trails = (The_mission.flags & MISSION_FLAG_TOGGLE_SHIP_TRAILS) ? 1 : 0;
|
||||
m_support_repairs_hull = (The_mission.flags &MISSION_FLAG_SUPPORT_REPAIRS_HULL) ? 1 : 0;
|
||||
m_beam_free_all_by_default = (The_mission.flags & MISSION_FLAG_BEAM_FREE_ALL_BY_DEFAULT) ? 1 : 0;
|
||||
m_player_start_using_ai = (The_mission.flags & MISSION_FLAG_PLAYER_START_AI) ? 1 : 0;
|
||||
m_no_briefing = (The_mission.flags & MISSION_FLAG_NO_BRIEFING) ? 1 : 0;
|
||||
m_no_debriefing = (The_mission.flags & MISSION_FLAG_NO_DEBRIEFING) ? 1 : 0;
|
||||
m_autpilot_cinematics = (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) ? 1 : 0;
|
||||
|
||||
|
||||
m_loading_640=_T(The_mission.loading_screen[GR_640]);
|
||||
m_loading_1024=_T(The_mission.loading_screen[GR_1024]);
|
||||
@@ -630,6 +680,25 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
box->AddString(Soundtracks[i].name);
|
||||
}
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_COMMAND_PERSONA);
|
||||
for (i=0; i<Num_personas; i++){
|
||||
if (Personas[i].flags & PERSONA_FLAG_COMMAND){
|
||||
box->AddString(Personas[i].name);
|
||||
box->SetItemData(box_index, i);
|
||||
if (i == The_mission.command_persona)
|
||||
mission_command_persona_box_index = box_index;
|
||||
box_index++;
|
||||
}
|
||||
}
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_COMMAND_SENDER);
|
||||
box->AddString(DEFAULT_COMMAND);
|
||||
for (i=0; i<MAX_SHIPS; i++){
|
||||
if (Ships[i].objnum >= 0)
|
||||
if (Ship_info[Ships[i].ship_info_index].flags & SIF_HUGE_SHIP)
|
||||
box->AddString(Ships[i].ship_name);
|
||||
}
|
||||
|
||||
// squad info
|
||||
if(strlen(The_mission.squad_name) > 0){
|
||||
m_squad_name = _T(The_mission.squad_name);
|
||||
@@ -641,9 +710,12 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
|
||||
m_type = The_mission.game_type;
|
||||
m_ai_profile = (The_mission.ai_profile - Ai_profiles);
|
||||
|
||||
m_event_music = Current_soundtrack_num + 1;
|
||||
m_substitute_event_music = The_mission.substitute_event_music_name;
|
||||
m_full_war = Mission_all_attack;
|
||||
|
||||
m_command_persona = mission_command_persona_box_index;
|
||||
m_command_sender = The_mission.command_sender;
|
||||
|
||||
// set up the game type checkboxes accoring to m_type
|
||||
if ( m_type & MISSION_TYPE_SINGLE ){
|
||||
@@ -755,7 +827,7 @@ void CMissionNotesDlg::OnSquadLogo()
|
||||
UpdateData(TRUE);
|
||||
|
||||
// get list of squad images
|
||||
z = cfile_push_chdir(CF_TYPE_SQUAD_IMAGES_MAIN);
|
||||
z = cfile_push_chdir(CF_TYPE_SQUAD_IMAGES);
|
||||
CFileDialog dlg(TRUE, "pcx", pcx_filename, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Pcx Files (*.pcx)|*.pcx");
|
||||
|
||||
// if we have a result
|
||||
|
||||
@@ -9,13 +9,23 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/Fred2/MissionNotesDlg.h $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2006-05-30 02:13:22 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.7 $
|
||||
* $Date: 2007-07-23 15:16:48 $
|
||||
* $Author: Kazan $
|
||||
*
|
||||
* Mission notes editor dialog box handling code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.6 2007/01/07 00:01:28 Goober5000
|
||||
* add a feature for specifying the source of Command messages
|
||||
*
|
||||
* Revision 1.5 2006/07/30 20:01:56 Kazan
|
||||
* resolve 1018 and an interface problem in fred2's ship editor
|
||||
*
|
||||
* Revision 1.4 2006/05/30 02:13:22 Goober5000
|
||||
* add substitute music boxes to FRED, and reset music properly when mission is cleared
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.3 2006/05/30 01:36:24 Goober5000
|
||||
* add AI Profile box to FRED
|
||||
* --Goober5000
|
||||
@@ -198,6 +208,8 @@ public:
|
||||
int m_ai_profile;
|
||||
int m_event_music;
|
||||
CString m_substitute_event_music;
|
||||
int m_command_persona;
|
||||
CString m_command_sender;
|
||||
BOOL m_full_war;
|
||||
BOOL m_red_alert;
|
||||
BOOL m_scramble;
|
||||
@@ -211,8 +223,10 @@ public:
|
||||
BOOL m_toggle_trails;
|
||||
BOOL m_support_repairs_hull;
|
||||
BOOL m_beam_free_all_by_default;
|
||||
BOOL m_player_start_using_ai;
|
||||
BOOL m_no_briefing;
|
||||
BOOL m_no_debriefing;
|
||||
BOOL m_autpilot_cinematics;
|
||||
float m_max_hull_repair_val;
|
||||
float m_max_subsys_repair_val;
|
||||
BOOL m_contrail_threshold_flag;
|
||||
|
||||
+624
-184
File diff suppressed because it is too large.
Load diff
@@ -9,13 +9,24 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/MissionSave.h $
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 2006-04-20 06:32:01 $
|
||||
* $Revision: 1.6 $
|
||||
* $Date: 2007-11-21 07:28:37 $
|
||||
* $Author: Goober5000 $
|
||||
*
|
||||
* Mission saving in Fred.
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.5 2006/12/28 00:59:20 wmcoolmon
|
||||
* WMC codebase commit. See pre-commit build thread for details on changes.
|
||||
*
|
||||
* Revision 1.4 2006/07/13 06:11:52 Goober5000
|
||||
* * better formatting for substitute music options
|
||||
* * better handling of all special FSO comment tags
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.3 2006/04/20 06:32:01 Goober5000
|
||||
* proper capitalization according to Volition
|
||||
*
|
||||
* Revision 1.2 2006/02/19 00:49:41 Goober5000
|
||||
* fixed saving of special tags
|
||||
* --Goober5000
|
||||
@@ -131,6 +142,7 @@
|
||||
#include "ai/ai.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "ship/ship.h"
|
||||
#include "object/waypoint/waypoint.h"
|
||||
|
||||
#define BACKUP_DEPTH 9
|
||||
|
||||
@@ -144,6 +156,7 @@ private:
|
||||
int save_plot_info();
|
||||
int save_variables();
|
||||
// int save_briefing_info();
|
||||
int save_fiction();
|
||||
int save_cmd_brief();
|
||||
int save_cmd_briefs();
|
||||
int save_briefing();
|
||||
@@ -179,6 +192,10 @@ public:
|
||||
int save_mission_file(char *pathname);
|
||||
int autosave_mission_file(char *pathname);
|
||||
int save_campaign_file(char *pathname);
|
||||
|
||||
// Goober5000
|
||||
int fout_and_bypass(char *format, ...);
|
||||
void bypass_comment(char *comment);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -57,6 +57,7 @@ BEGIN_MESSAGE_MAP(CModifyVariableDlg, CDialog)
|
||||
ON_BN_CLICKED(IDC_TYPE_NUMBER, OnTypeNumber)
|
||||
ON_BN_CLICKED(IDC_TYPE_PLAYER_PERSISTENT, OnTypePlayerPersistent)
|
||||
ON_BN_CLICKED(IDC_TYPE_CAMPAIGN_PERSISTENT, OnTypeCampaignPersistent)
|
||||
ON_BN_CLICKED(IDC_TYPE_NETWORK_VARIABLE, OnTypeNetworkVariable)
|
||||
ON_CBN_SELCHANGE(IDC_MODIFY_VARIABLE_NAME, OnSelchangeModifyVariableName)
|
||||
ON_CBN_EDITCHANGE(IDC_MODIFY_VARIABLE_NAME, OnEditchangeModifyVariableName)
|
||||
ON_EN_KILLFOCUS(IDC_MODIFY_DEFAULT_VALUE, OnKillfocusModifyDefaultValue)
|
||||
@@ -82,12 +83,10 @@ void CModifyVariableDlg::OnDeleteVariable()
|
||||
MessageBox("Can not delete variable. Name has been changed.");
|
||||
return;
|
||||
}
|
||||
|
||||
int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
|
||||
if (num_counts > 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "Can not delete variable. Used in %d location(s).", num_counts);
|
||||
MessageBox(buffer);
|
||||
|
||||
char message[128] = "Can not delete variable.";
|
||||
if (!IsChangeSafe(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,19 +101,40 @@ void CModifyVariableDlg::OnDeleteVariable()
|
||||
}
|
||||
}
|
||||
|
||||
// Karajorma - Checks whether it is safe to delete or modify this string
|
||||
bool CModifyVariableDlg::IsChangeSafe(char *message)
|
||||
{
|
||||
// Can't delete as there are SEXPs using it.
|
||||
int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
|
||||
if (num_counts > 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%s Used in %d SEXP(s).", message, num_counts);
|
||||
MessageBox(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can't delete as it is used in the team loadout
|
||||
num_counts = m_p_sexp_tree->get_loadout_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
|
||||
if (num_counts > 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%s Used in %d location(s) in loadout.", message, num_counts);
|
||||
MessageBox(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set type to string
|
||||
void CModifyVariableDlg::OnTypeString()
|
||||
{
|
||||
// check if type actually modified
|
||||
if (m_type_number == true) {
|
||||
|
||||
// Don't allow type change if in use.
|
||||
int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
|
||||
if (num_counts > 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "Can not modify variable type. Used in %d location(s).", num_counts);
|
||||
MessageBox(buffer);
|
||||
|
||||
// Don't allow type change if in use.
|
||||
char message[128] = "Can not modify variable type.";
|
||||
if (!IsChangeSafe(message))
|
||||
{
|
||||
m_type_number = true;
|
||||
m_modified_type = false;
|
||||
set_variable_type();
|
||||
@@ -137,14 +157,11 @@ void CModifyVariableDlg::OnTypeNumber()
|
||||
{
|
||||
// check if type actually modified
|
||||
if (m_type_number == false) {
|
||||
|
||||
// Don't allow type change if in use.
|
||||
int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
|
||||
if (num_counts > 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "Can not modify variable type. Used in %d location(s).", num_counts);
|
||||
MessageBox(buffer);
|
||||
|
||||
|
||||
// Don't allow type change if in use.
|
||||
char message[128] = "Can not modify variable type.";
|
||||
if (!IsChangeSafe(message))
|
||||
{
|
||||
m_type_number = false;
|
||||
m_modified_type = false;
|
||||
set_variable_type();
|
||||
@@ -190,6 +207,15 @@ void CModifyVariableDlg::OnTypeCampaignPersistent()
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
void CModifyVariableDlg::OnTypeNetworkVariable()
|
||||
{
|
||||
m_type_network_variable = ((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->GetCheck() ? true : false;
|
||||
|
||||
m_modified_type = true;
|
||||
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
void CModifyVariableDlg::OnSelchangeModifyVariableName()
|
||||
{
|
||||
CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
|
||||
@@ -224,6 +250,7 @@ void CModifyVariableDlg::OnSelchangeModifyVariableName()
|
||||
m_type_number = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NUMBER) != 0) ? true : false;
|
||||
m_type_campaign_persistent = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_CAMPAIGN_PERSISTENT) != 0) ? true : false;
|
||||
m_type_player_persistent = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_PLAYER_PERSISTENT) != 0) ? true : false;
|
||||
m_type_network_variable = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NETWORK) != 0) ? true : false;
|
||||
set_variable_type();
|
||||
|
||||
// Set new default value for selection
|
||||
@@ -309,6 +336,7 @@ BOOL CModifyVariableDlg::OnInitDialog()
|
||||
m_type_number = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_NUMBER) != 0) ? true : false;
|
||||
m_type_campaign_persistent = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_CAMPAIGN_PERSISTENT) != 0) ? true : false;
|
||||
m_type_player_persistent = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_PLAYER_PERSISTENT) != 0) ? true : false;
|
||||
m_type_network_variable = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_NETWORK) != 0) ? true : false;
|
||||
set_variable_type();
|
||||
|
||||
// keep track of changes
|
||||
@@ -339,6 +367,7 @@ void CModifyVariableDlg::set_variable_type()
|
||||
|
||||
((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->SetCheck(m_type_campaign_persistent);
|
||||
((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->SetCheck(m_type_player_persistent);
|
||||
((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->SetCheck(m_type_network_variable);
|
||||
}
|
||||
|
||||
void CModifyVariableDlg::OnOK()
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
bool m_type_number;
|
||||
bool m_type_player_persistent;
|
||||
bool m_type_campaign_persistent;
|
||||
bool m_type_network_variable;
|
||||
bool m_modified_name;
|
||||
bool m_modified_value;
|
||||
bool m_modified_type;
|
||||
@@ -59,6 +60,10 @@ public:
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
private:
|
||||
bool IsChangeSafe(char *message);
|
||||
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
@@ -68,6 +73,7 @@ protected:
|
||||
afx_msg void OnTypeNumber();
|
||||
afx_msg void OnTypePlayerPersistent();
|
||||
afx_msg void OnTypeCampaignPersistent();
|
||||
afx_msg void OnTypeNetworkVariable();
|
||||
afx_msg void OnSelchangeModifyVariableName();
|
||||
afx_msg void OnEditchangeModifyVariableName();
|
||||
virtual BOOL OnInitDialog();
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/FRED2/OrientEditor.cpp $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2006-12-28 00:59:20 $
|
||||
* $Author: wmcoolmon $
|
||||
*
|
||||
* Object orientation editor (or just object editor) dialog box handling code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.4 2005/04/13 20:11:06 chhogg
|
||||
* Changed vector to vec3d for Fred.
|
||||
*
|
||||
@@ -213,15 +217,15 @@ BOOL orient_editor::OnInitDialog()
|
||||
m_object_index = 0;
|
||||
}
|
||||
|
||||
m_spin1.SetRange(99999, -99999);
|
||||
m_spin1.SetRange((short)99999, (short)-99999);
|
||||
m_spin1.SetPos((int) convert(m_position_x));
|
||||
m_spin2.SetRange(99999, -99999);
|
||||
m_spin2.SetRange( (short)99999, (short)-99999);
|
||||
m_spin2.SetPos((int) convert(m_position_y));
|
||||
m_spin3.SetRange(99999, -99999);
|
||||
m_spin3.SetRange( (short)99999, (short)-99999);
|
||||
m_spin3.SetPos((int) convert(m_position_z));
|
||||
m_spin4.SetRange(99999, -99999);
|
||||
m_spin5.SetRange(99999, -99999);
|
||||
m_spin6.SetRange(99999, -99999);
|
||||
m_spin4.SetRange( (short)99999, (short)-99999);
|
||||
m_spin5.SetRange( (short)99999, (short)-99999);
|
||||
m_spin6.SetRange( (short)99999, (short)-99999);
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -9,13 +9,23 @@
|
||||
|
||||
/*
|
||||
* $Logfile: /Freespace2/code/fred2/PlayerStartEditor.cpp $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2006-01-19 02:27:31 $
|
||||
* $Author: Goober5000 $
|
||||
* $Revision: 1.4 $
|
||||
* $Date: 2007-12-19 10:54:26 $
|
||||
* $Author: karajorma $
|
||||
*
|
||||
* Player starting point editor dialog box handling code
|
||||
*
|
||||
* $Log: not supported by cvs2svn $
|
||||
* Revision 1.3 2007/01/07 12:55:57 taylor
|
||||
* safety check to make sure that we don't end up with non-player-usable weapons in the weaponselect pool (Mantis bug #1196)
|
||||
*
|
||||
* Revision 1.2 2006/06/02 09:52:42 karajorma
|
||||
* Complete overhaul of how ship loadout is handled to support the use of variables for setting the class and quantity of ships present in loadout.
|
||||
*
|
||||
* Revision 1.1 2006/01/19 02:27:31 Goober5000
|
||||
* import FRED2 back into fs2_open module
|
||||
* --Goober5000
|
||||
*
|
||||
* Revision 1.4 2005/12/29 08:21:00 wmcoolmon
|
||||
* No my widdle FRED, I didn't forget about you ^_^ (codebase commit)
|
||||
*
|
||||
@@ -75,7 +85,13 @@ void player_start_editor::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Control(pDX, IDC_DELAY_SPIN, m_delay_spin);
|
||||
DDX_Control(pDX, IDC_SPIN1, m_spin1);
|
||||
DDX_Control(pDX, IDC_SHIP_LIST, m_ship_list);
|
||||
DDX_Control(pDX, IDC_WEAPON_LIST, m_weapon_list);
|
||||
DDX_Control(pDX, IDC_WEAPON_LIST, m_weapon_list);
|
||||
DDX_Control(pDX, IDC_SHIP_VARIABLES_LIST, m_ship_variable_list);
|
||||
DDX_Control(pDX, IDC_WEAPON_VARIABLES_LIST, m_weapon_variable_list);
|
||||
DDX_Control(pDX, IDC_SHIP_VARIABLES_COMBO, m_ship_quantity_variable);
|
||||
DDX_Control(pDX, IDC_WEAPON_VARIABLES_COMBO, m_weapon_quantity_variable);
|
||||
DDX_Control(pDX, IDC_WINGS_SHP_COUNT, m_ships_used_in_wings);
|
||||
DDX_Control(pDX, IDC_WINGS_WPN_COUNT, m_weapons_used_in_wings);
|
||||
DDX_Text(pDX, IDC_DELAY, m_delay);
|
||||
DDX_Text(pDX, IDC_SHIP_POOL, m_ship_pool);
|
||||
DDX_Text(pDX, IDC_WEAPON_POOL, m_weapon_pool);
|
||||
@@ -86,10 +102,14 @@ BEGIN_MESSAGE_MAP(player_start_editor, CDialog)
|
||||
//{{AFX_MSG_MAP(player_start_editor)
|
||||
ON_WM_INITMENU()
|
||||
ON_LBN_SELCHANGE(IDC_SHIP_LIST, OnSelchangeShipList)
|
||||
ON_WM_CLOSE()
|
||||
ON_LBN_SELCHANGE(IDC_WEAPON_LIST, OnSelchangeWeaponList)
|
||||
ON_EN_UPDATE(IDC_SHIP_POOL, OnUpdateShipPool)
|
||||
ON_EN_UPDATE(IDC_WEAPON_POOL, OnUpdateWeaponPool)
|
||||
ON_LBN_SELCHANGE(IDC_SHIP_VARIABLES_LIST, OnSelchangeShipVariablesList)
|
||||
ON_LBN_SELCHANGE(IDC_WEAPON_VARIABLES_LIST, OnSelchangeWeaponVariablesList)
|
||||
ON_CBN_SELCHANGE(IDC_SHIP_VARIABLES_COMBO, OnSelchangeShipVariablesCombo)
|
||||
ON_WM_CLOSE()
|
||||
ON_CBN_SELCHANGE(IDC_WEAPON_VARIABLES_COMBO, OnSelchangeWeaponVariablesCombo)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
@@ -98,24 +118,7 @@ END_MESSAGE_MAP()
|
||||
|
||||
BOOL player_start_editor::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
int idx;
|
||||
|
||||
// initialize ship pool data
|
||||
memset(ship_pool, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
|
||||
for(i=0; i<MAX_TVT_TEAMS; i++){
|
||||
for(idx=0; idx<Team_data[i].number_choices; idx++){
|
||||
ship_pool[i][Team_data[i].ship_list[idx]] = Team_data[i].ship_count[idx];
|
||||
}
|
||||
}
|
||||
|
||||
// initialize weapon pool data
|
||||
memset(weapon_pool, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_WEAPON_TYPES);
|
||||
for(i=0; i<MAX_TVT_TEAMS; i++){
|
||||
for(idx=0; idx<MAX_WEAPON_TYPES; idx++){
|
||||
weapon_pool[i][idx] = Team_data[i].weaponry_pool[idx];
|
||||
}
|
||||
}
|
||||
SetupShipAndWeaponPools();
|
||||
|
||||
// entry delay time
|
||||
m_delay = f2i(Entry_delay_time);
|
||||
@@ -135,11 +138,126 @@ BOOL player_start_editor::OnInitDialog()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void player_start_editor::SetupShipAndWeaponPools()
|
||||
{
|
||||
int i, j;
|
||||
int idx;
|
||||
|
||||
// initialize ship pool data
|
||||
memset(static_ship_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
|
||||
memset(dynamic_ship_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SEXP_VARIABLES);
|
||||
memset(static_ship_variable_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
|
||||
memset(dynamic_ship_variable_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SEXP_VARIABLES);
|
||||
for(i=0; i<MAX_TVT_TEAMS; i++){
|
||||
for(idx=0; idx<Team_data[i].number_choices; idx++)
|
||||
{
|
||||
if (!strcmp(Team_data[i].ship_list_variables[idx], ""))
|
||||
{
|
||||
// This pool is set to hold the number of ships available at an index corresponding to the Ship_info array.
|
||||
static_ship_pool[i][Team_data[i].ship_list[idx]] = Team_data[i].ship_count[idx];
|
||||
// This pool is set to hold whether a ship at a Ship_info index has been set by a variable (and the
|
||||
// variables index in Sexp_variables) if it has).
|
||||
static_ship_variable_pool[i][Team_data[i].ship_list[idx]] = get_index_sexp_variable_name(Team_data[i].ship_count_variables[idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This pool is set to hold the number of ships available at an index corresponding to the Sexp_variables array
|
||||
dynamic_ship_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = Team_data[i].ship_count[idx];
|
||||
// This pool is set to hold whether a ship at a Ship_info index has been set by a variable (and the
|
||||
// variables index in Sexp_variables) if it has).
|
||||
dynamic_ship_variable_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = get_index_sexp_variable_name(Team_data[i].ship_count_variables[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize weapon pool data
|
||||
memset(weapon_pool, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_WEAPON_TYPES);
|
||||
for(i=0; i<MAX_TVT_TEAMS; i++){
|
||||
for(idx=0; idx<MAX_WEAPON_TYPES; idx++){
|
||||
weapon_pool[i][idx] = Team_data[i].weaponry_pool[idx];
|
||||
}
|
||||
}
|
||||
|
||||
// initialise the ship and weapon usage list
|
||||
memset(ship_usage, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
|
||||
memset(weapon_usage, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_WEAPON_TYPES);
|
||||
|
||||
if (The_mission.game_type & MISSION_TYPE_MULTI_TEAMS) {
|
||||
for (i=0; i<MAX_TVT_TEAMS; i++) {
|
||||
for (j=0; j<MAX_TVT_WINGS_PER_TEAM; j++) {
|
||||
generate_ship_usage_list(ship_usage[i], TVT_wings[(i*MAX_TVT_WINGS_PER_TEAM) + j]);
|
||||
generate_weaponry_usage_list(weapon_usage[i], TVT_wings[(i*MAX_TVT_WINGS_PER_TEAM) + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i=0; i<MAX_STARTING_WINGS; i++) {
|
||||
generate_ship_usage_list(ship_usage[0], Starting_wings[i]);
|
||||
generate_weaponry_usage_list(weapon_usage[0], Starting_wings[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// regenerate all controls
|
||||
void player_start_editor::reset_controls()
|
||||
{
|
||||
int i;
|
||||
int ct;
|
||||
|
||||
m_ship_variable_list.ResetContent();
|
||||
m_ship_quantity_variable.ResetContent();
|
||||
|
||||
m_weapon_variable_list.ResetContent();
|
||||
m_weapon_quantity_variable.ResetContent();
|
||||
|
||||
// Add the default entry to both variable quantity ComboBoxes
|
||||
m_ship_quantity_variable.AddString("Don't Use Variables");
|
||||
m_weapon_quantity_variable.AddString("Don't Use Variables");
|
||||
|
||||
int current_entry = 0;
|
||||
int num_sexp_variables = sexp_variable_count();
|
||||
for (i=0; i < num_sexp_variables; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
// Do ships
|
||||
m_ship_variable_list.AddString(Sexp_variables[i].variable_name);
|
||||
|
||||
// Now we set the checkbox.
|
||||
if((dynamic_ship_pool[selected_team][i] > 0) ||
|
||||
(dynamic_ship_variable_pool[selected_team][i] != NOT_SET_BY_SEXP_VARIABLE))
|
||||
{
|
||||
m_ship_variable_list.SetCheck(current_entry, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ship_variable_list.SetCheck(current_entry, FALSE);
|
||||
}
|
||||
|
||||
// Do weapons
|
||||
m_weapon_variable_list.AddString(Sexp_variables[i].variable_name);
|
||||
|
||||
/**Rest of the weapons variable list goes here! */
|
||||
|
||||
// next
|
||||
current_entry++;
|
||||
}
|
||||
|
||||
// Seeing as how we're looping through Sexp_variables we might as well fill the number variable combo boxes
|
||||
else if (Sexp_variables[i].type & SEXP_VARIABLE_NUMBER)
|
||||
{
|
||||
m_ship_quantity_variable.AddString(Sexp_variables[i].variable_name);
|
||||
m_weapon_quantity_variable.AddString(Sexp_variables[i].variable_name);
|
||||
}
|
||||
}
|
||||
|
||||
// If at at the end of all this there are no entries, disable the variables windows.
|
||||
if (!current_entry)
|
||||
{
|
||||
m_ship_variable_list.EnableWindow(false);
|
||||
m_weapon_variable_list.EnableWindow(false);
|
||||
}
|
||||
|
||||
|
||||
// create a checklistbox for each "player" ship type
|
||||
m_ship_list.ResetContent();
|
||||
@@ -148,8 +266,10 @@ void player_start_editor::reset_controls()
|
||||
if (Ship_info[i].flags & SIF_PLAYER_SHIP) {
|
||||
m_ship_list.AddString(Ship_info[i].name);
|
||||
|
||||
// if the ship currently has pool entries, check it
|
||||
if(ship_pool[selected_team][i] > 0){
|
||||
// if the ship currently has pool entries or was set by a variable, check it
|
||||
if((static_ship_pool[selected_team][i] > 0) ||
|
||||
(static_ship_variable_pool[selected_team][i] != NOT_SET_BY_SEXP_VARIABLE))
|
||||
{
|
||||
m_ship_list.SetCheck(ct, TRUE);
|
||||
} else {
|
||||
m_ship_list.SetCheck(ct, FALSE);
|
||||
@@ -175,12 +295,22 @@ void player_start_editor::reset_controls()
|
||||
}
|
||||
|
||||
ct++;
|
||||
} else if (weapon_pool[selected_team][i] > 0) {
|
||||
// not sure if this should be a verbal warning or not, so I'm adding both and making it verbal for now
|
||||
Warning(LOCATION, "Weapon '%s' in weapon pool isn't allowed on player loadout! Resetting count to 0...\n", Weapon_info[i].name);
|
||||
// mprintf(("Weapon '%s' in weapon pool isn't allowed on player loadout! Resetting to 0 count.\n", Weapon_info[i].name));
|
||||
weapon_pool[selected_team][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// be sure that nothing is selected
|
||||
m_ship_list.SetCurSel(-1);
|
||||
m_ship_variable_list.SetCurSel(-1);
|
||||
m_ship_quantity_variable.SetCurSel(-1);
|
||||
m_weapon_list.SetCurSel(-1);
|
||||
m_weapon_variable_list.SetCurSel(-1);
|
||||
m_weapon_quantity_variable.SetCurSel(-1);
|
||||
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
@@ -232,34 +362,61 @@ BOOL player_start_editor::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
|
||||
// ship list changed
|
||||
void player_start_editor::OnSelchangeShipList()
|
||||
{
|
||||
{
|
||||
int selected;
|
||||
int si_index;
|
||||
int ship_index;
|
||||
char ship_name[255] = "";
|
||||
char ship_usage_buff[10];
|
||||
|
||||
// If the ShipList is selected the variable ship list should be deselected
|
||||
m_ship_variable_list.SetCurSel(-1);
|
||||
|
||||
// determine if we've selected something
|
||||
selected = m_ship_list.GetCurSel();
|
||||
if (selected != -1) {
|
||||
if (selected != -1)
|
||||
{
|
||||
// lookup the ship
|
||||
m_ship_list.GetText(m_ship_list.GetCurSel(), ship_name);
|
||||
si_index = ship_info_lookup(ship_name);
|
||||
ship_index = ship_info_lookup(ship_name);
|
||||
|
||||
// if we have a valid ship type
|
||||
if(si_index >= 0){
|
||||
if(ship_index >= 0)
|
||||
{
|
||||
// if this item is checked
|
||||
if(m_ship_list.GetCheck(selected)) {
|
||||
if(ship_pool[selected_team][si_index] <= 0){
|
||||
ship_pool[selected_team][si_index] = 5;
|
||||
m_ship_pool = 5;
|
||||
} else {
|
||||
m_ship_pool = ship_pool[selected_team][si_index];
|
||||
if(m_ship_list.GetCheck(selected))
|
||||
{
|
||||
|
||||
if (static_ship_variable_pool[selected_team][ship_index] == NOT_SET_BY_SEXP_VARIABLE)
|
||||
{
|
||||
if (static_ship_pool[selected_team][ship_index] <= 0)
|
||||
{
|
||||
static_ship_pool[selected_team][ship_index] = 5;
|
||||
}
|
||||
m_ship_pool = static_ship_pool[selected_team][ship_index];
|
||||
// Set the ship variable ComboBox to reflect that we are not using variables for this ship
|
||||
m_ship_quantity_variable.SetCurSel(0);
|
||||
}
|
||||
// If the number of ships was set by a variable
|
||||
else
|
||||
{
|
||||
Assert (Sexp_variables[static_ship_variable_pool[selected_team][ship_index]].type & SEXP_VARIABLE_NUMBER);
|
||||
m_ship_pool = atoi(Sexp_variables[static_ship_variable_pool[selected_team][ship_index]].text);
|
||||
int selected_variable = GetTypedVariableIndex(static_ship_variable_pool[selected_team][ship_index], false);
|
||||
m_ship_quantity_variable.SetCurSel(selected_variable + VARIABLES_COMBO_OFFSET);
|
||||
}
|
||||
}
|
||||
// otherwise zero the count
|
||||
else {
|
||||
ship_pool[selected_team][si_index] = 0;
|
||||
else
|
||||
{
|
||||
static_ship_pool[selected_team][ship_index] = 0;
|
||||
m_ship_pool = 0;
|
||||
}
|
||||
m_ship_quantity_variable.SetCurSel(0);
|
||||
}
|
||||
|
||||
// set the number used in wings
|
||||
sprintf(ship_usage_buff, "%d", ship_usage[selected_team][ship_index]);
|
||||
m_ships_used_in_wings.SetWindowText(ship_usage_buff);
|
||||
|
||||
} else {
|
||||
Int3();
|
||||
}
|
||||
@@ -269,12 +426,130 @@ void player_start_editor::OnSelchangeShipList()
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
void player_start_editor::OnSelchangeShipVariablesList()
|
||||
{
|
||||
// If the variable list is selected the ship list should be deselected
|
||||
m_ship_list.SetCurSel(-1);
|
||||
|
||||
//Have we selected something?
|
||||
int selection = m_ship_variable_list.GetCurSel();
|
||||
if (selection != -1)
|
||||
{
|
||||
// Is this a valid SEXP variable
|
||||
char sexp_variable_name[TOKEN_LENGTH];
|
||||
m_ship_variable_list.GetText(selection, sexp_variable_name);
|
||||
int sexp_index = get_index_sexp_variable_name(sexp_variable_name);
|
||||
|
||||
if (sexp_index > -1)
|
||||
{
|
||||
// The selection should the selection'th string variable in Sexp_variables[]
|
||||
Assert(selection == GetTypedVariableIndex(sexp_index, true));
|
||||
|
||||
// Is this item checked?
|
||||
if (m_ship_variable_list.GetCheck(selection))
|
||||
{
|
||||
if (dynamic_ship_variable_pool[selected_team][sexp_index] == NOT_SET_BY_SEXP_VARIABLE)
|
||||
{
|
||||
if (dynamic_ship_pool[selected_team][sexp_index] <= 0)
|
||||
{
|
||||
dynamic_ship_pool[selected_team][sexp_index] = 5;
|
||||
}
|
||||
m_ship_pool = dynamic_ship_pool[selected_team][sexp_index];
|
||||
m_ship_quantity_variable.SetCurSel(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert (Sexp_variables[dynamic_ship_variable_pool[selected_team][sexp_index]].type & SEXP_VARIABLE_NUMBER);
|
||||
m_ship_pool = atoi(Sexp_variables[dynamic_ship_variable_pool[selected_team][sexp_index]].text);
|
||||
int selected_variable = GetTypedVariableIndex(dynamic_ship_variable_pool[selected_team][sexp_index], false);
|
||||
m_ship_quantity_variable.SetCurSel(selected_variable + VARIABLES_COMBO_OFFSET);
|
||||
}
|
||||
}
|
||||
// Set everything to zero
|
||||
else
|
||||
{
|
||||
dynamic_ship_pool[selected_team][sexp_index] = NOT_SET_BY_SEXP_VARIABLE;
|
||||
m_ship_pool = 0;
|
||||
m_ship_quantity_variable.SetCurSel(0);
|
||||
}
|
||||
|
||||
// It might be nice to have FRED work out if any ships of the class represented by the variable are in the wings
|
||||
// but for now just set it to zero
|
||||
m_ships_used_in_wings.SetWindowText("0");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Int3();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// update stuff
|
||||
UpdateData(FALSE);
|
||||
|
||||
}
|
||||
|
||||
void player_start_editor::OnSelchangeShipVariablesCombo()
|
||||
{
|
||||
// Get the new selection
|
||||
char variable_name[TOKEN_LENGTH];
|
||||
char name[255] = "";
|
||||
bool update_static_pool = false;
|
||||
bool update_dynamic_pool = false;
|
||||
|
||||
m_ship_quantity_variable.GetLBText(m_ship_quantity_variable.GetCurSel(), variable_name);
|
||||
int sexp_index = get_index_sexp_variable_name(variable_name);
|
||||
|
||||
Assert ((sexp_index > -1) || (!strcmp("Don't Use Variables", variable_name)));
|
||||
|
||||
// See if the ship_list was selected
|
||||
int ship_index = GetSelectedShipListIndex();
|
||||
if (ship_index >= 0)
|
||||
{
|
||||
static_ship_variable_pool[selected_team][ship_index] = sexp_index;
|
||||
update_static_pool = true;
|
||||
}
|
||||
|
||||
// Maybe it's the ship_variables_list that is actually selected
|
||||
int ship_variable_index = GetSelectedShipVariableListIndex();
|
||||
if (ship_variable_index >= 0 )
|
||||
{
|
||||
dynamic_ship_variable_pool[selected_team][ship_variable_index] = sexp_index;
|
||||
update_dynamic_pool = true;
|
||||
}
|
||||
|
||||
|
||||
// Update the ship_pool
|
||||
if (update_static_pool || update_dynamic_pool)
|
||||
{
|
||||
int new_quantity = 5;
|
||||
if (sexp_index > -1)
|
||||
{
|
||||
Assert (Sexp_variables[sexp_index].type & SEXP_VARIABLE_NUMBER);
|
||||
new_quantity = atoi(Sexp_variables[sexp_index].text);
|
||||
}
|
||||
if (update_static_pool)
|
||||
{
|
||||
static_ship_pool[selected_team][ship_index] = new_quantity;
|
||||
}
|
||||
m_ship_pool = new_quantity;
|
||||
}
|
||||
|
||||
// update stuff
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
// weapon list changed
|
||||
void player_start_editor::OnSelchangeWeaponList()
|
||||
{
|
||||
int selected;
|
||||
int wi_index;
|
||||
char weapon_name[255] = "";
|
||||
char weapon_usage_buff[10];
|
||||
|
||||
// Deselect the variables list when this one is selected
|
||||
m_weapon_quantity_variable.SetCurSel(-1);
|
||||
|
||||
// determine if we've selected something
|
||||
selected = m_weapon_list.GetCurSel();
|
||||
@@ -298,7 +573,11 @@ void player_start_editor::OnSelchangeWeaponList()
|
||||
else {
|
||||
weapon_pool[selected_team][wi_index] = 0;
|
||||
m_weapon_pool = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// set the number used in wings
|
||||
sprintf(weapon_usage_buff, "%d", weapon_usage[selected_team][wi_index]);
|
||||
m_weapons_used_in_wings.SetWindowText(weapon_usage_buff);
|
||||
} else {
|
||||
Int3();
|
||||
}
|
||||
@@ -324,15 +603,82 @@ void player_start_editor::OnOK()
|
||||
Entry_delay_time = i2f(m_delay);
|
||||
|
||||
// store ship pools
|
||||
for(i=0; i<MAX_TVT_TEAMS; i++){
|
||||
Team_data[i].number_choices = 0;
|
||||
for(idx=0; idx<Num_ship_classes; idx++){
|
||||
// if we have ships here
|
||||
if(ship_pool[i][idx] > 0){
|
||||
Team_data[i].ship_count[Team_data[i].number_choices] = ship_pool[i][idx];
|
||||
Team_data[i].ship_list[Team_data[i].number_choices++] = idx;
|
||||
for(i=0; i<MAX_TVT_TEAMS; i++)
|
||||
{
|
||||
int num_choices = 0;
|
||||
|
||||
// First look through the variables list and write out anything there
|
||||
int num_sexp_variables = sexp_variable_count();
|
||||
for (idx=0; idx < num_sexp_variables; idx++)
|
||||
{
|
||||
// As soon as we come across a sexp_variable we are using
|
||||
if (dynamic_ship_pool[i][idx] != NOT_SET_BY_SEXP_VARIABLE)
|
||||
{
|
||||
Assert (Sexp_variables[idx].type & SEXP_VARIABLE_STRING);
|
||||
int ship_class = ship_info_lookup(Sexp_variables[idx].text);
|
||||
|
||||
// If the variable doesn't actually contain a valid ship class name. Warn the player and skip to the next one
|
||||
if (ship_class < 0)
|
||||
{
|
||||
char buffer[256];
|
||||
sprintf(buffer,
|
||||
"Sexp Variable %s holds the value %s. This is not a valid ship class. Skipping this entry",
|
||||
Sexp_variables[idx].variable_name,
|
||||
Sexp_variables[idx].text
|
||||
);
|
||||
MessageBox(buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy the variable to Team_data
|
||||
strcpy(Team_data[i].ship_list_variables[num_choices], Sexp_variables[idx].variable_name);
|
||||
// Copy the class to Team_data
|
||||
Team_data[i].ship_list[num_choices] = ship_class;
|
||||
|
||||
// Now we need to set the number of this class available
|
||||
if (dynamic_ship_variable_pool[i][idx] == NOT_SET_BY_SEXP_VARIABLE)
|
||||
{
|
||||
Team_data[i].ship_count[num_choices] = dynamic_ship_pool[i][idx];
|
||||
strcpy(Team_data[i].ship_count_variables[num_choices], "");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(Team_data[i].ship_count_variables[num_choices], Sexp_variables[dynamic_ship_variable_pool[i][idx]].variable_name);
|
||||
Assert (Sexp_variables[dynamic_ship_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
|
||||
Team_data[i].ship_count[num_choices] = atoi(Sexp_variables[dynamic_ship_variable_pool[i][idx]].text);
|
||||
}
|
||||
|
||||
num_choices++;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we deal with the loadout ships that are statically assigned by class
|
||||
|
||||
for(idx=0; idx<Num_ship_classes; idx++)
|
||||
{
|
||||
// if we have ships here
|
||||
if(static_ship_pool[i][idx] > -1)
|
||||
{
|
||||
Team_data[i].ship_list[num_choices] = idx;
|
||||
strcpy(Team_data[i].ship_list_variables[num_choices], "");
|
||||
|
||||
// Now set the number of this class available
|
||||
if (static_ship_variable_pool[i][idx] == NOT_SET_BY_SEXP_VARIABLE)
|
||||
{
|
||||
Team_data[i].ship_count[num_choices] = static_ship_pool[i][idx];
|
||||
strcpy(Team_data[i].ship_count_variables[num_choices], "");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(Team_data[i].ship_count_variables[num_choices], Sexp_variables[static_ship_variable_pool[i][idx]].variable_name);
|
||||
Assert (Sexp_variables[static_ship_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
|
||||
Team_data[i].ship_count[num_choices] = atoi(Sexp_variables[static_ship_variable_pool[i][idx]].text);
|
||||
}
|
||||
|
||||
num_choices++;
|
||||
}
|
||||
}
|
||||
Team_data[i].number_choices = num_choices;
|
||||
}
|
||||
|
||||
// store weapon pools
|
||||
@@ -347,30 +693,82 @@ void player_start_editor::OnOK()
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
// Returns the ship_info index of the selected and checked ship_list item or -1 if nothing is checked or
|
||||
// the ship is invalid
|
||||
int player_start_editor::GetSelectedShipListIndex()
|
||||
{
|
||||
char name[255] = "";
|
||||
int selected = m_ship_list.GetCurSel();
|
||||
if((selected != -1) && m_ship_list.GetCheck(selected))
|
||||
{
|
||||
// lookup the ship
|
||||
m_ship_list.GetText(m_ship_list.GetCurSel(), name);
|
||||
int ship_index = ship_info_lookup(name);
|
||||
return ship_index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns the Sexp_variables index of the selected and checked ship_variables_list item or -1 if nothing is checked
|
||||
// or the ship is invalid
|
||||
int player_start_editor::GetSelectedShipVariableListIndex()
|
||||
{
|
||||
char name[255] = "";
|
||||
|
||||
// Try the ship_variables_list
|
||||
int selected = m_ship_variable_list.GetCurSel();
|
||||
if((selected != -1) && m_ship_variable_list.GetCheck(selected))
|
||||
{
|
||||
//lookup the variable
|
||||
m_ship_variable_list.GetText(m_ship_variable_list.GetCurSel(), name);
|
||||
int sexp_index = get_index_sexp_variable_name(name);
|
||||
return sexp_index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Updates the Sexp_variable in a variable combobox to the value supplied
|
||||
void player_start_editor::UpdateQuantityVariable(CComboBox *variable_list, int pool_value)
|
||||
{
|
||||
char variable_name[TOKEN_LENGTH];
|
||||
variable_list->GetLBText(variable_list->GetCurSel(), variable_name);
|
||||
int variable_index = get_index_sexp_variable_name(variable_name);
|
||||
if (variable_index > -1)
|
||||
{
|
||||
char variable_value[TOKEN_LENGTH];
|
||||
sprintf(variable_value, "%d", pool_value);
|
||||
Assert (Sexp_variables[variable_index].type & SEXP_VARIABLE_NUMBER);
|
||||
sexp_fred_modify_variable(variable_value, variable_name, variable_index, SEXP_VARIABLE_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
// ship pool count change
|
||||
void player_start_editor::OnUpdateShipPool()
|
||||
{
|
||||
int selected, si_index;
|
||||
char ship_name[255] = "";
|
||||
|
||||
if (!dlg_inited){
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
// if we have a ship selected and checked, update the pool
|
||||
selected = m_ship_list.GetCurSel();
|
||||
if((selected != -1) && m_ship_list.GetCheck(selected)){
|
||||
// lookup the ship
|
||||
m_ship_list.GetText(m_ship_list.GetCurSel(), ship_name);
|
||||
si_index = ship_info_lookup(ship_name);
|
||||
|
||||
// if we have a valid ship type
|
||||
if(si_index >= 0){
|
||||
ship_pool[selected_team][si_index] = m_ship_pool;
|
||||
}
|
||||
};
|
||||
int si_index = GetSelectedShipListIndex();
|
||||
// Update the pool if we have a valid ship type
|
||||
if(si_index >= 0)
|
||||
{
|
||||
static_ship_pool[selected_team][si_index] = m_ship_pool;
|
||||
// If this value came from a variable we should update its value
|
||||
UpdateQuantityVariable(&m_ship_quantity_variable, m_ship_pool);
|
||||
return ;
|
||||
}
|
||||
|
||||
// Maybe it's the ship_variables_list that is actually selected
|
||||
int sexp_index = GetSelectedShipVariableListIndex();
|
||||
// if we have a valid sexp_variable
|
||||
if(sexp_index >= 0)
|
||||
{
|
||||
dynamic_ship_pool[selected_team][sexp_index] = m_ship_pool;
|
||||
UpdateQuantityVariable(&m_ship_quantity_variable, m_ship_pool);
|
||||
}
|
||||
}
|
||||
|
||||
// weapon pool count change
|
||||
@@ -396,5 +794,45 @@ void player_start_editor::OnUpdateWeaponPool()
|
||||
if(wi_index >= 0){
|
||||
weapon_pool[selected_team][wi_index] = m_weapon_pool;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Given a Sexp_Variable index, returns the index this would have in Sexp_variables if the array only had variables of
|
||||
// a certain type or -1 if the supplied index wasn't of the supplied type.
|
||||
int player_start_editor::GetTypedVariableIndex(int sexp_variables_index, bool string_variable)
|
||||
{
|
||||
// Loop through Sexp_variables until we have found the one corresponding to the argument
|
||||
int count = 0;
|
||||
for (int i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable && (Sexp_variables[i].type & SEXP_VARIABLE_NUMBER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (!string_variable && (Sexp_variables[i].type & SEXP_VARIABLE_STRING))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// The type is correct at least. Now lets see if the index is correct
|
||||
if (i == sexp_variables_index)
|
||||
{
|
||||
return count ;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void player_start_editor::OnSelchangeWeaponVariablesList()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
|
||||
}
|
||||
|
||||
void player_start_editor::OnSelchangeWeaponVariablesCombo()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
|
||||
}
|
||||
|
||||
Loaded 100 of 515 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user