mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
460
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f5810732a | ||
|
|
f4bfec5029 | ||
|
|
c18f775962 | ||
|
|
608dcb6b44 | ||
|
|
b4b23e266b | ||
|
|
65e2aa88b3 | ||
|
|
fe0c6a629a | ||
|
|
730c62af81 | ||
|
|
13d4ebaceb | ||
|
|
ed6a780898 | ||
|
|
f0b9929cd3 | ||
|
|
f315caad95 | ||
|
|
b5a47e651f | ||
|
|
d49299225c | ||
|
|
3b0bb79d79 | ||
|
|
daacdc0035 | ||
|
|
39df9ef90e | ||
|
|
fc080cccbd | ||
|
|
0c07ad9d71 | ||
|
|
7d329bbbc6 | ||
|
|
17a449529f | ||
|
|
73f0addc42 | ||
|
|
0ba1583d90 | ||
|
|
2436697f2c | ||
|
|
0e10100aad | ||
|
|
60bcdefac0 | ||
|
|
5d8ac3cc11 | ||
|
|
e0bc2f188b | ||
|
|
d13bbdd534 | ||
|
|
44b09d137f | ||
|
|
4439edcb4d | ||
|
|
a9ddeda40e | ||
|
|
d606e4d952 | ||
|
|
2fa8a0bd84 | ||
|
|
f9d178d46b | ||
|
|
989235936e | ||
|
|
6df9c73a4c | ||
|
|
d794eb6e77 | ||
|
|
e5c06c9554 | ||
|
|
bc00b79922 | ||
|
|
e1e86667b3 | ||
|
|
881f787ac8 | ||
|
|
88d5bed064 | ||
|
|
d9b1659efc | ||
|
|
f6408113f2 | ||
|
|
6075c17255 | ||
|
|
da9f71dac0 | ||
|
|
03f1344794 | ||
|
|
59e9d7cb0c | ||
|
|
910595880a | ||
|
|
9f07e43455 | ||
|
|
7b8c156980 | ||
|
|
f8c11ccd2e | ||
|
|
7e36dc8afe | ||
|
|
b1ad89a9fa | ||
|
|
4d9b1a7674 | ||
|
|
72f3871b7b | ||
|
|
7906ff460a | ||
|
|
1eb1923751 | ||
|
|
6d1931bf99 | ||
|
|
f75cb1edd3 | ||
|
|
48586bc857 | ||
|
|
3adb861640 | ||
|
|
7b1f407c22 | ||
|
|
ed5b4b9b5a | ||
|
|
b63ddf08bb | ||
|
|
816d8e5415 | ||
|
|
e7e43e9466 | ||
|
|
48e630dfd1 | ||
|
|
00f2ddc8da | ||
|
|
c6d93275c2 | ||
|
|
e2ce0bea9b | ||
|
|
a98fd2cb54 | ||
|
|
5444e81fab | ||
|
|
83276a355d | ||
|
|
98606b37e4 | ||
|
|
c4a7e9694f | ||
|
|
2db1758ec2 | ||
|
|
cff070dc07 | ||
|
|
7b3ad77f36 | ||
|
|
d67e79a44b | ||
|
|
977190b358 | ||
|
|
ba3237604e | ||
|
|
a94550ee1a | ||
|
|
d55a6632ca | ||
|
|
680cb580cd | ||
|
|
2f74940f6a | ||
|
|
3dbe27e772 | ||
|
|
72d876bd4b | ||
|
|
e22398bec8 | ||
|
|
11661db6ab | ||
|
|
6164004df3 | ||
|
|
505aa3cdd1 | ||
|
|
cfeb8da3d3 | ||
|
|
ec7945276a | ||
|
|
2bf19afb94 | ||
|
|
34b38f63fa | ||
|
|
8f11d2e11c | ||
|
|
e4036b9e5a | ||
|
|
c86e94a4e7 | ||
|
|
a6475f59f0 | ||
|
|
69ebdd0417 | ||
|
|
9444b9ff9f | ||
|
|
4c7470fbf2 | ||
|
|
8d3eeec238 | ||
|
|
da0ff33fcb | ||
|
|
764b4b8422 | ||
|
|
a5d22589ec | ||
|
|
6a6940e0f0 | ||
|
|
2dfd9936d8 | ||
|
|
fb0847f4b5 | ||
|
|
7b959b09d2 | ||
|
|
f4b713c56c | ||
|
|
d32d3f55d1 | ||
|
|
1ebb72ee88 | ||
|
|
a988d0e972 | ||
|
|
8aa2f3b099 | ||
|
|
8365f0abb7 | ||
|
|
4afe739cbb | ||
|
|
2c469e0c88 | ||
|
|
822e61665d | ||
|
|
5f5616c0fa | ||
|
|
b38f6aa014 | ||
|
|
d88e6f5a88 | ||
|
|
760b601a95 | ||
|
|
0bf116b0cc | ||
|
|
2180296f9c | ||
|
|
b84fe72778 | ||
|
|
c5e460a90d | ||
|
|
271d3f97bd | ||
|
|
e70d6a89ee | ||
|
|
d1a8e66fce | ||
|
|
964f8f5ef1 | ||
|
|
8ebe012e12 | ||
|
|
92f142452a | ||
|
|
cfb80cfd16 | ||
|
|
39313ed8d7 | ||
|
|
1da2c03cef | ||
|
|
f9dbe4941b | ||
|
|
46319f1b4e | ||
|
|
8653d824cd | ||
|
|
3e7e7cde00 | ||
|
|
f63667b29e | ||
|
|
b42fc2122a | ||
|
|
3ca4ba16fe | ||
|
|
36c14e21e8 | ||
|
|
ce1ea75714 | ||
|
|
30373e9138 | ||
|
|
9e460332a6 | ||
|
|
473e2588bf | ||
|
|
6350110b21 | ||
|
|
0c92134de5 | ||
|
|
681dd9b871 | ||
|
|
213422076e | ||
|
|
41aff9d094 | ||
|
|
337ca94b53 | ||
|
|
13f5037b0c | ||
|
|
221d96f5d6 | ||
|
|
bd6441004b | ||
|
|
14b6e86e5d | ||
|
|
4824428971 | ||
|
|
6af8d4ccbd | ||
|
|
d2d730138f | ||
|
|
7d67d16094 | ||
|
|
3f4eb05f3e | ||
|
|
49f8660f7a | ||
|
|
2833ae150f | ||
|
|
8470548376 | ||
|
|
ea6bd1d9a4 | ||
|
|
18c0314652 | ||
|
|
98165dbce5 | ||
|
|
60bf6dec2c | ||
|
|
252ab4e282 | ||
|
|
bd93c8e661 | ||
|
|
0e4056f795 | ||
|
|
8f877d3826 | ||
|
|
6025ab8318 | ||
|
|
679cbe2526 | ||
|
|
fa0140fea7 | ||
|
|
5343503385 | ||
|
|
edd2cb89c7 | ||
|
|
6a2327088f | ||
|
|
f798c5b916 | ||
|
|
76115122a0 | ||
|
|
b4cb602e31 | ||
|
|
d26b5310e7 | ||
|
|
cdb65c154c | ||
|
|
fd0b612c64 | ||
|
|
07d83d473c | ||
|
|
1662a3c317 | ||
|
|
c70e4a0e7e | ||
|
|
d82479fb14 | ||
|
|
be90059b65 | ||
|
|
04abbf55ed | ||
|
|
1bc925ee9b | ||
|
|
d558c2d632 | ||
|
|
1c799653ce | ||
|
|
35af3a8b73 | ||
|
|
8586a319b0 | ||
|
|
15748adfda | ||
|
|
6b0f73e427 | ||
|
|
1d744d347c | ||
|
|
9332311b57 | ||
|
|
47e9c01ce6 | ||
|
|
5f176173bd | ||
|
|
8d6538d7a9 | ||
|
|
cc9e0a1096 | ||
|
|
223e78926f | ||
|
|
6679b623e4 | ||
|
|
8aa2d0e212 | ||
|
|
1dc449ffa6 | ||
|
|
6369cdec7c | ||
|
|
31fe15c4f4 | ||
|
|
dd384e7f1d | ||
|
|
c8fa5803b9 | ||
|
|
b57a608177 | ||
|
|
f9f7a23b4d | ||
|
|
7e88feff16 | ||
|
|
c6bf5e927b | ||
|
|
ad1ede7b74 | ||
|
|
3c812915e4 | ||
|
|
62963d23ec | ||
|
|
dc71bb47d7 | ||
|
|
b79a3385a1 | ||
|
|
dfac2e98e9 | ||
|
|
37f2c8249d | ||
|
|
5fa5a199bf | ||
|
|
c00a2897f4 | ||
|
|
ad4b1ca965 | ||
|
|
f1f784f237 | ||
|
|
2c307ef5d3 | ||
|
|
6f24d8d079 | ||
|
|
9fc94ab873 | ||
|
|
728ee2921f | ||
|
|
caea0f56ed | ||
|
|
94c9e1b494 | ||
|
|
7dd1788aee | ||
|
|
77934c7215 | ||
|
|
4a7c69082e | ||
|
|
74c4075aa6 | ||
|
|
008d66c706 | ||
|
|
1c385901cb | ||
|
|
5b9b06ab84 | ||
|
|
f8da2cdc83 | ||
|
|
b790d6a388 | ||
|
|
a7ba3fa373 | ||
|
|
6d7c786a38 | ||
|
|
49d5356043 | ||
|
|
572565c7bc | ||
|
|
c090ee5405 | ||
|
|
5597b56139 | ||
|
|
c72a062a84 | ||
|
|
422753976f | ||
|
|
374383bacb | ||
|
|
adfce4ec60 | ||
|
|
08faf52871 | ||
|
|
d99121cd52 | ||
|
|
6ff292a43c | ||
|
|
09f4f63be4 | ||
|
|
2d67fd3ef8 | ||
|
|
5666eb5014 | ||
|
|
8542e9e113 | ||
|
|
699c9e8d52 | ||
|
|
5b45a89287 | ||
|
|
741fc311cd | ||
|
|
aaa9c779c0 | ||
|
|
bfae614189 | ||
|
|
cb956961f6 | ||
|
|
6d2ebd1ed7 | ||
|
|
d7e6187ba8 | ||
|
|
62f6ee86ef | ||
|
|
56ae91c973 | ||
|
|
dfc8cbd1c9 | ||
|
|
77e61af23c | ||
|
|
7b80b0c564 | ||
|
|
a98d3bb064 | ||
|
|
741ee07249 | ||
|
|
04cefad927 | ||
|
|
3d68476505 | ||
|
|
81c63929b5 | ||
|
|
d6d03fbb14 | ||
|
|
9acd25bc28 | ||
|
|
7e00a8b10f | ||
|
|
bb0df2dc43 | ||
|
|
38f858198b | ||
|
|
a83307402a | ||
|
|
097148c2c2 | ||
|
|
fbf8a931c4 | ||
|
|
32d951b27a | ||
|
|
630e6c3e96 | ||
|
|
72ed33502b | ||
|
|
d3806b2107 | ||
|
|
c9a481f4f3 | ||
|
|
0a02f677fe | ||
|
|
d55e4343f9 | ||
|
|
e902934e89 | ||
|
|
26395f7c12 | ||
|
|
de92fe25e3 | ||
|
|
c72fa0917b | ||
|
|
bc0f47269d | ||
|
|
94469dc43f | ||
|
|
ce335dbcc2 | ||
|
|
6660d21f7e | ||
|
|
e622d81e89 | ||
|
|
10c8e16cda | ||
|
|
25029bfdf1 | ||
|
|
2255616ed5 | ||
|
|
62ab705d75 | ||
|
|
77fc335580 | ||
|
|
981b01eea2 | ||
|
|
366dc3749c | ||
|
|
e693367dd0 | ||
|
|
da53960003 | ||
|
|
687c1ba4f7 | ||
|
|
d901470880 | ||
|
|
7e74153a3d | ||
|
|
6cf75b77dc | ||
|
|
3ec0a9c35e | ||
|
|
519f60a63b | ||
|
|
252da89782 | ||
|
|
0f1b3fd6c2 | ||
|
|
58722425a3 | ||
|
|
211110d415 | ||
|
|
61a8aa5592 | ||
|
|
0692286bba | ||
|
|
72dae916a9 | ||
|
|
189ad9f694 | ||
|
|
b9f9fa0f73 | ||
|
|
dc7e88c888 | ||
|
|
b5dae2a56e | ||
|
|
969bfd0bdd | ||
|
|
63e8ae53c5 | ||
|
|
d57aaac8e4 | ||
|
|
ab981bd415 | ||
|
|
df7c91f3e7 | ||
|
|
ee73694cc8 | ||
|
|
65dcfe0a7c | ||
|
|
ae8f8baade | ||
|
|
86fcdb1502 | ||
|
|
b71fc4595c | ||
|
|
471402ec5d | ||
|
|
97fdca6b52 | ||
|
|
b50833e6fb | ||
|
|
4429cbb21c | ||
|
|
4a6d8573a0 | ||
|
|
2c6039759c | ||
|
|
f3a0d56a85 | ||
|
|
243aac1667 | ||
|
|
19fbe05cee | ||
|
|
e581a3b8a3 | ||
|
|
67a2d99a9b | ||
|
|
569f1ee237 | ||
|
|
e9a8b9d8a2 | ||
|
|
0efb98d4a9 | ||
|
|
ec99bf9c03 | ||
|
|
bd6ff021fd | ||
|
|
69213c3338 | ||
|
|
0bffac7615 | ||
|
|
ba089bd95e | ||
|
|
0a1519284f | ||
|
|
877a138192 | ||
|
|
8a34ceef91 | ||
|
|
d638cacc51 | ||
|
|
871317b5bd | ||
|
|
9b7a87d4c5 | ||
|
|
3b07636a16 | ||
|
|
8840d238d7 | ||
|
|
95128dd734 | ||
|
|
30866afbd6 | ||
|
|
2b43677c82 | ||
|
|
94a542a2a3 | ||
|
|
5c064afd95 | ||
|
|
6ee41c06d8 | ||
|
|
58fa411ad3 | ||
|
|
08c2449672 | ||
|
|
726af82c56 | ||
|
|
c11dce4a92 | ||
|
|
0121eb6123 | ||
|
|
8a325362f6 | ||
|
|
4eb0e41142 | ||
|
|
5528e4e42d | ||
|
|
968695f851 | ||
|
|
8f00c6e842 | ||
|
|
8a9edb1215 | ||
|
|
1c9e47ad3d | ||
|
|
74fd3c0637 | ||
|
|
fe0f0558c2 | ||
|
|
11ded47bd5 | ||
|
|
f8801446db | ||
|
|
7492615a31 | ||
|
|
53cfc1eae4 | ||
|
|
252facb6c4 | ||
|
|
65417be571 | ||
|
|
0da41b3943 | ||
|
|
97f9a6c91b | ||
|
|
10cd82456d | ||
|
|
7878ba0d19 | ||
|
|
a6879a1b40 | ||
|
|
cf7706eb1c | ||
|
|
09ed127d06 | ||
|
|
77c3c79143 | ||
|
|
62b74b8743 | ||
|
|
4d99a3b8b3 | ||
|
|
3a9a840633 | ||
|
|
86f67c3c84 | ||
|
|
28bb3bf914 | ||
|
|
bd4b116188 | ||
|
|
0a429e8a32 | ||
|
|
f70253e219 | ||
|
|
e901e44418 | ||
|
|
651268eeea | ||
|
|
9b7c32d0c1 | ||
|
|
d014e53505 | ||
|
|
00b0a80ad9 | ||
|
|
4a7109e1d5 | ||
|
|
1484ddbe77 | ||
|
|
48b03a1789 | ||
|
|
e790cf209a | ||
|
|
1eea298fe1 | ||
|
|
1de63cc881 | ||
|
|
c7be4734d3 | ||
|
|
fbc2a2dab2 | ||
|
|
e5be2372e1 | ||
|
|
9c69e11fe5 | ||
|
|
0173f44070 | ||
|
|
45559c13a9 | ||
|
|
34888cb1a6 | ||
|
|
b77b425f2f | ||
|
|
49b5c10295 | ||
|
|
0396d5670b | ||
|
|
bb6c00a516 | ||
|
|
4d0703ad98 | ||
|
|
27e91d8f6c | ||
|
|
3c4ab2eef1 | ||
|
|
4e7f29ea88 | ||
|
|
793a3d8dd3 | ||
|
|
49abb88385 | ||
|
|
4c2ed1501e | ||
|
|
6b425c1e6b | ||
|
|
978a58dba2 | ||
|
|
3de05aefef | ||
|
|
da951e8be4 | ||
|
|
483a6096bb | ||
|
|
0ac810e7f0 | ||
|
|
0de1e55fb7 | ||
|
|
3827bb9783 | ||
|
|
69013f1d41 | ||
|
|
3ac7864ac6 | ||
|
|
35a654660f | ||
|
|
f975edd343 | ||
|
|
9219712ff0 | ||
|
|
ead6cd9825 | ||
|
|
a32c5dad27 | ||
|
|
34d4ed5dba | ||
|
|
eb012584d6 | ||
|
|
7cadce113d | ||
|
|
15dc45cc0a | ||
|
|
3c41b56449 | ||
|
|
c667668c17 | ||
|
|
8d4643bc7a |
No files matched your search
@@ -0,0 +1,182 @@
|
||||
version: 2
|
||||
|
||||
references:
|
||||
container_config: &container_config
|
||||
docker:
|
||||
- image: "debian:stretch"
|
||||
working_directory: /root/build
|
||||
|
||||
restore_repo: &restore_repo
|
||||
restore_cache:
|
||||
keys:
|
||||
- source-repo-{{ .Branch }}-{{ .Revision }}
|
||||
- source-repo-{{ .Branch }}
|
||||
- source-repo
|
||||
|
||||
cmake_configure: &cmake_configure
|
||||
run:
|
||||
name: Creating Build Files
|
||||
command: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
|
||||
if [[ "$CC" =~ ^clang.*$ ]]; then
|
||||
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
|
||||
fi
|
||||
|
||||
eval $CC --version
|
||||
|
||||
export CXXFLAGS
|
||||
export CFLAGS
|
||||
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
|
||||
eval $CMAKE -DCMAKE_BUILD_TYPE=$CONFIGURATION -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON ..
|
||||
|
||||
compile: &compile
|
||||
run:
|
||||
name: Compiling Source code
|
||||
command: |
|
||||
cd build
|
||||
ninja -k 20 all
|
||||
|
||||
run_tests: &run_tests
|
||||
run:
|
||||
name: Run unit tests
|
||||
command: |
|
||||
./build/bin/unittests --gtest_shuffle
|
||||
|
||||
compile_steps: &compile_steps
|
||||
steps:
|
||||
- *restore_repo
|
||||
- *cmake_configure
|
||||
- *compile
|
||||
- *run_tests
|
||||
jobs:
|
||||
checkout_code:
|
||||
<<: *container_config
|
||||
steps:
|
||||
- run:
|
||||
name: Installing Git
|
||||
command: 'apt-get update && apt-get -yq install git'
|
||||
- *restore_repo
|
||||
- checkout
|
||||
- run:
|
||||
name: Updating submodules
|
||||
command: 'git submodule update --init --recursive'
|
||||
- save_cache:
|
||||
key: source-repo-{{ .Branch }}-{{ .Revision }}
|
||||
paths:
|
||||
- .
|
||||
|
||||
build_gcc_lowest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_gcc_lowest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
build_gcc_latest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_gcc_latest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_latest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang-8
|
||||
CXX: clang++-8
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_latest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang-8
|
||||
CXX: clang++-8
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_lowest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_lowest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
build_test:
|
||||
jobs:
|
||||
- checkout_code
|
||||
- build_gcc_lowest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_gcc_lowest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_gcc_latest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_gcc_latest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_latest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_latest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_lowest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_lowest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
@@ -47,6 +47,7 @@ Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^(<.*\.(h|hh|hpp)>)$' # Includes of external libraries
|
||||
Priority: 4
|
||||
|
||||
+2
-11
@@ -5,6 +5,7 @@ cache:
|
||||
directories:
|
||||
- $HOME/cmake-3.8
|
||||
- $HOME/.ccache
|
||||
- $HOME/curl_cache
|
||||
addons:
|
||||
apt:
|
||||
packages: &global_deps
|
||||
@@ -42,7 +43,7 @@ env:
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
|
||||
secure: "q619+eQTe7lv8UVphK4OIzU8Jw84KBbVkuprN2sWIubRcV3IbZr2+WahJoUMt+nyhiy3YjDYtstO2ZgkxupwnZgwGUBVIiD1c4SPuyy+HTjNMOtiVsEUHT2hf+xPAemWpTlK5HcwhMmHAOh6rt6dEj57QOg0gcmGiwD/tCbEriA="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
@@ -149,16 +150,6 @@ matrix:
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
# As long as Windows is still experimental on Travis CI, allow failures
|
||||
allow_failures:
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
|
||||
+3
-3
@@ -9,11 +9,11 @@ environment:
|
||||
- BuildID: 0
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015
|
||||
PlatformToolset: v140_xp
|
||||
QT_DIR: C:\Qt\5.9.5\msvc2015
|
||||
QT_DIR: C:\Qt\5.9\msvc2015
|
||||
- BuildID: 1
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015 Win64
|
||||
PlatformToolset: v140_xp
|
||||
QT_DIR: C:\Qt\5.9.5\msvc2015_64
|
||||
QT_DIR: C:\Qt\5.9\msvc2015_64
|
||||
before_build:
|
||||
- git submodule update --init --recursive
|
||||
build_script:
|
||||
@@ -24,7 +24,7 @@ test_script:
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
auth_token:
|
||||
secure: 3kV4efHXwRnfXzmJPRAOs8D7+MhwXUXYeayI/P5y114L09kJa6b6L70beXdW7yYr
|
||||
secure: h55Scpy+3vmo1Yb7WlSIGA4d9DRnsbzUYc2LYsQdByQHZHbqrqjBpicH0D2FFLEO
|
||||
on:
|
||||
ReleaseBuild: true # deploy on release push only
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ $NightlyConfigurations = @(
|
||||
PackageType="Win64";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.9.5\msvc2015_64";
|
||||
QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
SourcePackage=$false;
|
||||
},
|
||||
[BuildConfig]@{
|
||||
@@ -22,7 +22,7 @@ $NightlyConfigurations = @(
|
||||
PackageType="Win32";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.9.5\msvc2015";
|
||||
QtDir="C:\Qt\5.9\msvc2015";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
)
|
||||
@@ -32,7 +32,7 @@ $ReleaseConfigurations = @(
|
||||
PackageType="Win32";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.9.5\msvc2015";
|
||||
QtDir="C:\Qt\5.9\msvc2015";
|
||||
SourcePackage=$true;
|
||||
}
|
||||
[BuildConfig]@{
|
||||
@@ -40,7 +40,7 @@ $ReleaseConfigurations = @(
|
||||
PackageType="Win32-AVX";
|
||||
Toolset="v140_xp";
|
||||
SimdType="AVX";
|
||||
QtDir="C:\Qt\5.9.5\msvc2015";
|
||||
QtDir="C:\Qt\5.9\msvc2015";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
[BuildConfig]@{
|
||||
@@ -48,7 +48,7 @@ $ReleaseConfigurations = @(
|
||||
PackageType="Win64";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.9.5\msvc2015_64";
|
||||
QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
[BuildConfig]@{
|
||||
@@ -56,7 +56,7 @@ $ReleaseConfigurations = @(
|
||||
PackageType="Win64-AVX";
|
||||
Toolset="v140_xp";
|
||||
SimdType="AVX";
|
||||
QtDir="C:\Qt\5.9.5\msvc2015_64";
|
||||
QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
)
|
||||
|
||||
+53
-18
@@ -10,27 +10,62 @@ if [[ ! "$(curl -V)" == *"sftp"* ]]; then
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
|
||||
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
|
||||
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
|
||||
apt-get source curl
|
||||
sudo apt-get build-dep curl
|
||||
if [ -f ~/curl_cache/curl*.deb ]; then
|
||||
cd ~/curl_cache
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
else
|
||||
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
|
||||
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
|
||||
apt-get source curl
|
||||
sudo apt-get build-dep curl
|
||||
|
||||
cd curl-*
|
||||
export DEB_BUILD_OPTIONS="nocheck"
|
||||
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
|
||||
cd curl-*
|
||||
export DEB_BUILD_OPTIONS="nocheck"
|
||||
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
|
||||
|
||||
cd ..
|
||||
dpkg -l | grep curl
|
||||
ls -al
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
cd ..
|
||||
dpkg -l | grep curl
|
||||
ls -al
|
||||
|
||||
if [ ! -d ~/curl_cache ]; then
|
||||
mkdir ~/curl_cache
|
||||
fi
|
||||
|
||||
cp libcurl3*.deb curl*.deb ~/curl_cache
|
||||
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew install curl --with-libssh2
|
||||
export PATH="/usr/local/opt/curl/bin:$PATH"
|
||||
brew install libssh2
|
||||
|
||||
if [ -d ~/curl_cache/curl ]; then
|
||||
cd ~/curl_cache/curl
|
||||
sudo make install
|
||||
else
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
|
||||
curl -LO "https://curl.haxx.se/download/curl-7.64.0.tar.bz2"
|
||||
tar -xjf curl-7.64.0.tar.bz2
|
||||
|
||||
cd curl-7.64.0
|
||||
./configure --disable-debug --disable-dependency-tracking --disable-silent-rules --with-libssh2 --with-darwinssl --without-ca-bundle --without-ca-path
|
||||
make -j"$(sysctl hw.logicalcpu | cut -d " " -f 2)"
|
||||
|
||||
if [ ! -d ~/curl_cache ]; then
|
||||
mkdir ~/curl_cache
|
||||
fi
|
||||
|
||||
cp -a . ~/curl_cache/curl
|
||||
sudo make install
|
||||
fi
|
||||
export PATH=/usr/local/bin:$PATH
|
||||
fi
|
||||
|
||||
# After
|
||||
|
||||
+10
-10
@@ -10,8 +10,8 @@ include(CheckSymbolExists)
|
||||
include(CheckCXXSymbolExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFO_H)
|
||||
CHECK_INCLUDE_FILE_CXX("cxxabi.h" HAVE_CXXAPI_H)
|
||||
CHECK_INCLUDE_FILE("execinfo.h" SCP_HAVE_EXECINFO_H)
|
||||
CHECK_INCLUDE_FILE_CXX("cxxabi.h" SCP_HAVE_CXXAPI_H)
|
||||
|
||||
CHECK_TYPE_SIZE("max_align_t" MAX_ALIGN_T)
|
||||
|
||||
@@ -31,18 +31,18 @@ CHECK_TYPE_SIZE("U'b'" UNICODE_CHAR_LITERAL LANGUAGE CXX)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp SCP_HAVE_STRCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strncasecmp SCP_HAVE_STRNCASECMP)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
|
||||
CHECK_FUNCTION_EXISTS(_strnicmp HAVE__STRNICMP)
|
||||
CHECK_FUNCTION_EXISTS(_stricmp SCP_HAVE__STRICMP)
|
||||
CHECK_FUNCTION_EXISTS(_strnicmp SCP_HAVE__STRNICMP)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strlwr HAVE_STRLWR)
|
||||
CHECK_FUNCTION_EXISTS(strlwr SCP_HAVE_STRLWR)
|
||||
|
||||
CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
|
||||
CHECK_INCLUDE_FILE("strings.h" SCP_HAVE_STRINGS_H)
|
||||
|
||||
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
|
||||
check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
|
||||
check_symbol_exists(snprintf "stdio.h" SCP_HAVE_SNPRINTF)
|
||||
check_symbol_exists(_snprintf "stdio.h" SCP_HAVE__SNPRINTF)
|
||||
|
||||
set(PLATFORM_CHECK_HEADER "${GENERATED_SOURCE_DIR}/platformChecks.h")
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/platformChecks.h.in "${PLATFORM_CHECK_HEADER}")
|
||||
+14
-14
@@ -3,29 +3,29 @@
|
||||
#define __PLATFORM_CHECKS_H__
|
||||
#pragma once
|
||||
|
||||
#cmakedefine HAVE_EXECINFO_H
|
||||
#cmakedefine HAVE_CXXAPI_H
|
||||
#cmakedefine HAVE_MAX_ALIGN_T
|
||||
#cmakedefine HAVE_STD_MAX_ALIGN_T
|
||||
#cmakedefine SCP_HAVE_EXECINFO_H
|
||||
#cmakedefine SCP_HAVE_CXXAPI_H
|
||||
#cmakedefine SCP_HAVE_MAX_ALIGN_T
|
||||
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
|
||||
|
||||
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE
|
||||
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
|
||||
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE
|
||||
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
|
||||
|
||||
#cmakedefine01 IS_64BIT
|
||||
|
||||
#cmakedefine01 HAVE_STRCASECMP
|
||||
#cmakedefine01 HAVE_STRNCASECMP
|
||||
#cmakedefine01 HAVE__STRICMP
|
||||
#cmakedefine01 HAVE__STRNICMP
|
||||
#cmakedefine01 SCP_HAVE_STRCASECMP
|
||||
#cmakedefine01 SCP_HAVE_STRNCASECMP
|
||||
#cmakedefine01 SCP_HAVE__STRICMP
|
||||
#cmakedefine01 SCP_HAVE__STRNICMP
|
||||
|
||||
#cmakedefine01 HAVE_STRLWR
|
||||
#cmakedefine01 SCP_HAVE_STRLWR
|
||||
|
||||
#cmakedefine01 HAVE_STRINGS_H
|
||||
#cmakedefine01 SCP_HAVE_STRINGS_H
|
||||
|
||||
#cmakedefine01 HAVE_CHAR32_T
|
||||
#cmakedefine01 HAVE_UNICODE_CHAR_LITERAL
|
||||
|
||||
#cmakedefine01 HAVE_SNPRINTF
|
||||
#cmakedefine01 HAVE__SNPRINTF
|
||||
#cmakedefine01 SCP_HAVE_SNPRINTF
|
||||
#cmakedefine01 SCP_HAVE__SNPRINTF
|
||||
|
||||
#endif // __PLATFORM_CHECKS_H__
|
||||
@@ -9,8 +9,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -funroll-loops -fsigned-char -Wno-
|
||||
# Omit "conversion from string literal to 'char *' is deprecated" warnings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||
|
||||
@@ -66,8 +66,6 @@ set(COMPILER_FLAGS "${COMPILER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wformat-security")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-function")
|
||||
|
||||
# Dear Clang, please tell us if a function does not return a value since that part of the standard is stupid!
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wreturn-type")
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ set(COMPILER_FLAGS "${COMPILER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wformat-security")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-function")
|
||||
|
||||
# Dear GCC, please tell us if a function does not return a value since that part of the standard is stupid!
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wreturn-type")
|
||||
|
||||
|
||||
@@ -587,13 +587,10 @@ extern void get_absolute_wing_pos_autopilot( vec3d *result_pos, object *leader_o
|
||||
|
||||
// Interface from goals code to AI. Set ship to guard. *objp guards *other_objp
|
||||
extern void ai_set_guard_object(object *objp, object *other_objp);
|
||||
extern void ai_set_evade_object(object *objp, object *other_objp);
|
||||
extern void ai_set_guard_wing(object *objp, int wingnum);
|
||||
extern void ai_warp_out(object *objp, vec3d *vp);
|
||||
extern void ai_attack_wing(object *attacker, int wingnum);
|
||||
extern void ai_deathroll_start(object *ship_obj);
|
||||
extern void ai_fly_in_formation(int wing_num); // Force wing to fly in formation.
|
||||
extern void ai_disband_formation(int wing_num); // Force wing to disband formation flying.
|
||||
extern int set_target_objnum(ai_info *aip, int objnum);
|
||||
extern void ai_form_on_wing(object *objp, object *goal_objp);
|
||||
extern void ai_do_stay_near(object *objp, object *other_obj, float dist);
|
||||
@@ -646,8 +643,6 @@ extern void ai_do_objects_repairing_stuff( object *repaired_obj, object *repair_
|
||||
// Move to a position relative to a dock bay using thrusters.
|
||||
extern float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo = NULL);
|
||||
|
||||
extern int find_danger_weapon(object *sobjp, float dtime, float *atime, float dot_threshhold);
|
||||
|
||||
void ai_set_mode_warp_out(object *objp, ai_info *aip);
|
||||
|
||||
// prototyped by Goober5000
|
||||
|
||||
@@ -110,6 +110,7 @@ namespace AI {
|
||||
Smart_shield_management,
|
||||
Smart_subsystem_targeting_for_turrets,
|
||||
Strict_turred_tagged_only_targeting,
|
||||
Support_dont_add_primaries, //Prevents support ship from equipping new primary as requested in http://scp.indiegames.us/mantis/view.php?id=3198
|
||||
Turrets_ignore_target_radius,
|
||||
Use_actual_primary_range,
|
||||
Use_additive_weapon_velocity,
|
||||
|
||||
@@ -435,6 +435,8 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$ai guards specific ship in wing:", AI::Profile_Flags::Ai_guards_specific_ship_in_wing);
|
||||
|
||||
set_flag(profile, "$support don't add primaries:", AI::Profile_Flags::Support_dont_add_primaries);
|
||||
|
||||
profile->ai_path_mode = AI_PATH_MODE_NORMAL;
|
||||
if (optional_string("$ai path mode:"))
|
||||
{
|
||||
|
||||
+77
-135
@@ -58,6 +58,8 @@
|
||||
#include "physics/physics.h"
|
||||
#include "playerman/player.h"
|
||||
#include "render/3d.h"
|
||||
#include "scripting/api/objs/wing.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "ship/afterburner.h"
|
||||
#include "ship/awacs.h"
|
||||
#include "ship/ship.h"
|
||||
@@ -1312,7 +1314,9 @@ ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int pare
|
||||
}
|
||||
|
||||
if ( aip == Player_ai ) {
|
||||
hud_lock_reset(0.5f);
|
||||
if (aip->last_subsys_target != aip->targeted_subsys) {
|
||||
hud_lock_reset(0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -1345,6 +1349,7 @@ void ai_object_init(object * obj, int ai_index)
|
||||
aip->wing = -1; // Member of what wing? -1 means none.
|
||||
aip->ai_class = Ship_info[Ships[obj->instance].ship_info_index].ai_class;
|
||||
aip->behavior = AIM_NONE;
|
||||
aip->mode = aip->behavior;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4586,6 +4591,11 @@ void ai_waypoints()
|
||||
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
|
||||
mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, aip->wp_list->get_name(), -1 );
|
||||
}
|
||||
// adds scripting hook for 'On Waypoints Done' --wookieejedi
|
||||
Script_system.SetHookObject("Ship", &Objects[Ships[Pl_objp->instance].objnum]);
|
||||
Script_system.SetHookVar("Wing", 'o', scripting::api::l_Wing.Set(Ships[Pl_objp->instance].wingnum));
|
||||
Script_system.RunCondition(CHA_ONWAYPOINTSDONE);
|
||||
Script_system.RemHookVars(2, "Ship", "Wing");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5310,9 +5320,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
|
||||
{
|
||||
if (swp->current_primary_bank >= 0)
|
||||
{
|
||||
int bank_index;
|
||||
|
||||
bank_index = swp->current_primary_bank;
|
||||
int bank_index = swp->current_primary_bank;
|
||||
|
||||
if (Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Puncture])
|
||||
{
|
||||
@@ -5321,11 +5329,9 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
|
||||
}
|
||||
for (int i=0; i<swp->num_primary_banks; i++)
|
||||
{
|
||||
int weapon_info_index;
|
||||
int weapon_info_index = swp->primary_bank_weapons[i];
|
||||
|
||||
weapon_info_index = swp->primary_bank_weapons[i];
|
||||
|
||||
if (weapon_info_index > -1)
|
||||
if (weapon_info_index >= 0)
|
||||
{
|
||||
if (Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Puncture])
|
||||
{
|
||||
@@ -5336,44 +5342,51 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
|
||||
}
|
||||
}
|
||||
|
||||
if ( (other_objp->type == OBJ_SHIP) && (Ship_info[Ships[other_objp->instance].ship_info_index].is_big_or_huge() ) )
|
||||
auto other_is_ship = (other_objp->type == OBJ_SHIP);
|
||||
float enemy_remaining_shield = get_shield_pct(other_objp);
|
||||
|
||||
if ( other_is_ship && (Ship_info[Ships[other_objp->instance].ship_info_index].is_big_or_huge() ) )
|
||||
{
|
||||
//Check if we have a capital+ weapon on board
|
||||
for (int i = 0; i < swp->num_primary_banks; i++)
|
||||
{
|
||||
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
|
||||
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
|
||||
{
|
||||
if (Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus])
|
||||
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
|
||||
if (wip->wi_flags[Weapon::Info_Flags::Capital_plus])
|
||||
{
|
||||
swp->current_primary_bank = i;
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i]].name));
|
||||
return i;
|
||||
// handle shielded big/huge ships (non FS-verse)
|
||||
// only pick capital+ if the target has no shields; or the weapon is an ok shield-breaker anyway
|
||||
if (enemy_remaining_shield <= 0.05f || (wip->shield_factor * 1.33f > wip->armor_factor))
|
||||
{
|
||||
swp->current_primary_bank = i;
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s (capital+) vs target %s\n", Framecount, Ships[objp->instance].ship_name, wip->name, Ships[other_objp->instance].ship_name));
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float enemy_remaining_shield = get_shield_pct(other_objp);
|
||||
|
||||
// Is the target shielded by say only 5%?
|
||||
if (enemy_remaining_shield <= 0.05f)
|
||||
{
|
||||
// Then it is safe to start using a heavy hull damage weapon such as the maxim
|
||||
int i;
|
||||
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
|
||||
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
|
||||
|
||||
// Find the weapon with the highest hull * damage / fire delay factor
|
||||
for (i = 0; i < swp->num_primary_banks; i++)
|
||||
for (int i = 0; i < swp->num_primary_banks; i++)
|
||||
{
|
||||
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
|
||||
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
|
||||
{
|
||||
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
|
||||
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
|
||||
if ((((wip->armor_factor) * (wip->damage)) / wip->fire_wait) > i_hullfactor_prev)
|
||||
{
|
||||
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
|
||||
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
|
||||
{
|
||||
// This weapon is the new candidate
|
||||
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
|
||||
i_hullfactor_prev = ( ((wip->armor_factor) * (wip->damage)) / wip->fire_wait );
|
||||
i_hullfactor_prev_bank = i;
|
||||
}
|
||||
}
|
||||
@@ -5384,6 +5397,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
|
||||
i_hullfactor_prev_bank = 0; // Just switch to the first one
|
||||
}
|
||||
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s (no shields) vs target %s\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name, (other_is_ship ? Ships[other_objp->instance].ship_name : "non-ship") ));
|
||||
return i_hullfactor_prev_bank; // Return
|
||||
}
|
||||
|
||||
@@ -5392,26 +5406,23 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
|
||||
{
|
||||
if (swp->current_primary_bank >= 0)
|
||||
{
|
||||
int bank_index;
|
||||
auto wip = &Weapon_info[swp->primary_bank_weapons[swp->current_primary_bank]];
|
||||
|
||||
bank_index = swp->current_primary_bank;
|
||||
|
||||
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Capital_plus]))
|
||||
if ((wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]))
|
||||
{
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, shipp->ship_name, wip->name));
|
||||
return swp->current_primary_bank;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<swp->num_primary_banks; i++)
|
||||
{
|
||||
int weapon_info_index;
|
||||
|
||||
weapon_info_index = swp->primary_bank_weapons[i];
|
||||
|
||||
if (weapon_info_index > -1)
|
||||
if (swp->primary_bank_weapons[i] >= 0)
|
||||
{
|
||||
if ((Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]))
|
||||
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
|
||||
if ((wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]))
|
||||
{
|
||||
swp->current_primary_bank = i;
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, shipp->ship_name, wip->name));
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -5421,61 +5432,63 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
|
||||
// Is the target shielded by less then 50%?
|
||||
if (enemy_remaining_shield <= 0.50f)
|
||||
{
|
||||
// Should be using best balanced shield gun
|
||||
int i;
|
||||
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
|
||||
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
|
||||
// Should be using best balanced shield/hull gun
|
||||
float i_balancedfactor_prev = 0; // Previous weapon bank "balanced" factor (this is the safe way to do it)
|
||||
int i_balancedfactor_prev_bank = -1; // Bank which gave us this "balanced" factor
|
||||
// Find the weapon with the highest average hull and shield * damage / fire delay factor
|
||||
for (i = 0; i < swp->num_primary_banks; i++)
|
||||
for (int i = 0; i < swp->num_primary_banks; i++)
|
||||
{
|
||||
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
|
||||
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
|
||||
{
|
||||
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
|
||||
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
|
||||
if ((((wip->armor_factor + wip->shield_factor) * wip->damage) / wip->fire_wait) > i_balancedfactor_prev)
|
||||
{
|
||||
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
|
||||
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
|
||||
{
|
||||
// This weapon is the new candidate
|
||||
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
|
||||
i_hullfactor_prev_bank = i;
|
||||
i_balancedfactor_prev = ((((wip->armor_factor + wip->shield_factor) * wip->damage) / wip->fire_wait));
|
||||
i_balancedfactor_prev_bank = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i_hullfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
|
||||
if (i_balancedfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
|
||||
{
|
||||
i_hullfactor_prev_bank = 0; // Just switch to the first one
|
||||
i_balancedfactor_prev_bank = 0; // Just switch to the first one
|
||||
}
|
||||
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
|
||||
return i_hullfactor_prev_bank; // Return
|
||||
swp->current_primary_bank = i_balancedfactor_prev_bank; // Select the best weapon
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s (<50%% shields)\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_balancedfactor_prev_bank]].name));
|
||||
return i_balancedfactor_prev_bank; // Return
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should be using best shield destroying gun
|
||||
int i;
|
||||
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
|
||||
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
|
||||
float i_shieldfactor_prev = 0; // Previous weapon bank shield factor (this is the safe way to do it)
|
||||
int i_shieldfactor_prev_bank = -1; // Bank which gave us this shield factor
|
||||
// Find the weapon with the highest average hull and shield * damage / fire delay factor
|
||||
for (i = 0; i < swp->num_primary_banks; i++)
|
||||
for (int i = 0; i < swp->num_primary_banks; i++)
|
||||
{
|
||||
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
|
||||
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
|
||||
{
|
||||
if ((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
|
||||
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
|
||||
if ((((wip->shield_factor) * wip->damage) / wip->fire_wait) > i_shieldfactor_prev)
|
||||
{
|
||||
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
|
||||
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
|
||||
{
|
||||
// This weapon is the new candidate
|
||||
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
|
||||
i_hullfactor_prev_bank = i;
|
||||
i_shieldfactor_prev = ( ((wip->shield_factor) * (wip->damage)) / wip->fire_wait );
|
||||
i_shieldfactor_prev_bank = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i_hullfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
|
||||
if (i_shieldfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
|
||||
{
|
||||
i_hullfactor_prev_bank = 0; // Just switch to the first one
|
||||
i_shieldfactor_prev_bank = 0; // Just switch to the first one
|
||||
}
|
||||
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
|
||||
return i_hullfactor_prev_bank; // Return
|
||||
swp->current_primary_bank = i_shieldfactor_prev_bank; // Select the best weapon
|
||||
nprintf(("AI", "%i: Ship %s selecting weapon %s (>50%% shields)\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_shieldfactor_prev_bank]].name));
|
||||
return i_shieldfactor_prev_bank; // Return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5502,7 +5515,9 @@ void set_primary_weapon_linkage(object *objp)
|
||||
// If trying to destroy a big ship (i.e., not disable/disarm), always unleash all weapons
|
||||
if ( Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].is_big_ship() ) {
|
||||
if ( aip->targeted_subsys == NULL ) {
|
||||
shipp->flags.set(Ship::Ship_Flags::Primary_linked);
|
||||
if (!sip->flags[Ship::Info_Flags::No_primary_linking] ) {
|
||||
shipp->flags.set(Ship::Ship_Flags::Primary_linked);
|
||||
}
|
||||
shipp->flags.set(Ship::Ship_Flags::Secondary_dual_fire);
|
||||
return;
|
||||
}
|
||||
@@ -7478,32 +7493,6 @@ void ai_set_guard_wing(object *objp, int wingnum)
|
||||
}
|
||||
}
|
||||
|
||||
// Make object *objp guard object *other_objp.
|
||||
// To be called from the goals code.
|
||||
void ai_set_evade_object(object *objp, object *other_objp)
|
||||
{
|
||||
ship *shipp;
|
||||
ai_info *aip;
|
||||
int other_objnum;
|
||||
|
||||
Assert(objp->type == OBJ_SHIP);
|
||||
Assert(objp->instance >= 0);
|
||||
|
||||
shipp = &Ships[objp->instance];
|
||||
|
||||
Assert(shipp->ai_index >= 0);
|
||||
|
||||
aip = &Ai_info[shipp->ai_index];
|
||||
|
||||
other_objnum = OBJ_INDEX(other_objp);
|
||||
Assert(other_objnum >= 0);
|
||||
|
||||
Assert(other_objnum != Ships[aip->shipnum].objnum); // make sure not targeting self
|
||||
aip->target_objnum = other_objnum;
|
||||
|
||||
aip->mode = AIM_EVADE;
|
||||
}
|
||||
|
||||
// Make objp guard other_objp
|
||||
// If other_objp is a member of a wing, objp will guard that whole wing
|
||||
// UNLESS objp is also a member of the wing!
|
||||
@@ -11538,53 +11527,6 @@ void render_wing_phantoms_all()
|
||||
|
||||
#endif
|
||||
|
||||
// Hook from goals code to AI.
|
||||
// Force a wing to fly in formation.
|
||||
// Sets AIF_FORMATION bit in ai_flags.
|
||||
// wingnum Wing to force to fly in formation
|
||||
void ai_fly_in_formation(int wingnum)
|
||||
{
|
||||
object *objp;
|
||||
ship *shipp;
|
||||
ship_obj *so;
|
||||
|
||||
for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
|
||||
objp = &Objects[so->objnum];
|
||||
Assert((objp->instance >= 0) && (objp->instance < MAX_SHIPS));
|
||||
|
||||
shipp = &Ships[objp->instance];
|
||||
Assert((shipp->ai_index >= 0) && (shipp->ai_index < MAX_AI_INFO));
|
||||
|
||||
if (Ai_info[shipp->ai_index].wing == wingnum) {
|
||||
Ai_info[shipp->ai_index].ai_flags.set(AI::AI_Flags::Formation_wing);
|
||||
Ai_info[shipp->ai_index].ai_flags.remove(AI::AI_Flags::Formation_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hook from goals code to AI.
|
||||
// Force a wing to abandon formation flying.
|
||||
// Clears AIF_FORMATION bit in ai_flags.
|
||||
// wingnum Wing to force to fly in formation
|
||||
void ai_disband_formation(int wingnum)
|
||||
{
|
||||
object *objp;
|
||||
ship *shipp;
|
||||
ship_obj *so;
|
||||
|
||||
for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
|
||||
objp = &Objects[so->objnum];
|
||||
Assert((objp->instance >= 0) && (objp->instance < MAX_SHIPS));
|
||||
|
||||
shipp = &Ships[objp->instance];
|
||||
Assert((shipp->ai_index >= 0) && (shipp->ai_index < MAX_AI_INFO));
|
||||
|
||||
if (Ai_info[shipp->ai_index].wing == wingnum) {
|
||||
Ai_info[shipp->ai_index].ai_flags.remove(AI::AI_Flags::Formation_wing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Leader_chaos = 0.0f;
|
||||
int Chaos_frame = -1;
|
||||
|
||||
@@ -13359,7 +13301,7 @@ void ai_warp_out(object *objp)
|
||||
case AIS_WARP_2: // Make sure won't collide with any object.
|
||||
if (timestamp_elapsed(aip->force_warp_time)
|
||||
|| (!collide_predict_large_ship(objp, objp->radius*2.0f + 100.0f)
|
||||
|| (Ship_info[shipp->ship_info_index].warpout_type == WT_HYPERSPACE
|
||||
|| (Warp_params[shipp->warpout_params_index].warp_type == WT_HYPERSPACE
|
||||
&& !collide_predict_large_ship(objp, 100000.0f)))) {
|
||||
aip->submode = AIS_WARP_3;
|
||||
aip->submode_start_time = Missiontime;
|
||||
@@ -13402,7 +13344,7 @@ void ai_warp_out(object *objp)
|
||||
break;
|
||||
case AIS_WARP_4: {
|
||||
// Only lets the ship warp after waiting for the warpout engage time
|
||||
if ( (Missiontime / 100) >= (aip->submode_start_time / 100 + Ship_info[shipp->ship_info_index].warpout_engage_time) ) {
|
||||
if ( (Missiontime / 100) >= (aip->submode_start_time / 100 + Warp_params[shipp->warpout_params_index].warpout_engage_time) ) {
|
||||
shipfx_warpout_start(objp);
|
||||
aip->submode = AIS_WARP_5;
|
||||
aip->submode_start_time = Missiontime;
|
||||
|
||||
+55
-48
@@ -62,31 +62,32 @@ char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
|
||||
// Used in objecttypes.tbl to define custom ship types
|
||||
ai_goal_list Ai_goal_names[] =
|
||||
{
|
||||
{ "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 },
|
||||
{ "Attack ship class", AI_GOAL_CHASE_SHIP_CLASS, 0 },
|
||||
{ "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 },
|
||||
{ "Play dead (persistent)", AI_GOAL_PLAY_DEAD_PERSISTENT, 0 },
|
||||
{ "Attack weapon", AI_GOAL_CHASE_WEAPON, 0 },
|
||||
{ "Fly to ship", AI_GOAL_FLY_TO_SHIP, 0 },
|
||||
{ "Attack ship class", AI_GOAL_CHASE_SHIP_CLASS, 0 },
|
||||
};
|
||||
|
||||
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
|
||||
@@ -732,6 +733,12 @@ void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, ch
|
||||
aigp->target_signature = Objects[Weapons[submode].objnum].signature;
|
||||
}
|
||||
|
||||
if ( mode == AI_GOAL_WAYPOINTS_ONCE || mode == AI_GOAL_WAYPOINTS ) {
|
||||
// should be the same as setting via sexp, see ai_add_goal_sub_sexp
|
||||
// set to null so the AI code can setup the new waypoint list, see ai_mission_goal_achievable
|
||||
aigp->wp_list = nullptr;
|
||||
}
|
||||
|
||||
if ( target_name != NULL )
|
||||
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
|
||||
else
|
||||
@@ -937,6 +944,11 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
aigp->ai_mode = AI_GOAL_PLAY_DEAD;
|
||||
break;
|
||||
|
||||
case OP_AI_PLAY_DEAD_PERSISTENT:
|
||||
aigp->priority = atoi( CTEXT(CDR(node)) );
|
||||
aigp->ai_mode = AI_GOAL_PLAY_DEAD_PERSISTENT;
|
||||
break;
|
||||
|
||||
case OP_AI_KEEP_SAFE_DISTANCE:
|
||||
aigp->priority = atoi( CTEXT(CDR(node)) );
|
||||
aigp->ai_mode = AI_GOAL_KEEP_SAFE_DISTANCE;
|
||||
@@ -1126,6 +1138,10 @@ int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp )
|
||||
goalmode = AI_GOAL_PLAY_DEAD;
|
||||
priority = ( CDR(node) >= 0 ) ? atoi( CTEXT( CDR( node ) ) ) : -1;
|
||||
break;
|
||||
case OP_AI_PLAY_DEAD_PERSISTENT:
|
||||
goalmode = AI_GOAL_PLAY_DEAD_PERSISTENT;
|
||||
priority = ( CDR(node) >= 0 ) ? atoi( CTEXT( CDR( node ) ) ) : -1;
|
||||
break;
|
||||
case OP_AI_KEEP_SAFE_DISTANCE:
|
||||
priority = ( CDR(node) >= 0 ) ? atoi( CTEXT( CDR( node ) ) ) : -1;
|
||||
goalmode = AI_GOAL_KEEP_SAFE_DISTANCE;
|
||||
@@ -1340,25 +1356,6 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int /*
|
||||
ai_process_mission_orders( Ships[aip->shipnum].objnum, aip );
|
||||
}
|
||||
|
||||
// function to add an internal goal to a wing. Mike K says that the goal doesn't need to persist
|
||||
// across waves of the wing so we merely need to add the goal to each ship in the wing. Certain
|
||||
// goal are simply not valid for wings (like dock, undock). Immediate parameter gets passed to add_ship_goal
|
||||
// to say whether or not we should process this goal right away
|
||||
void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
|
||||
{
|
||||
int i;
|
||||
|
||||
// be sure we are not trying to issue dock or undock goals to wings
|
||||
Assert ( (goal_type != AI_GOAL_DOCK) && (goal_type != AI_GOAL_UNDOCK) );
|
||||
|
||||
for (i = 0; i < wingp->current_count; i++) {
|
||||
int num = wingp->ship_index[i];
|
||||
if ( num == -1 ) // ship must have been destroyed or departed
|
||||
continue;
|
||||
ai_add_goal_ship_internal( &Ai_info[Ships[num].ai_index], goal_type, name, -1, -1, immediate);
|
||||
}
|
||||
}
|
||||
|
||||
// this function copies goals from a wing to an ai_info * from a ship.
|
||||
void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
{
|
||||
@@ -1401,7 +1398,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// these orders are always achievable.
|
||||
if ( (aigp->ai_mode == AI_GOAL_KEEP_SAFE_DISTANCE)
|
||||
|| (aigp->ai_mode == AI_GOAL_CHASE_ANY) || (aigp->ai_mode == AI_GOAL_STAY_STILL)
|
||||
|| (aigp->ai_mode == AI_GOAL_PLAY_DEAD) )
|
||||
|| (aigp->ai_mode == AI_GOAL_PLAY_DEAD) || (aigp->ai_mode == AI_GOAL_PLAY_DEAD_PERSISTENT) )
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
|
||||
// warp (depart) only achievable if there's somewhere to depart to
|
||||
@@ -1629,7 +1626,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
status = SHIP_STATUS_ARRIVED;
|
||||
}
|
||||
// goal ship is still on the arrival list
|
||||
else if ( mission_parse_get_arrival_ship(aigp->target_name) )
|
||||
else if ( mission_check_ship_yet_to_arrive(aigp->target_name) )
|
||||
{
|
||||
status = SHIP_STATUS_NOT_ARRIVED;
|
||||
}
|
||||
@@ -1895,9 +1892,12 @@ int ai_goal_priority_compare(const void *a, const void *b)
|
||||
// check whether or not the goal override flag is set. If it is set, then push this goal higher
|
||||
// in the list
|
||||
|
||||
else if ( (ga->flags[AI::Goal_Flags::Goal_override]) && !(gb->flags[AI::Goal_Flags::Goal_override]) )
|
||||
// Goober5000: the ONLY goals we do not override are play-dead and play-dead-persistent,
|
||||
// because the override flag needs to work in any other situation
|
||||
|
||||
else if ( (ga->flags[AI::Goal_Flags::Goal_override]) && !(gb->flags[AI::Goal_Flags::Goal_override]) && !(gb->ai_mode == AI_GOAL_PLAY_DEAD) && !(gb->ai_mode == AI_GOAL_PLAY_DEAD_PERSISTENT) )
|
||||
return -1;
|
||||
else if ( !(ga->flags[AI::Goal_Flags::Goal_override]) && (gb->flags[AI::Goal_Flags::Goal_override]) )
|
||||
else if ( !(ga->flags[AI::Goal_Flags::Goal_override]) && (gb->flags[AI::Goal_Flags::Goal_override]) && !(ga->ai_mode == AI_GOAL_PLAY_DEAD) && !(ga->ai_mode == AI_GOAL_PLAY_DEAD_PERSISTENT))
|
||||
return 1;
|
||||
|
||||
// now normal priority processing
|
||||
@@ -2290,6 +2290,13 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
aip->submode_start_time = Missiontime;
|
||||
break;
|
||||
|
||||
case AI_GOAL_PLAY_DEAD_PERSISTENT:
|
||||
// same as above, but we don't clear out ship goals
|
||||
aip->mode = AIM_PLAY_DEAD;
|
||||
aip->submode = -1;
|
||||
aip->submode_start_time = Missiontime;
|
||||
break;
|
||||
|
||||
case AI_GOAL_FORM_ON_WING:
|
||||
// for form on wing, we need to clear out all goals for this ship, and then call the form
|
||||
// on wing AI code
|
||||
|
||||
+5
-5
@@ -58,16 +58,17 @@ struct ai_goal;
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
|
||||
#define AI_GOAL_CHASE_SHIP_CLASS (1<<25) // 0x02000000
|
||||
#define AI_GOAL_PLAY_DEAD_PERSISTENT (1<<26) // 0x03000000
|
||||
|
||||
// now the masks for ship types
|
||||
|
||||
// Goober5000: added AI_GOAL_STAY_NEAR_SHIP and AI_GOAL_KEEP_SAFE_DISTANCE as valid for fighters
|
||||
//WMC - Don't need these anymore. Whee!
|
||||
/*
|
||||
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_BOMBER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_STEALTH ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD| AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_FREIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CRUISER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FREIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CORVETTE ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
@@ -75,7 +76,7 @@ struct ai_goal;
|
||||
#define AI_GOAL_ACCEPT_AWACS ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CAPITAL ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER & ~(AI_GOAL_DOCK | AI_GOAL_UNDOCK) | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_SUPERCAP ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CAPITAL | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_SUPPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_DOCK | AI_GOAL_UNDOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD)
|
||||
#define AI_GOAL_ACCEPT_SUPPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_DOCK | AI_GOAL_UNDOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT )
|
||||
#define AI_GOAL_ACCEPT_ESCAPEPOD ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT| AI_GOAL_STAY_NEAR_SHIP )
|
||||
*/
|
||||
|
||||
@@ -102,7 +103,7 @@ extern int ai_goal_num(ai_goal *goals);
|
||||
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipname, ai_info *aip);
|
||||
extern void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip );
|
||||
extern void ai_add_wing_goal_sexp( int sexp, int type, int wingnum );
|
||||
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp );
|
||||
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name );
|
||||
|
||||
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp );
|
||||
extern void ai_remove_wing_goal_sexp(int sexp, int wingnum);
|
||||
@@ -127,6 +128,5 @@ extern char *ai_add_dock_name(const char *str);
|
||||
extern int ai_query_goal_valid( int ship, int ai_goal_type );
|
||||
|
||||
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
|
||||
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
|
||||
|
||||
#endif
|
||||
@@ -856,11 +856,11 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
// flags for weapon types
|
||||
if (beam_flag)
|
||||
eeo.eeo_flags |= EEOF_BEAM;
|
||||
else if (flak_flag)
|
||||
if (flak_flag)
|
||||
eeo.eeo_flags |= EEOF_FLAK;
|
||||
else if (laser_flag)
|
||||
if (laser_flag)
|
||||
eeo.eeo_flags |= EEOF_LASER;
|
||||
else if (missile_flag)
|
||||
if (missile_flag)
|
||||
eeo.eeo_flags |= EEOF_MISSILE;
|
||||
|
||||
eeo.enemy_team_mask = enemy_team_mask;
|
||||
@@ -1290,7 +1290,9 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
model_instance_find_world_point(&tmp_pos, &avg, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient, &objp->pos);
|
||||
|
||||
if (targetp == nullptr) {
|
||||
Assertion(ssp->turret_enemy_objnum >= 0, "The turret enemy object number %d for %s on ship number %d is invalid.", ssp->turret_enemy_objnum, ssp->sub_name, ssp->parent_objnum);
|
||||
ship* shipp = &Ships[Objects[ssp->parent_objnum].instance];
|
||||
Assertion(ssp->turret_enemy_objnum >= 0, "The turret enemy object number %d for %s on ship name %s is invalid.", ssp->turret_enemy_objnum, ssp->sub_name,
|
||||
(shipp->has_display_name()) ? shipp->display_name.c_str() : shipp->ship_name);
|
||||
object *lep = &Objects[ssp->turret_enemy_objnum];
|
||||
|
||||
int best_weapon_tidx = turret_select_best_weapon(ssp, lep);
|
||||
@@ -1301,9 +1303,9 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
|
||||
weapon_info *wip = get_turret_weapon_wip(&ssp->weapons, best_weapon_tidx);
|
||||
|
||||
float weapon_system_strength = ship_get_subsystem_strength(&Ships[ssp->parent_objnum], SUBSYSTEM_WEAPONS);
|
||||
float weapon_system_strength = ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS);
|
||||
|
||||
turret_ai_update_aim(&Ai_info[Ships[ssp->parent_objnum].ai_index], &Objects[ssp->turret_enemy_objnum], ssp);
|
||||
turret_ai_update_aim(&Ai_info[shipp->ai_index], &Objects[ssp->turret_enemy_objnum], ssp);
|
||||
|
||||
if ((ssp->targeted_subsys != nullptr) && !(ssp->flags[Ship::Subsystem_Flags::No_SS_targeting])) {
|
||||
vm_vec_unrotate(&enemy_point, &ssp->targeted_subsys->system_info->pnt, &Objects[ssp->turret_enemy_objnum].orient);
|
||||
|
||||
@@ -519,19 +519,6 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop an anim instance that is on the anim_render_list from playing
|
||||
*/
|
||||
int anim_stop_playing(anim_instance* instance)
|
||||
{
|
||||
Assert(instance != NULL);
|
||||
|
||||
if ( anim_playing(instance) ) {
|
||||
anim_release_render_instance(instance);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free a particular animation instance that is on the anim_render_list.
|
||||
* Do not call this function to free an animation instance in general (use
|
||||
@@ -866,20 +853,6 @@ int anim_free(anim *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return if an anim is playing or not.
|
||||
*/
|
||||
int anim_playing(anim_instance *ai)
|
||||
{
|
||||
Assert(ai != NULL);
|
||||
if ( ai->frame == NULL )
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Called at the beginning of a mission to initialize any mission dependent anim data.
|
||||
* @todo Redundant?
|
||||
@@ -896,138 +869,6 @@ void anim_level_close()
|
||||
anim_release_all_instances();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the frames of a .ani file out to disk as .pcx files.
|
||||
* @details Use naming convention: filename0000.pcx, filename0001.pcx etc.
|
||||
*
|
||||
* @return If success 0, or if failed -1
|
||||
*/
|
||||
int anim_write_frames_out(char *filename)
|
||||
{
|
||||
anim *source_anim;
|
||||
anim_instance *ai;
|
||||
char root_name[256], pcxname[256];
|
||||
char buf[64];
|
||||
int i,j;
|
||||
ubyte **row_data;
|
||||
|
||||
strcpy_s(root_name, filename);
|
||||
root_name[strlen(filename)-4] = 0;
|
||||
|
||||
source_anim = anim_load(filename);
|
||||
if ( source_anim == NULL )
|
||||
return -1;
|
||||
|
||||
ai = init_anim_instance(source_anim, 16);
|
||||
|
||||
row_data = (ubyte**)vm_malloc((source_anim->height+1) * 4);
|
||||
|
||||
for ( i = 0; i < source_anim->total_frames; i++ ) {
|
||||
anim_get_next_raw_buffer(ai, 0, 0, 16);
|
||||
strcpy_s(pcxname, root_name);
|
||||
sprintf(buf,"%04d",i);
|
||||
strcat_s(pcxname, buf);
|
||||
|
||||
for ( j = 0; j < source_anim->height; j++ ) {
|
||||
row_data[j] = &ai->frame[j*source_anim->width];
|
||||
}
|
||||
|
||||
|
||||
pcx_write_bitmap( pcxname,
|
||||
source_anim->width,
|
||||
source_anim->height,
|
||||
row_data,
|
||||
source_anim->palette);
|
||||
|
||||
printf(".");
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
vm_free(row_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display information and statistics about a .ani file.
|
||||
* @details This is called when -i switch is on when running ac.exe
|
||||
*/
|
||||
void anim_display_info(char *real_filename)
|
||||
{
|
||||
CFILE *fp;
|
||||
anim A;
|
||||
float percent;
|
||||
int i, uncompressed, compressed, *key_frame_nums=NULL, tmp;
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
|
||||
strcpy_s( filename, real_filename );
|
||||
char *p = strchr( filename, '.' );
|
||||
if ( p ) {
|
||||
*p = 0;
|
||||
}
|
||||
strcat_s( filename, ".ani" );
|
||||
|
||||
fp = cfopen(filename, "rb");
|
||||
if ( !fp ) {
|
||||
printf("Fatal error opening %s", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
anim_read_header(&A, fp);
|
||||
|
||||
if (A.width < 0 || A.height < 0) {
|
||||
Error(LOCATION, "Ani file %s has a faulty header and cannot be loaded.", filename);
|
||||
}
|
||||
|
||||
// read the keyframe frame nums and offsets
|
||||
key_frame_nums = (int*)vm_malloc(sizeof(int)*A.num_keys);
|
||||
Assert(key_frame_nums != NULL);
|
||||
if (key_frame_nums == NULL)
|
||||
return;
|
||||
|
||||
for ( i = 0; i < A.num_keys; i++ ) {
|
||||
key_frame_nums[i] = 0;
|
||||
cfread(&key_frame_nums[i], 2, 1, fp);
|
||||
cfread(&tmp, 4, 1, fp);
|
||||
}
|
||||
|
||||
cfread(&compressed, 4, 1, fp);
|
||||
|
||||
uncompressed = A.width * A.height * A.total_frames; // 8 bits per pixel
|
||||
percent = i2fl(compressed) / uncompressed * 100.0f;
|
||||
|
||||
printf("%% of uncompressed size: %.0f%%\n", percent);
|
||||
printf("Width: %d\n", A.width);
|
||||
printf("Height: %d\n", A.height);
|
||||
printf("Total Frames: %d\n", A.total_frames);
|
||||
|
||||
#ifndef NDEBUG
|
||||
printf("Key Frames: %d\n", A.num_keys);
|
||||
if ( A.num_keys > 1 && (A.total_frames != A.num_keys) ) {
|
||||
printf("key list: (");
|
||||
for ( i = 0; i < A.num_keys; i++ ) {
|
||||
if ( i < A.num_keys-1 )
|
||||
printf("%d, ", key_frame_nums[i]);
|
||||
else
|
||||
printf("%d)\n", key_frame_nums[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("FPS: %d\n", A.fps);
|
||||
|
||||
#ifndef NDEBUG
|
||||
printf("Transparent RGB: (%u,%u,%u)\n", A.xparent_r, A.xparent_g, A.xparent_b);
|
||||
#endif
|
||||
|
||||
printf("ac version: %d\n", A.version);
|
||||
|
||||
if ( key_frame_nums != NULL ) {
|
||||
vm_free(key_frame_nums);
|
||||
}
|
||||
|
||||
cfclose(fp);
|
||||
}
|
||||
|
||||
void anim_reverse_direction(anim_instance *ai)
|
||||
{
|
||||
int temp;
|
||||
@@ -1061,16 +902,6 @@ void anim_reverse_direction(anim_instance *ai)
|
||||
}
|
||||
}
|
||||
|
||||
void anim_pause(anim_instance *ai)
|
||||
{
|
||||
ai->paused = 1;
|
||||
}
|
||||
|
||||
void anim_unpause(anim_instance *ai)
|
||||
{
|
||||
ai->paused = 0;
|
||||
}
|
||||
|
||||
void anim_ignore_next_frametime()
|
||||
{
|
||||
Anim_ignore_frametime=1;
|
||||
|
||||
@@ -54,19 +54,13 @@ void anim_render_one(int screen_id, anim_instance *ani, float frametime);
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int max_x = -1, int max_y = -1);
|
||||
anim_instance *anim_play(anim_play_struct *aps);
|
||||
void anim_ignore_next_frametime();
|
||||
int anim_stop_playing(anim_instance* anim_instance);
|
||||
int anim_show_next_frame(anim_instance *instance, float frametime);
|
||||
void anim_release_all_instances(int screen_id = 0);
|
||||
void anim_release_render_instance(anim_instance* instance);
|
||||
anim *anim_load(const char *name, int cf_dir_type = CF_TYPE_ANY, int file_mapped = PAGE_FROM_DISK);
|
||||
int anim_free(anim *ptr);
|
||||
int anim_playing(anim_instance *ai);
|
||||
int anim_write_frames_out(char *filename);
|
||||
void anim_display_info(char *filename);
|
||||
void anim_read_header(anim *ptr, CFILE *fp);
|
||||
void anim_reverse_direction(anim_instance *ai); // called automatically for ping-ponging, and can also be called externally
|
||||
void anim_pause(anim_instance *ai);
|
||||
void anim_unpause(anim_instance *ai);
|
||||
|
||||
int anim_instance_is_streamed(anim_instance *ai);
|
||||
unsigned char anim_instance_get_byte(anim_instance *ai, int offset);
|
||||
|
||||
@@ -78,52 +78,6 @@ void free_anim_instance(anim_instance *inst)
|
||||
vm_free(inst);
|
||||
}
|
||||
|
||||
int anim_get_next_frame(anim_instance *inst)
|
||||
{
|
||||
int bm, bitmap_flags;
|
||||
int aabitmap = 0;
|
||||
int bpp = 16;
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
if ( inst->file_offset <= 0 ) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!inst->data)
|
||||
return -1;
|
||||
}
|
||||
|
||||
inst->frame_num++;
|
||||
if (inst->frame_num >= inst->parent->total_frames) {
|
||||
inst->data = NULL;
|
||||
inst->file_offset = inst->parent->file_offset;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bitmap_flags = 0;
|
||||
|
||||
bpp = 16;
|
||||
if(inst->aa_color != NULL){
|
||||
bitmap_flags |= BMP_AABITMAP;
|
||||
aabitmap = 1;
|
||||
bpp = 8;
|
||||
}
|
||||
|
||||
anim_check_for_palette_change(inst);
|
||||
|
||||
BM_SELECT_TEX_FORMAT();
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
|
||||
} else {
|
||||
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
|
||||
}
|
||||
|
||||
bm = bm_create(bpp, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
|
||||
bm_unload(bm);
|
||||
return bm;
|
||||
}
|
||||
|
||||
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
|
||||
{
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
@@ -162,321 +116,6 @@ ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap
|
||||
return inst->frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack key frame
|
||||
*
|
||||
* @param frame Frame pixel data to pack
|
||||
* @param save Memory to store packed data to
|
||||
* @param size Number of bytes to pack
|
||||
* @param max Maximum number of packed bytes (size of buffer)
|
||||
* @param compress_type Compress type
|
||||
* @return Actual number of bytes data packed to or -1 if error
|
||||
*/
|
||||
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
|
||||
{
|
||||
int last = -32768, count = 0;
|
||||
long packed_size = 1;
|
||||
|
||||
switch ( compress_type ) {
|
||||
case PACKING_METHOD_RLE_KEY:
|
||||
*save++ = PACKING_METHOD_RLE_KEY;
|
||||
while (size--) {
|
||||
if (*frame != last || count > 255) {
|
||||
if (packed_size + 3 >= max)
|
||||
return -1;
|
||||
|
||||
if (count < 3) {
|
||||
if (last == packer_code) {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
packed_size += 2;
|
||||
|
||||
} else
|
||||
while (count--) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
}
|
||||
|
||||
} else {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 3;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
last = *frame;
|
||||
}
|
||||
|
||||
count++;
|
||||
frame++;
|
||||
}
|
||||
|
||||
if (packed_size + 3 >= max)
|
||||
return -1;
|
||||
|
||||
if (count < 3) {
|
||||
if (last == packer_code) {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
packed_size += 2;
|
||||
|
||||
} else
|
||||
while (count--) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
}
|
||||
|
||||
} else {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case PACKING_METHOD_STD_RLE_KEY: {
|
||||
ubyte *dest_start;
|
||||
int i;
|
||||
|
||||
dest_start = save;
|
||||
count = 1;
|
||||
|
||||
last = *frame++;
|
||||
*save++ = PACKING_METHOD_STD_RLE_KEY;
|
||||
for (i=1; i < size; i++ ) {
|
||||
|
||||
if ( *frame != last ) {
|
||||
if ( count ) {
|
||||
|
||||
if (packed_size + 2 >= max)
|
||||
return -1;
|
||||
|
||||
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
Assert( last != STD_RLE_CODE );
|
||||
}
|
||||
else {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
}
|
||||
}
|
||||
|
||||
last = *frame;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
count++;
|
||||
frame++;
|
||||
|
||||
if ( count == 127 ) {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
count = 0;
|
||||
}
|
||||
} // end for
|
||||
|
||||
if (count) {
|
||||
|
||||
if (packed_size + 2 >= max)
|
||||
return -1;
|
||||
|
||||
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
Assert( last != STD_RLE_CODE );
|
||||
}
|
||||
else {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(packed_size == (save-dest_start) );
|
||||
return packed_size;
|
||||
}
|
||||
|
||||
default:
|
||||
Assert(0);
|
||||
return -1;
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
return packed_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack frame
|
||||
*
|
||||
* @param frame Frame pixel data to pack
|
||||
* @param frame2 Previous frame's pixel data
|
||||
* @param save Memory to store packed data to
|
||||
* @param size Number of bytes to pack
|
||||
* @param max Maximum number of packed bytes (size of buffer)
|
||||
* @param compress_type Compress type
|
||||
* @return Actual number of bytes data packed to or -1 if error
|
||||
*/
|
||||
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
|
||||
{
|
||||
int pixel, last = -32768, count = 0, i;
|
||||
long packed_size = 1;
|
||||
|
||||
switch ( compress_type ) {
|
||||
case PACKING_METHOD_RLE: // Hoffoss RLE regular frame
|
||||
*save++ = PACKING_METHOD_RLE;
|
||||
while (size--) {
|
||||
if (*frame != *frame2++)
|
||||
pixel = *frame;
|
||||
else
|
||||
pixel = transparent_code;
|
||||
|
||||
if (pixel != last || count > 255) {
|
||||
if (packed_size + 3 >= max)
|
||||
return -1;
|
||||
|
||||
if (count < 3) {
|
||||
if (last == packer_code) {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
packed_size += 2;
|
||||
|
||||
} else
|
||||
while (count--) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
}
|
||||
|
||||
} else {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 3;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
last = pixel;
|
||||
}
|
||||
|
||||
frame++;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (packed_size + 3 >= max)
|
||||
return -1;
|
||||
|
||||
if (count < 3) {
|
||||
if (last == packer_code) {
|
||||
*save++ = (ubyte)packer_code;
|
||||
*save++ = (ubyte)(count - 1);
|
||||
packed_size += 2;
|
||||
|
||||
} else
|
||||
while (count--) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
}
|
||||
|
||||
} else {
|
||||
*save++ = (ubyte)(packer_code);
|
||||
*save++ = (ubyte)(count - 1);
|
||||
*save++ = (ubyte)(last);
|
||||
packed_size += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case PACKING_METHOD_STD_RLE: { // high bit count regular RLE frame
|
||||
|
||||
ubyte *dest_start;
|
||||
|
||||
dest_start = save;
|
||||
count = 1;
|
||||
|
||||
if (*frame++ != *frame2++)
|
||||
last = *frame;
|
||||
else
|
||||
last = transparent_code;
|
||||
|
||||
*save++ = PACKING_METHOD_STD_RLE;
|
||||
for (i=1; i < size; i++ ) {
|
||||
|
||||
if (*frame != *frame2++)
|
||||
pixel = *frame;
|
||||
else
|
||||
pixel = transparent_code;
|
||||
|
||||
if ( pixel != last ) {
|
||||
if ( count ) {
|
||||
|
||||
if (packed_size + 2 >= max)
|
||||
return -1;
|
||||
|
||||
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
Assert( last != STD_RLE_CODE );
|
||||
}
|
||||
else {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
}
|
||||
}
|
||||
|
||||
last = pixel;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
count++;
|
||||
frame++;
|
||||
|
||||
if ( count == 127 ) {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
count = 0;
|
||||
}
|
||||
} // end for
|
||||
|
||||
if (count) {
|
||||
|
||||
if (packed_size + 2 >= max)
|
||||
return -1;
|
||||
|
||||
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
|
||||
*save++ = (ubyte)last;
|
||||
packed_size++;
|
||||
Assert( last != STD_RLE_CODE );
|
||||
}
|
||||
else {
|
||||
count |= STD_RLE_CODE;
|
||||
*save++ = (ubyte)count;
|
||||
*save++ = (ubyte)last;
|
||||
packed_size += 2;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(packed_size == (save-dest_start) );
|
||||
return packed_size;
|
||||
}
|
||||
|
||||
default:
|
||||
Assert(0);
|
||||
return -1;
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
return packed_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a 24 bit value to a 16 bit value
|
||||
* @param bit_24 24 bit value
|
||||
|
||||
@@ -97,16 +97,12 @@ typedef struct anim_instance {
|
||||
int loop_count; // starts at 0, and is incremented each time it loops
|
||||
} anim_instance;
|
||||
|
||||
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type);
|
||||
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type);
|
||||
|
||||
ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp);
|
||||
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp);
|
||||
|
||||
void anim_init();
|
||||
anim_instance *init_anim_instance(anim *ptr, int bpp);
|
||||
void free_anim_instance(anim_instance *inst);
|
||||
int anim_get_next_frame(anim_instance *inst);
|
||||
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
|
||||
void anim_set_palette(anim *a);
|
||||
void anim_check_for_palette_change(anim_instance *inst);
|
||||
|
||||
@@ -1143,8 +1143,6 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
|
||||
// SET PHYSICS PARAMETERS
|
||||
// already have (hitpos - heavy) and light_cm_pos
|
||||
// get heavy cm pos - already have light_cm_pos
|
||||
asteroid_hit_info->heavy_collision_cm_pos = zero;
|
||||
|
||||
// get r_heavy and r_light
|
||||
asteroid_hit_info->r_heavy = asteroid_hit_info->hit_pos;
|
||||
@@ -1263,7 +1261,7 @@ static float asteroid_create_explosion(object *objp)
|
||||
|
||||
fireball_scale_multiplier = asteroid_get_fireball_scale_multiplier(objp->instance);
|
||||
|
||||
fireball_objnum = fireball_create( &objp->pos, fireball_type, FIREBALL_LARGE_EXPLOSION, OBJ_INDEX(objp), objp->radius*fireball_scale_multiplier, 0, &objp->phys_info.vel );
|
||||
fireball_objnum = fireball_create( &objp->pos, fireball_type, FIREBALL_LARGE_EXPLOSION, OBJ_INDEX(objp), objp->radius*fireball_scale_multiplier, false, &objp->phys_info.vel );
|
||||
if ( fireball_objnum > -1 ) {
|
||||
explosion_life = fireball_lifeleft(&Objects[fireball_objnum]);
|
||||
} else {
|
||||
|
||||
@@ -122,31 +122,6 @@ vec3d *NavPoint::GetPosition()
|
||||
}
|
||||
}
|
||||
|
||||
char* NavPoint::GetInternalName()
|
||||
{
|
||||
char *NavName;
|
||||
char strtmp[33];
|
||||
|
||||
if (flags & NP_WAYPOINT)
|
||||
{
|
||||
NavName = new char[strlen(((waypoint_list*)target_obj)->get_name())+5];
|
||||
memset(NavName, 0, strlen(((waypoint_list*)target_obj)->get_name())+5);
|
||||
strcpy(NavName, ((waypoint_list*)target_obj)->get_name());
|
||||
|
||||
strcat(NavName, ":");
|
||||
sprintf(strtmp, "%d", waypoint_num);
|
||||
strcat(NavName, strtmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
NavName = new char[strlen(((ship*)target_obj)->ship_name)+1];
|
||||
memset(NavName, 0, strlen(((ship*)target_obj)->ship_name)+1);
|
||||
strcpy(NavName, ((ship*)target_obj)->ship_name);
|
||||
}
|
||||
|
||||
return NavName;
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg)
|
||||
{
|
||||
@@ -998,7 +973,6 @@ camera* nav_get_set_camera()
|
||||
return nav_camera.getCamera();
|
||||
}
|
||||
|
||||
extern int Cmdline_old_collision_sys;
|
||||
void nav_warp(bool prewarp=false)
|
||||
{
|
||||
/* ok... find our end distance - norm1 is still a unit vector in the
|
||||
@@ -1053,11 +1027,7 @@ void nav_warp(bool prewarp=false)
|
||||
}
|
||||
|
||||
// retime all collision pairs
|
||||
if ( Cmdline_old_collision_sys ) {
|
||||
obj_all_collisions_retime();
|
||||
} else {
|
||||
obj_collide_retime_cached_pairs();
|
||||
}
|
||||
obj_collide_retime_cached_pairs();
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -1464,22 +1434,6 @@ bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags)
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
//Change Flags
|
||||
bool Nav_Alt_Flags(char *Nav, int flags)
|
||||
{
|
||||
flags &= ~NP_VALIDTYPE; //clear the NP_SHIP and NP_WAYPOINT bits, make sure they haven't been set
|
||||
|
||||
int nav = FindNav(Nav);
|
||||
|
||||
if (nav != -1)
|
||||
{
|
||||
Navs[nav].flags &= NP_VALIDTYPE; // Clear all bits BUT NP_SHIP or NO_WAYPOINT
|
||||
Navs[nav].flags |= flags; // merge
|
||||
}
|
||||
|
||||
return (nav != -1);
|
||||
}
|
||||
|
||||
//Get Flags
|
||||
int Nav_Get_Flags(char *Nav)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,6 @@ public:
|
||||
int waypoint_num; //only used when flags & NP_WAYPOINT
|
||||
|
||||
vec3d *GetPosition();
|
||||
char* GetInternalName();
|
||||
|
||||
void clear()
|
||||
{
|
||||
@@ -129,9 +128,6 @@ void SelectNav(char *Nav);
|
||||
// Deselects any navpoint selected.
|
||||
void DeselectNav();
|
||||
|
||||
// Set A Nav point to "ZERO"
|
||||
void ZeroNav(int i);
|
||||
|
||||
// Removes a Nav
|
||||
bool DelNavPoint(char *Nav);
|
||||
bool DelNavPoint(int nav);
|
||||
@@ -140,9 +136,6 @@ bool DelNavPoint(int nav);
|
||||
bool AddNav_Ship(char *Nav, char *TargetName, int flags);
|
||||
bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags);
|
||||
|
||||
//Change Flags
|
||||
bool Nav_Alt_Flags(char *Nav, int flags);
|
||||
|
||||
// Sexp Accessors
|
||||
bool Nav_Set_Flag(char *Nav, int flag);
|
||||
bool Nav_UnSet_Flag(char *Nav, int flag);
|
||||
|
||||
@@ -67,9 +67,7 @@ struct bitmap_entry {
|
||||
char filename[MAX_FILENAME_LEN]; //!< filename for this bitmap
|
||||
|
||||
uint signature; //!< a unique signature identifying the data
|
||||
uint palette_checksum; //!< checksum used to be sure bitmap is in current palette
|
||||
int handle; //!< Handle = id*MAX_BITMAPS + bitmapnum
|
||||
int last_used; //!< When this bitmap was last used
|
||||
|
||||
BM_TYPE type; //!< PCX, USER, ANI, etc
|
||||
BM_TYPE comp_type; //!< What sort of compressed type, BM_TYPE_NONE if not compressed
|
||||
|
||||
@@ -55,14 +55,7 @@ MONITOR(SizeBitmapPage)
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Definition of public variables (declared as extern in bmpman.h).
|
||||
int GLOWMAP = -1;
|
||||
int SPECMAP = -1;
|
||||
int SPECGLOSSMAP = -1;
|
||||
int ENVMAP = -1;
|
||||
int NORMMAP = -1;
|
||||
int HEIGHTMAP = -1;
|
||||
int MISCMAP = -1;
|
||||
int AMBIENTMAP = -1;
|
||||
|
||||
size_t bm_texture_ram = 0;
|
||||
int Bm_paging = 0;
|
||||
@@ -80,11 +73,6 @@ const char *bm_ani_ext_list[] = { ".eff", ".ani", ".png" };
|
||||
const int BM_ANI_NUM_TYPES = sizeof(bm_ani_type_list) / sizeof(bm_ani_type_list[0]);
|
||||
|
||||
void(*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) = NULL;
|
||||
void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) = NULL;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Declaration of protected variables (defined in cmdline.cpp).
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Definition of public variables (declared as extern in bm_internal.h).
|
||||
@@ -193,42 +181,6 @@ float bitmap_lookup::map_texture_address(float address)
|
||||
return address - floorf(address);
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_red(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
CLAMP(u, 0.0f, 1.0f);
|
||||
CLAMP(v, 0.0f, 1.0f);
|
||||
|
||||
int x = fl2i(map_texture_address(u) * (Width-1));
|
||||
int y = fl2i(map_texture_address(v) * (Height-1));
|
||||
|
||||
return i2fl(Bitmap_data[(y*Width + x)*Num_channels]) / 255.0f;
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_green(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
CLAMP(u, 0.0, 1.0f);
|
||||
CLAMP(v, 0.0, 1.0f);
|
||||
|
||||
int x = fl2i(map_texture_address(u) * (Width-1));
|
||||
int y = fl2i(map_texture_address(v) * (Height-1));
|
||||
|
||||
return i2fl(Bitmap_data[(y*Width + x)*Num_channels + 1]) / 255.0f;
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_blue(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
int x = fl2i(map_texture_address(u) * (Width-1));
|
||||
int y = fl2i(map_texture_address(v) * (Height-1));
|
||||
|
||||
return i2fl(Bitmap_data[(y*Width + x)*Num_channels + 2]) / 255.0f;
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_alpha(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
@@ -594,7 +546,6 @@ int bm_create(int bpp, int w, int h, void *data, int flags) {
|
||||
sprintf_safe(entry->filename, "TMP%dx%d+%d", w, h, bpp);
|
||||
entry->type = BM_TYPE_USER;
|
||||
entry->comp_type = BM_TYPE_NONE;
|
||||
entry->palette_checksum = 0;
|
||||
|
||||
entry->bm.w = (short)w;
|
||||
entry->bm.h = (short)h;
|
||||
@@ -612,7 +563,6 @@ int bm_create(int bpp, int w, int h, void *data, int flags) {
|
||||
entry->signature = Bm_next_signature++;
|
||||
|
||||
entry->handle = n;
|
||||
entry->last_used = -1;
|
||||
entry->mem_taken = (w * h * (bpp >> 3));
|
||||
|
||||
entry->load_count++;
|
||||
@@ -958,16 +908,6 @@ void bm_get_palette(int handle, ubyte *pal, char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
uint bm_get_signature(int handle) {
|
||||
Assertion(bm_inited, "bmpman must be initialized before this function can be called!");
|
||||
|
||||
return bm_get_entry(handle)->signature;
|
||||
}
|
||||
|
||||
size_t bm_get_size(int handle) {
|
||||
return bm_get_entry(handle)->mem_taken;
|
||||
}
|
||||
|
||||
int bm_get_tcache_type(int num) {
|
||||
if (bm_is_compressed(num))
|
||||
return TCACHE_TYPE_COMPRESSED;
|
||||
@@ -1268,9 +1208,7 @@ int bm_load(const char *real_filename) {
|
||||
entry->num_mipmaps = mm_lvl;
|
||||
entry->mem_taken = (size_t)bm_size;
|
||||
entry->dir_type = CF_TYPE_ANY;
|
||||
entry->palette_checksum = 0;
|
||||
entry->handle = handle;
|
||||
entry->last_used = -1;
|
||||
|
||||
entry->load_count++;
|
||||
|
||||
@@ -1733,10 +1671,8 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
entry->bm.palette = nullptr;
|
||||
entry->type = type;
|
||||
entry->comp_type = c_type;
|
||||
entry->palette_checksum = 0;
|
||||
entry->signature = Bm_next_signature++;
|
||||
entry->handle = n + i;
|
||||
entry->last_used = -1;
|
||||
entry->num_mipmaps = mm_lvl;
|
||||
entry->mem_taken = (size_t)img_size;
|
||||
entry->dir_type = dir_type;
|
||||
@@ -1979,8 +1915,6 @@ bitmap * bm_lock(int handle, int bpp, ubyte flags, bool nodebug) {
|
||||
// Mark all the bitmaps in this bitmap or animation as recently used
|
||||
auto frame_entry = bm_get_entry(first + i);
|
||||
|
||||
frame_entry->last_used = timer_get_milliseconds();
|
||||
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
// Mark all the bitmaps in this bitmap or animation as used for the usage tracker.
|
||||
frame_entry->used_count++;
|
||||
@@ -1989,9 +1923,6 @@ bitmap * bm_lock(int handle, int bpp, ubyte flags, bool nodebug) {
|
||||
frame_entry->used_flags = flags;
|
||||
}
|
||||
} else {
|
||||
// Mark all the bitmaps in this bitmap or animation as recently used
|
||||
be->last_used = timer_get_milliseconds();
|
||||
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
// Mark all the bitmaps in this bitmap or animation as used for the usage tracker.
|
||||
be->used_count++;
|
||||
@@ -2536,9 +2467,7 @@ int bm_make_render_target(int width, int height, int flags) {
|
||||
entry->mem_taken = (size_t)size;
|
||||
entry->dir_type = CF_TYPE_ANY;
|
||||
|
||||
entry->palette_checksum = 0;
|
||||
entry->handle = n;
|
||||
entry->last_used = -1;
|
||||
|
||||
if (entry->mem_taken) {
|
||||
entry->bm.data = (ptr_u)bm_malloc(n, entry->mem_taken);
|
||||
@@ -2775,30 +2704,6 @@ void bm_page_in_xparent_texture(int bitmapnum, int nframes) {
|
||||
}
|
||||
}
|
||||
|
||||
bool bm_page_out(int handle) {
|
||||
auto entry = bm_get_entry(handle);
|
||||
|
||||
// in case it's already been released
|
||||
if (entry->type == BM_TYPE_NONE)
|
||||
return 0;
|
||||
|
||||
// it's possible to hit < 0 here when model_page_out_textures() is
|
||||
// called from anywhere other than in a mission
|
||||
if (entry->preload_count > 0) {
|
||||
nprintf(("BmpMan",
|
||||
"PAGE-OUT: %s - preload_count remaining: %d\n",
|
||||
entry->filename,
|
||||
entry->preload_count));
|
||||
|
||||
// lets decrease it for next time around
|
||||
entry->preload_count--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (bm_unload(handle) == 1);
|
||||
}
|
||||
|
||||
void bm_print_bitmaps() {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
for (auto& block : bm_blocks) {
|
||||
@@ -2884,7 +2789,6 @@ int bm_release(int handle, int clear_render_targets) {
|
||||
// For debugging:
|
||||
strcpy_s(entry->filename, "IVE_BEEN_RELEASED!");
|
||||
entry->signature = 0xDEADBEEF; // a unique signature identifying the data
|
||||
entry->palette_checksum = 0xDEADBEEF; // checksum used to be sure bitmap is in current palette
|
||||
|
||||
// bookeeping
|
||||
entry->ref_count = -1; // Number of locks on bitmap. Can't unload unless ref_count is 0.
|
||||
@@ -2911,7 +2815,6 @@ int bm_release(int handle, int clear_render_targets) {
|
||||
// For debugging:
|
||||
strcpy_s(entry->filename, "IVE_BEEN_RELEASED!");
|
||||
entry->signature = 0xDEADBEEF; // a unique signature identifying the data
|
||||
entry->palette_checksum = 0xDEADBEEF; // checksum used to be sure bitmap is in current palette
|
||||
|
||||
// bookeeping
|
||||
entry->ref_count = -1; // Number of locks on bitmap. Can't unload unless ref_count is 0.
|
||||
@@ -2953,7 +2856,6 @@ void BM_SELECT_ALPHA_TEX_FORMAT() {
|
||||
Gr_current_alpha = &Gr_ta_alpha;
|
||||
|
||||
// setup pointers
|
||||
bm_set_components_32 = bm_set_components_argb_32_tex;
|
||||
// should always assume that 16-bit is the default request
|
||||
bm_set_components = bm_set_components_argb_16_tex;
|
||||
}
|
||||
@@ -2965,7 +2867,6 @@ void BM_SELECT_SCREEN_FORMAT() {
|
||||
Gr_current_alpha = &Gr_alpha;
|
||||
|
||||
// setup pointers
|
||||
bm_set_components_32 = bm_set_components_argb_32_screen;
|
||||
// should always assume that 16-bit is the default request
|
||||
bm_set_components = bm_set_components_argb_16_screen;
|
||||
}
|
||||
@@ -2977,7 +2878,6 @@ void BM_SELECT_TEX_FORMAT() {
|
||||
Gr_current_alpha = &Gr_t_alpha;
|
||||
|
||||
// setup pointers
|
||||
bm_set_components_32 = bm_set_components_argb_32_tex;
|
||||
// should always assume that 16-bit is the default request
|
||||
bm_set_components = bm_set_components_argb_16_tex;
|
||||
}
|
||||
@@ -3005,29 +2905,6 @@ void bm_set_components_argb_16_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv
|
||||
*((unsigned short*)pixel) |= (unsigned short)(Gr_current_alpha->mask);
|
||||
}
|
||||
|
||||
void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) {
|
||||
if (*av == 0) {
|
||||
*((unsigned int*)pixel) = (unsigned int)Gr_current_green->mask;
|
||||
return;
|
||||
}
|
||||
|
||||
*((unsigned int*)pixel) = (unsigned int)(((int)*rv / Gr_current_red->scale) << Gr_current_red->shift);
|
||||
*((unsigned int*)pixel) |= (unsigned int)(((int)*gv / Gr_current_green->scale) << Gr_current_green->shift);
|
||||
*((unsigned int*)pixel) |= (unsigned int)(((int)*bv / Gr_current_blue->scale) << Gr_current_blue->shift);
|
||||
}
|
||||
|
||||
void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) {
|
||||
if (*av == 0) {
|
||||
*((unsigned int*)pixel) = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*((unsigned int*)pixel) = (unsigned int)(((int)*rv / Gr_current_red->scale) << Gr_current_red->shift);
|
||||
*((unsigned int*)pixel) |= (unsigned int)(((int)*gv / Gr_current_green->scale) << Gr_current_green->shift);
|
||||
*((unsigned int*)pixel) |= (unsigned int)(((int)*bv / Gr_current_blue->scale) << Gr_current_blue->shift);
|
||||
*((unsigned int*)pixel) |= (unsigned int)(Gr_current_alpha->mask);
|
||||
}
|
||||
|
||||
void bm_set_low_mem(int mode) {
|
||||
Assert((mode >= 0) && (mode <= 2));
|
||||
|
||||
|
||||
@@ -113,12 +113,7 @@ extern const BM_TYPE bm_ani_type_list[]; //!< List of valid bitmap animation t
|
||||
extern const char *bm_ani_ext_list[]; //!< List of extensions for those types
|
||||
extern const int BM_ANI_NUM_TYPES; //!< Calculated number of bitmap animation types
|
||||
|
||||
extern int GLOWMAP; //!< References a map that is a fully lit version of its index -Bobboau
|
||||
extern int SPECMAP; //!< References a map that is for specular mapping -Bobboau
|
||||
extern int ENVMAP; //!< References a map that is for environment mapping -Bobboau
|
||||
extern int NORMMAP; //!< Normal mapping
|
||||
extern int HEIGHTMAP; //!< Height map for normal mapping
|
||||
extern int MISCMAP; //!< Utility map, to be utilized for various things shader authors can come up with
|
||||
|
||||
/**
|
||||
* @brief Initilizes the bitmap manager
|
||||
@@ -167,9 +162,6 @@ public:
|
||||
|
||||
bool valid();
|
||||
|
||||
float get_channel_red(float u, float v);
|
||||
float get_channel_green(float u, float v);
|
||||
float get_channel_blue(float u, float v);
|
||||
float get_channel_alpha(float u, float v);
|
||||
};
|
||||
|
||||
@@ -311,13 +303,6 @@ int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, i
|
||||
*/
|
||||
bitmap* bm_lock(int handle, int bpp, ubyte flags, bool nodebug = false);
|
||||
|
||||
/**
|
||||
* @brief Returns a unique signiature for the bitmap indexed by handle
|
||||
*
|
||||
* @details A signature will change when the bitmap's data changes
|
||||
*/
|
||||
uint bm_get_signature(int handle);
|
||||
|
||||
/**
|
||||
* @brief Returns the image type of the given bitmap handle
|
||||
*/
|
||||
@@ -459,15 +444,6 @@ void bm_page_in_xparent_texture(int bitmapnum, int num_frames = 1);
|
||||
*/
|
||||
void bm_page_in_aabitmap(int bitmapnum, int num_frames = 1);
|
||||
|
||||
/**
|
||||
* @brief Unloads the bitmap indexed by handle that was previously paged-in
|
||||
*
|
||||
* @returns 0 If the bitmap had already been released, or
|
||||
* @returns 0 If the handle is invalid, or
|
||||
* @returns 1 If successful
|
||||
*/
|
||||
bool bm_page_out(int handle);
|
||||
|
||||
/**
|
||||
* @brief Sets BMPMAN's memory mode
|
||||
*
|
||||
@@ -516,16 +492,6 @@ void BM_SELECT_ALPHA_TEX_FORMAT();
|
||||
*/
|
||||
extern void(*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Functional pointer that references any of the bm_set_components_32 functions.
|
||||
*
|
||||
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
|
||||
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
extern void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 16bpp screen pixel to the specified RGBA value
|
||||
*
|
||||
@@ -533,13 +499,6 @@ extern void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, u
|
||||
*/
|
||||
void bm_set_components_argb_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 32bpp screen pixel to the specified RGBA value
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 16bpp texture pixel to the specified RGBA value
|
||||
*
|
||||
@@ -561,15 +520,7 @@ void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, u
|
||||
*/
|
||||
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
extern int UNLITMAP; //this holds a reference to a map that is optional used instead of the base map for unlit rendering
|
||||
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 SPECGLOSSMAP; //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 NORMMAP; // normal mapping
|
||||
extern int HEIGHTMAP; // height map for normal mapping
|
||||
extern int AMBIENTMAP; // ambient occluion map. red channel affects ambient lighting, green channel affects diffuse and specular
|
||||
extern int MISCMAP; // Utility map, to be utilized for various things shader authors can come up with
|
||||
|
||||
/**
|
||||
* @brief Returns the compression type of the bitmap indexed by handle
|
||||
@@ -581,10 +532,6 @@ int bm_is_compressed(int handle);
|
||||
*/
|
||||
int bm_get_tcache_type(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets the size, in bytes, taken up by the bitmap indexed by handle
|
||||
*/
|
||||
size_t bm_get_size(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of mipmaps of the indexed texture
|
||||
|
||||
+21
-15
@@ -7,9 +7,10 @@
|
||||
#include "math/vecmat.h"
|
||||
#include "mod_table/mod_table.h"
|
||||
#include "model/model.h" //polymodel, model_get
|
||||
#include "options/Option.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "playerman/player.h" //player_get_padlock_orient
|
||||
#include "ship/ship.h" //compute_slew_matrix
|
||||
#include "ship/ship.h" //compute_slew_matrix
|
||||
|
||||
//*************************IMPORTANT GLOBALS*************************
|
||||
float VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
|
||||
@@ -24,6 +25,23 @@ SCP_vector<camera*> Cameras;
|
||||
camid Current_camera;
|
||||
camid Main_camera;
|
||||
|
||||
static SCP_string fov_display(float val)
|
||||
{
|
||||
auto degrees = fl_degrees(val);
|
||||
SCP_string out;
|
||||
sprintf(out, u8"%.1f\u00B0", degrees);
|
||||
return out;
|
||||
}
|
||||
auto FovOption = options::OptionBuilder<float>("Graphics.FOV", "Field Of View", "The vertical field of view.")
|
||||
.category("Graphics")
|
||||
.range(0.436332f, 1.5708f)
|
||||
.bind_to(&VIEWER_ZOOM_DEFAULT)
|
||||
.display(fov_display)
|
||||
.default_val(0.75f)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(60)
|
||||
.finish();
|
||||
|
||||
//*************************CLASS: camera*************************
|
||||
//This is where the camera class beings! :D
|
||||
camera::camera(const char *in_name, int in_signature)
|
||||
@@ -145,7 +163,7 @@ void camera::set_object_target(object *objp, int n_object_target_submodel)
|
||||
* Custom function receives the already-modified current position value.
|
||||
* It should be replaced or added to as the custom function modifier sees fit.
|
||||
*/
|
||||
void camera::set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *camera_pos))
|
||||
void camera::set_custom_position_function(void (*n_func_custom_position)(camera* /*cam*/, vec3d* /*camera_pos*/))
|
||||
{
|
||||
func_custom_position = n_func_custom_position;
|
||||
}
|
||||
@@ -154,7 +172,7 @@ void camera::set_custom_position_function(void (*n_func_custom_position)(camera
|
||||
* Custom function receives the already-modified current orientation value.
|
||||
* It should be replaced or added to as the custom function modifier sees fit.
|
||||
*/
|
||||
void camera::set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *camera_ori))
|
||||
void camera::set_custom_orientation_function(void (*n_func_custom_orientation)(camera* /*cam*/, matrix* /*camera_ori*/))
|
||||
{
|
||||
func_custom_orientation = n_func_custom_orientation;
|
||||
}
|
||||
@@ -185,13 +203,6 @@ void camera::set_position(vec3d *in_position, float in_translation_time, float i
|
||||
pos_z.setAVD(in_position->xyz.z, in_translation_time, in_translation_acceleration_time, in_translation_deceleration_time, in_end_velocity);
|
||||
}
|
||||
|
||||
void camera::set_translation_velocity(vec3d *in_velocity, float in_acceleration_time)
|
||||
{
|
||||
pos_x.setVD(in_acceleration_time, in_acceleration_time, in_velocity->xyz.x);
|
||||
pos_y.setVD(in_acceleration_time, in_acceleration_time, in_velocity->xyz.y);
|
||||
pos_z.setVD(in_acceleration_time, in_acceleration_time, in_velocity->xyz.z);
|
||||
}
|
||||
|
||||
void camera::set_rotation(matrix *in_orientation, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
|
||||
{
|
||||
if(in_orientation != NULL && in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f && in_rotation_deceleration_time == 0.0f)
|
||||
@@ -245,11 +256,6 @@ void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float
|
||||
set_rotation(&temp_matrix, in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time);
|
||||
}
|
||||
|
||||
void camera::set_rotation_velocity(angles * /*in_rotation_rate*/, float /*in_acceleration_time*/)
|
||||
{
|
||||
Error(LOCATION, "This function is disabled until further notice.");
|
||||
}
|
||||
|
||||
void camera::do_frame(float /*in_frametime*/)
|
||||
{
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
class camera
|
||||
{
|
||||
friend class avd_camera;
|
||||
protected:
|
||||
char name[NAME_LENGTH];
|
||||
int sig;
|
||||
@@ -60,12 +59,10 @@ public:
|
||||
void set_fov(float in_fov, float in_fov_time = 0.0f, float in_fov_acceleration_time = 0.0f, float in_deceleration_time = 0.0f);
|
||||
|
||||
void set_position(vec3d *in_position = NULL, float in_translation_time = 0.0f, float in_translation_acceleration_time = 0.0f, float in_translation_deceleration_time = 0.0f, float in_end_velocity = 0.0f);
|
||||
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, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation(angles *in_angles, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation_facing(vec3d *in_target, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time = 0.0f);
|
||||
|
||||
//Get
|
||||
const char* get_name() { return name; }
|
||||
|
||||
+114
-257
@@ -101,8 +101,7 @@ static int Cfile_stack_pos = 0;
|
||||
|
||||
static char Cfile_stack[CFILE_STACK_MAX][CFILE_ROOT_DIRECTORY_LEN];
|
||||
|
||||
Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS];
|
||||
static CFILE Cfile_list[MAX_CFILE_BLOCKS];
|
||||
std::array<CFILE, MAX_CFILE_BLOCKS> Cfile_block_list;
|
||||
|
||||
static const char *Cfile_cdrom_dir = NULL;
|
||||
|
||||
@@ -201,7 +200,6 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
|
||||
|
||||
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
buf[CFILE_ROOT_DIRECTORY_LEN - 1] = '\0';
|
||||
size_t i = strlen(buf);
|
||||
|
||||
// are we in a root directory?
|
||||
if(cfile_in_root_dir(buf)){
|
||||
@@ -229,9 +227,8 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
|
||||
strcpy_s(Cfile_root_dir, buf);
|
||||
strcpy_s(Cfile_user_dir, os_get_config_path().c_str());
|
||||
|
||||
for (i = 0; i < MAX_CFILE_BLOCKS; i++) {
|
||||
Cfile_block_list[i].type = CFILE_BLOCK_UNUSED;
|
||||
}
|
||||
// Initialize the block list with proper data
|
||||
Cfile_block_list.fill({});
|
||||
|
||||
// 32 bit CRC table init
|
||||
cf_chksum_long_init();
|
||||
@@ -242,16 +239,6 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Call this if pack files got added or removed or the
|
||||
// cdrom changed. This will refresh the list of filenames
|
||||
// stored in packfiles and on the cdrom.
|
||||
void cfile_refresh()
|
||||
{
|
||||
cf_build_secondary_filelist(Cfile_cdrom_dir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// Changes to a drive if valid.. 1=A, 2=B, etc
|
||||
// If flag, then changes to it.
|
||||
@@ -643,9 +630,6 @@ void cf_create_directory(int dir_type, uint32_t location_flags)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int game_cd_changed();
|
||||
|
||||
// cfopen()
|
||||
//
|
||||
// parameters: *filepath ==> name of file to open (may be path+name)
|
||||
@@ -878,14 +862,14 @@ CFILE *ctmpfile()
|
||||
static int cfget_cfile_block()
|
||||
{
|
||||
int i;
|
||||
Cfile_block *cb;
|
||||
CFILE* cfile;
|
||||
|
||||
for ( i = 0; i < MAX_CFILE_BLOCKS; i++ ) {
|
||||
cb = &Cfile_block_list[i];
|
||||
if ( cb->type == CFILE_BLOCK_UNUSED ) {
|
||||
cb->data = NULL;
|
||||
cb->fp = NULL;
|
||||
cb->type = CFILE_BLOCK_USED;
|
||||
cfile = &Cfile_block_list[i];
|
||||
if (cfile->type == CFILE_BLOCK_UNUSED) {
|
||||
cfile->data = nullptr;
|
||||
cfile->fp = nullptr;
|
||||
cfile->type = CFILE_BLOCK_USED;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -913,39 +897,36 @@ int cfclose( CFILE * cfile )
|
||||
int result;
|
||||
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
result = 0;
|
||||
if ( cb->data && cb->mem_mapped ) {
|
||||
if ( cfile->data && cfile->mem_mapped ) {
|
||||
// close memory mapped file
|
||||
#if defined _WIN32
|
||||
result = UnmapViewOfFile((void*)cb->data);
|
||||
result = UnmapViewOfFile((void*)cfile->data);
|
||||
Assert(result);
|
||||
result = CloseHandle(cb->hInFile);
|
||||
result = CloseHandle(cfile->hInFile);
|
||||
Assert(result); // Ensure file handle is closed properly
|
||||
result = CloseHandle(cb->hMapFile);
|
||||
result = CloseHandle(cfile->hMapFile);
|
||||
Assert(result); // Ensure file handle is closed properly
|
||||
result = 0;
|
||||
#elif defined SCP_UNIX
|
||||
// FIXME: result is wrong after munmap() but it is successful
|
||||
//result = munmap(cb->data, cb->data_length);
|
||||
//result = munmap(cfile->data, cfile->data_length);
|
||||
//Assert(result);
|
||||
// This const_cast is safe since the pointer returned by mmap was also non-const
|
||||
munmap(const_cast<void*>(cb->data), cb->data_length);
|
||||
if ( cb->fp != NULL)
|
||||
result = fclose(cb->fp);
|
||||
munmap(const_cast<void*>(cfile->data), cfile->data_length);
|
||||
if ( cfile->fp != nullptr)
|
||||
result = fclose(cfile->fp);
|
||||
#endif
|
||||
|
||||
} else if ( cb->fp != NULL ) {
|
||||
Assert(cb->fp != NULL);
|
||||
result = fclose(cb->fp);
|
||||
} else if ( cfile->fp != nullptr ) {
|
||||
Assert(cfile->fp != nullptr);
|
||||
result = fclose(cfile->fp);
|
||||
} else {
|
||||
// VP do nothing
|
||||
}
|
||||
|
||||
cb->type = CFILE_BLOCK_UNUSED;
|
||||
cfile->type = CFILE_BLOCK_UNUSED;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -955,13 +936,8 @@ int cf_is_valid(CFILE *cfile)
|
||||
if(cfile == NULL)
|
||||
return 0;
|
||||
|
||||
//Does it have a valid ID?
|
||||
if(cfile->id < 0 || cfile->id >= MAX_CFILE_BLOCKS)
|
||||
return 0;
|
||||
|
||||
//Is it used?
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
if(cb->type != CFILE_BLOCK_USED && (cb->fp != NULL || cb->data != NULL))
|
||||
if (cfile->type != CFILE_BLOCK_USED && (cfile->fp != nullptr || cfile->data != nullptr))
|
||||
return 0;
|
||||
|
||||
//It's good, as near as we can tell.
|
||||
@@ -986,20 +962,15 @@ static CFILE *cf_open_fill_cfblock(const char* source, int line, FILE *fp, int t
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
} else {
|
||||
CFILE *cfp;
|
||||
Cfile_block *cfbp;
|
||||
cfbp = &Cfile_block_list[cfile_block_index];
|
||||
cfp = &Cfile_list[cfile_block_index];
|
||||
cfp->id = cfile_block_index;
|
||||
cfp->version = 0;
|
||||
cfbp->data = NULL;
|
||||
cfbp->mem_mapped = false;
|
||||
cfbp->fp = fp;
|
||||
cfbp->dir_type = type;
|
||||
cfbp->max_read_len = 0;
|
||||
CFILE *cfp = &Cfile_block_list[cfile_block_index];
|
||||
cfp->data = nullptr;
|
||||
cfp->mem_mapped = false;
|
||||
cfp->fp = fp;
|
||||
cfp->dir_type = type;
|
||||
cfp->max_read_len = 0;
|
||||
|
||||
cfbp->source_file = source;
|
||||
cfbp->line_num = line;
|
||||
cfp->source_file = source;
|
||||
cfp->line_num = line;
|
||||
|
||||
int pos = ftell(fp);
|
||||
if(pos == -1L)
|
||||
@@ -1027,21 +998,16 @@ static CFILE *cf_open_packed_cfblock(const char* source, int line, FILE *fp, int
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
} else {
|
||||
CFILE *cfp;
|
||||
Cfile_block *cfbp;
|
||||
cfbp = &Cfile_block_list[cfile_block_index];
|
||||
|
||||
cfp = &Cfile_list[cfile_block_index];
|
||||
cfp->id = cfile_block_index;
|
||||
cfp->version = 0;
|
||||
cfbp->data = NULL;
|
||||
cfbp->fp = fp;
|
||||
cfbp->mem_mapped = false;
|
||||
cfbp->dir_type = type;
|
||||
cfbp->max_read_len = 0;
|
||||
CFILE *cfp = &Cfile_block_list[cfile_block_index];
|
||||
|
||||
cfbp->source_file = source;
|
||||
cfbp->line_num = line;
|
||||
cfp->data = nullptr;
|
||||
cfp->fp = fp;
|
||||
cfp->mem_mapped = false;
|
||||
cfp->dir_type = type;
|
||||
cfp->max_read_len = 0;
|
||||
|
||||
cfp->source_file = source;
|
||||
cfp->line_num = line;
|
||||
|
||||
cf_init_lowlevel_read_code(cfp,offset, size, 0 );
|
||||
|
||||
@@ -1073,44 +1039,39 @@ static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, FILE *fp
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
CFILE *cfp;
|
||||
Cfile_block *cfbp;
|
||||
cfbp = &Cfile_block_list[cfile_block_index];
|
||||
CFILE *cfp = &Cfile_block_list[cfile_block_index];
|
||||
|
||||
cfp = &Cfile_list[cfile_block_index];
|
||||
cfp->id = cfile_block_index;
|
||||
cfp->version = 0;
|
||||
cfbp->max_read_len = 0;
|
||||
cfbp->fp = NULL;
|
||||
cfbp->mem_mapped = true;
|
||||
cfp->max_read_len = 0;
|
||||
cfp->fp = nullptr;
|
||||
cfp->mem_mapped = true;
|
||||
#if defined _WIN32
|
||||
cfbp->hInFile = hFile;
|
||||
cfp->hInFile = hFile;
|
||||
#endif
|
||||
cfbp->dir_type = type;
|
||||
cfp->dir_type = type;
|
||||
|
||||
cfbp->source_file = source;
|
||||
cfbp->line_num = line;
|
||||
cfp->source_file = source;
|
||||
cfp->line_num = line;
|
||||
|
||||
cf_init_lowlevel_read_code(cfp, 0, 0, 0 );
|
||||
#if defined _WIN32
|
||||
cfbp->hMapFile = CreateFileMapping(cfbp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
if (cfbp->hMapFile == NULL) {
|
||||
cfp->hMapFile = CreateFileMapping(cfp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
if (cfp->hMapFile == NULL) {
|
||||
nprintf(("Error", "Could not create file-mapping object.\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cfbp->data = (ubyte*)MapViewOfFile(cfbp->hMapFile, FILE_MAP_READ, 0, 0, 0);
|
||||
Assert( cfbp->data != NULL );
|
||||
cfp->data = (ubyte*)MapViewOfFile(cfp->hMapFile, FILE_MAP_READ, 0, 0, 0);
|
||||
Assert( cfp->data != NULL );
|
||||
#elif defined SCP_UNIX
|
||||
cfbp->fp = fp;
|
||||
cfbp->data_length = filelength( fileno(fp) );
|
||||
cfbp->data = mmap(NULL, // start
|
||||
cfbp->data_length, // length
|
||||
PROT_READ, // prot
|
||||
MAP_SHARED, // flags
|
||||
fileno(fp), // fd
|
||||
0); // offset
|
||||
Assert( cfbp->data != NULL );
|
||||
cfp->fp = fp;
|
||||
cfp->data_length = filelength(fileno(fp));
|
||||
cfp->data = mmap(nullptr, // start
|
||||
cfp->data_length, // length
|
||||
PROT_READ, // prot
|
||||
MAP_SHARED, // flags
|
||||
fileno(fp), // fd
|
||||
0); // offset
|
||||
Assert(cfp->data != nullptr);
|
||||
#endif
|
||||
|
||||
return cfp;
|
||||
@@ -1126,23 +1087,18 @@ static CFILE *cf_open_memory_fill_cfblock(const char* source, int line, const vo
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
CFILE *cfp;
|
||||
Cfile_block *cfbp;
|
||||
cfbp = &Cfile_block_list[cfile_block_index];
|
||||
CFILE *cfp = &Cfile_block_list[cfile_block_index];
|
||||
|
||||
cfp = &Cfile_list[cfile_block_index];
|
||||
cfp->id = cfile_block_index;
|
||||
cfp->version = 0;
|
||||
cfbp->max_read_len = 0;
|
||||
cfbp->fp = NULL;
|
||||
cfbp->mem_mapped = false;
|
||||
cfbp->dir_type = dir_type;
|
||||
cfp->max_read_len = 0;
|
||||
cfp->fp = nullptr;
|
||||
cfp->mem_mapped = false;
|
||||
cfp->dir_type = dir_type;
|
||||
|
||||
cfbp->source_file = source;
|
||||
cfbp->line_num = line;
|
||||
cfp->source_file = source;
|
||||
cfp->line_num = line;
|
||||
|
||||
cf_init_lowlevel_read_code(cfp, 0, size, 0 );
|
||||
cfbp->data = data;
|
||||
cfp->data = data;
|
||||
|
||||
return cfp;
|
||||
}
|
||||
@@ -1150,7 +1106,7 @@ static CFILE *cf_open_memory_fill_cfblock(const char* source, int line, const vo
|
||||
|
||||
int cf_get_dir_type(CFILE *cfile)
|
||||
{
|
||||
return Cfile_block_list[cfile->id].dir_type;
|
||||
return cfile->dir_type;
|
||||
}
|
||||
|
||||
// cf_returndata() returns the data pointer for a memory-mapped file that is associated
|
||||
@@ -1161,22 +1117,8 @@ int cf_get_dir_type(CFILE *cfile)
|
||||
const void *cf_returndata(CFILE *cfile)
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
Assert(cb->data != NULL);
|
||||
return cb->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// version number of opened file. Will be 0 unless you put something else here after you
|
||||
// open a file. Once set, you can use minimum version numbers with the read functions.
|
||||
void cf_set_version( CFILE * cfile, int version )
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
|
||||
cfile->version = version;
|
||||
Assert(cfile->data != nullptr);
|
||||
return cfile->data;
|
||||
}
|
||||
|
||||
// cutoff point where cfread() will throw an error when it hits this limit
|
||||
@@ -1184,27 +1126,21 @@ void cf_set_version( CFILE * cfile, int version )
|
||||
void cf_set_max_read_len( CFILE * cfile, size_t len )
|
||||
{
|
||||
Assert( cfile != NULL );
|
||||
Assert( (cfile->id >= 0) && (cfile->id < MAX_CFILE_BLOCKS) );
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
if (len) {
|
||||
cb->max_read_len = cb->raw_position + len;
|
||||
cfile->max_read_len = cfile->raw_position + len;
|
||||
} else {
|
||||
cb->max_read_len = 0;
|
||||
cfile->max_read_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// routines to read basic data types from CFILE's. Put here to
|
||||
// simplify mac/pc reading from cfiles.
|
||||
|
||||
float cfread_float(CFILE *file, int ver, float deflt)
|
||||
float cfread_float(CFILE* file, float deflt)
|
||||
{
|
||||
float f;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &f, sizeof(f), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
@@ -1212,13 +1148,10 @@ float cfread_float(CFILE *file, int ver, float deflt)
|
||||
return f;
|
||||
}
|
||||
|
||||
int cfread_int(CFILE *file, int ver, int deflt)
|
||||
int cfread_int(CFILE* file, int deflt)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &i, sizeof(i), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
@@ -1226,13 +1159,10 @@ int cfread_int(CFILE *file, int ver, int deflt)
|
||||
return i;
|
||||
}
|
||||
|
||||
uint cfread_uint(CFILE *file, int ver, uint deflt)
|
||||
uint cfread_uint(CFILE* file, uint deflt)
|
||||
{
|
||||
uint i;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &i, sizeof(i), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
@@ -1240,13 +1170,10 @@ uint cfread_uint(CFILE *file, int ver, uint deflt)
|
||||
return i;
|
||||
}
|
||||
|
||||
short cfread_short(CFILE *file, int ver, short deflt)
|
||||
short cfread_short(CFILE* file, short deflt)
|
||||
{
|
||||
short s;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &s, sizeof(s), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
@@ -1254,13 +1181,10 @@ short cfread_short(CFILE *file, int ver, short deflt)
|
||||
return s;
|
||||
}
|
||||
|
||||
ushort cfread_ushort(CFILE *file, int ver, ushort deflt)
|
||||
ushort cfread_ushort(CFILE* file, ushort deflt)
|
||||
{
|
||||
ushort s;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &s, sizeof(s), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
@@ -1268,58 +1192,26 @@ ushort cfread_ushort(CFILE *file, int ver, ushort deflt)
|
||||
return s;
|
||||
}
|
||||
|
||||
ubyte cfread_ubyte(CFILE *file, int ver, ubyte deflt)
|
||||
ubyte cfread_ubyte(CFILE* file, ubyte deflt)
|
||||
{
|
||||
ubyte b;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &b, sizeof(b), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void cfread_vector(vec3d *vec, CFILE *file, int ver, vec3d *deflt)
|
||||
{
|
||||
if (file->version < ver) {
|
||||
if (deflt)
|
||||
*vec = *deflt;
|
||||
else
|
||||
vec->xyz.x = vec->xyz.y = vec->xyz.z = 0.0f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
vec->xyz.x = cfread_float(file, ver, deflt ? deflt->xyz.x : 0.0f);
|
||||
vec->xyz.y = cfread_float(file, ver, deflt ? deflt->xyz.y : 0.0f);
|
||||
vec->xyz.z = cfread_float(file, ver, deflt ? deflt->xyz.z : 0.0f);
|
||||
}
|
||||
|
||||
void cfread_angles(angles *ang, CFILE *file, int ver, angles *deflt)
|
||||
{
|
||||
if (file->version < ver) {
|
||||
if (deflt)
|
||||
*ang = *deflt;
|
||||
else
|
||||
ang->p = ang->b = ang->h = 0.0f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ang->p = cfread_float(file, ver, deflt ? deflt->p : 0.0f);
|
||||
ang->b = cfread_float(file, ver, deflt ? deflt->b : 0.0f);
|
||||
ang->h = cfread_float(file, ver, deflt ? deflt->h : 0.0f);
|
||||
void cfread_vector(vec3d* vec, CFILE* file, vec3d* deflt) {
|
||||
vec->xyz.x = cfread_float(file, deflt ? deflt->xyz.x : 0.0f);
|
||||
vec->xyz.y = cfread_float(file, deflt ? deflt->xyz.y : 0.0f);
|
||||
vec->xyz.z = cfread_float(file, deflt ? deflt->xyz.z : 0.0f);
|
||||
}
|
||||
|
||||
char cfread_char(CFILE *file, int ver, char deflt)
|
||||
char cfread_char(CFILE* file, char deflt)
|
||||
{
|
||||
char b;
|
||||
|
||||
if (file->version < ver)
|
||||
return deflt;
|
||||
|
||||
if (cfread( &b, sizeof(b), 1, file) != 1)
|
||||
return deflt;
|
||||
|
||||
@@ -1400,28 +1292,6 @@ int cfwrite_ubyte(ubyte b, CFILE *file)
|
||||
return cfwrite(&b, sizeof(b), 1, file);
|
||||
}
|
||||
|
||||
int cfwrite_vector(vec3d *vec, CFILE *file)
|
||||
{
|
||||
if(!cfwrite_float(vec->xyz.x, file)){
|
||||
return 0;
|
||||
}
|
||||
if(!cfwrite_float(vec->xyz.y, file)){
|
||||
return 0;
|
||||
}
|
||||
return cfwrite_float(vec->xyz.z, file);
|
||||
}
|
||||
|
||||
int cfwrite_angles(angles *ang, CFILE *file)
|
||||
{
|
||||
if(!cfwrite_float(ang->p, file)){
|
||||
return 0;
|
||||
}
|
||||
if(!cfwrite_float(ang->b, file)){
|
||||
return 0;
|
||||
}
|
||||
return cfwrite_float(ang->h, file);
|
||||
}
|
||||
|
||||
int cfwrite_char(char b, CFILE *file)
|
||||
{
|
||||
return cfwrite( &b, sizeof(b), 1, file);
|
||||
@@ -1454,22 +1324,18 @@ int cfwrite_string_len(const char *buf, CFILE *file)
|
||||
}
|
||||
|
||||
// Get the filelength
|
||||
int cfilelength( CFILE * cfile )
|
||||
{
|
||||
int cfilelength(CFILE* cfile) {
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// TODO: return length of memory mapped file
|
||||
Assert( !cb->mem_mapped );
|
||||
Assert(!cfile->mem_mapped);
|
||||
|
||||
// cfile->size gets set at cfopen
|
||||
|
||||
// cb->size gets set at cfopen
|
||||
|
||||
// The rest of the code still uses ints, do an overflow check to detect cases where this fails
|
||||
Assertion(cb->size <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
||||
"Integer overflow in cfilelength! A file is too large (but I don't know which...).");
|
||||
return (int) cb->size;
|
||||
Assertion(cfile->size <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
||||
"Integer overflow in cfilelength! A file is too large (but I don't know which...).");
|
||||
return (int) cfile->size;
|
||||
}
|
||||
|
||||
// cfwrite() writes to the file
|
||||
@@ -1485,15 +1351,13 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
if(buf == NULL || elsize == 0 || nelem == 0)
|
||||
return 0;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
if(cb->lib_offset != 0)
|
||||
if(cfile->lib_offset != 0)
|
||||
{
|
||||
Error(LOCATION, "Attempt to write to a VP file (unsupported)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(cb->data != NULL)
|
||||
if(cfile->data != nullptr)
|
||||
{
|
||||
Warning(LOCATION, "Writing is not supported for mem-mapped files");
|
||||
return EOF;
|
||||
@@ -1502,16 +1366,16 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
size_t bytes_written = 0;
|
||||
size_t size = elsize * nelem;
|
||||
|
||||
bytes_written = fwrite(buf, 1, size, cb->fp);
|
||||
bytes_written = fwrite(buf, 1, size, cfile->fp);
|
||||
|
||||
//WMC - update filesize and position
|
||||
if (bytes_written > 0) {
|
||||
cb->size += bytes_written;
|
||||
cb->raw_position += bytes_written;
|
||||
cfile->size += bytes_written;
|
||||
cfile->raw_position += bytes_written;
|
||||
}
|
||||
|
||||
#if defined(CHECK_SIZE) && !defined(NDEBUG)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
Assert( cfile->size == filelength(fileno(cfile->fp)) );
|
||||
#endif
|
||||
|
||||
return (int)(bytes_written / elsize);
|
||||
@@ -1528,34 +1392,32 @@ int cfputc(int c, CFILE *cfile)
|
||||
if(!cf_is_valid(cfile))
|
||||
return EOF;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
if(cb->lib_offset != 0)
|
||||
if(cfile->lib_offset != 0)
|
||||
{
|
||||
Error(LOCATION, "Attempt to write character to a VP file (unsupported)");
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if(cb->data != NULL)
|
||||
if(cfile->data != nullptr)
|
||||
{
|
||||
Warning(LOCATION, "Writing is not supported for mem-mapped files");
|
||||
return EOF;
|
||||
}
|
||||
|
||||
// writing not supported for memory-mapped files
|
||||
Assert( !cb->data );
|
||||
Assert( !cfile->data );
|
||||
|
||||
int result = fputc(c, cb->fp);
|
||||
int result = fputc(c, cfile->fp);
|
||||
|
||||
//WMC - update filesize and position
|
||||
if(result != EOF)
|
||||
{
|
||||
cb->size += 1;
|
||||
cb->raw_position += 1;
|
||||
cfile->size += 1;
|
||||
cfile->raw_position += 1;
|
||||
}
|
||||
|
||||
#if defined(CHECK_SIZE) && !defined(NDEBUG)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
Assert( cfile->size == filelength(fileno(cfile->fp)) );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
@@ -1574,31 +1436,29 @@ int cfputs(const char *str, CFILE *cfile)
|
||||
if(str == NULL)
|
||||
return EOF;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
if(cb->lib_offset != 0)
|
||||
if(cfile->lib_offset != 0)
|
||||
{
|
||||
Error(LOCATION, "Attempt to write character to a VP file (unsupported)");
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if(cb->data != NULL)
|
||||
if(cfile->data != nullptr)
|
||||
{
|
||||
Warning(LOCATION, "Writing is not supported for mem-mapped files");
|
||||
return EOF;
|
||||
}
|
||||
|
||||
int result = fputs(str, cb->fp);
|
||||
int result = fputs(str, cfile->fp);
|
||||
|
||||
//WMC - update filesize and position
|
||||
if(result != EOF)
|
||||
{
|
||||
cb->size += strlen(str);
|
||||
cb->raw_position += strlen(str);
|
||||
cfile->size += strlen(str);
|
||||
cfile->raw_position += strlen(str);
|
||||
}
|
||||
|
||||
#if defined(CHECK_SIZE) && !defined(NDEBUG)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
Assert( cfile->size == filelength(fileno(cfile->fp)) );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
@@ -1960,19 +1820,16 @@ int cf_chksum_long(CFILE *file, uint *chksum, int max_size)
|
||||
int cflush(CFILE *cfile)
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// not supported for memory mapped files
|
||||
Assert( !cb->data );
|
||||
Assert( !cfile->data );
|
||||
|
||||
Assert(cb->fp != NULL);
|
||||
Assert(cfile->fp != nullptr);
|
||||
|
||||
int result = fflush(cb->fp);
|
||||
int result = fflush(cfile->fp);
|
||||
|
||||
//WMC - update filesize
|
||||
cb->size = filelength(fileno(cb->fp));
|
||||
cfile->size = filelength(fileno(cfile->fp));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+25
-34
@@ -13,10 +13,11 @@
|
||||
#define __CFILE_H__
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#define CF_EOF (-1)
|
||||
@@ -25,10 +26,8 @@
|
||||
#define CF_SEEK_CUR (1)
|
||||
#define CF_SEEK_END (2)
|
||||
|
||||
typedef struct CFILE {
|
||||
int id; // Index into cfile.cpp specific structure
|
||||
int version; // version of this file
|
||||
} CFILE;
|
||||
// Opaque file handle
|
||||
struct CFILE;
|
||||
|
||||
// extra info that can be returned when getting a file listing
|
||||
typedef struct {
|
||||
@@ -155,9 +154,6 @@ enum CFileLocationFlags {
|
||||
CF_LOCATION_ALL = CF_LOCATION_ROOT_MASK | CF_LOCATION_TYPE_MASK
|
||||
};
|
||||
|
||||
#define cfread_fix(file) (fix)cfread_int(file)
|
||||
#define cfwrite_fix(i,file) cfwrite_int(i,file)
|
||||
|
||||
// callback function used for get_file_list() to filter files to be added to list. Return 1
|
||||
// to add file to list, or 0 to not add it.
|
||||
extern int (*Get_file_list_filter)(const char *filename);
|
||||
@@ -176,11 +172,6 @@ extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL);
|
||||
void cfile_close();
|
||||
|
||||
// Call this if pack files got added or removed or the
|
||||
// cdrom changed. This will refresh the list of filenames
|
||||
// stored in packfiles and on the cdrom.
|
||||
void cfile_refresh();
|
||||
|
||||
// add an extension to a filename if it doesn't already have it
|
||||
char *cf_add_ext(const char *filename, const char *ext);
|
||||
|
||||
@@ -202,10 +193,6 @@ CFILE *_cfopen_special(const char* source_file, int line, const char *file_path,
|
||||
// Flush the open file buffer
|
||||
int cflush(CFILE *cfile);
|
||||
|
||||
// version number of opened file. Will be 0 unless you put something else here after you
|
||||
// open a file. Once set, you can use minimum version numbers with the read functions.
|
||||
void cf_set_version( CFILE * cfile, int version );
|
||||
|
||||
// will throw an error if cfread*() functions read past this mark
|
||||
// converted to raw offsets when used, but gets passed actual length from current position
|
||||
// setting 'len' to zero will disable the check
|
||||
@@ -246,10 +233,6 @@ int cfread(void *buf, int elsize, int nelem, CFILE *fp);
|
||||
// cfwrite() writes to the file
|
||||
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
|
||||
// Reads/writes RLE compressed data.
|
||||
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile);
|
||||
|
||||
// Moves the file pointer
|
||||
int cfseek(CFILE *fp, int offset, int where);
|
||||
|
||||
@@ -301,7 +284,6 @@ uint cf_add_chksum_long(uint seed, ubyte *buffer, size_t size);
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
//================= HIGH LEVEL FUNCTIONS ==================
|
||||
int cfexist(const char *filename); // Returns true if file exists on disk (1) or in hog (2).
|
||||
|
||||
// rename a file, utilizing the extension to determine where file is.
|
||||
#define CF_RENAME_SUCCESS 0 // successfully renamed the file
|
||||
@@ -319,17 +301,15 @@ int cfile_flush_dir(int type);
|
||||
// functions for reading from cfile
|
||||
// These are all high level, built up from
|
||||
// cfread.
|
||||
int cfgetc(CFILE *fp);
|
||||
char *cfgets(char *buf, size_t n, CFILE *fp);
|
||||
char cfread_char(CFILE *file, int ver = 0, char deflt = 0);
|
||||
ubyte cfread_ubyte(CFILE *file, int ver = 0, ubyte deflt = 0);
|
||||
short cfread_short(CFILE *file, int ver = 0, short deflt = 0);
|
||||
ushort cfread_ushort(CFILE *file, int ver = 0, ushort deflt = 0);
|
||||
int cfread_int(CFILE *file, int ver = 0, int deflt = 0);
|
||||
uint cfread_uint(CFILE *file, int ver = 0, uint deflt = 0);
|
||||
float cfread_float(CFILE *file, int ver = 0, float deflt = 0.0f);
|
||||
void cfread_vector(vec3d *vec, CFILE *file, int ver = 0, vec3d *deflt = NULL);
|
||||
void cfread_angles(angles *ang, CFILE *file, int ver = 0, angles *deflt = NULL);
|
||||
char cfread_char(CFILE* file, char deflt = 0);
|
||||
ubyte cfread_ubyte(CFILE* file, ubyte deflt = 0);
|
||||
short cfread_short(CFILE* file, short deflt = 0);
|
||||
ushort cfread_ushort(CFILE* file, ushort deflt = 0);
|
||||
int cfread_int(CFILE* file, int deflt = 0);
|
||||
uint cfread_uint(CFILE* file, uint deflt = 0);
|
||||
float cfread_float(CFILE* file, float deflt = 0.0f);
|
||||
void cfread_vector(vec3d* vec, CFILE* file, vec3d* deflt = nullptr);
|
||||
|
||||
// Reads variable length, null-termined string. Will only read up
|
||||
// to n characters.
|
||||
@@ -360,8 +340,6 @@ int cfwrite_uint(uint i, CFILE *file);
|
||||
int cfwrite_short(short s, CFILE *file);
|
||||
int cfwrite_ushort(ushort s, CFILE *file);
|
||||
int cfwrite_ubyte(ubyte u, CFILE *file);
|
||||
int cfwrite_vector(vec3d *vec, CFILE *file);
|
||||
int cfwrite_angles(angles *ang, CFILE *file);
|
||||
|
||||
// writes variable length, null-termined string.
|
||||
int cfwrite_string(const char *buf, CFILE *file);
|
||||
@@ -483,4 +461,17 @@ namespace cfile
|
||||
|
||||
}
|
||||
|
||||
// This allows to use std::unique_ptr with CFILE
|
||||
namespace std {
|
||||
template <>
|
||||
struct default_delete<CFILE> {
|
||||
void operator()(CFILE* ptr)
|
||||
{
|
||||
if (cf_is_valid(ptr)) {
|
||||
cfclose(ptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif /* __CFILE_H__ */
|
||||
+55
-74
@@ -36,24 +36,20 @@
|
||||
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size, size_t pos )
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
Assert(cfile != nullptr);
|
||||
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
cfile->lib_offset = lib_offset;
|
||||
cfile->raw_position = pos;
|
||||
cfile->size = size;
|
||||
|
||||
cb->lib_offset = lib_offset;
|
||||
cb->raw_position = pos;
|
||||
cb->size = size;
|
||||
|
||||
if ( cb->fp ) {
|
||||
if ( cb->lib_offset ) {
|
||||
fseek( cb->fp, (long)cb->lib_offset, SEEK_SET );
|
||||
if ( cfile->fp ) {
|
||||
if ( cfile->lib_offset ) {
|
||||
fseek( cfile->fp, (long)cfile->lib_offset, SEEK_SET );
|
||||
}
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
auto raw_position = ftell(cfile->fp) - cfile->lib_offset;
|
||||
Assert(raw_position == cfile->raw_position);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -70,20 +66,16 @@ int cfeof(CFILE *cfile)
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
int result = 0;
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
if (cb->fp) {
|
||||
auto raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
if (cfile->fp) {
|
||||
auto raw_position = ftell(cfile->fp) - cfile->lib_offset;
|
||||
Assert(raw_position == cfile->raw_position);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cb->raw_position >= cb->size ) {
|
||||
if (cfile->raw_position >= cfile->size ) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
@@ -100,21 +92,18 @@ int cfeof(CFILE *cfile)
|
||||
int cftell( CFILE * cfile )
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
if (cb->fp) {
|
||||
auto raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
if (cfile->fp) {
|
||||
auto raw_position = ftell(cfile->fp) - cfile->lib_offset;
|
||||
Assert(raw_position == cfile->raw_position);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The rest of the code still uses ints, do an overflow check to detect cases where this fails
|
||||
Assertion(cb->raw_position <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
||||
Assertion(cfile->raw_position <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
||||
"Integer overflow in cftell, a file is probably too large (but I don't know which one).");
|
||||
return (int) cb->raw_position;
|
||||
return (int) cfile->raw_position;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,27 +116,23 @@ int cfseek( CFILE *cfile, int offset, int where )
|
||||
{
|
||||
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
|
||||
// TODO: seek to offset in memory mapped file
|
||||
Assert( !cb->mem_mapped );
|
||||
Assert( !cfile->mem_mapped );
|
||||
|
||||
size_t goal_position;
|
||||
|
||||
switch( where ) {
|
||||
case CF_SEEK_SET:
|
||||
goal_position = offset+cb->lib_offset;
|
||||
goal_position = offset+cfile->lib_offset;
|
||||
break;
|
||||
case CF_SEEK_CUR:
|
||||
{
|
||||
goal_position = cb->raw_position+offset+cb->lib_offset;
|
||||
goal_position = cfile->raw_position+offset+cfile->lib_offset;
|
||||
}
|
||||
break;
|
||||
case CF_SEEK_END:
|
||||
goal_position = cb->size+offset+cb->lib_offset;
|
||||
goal_position = cfile->size+offset+cfile->lib_offset;
|
||||
break;
|
||||
default:
|
||||
Int3();
|
||||
@@ -155,23 +140,23 @@ int cfseek( CFILE *cfile, int offset, int where )
|
||||
}
|
||||
|
||||
// Make sure we don't seek beyond the end of the file
|
||||
CAP(goal_position, cb->lib_offset, cb->lib_offset + cb->size);
|
||||
CAP(goal_position, cfile->lib_offset, cfile->lib_offset + cfile->size);
|
||||
|
||||
int result = 0;
|
||||
|
||||
if (cb->fp) {
|
||||
if (cfile->fp) {
|
||||
// If we have a file pointer we can also seek in that file
|
||||
result = fseek(cb->fp, (long)goal_position, SEEK_SET );
|
||||
Assertion(goal_position >= cb->lib_offset, "Invalid offset values detected while seeking! Goal was " SIZE_T_ARG ", lib_offset is " SIZE_T_ARG ".", goal_position, cb->lib_offset);
|
||||
result = fseek(cfile->fp, (long)goal_position, SEEK_SET );
|
||||
Assertion(goal_position >= cfile->lib_offset, "Invalid offset values detected while seeking! Goal was " SIZE_T_ARG ", lib_offset is " SIZE_T_ARG ".", goal_position, cfile->lib_offset);
|
||||
}
|
||||
// If we only have a data pointer this will do all the work
|
||||
cb->raw_position = goal_position - cb->lib_offset;
|
||||
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
|
||||
cfile->raw_position = goal_position - cfile->lib_offset;
|
||||
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
if (cb->fp) {
|
||||
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset == cb->raw_position);
|
||||
if (cfile->fp) {
|
||||
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
|
||||
Assert(tmp_offset == cfile->raw_position);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -194,19 +179,17 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
if(buf == NULL || size <= 0)
|
||||
return 0;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
if ( (cb->raw_position+size) > cb->size ) {
|
||||
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
|
||||
size = cb->size - cb->raw_position;
|
||||
if ( (cfile->raw_position+size) > cfile->size ) {
|
||||
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
|
||||
size = cfile->size - cfile->raw_position;
|
||||
if ( size < 1 ) {
|
||||
return 0;
|
||||
}
|
||||
//mprintf(( "CFILE: EOF encountered in file\n" ));
|
||||
}
|
||||
|
||||
if (cb->max_read_len) {
|
||||
if ( cb->raw_position+size > cb->max_read_len ) {
|
||||
if (cfile->max_read_len) {
|
||||
if ( cfile->raw_position+size > cfile->max_read_len ) {
|
||||
std::ostringstream s_buf;
|
||||
s_buf << "Attempted to read " << size << "-byte(s) beyond length limit";
|
||||
|
||||
@@ -215,22 +198,22 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
}
|
||||
|
||||
size_t bytes_read;
|
||||
if (cb->data != nullptr) {
|
||||
if (cfile->data != nullptr) {
|
||||
// This is a file from memory
|
||||
bytes_read = size;
|
||||
memcpy(buf, reinterpret_cast<const char*>(cb->data) + cb->raw_position, size);
|
||||
memcpy(buf, reinterpret_cast<const char*>(cfile->data) + cfile->raw_position, size);
|
||||
} else {
|
||||
bytes_read = fread( buf, 1, size, cb->fp );
|
||||
bytes_read = fread( buf, 1, size, cfile->fp );
|
||||
}
|
||||
if ( bytes_read > 0 ) {
|
||||
cb->raw_position += bytes_read;
|
||||
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
|
||||
cfile->raw_position += bytes_read;
|
||||
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
|
||||
}
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
if (cb->fp) {
|
||||
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
if (cfile->fp) {
|
||||
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
|
||||
Assert(tmp_offset==cfile->raw_position);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -246,10 +229,8 @@ int cfread_lua_number(double *buf, CFILE *cfile)
|
||||
if(buf == NULL)
|
||||
return 0;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// cfread() not supported for memory-mapped files
|
||||
if(cb->data != NULL)
|
||||
if(cfile->data != nullptr)
|
||||
{
|
||||
Warning(LOCATION, "Writing is not supported for mem-mapped files");
|
||||
return 0;
|
||||
@@ -257,28 +238,28 @@ int cfread_lua_number(double *buf, CFILE *cfile)
|
||||
|
||||
size_t advance = 0;
|
||||
int items_read;
|
||||
if (cb->fp) {
|
||||
long orig_pos = ftell(cb->fp);
|
||||
items_read = fscanf(cb->fp, LUA_NUMBER_SCAN, buf);
|
||||
advance = (size_t) (ftell(cb->fp)-orig_pos);
|
||||
if (cfile->fp) {
|
||||
long orig_pos = ftell(cfile->fp);
|
||||
items_read = fscanf(cfile->fp, LUA_NUMBER_SCAN, buf);
|
||||
advance = (size_t) (ftell(cfile->fp)-orig_pos);
|
||||
} else {
|
||||
int read;
|
||||
// %n returns the number of bytes currently read so we append that to the scan format at the end so it will return
|
||||
// how many bytes we have consumed
|
||||
items_read = sscanf(reinterpret_cast<const char*>(cb->data), LUA_NUMBER_SCAN "%n", buf, &read);
|
||||
items_read = sscanf(reinterpret_cast<const char*>(cfile->data), LUA_NUMBER_SCAN "%n", buf, &read);
|
||||
if (items_read == 2) {
|
||||
// We need to correct the items read counter since we read one additional item
|
||||
items_read = 1;
|
||||
}
|
||||
advance = (size_t) read;
|
||||
}
|
||||
cb->raw_position += advance;
|
||||
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
|
||||
cfile->raw_position += advance;
|
||||
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
if (cb->fp) {
|
||||
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
if (cfile->fp) {
|
||||
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
|
||||
Assert(tmp_offset==cfile->raw_position);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+14
-15
@@ -22,31 +22,30 @@
|
||||
#define CFILE_BLOCK_UNUSED 0
|
||||
#define CFILE_BLOCK_USED 1
|
||||
|
||||
typedef struct Cfile_block {
|
||||
int type; // CFILE_BLOCK_UNUSED, CFILE_BLOCK_USED
|
||||
int dir_type; // directory location
|
||||
FILE *fp; // File pointer if opening an individual file
|
||||
const void *data; // Pointer for memory-mapped file access. NULL if not mem-mapped.
|
||||
bool mem_mapped; // Flag for memory mapped files (if data is not null and this is false it means that it's an embedded file)
|
||||
struct CFILE {
|
||||
int type = CFILE_BLOCK_UNUSED; // CFILE_BLOCK_UNUSED, CFILE_BLOCK_USED
|
||||
int dir_type; // directory location
|
||||
FILE* fp; // File pointer if opening an individual file
|
||||
const void* data; // Pointer for memory-mapped file access. NULL if not mem-mapped.
|
||||
bool mem_mapped; // Flag for memory mapped files (if data is not null and this is false it means that it's an embedded file)
|
||||
#ifdef _WIN32
|
||||
HANDLE hInFile; // Handle from CreateFile()
|
||||
HANDLE hMapFile; // Handle from CreateFileMapping()
|
||||
#else
|
||||
// int fd; // file descriptor
|
||||
size_t data_length; // length of data for mmap
|
||||
size_t data_length; // length of data for mmap
|
||||
#endif
|
||||
size_t lib_offset;
|
||||
size_t raw_position;
|
||||
size_t size; // for packed files
|
||||
size_t lib_offset;
|
||||
size_t raw_position;
|
||||
size_t size; // for packed files
|
||||
|
||||
size_t max_read_len; // max read offset, for special error handling
|
||||
|
||||
size_t max_read_len; // max read offset, for special error handling
|
||||
|
||||
const char* source_file;
|
||||
int line_num;
|
||||
} Cfile_block;
|
||||
};
|
||||
|
||||
#define MAX_CFILE_BLOCKS 64
|
||||
extern Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS];
|
||||
extern std::array<CFILE, MAX_CFILE_BLOCKS> Cfile_block_list;
|
||||
|
||||
// Called once to setup the low-level reading code.
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size, size_t pos );
|
||||
|
||||
+1
-350
@@ -200,353 +200,4 @@ void cf_sort_filenames( int n, char **list, int sort, file_list_info *info )
|
||||
}
|
||||
|
||||
nprintf(("Error", "Unknown sorting method %d passed to cf_sort_filenames()\n", sort));
|
||||
}
|
||||
|
||||
|
||||
#if (0) // these aren't used anywhere now
|
||||
|
||||
// cf_compress - Do Run Length Compression on a block of data. Targa format.
|
||||
//
|
||||
// Usage:
|
||||
// out Buffer to write it out to
|
||||
// in Buffer to compress
|
||||
// bytecount Number of bytes input
|
||||
int cf_compress(char *out, char *in, int bytecount )
|
||||
{
|
||||
int pixcount; // number of pixels in the current packet
|
||||
char *inputpixel=NULL; // current input pixel position
|
||||
char *matchpixel=NULL; // pixel value to match for a run
|
||||
char *flagbyte=NULL; // location of last flag byte to set
|
||||
int rlcount; // current count in r.l. string
|
||||
int rlthresh; // minimum valid run length
|
||||
char *copyloc; // location to begin copying at
|
||||
|
||||
// set the threshold -- the minimum valid run length
|
||||
rlthresh = 2; // Require a 2 pixel span before rle'ing
|
||||
|
||||
// set the first pixel up
|
||||
|
||||
flagbyte = out; // place to put next flag if run
|
||||
inputpixel = in;
|
||||
pixcount = 1;
|
||||
rlcount = 0;
|
||||
copyloc = (char *)0;
|
||||
|
||||
// loop till data processing complete
|
||||
do {
|
||||
|
||||
// if we have accumulated a 128-byte packet, process it
|
||||
if ( pixcount == 129 ) {
|
||||
*flagbyte = 127;
|
||||
|
||||
// set the run flag if this is a run
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
*flagbyte |= 0x80;
|
||||
pixcount = 2;
|
||||
}
|
||||
|
||||
// copy the data into place
|
||||
++flagbyte;
|
||||
memmove( flagbyte, copyloc, pixcount-1 );
|
||||
flagbyte += pixcount-1;
|
||||
pixcount = 1;
|
||||
|
||||
// set up for next packet
|
||||
continue;
|
||||
}
|
||||
|
||||
// if zeroth byte, handle as special case
|
||||
if ( pixcount == 1 ) {
|
||||
rlcount = 0;
|
||||
copyloc = inputpixel; /* point to 1st guy in packet */
|
||||
matchpixel = inputpixel; /* set pointer to pix to match */
|
||||
pixcount = 2;
|
||||
inputpixel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// assembling a packet -- look at next pixel
|
||||
|
||||
// current pixel == match pixel?
|
||||
if ( *inputpixel == *matchpixel ) {
|
||||
|
||||
// establishing a run of enough length to
|
||||
// save space by doing it
|
||||
// -- write the non-run length packet
|
||||
// -- start run-length packet
|
||||
|
||||
if ( ++rlcount == rlthresh ) {
|
||||
|
||||
// close a non-run packet
|
||||
|
||||
if ( pixcount > (rlcount+1) ) {
|
||||
// write out length and do not set run flag
|
||||
|
||||
*flagbyte++ = (char)(pixcount - 2 - rlthresh);
|
||||
|
||||
memmove(flagbyte, copyloc, (pixcount-1-rlcount) );
|
||||
flagbyte += (pixcount-1-rlcount);
|
||||
|
||||
copyloc = inputpixel;
|
||||
pixcount = rlcount + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// no match -- either break a run or continue without one
|
||||
// if a run exists break it:
|
||||
// write the bytes in the string (1+1)
|
||||
// start the next string
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
|
||||
*flagbyte++ = (char)(0x80 | rlcount);
|
||||
memmove(flagbyte, copyloc, 1 );
|
||||
flagbyte += 1;
|
||||
pixcount = 1;
|
||||
continue;
|
||||
} else {
|
||||
|
||||
// not a match and currently not a run
|
||||
// - save the current pixel
|
||||
// - reset the run-length flag
|
||||
rlcount = 0;
|
||||
matchpixel = inputpixel;
|
||||
}
|
||||
}
|
||||
pixcount++;
|
||||
inputpixel += 1;
|
||||
} while ( inputpixel < (in + bytecount));
|
||||
|
||||
// quit this buffer without loosing any data
|
||||
if ( --pixcount >= 1 ) {
|
||||
*flagbyte = (char)(pixcount - 1);
|
||||
if ( rlcount >= rlthresh ) {
|
||||
*flagbyte |= 0x80;
|
||||
pixcount = 1;
|
||||
}
|
||||
|
||||
// copy the data into place
|
||||
++flagbyte;
|
||||
memmove(flagbyte, copyloc, pixcount );
|
||||
flagbyte += pixcount;
|
||||
}
|
||||
return(flagbyte-out);
|
||||
}
|
||||
|
||||
|
||||
// cf_decompress - Do Decompression on a run-length encoded block of data. Targa format.
|
||||
//
|
||||
// Usage:
|
||||
// out Buffer to write it out to
|
||||
// in Buffer to compress
|
||||
// bytecount Number of bytes input
|
||||
int cf_decompress(char *out, char *in )
|
||||
{
|
||||
int count;
|
||||
|
||||
char *param_out = out;
|
||||
|
||||
while(1) {
|
||||
|
||||
count = int(*in++);
|
||||
int run_span = count & 0x80;
|
||||
|
||||
count &= (~0x80);
|
||||
|
||||
if ( count > 0 ) {
|
||||
if ( run_span ) {
|
||||
// RLE'd data
|
||||
ubyte c = *in++;
|
||||
|
||||
memset( out, c, count );
|
||||
out += count;
|
||||
} else {
|
||||
memmove( out, in, count );
|
||||
in += count;
|
||||
out += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out - param_out;
|
||||
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
// cfread() reads from a file and decompresses it
|
||||
//
|
||||
// returns: returns the number of full elements read
|
||||
//
|
||||
//
|
||||
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
{
|
||||
char *out = (char *)buf;
|
||||
|
||||
while(1) {
|
||||
|
||||
ubyte count;
|
||||
|
||||
if ( cfread( &count, 1, 1, cfile ) != 1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
int run_span = count & 0x80;
|
||||
count &= (~0x80);
|
||||
count++;
|
||||
|
||||
if ( count > 0 ) {
|
||||
if ( run_span ) {
|
||||
// RLE'd data
|
||||
ubyte c;
|
||||
if ( cfread( &c, 1, 1, cfile ) != 1 ) {
|
||||
break;
|
||||
}
|
||||
memset( out, c, count );
|
||||
} else {
|
||||
if ( cfread( out, 1, count, cfile ) != count ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
out += count;
|
||||
if ( out >= (char *)buf + (elsize*nelem)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (int)((out - (char *)buf)/elsize);
|
||||
}
|
||||
|
||||
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile)
|
||||
{
|
||||
char *in = (char *)param_buf;
|
||||
int bytecount = (param_elsize * param_nelem );
|
||||
|
||||
int pixcount; // number of pixels in the current packet
|
||||
char *inputpixel=NULL; // current input pixel position
|
||||
char *matchpixel=NULL; // pixel value to match for a run
|
||||
int rlcount; // current count in r.l. string
|
||||
int rlthresh; // minimum valid run length
|
||||
char *copyloc; // location to begin copying at
|
||||
|
||||
// set the threshold -- the minimum valid run length
|
||||
rlthresh = 2; // Require a 2 pixel span before rle'ing
|
||||
|
||||
// set the first pixel up
|
||||
|
||||
inputpixel = in;
|
||||
pixcount = 1;
|
||||
rlcount = 0;
|
||||
copyloc = (char *)0;
|
||||
|
||||
// loop till data processing complete
|
||||
do {
|
||||
|
||||
// if we have accumulated a 128-byte packet, process it
|
||||
if ( pixcount == 129 ) {
|
||||
ubyte code = 127;
|
||||
|
||||
// set the run flag if this is a run
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
code |= 0x80;
|
||||
pixcount = 2;
|
||||
}
|
||||
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
|
||||
// copy the data into place
|
||||
cfwrite( copyloc, 1, pixcount-1, cfile );
|
||||
pixcount = 1;
|
||||
|
||||
// set up for next packet
|
||||
continue;
|
||||
}
|
||||
|
||||
// if zeroth byte, handle as special case
|
||||
if ( pixcount == 1 ) {
|
||||
rlcount = 0;
|
||||
copyloc = inputpixel; /* point to 1st guy in packet */
|
||||
matchpixel = inputpixel; /* set pointer to pix to match */
|
||||
pixcount = 2;
|
||||
inputpixel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// assembling a packet -- look at next pixel
|
||||
|
||||
// current pixel == match pixel?
|
||||
if ( *inputpixel == *matchpixel ) {
|
||||
|
||||
// establishing a run of enough length to
|
||||
// save space by doing it
|
||||
// -- write the non-run length packet
|
||||
// -- start run-length packet
|
||||
|
||||
if ( ++rlcount == rlthresh ) {
|
||||
|
||||
// close a non-run packet
|
||||
|
||||
if ( pixcount > (rlcount+1) ) {
|
||||
// write out length and do not set run flag
|
||||
|
||||
ubyte code = (ubyte)(pixcount - 2 - rlthresh);
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
|
||||
cfwrite( copyloc, 1, (pixcount-1-rlcount), cfile );
|
||||
copyloc = inputpixel;
|
||||
pixcount = rlcount + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// no match -- either break a run or continue without one
|
||||
// if a run exists break it:
|
||||
// write the bytes in the string (1+1)
|
||||
// start the next string
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
|
||||
ubyte code = (ubyte)(0x80 | rlcount);
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
cfwrite( copyloc, 1, 1, cfile );
|
||||
pixcount = 1;
|
||||
continue;
|
||||
} else {
|
||||
|
||||
// not a match and currently not a run
|
||||
// - save the current pixel
|
||||
// - reset the run-length flag
|
||||
rlcount = 0;
|
||||
matchpixel = inputpixel;
|
||||
}
|
||||
}
|
||||
pixcount++;
|
||||
inputpixel += 1;
|
||||
} while ( inputpixel < (in + bytecount));
|
||||
|
||||
// quit this buffer without loosing any data
|
||||
if ( --pixcount >= 1 ) {
|
||||
ubyte code = ubyte(pixcount - 1);
|
||||
|
||||
// set the run flag if this is a run
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
code |= 0x80;
|
||||
pixcount = 1;
|
||||
}
|
||||
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
|
||||
// copy the data into place
|
||||
cfwrite( copyloc, 1, pixcount, cfile );
|
||||
}
|
||||
|
||||
return param_nelem;
|
||||
}
|
||||
}
|
||||
+103
-54
@@ -5,27 +5,27 @@
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "camera/camera.h" //VIEWER_ZOOM_DEFAULT
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "camera/camera.h" //VIEWER_ZOOM_DEFAULT
|
||||
#include "cfile/cfilesystem.h"
|
||||
#include "fireball/fireballs.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "hud/hudconfig.h"
|
||||
#include "network/multi.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "cfile/cfilesystem.h"
|
||||
#include "sound/speech.h"
|
||||
#include "sound/openal.h"
|
||||
#include "io/joy.h"
|
||||
#include "network/multi.h"
|
||||
#include "options/OptionsManager.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "sound/openal.h"
|
||||
#include "sound/speech.h"
|
||||
#include "starfield/starfield.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
@@ -82,8 +82,8 @@ public:
|
||||
int name_found; // true if parameter on command line, otherwise false
|
||||
const int arg_type; // from enum cmdline_arg_type; used for help
|
||||
|
||||
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false);
|
||||
~cmdline_parm();
|
||||
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false) noexcept;
|
||||
~cmdline_parm() noexcept;
|
||||
int found();
|
||||
int get_int();
|
||||
float get_float();
|
||||
@@ -152,6 +152,7 @@ typedef struct
|
||||
|
||||
} Flag;
|
||||
|
||||
// clang-format off
|
||||
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
|
||||
Flag exe_params[] =
|
||||
{
|
||||
@@ -167,6 +168,7 @@ Flag exe_params[] =
|
||||
{ "-post_process", "Enable post processing", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
|
||||
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
|
||||
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
|
||||
{ "-smaa", "Enable SMAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-smaa" },
|
||||
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
|
||||
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
|
||||
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
|
||||
@@ -204,7 +206,6 @@ Flag exe_params[] =
|
||||
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
||||
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
|
||||
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
|
||||
{ "-query_speech", "Check if this build has speech", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
|
||||
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
|
||||
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
|
||||
{ "-disable_pbo", "Disable OpenGL Pixel Buffer Objects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_pbo", },
|
||||
@@ -212,7 +213,6 @@ Flag exe_params[] =
|
||||
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
|
||||
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
|
||||
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
|
||||
{ "-old_collision", "Use old collision detection system", true, EASY_DEFAULT, EASY_ALL_ON, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-old_collision", },
|
||||
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
|
||||
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
@@ -250,6 +250,7 @@ Flag exe_params[] =
|
||||
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
|
||||
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// forward declaration
|
||||
const char * get_param_desc(const char *flag_name);
|
||||
@@ -324,6 +325,8 @@ cmdline_parm postprocess_arg("-post_process", NULL, AT_NONE);
|
||||
cmdline_parm bloom_intensity_arg("-bloom_intensity", "Set bloom intensity, requires -post_process", AT_INT);
|
||||
cmdline_parm fxaa_arg("-fxaa", NULL, AT_NONE);
|
||||
cmdline_parm fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-9), requires -post_process and -fxaa", AT_INT);
|
||||
cmdline_parm smaa_arg("-smaa", nullptr, AT_NONE);
|
||||
cmdline_parm smaa_preset_arg("-smaa_preset", "SMAA quality (0-9), requires -post_process and -smaa", AT_INT);
|
||||
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
|
||||
cmdline_parm fb_thrusters_arg("-fb_thrusters", NULL, AT_NONE);
|
||||
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
|
||||
@@ -333,13 +336,11 @@ cmdline_parm no_deferred_lighting_arg("-no_deferred", NULL, AT_NONE); // Cmdline
|
||||
cmdline_parm anisotropy_level_arg("-anisotropic_filter", NULL, AT_INT);
|
||||
|
||||
float Cmdline_clip_dist = Default_min_draw_distance;
|
||||
float Cmdline_fov = 0.75f;
|
||||
float Cmdline_ogl_spec = 80.0f;
|
||||
int Cmdline_ambient_factor = 128;
|
||||
int Cmdline_env = 1;
|
||||
int Cmdline_mipmap = 0;
|
||||
int Cmdline_glow = 1;
|
||||
int Cmdline_nomotiondebris = 0;
|
||||
int Cmdline_noscalevid = 0;
|
||||
int Cmdline_spec = 1;
|
||||
int Cmdline_no_emissive = 0;
|
||||
@@ -347,15 +348,8 @@ int Cmdline_normal = 1;
|
||||
int Cmdline_height = 1;
|
||||
int Cmdline_enable_3d_shockwave = 0;
|
||||
int Cmdline_softparticles = 0;
|
||||
int Cmdline_postprocess = 0;
|
||||
int Cmdline_bloom_intensity = 75;
|
||||
bool Cmdline_fxaa = false;
|
||||
int Cmdline_fxaa_preset = 6;
|
||||
extern int Fxaa_preset_last_frame;
|
||||
bool Cmdline_fb_explosions = 0;
|
||||
bool Cmdline_fb_thrusters = false;
|
||||
extern bool ls_force_off;
|
||||
int Cmdline_shadow_quality = 0;
|
||||
int Cmdline_no_deferred_lighting = 0;
|
||||
int Cmdline_aniso_level = 0;
|
||||
|
||||
@@ -395,10 +389,8 @@ int Cmdline_autopilot_interruptable = 1;
|
||||
int Cmdline_stretch_menu = 0;
|
||||
|
||||
// Audio related
|
||||
cmdline_parm query_speech_arg("-query_speech", NULL, AT_NONE); // Cmdline_query_speech
|
||||
cmdline_parm voice_recognition_arg("-voicer", NULL, AT_NONE); // Cmdline_voice_recognition
|
||||
|
||||
int Cmdline_query_speech = 0;
|
||||
int Cmdline_voice_recognition = 0;
|
||||
int Cmdline_no_enhanced_sound = 0;
|
||||
|
||||
@@ -438,7 +430,6 @@ cmdline_parm atiswap_arg("-ati_swap", NULL, AT_NONE); // Cmdline_atiswap
|
||||
cmdline_parm no3dsound_arg("-no_3d_sound", NULL, AT_NONE); // Cmdline_no_3d_sound - Disable use of full 3D sounds
|
||||
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL, AT_NONE); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
|
||||
cmdline_parm keyboard_layout("-keyboard_layout", "Specify keyboard layout (qwertz or azerty)", AT_STRING);
|
||||
cmdline_parm old_collision_system("-old_collision", NULL, AT_NONE); // Cmdline_old_collision_sys
|
||||
cmdline_parm gl_finish ("-gl_finish", NULL, AT_NONE);
|
||||
cmdline_parm no_geo_sdr_effects("-no_geo_effects", NULL, AT_NONE);
|
||||
cmdline_parm set_cpu_affinity("-set_cpu_affinity", NULL, AT_NONE);
|
||||
@@ -495,7 +486,6 @@ cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_
|
||||
|
||||
|
||||
char *Cmdline_start_mission = NULL;
|
||||
int Cmdline_old_collision_sys = 0;
|
||||
int Cmdline_dis_collisions = 0;
|
||||
int Cmdline_dis_weapons = 0;
|
||||
bool Cmdline_output_sexp_info = false;
|
||||
@@ -1046,7 +1036,7 @@ void os_init_cmdline(int argc, char *argv[])
|
||||
* @param arg_type_ parameters arguement type (if any)
|
||||
* @param stacks_ can the parameter be stacked
|
||||
*/
|
||||
cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_type_, const bool stacks_):
|
||||
cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_type_, const bool stacks_) noexcept:
|
||||
name(name_), help(help_), stacks(stacks_), arg_type(arg_type_)
|
||||
{
|
||||
args = NULL;
|
||||
@@ -1069,7 +1059,7 @@ cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_t
|
||||
|
||||
|
||||
// destructor - frees any allocated memory
|
||||
cmdline_parm::~cmdline_parm()
|
||||
cmdline_parm::~cmdline_parm() noexcept
|
||||
{
|
||||
#ifndef FRED
|
||||
if (args) {
|
||||
@@ -1691,18 +1681,32 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
// d3d windowed
|
||||
if(window_arg.found()){
|
||||
if(window_arg.found()) {
|
||||
// We need to set both values since we don't know if we are going to use the new config system
|
||||
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
|
||||
Cmdline_window = 1;
|
||||
}
|
||||
|
||||
if ( fullscreen_window_arg.found( ) )
|
||||
{
|
||||
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
|
||||
Cmdline_fullscreen_window = 1;
|
||||
Cmdline_window = 0; /* Make sure no-one sets both */
|
||||
}
|
||||
|
||||
if(res_arg.found()){
|
||||
Cmdline_res = res_arg.str();
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
if ( sscanf(Cmdline_res, "%dx%d", &width, &height) == 2 ) {
|
||||
SCP_string override;
|
||||
sprintf(override, "{\"width\":%d,\"height\":%d}", width, height);
|
||||
options::OptionsManager::instance()->setOverride("Graphics.Resolution", override);
|
||||
} else {
|
||||
mprintf(("Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".", Cmdline_res));
|
||||
}
|
||||
}
|
||||
if(center_res_arg.found()){
|
||||
Cmdline_center_res = center_res_arg.str();
|
||||
@@ -1782,7 +1786,7 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
if ( nomotiondebris_arg.found() ) {
|
||||
Cmdline_nomotiondebris = 1;
|
||||
Motion_debris_enabled = false;
|
||||
}
|
||||
|
||||
if( mipmap_arg.found() ) {
|
||||
@@ -1794,11 +1798,11 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
if ( fov_arg.found() ) {
|
||||
Cmdline_fov = fov_arg.get_float();
|
||||
if (Cmdline_fov > 0.1) {
|
||||
VIEWER_ZOOM_DEFAULT = Cmdline_fov;
|
||||
auto val = fov_arg.get_float();
|
||||
if (val > 0.1) {
|
||||
VIEWER_ZOOM_DEFAULT = val;
|
||||
} else {
|
||||
VIEWER_ZOOM_DEFAULT = Cmdline_fov = 0.75f;
|
||||
VIEWER_ZOOM_DEFAULT = 0.75f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1812,7 +1816,7 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
if ( use_3dwarp.found() ) {
|
||||
Cmdline_3dwarp = 1;
|
||||
Fireball_use_3d_warp = true;
|
||||
}
|
||||
|
||||
if ( use_warp_flash.found() ) {
|
||||
@@ -1855,7 +1859,7 @@ bool SetCmdlineParams()
|
||||
|
||||
if(no_vsync_arg.found() )
|
||||
{
|
||||
Cmdline_no_vsync = 1;
|
||||
Gr_enable_vsync = false;
|
||||
}
|
||||
|
||||
if ( normal_arg.found() ) {
|
||||
@@ -1867,21 +1871,49 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
if (fxaa_arg.found() ) {
|
||||
Cmdline_fxaa = true;
|
||||
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
|
||||
|
||||
if (fxaa_preset_arg.found()) {
|
||||
Cmdline_fxaa_preset = fxaa_preset_arg.get_int();
|
||||
auto val = fxaa_preset_arg.get_int();
|
||||
if (val > 6) {
|
||||
Gr_aa_mode = AntiAliasMode::FXAA_High;
|
||||
} else if (val > 3) {
|
||||
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
|
||||
} else {
|
||||
Gr_aa_mode = AntiAliasMode::FXAA_Low;
|
||||
}
|
||||
}
|
||||
|
||||
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
|
||||
Gr_aa_mode_last_frame = Gr_aa_mode;
|
||||
}
|
||||
|
||||
if (smaa_arg.found()) {
|
||||
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
|
||||
|
||||
if (smaa_preset_arg.found()) {
|
||||
switch (smaa_preset_arg.get_int()) {
|
||||
case 0:
|
||||
Gr_aa_mode = AntiAliasMode::SMAA_Low;
|
||||
break;
|
||||
case 1:
|
||||
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
|
||||
break;
|
||||
case 2:
|
||||
Gr_aa_mode = AntiAliasMode::SMAA_High;
|
||||
break;
|
||||
case 3:
|
||||
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
|
||||
break;
|
||||
default:
|
||||
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( glow_arg.found() )
|
||||
Cmdline_glow = 0;
|
||||
|
||||
if ( query_speech_arg.found() )
|
||||
Cmdline_query_speech = 1;
|
||||
|
||||
if ( ship_choice_3d_arg.found() )
|
||||
Cmdline_ship_choice_3d = 1;
|
||||
|
||||
@@ -1964,9 +1996,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_ballistic_gauge = 1;
|
||||
}
|
||||
|
||||
if(old_collision_system.found())
|
||||
Cmdline_old_collision_sys = 1;
|
||||
|
||||
if(dis_collisions.found())
|
||||
Cmdline_dis_collisions = 1;
|
||||
|
||||
@@ -2016,17 +2045,17 @@ bool SetCmdlineParams()
|
||||
|
||||
if ( fb_explosions_arg.found() )
|
||||
{
|
||||
Cmdline_fb_explosions = 1;
|
||||
Gr_framebuffer_effects.set(FramebufferEffects::Shockwaves, true);
|
||||
}
|
||||
|
||||
if (fb_thrusters_arg.found())
|
||||
{
|
||||
Cmdline_fb_thrusters = true;
|
||||
Gr_framebuffer_effects.set(FramebufferEffects::Thrusters, true);
|
||||
}
|
||||
|
||||
if ( postprocess_arg.found() )
|
||||
{
|
||||
Cmdline_postprocess = 1;
|
||||
Gr_post_processing_enabled = true;
|
||||
}
|
||||
|
||||
if ( bloom_intensity_arg.found() )
|
||||
@@ -2046,12 +2075,32 @@ bool SetCmdlineParams()
|
||||
|
||||
if( enable_shadows_arg.found() )
|
||||
{
|
||||
Cmdline_shadow_quality = 2;
|
||||
Shadow_quality = ShadowQuality::Medium;
|
||||
}
|
||||
|
||||
if( shadow_quality_arg.found() )
|
||||
{
|
||||
Cmdline_shadow_quality = shadow_quality_arg.get_int();
|
||||
switch (shadow_quality_arg.get_int()) {
|
||||
case 0:
|
||||
Shadow_quality = ShadowQuality::Disabled;
|
||||
break;
|
||||
case 1:
|
||||
Shadow_quality = ShadowQuality::Low;
|
||||
break;
|
||||
case 2:
|
||||
Shadow_quality = ShadowQuality::Medium;
|
||||
break;
|
||||
case 3:
|
||||
Shadow_quality = ShadowQuality::High;
|
||||
break;
|
||||
case 4:
|
||||
Shadow_quality = ShadowQuality::Ultra;
|
||||
break;
|
||||
default:
|
||||
mprintf(("Invalid shadow quality %d. Disabling shadows...\n", shadow_quality_arg.get_int()));
|
||||
Shadow_quality = ShadowQuality::Disabled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( no_deferred_lighting_arg.found() )
|
||||
|
||||
@@ -55,7 +55,6 @@ extern char *Cmdline_center_res;
|
||||
// Graphics related
|
||||
extern double specular_exponent_value;
|
||||
extern float Cmdline_clip_dist;
|
||||
extern float Cmdline_fov;
|
||||
extern float Cmdline_ogl_spec;
|
||||
extern float static_light_factor;
|
||||
extern float static_point_factor;
|
||||
@@ -63,20 +62,13 @@ extern float static_tube_factor;
|
||||
extern int Cmdline_ambient_factor;
|
||||
extern int Cmdline_env;
|
||||
extern int Cmdline_glow;
|
||||
extern int Cmdline_nomotiondebris;
|
||||
extern int Cmdline_noscalevid; // disables fit-to-window for movies - taylor
|
||||
extern int Cmdline_spec;
|
||||
extern int Cmdline_normal;
|
||||
extern int Cmdline_height;
|
||||
extern int Cmdline_enable_3d_shockwave;
|
||||
extern int Cmdline_softparticles;
|
||||
extern int Cmdline_postprocess;
|
||||
extern int Cmdline_bloom_intensity;
|
||||
extern bool Cmdline_fxaa;
|
||||
extern int Cmdline_fxaa_preset;
|
||||
extern bool Cmdline_fb_explosions;
|
||||
extern bool Cmdline_fb_thrusters;
|
||||
extern int Cmdline_shadow_quality;
|
||||
extern int Cmdline_no_deferred_lighting;
|
||||
extern int Cmdline_no_emissive;
|
||||
extern int Cmdline_aniso_level;
|
||||
@@ -101,7 +93,6 @@ extern int Cmdline_autopilot_interruptable;
|
||||
extern int Cmdline_stretch_menu;
|
||||
|
||||
// Audio related
|
||||
extern int Cmdline_query_speech;
|
||||
extern int Cmdline_voice_recognition;
|
||||
extern int Cmdline_no_enhanced_sound;
|
||||
|
||||
@@ -140,7 +131,6 @@ extern bool Cmdline_alternate_registry_path;
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
extern int Cmdline_old_collision_sys;
|
||||
extern int Cmdline_dis_collisions;
|
||||
extern int Cmdline_dis_weapons;
|
||||
extern bool Cmdline_output_sexp_info;
|
||||
|
||||
@@ -53,26 +53,6 @@ void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
|
||||
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z );
|
||||
}
|
||||
|
||||
void cmeasure_select_next(ship *shipp)
|
||||
{
|
||||
Assert(shipp != NULL);
|
||||
int i, new_index;
|
||||
|
||||
for (i = 1; i < Num_weapon_types; i++)
|
||||
{
|
||||
new_index = (shipp->current_cmeasure + i) % Num_weapon_types;
|
||||
|
||||
if(Weapon_info[new_index].wi_flags[Weapon::Info_Flags::Cmeasure])
|
||||
{
|
||||
shipp->current_cmeasure = new_index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mprintf(("Countermeasure type set to %i in frame %i\n", shipp->current_cmeasure, Framecount));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief If this is a player countermeasure, let the player know they evaded a missile.
|
||||
* @param objp [description]
|
||||
|
||||
@@ -28,7 +28,6 @@ extern int Cmeasures_homing_check;
|
||||
extern int Countermeasures_enabled;
|
||||
|
||||
extern void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand);
|
||||
extern void cmeasure_select_next(object *objp);
|
||||
extern void cmeasure_maybe_alert_success(object *objp);
|
||||
|
||||
#endif // _CMEASURE_H
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
|
||||
|
||||
#define NUM_SYSTEM_KEYS 14
|
||||
#define NUM_BUTTONS 19
|
||||
#define NUM_TABS 4
|
||||
|
||||
@@ -157,11 +156,6 @@ char *Mouse_button_text[NUM_MOUSE_TEXT];
|
||||
char *Mouse_axis_text[NUM_MOUSE_AXIS_TEXT];
|
||||
char *Invert_text[NUM_INVERT_TEXT];
|
||||
|
||||
ubyte System_keys[NUM_SYSTEM_KEYS] = {
|
||||
KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,
|
||||
KEY_F11, KEY_F12, KEY_PRINT_SCRN
|
||||
};
|
||||
|
||||
int Control_check_count = 0;
|
||||
|
||||
static int Tab; // which tab we are currently in
|
||||
@@ -2193,17 +2187,6 @@ void control_config_do_frame(float frametime)
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
void clear_key_binding(short key)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].key_id == key) {
|
||||
Control_config[i].key_id = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float check_control_timef(int id)
|
||||
{
|
||||
float t1, t2;
|
||||
@@ -2447,9 +2430,4 @@ void control_config_clear()
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
Control_config[i].key_id = Control_config[i].joy_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int control_config_handle_conflict()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -277,12 +277,6 @@ enum IoActionId {
|
||||
};
|
||||
|
||||
extern int Failed_key_index;
|
||||
extern int Invert_heading;
|
||||
extern int Invert_pitch;
|
||||
extern int Invert_roll;
|
||||
extern int Invert_thrust;
|
||||
extern int Disable_axis2;
|
||||
extern int Disable_axis3;
|
||||
|
||||
extern int Axis_map_to[];
|
||||
extern int Invert_axis[];
|
||||
@@ -336,7 +330,6 @@ 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_used(int id);
|
||||
void control_config_clear();
|
||||
void clear_key_binding(short key);
|
||||
void control_check_indicate();
|
||||
void control_config_clear_used_status();
|
||||
|
||||
|
||||
@@ -34,13 +34,6 @@ int Failed_key_index;
|
||||
int Joy_dead_zone_size = 10;
|
||||
int Joy_sensitivity = 9;
|
||||
|
||||
// assume control keys are used as modifiers until we find out
|
||||
int Shift_is_modifier;
|
||||
int Ctrl_is_modifier;
|
||||
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 };
|
||||
|
||||
@@ -410,31 +403,6 @@ const char **Joy_button_text = Joy_button_text_english;
|
||||
SCP_vector<config_item*> Control_config_presets;
|
||||
SCP_vector<SCP_string> Control_config_preset_names;
|
||||
|
||||
void set_modifier_status()
|
||||
{
|
||||
int i;
|
||||
|
||||
Alt_is_modifier = 0;
|
||||
Shift_is_modifier = 0;
|
||||
Ctrl_is_modifier = 0;
|
||||
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].key_id < 0)
|
||||
continue;
|
||||
|
||||
if (Control_config[i].key_id & KEY_ALTED)
|
||||
Alt_is_modifier = 1;
|
||||
|
||||
if (Control_config[i].key_id & KEY_SHIFTED)
|
||||
Shift_is_modifier = 1;
|
||||
|
||||
if (Control_config[i].key_id & KEY_CTRLED) {
|
||||
Assert(0); // get Alan
|
||||
Ctrl_is_modifier = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If find_override is set to true, then this returns the index of the action
|
||||
// which has been bound to the given key. Otherwise, the index of the action
|
||||
// which has the given key as its default key will be returned.
|
||||
@@ -536,7 +504,9 @@ char *translate_key(char *key)
|
||||
// both key and joystick button are mapped to this control
|
||||
if ((key_code >= 0 ) && (joy_code >= 0) ) {
|
||||
strcpy_s(text, key_text);
|
||||
strcat_s(text, " or ");
|
||||
strcat_s(text, " ");
|
||||
strcat_s(text, XSTR("or", 1638));
|
||||
strcat_s(text, " ");
|
||||
strcat_s(text, joy_text);
|
||||
}
|
||||
// if we only have one
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace cutscene {
|
||||
FrameSize::FrameSize(size_t in_width, size_t in_height, size_t in_stride)
|
||||
: width(in_width), height(in_height), stride(in_stride)
|
||||
: width(in_width), height(in_height), stride(in_stride)
|
||||
{
|
||||
}
|
||||
FrameSize::FrameSize() = default;
|
||||
@@ -46,10 +46,6 @@ void Decoder::stopDecoder() {
|
||||
m_subtitleQueue->close();
|
||||
}
|
||||
|
||||
bool Decoder::canPushAudioData() {
|
||||
return !isAudioQueueFull();
|
||||
}
|
||||
|
||||
void Decoder::pushAudioData(AudioFramePtr&& data) {
|
||||
Assertion(data, "Invalid audio data passed!");
|
||||
|
||||
@@ -61,9 +57,6 @@ void Decoder::pushAudioData(AudioFramePtr&& data) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Decoder::canPushSubtitleData() {
|
||||
return !isSubtitleQueueFull();
|
||||
}
|
||||
void Decoder::pushSubtitleData(SubtitleFramePtr&& data) {
|
||||
Assertion(data, "Invalid audio data passed!");
|
||||
|
||||
@@ -75,10 +68,6 @@ void Decoder::pushSubtitleData(SubtitleFramePtr&& data) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Decoder::canPushVideoData() {
|
||||
return !isVideoQueueFull();
|
||||
}
|
||||
|
||||
void Decoder::pushFrameData(VideoFramePtr&& frame) {
|
||||
Assertion(frame, "Invalid video data passed!");
|
||||
|
||||
|
||||
+1
-11
@@ -11,8 +11,8 @@ struct FrameSize {
|
||||
size_t height = 0;
|
||||
size_t stride = 0;
|
||||
|
||||
FrameSize(size_t width, size_t in_height, size_t in_stride);
|
||||
FrameSize();
|
||||
FrameSize(size_t width, size_t in_height, size_t in_stride);
|
||||
};
|
||||
|
||||
class VideoFrame {
|
||||
@@ -147,10 +147,6 @@ class Decoder {
|
||||
|
||||
bool isSubtitleQueueFull() { return m_subtitleQueue->size() == m_queueSize; }
|
||||
|
||||
bool isSubtitleFrameAvailable() { return !m_subtitleQueue->empty(); }
|
||||
|
||||
size_t getSubtitleQueueSize() { return m_subtitleQueue->size(); }
|
||||
|
||||
bool tryPopSubtitleData(SubtitleFramePtr&);
|
||||
|
||||
bool isVideoQueueFull() { return m_videoQueue->size() == m_queueSize; }
|
||||
@@ -168,16 +164,10 @@ class Decoder {
|
||||
protected:
|
||||
void initializeQueues(size_t queueSize);
|
||||
|
||||
bool canPushAudioData();
|
||||
|
||||
void pushAudioData(AudioFramePtr&& data);
|
||||
|
||||
bool canPushSubtitleData();
|
||||
|
||||
void pushSubtitleData(SubtitleFramePtr&& data);
|
||||
|
||||
bool canPushVideoData();
|
||||
|
||||
void pushFrameData(VideoFramePtr&& frame);
|
||||
};
|
||||
}
|
||||
@@ -21,15 +21,7 @@ typedef struct cutscene_info
|
||||
bool viewable;
|
||||
} cutscene_info;
|
||||
|
||||
#if SCP_COMPILER_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
// This suppresses a GCC bug where it thinks that the Cutscenes from the enum class below shadows a global variable
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
extern SCP_vector<cutscene_info> Cutscenes;
|
||||
#if SCP_COMPILER_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// initializa table data
|
||||
void cutscene_init();
|
||||
|
||||
+4
-21
@@ -31,7 +31,6 @@
|
||||
#include "weapon/weapon.h"
|
||||
#include "tracing/Monitor.h"
|
||||
|
||||
#define MAX_LIFE 10.0f
|
||||
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
|
||||
#define DEBRIS_SOUND_DELAY 2000 // time to start debris sound after created
|
||||
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES // limit the number of hull debris chunks that can exist.
|
||||
@@ -52,10 +51,6 @@ int Debris_num_submodels = 0;
|
||||
#define DEBRIS_DISTANCE_CHECK_TIME (10*1000) // Check every 10 seconds.
|
||||
#define DEBRIS_INDEX(dp) (int)(dp-Debris)
|
||||
|
||||
#define MAX_SPEED_SMALL_DEBRIS 200 // maximum velocity of small debris piece
|
||||
#define MAX_SPEED_BIG_DEBRIS 150 // maximum velocity of big debris piece
|
||||
#define MAX_SPEED_CAPITAL_DEBRIS 100 // maximum velocity of capital debris piece
|
||||
|
||||
/**
|
||||
* Start the sequence of a piece of debris writhing in unholy agony!!!
|
||||
*/
|
||||
@@ -270,13 +265,8 @@ void debris_process_post(object * obj, float frame_time)
|
||||
|
||||
vec3d v1, v2, v3, v4;
|
||||
|
||||
if ( Cmdline_old_collision_sys ) {
|
||||
submodel_get_two_random_points( db->model_num, db->submodel_num, &v1, &v2 );
|
||||
submodel_get_two_random_points( db->model_num, db->submodel_num, &v3, &v4 );
|
||||
} else {
|
||||
submodel_get_two_random_points_better( db->model_num, db->submodel_num, &v1, &v2 );
|
||||
submodel_get_two_random_points_better( db->model_num, db->submodel_num, &v3, &v4 );
|
||||
}
|
||||
submodel_get_two_random_points_better(db->model_num, db->submodel_num, &v1, &v2);
|
||||
submodel_get_two_random_points_better(db->model_num, db->submodel_num, &v3, &v4);
|
||||
|
||||
n = 0;
|
||||
|
||||
@@ -352,12 +342,8 @@ void debris_process_post(object * obj, float frame_time)
|
||||
if ( mr < RAND_MAX/5 ) {
|
||||
vec3d v1, v2;
|
||||
|
||||
if ( Cmdline_old_collision_sys ) {
|
||||
submodel_get_two_random_points( db->model_num, db->submodel_num, &v1, &v2 );
|
||||
} else {
|
||||
submodel_get_two_random_points_better( db->model_num, db->submodel_num, &v1, &v2 );
|
||||
}
|
||||
|
||||
submodel_get_two_random_points_better(db->model_num, db->submodel_num, &v1, &v2);
|
||||
|
||||
db->arc_pts[i][mr % 2] = v1;
|
||||
}
|
||||
}
|
||||
@@ -505,7 +491,6 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
db->flags |= DEBRIS_USED;
|
||||
db->is_hull = hull_flag;
|
||||
db->source_objnum = parent_objnum;
|
||||
db->source_sig = source_obj->signature;
|
||||
db->damage_type_idx = shipp->debris_damage_type_idx;
|
||||
db->ship_info_index = shipp->ship_info_index;
|
||||
db->team = shipp->team;
|
||||
@@ -989,8 +974,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
// SET PHYSICS PARAMETERS
|
||||
// already have (hitpos - heavy) and light_cm_pos
|
||||
// get heavy cm pos - already have light_cm_pos
|
||||
debris_hit_info->heavy_collision_cm_pos = zero;
|
||||
|
||||
// get r_heavy and r_light
|
||||
debris_hit_info->r_heavy = debris_hit_info->hit_pos;
|
||||
|
||||
@@ -24,7 +24,6 @@ typedef struct debris {
|
||||
debris *next, *prev; // used for a linked list of the hull debris chunks
|
||||
int flags; // See DEBRIS_??? defines
|
||||
int source_objnum; // What object this came from
|
||||
int source_sig; // Signature of the source object
|
||||
int damage_type_idx; // Damage type of this debris
|
||||
int ship_info_index; // Ship info index of the ship type debris came from
|
||||
int team; // Team of the ship where the debris came from
|
||||
|
||||
@@ -70,7 +70,6 @@ int dc_font = font::FONT1;
|
||||
|
||||
SCP_string dc_title;
|
||||
|
||||
#define SCROLL_X_MAX (DBCOLS - DCOLS)
|
||||
#define SCROLL_Y_MAX (DBROWS - DROWS)
|
||||
|
||||
// Commands and History
|
||||
@@ -117,11 +116,6 @@ void dc_draw_window(bool show_prompt);
|
||||
*/
|
||||
void dc_putc(char c);
|
||||
|
||||
/**
|
||||
* @brief Predicate function used to sort debug_commands
|
||||
*/
|
||||
bool dcmd_less(debug_command *first, debug_command *second);
|
||||
|
||||
// ============================== IMPLEMENTATIONS =============================
|
||||
void dc_do_command(SCP_string *cmd_str)
|
||||
{
|
||||
@@ -494,11 +488,6 @@ void dc_putc(char c)
|
||||
line_str->push_back(c);
|
||||
}
|
||||
|
||||
bool dcmd_less(debug_command *first, debug_command *second)
|
||||
{
|
||||
return (strcmp(first->name, second->name) < 0);
|
||||
}
|
||||
|
||||
void debug_console(void (*_func)(void))
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
@@ -28,10 +28,6 @@ debug_command *dc_commands[DC_MAX_COMMANDS];
|
||||
int dc_commands_size = 0;
|
||||
|
||||
// ========================= LOCALS ==========================
|
||||
// dcf_shell commands
|
||||
void dc_shell_font( void );
|
||||
void dc_shell_resize( void );
|
||||
void dc_shell_resize_buf( void );
|
||||
|
||||
// =================== class debug_command ===================
|
||||
debug_command::debug_command()
|
||||
@@ -155,6 +151,4 @@ DCF(help, "Displays the help list." )
|
||||
|
||||
dc_printf(" %s - %s\n", dc_commands[i]->name, dc_commands[i]->help);
|
||||
}
|
||||
}
|
||||
|
||||
debug_command dc_man("man", "Also displays the help list", dcf_help);
|
||||
}
|
||||
@@ -226,6 +226,7 @@ void parse_decals_table(const char* filename) {
|
||||
struct Decal {
|
||||
int definition_handle = -1;
|
||||
object_h object;
|
||||
int orig_obj_type = OBJ_NONE;
|
||||
int submodel = -1;
|
||||
|
||||
float creation_time = -1.0f; //!< The mission time at which this decal was created
|
||||
@@ -244,6 +245,12 @@ struct Decal {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (orig_obj_type != object.objp->type) {
|
||||
mprintf(("Decal object type for object %d has changed from %s to %s. Please let m!m know about this\n",
|
||||
OBJ_INDEX(object.objp), Object_type_names[orig_obj_type], Object_type_names[object.objp->type]));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lifetime > 0.0f) {
|
||||
if (f2fl(Missiontime) >= creation_time + lifetime) {
|
||||
// Decal has expired
|
||||
@@ -525,6 +532,7 @@ addDecal(creation_info& info, object* host, int submodel, const vec3d& local_pos
|
||||
Decal newDecal;
|
||||
newDecal.definition_handle = info.definition_handle;
|
||||
newDecal.object = object_h(host);
|
||||
newDecal.orig_obj_type = host->type;
|
||||
newDecal.submodel = submodel;
|
||||
newDecal.creation_time = f2fl(Missiontime);
|
||||
newDecal.lifetime = info.lifetime.next();
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,23 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
#define SMAA_INCLUDE_VS 0
|
||||
#define SMAA_INCLUDE_PS 1
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec2 fragPixcoord;
|
||||
in vec4 fragOffset[3];
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D edgesTex;
|
||||
uniform sampler2D areaTex;
|
||||
uniform sampler2D searchTex;
|
||||
|
||||
void main() {
|
||||
fragOut0 = SMAABlendingWeightCalculationPS(fragTexCoord, fragPixcoord, fragOffset, edgesTex, areaTex, searchTex, vec4(0.0));
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
#define SMAA_INCLUDE_VS 1
|
||||
#define SMAA_INCLUDE_PS 0
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
in vec4 vertPosition;
|
||||
in vec2 vertTexCoord;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
out vec2 fragPixcoord;
|
||||
out vec4 fragOffset[3];
|
||||
|
||||
void main() {
|
||||
gl_Position = vertPosition;
|
||||
fragTexCoord = vertTexCoord;
|
||||
SMAABlendingWeightCalculationVS(vertTexCoord, fragPixcoord, fragOffset);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
#define SMAA_INCLUDE_VS 0
|
||||
#define SMAA_INCLUDE_PS 1
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragOffset[3];
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
|
||||
void main() {
|
||||
fragOut0 = vec4(SMAALumaEdgeDetectionPS(fragTexCoord, fragOffset, colorTex), 0.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
#define SMAA_INCLUDE_VS 1
|
||||
#define SMAA_INCLUDE_PS 0
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
in vec4 vertPosition;
|
||||
in vec2 vertTexCoord;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragOffset[3];
|
||||
|
||||
void main() {
|
||||
gl_Position = vertPosition;
|
||||
fragTexCoord = vertTexCoord;
|
||||
SMAAEdgeDetectionVS(vertTexCoord, fragOffset);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
#define SMAA_INCLUDE_VS 0
|
||||
#define SMAA_INCLUDE_PS 1
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragOffset;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D blendTex;
|
||||
|
||||
void main() {
|
||||
fragOut0 = SMAANeighborhoodBlendingPS(fragTexCoord, fragOffset, colorTex, blendTex);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
#define SMAA_INCLUDE_VS 1
|
||||
#define SMAA_INCLUDE_PS 0
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
in vec4 vertPosition;
|
||||
in vec2 vertTexCoord;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragOffset;
|
||||
|
||||
void main() {
|
||||
gl_Position = vertPosition;
|
||||
fragTexCoord = vertTexCoord;
|
||||
SMAANeighborhoodBlendingVS(vertTexCoord, fragOffset);
|
||||
}
|
||||
@@ -45,7 +45,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 600.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Actively Pursues: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
|
||||
+Turrets attack this: YES
|
||||
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
|
||||
@@ -79,7 +79,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 500.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "dock" "undock" "waypoints" "waypoints once" "stay near ship" "keep safe dist" "stay still" "play dead" )
|
||||
+Valid goals: ( "fly to ship" "dock" "undock" "waypoints" "waypoints once" "stay near ship" "keep safe dist" "stay still" "play dead" "play dead (persistent)" )
|
||||
+Accept Player Orders: YES
|
||||
+Player orders: ( "rearm me" "abort rearm" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -104,7 +104,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 500.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "stay near ship" "keep safe dist" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "disable ship" "disarm ship" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "depart" "disable subsys" )
|
||||
+Auto attacks: YES
|
||||
@@ -130,7 +130,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 500.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "stay near ship" "keep safe dist" "form on wing")
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing")
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "disable ship" "disarm ship" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "depart" "disable subsys" )
|
||||
+Auto attacks: YES
|
||||
@@ -157,7 +157,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 500.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "stay near ship" "keep safe dist" "form on wing" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "disable ship" "disarm ship" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "depart" "disable subsys" )
|
||||
+Auto attacks: YES
|
||||
@@ -184,7 +184,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 500.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "stay near ship" "keep safe dist" "form on wing" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disarm ship" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "disable ship" "disarm ship" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "depart" "disable subsys" )
|
||||
+Auto attacks: YES
|
||||
@@ -210,7 +210,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 500.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "dock" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -238,7 +238,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 600.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "dock" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -266,7 +266,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 600.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -293,7 +293,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 600.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -320,7 +320,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 600.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -347,7 +347,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 600.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "dock" "waypoints" "waypoints once" "depart" "undock" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "attack ship" "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -375,7 +375,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 750.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "waypoints" "waypoints once" "depart" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "waypoints" "waypoints once" "depart" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Accept Player Orders: YES
|
||||
+Player Orders: ( "depart" )
|
||||
+Auto attacks: YES
|
||||
@@ -403,7 +403,7 @@ $Fog:
|
||||
+Start dist: 10.0
|
||||
+Compl dist: 1000.0
|
||||
$AI:
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "waypoints" "waypoints once" "depart" "stay still" "play dead" "stay near ship" )
|
||||
+Valid goals: ( "fly to ship" "attack ship" "attack wing" "waypoints" "waypoints once" "depart" "stay still" "play dead" "play dead (persistent)" "stay near ship" )
|
||||
+Auto attacks: YES
|
||||
+Attempt Broadside: YES
|
||||
+Actively Pursues: ( "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
/*
|
||||
* 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
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "fireball/fireballs.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "fireball/fireballs.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "graphics/tmapper.h"
|
||||
#include "localization/localize.h"
|
||||
#include "model/model.h"
|
||||
#include "object/object.h"
|
||||
#include "options/Option.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "render/3d.h"
|
||||
#include "render/batching.h"
|
||||
@@ -46,8 +45,15 @@ int Num_fireball_types = 0;
|
||||
bool fireballs_inited = false;
|
||||
bool fireballs_parsed = false;
|
||||
|
||||
#define FB_INDEX(fb) (fb-Fireballs)
|
||||
bool Fireball_use_3d_warp = false;
|
||||
|
||||
static auto WarpOption = options::OptionBuilder<bool>("Graphics.3dWarp", "3D Warp", "Use a 3D model for warp effects")
|
||||
.category("Graphics")
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Fireball_use_3d_warp)
|
||||
.importance(65)
|
||||
.finish();
|
||||
/**
|
||||
* Play warp in sound for warp effect
|
||||
*/
|
||||
@@ -767,7 +773,7 @@ int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
|
||||
/**
|
||||
* Create a fireball, return object index.
|
||||
*/
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, gamesnd_id warp_open_sound, gamesnd_id warp_close_sound, float warp_open_duration, float warp_close_duration)
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, bool reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, gamesnd_id warp_open_sound, gamesnd_id warp_close_sound, float warp_open_duration, float warp_close_duration)
|
||||
{
|
||||
int n, objnum, fb_lod;
|
||||
object *obj;
|
||||
|
||||
@@ -103,11 +103,11 @@ void fireball_parse_tbl();
|
||||
|
||||
int fireball_info_lookup(const char *unique_id);
|
||||
|
||||
// reversed is for warp_in/out effects
|
||||
// Velocity: If not NULL, the fireball will move at a constant velocity.
|
||||
// reverse is for warp_in/out effects
|
||||
// velocity: If not NULL, the fireball will move at a constant velocity.
|
||||
// warp_lifetime: If warp_lifetime > 0.0f then makes the explosion loop so it lasts this long. Only works for warp effect
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reversed=0, vec3d *velocity=nullptr, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=nullptr, int low_res=0, int extra_flags=0, gamesnd_id warp_open_sound=gamesnd_id(), gamesnd_id warp_close_sound=gamesnd_id(), float warp_open_duration=-1.0f, float warp_close_duration=-1.0f);
|
||||
void fireball_render_plane(int plane);
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, bool reverse=false, vec3d *velocity=nullptr, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=nullptr, int low_res=0, int extra_flags=0, gamesnd_id warp_open_sound=gamesnd_id(), gamesnd_id warp_close_sound=gamesnd_id(), float warp_open_duration=-1.0f, float warp_close_duration=-1.0f);
|
||||
|
||||
void fireball_close();
|
||||
|
||||
// Returns 1 if you can remove this fireball
|
||||
@@ -137,4 +137,6 @@ float fireball_wormhole_intensity( fireball *fb );
|
||||
// Goober5000
|
||||
extern int Knossos_warp_ani_used;
|
||||
|
||||
extern bool Fireball_use_3d_warp;
|
||||
|
||||
#endif /* _FIREBALLS_H */
|
||||
@@ -100,7 +100,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
|
||||
}
|
||||
}
|
||||
|
||||
if ( (warp_model_id >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
if ( (warp_model_id >= 0) && (warp_3d || Fireball_use_3d_warp) ) {
|
||||
model_render_params render_info;
|
||||
|
||||
float scale = radius / 25.0f;
|
||||
@@ -137,7 +137,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
|
||||
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], center, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
verts[0].texture_position.u = 0.01f;
|
||||
|
||||
@@ -109,38 +109,6 @@ static int Gameplay_help_inited = 0;
|
||||
|
||||
static int Current_help_page;
|
||||
|
||||
// generate a line for the on-line help for a control item with specified id
|
||||
// input: id => index for control item within Control_config[]
|
||||
// buf => buffer with enough space to hold ouput string
|
||||
const char *gameplay_help_control_text(int id, char *buf)
|
||||
{
|
||||
int has_key=0, has_joy=0;
|
||||
config_item *ci;
|
||||
|
||||
ci = &Control_config[id];
|
||||
|
||||
if ( ci->key_id >= 0 ) {
|
||||
strcpy(buf, textify_scancode(ci->key_id));
|
||||
has_key=1;
|
||||
}
|
||||
|
||||
if ( ci->joy_id >= 0 ) {
|
||||
if ( has_key ) {
|
||||
strcat(buf, XSTR( ", ", 129));
|
||||
}
|
||||
strcat(buf, Joy_button_text[ci->joy_id]);
|
||||
has_joy=1;
|
||||
}
|
||||
|
||||
if ( !has_key && !has_joy ) {
|
||||
strcpy(buf, XSTR( "no binding", 130));
|
||||
}
|
||||
|
||||
strcat(buf, XSTR( " - ", 131));
|
||||
strcat(buf, ci->text);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void gameplay_help_blit_control_line(int x, int y, int id)
|
||||
{
|
||||
@@ -824,20 +792,3 @@ void gameplay_help_do_frame(float /*frametime*/)
|
||||
gameplay_help_draw_text();
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
|
||||
// called once when leaving the gameplay help state
|
||||
void gameplay_help_close()
|
||||
{
|
||||
if ( Gameplay_help_inited ) {
|
||||
if (Background_bitmap >= 0) {
|
||||
bm_release(Background_bitmap);
|
||||
}
|
||||
|
||||
Ui_window.destroy();
|
||||
common_free_interface_palette(); // restore game palette
|
||||
game_flush();
|
||||
}
|
||||
|
||||
Gameplay_help_inited = 0;
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
#define __GAMEPLAY_HELP_H__
|
||||
|
||||
void gameplay_help_init();
|
||||
void gameplay_help_close();
|
||||
void gameplay_help_do_frame(float frametime);
|
||||
|
||||
#endif
|
||||
@@ -350,29 +350,6 @@ void gameseq_pop_state()
|
||||
|
||||
}
|
||||
|
||||
// gameseq_pop_and_discard_state() is used to remove a state that was pushed onto the stack, but
|
||||
// will never need to be popped. An example of this is entering a state that may require returning
|
||||
// to the previous state (then you would call gameseq_pop_state). Or you may simply continue to
|
||||
// another part of the game, to avoid filling up the stack with states that may never be popped, you
|
||||
// call this function to discard the top of the gs.
|
||||
//
|
||||
|
||||
void gameseq_pop_and_discard_state()
|
||||
{
|
||||
if (gs_current_stack > 0 ) {
|
||||
gs_current_stack--;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the last state pushed on stack
|
||||
int gameseq_get_pushed_state()
|
||||
{
|
||||
if (gs_current_stack >= 1) {
|
||||
return gs[gs_current_stack-1].current_state;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// gameseq_process_events gets called every time through high level loops
|
||||
// (i.e. game loops, main menu loop). Function is responsible for pulling
|
||||
// game sequence events off the queue and changing the state when necessary.
|
||||
|
||||
@@ -181,11 +181,8 @@ int gameseq_get_event( void );
|
||||
void gameseq_set_state(int new_state, int override = 0);
|
||||
void gameseq_push_state( int new_state );
|
||||
void gameseq_pop_state( void );
|
||||
int gameseq_get_pushed_state();
|
||||
int gameseq_get_depth();
|
||||
int gameseq_get_previous_state();
|
||||
void gameseq_pop_and_discard_state(void);
|
||||
|
||||
|
||||
// Called by the sequencing code when things happen.
|
||||
void game_process_event(int current_state, int event);
|
||||
|
||||
@@ -57,11 +57,8 @@ SOUNDTRACK_INFO Soundtracks[MAX_SOUNDTRACKS];
|
||||
int Num_soundtracks;
|
||||
int Current_soundtrack_num; // Active soundtrack for the current mission.. index into Soundtracks[]
|
||||
|
||||
#define PATTERN_DELAY 1000 // in ms
|
||||
int Current_pattern = -1; // currently playing part of track
|
||||
int Pending_pattern = -1;
|
||||
int Pattern_timer_id = 0;
|
||||
int Current_nrml = SONG_NRML_1;
|
||||
|
||||
// File Globals
|
||||
static int Num_enemy_arrivals;
|
||||
@@ -240,7 +237,6 @@ static int Event_music_begun = FALSE;
|
||||
|
||||
// forward function declarations
|
||||
int hostile_ships_present();
|
||||
int hostile_ships_to_arrive();
|
||||
extern int hud_target_invalid_awacs(object *objp);
|
||||
|
||||
// Holds file names of spooled music that is played at menus, briefings, credits etc.
|
||||
@@ -544,7 +540,6 @@ void event_music_level_init(int force_soundtrack)
|
||||
return;
|
||||
|
||||
Current_pattern = -1;
|
||||
Current_nrml = SONG_NRML_1;
|
||||
|
||||
if (Event_music_inited == FALSE)
|
||||
return;
|
||||
@@ -556,15 +551,6 @@ void event_music_level_init(int force_soundtrack)
|
||||
if (Current_soundtrack_num < 0)
|
||||
{
|
||||
return;
|
||||
/*
|
||||
// okay, assign a random soundtrack if one exists
|
||||
if ( Num_soundtracks > 0 ) {
|
||||
Current_soundtrack_num = rand()%Num_soundtracks;
|
||||
nprintf(("EVENTMUSIC", "EVENTMUSIC ==> Picking random event music soundtrack: %s\n", Soundtracks[Current_soundtrack_num].name));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Assert(Current_soundtrack_num >= 0 && Current_soundtrack_num < Num_soundtracks);
|
||||
@@ -631,9 +617,7 @@ void event_music_level_init(int force_soundtrack)
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// event_music_first_pattern()
|
||||
//
|
||||
// Picks the first pattern to play, based on whether the battle has started. Delay start
|
||||
// by PATTERN_DELAY
|
||||
//
|
||||
// Picks the first pattern to play, based on whether the battle has started.
|
||||
void event_music_first_pattern()
|
||||
{
|
||||
if ( Event_music_inited == FALSE ) {
|
||||
@@ -1520,59 +1504,6 @@ void event_music_start_default()
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// event_music_pause()
|
||||
//
|
||||
// Stop any playing pattern, but don't rewind.
|
||||
//
|
||||
void event_music_pause()
|
||||
{
|
||||
if ( Event_music_enabled == FALSE ) {
|
||||
nprintf(("EVENTMUSIC", "EVENTMUSIC ==> Requested a song switch when event music is not enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Event_music_level_inited == FALSE ) {
|
||||
nprintf(("EVENTMUSIC", "EVENTMUSIC ==> Event music is not enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Current_pattern == -1)
|
||||
return;
|
||||
|
||||
Assert( Current_pattern >= 0 && Current_pattern < MAX_PATTERNS );
|
||||
if ( audiostream_is_playing(Patterns[Current_pattern].handle) ) {
|
||||
audiostream_stop(Patterns[Current_pattern].handle, 0); // stop current and don't rewind
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// event_music_unpause()
|
||||
//
|
||||
// Start the Current_pattern if it is paused.
|
||||
//
|
||||
void event_music_unpause()
|
||||
{
|
||||
if ( Event_music_enabled == FALSE ) {
|
||||
nprintf(("EVENTMUSIC", "EVENTMUSIC ==> Requested a song switch when event music is not enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Event_music_level_inited == FALSE ) {
|
||||
nprintf(("EVENTMUSIC", "EVENTMUSIC ==> Event music is not enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Current_pattern == -1)
|
||||
return;
|
||||
|
||||
Assert( Current_pattern >= 0 && Current_pattern < MAX_PATTERNS );
|
||||
if ( audiostream_is_paused(Patterns[Current_pattern].handle) == TRUE ) {
|
||||
audiostream_play(Patterns[Current_pattern].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
|
||||
audiostream_set_sample_cutoff(Patterns[Current_pattern].handle, fl2i(Patterns[Current_pattern].num_measures * Patterns[Current_pattern].samples_per_measure) );
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// event_music_set_volume_all()
|
||||
//
|
||||
@@ -1628,33 +1559,6 @@ int hostile_ships_present()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// hostile_ships_to_arrive()
|
||||
//
|
||||
// Determine if there are any non-friendly ships yet to arrive
|
||||
//
|
||||
// NOTE: neutral ships are considered hostile for the purpose of event music
|
||||
//
|
||||
int hostile_ships_to_arrive()
|
||||
{
|
||||
p_object *p_objp;
|
||||
|
||||
for (p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp))
|
||||
{
|
||||
// check if ship can arrive
|
||||
if (p_objp->flags[Mission::Parse_Object_Flags::SF_Cannot_arrive])
|
||||
continue;
|
||||
|
||||
// check if ship is enemy ship (we attack it)
|
||||
if (!(iff_x_attacks_y(Player_ship->team, p_objp->team)))
|
||||
continue;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// event_music_get_info()
|
||||
//
|
||||
|
||||
@@ -102,8 +102,6 @@ void event_music_level_close();
|
||||
void event_music_do_frame();
|
||||
void event_music_disable();
|
||||
void event_music_enable();
|
||||
void event_music_pause();
|
||||
void event_music_unpause();
|
||||
void event_music_set_volume_all(float volume);
|
||||
void event_music_parse_musictbl(const char *filename);
|
||||
void event_music_change_pattern(int new_pattern);
|
||||
|
||||
@@ -246,7 +246,7 @@ enum class GameSounds {
|
||||
/**
|
||||
* Interface sounds
|
||||
*/
|
||||
enum InterfaceSounds {
|
||||
enum class InterfaceSounds {
|
||||
IFACE_MOUSE_CLICK =0, //!< mouse click
|
||||
ICON_PICKUP =1, //!< pick up a ship icon (Empty in Retail)
|
||||
ICON_DROP_ON_WING =2, //!< drop a ship icon on a wing slot
|
||||
|
||||
@@ -125,8 +125,17 @@ class flagset {
|
||||
|
||||
void from_u64(std::uint64_t num) { values = (unsigned long) num; }
|
||||
std::uint64_t to_u64() const { return (std::uint64_t) values.to_ulong(); }
|
||||
|
||||
size_t hash() const { return std::hash<std::bitset<SIZE>>()(values); }
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <typename T, size_t N>
|
||||
struct hash<::flagset<T, N>> {
|
||||
size_t operator()(const ::flagset<T, N>& val) { return val.hash(); }
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#define FLAG_LIST(Type) enum class Type : size_t
|
||||
|
||||
template<typename TEnum, size_t SIZE>
|
||||
|
||||
@@ -450,7 +450,7 @@ SCP_string dump_stacktrace();
|
||||
// DEBUG compile time catch for dangerous uses of memset/memcpy/memmove
|
||||
// This is disabled for VS2013 and lower since that doesn't support the necessary features
|
||||
#if !defined(NDEBUG) && !defined(USING_THIRD_PARTY_LIBS) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
|
||||
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(HAVE_STD_IS_TRIVIALLY_COPYABLE)
|
||||
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE)
|
||||
// feature support seems to be: gcc clang msvc
|
||||
// auto 4.4 2.9 2010
|
||||
// std::is_trivial 4.5 ? 2012 (2010 only duplicates std::is_pod)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "scp_compiler_detection.h"
|
||||
#include "platformChecks.h"
|
||||
|
||||
#define SCP_TOKEN_CONCAT1(x, y) x ## y
|
||||
#define SCP_TOKEN_CONCAT(x, y) SCP_TOKEN_CONCAT1(x, y)
|
||||
|
||||
@@ -61,6 +61,7 @@ version get_executable_version() {
|
||||
version::version(int major_in, int minor_in, int build_in, int revision_in) :
|
||||
major(major_in), minor(minor_in), build(build_in), revision(revision_in) {
|
||||
}
|
||||
bool version::isValid() const { return major != 0 || minor != 0 || build != 0 || revision != 0; }
|
||||
bool version::operator<(const version& v) const {
|
||||
|
||||
if (major < v.major) {
|
||||
|
||||
@@ -57,6 +57,8 @@ struct version {
|
||||
|
||||
version(int major, int minor, int build, int revision);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
bool operator<(const version& other) const;
|
||||
bool operator==(const version& other) const;
|
||||
bool operator!=(const version& other) const;
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
/* SCP_vm_allocator - maintained by portej05 (i.e. please don't patch this one yourself!) */
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
template< typename T >
|
||||
using SCP_vector = std::vector< T, std::allocator< T > >;
|
||||
@@ -35,7 +35,41 @@ using SCP_queue = std::queue< T, std::deque< T, std::allocator< T > > >;
|
||||
template< typename T >
|
||||
using SCP_deque = std::deque< T, std::allocator< T > >;
|
||||
|
||||
template< typename Key, typename T, typename Hash = std::hash<Key>, typename KeyEqual = std::equal_to<Key> >
|
||||
using SCP_unordered_map = std::unordered_map< Key, T, Hash, KeyEqual, std::allocator< std::pair<const Key, T> > >;
|
||||
#if __cplusplus < 201402L
|
||||
template <class T, bool>
|
||||
struct enum_hasher_util {
|
||||
inline size_t operator()(const T& elem) { return std::hash<T>()(elem); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enum_hasher_util<T, true> {
|
||||
inline size_t operator()(const T& elem)
|
||||
{
|
||||
typedef typename std::underlying_type<T>::type enumType;
|
||||
return std::hash<enumType>()(static_cast<enumType>(elem));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An enum class compatible hashing class
|
||||
*
|
||||
* This is the same as std::hash except that is can handle enum classes properly using their underlying type. This is
|
||||
* only required for C++ < 14 since after that the standard mandates that enum classes should be hashable.
|
||||
*
|
||||
* @tparam T The type that should be hashed
|
||||
*/
|
||||
template <class T>
|
||||
struct SCP_hash {
|
||||
inline size_t operator()(const T& elem) const { return enum_hasher_util<T, std::is_enum<T>::value>()(elem); }
|
||||
};
|
||||
|
||||
#else
|
||||
// No need for the special hash class so just use the standard hash
|
||||
template <typename T>
|
||||
using SCP_hash = std::hash<T>;
|
||||
#endif
|
||||
|
||||
template <typename Key, typename T, typename Hash = SCP_hash<Key>, typename KeyEqual = std::equal_to<Key>>
|
||||
using SCP_unordered_map = std::unordered_map<Key, T, Hash, KeyEqual, std::allocator<std::pair<const Key, T>>>;
|
||||
|
||||
#endif // _VMALLOCATOR_H_INCLUDED_
|
||||
+299
-49
@@ -36,6 +36,8 @@
|
||||
#include "graphics/util/UniformBufferManager.h"
|
||||
#include "io/keycontrol.h" // m!m
|
||||
#include "io/timer.h"
|
||||
#include "libs/jansson.h"
|
||||
#include "options/Option.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "popup/popup.h"
|
||||
@@ -103,6 +105,246 @@ float Gr_save_menu_zoomed_offset_X = 0.0f, Gr_save_menu_zoomed_offset_Y = 0.0f;
|
||||
|
||||
bool Save_custom_screen_size;
|
||||
|
||||
static int videodisplay_deserializer(const json_t* value)
|
||||
{
|
||||
int id;
|
||||
|
||||
json_error_t err;
|
||||
if (json_unpack_ex((json_t*)value, &err, 0, "i", &id) != 0) {
|
||||
throw json_exception(err);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
static json_t* videodisplay_serializer(int value) { return json_pack("i", value); }
|
||||
static SCP_vector<int> videodisplay_enumerator()
|
||||
{
|
||||
SCP_vector<int> vals;
|
||||
for (int i = 0; i < SDL_GetNumVideoDisplays(); ++i) {
|
||||
vals.push_back(i);
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
static SCP_string videodisplay_display(int id)
|
||||
{
|
||||
SCP_string out;
|
||||
sprintf(out, "(%d) %s", id + 1, SDL_GetDisplayName(id));
|
||||
return out;
|
||||
}
|
||||
static bool videodisplay_change(int display, bool initial)
|
||||
{
|
||||
if (initial) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto window = os::getSDLMainWindow();
|
||||
if (window == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display));
|
||||
return true;
|
||||
}
|
||||
static auto VideoDisplayOption =
|
||||
options::OptionBuilder<int>("Graphics.Display", "Primary display", "The display used for rendering.")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.deserializer(videodisplay_deserializer)
|
||||
.serializer(videodisplay_serializer)
|
||||
.enumerator(videodisplay_enumerator)
|
||||
.display(videodisplay_display)
|
||||
.default_val(0)
|
||||
.change_listener(videodisplay_change)
|
||||
.importance(99)
|
||||
.finish();
|
||||
|
||||
struct ResolutionInfo {
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
ResolutionInfo(uint32_t _width, uint32_t _height) : width(_width), height(_height) {}
|
||||
ResolutionInfo() = default;
|
||||
friend bool operator==(const ResolutionInfo& lhs, const ResolutionInfo& rhs)
|
||||
{
|
||||
return lhs.width == rhs.width && lhs.height == rhs.height;
|
||||
}
|
||||
friend bool operator!=(const ResolutionInfo& lhs, const ResolutionInfo& rhs) { return !(rhs == lhs); }
|
||||
};
|
||||
|
||||
static ResolutionInfo resolution_deserializer(const json_t* el)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
|
||||
json_error_t err;
|
||||
if (json_unpack_ex((json_t*)el, &err, 0, "{s:i, s:i}", "width", &width, "height", &height) != 0) {
|
||||
throw json_exception(err);
|
||||
}
|
||||
|
||||
return {(uint32_t)width, (uint32_t)height};
|
||||
}
|
||||
static json_t* resolution_serializer(const ResolutionInfo& value)
|
||||
{
|
||||
return json_pack("{s:i, s:i}", "width", value.width, "height", value.height);
|
||||
}
|
||||
static SCP_vector<ResolutionInfo> resolution_enumerator()
|
||||
{
|
||||
SCP_vector<ResolutionInfo> out;
|
||||
auto display = VideoDisplayOption->getValue();
|
||||
for (auto i = 0; i < SDL_GetNumDisplayModes(display); ++i) {
|
||||
SDL_DisplayMode mode;
|
||||
if (SDL_GetDisplayMode(display, i, &mode) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto res = ResolutionInfo(mode.w, mode.h);
|
||||
if (std::find(out.begin(), out.end(), res) == out.end()) {
|
||||
out.push_back(res);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
static SCP_string resolution_display(const ResolutionInfo& info)
|
||||
{
|
||||
SCP_string str;
|
||||
sprintf(str, "%dx%d", info.width, info.height);
|
||||
return str;
|
||||
}
|
||||
static ResolutionInfo resolution_default()
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
if (SDL_GetDesktopDisplayMode(VideoDisplayOption->getValue(), &mode) != 0) {
|
||||
return {};
|
||||
}
|
||||
return ResolutionInfo(mode.w, mode.h);
|
||||
}
|
||||
static bool resolution_change(const ResolutionInfo& /*info*/, bool initial)
|
||||
{
|
||||
if (initial) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
// The following code should change the size of the window properly but FSO currently can't handle that
|
||||
/*
|
||||
auto window = os::getSDLMainWindow();
|
||||
if (window == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto display = VideoDisplayOption->getValue();
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
|
||||
SDL_DisplayMode target;
|
||||
target.w = info.width;
|
||||
target.h = info.height;
|
||||
target.format = 0; // don't care
|
||||
target.refresh_rate = 0; // don't care
|
||||
target.driverdata = 0; // initialize to 0
|
||||
|
||||
SDL_DisplayMode closest;
|
||||
if (SDL_GetClosestDisplayMode(display, &target, &closest) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_SetWindowDisplayMode(window, &closest);
|
||||
} else {
|
||||
SDL_SetWindowSize(window, info.width, info.height);
|
||||
// Recenter the window
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display));
|
||||
}
|
||||
*/
|
||||
}
|
||||
static auto ResolutionOption =
|
||||
options::OptionBuilder<ResolutionInfo>("Graphics.Resolution", "Resolution", "The rendering resolution.")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.deserializer(resolution_deserializer)
|
||||
.serializer(resolution_serializer)
|
||||
.enumerator(resolution_enumerator)
|
||||
.display(resolution_display)
|
||||
.default_func(resolution_default)
|
||||
.change_listener(resolution_change)
|
||||
.importance(100)
|
||||
.finish();
|
||||
|
||||
bool Gr_enable_soft_particles = false;
|
||||
|
||||
static auto SoftParticlesOption = options::OptionBuilder<bool>("Graphics.SoftParticles", "Soft Particles",
|
||||
"Enable or disable soft particle rendering.")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_enable_soft_particles)
|
||||
.importance(68)
|
||||
.finish();
|
||||
|
||||
flagset<FramebufferEffects> Gr_framebuffer_effects;
|
||||
|
||||
static auto FramebufferEffectsOption =
|
||||
options::OptionBuilder<flagset<FramebufferEffects>>(
|
||||
"Graphics.FramebufferEffects", "Framebuffer effects",
|
||||
"Controls which framebuffer effects will be applied to the scene.")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{{}, "None"},
|
||||
{{FramebufferEffects::Shockwaves}, "Shockwaves"},
|
||||
{{FramebufferEffects::Thrusters}, "Thrusters"},
|
||||
{{FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters}, "All"}})
|
||||
.default_val({FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters})
|
||||
.bind_to_once(&Gr_framebuffer_effects)
|
||||
.importance(77)
|
||||
.finish();
|
||||
|
||||
AntiAliasMode Gr_aa_mode = AntiAliasMode::None;
|
||||
AntiAliasMode Gr_aa_mode_last_frame = AntiAliasMode::None;
|
||||
|
||||
static auto AAOption = options::OptionBuilder<AntiAliasMode>("Graphics.AAMode", "Anti Aliasing",
|
||||
"Controls the anti aliasing mode of the engine.")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{AntiAliasMode::None, "None"},
|
||||
{AntiAliasMode::FXAA_Low, "FXAA Low"},
|
||||
{AntiAliasMode::FXAA_Medium, "FXAA Medium"},
|
||||
{AntiAliasMode::FXAA_High, "FXAA High"},
|
||||
{AntiAliasMode::SMAA_Low, "SMAA Low"},
|
||||
{AntiAliasMode::SMAA_Medium, "SMAA Medium"},
|
||||
{AntiAliasMode::SMAA_High, "SMAA High"},
|
||||
{AntiAliasMode::SMAA_Ultra, "SMAA Ultra"}})
|
||||
.default_val(AntiAliasMode::None)
|
||||
.bind_to(&Gr_aa_mode)
|
||||
.importance(79)
|
||||
.finish();
|
||||
|
||||
bool gr_is_fxaa_mode(AntiAliasMode mode)
|
||||
{
|
||||
return mode == AntiAliasMode::FXAA_Low || mode == AntiAliasMode::FXAA_Medium || mode == AntiAliasMode::FXAA_High;
|
||||
}
|
||||
bool gr_is_smaa_mode(AntiAliasMode mode) {
|
||||
return mode == AntiAliasMode::SMAA_Low || mode == AntiAliasMode::SMAA_Medium || mode == AntiAliasMode::SMAA_High || mode == AntiAliasMode::SMAA_Ultra;
|
||||
}
|
||||
|
||||
bool Gr_post_processing_enabled = false;
|
||||
|
||||
static auto PostProcessOption =
|
||||
options::OptionBuilder<bool>("Graphis.PostProcessing", "Post processing",
|
||||
"Controls whether post processing is enabled in the engine")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(false)
|
||||
.bind_to_once(&Gr_post_processing_enabled)
|
||||
.importance(69)
|
||||
.finish();
|
||||
|
||||
bool Gr_enable_vsync = true;
|
||||
|
||||
static auto VSyncOption = options::OptionBuilder<bool>("Graphis.VSync", "Vertical Sync",
|
||||
"Controls how the engine does vertical synchronization")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_enable_vsync)
|
||||
.importance(70)
|
||||
.finish();
|
||||
|
||||
// Forward definitions
|
||||
static void uniform_buffer_managers_init();
|
||||
static void uniform_buffer_managers_deinit();
|
||||
@@ -953,69 +1195,77 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot continue without this, quit, but try to help the user out first
|
||||
ptr = os_config_read_string(NULL, NOX("VideocardFs2open"), NULL);
|
||||
if (Using_in_game_options) {
|
||||
auto res = ResolutionOption->getValue();
|
||||
width = res.width;
|
||||
height = res.height;
|
||||
} else {
|
||||
// We cannot continue without this, quit, but try to help the user out first
|
||||
ptr = os_config_read_string(nullptr, NOX("VideocardFs2open"), nullptr);
|
||||
|
||||
// if we don't have a config string then construct one, using OpenGL 1024x768 32-bit as the default
|
||||
if (ptr == NULL) {
|
||||
// If we don't have a display mode, use SDL to get default settings
|
||||
// We need to initialize SDL to do this
|
||||
// if we don't have a config string then construct one, using OpenGL 1024x768 32-bit as the default
|
||||
if (ptr == nullptr) {
|
||||
// If we don't have a display mode, use SDL to get default settings
|
||||
// We need to initialize SDL to do this
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0)
|
||||
{
|
||||
int display = static_cast<int>(os_config_read_uint("Video", "Display", 0));
|
||||
SDL_DisplayMode displayMode;
|
||||
if (SDL_GetDesktopDisplayMode(display, &displayMode) == 0)
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0)
|
||||
{
|
||||
width = displayMode.w;
|
||||
height = displayMode.h;
|
||||
int sdlBits = SDL_BITSPERPIXEL(displayMode.format);
|
||||
auto display = static_cast<int>(os_config_read_uint("Video", "Display", 0));
|
||||
SDL_DisplayMode displayMode;
|
||||
if (SDL_GetDesktopDisplayMode(display, &displayMode) == 0)
|
||||
{
|
||||
width = displayMode.w;
|
||||
height = displayMode.h;
|
||||
int sdlBits = SDL_BITSPERPIXEL(displayMode.format);
|
||||
|
||||
if (SDL_ISPIXELFORMAT_ALPHA(displayMode.format))
|
||||
{
|
||||
depth = sdlBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fix a few values
|
||||
if (sdlBits == 24)
|
||||
{
|
||||
depth = 32;
|
||||
}
|
||||
else if (sdlBits == 15)
|
||||
{
|
||||
depth = 16;
|
||||
}
|
||||
else
|
||||
if (SDL_ISPIXELFORMAT_ALPHA(displayMode.format))
|
||||
{
|
||||
depth = sdlBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fix a few values
|
||||
if (sdlBits == 24)
|
||||
{
|
||||
depth = 32;
|
||||
}
|
||||
else if (sdlBits == 15)
|
||||
{
|
||||
depth = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth = sdlBits;
|
||||
}
|
||||
}
|
||||
|
||||
SCP_string videomode;
|
||||
sprintf(videomode, "OGL -(%dx%d)x%d bit", width, height, depth);
|
||||
|
||||
os_config_write_string(nullptr, NOX("VideocardFs2open"), videomode.c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Assert(ptr != nullptr);
|
||||
|
||||
SCP_string videomode;
|
||||
sprintf(videomode, "OGL -(%dx%d)x%d bit", width, height, depth);
|
||||
|
||||
os_config_write_string(NULL, NOX("VideocardFs2open"), videomode.c_str());
|
||||
// NOTE: The "ptr+5" is to skip over the initial "????-" in the video string.
|
||||
// If the format of that string changes you'll have to change this too!!!
|
||||
if (sscanf(ptr + 5, "(%dx%d)x%d ", &width, &height, &depth) != 3) {
|
||||
Error(LOCATION, "Can't understand 'VideocardFs2open' config entry!");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Assert(ptr != NULL);
|
||||
|
||||
// NOTE: The "ptr+5" is to skip over the initial "????-" in the video string.
|
||||
// If the format of that string changes you'll have to change this too!!!
|
||||
if (sscanf(ptr + 5, "(%dx%d)x%d ", &width, &height, &depth) != 3) {
|
||||
Error(LOCATION, "Can't understand 'VideocardFs2open' config entry!");
|
||||
if (Cmdline_res != nullptr) {
|
||||
int tmp_width = 0;
|
||||
int tmp_height = 0;
|
||||
|
||||
if ( sscanf(Cmdline_res, "%dx%d", &tmp_width, &tmp_height) == 2 ) {
|
||||
width = tmp_width;
|
||||
height = tmp_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Cmdline_res != NULL) {
|
||||
int tmp_width = 0;
|
||||
int tmp_height = 0;
|
||||
|
||||
if ( sscanf(Cmdline_res, "%dx%d", &tmp_width, &tmp_height) == 2 ) {
|
||||
width = tmp_width;
|
||||
height = tmp_height;
|
||||
}
|
||||
Gr_enable_soft_particles = Cmdline_softparticles != 0;
|
||||
}
|
||||
if (Cmdline_center_res != NULL) {
|
||||
int tmp_center_width = 0;
|
||||
|
||||
+37
-4
@@ -12,15 +12,15 @@
|
||||
#ifndef _GRAPHICS_H
|
||||
#define _GRAPHICS_H
|
||||
|
||||
#include "graphics/grinternal.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/flagset.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/grinternal.h"
|
||||
#include "graphics/tmapper.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "io/cursor.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "osapi/osapi.h"
|
||||
|
||||
// Forward definition
|
||||
namespace graphics {
|
||||
@@ -40,6 +40,33 @@ extern int Gr_inited;
|
||||
extern int gr_zbuffering, gr_zbuffering_mode;
|
||||
extern int gr_global_zbuffering;
|
||||
|
||||
extern bool Gr_enable_soft_particles;
|
||||
|
||||
FLAG_LIST(FramebufferEffects){Thrusters = 0, Shockwaves, NUM_VALUES};
|
||||
extern flagset<FramebufferEffects> Gr_framebuffer_effects;
|
||||
|
||||
enum class AntiAliasMode {
|
||||
None,
|
||||
|
||||
FXAA_Low,
|
||||
FXAA_Medium,
|
||||
FXAA_High,
|
||||
|
||||
SMAA_Low,
|
||||
SMAA_Medium,
|
||||
SMAA_High,
|
||||
SMAA_Ultra,
|
||||
};
|
||||
extern AntiAliasMode Gr_aa_mode;
|
||||
extern AntiAliasMode Gr_aa_mode_last_frame;
|
||||
|
||||
bool gr_is_fxaa_mode(AntiAliasMode mode);
|
||||
bool gr_is_smaa_mode(AntiAliasMode mode);
|
||||
|
||||
extern bool Gr_post_processing_enabled;
|
||||
|
||||
extern bool Gr_enable_vsync;
|
||||
|
||||
class material;
|
||||
class model_material;
|
||||
class particle_material;
|
||||
@@ -164,6 +191,11 @@ enum shader_type {
|
||||
SDR_TYPE_DECAL,
|
||||
SDR_TYPE_SCENE_FOG,
|
||||
SDR_TYPE_ROCKET_UI,
|
||||
|
||||
SDR_TYPE_POST_PROCESS_SMAA_EDGE,
|
||||
SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT,
|
||||
SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING,
|
||||
|
||||
NUM_SHADER_TYPES
|
||||
};
|
||||
|
||||
@@ -294,6 +326,7 @@ typedef enum gr_capability {
|
||||
enum class gr_property {
|
||||
UNIFORM_BUFFER_OFFSET_ALIGNMENT,
|
||||
UNIFORM_BUFFER_MAX_SIZE,
|
||||
MAX_ANISOTROPY
|
||||
};
|
||||
|
||||
// stencil buffering stuff
|
||||
|
||||
+67
-69
@@ -667,7 +667,7 @@ float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float wid
|
||||
batch_item *item = NULL;
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -690,12 +690,12 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Cmdline_softparticles ) {
|
||||
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Gr_enable_soft_particles ) {
|
||||
// don't render this as a soft particle if we don't support soft particles
|
||||
tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
|
||||
}
|
||||
|
||||
if ( Cmdline_softparticles && !Cmdline_no_geo_sdr_effects && (tmap_flags & TMAP_FLAG_VERTEX_GEN) ) {
|
||||
if ( Gr_enable_soft_particles && !Cmdline_no_geo_sdr_effects && (tmap_flags & TMAP_FLAG_VERTEX_GEN) ) {
|
||||
geometry_batch_add_bitmap(texture, tmap_flags, pnt, orient, rad, alpha, depth);
|
||||
return 0;
|
||||
} else if ( tmap_flags & TMAP_FLAG_VERTEX_GEN ) {
|
||||
@@ -706,7 +706,7 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -735,7 +735,7 @@ int geometry_batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orie
|
||||
g_sdr_batch_item *item = NULL;
|
||||
SCP_map<int, g_sdr_batch_item>::iterator it = geometry_shader_map.find(texture);
|
||||
|
||||
if ( !geometry_shader_map.empty() && it != geometry_shader_map.end() ) {
|
||||
if (it != geometry_shader_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_shader_map[texture];
|
||||
@@ -759,7 +759,7 @@ int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float ang
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Cmdline_softparticles ) {
|
||||
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Gr_enable_soft_particles ) {
|
||||
// don't render this as a soft particle if we don't support soft particles
|
||||
tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
|
||||
}
|
||||
@@ -768,7 +768,7 @@ int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float ang
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -798,7 +798,7 @@ int batch_add_tri(int texture, int tmap_flags, vertex *verts, float alpha)
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -828,7 +828,7 @@ int batch_add_quad(int texture, int tmap_flags, vertex *verts, float alpha)
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -908,7 +908,7 @@ int batch_add_polygon(int texture, int tmap_flags, vec3d *pos, matrix *orient, f
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -938,7 +938,7 @@ int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
if (it != geometry_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
@@ -959,102 +959,102 @@ int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float
|
||||
|
||||
void batch_render_lasers(int buffer_handle)
|
||||
{
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (auto &bi : geometry_map) {
|
||||
|
||||
if ( !bi->second.laser )
|
||||
if ( !bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
|
||||
if ( buffer_handle >= 0 ) {
|
||||
bi->second.batch.render_buffer(buffer_handle, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
|
||||
bi.second.batch.render_buffer(buffer_handle, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
|
||||
} else {
|
||||
bi->second.batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
|
||||
bi.second.batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_lasers(effect_vertex* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (auto &bi : geometry_map) {
|
||||
|
||||
if ( !bi->second.laser )
|
||||
if ( !bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
bi.second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
void batch_render_geometry_map_bitmaps(int buffer_handle)
|
||||
{
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (auto &bi : geometry_map) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi.second.alpha);
|
||||
if ( buffer_handle >= 0 ) {
|
||||
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
|
||||
bi.second.batch.render_buffer(buffer_handle, bi.second.tmap_flags);
|
||||
} else {
|
||||
bi->second.batch.render( bi->second.tmap_flags);
|
||||
bi.second.batch.render( bi.second.tmap_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void batch_render_geometry_shader_map_bitmaps(int buffer_handle)
|
||||
{
|
||||
for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
|
||||
for (auto &bi : geometry_shader_map) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
|
||||
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi.second.alpha);
|
||||
bi.second.batch.render_buffer(buffer_handle, bi.second.tmap_flags);
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_geometry_map_bitmaps(effect_vertex* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (auto &bi : geometry_map) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
bi.second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_geometry_shader_map_bitmaps(particle_pnt* buffer, size_t *n_verts)
|
||||
{
|
||||
for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
|
||||
for (auto &bi : geometry_shader_map) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
bi.second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1145,7 +1145,7 @@ int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, floa
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
|
||||
|
||||
if ( !distortion_map.empty() && it != distortion_map.end() ) {
|
||||
if (it != distortion_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &distortion_map[texture];
|
||||
@@ -1175,7 +1175,7 @@ int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, f
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
|
||||
|
||||
if ( !distortion_map.empty() && it != distortion_map.end() ) {
|
||||
if (it != distortion_map.end()) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &distortion_map[texture];
|
||||
@@ -1196,54 +1196,53 @@ int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, f
|
||||
|
||||
void batch_render_distortion_map_bitmaps(int buffer_handle)
|
||||
{
|
||||
for (SCP_map<int,batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
for (auto &bi : distortion_map) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi.second.alpha);
|
||||
|
||||
if ( buffer_handle >= 0 ) {
|
||||
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
|
||||
bi.second.batch.render_buffer(buffer_handle, bi.second.tmap_flags);
|
||||
} else {
|
||||
bi->second.batch.render( bi->second.tmap_flags);
|
||||
bi.second.batch.render( bi.second.tmap_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_distortion_map_bitmaps(effect_vertex* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_map<int, batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
for (auto &bi : distortion_map) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
if ( !bi.second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi.second.texture >= 0 );
|
||||
bi.second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
int batch_get_size()
|
||||
{
|
||||
int n_to_render = 0;
|
||||
SCP_map<int, batch_item>::iterator bi;
|
||||
|
||||
for (bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
n_to_render += bi->second.batch.need_to_render();
|
||||
for (auto &bi : geometry_map) {
|
||||
n_to_render += bi.second.batch.need_to_render();
|
||||
}
|
||||
|
||||
for (bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
if ( bi->second.laser )
|
||||
for (auto &bi : distortion_map) {
|
||||
if ( bi.second.laser )
|
||||
continue;
|
||||
|
||||
n_to_render += bi->second.batch.need_to_render();
|
||||
n_to_render += bi.second.batch.need_to_render();
|
||||
}
|
||||
|
||||
return n_to_render * 3;
|
||||
@@ -1252,10 +1251,9 @@ int batch_get_size()
|
||||
size_t geometry_batch_get_size()
|
||||
{
|
||||
size_t n_to_render = 0;
|
||||
SCP_map<int, g_sdr_batch_item>::iterator bi;
|
||||
|
||||
for (bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
|
||||
n_to_render += bi->second.batch.need_to_render();
|
||||
for (auto &bi : geometry_shader_map) {
|
||||
n_to_render += bi.second.batch.need_to_render();
|
||||
}
|
||||
|
||||
return n_to_render;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com)
|
||||
* Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com)
|
||||
* Copyright (C) 2013 Belen Masia (bmasia@unizar.es)
|
||||
* Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com)
|
||||
* Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to
|
||||
* do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software. As clarification, there
|
||||
* is no requirement that the copyright notice and permission be included in
|
||||
* binary distributions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SEARCHTEX_H
|
||||
#define SEARCHTEX_H
|
||||
|
||||
#define SEARCHTEX_WIDTH 64
|
||||
#define SEARCHTEX_HEIGHT 16
|
||||
#define SEARCHTEX_PITCH SEARCHTEX_WIDTH
|
||||
#define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* Stored in R8 format. Load it in the following format:
|
||||
* - DX9: D3DFMT_L8
|
||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||
*/
|
||||
static const unsigned char searchTexBytes[] = {
|
||||
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
|
||||
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
|
||||
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,16 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "gropengl.h"
|
||||
#include "gropenglbmpman.h"
|
||||
#include "gropengldeferred.h"
|
||||
#include "gropengldraw.h"
|
||||
#include "gropenglpostprocessing.h"
|
||||
#include "gropenglquery.h"
|
||||
#include "gropenglshader.h"
|
||||
#include "gropenglstate.h"
|
||||
#include "gropenglsync.h"
|
||||
#include "gropengltexture.h"
|
||||
#include "gropengltnl.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
@@ -10,32 +18,22 @@
|
||||
#include "debugconsole/console.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "graphics/line.h"
|
||||
#include "graphics/matrix.h"
|
||||
#include "graphics/paths/PathRenderer.h"
|
||||
#include "gropengl.h"
|
||||
#include "gropenglbmpman.h"
|
||||
#include "gropengldraw.h"
|
||||
#include "gropenglpostprocessing.h"
|
||||
#include "gropenglquery.h"
|
||||
#include "gropenglsync.h"
|
||||
#include "gropenglshader.h"
|
||||
#include "gropenglstate.h"
|
||||
#include "gropengltexture.h"
|
||||
#include "gropengltnl.h"
|
||||
#include "gropengldeferred.h"
|
||||
#include "graphics/line.h"
|
||||
#include "io/mouse.h"
|
||||
#include "io/timer.h"
|
||||
#include "libs/renderdoc/renderdoc.h"
|
||||
#include "math/floating.h"
|
||||
#include "model/model.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "libs/renderdoc/renderdoc.h"
|
||||
#include "options/Option.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "osapi/osregistry.h"
|
||||
#include "render/3d.h"
|
||||
#include "popup/popup.h"
|
||||
#include "tracing/tracing.h"
|
||||
#include "pngutils/pngutils.h"
|
||||
#include "popup/popup.h"
|
||||
#include "render/3d.h"
|
||||
#include "tracing/tracing.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
@@ -99,6 +97,33 @@ static std::unique_ptr<os::OpenGLContext> GL_context = nullptr;
|
||||
static std::unique_ptr<os::GraphicsOperations> graphic_operations = nullptr;
|
||||
static os::Viewport* current_viewport = nullptr;
|
||||
|
||||
static bool mode_change_func(os::ViewportState state, bool initial)
|
||||
{
|
||||
if (initial) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto window = os::getMainViewport();
|
||||
if (window == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window->setState(state);
|
||||
|
||||
return true;
|
||||
}
|
||||
static auto WindowModeOption = options::OptionBuilder<os::ViewportState>("Graphics.WindowMode", "Window Mode",
|
||||
"Controls how the game window is created.")
|
||||
.category("Graphics")
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.values({{os::ViewportState::Fullscreen, "Fullscreen"},
|
||||
{os::ViewportState::Borderless, "Borderless"},
|
||||
{os::ViewportState::Windowed, "Windowed"}})
|
||||
.importance(98)
|
||||
.default_val(os::ViewportState::Fullscreen)
|
||||
.change_listener(mode_change_func)
|
||||
.finish();
|
||||
|
||||
void opengl_go_fullscreen()
|
||||
{
|
||||
if (Cmdline_fullscreen_window || Cmdline_window || GL_fullscreen || Fred_running)
|
||||
@@ -854,16 +879,16 @@ int opengl_check_for_errors(const char *err_at)
|
||||
return num_errors;
|
||||
}
|
||||
|
||||
void opengl_set_vsync(int status)
|
||||
void opengl_set_vsync(bool enable)
|
||||
{
|
||||
if ( (status < 0) || (status > 1) ) {
|
||||
Int3();
|
||||
return;
|
||||
if (enable) {
|
||||
// Try to use adaptive vsync when supported
|
||||
if (!GL_context->setSwapInterval(-1)) {
|
||||
GL_context->setSwapInterval(1);
|
||||
}
|
||||
} else {
|
||||
GL_context->setSwapInterval(0);
|
||||
}
|
||||
|
||||
GL_context->setSwapInterval(status);
|
||||
|
||||
GL_CHECK_FOR_ERRORS("end of set_vsync()");
|
||||
}
|
||||
|
||||
std::unique_ptr<os::Viewport> gr_opengl_create_viewport(const os::ViewPortProperties& props) {
|
||||
@@ -1021,10 +1046,24 @@ int opengl_init_display_device()
|
||||
attrs.title = Window_title;
|
||||
}
|
||||
|
||||
if (!Cmdline_window && ! Cmdline_fullscreen_window) {
|
||||
attrs.flags.set(os::ViewPortFlags::Fullscreen);
|
||||
} else if (Cmdline_fullscreen_window) {
|
||||
attrs.flags.set(os::ViewPortFlags::Borderless);
|
||||
if (Using_in_game_options) {
|
||||
switch (WindowModeOption->getValue()) {
|
||||
case os::ViewportState::Windowed:
|
||||
// That's the default
|
||||
break;
|
||||
case os::ViewportState::Borderless:
|
||||
attrs.flags.set(os::ViewPortFlags::Borderless);
|
||||
break;
|
||||
case os::ViewportState::Fullscreen:
|
||||
attrs.flags.set(os::ViewPortFlags::Fullscreen);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!Cmdline_window && !Cmdline_fullscreen_window) {
|
||||
attrs.flags.set(os::ViewPortFlags::Fullscreen);
|
||||
} else if (Cmdline_fullscreen_window) {
|
||||
attrs.flags.set(os::ViewPortFlags::Borderless);
|
||||
}
|
||||
}
|
||||
|
||||
auto viewport = gr_opengl_create_viewport(attrs);
|
||||
@@ -1497,7 +1536,7 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
|
||||
opengl_post_process_init();
|
||||
|
||||
// must be called after extensions are setup
|
||||
opengl_set_vsync( !Cmdline_no_vsync );
|
||||
opengl_set_vsync(Gr_enable_vsync);
|
||||
|
||||
gr_reset_matrices();
|
||||
gr_setup_viewport();
|
||||
@@ -1541,7 +1580,7 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
|
||||
|
||||
mprintf(( " Can use compressed textures: %s\n", Use_compressed_textures ? NOX("YES") : NOX("NO") ));
|
||||
mprintf(( " Texture compression available: %s\n", Texture_compression_available ? NOX("YES") : NOX("NO") ));
|
||||
mprintf(( " Post-processing enabled: %s\n", (Cmdline_postprocess) ? "YES" : "NO"));
|
||||
mprintf(( " Post-processing enabled: %s\n", (Gr_post_processing_enabled) ? "YES" : "NO"));
|
||||
mprintf(( " Using %s texture filter.\n", (GL_mipmap_filter) ? NOX("trilinear") : NOX("bilinear") ));
|
||||
|
||||
mprintf(( " OpenGL Shader Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION) ));
|
||||
@@ -1572,9 +1611,9 @@ bool gr_opengl_is_capable(gr_capability capability)
|
||||
return Cmdline_height ? true : false;
|
||||
case CAPABILITY_SOFT_PARTICLES:
|
||||
case CAPABILITY_DISTORTION:
|
||||
return Cmdline_softparticles && !Cmdline_no_fbo;
|
||||
return Gr_enable_soft_particles && !Cmdline_no_fbo;
|
||||
case CAPABILITY_POST_PROCESSING:
|
||||
return Cmdline_postprocess && !Cmdline_no_fbo;
|
||||
return Gr_post_processing_enabled && !Cmdline_no_fbo;
|
||||
case CAPABILITY_DEFERRED_LIGHTING:
|
||||
return !Cmdline_no_fbo && !Cmdline_no_deferred_lighting;
|
||||
case CAPABILITY_SHADOWS:
|
||||
@@ -1592,16 +1631,20 @@ bool gr_opengl_is_capable(gr_capability capability)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gr_opengl_get_property(gr_property prop, void* dest) {
|
||||
switch(prop) {
|
||||
case gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
|
||||
*((int*)dest) = GL_state.Constants.GetUniformBufferOffsetAlignment();
|
||||
return true;
|
||||
case gr_property::UNIFORM_BUFFER_MAX_SIZE:
|
||||
*((int*)dest) = GL_state.Constants.GetMaxUniformBlockSize();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
bool gr_opengl_get_property(gr_property prop, void* dest)
|
||||
{
|
||||
switch (prop) {
|
||||
case gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
|
||||
*((int*)dest) = GL_state.Constants.GetUniformBufferOffsetAlignment();
|
||||
return true;
|
||||
case gr_property::UNIFORM_BUFFER_MAX_SIZE:
|
||||
*((int*)dest) = GL_state.Constants.GetMaxUniformBlockSize();
|
||||
return true;
|
||||
case gr_property::MAX_ANISOTROPY:
|
||||
*((float*)dest) = GL_state.Constants.GetMaxAnisotropy();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1679,7 +1722,8 @@ DCF(ogl_anisotropy, "toggles anisotropic filtering")
|
||||
|
||||
if (dc_optional_string_either("help", "--help")) {
|
||||
dc_printf("Sets OpenGL anisotropic filtering level.\n");
|
||||
dc_printf("GL_anisotropy [int] Valid values are 0 to %i. 0 turns off anisotropic filtering.\n", (int)opengl_get_max_anisotropy());
|
||||
dc_printf("GL_anisotropy [int] Valid values are 0 to %i. 0 turns off anisotropic filtering.\n",
|
||||
(int)GL_state.Constants.GetMaxAnisotropy());
|
||||
process = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,6 @@
|
||||
|
||||
|
||||
|
||||
static inline int is_power_of_two(int w, int h)
|
||||
{
|
||||
// NOTE: OpenGL texture code has a min tex size of 16 (currently), so we need to be at least
|
||||
// the min size here to qualify as power-of-2 and not get resized later on
|
||||
return ( ((w >= GL_min_texture_width) && !(w & (w-1))) && ((h >= GL_min_texture_height) && !(h & (h-1))) );
|
||||
}
|
||||
|
||||
int get_num_mipmap_levels(int w, int h)
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ void opengl_clear_deferred_buffers()
|
||||
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_CLEAR, 0) );
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
opengl_shader_set_current();
|
||||
|
||||
@@ -115,7 +115,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_normal_texture);
|
||||
GL_state.Texture.Enable(2, GL_TEXTURE_2D, Scene_position_texture);
|
||||
GL_state.Texture.Enable(3, GL_TEXTURE_2D, Scene_specular_texture);
|
||||
if (Cmdline_shadow_quality) {
|
||||
if (Shadow_quality != ShadowQuality::Disabled) {
|
||||
GL_state.Texture.Enable(4, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
GR_DEBUG_SCOPE("Build buffer data");
|
||||
|
||||
auto header = uniformAligner.getHeader<deferred_global_data>();
|
||||
if (Cmdline_shadow_quality) {
|
||||
if (Shadow_quality != ShadowQuality::Disabled) {
|
||||
// Avoid this overhead when we are not going to use these values
|
||||
header->shadow_mv_matrix = Shadow_view_matrix;
|
||||
for (size_t i = 0; i < MAX_SHADOW_CASCADES; ++i) {
|
||||
@@ -173,7 +173,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
|
||||
switch (l.type) {
|
||||
case Light_Type::Directional:
|
||||
if (Cmdline_shadow_quality) {
|
||||
if (Shadow_quality != ShadowQuality::Disabled) {
|
||||
light_data->enable_shadows = first_directional ? 1 : 0;
|
||||
}
|
||||
vec4 light_dir;
|
||||
@@ -263,7 +263,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
uniformAligner.getOffset(element_index),
|
||||
sizeof(graphics::deferred_light_data),
|
||||
buffer->bufferHandle());
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
++element_index;
|
||||
break;
|
||||
case Light_Type::Cone:
|
||||
@@ -335,7 +335,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
Current_shader->program->Uniforms.setUniformf("zNear", Min_draw_distance);
|
||||
Current_shader->program->Uniforms.setUniformf("zFar", Max_draw_distance);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
} else {
|
||||
// Transfer the resolved lighting back to the color texture
|
||||
// TODO: Maybe this could be improved so that it doesn't require the copy back operation?
|
||||
|
||||
@@ -88,9 +88,9 @@ void opengl_setup_scene_textures()
|
||||
Scene_texture_initialized = 0;
|
||||
|
||||
if ( Cmdline_no_fbo ) {
|
||||
Cmdline_postprocess = 0;
|
||||
Cmdline_softparticles = 0;
|
||||
Cmdline_fb_explosions = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
Gr_enable_soft_particles = false;
|
||||
Gr_framebuffer_effects = {};
|
||||
|
||||
Scene_ldr_texture = 0;
|
||||
Scene_color_texture = 0;
|
||||
@@ -338,13 +338,13 @@ void opengl_setup_scene_textures()
|
||||
//glDeleteTextures(1, &Scene_fxaa_output_texture);
|
||||
//Scene_fxaa_output_texture = 0;
|
||||
|
||||
Cmdline_postprocess = 0;
|
||||
Cmdline_softparticles = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
Gr_enable_soft_particles = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//Setup thruster distortion framebuffer
|
||||
if (Cmdline_fb_thrusters || Cmdline_fb_explosions)
|
||||
if (Gr_framebuffer_effects.any_set())
|
||||
{
|
||||
glGenFramebuffers(1, &Distortion_framebuffer);
|
||||
GL_state.BindFrameBuffer(Distortion_framebuffer);
|
||||
@@ -392,8 +392,8 @@ void opengl_setup_scene_textures()
|
||||
Scene_color_texture = 0;
|
||||
Scene_depth_texture = 0;
|
||||
|
||||
Cmdline_postprocess = 0;
|
||||
Cmdline_softparticles = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
Gr_enable_soft_particles = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ void gr_opengl_scene_texture_begin()
|
||||
|
||||
Scene_framebuffer_in_frame = true;
|
||||
|
||||
if ( Cmdline_postprocess && !PostProcessing_override ) {
|
||||
if ( Gr_post_processing_enabled && !PostProcessing_override ) {
|
||||
High_dynamic_range = true;
|
||||
}
|
||||
}
|
||||
@@ -533,8 +533,8 @@ void gr_opengl_scene_texture_end()
|
||||
time_buffer = 0.0f;
|
||||
}
|
||||
|
||||
if ( Cmdline_postprocess && !PostProcessing_override ) {
|
||||
gr_post_process_end();
|
||||
if ( Gr_post_processing_enabled && !PostProcessing_override ) {
|
||||
gr_opengl_post_process_end();
|
||||
} else {
|
||||
GR_DEBUG_SCOPE("Draw scene texture");
|
||||
TRACE_SCOPE(tracing::DrawSceneTexture);
|
||||
@@ -551,7 +551,7 @@ void gr_opengl_scene_texture_end()
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
opengl_shader_set_passthrough(true);
|
||||
opengl_shader_set_passthrough(true, High_dynamic_range);
|
||||
|
||||
GL_state.Array.BindArrayBuffer(0);
|
||||
|
||||
@@ -650,7 +650,7 @@ void gr_opengl_update_distortion()
|
||||
GLboolean blend = GL_state.Blend(GL_FALSE);
|
||||
GLboolean cull = GL_state.CullFace(GL_FALSE);
|
||||
|
||||
opengl_shader_set_passthrough(true);
|
||||
opengl_shader_set_passthrough(true, High_dynamic_range);
|
||||
|
||||
GL_state.PushFramebufferState();
|
||||
GL_state.BindFrameBuffer(Distortion_framebuffer);
|
||||
@@ -695,7 +695,7 @@ void gr_opengl_update_distortion()
|
||||
|
||||
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, vertices, sizeof(vertex) * 4);
|
||||
|
||||
opengl_shader_set_passthrough(false);
|
||||
opengl_shader_set_passthrough(false, High_dynamic_range);
|
||||
|
||||
vertex distortion_verts[33];
|
||||
|
||||
@@ -864,7 +864,25 @@ void opengl_draw_textured_quad(GLfloat x1,
|
||||
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
|
||||
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
|
||||
|
||||
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(GLfloat) * 4 * 4);
|
||||
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(glVertices));
|
||||
}
|
||||
|
||||
void opengl_draw_full_screen_textured(GLfloat u1, GLfloat v1, GLfloat u2, GLfloat v2)
|
||||
{
|
||||
GR_DEBUG_SCOPE("Draw full screen triangle");
|
||||
|
||||
GLfloat glVertices[3][4] = {
|
||||
{-1.f, -1.f, u1, v1},
|
||||
{3.f, -1.f, u2 * 2.f, v1},
|
||||
{-1.f, 3.f, u1, v2 * 2.f},
|
||||
};
|
||||
|
||||
vertex_layout vert_def;
|
||||
|
||||
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
|
||||
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
|
||||
|
||||
opengl_render_primitives_immediate(PRIM_TYPE_TRIS, &vert_def, 3, glVertices, sizeof(glVertices));
|
||||
}
|
||||
|
||||
void gr_opengl_render_decals(decal_material* material_info,
|
||||
|
||||
@@ -64,6 +64,20 @@ void gr_opengl_render_rocket_primitives(interface_material* material_info, primi
|
||||
void opengl_draw_textured_quad(GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
|
||||
GLfloat x2, GLfloat y2, GLfloat u2, GLfloat v2 );
|
||||
|
||||
/**
|
||||
* @brief Draw "something" so that the entire screen is covered and the corners use the UV values that are provided.
|
||||
*
|
||||
* @details This actually draws a a single oversized triangle that covers the screen in such a way so that the provided
|
||||
* UV values are generated by the GPU in the corners of the screen. This is better than drawing two triangles since then
|
||||
* the diagonal would be shaded differently for the two triangles causing visual differences.
|
||||
*
|
||||
* @param u1 The U value of the lower left corner.
|
||||
* @param v1 The V value of the lower left corner.
|
||||
* @param u2 The U value of the upper right corner.
|
||||
* @param v2 The V value of the upper right corner.
|
||||
*/
|
||||
void opengl_draw_full_screen_textured(GLfloat u1, GLfloat v1, GLfloat u2, GLfloat v2);
|
||||
|
||||
inline GLenum opengl_primitive_type(primitive_type prim_type);
|
||||
|
||||
void gr_opengl_start_decal_pass();
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "gropenglpostprocessing.h"
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
#include "SmaaAreaTex.h"
|
||||
#include "SmaaSearchTex.h"
|
||||
#include "freespace.h"
|
||||
#include "def_files/def_files.h"
|
||||
#include "gropengl.h"
|
||||
#include "gropengldraw.h"
|
||||
#include "gropenglpostprocessing.h"
|
||||
#include "gropenglshader.h"
|
||||
#include "gropenglstate.h"
|
||||
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "def_files/def_files.h"
|
||||
#include "io/timer.h"
|
||||
#include "lighting/lighting.h"
|
||||
#include "mod_table/mod_table.h"
|
||||
@@ -14,17 +19,13 @@
|
||||
#include "parse/parselo.h"
|
||||
#include "ship/ship.h"
|
||||
#include "tracing/tracing.h"
|
||||
#include "ShaderProgram.h"
|
||||
|
||||
|
||||
extern bool PostProcessing_override;
|
||||
extern int opengl_check_framebuffer();
|
||||
|
||||
//Needed to track where the FXAA shaders are
|
||||
size_t fxaa_shader_id;
|
||||
//In case we don't find the shaders at all, this override is needed
|
||||
bool fxaa_unavailable = false;
|
||||
int Fxaa_preset_last_frame;
|
||||
bool zbuffer_saved = false;
|
||||
|
||||
// lightshaft parameters
|
||||
@@ -77,6 +78,18 @@ static GLuint Post_framebuffer_id[2] = { 0 };
|
||||
static int Post_texture_width = 0;
|
||||
static int Post_texture_height = 0;
|
||||
|
||||
static GLuint Smaa_edge_detection_fb = 0;
|
||||
static GLuint Smaa_edges_tex = 0;
|
||||
|
||||
static GLuint Smaa_blending_weight_fb = 0;
|
||||
static GLuint Smaa_blend_tex = 0;
|
||||
|
||||
static GLuint Smaa_neighborhood_blending_fb = 0;
|
||||
static GLuint Smaa_output_tex = 0;
|
||||
|
||||
static GLuint Smaa_search_tex = 0;
|
||||
static GLuint Smaa_area_tex = 0;
|
||||
|
||||
void opengl_post_pass_tonemap()
|
||||
{
|
||||
GR_DEBUG_SCOPE("Tonemapping");
|
||||
@@ -91,7 +104,7 @@ void opengl_post_pass_tonemap()
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
}
|
||||
|
||||
void opengl_post_pass_bloom()
|
||||
@@ -126,7 +139,7 @@ void opengl_post_pass_bloom()
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
// ------ end bright pass ------
|
||||
|
||||
@@ -166,7 +179,7 @@ void opengl_post_pass_bloom()
|
||||
|
||||
glViewport(0, 0, bloom_width, bloom_height);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +203,7 @@ void opengl_post_pass_bloom()
|
||||
|
||||
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
}
|
||||
@@ -227,8 +240,11 @@ void gr_opengl_post_process_begin()
|
||||
}
|
||||
|
||||
void recompile_fxaa_shader() {
|
||||
if (!gr_is_fxaa_mode(Gr_aa_mode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mprintf(("Recompiling FXAA shader with preset %d\n", Cmdline_fxaa_preset));
|
||||
mprintf(("Recompiling FXAA shader...\n"));
|
||||
|
||||
// start recompile by grabbing deleting the current shader we have, assuming it's already created
|
||||
opengl_delete_shader( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
|
||||
@@ -236,7 +252,7 @@ void recompile_fxaa_shader() {
|
||||
// then recreate it again. shader loading code will be updated with the new FXAA presets
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
|
||||
|
||||
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
|
||||
Gr_aa_mode_last_frame = Gr_aa_mode;
|
||||
}
|
||||
|
||||
void opengl_post_pass_fxaa() {
|
||||
@@ -244,7 +260,7 @@ void opengl_post_pass_fxaa() {
|
||||
TRACE_SCOPE(tracing::FXAA);
|
||||
|
||||
//If the preset changed, recompile the shader
|
||||
if (Fxaa_preset_last_frame != Cmdline_fxaa_preset) {
|
||||
if (Gr_aa_mode_last_frame != Gr_aa_mode) {
|
||||
recompile_fxaa_shader();
|
||||
}
|
||||
|
||||
@@ -262,7 +278,7 @@ void opengl_post_pass_fxaa() {
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
|
||||
// set and configure post shader ..
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
|
||||
@@ -276,11 +292,124 @@ void opengl_post_pass_fxaa() {
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_luminance_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
|
||||
opengl_shader_set_current();
|
||||
}
|
||||
|
||||
static void smaa_detect_edges()
|
||||
{
|
||||
GR_DEBUG_SCOPE("SMAA Detect Edges");
|
||||
TRACE_SCOPE(tracing::SMAAEdgeDetection);
|
||||
|
||||
GL_state.BindFrameBuffer(Smaa_edge_detection_fb);
|
||||
|
||||
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
glClearBufferfv(GL_COLOR, 0, clearValues);
|
||||
|
||||
// Do the edge detection step
|
||||
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0));
|
||||
|
||||
// basic/default uniforms
|
||||
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
|
||||
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
|
||||
i2fl(Post_texture_height));
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
|
||||
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
}
|
||||
|
||||
static void smaa_calculate_blending_weights()
|
||||
{
|
||||
GR_DEBUG_SCOPE("SMAA Blending Weights calculation");
|
||||
TRACE_SCOPE(tracing::SMAACalculateBlendingWeights);
|
||||
|
||||
GL_state.BindFrameBuffer(Smaa_blending_weight_fb);
|
||||
|
||||
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
glClearBufferfv(GL_COLOR, 0, clearValues);
|
||||
|
||||
// Do the edge detection step
|
||||
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0));
|
||||
|
||||
// basic/default uniforms
|
||||
Current_shader->program->Uniforms.setUniformi("edgesTex", 0);
|
||||
Current_shader->program->Uniforms.setUniformi("areaTex", 1);
|
||||
Current_shader->program->Uniforms.setUniformi("searchTex", 2);
|
||||
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
|
||||
i2fl(Post_texture_height));
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_edges_tex);
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_area_tex);
|
||||
GL_state.Texture.Enable(2, GL_TEXTURE_2D, Smaa_search_tex);
|
||||
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
}
|
||||
|
||||
static void smaa_neighborhood_blending()
|
||||
{
|
||||
GR_DEBUG_SCOPE("SMAA Neighborhood Blending");
|
||||
TRACE_SCOPE(tracing::SMAANeighborhoodBlending);
|
||||
|
||||
GL_state.BindFrameBuffer(Smaa_neighborhood_blending_fb);
|
||||
|
||||
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
glClearBufferfv(GL_COLOR, 0, clearValues);
|
||||
|
||||
// Do the edge detection step
|
||||
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0));
|
||||
|
||||
// basic/default uniforms
|
||||
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
|
||||
Current_shader->program->Uniforms.setUniformi("blendTex", 1);
|
||||
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
|
||||
i2fl(Post_texture_height));
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_blend_tex);
|
||||
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
}
|
||||
|
||||
void smaa_resolve()
|
||||
{
|
||||
GR_DEBUG_SCOPE("SMAA Resolve");
|
||||
TRACE_SCOPE(tracing::SMAAResolve);
|
||||
|
||||
opengl_shader_set_passthrough(true, false);
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_output_tex);
|
||||
|
||||
// Copy SMAA output back to the original framebuffer
|
||||
if (GL_rendering_to_texture) {
|
||||
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, 0.0f, (float)gr_screen.max_w, (float)gr_screen.max_h,
|
||||
Scene_texture_u_scale, Scene_texture_v_scale);
|
||||
} else {
|
||||
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, Scene_texture_v_scale, (float)gr_screen.max_w,
|
||||
(float)gr_screen.max_h, Scene_texture_u_scale, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_post_pass_smaa()
|
||||
{
|
||||
GR_DEBUG_SCOPE("SMAA");
|
||||
TRACE_SCOPE(tracing::SMAA);
|
||||
|
||||
GL_state.PushFramebufferState();
|
||||
|
||||
GL_state.ColorMask(true, true, true, true);
|
||||
|
||||
smaa_detect_edges();
|
||||
|
||||
smaa_calculate_blending_weights();
|
||||
|
||||
smaa_neighborhood_blending();
|
||||
|
||||
GL_state.PopFramebufferState();
|
||||
|
||||
smaa_resolve();
|
||||
}
|
||||
|
||||
extern GLuint Shadow_map_depth_texture;
|
||||
extern GLuint Scene_depth_texture;
|
||||
extern GLuint Cockpit_depth_texture;
|
||||
@@ -331,7 +460,7 @@ void opengl_post_lightshafts()
|
||||
GL_state.Blend(GL_TRUE);
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
|
||||
GL_state.Blend(GL_FALSE);
|
||||
break;
|
||||
@@ -361,10 +490,14 @@ void gr_opengl_post_process_end()
|
||||
// do tone mapping
|
||||
opengl_post_pass_tonemap();
|
||||
|
||||
// Do FXAA
|
||||
if (Cmdline_fxaa && !fxaa_unavailable && !GL_rendering_to_texture) {
|
||||
opengl_post_pass_fxaa();
|
||||
}
|
||||
// Do Post processing AA
|
||||
if (!GL_rendering_to_texture) {
|
||||
if (gr_is_smaa_mode(Gr_aa_mode)) {
|
||||
opengl_post_pass_smaa();
|
||||
} else if (gr_is_fxaa_mode(Gr_aa_mode) && !fxaa_unavailable) {
|
||||
opengl_post_pass_fxaa();
|
||||
}
|
||||
}
|
||||
|
||||
// render lightshafts
|
||||
opengl_post_lightshafts();
|
||||
@@ -421,7 +554,7 @@ void gr_opengl_post_process_end()
|
||||
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
|
||||
//Shadow Map debug window
|
||||
//#define SHADOW_DEBUG
|
||||
@@ -704,9 +837,58 @@ static bool opengl_post_init_table()
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_post_shader_header(SCP_stringstream &sflags, shader_type shader_t, int flags)
|
||||
static void set_fxaa_defines(SCP_stringstream& sflags)
|
||||
{
|
||||
if ( shader_t == SDR_TYPE_POST_PROCESS_MAIN ) {
|
||||
// Since we require OpenGL 3.2 we always have support for GLSL 130
|
||||
sflags << "#define FXAA_GLSL_120 0\n";
|
||||
sflags << "#define FXAA_GLSL_130 1\n";
|
||||
|
||||
if (GLSL_version >= 400) {
|
||||
// The gather function became part of the standard with GLSL 4.00
|
||||
sflags << "#define FXAA_GATHER4_ALPHA 1\n";
|
||||
}
|
||||
|
||||
switch (Gr_aa_mode) {
|
||||
case AntiAliasMode::None:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 10\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case AntiAliasMode::FXAA_Low:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 12\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/8.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/16.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case AntiAliasMode::FXAA_Medium:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 26\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/12.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/24.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case AntiAliasMode::FXAA_High:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 39\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/15.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("Unhandled FXAA mode!");
|
||||
}
|
||||
}
|
||||
void set_smaa_defines(SCP_stringstream& sflags)
|
||||
{
|
||||
// Define what GLSL version we use
|
||||
if (GLSL_version >= 400) {
|
||||
sflags << "#define SMAA_GLSL_4\n";
|
||||
} else {
|
||||
sflags << "#define SMAA_GLSL_3\n";
|
||||
}
|
||||
}
|
||||
void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, int flags)
|
||||
{
|
||||
if (shader_t == SDR_TYPE_POST_PROCESS_MAIN) {
|
||||
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
|
||||
if (flags & (1 << idx)) {
|
||||
sflags << "#define ";
|
||||
@@ -714,83 +896,15 @@ void opengl_post_shader_header(SCP_stringstream &sflags, shader_type shader_t, i
|
||||
sflags << "\n";
|
||||
}
|
||||
}
|
||||
} else if ( shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ) {
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS) {
|
||||
char temp[64];
|
||||
sprintf(temp, "#define SAMPLE_NUM %d\n", ls_samplenum);
|
||||
sflags << temp;
|
||||
} else if ( shader_t == SDR_TYPE_POST_PROCESS_FXAA ) {
|
||||
// Since we require OpenGL 3.2 we always have support for GLSL 130
|
||||
sflags << "#define FXAA_GLSL_120 0\n";
|
||||
sflags << "#define FXAA_GLSL_130 1\n";
|
||||
|
||||
if (GLSL_version >= 400) {
|
||||
// The gather function became part of the standard with GLSL 4.00
|
||||
sflags << "#define FXAA_GATHER4_ALPHA 1\n";
|
||||
}
|
||||
|
||||
switch (Cmdline_fxaa_preset) {
|
||||
case 0:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 10\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 1:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 11\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/7.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/14.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 2:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 12\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/8.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/16.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 3:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 13\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/9.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/18.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 4:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 14\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/10.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/20.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 5:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 25\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/11.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/22.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 6:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 26\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/12.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/24.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 7:
|
||||
sflags << "#define FXAA_PC 1\n";
|
||||
sflags << "#define FXAA_QUALITY_PRESET 27\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/13.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/26.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 8:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 28\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/14.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/28.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
case 9:
|
||||
sflags << "#define FXAA_QUALITY_PRESET 39\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/15.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
|
||||
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
}
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_FXAA) {
|
||||
set_fxaa_defines(sflags);
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_SMAA_EDGE || shader_t == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
|
||||
shader_t == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
|
||||
set_smaa_defines(sflags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -819,11 +933,17 @@ bool opengl_post_init_shaders()
|
||||
Cmdline_bloom_intensity = 0;
|
||||
}
|
||||
|
||||
if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) < 0 ||
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) < 0 ) {
|
||||
Cmdline_fxaa = false;
|
||||
fxaa_unavailable = true;
|
||||
mprintf(("Error while compiling FXAA shaders. FXAA will be unavailable.\n"));
|
||||
if (gr_is_fxaa_mode(Gr_aa_mode))
|
||||
{
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0);
|
||||
}
|
||||
|
||||
if (gr_is_smaa_mode(Gr_aa_mode)) {
|
||||
// Precompile the SMAA shaders if enabled
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0);
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0);
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -861,6 +981,148 @@ void opengl_setup_bloom_textures()
|
||||
GL_state.BindFrameBuffer(0);
|
||||
}
|
||||
|
||||
void setup_smaa_edges_resources()
|
||||
{
|
||||
glGenTextures(1, &Smaa_edges_tex);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Smaa_edges_tex);
|
||||
|
||||
opengl_set_object_label(GL_TEXTURE, Smaa_edges_tex, "SMAA Edge detection texture");
|
||||
|
||||
if (GLAD_GL_ARB_texture_storage) {
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glGenFramebuffers(1, &Smaa_edge_detection_fb);
|
||||
GL_state.BindFrameBuffer(Smaa_edge_detection_fb);
|
||||
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_edge_detection_fb, "SMAA Edge detection framebuffer");
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_edges_tex, 0);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
void setup_smaa_blending_weight_resources()
|
||||
{
|
||||
glGenTextures(1, &Smaa_blend_tex);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Smaa_blend_tex);
|
||||
|
||||
opengl_set_object_label(GL_TEXTURE, Smaa_blend_tex, "SMAA Blending weight calculation texture");
|
||||
|
||||
if (GLAD_GL_ARB_texture_storage) {
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glGenFramebuffers(1, &Smaa_blending_weight_fb);
|
||||
GL_state.BindFrameBuffer(Smaa_blending_weight_fb);
|
||||
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_blending_weight_fb, "SMAA Blending widght calculation framebuffer");
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_blend_tex, 0);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
void setup_smaa_neighborhood_blending_resources()
|
||||
{
|
||||
glGenTextures(1, &Smaa_output_tex);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Smaa_output_tex);
|
||||
|
||||
opengl_set_object_label(GL_TEXTURE, Smaa_output_tex, "SMAA output texture");
|
||||
|
||||
if (GLAD_GL_ARB_texture_storage) {
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glGenFramebuffers(1, &Smaa_neighborhood_blending_fb);
|
||||
GL_state.BindFrameBuffer(Smaa_neighborhood_blending_fb);
|
||||
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_neighborhood_blending_fb, "SMAA neighborhood blending framebuffer");
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_output_tex, 0);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
static GLuint load_smaa_texture(GLsizei width, GLsizei height, GLenum format, const uint8_t* pixels, const char* name)
|
||||
{
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(tex);
|
||||
|
||||
opengl_set_object_label(GL_TEXTURE, tex, name);
|
||||
|
||||
if (GLAD_GL_ARB_texture_storage) {
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
}
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format == GL_RG8 ? GL_RG : GL_RED, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void setup_smaa_resources()
|
||||
{
|
||||
GL_state.PushFramebufferState();
|
||||
|
||||
Smaa_area_tex = load_smaa_texture(AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG8, areaTexBytes, "SMAA Area Texture");
|
||||
Smaa_search_tex =
|
||||
load_smaa_texture(SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_R8, searchTexBytes, "SMAA Search Texture");
|
||||
|
||||
setup_smaa_edges_resources();
|
||||
|
||||
setup_smaa_blending_weight_resources();
|
||||
|
||||
setup_smaa_neighborhood_blending_resources();
|
||||
|
||||
GL_state.PopFramebufferState();
|
||||
}
|
||||
|
||||
// generate and test the framebuffer and textures that we are going to use
|
||||
static bool opengl_post_init_framebuffer()
|
||||
{
|
||||
@@ -880,6 +1142,10 @@ static bool opengl_post_init_framebuffer()
|
||||
|
||||
opengl_setup_bloom_textures();
|
||||
|
||||
if (gr_is_smaa_mode(Gr_aa_mode)) {
|
||||
setup_smaa_resources();
|
||||
}
|
||||
|
||||
GL_state.BindFrameBuffer(0);
|
||||
|
||||
rval = true;
|
||||
@@ -918,11 +1184,11 @@ void opengl_post_process_init()
|
||||
//We need to read the tbl first. This is mostly for FRED's benefit, as otherwise the list of post effects for the sexp doesn't get updated.
|
||||
if ( !opengl_post_init_table() ) {
|
||||
mprintf((" Unable to read post-processing table! Disabling post-processing...\n\n"));
|
||||
Cmdline_postprocess = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Cmdline_postprocess ) {
|
||||
if ( !Gr_post_processing_enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -931,19 +1197,19 @@ void opengl_post_process_init()
|
||||
}
|
||||
|
||||
if ( Cmdline_no_fbo ) {
|
||||
Cmdline_postprocess = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !opengl_post_init_shaders() ) {
|
||||
mprintf((" Unable to initialize post-processing shaders! Disabling post-processing...\n\n"));
|
||||
Cmdline_postprocess = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !opengl_post_init_framebuffer() ) {
|
||||
mprintf((" Unable to initialize post-processing framebuffer! Disabling post-processing...\n\n"));
|
||||
Cmdline_postprocess = 0;
|
||||
Gr_post_processing_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#ifndef _GROPENGLPOSTPROCESSING_H
|
||||
#define _GROPENGLPOSTPROCESSING_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/opengl/gropenglshader.h"
|
||||
|
||||
void opengl_post_process_init();
|
||||
void opengl_post_process_shutdown();
|
||||
|
||||
|
||||
@@ -31,6 +31,18 @@
|
||||
|
||||
SCP_vector<opengl_shader_t> GL_shader;
|
||||
|
||||
typedef std::pair<int, uint32_t> shader_descriptor_t;
|
||||
|
||||
struct key_hasher
|
||||
{
|
||||
size_t operator()(const shader_descriptor_t &obj) const
|
||||
{
|
||||
return obj.first ^ obj.second;
|
||||
}
|
||||
};
|
||||
|
||||
SCP_unordered_map<shader_descriptor_t, size_t, key_hasher> GL_shader_map;
|
||||
|
||||
GLuint Framebuffer_fallback_texture_id = 0;
|
||||
|
||||
SCP_vector<opengl_vert_attrib> GL_vertex_attrib_info =
|
||||
@@ -131,6 +143,15 @@ static opengl_shader_type_t GL_shader_types[] = {
|
||||
|
||||
{ SDR_TYPE_ROCKET_UI, "rocketui-v.sdr", "rocketui-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::COLOR, opengl_vert_attrib::TEXCOORD }, "libRocket UI" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_SMAA_EDGE, "smaa-edge-v.sdr", "smaa-edge-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Edge detection" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, "smaa-blend-v.sdr", "smaa-blend-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Blending weight calculation" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, "smaa-neighbour-v.sdr", "smaa-neighbour-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Neighborhood Blending" },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -296,12 +317,10 @@ void opengl_shader_set_current(int handle)
|
||||
|
||||
size_t opengl_get_shader_idx(shader_type shader_t, unsigned int flags)
|
||||
{
|
||||
for (size_t idx = 0; idx < GL_shader.size(); idx++) {
|
||||
if (GL_shader[idx].shader == shader_t && GL_shader[idx].flags == flags) {
|
||||
return idx;
|
||||
}
|
||||
auto found = GL_shader_map.find(shader_descriptor_t(shader_t, flags));
|
||||
if (found != GL_shader_map.end()) {
|
||||
return found->second;
|
||||
}
|
||||
|
||||
return GL_shader.size();
|
||||
}
|
||||
|
||||
@@ -327,6 +346,8 @@ void opengl_delete_shader(int sdr_handle)
|
||||
{
|
||||
Assert(sdr_handle >= 0);
|
||||
Assert(sdr_handle < (int)GL_shader.size());
|
||||
opengl_shader_t &victim = GL_shader[sdr_handle];
|
||||
GL_shader_map.erase(shader_descriptor_t(victim.shader, victim.flags));
|
||||
|
||||
GL_shader[sdr_handle].program.reset();
|
||||
|
||||
@@ -341,6 +362,7 @@ void opengl_delete_shader(int sdr_handle)
|
||||
void opengl_shader_shutdown()
|
||||
{
|
||||
GL_shader.clear();
|
||||
GL_shader_map.clear();
|
||||
}
|
||||
|
||||
static SCP_string opengl_shader_get_header(shader_type type_id, int flags, bool has_geo_shader) {
|
||||
@@ -357,11 +379,13 @@ static SCP_string opengl_shader_get_header(shader_type type_id, int flags, bool
|
||||
sflags << "#define HAS_GEOMETRY_SHADER\n";
|
||||
}
|
||||
|
||||
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS || type_id == SDR_TYPE_POST_PROCESS_FXAA) {
|
||||
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ||
|
||||
type_id == SDR_TYPE_POST_PROCESS_FXAA || type_id == SDR_TYPE_POST_PROCESS_SMAA_EDGE ||
|
||||
type_id == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
|
||||
type_id == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
|
||||
// ignore looking for variants. main post process, lightshafts, and FXAA shaders need special headers to be hacked in
|
||||
opengl_post_shader_header(sflags, type_id, flags);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (int i = 0; i < GL_num_shader_variants; ++i) {
|
||||
opengl_shader_variant_t &variant = GL_shader_variants[i];
|
||||
|
||||
@@ -840,6 +864,8 @@ int opengl_compile_shader(shader_type sdr, uint flags)
|
||||
}
|
||||
}
|
||||
|
||||
int new_shader_shader = new_shader.shader;
|
||||
uint32_t new_shader_flags = new_shader.flags;
|
||||
// then insert it at an empty slot or at the end
|
||||
if ( empty_idx >= 0 ) {
|
||||
GL_shader[empty_idx] = std::move(new_shader);
|
||||
@@ -848,7 +874,7 @@ int opengl_compile_shader(shader_type sdr, uint flags)
|
||||
sdr_index = (int)GL_shader.size();
|
||||
GL_shader.push_back(std::move(new_shader));
|
||||
}
|
||||
|
||||
GL_shader_map[shader_descriptor_t(new_shader_shader, new_shader_flags)] = sdr_index;
|
||||
return sdr_index;
|
||||
}
|
||||
|
||||
@@ -939,6 +965,7 @@ void opengl_shader_init()
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &pixels);
|
||||
|
||||
GL_shader.clear();
|
||||
GL_shader_map.clear();
|
||||
|
||||
// Reserve 32 shader slots. This should cover most use cases in real life.
|
||||
GL_shader.reserve(32);
|
||||
@@ -976,7 +1003,7 @@ GLint opengl_shader_get_attribute(opengl_vert_attrib::attrib_id attribute)
|
||||
return Current_shader->program->getAttributeLocation(attribute);
|
||||
}
|
||||
|
||||
void opengl_shader_set_passthrough(bool textured)
|
||||
void opengl_shader_set_passthrough(bool textured, bool hdr)
|
||||
{
|
||||
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0));
|
||||
|
||||
@@ -988,7 +1015,7 @@ void opengl_shader_set_passthrough(bool textured)
|
||||
|
||||
Current_shader->program->Uniforms.setUniformi("alphaTexture", 0);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0);
|
||||
Current_shader->program->Uniforms.setUniformi("srgb", hdr ? 1 : 0);
|
||||
Current_shader->program->Uniforms.setUniformf("intensity", 1.0f);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold);
|
||||
|
||||
@@ -164,7 +164,7 @@ void opengl_shader_compile_deferred_light_clear_shader();
|
||||
|
||||
void opengl_shader_compile_passthrough_shader();
|
||||
|
||||
void opengl_shader_set_passthrough(bool textured = true);
|
||||
void opengl_shader_set_passthrough(bool textured, bool hdr);
|
||||
|
||||
void opengl_shader_set_default_material(bool textured, bool alpha, vec4* clr, float color_scale, uint32_t array_index, const material::clip_plane& clip_plane);
|
||||
|
||||
|
||||
@@ -718,10 +718,8 @@ void opengl_array_state::VertexAttribPointer(GLuint index, GLint size, GLenum ty
|
||||
|
||||
void opengl_array_state::ResetVertexAttribs()
|
||||
{
|
||||
SCP_map<GLuint, opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for ( it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it ) {
|
||||
DisableVertexAttrib(it->first);
|
||||
for (auto &it : vertex_attrib_units) {
|
||||
DisableVertexAttrib(it.first);
|
||||
}
|
||||
|
||||
vertex_attrib_units.clear();
|
||||
@@ -733,19 +731,17 @@ void opengl_array_state::BindPointersBegin()
|
||||
client_texture_units[i].used_for_draw = false;
|
||||
}
|
||||
|
||||
SCP_map<GLuint, opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for (it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it) {
|
||||
it->second.used_for_draw = false;
|
||||
for (auto &it : vertex_attrib_units) {
|
||||
it.second.used_for_draw = false;
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_array_state::BindPointersEnd()
|
||||
{
|
||||
SCP_map<GLuint, opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for (it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it) {
|
||||
if ( !it->second.used_for_draw ) DisableVertexAttrib(it->first);
|
||||
for (auto &it : vertex_attrib_units) {
|
||||
if (!it.second.used_for_draw) {
|
||||
DisableVertexAttrib(it.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,10 +760,8 @@ void opengl_array_state::BindArrayBuffer(GLuint id)
|
||||
client_texture_units[i].reset_ptr = true;
|
||||
}
|
||||
|
||||
SCP_map<GLuint,opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for ( it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it ) {
|
||||
it->second.reset_ptr = true;
|
||||
for (auto &it : vertex_attrib_units) {
|
||||
it.second.reset_ptr = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -849,6 +843,12 @@ void opengl_constant_state::init() {
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &_uniform_buffer_offset_alignment);
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &_max_uniform_block_size);
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &_max_uniform_block_bindings);
|
||||
|
||||
if (GLAD_GL_EXT_texture_filter_anisotropic) {
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &_max_anisotropy);
|
||||
} else {
|
||||
_max_anisotropy = -1.0f;
|
||||
}
|
||||
}
|
||||
GLint opengl_constant_state::GetUniformBufferOffsetAlignment() {
|
||||
return _uniform_buffer_offset_alignment;
|
||||
@@ -859,6 +859,9 @@ GLint opengl_constant_state::GetMaxUniformBlockSize() {
|
||||
GLint opengl_constant_state::GetMaxUniformBlockBindings() {
|
||||
return _max_uniform_block_bindings;
|
||||
}
|
||||
GLfloat opengl_constant_state::GetMaxAnisotropy() {
|
||||
return _max_anisotropy;
|
||||
}
|
||||
|
||||
void gr_opengl_clear_states()
|
||||
{
|
||||
|
||||
@@ -178,6 +178,7 @@ class opengl_constant_state {
|
||||
GLint _uniform_buffer_offset_alignment;
|
||||
GLint _max_uniform_block_size;
|
||||
GLint _max_uniform_block_bindings;
|
||||
GLfloat _max_anisotropy;
|
||||
|
||||
public:
|
||||
opengl_constant_state();
|
||||
@@ -189,6 +190,8 @@ class opengl_constant_state {
|
||||
GLint GetMaxUniformBlockSize();
|
||||
|
||||
GLint GetMaxUniformBlockBindings();
|
||||
|
||||
GLfloat GetMaxAnisotropy();
|
||||
};
|
||||
|
||||
class opengl_state
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
#endif
|
||||
|
||||
#define BMPMAN_INTERNAL
|
||||
#include "gropenglstate.h"
|
||||
#include "gropengltexture.h"
|
||||
#include "bmpman/bm_internal.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "ddsutils/ddsutils.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "graphics/grinternal.h"
|
||||
#include "gropenglstate.h"
|
||||
#include "gropengltexture.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "options/Option.h"
|
||||
#include "osapi/osregistry.h"
|
||||
|
||||
matrix4 GL_texture_matrix;
|
||||
@@ -35,7 +36,6 @@ int GL_last_detail = -1;
|
||||
GLint GL_supported_texture_units = 2;
|
||||
int GL_should_preload = 0;
|
||||
GLfloat GL_anisotropy = 1.0f;
|
||||
GLfloat GL_max_anisotropy = -1.0f;
|
||||
int GL_mipmap_filter = 0;
|
||||
GLenum GL_texture_target = GL_TEXTURE_2D;
|
||||
GLenum GL_texture_face = GL_TEXTURE_2D;
|
||||
@@ -49,6 +49,57 @@ extern int CLOAKMAP;
|
||||
extern int ENVMAP;
|
||||
extern int Interp_multitex_cloakmap;
|
||||
|
||||
static SCP_vector<float> anisotropic_value_enumerator()
|
||||
{
|
||||
float max;
|
||||
if (!gr_get_property(gr_property::MAX_ANISOTROPY, &max)) {
|
||||
return SCP_vector<float>();
|
||||
}
|
||||
|
||||
if (max <= 2.0f) {
|
||||
return SCP_vector<float>();
|
||||
}
|
||||
|
||||
SCP_vector<float> out;
|
||||
|
||||
// We assume here that the anisotropy levels are powers of two...
|
||||
float current = 1.0f;
|
||||
while (current <= max) {
|
||||
out.push_back(current);
|
||||
current *= 2.0f;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
static SCP_string anisotropic_display(float val)
|
||||
{
|
||||
if (val < 2.0f) {
|
||||
return "None";
|
||||
}
|
||||
|
||||
SCP_string out;
|
||||
sprintf(out, "%.0fx", val);
|
||||
return out;
|
||||
}
|
||||
static float anisotropic_default()
|
||||
{
|
||||
float max;
|
||||
if (!gr_get_property(gr_property::MAX_ANISOTROPY, &max)) {
|
||||
return 1.0f;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
static auto AnisotropyOption =
|
||||
options::OptionBuilder<float>("Graphics.Anisotropy", "Anisotropic filtering",
|
||||
"Controls the amount of anisotropic filtering of the textures.")
|
||||
.enumerator(anisotropic_value_enumerator)
|
||||
.category("Graphics")
|
||||
.display(anisotropic_display)
|
||||
.default_func(anisotropic_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(78)
|
||||
.finish();
|
||||
|
||||
// forward declarations
|
||||
int opengl_free_texture(tcache_slot_opengl *t);
|
||||
@@ -72,22 +123,6 @@ void opengl_set_modulate_tex_env()
|
||||
GL_CHECK_FOR_ERRORS("end of set_modulate_tex_env()");
|
||||
}
|
||||
|
||||
GLfloat opengl_get_max_anisotropy()
|
||||
{
|
||||
if ( !GLAD_GL_EXT_texture_filter_anisotropic ) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if ( GL_max_anisotropy < 0.0f ) {
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &GL_max_anisotropy);
|
||||
}
|
||||
|
||||
// the spec says that it should be a minimum of 2.0
|
||||
Assert( GL_max_anisotropy >= 2.0f );
|
||||
|
||||
return GL_max_anisotropy;
|
||||
}
|
||||
|
||||
void opengl_set_texture_target( GLenum target )
|
||||
{
|
||||
GL_texture_target = target;
|
||||
@@ -131,13 +166,17 @@ void opengl_tcache_init()
|
||||
// anisotropy
|
||||
if ( GLAD_GL_EXT_texture_filter_anisotropic ) {
|
||||
// set max value first thing
|
||||
GL_anisotropy = opengl_get_max_anisotropy();
|
||||
GL_anisotropy = GL_state.Constants.GetMaxAnisotropy();
|
||||
|
||||
// now for the user setting
|
||||
if (Cmdline_aniso_level != 0)
|
||||
GL_anisotropy = (GLfloat) Cmdline_aniso_level;
|
||||
if (Using_in_game_options) {
|
||||
GL_anisotropy = AnisotropyOption->getValue();
|
||||
} else {
|
||||
// now for the user setting
|
||||
if (Cmdline_aniso_level != 0)
|
||||
GL_anisotropy = (GLfloat)Cmdline_aniso_level;
|
||||
}
|
||||
|
||||
CLAMP(GL_anisotropy, 1.0f, GL_max_anisotropy);
|
||||
CLAMP(GL_anisotropy, 1.0f, GL_state.Constants.GetMaxAnisotropy());
|
||||
}
|
||||
|
||||
Assert( GL_supported_texture_units >= 2 );
|
||||
@@ -160,7 +199,6 @@ void opengl_tcache_flush()
|
||||
|
||||
extern void opengl_kill_all_render_targets();
|
||||
|
||||
void opengl_tex_array_storage(GLenum target, GLint levels, GLenum format, GLint width, GLint height, GLint frames);
|
||||
void opengl_tcache_shutdown()
|
||||
{
|
||||
opengl_kill_all_render_targets();
|
||||
@@ -284,37 +322,24 @@ int opengl_free_texture(tcache_slot_opengl *t)
|
||||
// bmap_h == height of source bitmap
|
||||
// tex_w == width of final texture
|
||||
// tex_h == height of final texture
|
||||
int opengl_texture_set_level(int bitmap_handle,
|
||||
int bitmap_type,
|
||||
int bmap_w,
|
||||
int bmap_h,
|
||||
int tex_w,
|
||||
int tex_h,
|
||||
ubyte* data,
|
||||
tcache_slot_opengl* tSlot,
|
||||
int /*base_level*/,
|
||||
bool resize,
|
||||
GLenum intFormat)
|
||||
{
|
||||
static int opengl_texture_set_level(int bitmap_handle, int bitmap_type, int bmap_w, int bmap_h, int tex_w, int tex_h,
|
||||
ubyte* data, tcache_slot_opengl* tSlot, int base_level, int mipmap_levels,
|
||||
bool resize, GLenum intFormat) {
|
||||
GR_DEBUG_SCOPE("Upload single frame");
|
||||
|
||||
int ret_val = 1;
|
||||
ubyte *bmp_data = data;
|
||||
int ret_val = 1;
|
||||
ubyte* bmp_data = data;
|
||||
ubyte *texmem = NULL, *texmemp = NULL;
|
||||
int skip_size = 0, mipmap_levels = 0;
|
||||
int skip_size = 0;
|
||||
|
||||
GL_CHECK_FOR_ERRORS("start of create_texture_sub()");
|
||||
|
||||
// bogus
|
||||
if ( (tSlot == NULL) || (bmp_data == NULL) ) {
|
||||
if ((tSlot == nullptr) || (bmp_data == nullptr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// for everything that might use mipmaps
|
||||
auto mipmap_w = tex_w;
|
||||
auto mipmap_h = tex_h;
|
||||
|
||||
if ( (bitmap_type == TCACHE_TYPE_AABITMAP) || (bitmap_type == TCACHE_TYPE_INTERFACE) ) {
|
||||
if ((bitmap_type == TCACHE_TYPE_AABITMAP) || (bitmap_type == TCACHE_TYPE_INTERFACE)) {
|
||||
tSlot->u_scale = (float)bmap_w / (float)tex_w;
|
||||
tSlot->v_scale = (float)bmap_h / (float)tex_h;
|
||||
} else {
|
||||
@@ -326,73 +351,207 @@ int opengl_texture_set_level(int bitmap_handle,
|
||||
auto byte_mult = (tSlot->bpp >> 3);
|
||||
|
||||
GLenum texFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
GLenum glFormat = GL_BGRA;
|
||||
GLenum glFormat = GL_BGRA;
|
||||
// GL_BGRA_EXT is *much* faster with some hardware/drivers
|
||||
if (byte_mult == 4) {
|
||||
texFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
intFormat = (gr_screen.bits_per_pixel == 32) ? GL_RGBA8 : GL_RGB5_A1;
|
||||
glFormat = GL_BGRA;
|
||||
glFormat = GL_BGRA;
|
||||
} else if (byte_mult == 3) {
|
||||
texFormat = GL_UNSIGNED_BYTE;
|
||||
intFormat = (gr_screen.bits_per_pixel == 32) ? GL_RGB8 : GL_RGB5;
|
||||
glFormat = GL_BGR;
|
||||
glFormat = GL_BGR;
|
||||
} else if (byte_mult == 2) {
|
||||
texFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
intFormat = GL_RGB5_A1;
|
||||
glFormat = GL_BGRA;
|
||||
glFormat = GL_BGRA;
|
||||
} else if (byte_mult == 1) {
|
||||
Assertion( bitmap_type == TCACHE_TYPE_AABITMAP, "Invalid type for bitmap: %s BMPMAN handle: %d. Type expected was 0, we got %d instead.\nThis can be caused by using texture compression on a non-power-of-2 texture.\n", bm_get_filename(bitmap_handle), bitmap_handle, bitmap_type );
|
||||
Assertion(bitmap_type == TCACHE_TYPE_AABITMAP,
|
||||
"Invalid type for bitmap: %s BMPMAN handle: %d. Type expected was 0, we got %d instead.\nThis can be "
|
||||
"caused by using texture compression on a non-power-of-2 texture.\n",
|
||||
bm_get_filename(bitmap_handle), bitmap_handle, bitmap_type);
|
||||
texFormat = GL_UNSIGNED_BYTE;
|
||||
intFormat = GL_RED;
|
||||
glFormat = GL_RED;
|
||||
glFormat = GL_RED;
|
||||
} else {
|
||||
texFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
intFormat = GL_RGBA;
|
||||
glFormat = GL_BGRA;
|
||||
glFormat = GL_BGRA;
|
||||
}
|
||||
|
||||
// check for compressed image types
|
||||
auto block_size = 0;
|
||||
switch ( bm_is_compressed(bitmap_handle) ) {
|
||||
case DDS_DXT1:
|
||||
case DDS_CUBEMAP_DXT1:
|
||||
intFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
block_size = 8;
|
||||
break;
|
||||
switch (bm_is_compressed(bitmap_handle)) {
|
||||
case DDS_DXT1:
|
||||
case DDS_CUBEMAP_DXT1:
|
||||
intFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
block_size = 8;
|
||||
break;
|
||||
|
||||
case DDS_DXT3:
|
||||
case DDS_CUBEMAP_DXT3:
|
||||
intFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
block_size = 16;
|
||||
break;
|
||||
case DDS_DXT3:
|
||||
case DDS_CUBEMAP_DXT3:
|
||||
intFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
block_size = 16;
|
||||
break;
|
||||
|
||||
case DDS_DXT5:
|
||||
case DDS_CUBEMAP_DXT5:
|
||||
intFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
block_size = 16;
|
||||
break;
|
||||
case DDS_DXT5:
|
||||
case DDS_CUBEMAP_DXT5:
|
||||
intFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
block_size = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( bitmap_type == TCACHE_TYPE_CUBEMAP ) {
|
||||
if (bitmap_type == TCACHE_TYPE_CUBEMAP) {
|
||||
tSlot->texture_target = GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
mipmap_levels = bm_get_num_mipmaps(bitmap_handle);
|
||||
|
||||
auto dsize = 0;
|
||||
auto dsize = 0;
|
||||
auto doffset = 0;
|
||||
|
||||
switch (bitmap_type) {
|
||||
case TCACHE_TYPE_COMPRESSED: {
|
||||
if (block_size > 0) {
|
||||
for (auto i = 0; i < mipmap_levels; i++) {
|
||||
case TCACHE_TYPE_COMPRESSED: {
|
||||
if (block_size > 0) {
|
||||
auto mipmap_w = bmap_w;
|
||||
auto mipmap_h = bmap_h;
|
||||
|
||||
for (auto i = 0; i < mipmap_levels + base_level; i++) {
|
||||
// size of data block (4x4)
|
||||
dsize = ((mipmap_h + 3) / 4) * ((mipmap_w + 3) / 4) * block_size;
|
||||
|
||||
if (i >= base_level) {
|
||||
glCompressedTexSubImage3D(tSlot->texture_target, i - base_level, 0, 0, tSlot->array_index, mipmap_w,
|
||||
mipmap_h, 1, intFormat, dsize, bmp_data + doffset);
|
||||
}
|
||||
|
||||
// adjust the data offset for the next block
|
||||
doffset += dsize;
|
||||
|
||||
// reduce size by half for the next pass
|
||||
mipmap_w >>= 1;
|
||||
mipmap_h >>= 1;
|
||||
|
||||
if (mipmap_w <= 0) {
|
||||
mipmap_w = 1;
|
||||
}
|
||||
|
||||
if (mipmap_h <= 0) {
|
||||
mipmap_h = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCACHE_TYPE_AABITMAP: {
|
||||
texmem = (ubyte*)vm_malloc(tex_w * tex_h * byte_mult);
|
||||
texmemp = texmem;
|
||||
|
||||
Assert(texmem != nullptr);
|
||||
|
||||
int luminance = 0;
|
||||
for (auto i = 0; i < tex_h; i++) {
|
||||
for (auto j = 0; j < tex_w; j++) {
|
||||
if ((i < bmap_h) && (j < bmap_w)) {
|
||||
if (byte_mult > 1) {
|
||||
luminance = 0;
|
||||
|
||||
if (byte_mult > 3) {
|
||||
for (auto k = 0; k < 3; k++) {
|
||||
luminance += bmp_data[(i * bmap_w + j) * byte_mult + k];
|
||||
}
|
||||
|
||||
*texmemp++ =
|
||||
(ubyte)((luminance / 3) * (bmp_data[(i * bmap_w + j) * byte_mult + 3] / 255.0f));
|
||||
} else {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
luminance += bmp_data[(i * bmap_w + j) * byte_mult + k];
|
||||
}
|
||||
|
||||
*texmemp++ = (ubyte)(luminance / byte_mult);
|
||||
}
|
||||
} else {
|
||||
*texmemp++ = bmp_data[i * bmap_w + j];
|
||||
}
|
||||
} else {
|
||||
*texmemp++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLenum aa_format = GL_RED;
|
||||
|
||||
glTexSubImage3D(tSlot->texture_target, 0, 0, 0, tSlot->array_index, tex_w, tex_h, 1, aa_format,
|
||||
GL_UNSIGNED_BYTE, texmem);
|
||||
|
||||
if (texmem != nullptr) {
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCACHE_TYPE_INTERFACE: {
|
||||
// if we aren't resizing then we can just use bmp_data directly
|
||||
if (resize) {
|
||||
texmem = (ubyte*)vm_malloc(tex_w * tex_h * byte_mult);
|
||||
texmemp = texmem;
|
||||
|
||||
Assert(texmem != nullptr);
|
||||
|
||||
for (auto i = 0; i < tex_h; i++) {
|
||||
for (auto j = 0; j < tex_w; j++) {
|
||||
if ((i < bmap_h) && (j < bmap_w)) {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
*texmemp++ = bmp_data[(i * bmap_w + j) * byte_mult + k];
|
||||
}
|
||||
} else {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
*texmemp++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glTexSubImage3D(tSlot->texture_target, 0, 0, 0, tSlot->array_index, tex_w, tex_h, 1, glFormat, texFormat,
|
||||
(resize) ? texmem : bmp_data);
|
||||
|
||||
if (texmem != nullptr) {
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCACHE_TYPE_CUBEMAP: {
|
||||
Assert(!resize);
|
||||
Assert(texmem == nullptr);
|
||||
|
||||
// we have to load in all 6 faces...
|
||||
doffset = 0;
|
||||
for (auto i = 0; i < 6; i++) {
|
||||
// We need to use the actual size of the bitmap here since tex_h/w is already
|
||||
// adjusted for the size of the target bitmap. Since we are not resizing here that is not a problem
|
||||
auto mipmap_w = bmap_w;
|
||||
auto mipmap_h = bmap_h;
|
||||
|
||||
// check if it's a compressed cubemap first
|
||||
if (block_size > 0) {
|
||||
for (auto level = 0; level < mipmap_levels + base_level; level++) {
|
||||
// size of data block (4x4)
|
||||
dsize = ((mipmap_h + 3) / 4) * ((mipmap_w + 3) / 4) * block_size;
|
||||
|
||||
glCompressedTexSubImage3D(tSlot->texture_target, i, 0, 0, tSlot->array_index, mipmap_w, mipmap_h, 1, intFormat, dsize, bmp_data + doffset);
|
||||
if (level >= base_level) {
|
||||
// We skipped ahead to the base level so we can start uploading frames now
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, level - base_level, 0, 0,
|
||||
mipmap_w, mipmap_h, intFormat, dsize, bmp_data + doffset);
|
||||
}
|
||||
|
||||
// adjust the data offset for the next block
|
||||
doffset += dsize;
|
||||
@@ -410,233 +569,112 @@ int opengl_texture_set_level(int bitmap_handle,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCACHE_TYPE_AABITMAP: {
|
||||
texmem = (ubyte *) vm_malloc (tex_w*tex_h*byte_mult);
|
||||
texmemp = texmem;
|
||||
|
||||
Assert( texmem != NULL );
|
||||
|
||||
int luminance = 0;
|
||||
for (auto i = 0; i < tex_h; i++) {
|
||||
for (auto j = 0; j < tex_w; j++) {
|
||||
if ( (i < bmap_h) && (j < bmap_w) ) {
|
||||
if ( byte_mult > 1 ) {
|
||||
luminance = 0;
|
||||
|
||||
if ( byte_mult > 3 ) {
|
||||
for (auto k = 0; k < 3; k++) {
|
||||
luminance += bmp_data[(i*bmap_w+j)*byte_mult+k];
|
||||
}
|
||||
|
||||
*texmemp++ = (ubyte)((luminance / 3) * (bmp_data[(i*bmap_w+j)*byte_mult+3]/255.0f));
|
||||
} else {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
luminance += bmp_data[(i*bmap_w+j)*byte_mult+k];
|
||||
}
|
||||
|
||||
*texmemp++ = (ubyte)(luminance / byte_mult);
|
||||
}
|
||||
} else {
|
||||
*texmemp++ = bmp_data[i*bmap_w+j];
|
||||
}
|
||||
} else {
|
||||
*texmemp++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLenum aa_format = GL_RED;
|
||||
|
||||
glTexSubImage3D (tSlot->texture_target, 0, 0, 0, tSlot->array_index, tex_w, tex_h, 1, aa_format, GL_UNSIGNED_BYTE, texmem);
|
||||
|
||||
if (texmem != NULL) {
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCACHE_TYPE_INTERFACE: {
|
||||
// if we aren't resizing then we can just use bmp_data directly
|
||||
if (resize) {
|
||||
texmem = (ubyte *) vm_malloc (tex_w*tex_h*byte_mult);
|
||||
texmemp = texmem;
|
||||
|
||||
Assert( texmem != NULL );
|
||||
|
||||
for (auto i = 0; i < tex_h; i++) {
|
||||
for (auto j = 0;j < tex_w; j++) {
|
||||
if ( (i < bmap_h) && (j < bmap_w) ) {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
*texmemp++ = bmp_data[(i*bmap_w+j)*byte_mult+k];
|
||||
}
|
||||
} else {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
*texmemp++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glTexSubImage3D (tSlot->texture_target, 0, 0, 0, tSlot->array_index, mipmap_w, mipmap_h, 1, glFormat, texFormat, (resize) ? texmem : bmp_data);
|
||||
|
||||
if (texmem != NULL) {
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCACHE_TYPE_CUBEMAP: {
|
||||
Assert( !resize );
|
||||
Assert( texmem == NULL );
|
||||
|
||||
// we have to load in all 6 faces...
|
||||
doffset = 0;
|
||||
for (auto i = 0; i < 6; i++) {
|
||||
doffset += dsize;
|
||||
|
||||
// check if it's a compressed cubemap first
|
||||
if (block_size > 0) {
|
||||
// size of data block (4x4)
|
||||
dsize = ((mipmap_h + 3) / 4) * ((mipmap_w + 3) / 4) * block_size;
|
||||
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, 0, 0, mipmap_w, mipmap_h, intFormat, dsize, bmp_data + doffset);
|
||||
|
||||
// now that the base image is done handle any mipmap levels
|
||||
for (auto j = 1; j < mipmap_levels; j++) {
|
||||
// adjust the data offset for the next block
|
||||
doffset += dsize;
|
||||
|
||||
// reduce size by half for the next pass
|
||||
mipmap_w >>= 1;
|
||||
mipmap_h >>= 1;
|
||||
|
||||
if (mipmap_w <= 0) {
|
||||
mipmap_w = 1;
|
||||
}
|
||||
|
||||
if (mipmap_h <= 0) {
|
||||
mipmap_h = 1;
|
||||
}
|
||||
|
||||
// size of data block (4x4)
|
||||
dsize = ((mipmap_h + 3) / 4) * ((mipmap_w + 3) / 4) * block_size;
|
||||
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, j, 0, 0, mipmap_w, mipmap_h, intFormat, dsize, bmp_data + doffset);
|
||||
}
|
||||
}
|
||||
// nope, it's uncompressed...
|
||||
else {
|
||||
for (auto level = 0; level < mipmap_levels + base_level; level++) {
|
||||
dsize = mipmap_h * mipmap_w * byte_mult;
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, 0, 0, mipmap_w, mipmap_h, glFormat, texFormat, bmp_data + doffset);
|
||||
if (level >= base_level) {
|
||||
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, level - base_level, 0, 0, mipmap_w,
|
||||
mipmap_h, glFormat, texFormat, bmp_data + doffset);
|
||||
}
|
||||
|
||||
// base image is done so now take care of any mipmap levels
|
||||
for (auto j = 1; j < mipmap_levels; j++) {
|
||||
doffset += dsize;
|
||||
mipmap_w >>= 1;
|
||||
mipmap_h >>= 1;
|
||||
doffset += dsize;
|
||||
mipmap_w >>= 1;
|
||||
mipmap_h >>= 1;
|
||||
|
||||
if (mipmap_w <= 0) {
|
||||
mipmap_w = 1;
|
||||
}
|
||||
if (mipmap_w <= 0) {
|
||||
mipmap_w = 1;
|
||||
}
|
||||
|
||||
if (mipmap_h <= 0) {
|
||||
mipmap_h = 1;
|
||||
}
|
||||
|
||||
dsize = mipmap_h * mipmap_w * byte_mult;
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, j, 0, 0, mipmap_w, mipmap_h, glFormat, texFormat, bmp_data + doffset);
|
||||
if (mipmap_h <= 0) {
|
||||
mipmap_h = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// reset width and height for next face
|
||||
mipmap_w = tex_w;
|
||||
mipmap_h = tex_h;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// if we aren't resizing then we can just use bmp_data directly
|
||||
if (resize) {
|
||||
texmem = (ubyte *) vm_malloc (tex_w*tex_h*byte_mult);
|
||||
texmemp = texmem;
|
||||
break;
|
||||
}
|
||||
|
||||
Assert( texmem != NULL );
|
||||
default: {
|
||||
// if we aren't resizing then we can just use bmp_data directly
|
||||
if (resize) {
|
||||
texmem = (ubyte*)vm_malloc(tex_w * tex_h * byte_mult);
|
||||
texmemp = texmem;
|
||||
|
||||
fix u, utmp, v, du, dv;
|
||||
Assert(texmem != nullptr);
|
||||
|
||||
u = v = 0;
|
||||
fix u, utmp, v, du, dv;
|
||||
|
||||
du = ( (bmap_w-1)*F1_0 ) / tex_w;
|
||||
dv = ( (bmap_h-1)*F1_0 ) / tex_h;
|
||||
u = v = 0;
|
||||
|
||||
for (auto j=0;j<tex_h;j++)
|
||||
{
|
||||
utmp = u;
|
||||
for (auto i=0;i<tex_w;i++)
|
||||
{
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
*texmemp++ = bmp_data[(f2i(v)*bmap_w+f2i(utmp))*byte_mult+k];
|
||||
}
|
||||
utmp += du;
|
||||
du = ((bmap_w - 1) * F1_0) / tex_w;
|
||||
dv = ((bmap_h - 1) * F1_0) / tex_h;
|
||||
|
||||
for (auto j = 0; j < tex_h; j++) {
|
||||
utmp = u;
|
||||
for (auto i = 0; i < tex_w; i++) {
|
||||
for (auto k = 0; k < byte_mult; k++) {
|
||||
*texmemp++ = bmp_data[(f2i(v) * bmap_w + f2i(utmp)) * byte_mult + k];
|
||||
}
|
||||
v += dv;
|
||||
utmp += du;
|
||||
}
|
||||
v += dv;
|
||||
}
|
||||
|
||||
// should never have mipmap levels if we also have to manually resize
|
||||
if ( (mipmap_levels > 1) && resize ) {
|
||||
Assert( texmem == NULL );
|
||||
}
|
||||
|
||||
for (auto i = 0; i < mipmap_levels; i++) {
|
||||
// size of data block (4x4)
|
||||
dsize = mipmap_h * mipmap_w * byte_mult;
|
||||
|
||||
glTexSubImage3D (tSlot->texture_target, i, 0, 0, tSlot->array_index, mipmap_w, mipmap_h, 1, glFormat, texFormat, (texmem != NULL) ? texmem : bmp_data + doffset);
|
||||
|
||||
// adjust the data offset for the next block
|
||||
doffset += dsize;
|
||||
|
||||
// reduce size by half for the next pass
|
||||
mipmap_w >>= 1;
|
||||
mipmap_h >>= 1;
|
||||
|
||||
if (mipmap_w <= 0) {
|
||||
mipmap_w = 1;
|
||||
}
|
||||
|
||||
if (mipmap_h <= 0) {
|
||||
mipmap_h = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (texmem != NULL) {
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}//end switch
|
||||
|
||||
auto mipmap_w = tex_w;
|
||||
auto mipmap_h = tex_h;
|
||||
|
||||
// should never have mipmap levels if we also have to manually resize
|
||||
if ((mipmap_levels > 1) && resize) {
|
||||
Assert(texmem == nullptr);
|
||||
|
||||
// If we have mipmaps then tex_w/h are already adjusted for the base level but that will cause problems with
|
||||
// the code below. Instead we set the values to the actual size of the bitmap here to make sure we can
|
||||
// iterate properly through the mipmap levels.
|
||||
mipmap_w = bmap_w;
|
||||
mipmap_h = bmap_h;
|
||||
}
|
||||
|
||||
for (auto i = 0; i < mipmap_levels + base_level; i++) {
|
||||
// size of data block (4x4)
|
||||
dsize = mipmap_h * mipmap_w * byte_mult;
|
||||
|
||||
if (i >= base_level) {
|
||||
glTexSubImage3D(tSlot->texture_target, i - base_level, 0, 0, tSlot->array_index, mipmap_w, mipmap_h, 1,
|
||||
glFormat, texFormat, (texmem != nullptr) ? texmem : bmp_data + doffset);
|
||||
}
|
||||
|
||||
// adjust the data offset for the next block
|
||||
doffset += dsize;
|
||||
|
||||
// reduce size by half for the next pass
|
||||
mipmap_w >>= 1;
|
||||
mipmap_h >>= 1;
|
||||
|
||||
if (mipmap_w <= 0) {
|
||||
mipmap_w = 1;
|
||||
}
|
||||
|
||||
if (mipmap_h <= 0) {
|
||||
mipmap_h = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (texmem != nullptr) {
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
tSlot->bitmap_handle = bitmap_handle;
|
||||
tSlot->size = (dsize) ? ((doffset + dsize) - skip_size) : (tex_w * tex_h * byte_mult);
|
||||
tSlot->w = (ushort)tex_w;
|
||||
tSlot->h = (ushort)tex_h;
|
||||
tSlot->size = (dsize) ? ((doffset + dsize) - skip_size) : (tex_w * tex_h * byte_mult);
|
||||
tSlot->w = (ushort)tex_w;
|
||||
tSlot->h = (ushort)tex_h;
|
||||
|
||||
GL_textures_in_frame += tSlot->size;
|
||||
|
||||
@@ -780,6 +818,8 @@ void opengl_tex_array_storage(GLenum target, GLint levels, GLenum format, GLint
|
||||
mip_height = std::max(1, (mip_height / 2));
|
||||
}
|
||||
}
|
||||
// Make sure that the image is complete with the right number of mipmap levels
|
||||
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels);
|
||||
}
|
||||
} else {
|
||||
if (GLAD_GL_ARB_texture_storage) {
|
||||
@@ -791,6 +831,8 @@ void opengl_tex_array_storage(GLenum target, GLint levels, GLenum format, GLint
|
||||
width = std::max(1, (width / 2));
|
||||
height = std::max(1, (height / 2));
|
||||
}
|
||||
// Make sure that the image is complete with the right number of mipmap levels
|
||||
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -856,6 +898,10 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
|
||||
}
|
||||
|
||||
Assert( (max_levels - base_level) >= 1 );
|
||||
|
||||
// Adjust the size to match the size of the used base-mipmap
|
||||
width >>= base_level;
|
||||
height >>= base_level;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,19 +943,24 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
|
||||
|
||||
GLenum min_filter = GL_LINEAR;
|
||||
|
||||
auto mipmap_levels = (ubyte)(max_levels - base_level);
|
||||
auto mipmap_levels = max_levels - base_level;
|
||||
// Needed in case we need to allocate more mipmaps than are in the texture file
|
||||
auto allocated_mipmap_levels = mipmap_levels;
|
||||
if (mipmap_levels > 1) {
|
||||
min_filter = (GL_mipmap_filter) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST;
|
||||
|
||||
if ( GLAD_GL_EXT_texture_filter_anisotropic ) {
|
||||
glTexParameterf(tslot->texture_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, GL_anisotropy);
|
||||
}
|
||||
} else if (mipmap_levels == 1 && bitmap_type == TCACHE_TYPE_CUBEMAP) {
|
||||
Assertion(num_frames == 1, "Cube map arrays are not supported yet!");
|
||||
// For cubemaps without mipmaps, we will generate them later so we need to make sure that enough space is
|
||||
// allocated for the generated mipmaps
|
||||
allocated_mipmap_levels = get_num_mipmap_levels(width, height);
|
||||
|
||||
min_filter = GL_LINEAR_MIPMAP_LINEAR;
|
||||
}
|
||||
|
||||
if (base_level != 0) {
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_BASE_LEVEL, base_level);
|
||||
}
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_MAX_LEVEL, mipmap_levels);
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
@@ -923,7 +974,7 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
|
||||
opengl_determine_bpp_and_flags(animation_begin, bitmap_type, bitmap_flags, bits_per_pixel);
|
||||
|
||||
auto intFormat = opengl_get_internal_format(bitmap_handle, bitmap_type, bits_per_pixel);
|
||||
opengl_tex_array_storage(tslot->texture_target, max_levels, intFormat, width, height, num_frames);
|
||||
opengl_tex_array_storage(tslot->texture_target, allocated_mipmap_levels, intFormat, width, height, num_frames);
|
||||
|
||||
bool frames_loaded = true;
|
||||
for (int frame = animation_begin; frame < animation_begin + num_frames; ++frame) {
|
||||
@@ -961,17 +1012,8 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
|
||||
frame_slot->array_index = (uint32_t) (frame - animation_begin);
|
||||
|
||||
// call the helper
|
||||
int ret_val = opengl_texture_set_level(frame,
|
||||
bitmap_type,
|
||||
bmp->w,
|
||||
bmp->h,
|
||||
width,
|
||||
height,
|
||||
(ubyte*) bmp->data,
|
||||
frame_slot,
|
||||
base_level,
|
||||
resize,
|
||||
intFormat);
|
||||
int ret_val = opengl_texture_set_level(frame, bitmap_type, bmp->w, bmp->h, width, height, (ubyte*)bmp->data,
|
||||
frame_slot, base_level, mipmap_levels, resize, intFormat);
|
||||
frames_loaded = frames_loaded && ret_val;
|
||||
|
||||
// unlock the bitmap
|
||||
@@ -980,12 +1022,8 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
|
||||
|
||||
if ( tslot->mipmap_levels == 1 && bitmap_type == TCACHE_TYPE_CUBEMAP ) {
|
||||
Assertion(num_frames == 1, "Cube map arrays are not supported yet!");
|
||||
// generate mip maps for cube maps so we can get glossy reflections; necessary for gloss maps and physically-based lighting
|
||||
// OGL_EXT_FRAMEBUFFER_OBJECT required to use glGenerateMipmap()
|
||||
tslot->mipmap_levels = get_num_mipmap_levels(tslot->w, tslot->h);
|
||||
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_MAX_LEVEL, tslot->mipmap_levels - 1);
|
||||
glTexParameteri(tslot->texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
// generate mip maps for cube maps so we can get glossy reflections; necessary for gloss maps and
|
||||
// physically-based lighting OGL_EXT_FRAMEBUFFER_OBJECT required to use glGenerateMipmap()
|
||||
|
||||
glGenerateMipmap(tslot->texture_target);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@ void opengl_tcache_frame();
|
||||
void opengl_set_additive_tex_env();
|
||||
void opengl_set_modulate_tex_env();
|
||||
void opengl_preload_init();
|
||||
GLfloat opengl_get_max_anisotropy();
|
||||
void opengl_kill_render_target(bitmap_slot* slot);
|
||||
int opengl_make_render_target(int handle, int *w, int *h, int *bpp, int *mm_lvl, int flags);
|
||||
int opengl_set_render_target(int slot, int face = -1, int is_static = 0);
|
||||
@@ -88,6 +87,7 @@ void gr_opengl_get_bitmap_from_texture(void* data_out, int bitmap_num);
|
||||
size_t opengl_export_render_target( int slot, int width, int height, int alpha, int num_mipmaps, ubyte *image_data );
|
||||
void opengl_set_texture_target(GLenum target = GL_TEXTURE_2D);
|
||||
void opengl_set_texture_face(GLenum face = GL_TEXTURE_2D);
|
||||
void opengl_tex_array_storage(GLenum target, GLint levels, GLenum format, GLint width, GLint height, GLint frames);
|
||||
|
||||
int gr_opengl_tcache_set(int bitmap_handle, int bitmap_type, float *u_scale, float *v_scale, uint32_t *array_index, int stage = 0);
|
||||
int gr_opengl_preload(int bitmap_num, int is_aabitmap);
|
||||
|
||||
@@ -12,28 +12,29 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
#include "gropengldeferred.h"
|
||||
#include "gropengldraw.h"
|
||||
#include "gropenglshader.h"
|
||||
#include "gropenglstate.h"
|
||||
#include "gropengltexture.h"
|
||||
#include "gropengltnl.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "def_files/def_files.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "graphics/matrix.h"
|
||||
#include "graphics/grinternal.h"
|
||||
#include "gropengldraw.h"
|
||||
#include "gropenglshader.h"
|
||||
#include "gropenglstate.h"
|
||||
#include "gropengltexture.h"
|
||||
#include "gropengldeferred.h"
|
||||
#include "gropengltnl.h"
|
||||
#include "graphics/light.h"
|
||||
#include "graphics/material.h"
|
||||
#include "graphics/matrix.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "lighting/lighting.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "options/Option.h"
|
||||
#include "particle/particle.h"
|
||||
#include "render/3d.h"
|
||||
#include "weapon/trails.h"
|
||||
#include "particle/particle.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "graphics/material.h"
|
||||
#include "graphics/light.h"
|
||||
#include "ShaderProgram.h"
|
||||
|
||||
extern int GLOWMAP;
|
||||
extern int CLOAKMAP;
|
||||
@@ -61,6 +62,7 @@ GLint GL_max_elements_indices = 4096;
|
||||
GLuint Shadow_map_texture = 0;
|
||||
GLuint Shadow_map_depth_texture = 0;
|
||||
GLuint shadow_fbo = 0;
|
||||
int Shadow_texture_size = 0;
|
||||
bool Rendering_to_shadow_map = false;
|
||||
|
||||
int Transform_buffer_handle = -1;
|
||||
@@ -421,6 +423,8 @@ static bool opengl_init_shadow_framebuffer(int size, GLenum color_format)
|
||||
|
||||
glGenTextures(1, &Shadow_map_depth_texture);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
|
||||
GL_state.Texture.Enable(Shadow_map_depth_texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@@ -453,6 +457,7 @@ static bool opengl_init_shadow_framebuffer(int size, GLenum color_format)
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE) {
|
||||
// Everything is fine
|
||||
mprintf(("Shadow framebuffer created successfully.\n"));
|
||||
Shadow_texture_size = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -489,13 +494,30 @@ void opengl_tnl_init()
|
||||
{
|
||||
Transform_buffer_handle = opengl_create_texture_buffer_object();
|
||||
|
||||
if (Cmdline_shadow_quality) {
|
||||
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
|
||||
if (Shadow_quality != ShadowQuality::Disabled) {
|
||||
int size;
|
||||
switch (Shadow_quality) {
|
||||
case ShadowQuality::Low:
|
||||
size = 512;
|
||||
break;
|
||||
case ShadowQuality::Medium:
|
||||
size = 1024;
|
||||
break;
|
||||
case ShadowQuality::High:
|
||||
size = 2048;
|
||||
break;
|
||||
case ShadowQuality::Ultra:
|
||||
size = 4096;
|
||||
break;
|
||||
default:
|
||||
size = 256;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!opengl_init_shadow_framebuffer(size, GL_RGBA32F)) {
|
||||
if (!opengl_init_shadow_framebuffer(size, GL_RGBA16F)) {
|
||||
mprintf(("Failed to create either 32 or 16-bit color shadow framebuffer. Disabling shadow support.\n"));
|
||||
Cmdline_shadow_quality = 0;
|
||||
Shadow_quality = ShadowQuality::Disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -626,7 +648,7 @@ extern bool gr_htl_projection_matrix_set;
|
||||
|
||||
void gr_opengl_shadow_map_start(matrix4 *shadow_view_matrix, const matrix *light_orient)
|
||||
{
|
||||
if ( !Cmdline_shadow_quality )
|
||||
if (Shadow_quality == ShadowQuality::Disabled)
|
||||
return;
|
||||
|
||||
GL_state.PushFramebufferState();
|
||||
@@ -650,8 +672,7 @@ void gr_opengl_shadow_map_start(matrix4 *shadow_view_matrix, const matrix *light
|
||||
|
||||
*shadow_view_matrix = gr_view_matrix;
|
||||
|
||||
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
|
||||
glViewport(0, 0, size, size);
|
||||
glViewport(0, 0, Shadow_texture_size, Shadow_texture_size);
|
||||
}
|
||||
|
||||
void gr_opengl_shadow_map_end()
|
||||
|
||||
@@ -490,8 +490,6 @@ int NanoVGRenderer::createTexture(int type, int w, int h, int imageFlags, const
|
||||
img.width = w;
|
||||
img.height = h;
|
||||
|
||||
bm_get_info(img.bitmap);
|
||||
|
||||
auto id = ++_lastImageId;
|
||||
_textureMap.insert(std::make_pair(id, std::move(img)));
|
||||
|
||||
@@ -509,7 +507,11 @@ int NanoVGRenderer::updateTexture(int image, int /*x*/, int /*y*/, int /*w*/,
|
||||
} else {
|
||||
bpp = 8;
|
||||
}
|
||||
bm_get_info(texture->bitmap);
|
||||
|
||||
// Copy the updated data to our internal buffer so that changes in the hardware texture detail don't discard the
|
||||
// changes NanoVG made to the texture
|
||||
memcpy(texture->data.get(), data, texture->width * texture->height * bpp / 8);
|
||||
|
||||
// TODO: This could probably be done better by only uploading the changed area
|
||||
gr_update_texture(texture->bitmap, bpp, data, texture->width, texture->height);
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) Freespace Open 2013. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Freespace Open. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* All source code herein is the property of Freespace Open. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "graphics/shadows.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "debris/debris.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "graphics/matrix.h"
|
||||
#include "lighting/lighting.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "model/model.h"
|
||||
#include "model/modelrender.h"
|
||||
#include "options/Option.h"
|
||||
#include "render/3d.h"
|
||||
#include "tracing/tracing.h"
|
||||
|
||||
@@ -27,6 +28,27 @@ float Shadow_cascade_distances[MAX_SHADOW_CASCADES];
|
||||
|
||||
light_frustum_info Shadow_frustums[MAX_SHADOW_CASCADES];
|
||||
|
||||
ShadowQuality Shadow_quality;
|
||||
|
||||
auto ShadowQualityOption =
|
||||
options::OptionBuilder<ShadowQuality>("Graphics.Shadows", "Shadow Quality", "The quality of the shadows")
|
||||
.values({{ShadowQuality::Disabled, "Disabled"},
|
||||
{ShadowQuality::Low, "Low"},
|
||||
{ShadowQuality::Medium, "Medium"},
|
||||
{ShadowQuality::High, "High"},
|
||||
{ShadowQuality::Ultra, "Ultra"}})
|
||||
.change_listener([](ShadowQuality val, bool initial) {
|
||||
if (initial) {
|
||||
Shadow_quality = val;
|
||||
}
|
||||
return initial; // No dynamic changes implemented
|
||||
})
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.category("Graphics")
|
||||
.default_val(ShadowQuality::Disabled)
|
||||
.importance(80)
|
||||
.finish();
|
||||
|
||||
bool shadows_obj_in_frustum(object *objp, matrix *light_orient, vec3d *min, vec3d *max)
|
||||
{
|
||||
vec3d pos, pos_rot;
|
||||
@@ -402,7 +424,7 @@ void shadows_render_all(float fov, matrix *eye_orient, vec3d *eye_pos)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Cmdline_shadow_quality) {
|
||||
if (Shadow_quality == ShadowQuality::Disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ struct light_frustum_info
|
||||
float start_dist;
|
||||
};
|
||||
|
||||
enum class ShadowQuality { Disabled = 0, Low = 1, Medium = 2, High = 3, Ultra = 4 };
|
||||
|
||||
extern ShadowQuality Shadow_quality;
|
||||
|
||||
extern matrix4 Shadow_view_matrix;
|
||||
extern matrix4 Shadow_proj_matrix[MAX_SHADOW_CASCADES];
|
||||
extern float Shadow_cascade_distances[MAX_SHADOW_CASCADES];
|
||||
@@ -36,4 +40,4 @@ void shadows_render_all(float fov, matrix *eye_orient, vec3d *eye_pos);
|
||||
matrix shadows_start_render(matrix *eye_orient, vec3d *eye_pos, float fov, float aspect, float veryneardist, float neardist, float middist, float fardist);
|
||||
void shadows_end_render();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+43
-9
@@ -5,7 +5,7 @@
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
#include "ai/aigoals.h"
|
||||
@@ -23,9 +23,10 @@
|
||||
#include "hud/hudets.h"
|
||||
#include "hud/hudlock.h"
|
||||
#include "hud/hudmessage.h"
|
||||
#include "hud/hudnavigation.h" //kazan
|
||||
#include "hud/hudnavigation.h" //kazan
|
||||
#include "hud/hudobserver.h"
|
||||
#include "hud/hudreticle.h"
|
||||
#include "hud/hudscripting.h"
|
||||
#include "hud/hudshield.h"
|
||||
#include "hud/hudsquadmsg.h"
|
||||
#include "hud/hudtarget.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
#include "radar/radar.h"
|
||||
#include "radar/radarsetup.h"
|
||||
#include "render/3d.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "ship/ship.h"
|
||||
#include "starfield/supernova.h"
|
||||
#include "weapon/emp.h"
|
||||
@@ -246,7 +248,7 @@ static int Damage_flash_timer;
|
||||
|
||||
HudGauge::HudGauge():
|
||||
base_w(0), base_h(0), gauge_config(-1), font_num(font::FONT1), lock_color(false), sexp_lock_color(false), reticle_follow(false),
|
||||
active(false), off_by_default(false), sexp_override(false), pop_up(false), disabled_views(0), custom_gauge(false),
|
||||
active(false), off_by_default(false), sexp_override(false), pop_up(false), disabled_views(0), only_render_in_chase_view(false), custom_gauge(false),
|
||||
texture_target(-1), canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
{
|
||||
position[0] = 0;
|
||||
@@ -271,7 +273,7 @@ texture_target(-1), canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
HudGauge::HudGauge(int _gauge_object, int _gauge_config, bool _slew, bool _message, int _disabled_views, int r, int g, int b):
|
||||
base_w(0), base_h(0), gauge_config(_gauge_config), gauge_object(_gauge_object), font_num(font::FONT1), lock_color(false), sexp_lock_color(false),
|
||||
reticle_follow(_slew), active(false), off_by_default(false), sexp_override(false), pop_up(false), message_gauge(_message),
|
||||
disabled_views(_disabled_views), custom_gauge(false), textoffset_x(0), textoffset_y(0), texture_target(-1),
|
||||
disabled_views(_disabled_views), only_render_in_chase_view(false), custom_gauge(false), textoffset_x(0), textoffset_y(0), texture_target(-1),
|
||||
canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
{
|
||||
Assert(gauge_config <= NUM_HUD_GAUGES && gauge_config >= 0);
|
||||
@@ -307,8 +309,8 @@ canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
HudGauge::HudGauge(int _gauge_config, bool _slew, int r, int g, int b, char* _custom_name, char* _custom_text, char* frame_fname, int txtoffset_x, int txtoffset_y):
|
||||
base_w(0), base_h(0), gauge_config(_gauge_config), gauge_object(HUD_OBJECT_CUSTOM), font_num(font::FONT1), lock_color(false), sexp_lock_color(false),
|
||||
reticle_follow(_slew), active(false), off_by_default(false), sexp_override(false), pop_up(false), message_gauge(false),
|
||||
disabled_views(VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY), custom_gauge(true), textoffset_x(txtoffset_x),
|
||||
textoffset_y(txtoffset_y), texture_target(-1), canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
disabled_views(VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY), only_render_in_chase_view(false), custom_gauge(true), textoffset_x(txtoffset_x),
|
||||
textoffset_y(txtoffset_y), texture_target(-1), canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
{
|
||||
position[0] = 0;
|
||||
position[1] = 0;
|
||||
@@ -546,6 +548,11 @@ void HudGauge::initRenderStatus(bool do_render)
|
||||
off_by_default = !do_render;
|
||||
}
|
||||
|
||||
void HudGauge::initChase_view_only(bool chase_view_only)
|
||||
{
|
||||
only_render_in_chase_view = chase_view_only;
|
||||
}
|
||||
|
||||
bool HudGauge::isOffbyDefault()
|
||||
{
|
||||
return off_by_default;
|
||||
@@ -917,7 +924,7 @@ void HudGauge::renderRect(int x, int y, int w, int h)
|
||||
gr_reset_screen_scale();
|
||||
}
|
||||
|
||||
void HudGauge::renderCircle(int x, int y, int diameter)
|
||||
void HudGauge::renderCircle(int x, int y, int diameter, bool filled)
|
||||
{
|
||||
int nx = 0, ny = 0;
|
||||
|
||||
@@ -935,8 +942,12 @@ void HudGauge::renderCircle(int x, int y, int diameter)
|
||||
gr_set_screen_scale(base_w, base_h);
|
||||
}
|
||||
}
|
||||
if (filled) {
|
||||
gr_circle(x + nx, y + ny, diameter);
|
||||
} else {
|
||||
gr_unfilled_circle(x + nx, y + ny, diameter);
|
||||
}
|
||||
|
||||
gr_circle(x+nx, y+ny, diameter);
|
||||
gr_reset_screen_scale();
|
||||
}
|
||||
|
||||
@@ -1082,6 +1093,10 @@ bool HudGauge::canRender()
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((Viewer_mode & (VM_CHASE)) == 0 && only_render_in_chase_view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(pop_up) {
|
||||
if(!popUpActive()) {
|
||||
return false;
|
||||
@@ -1222,6 +1237,25 @@ void HUD_init()
|
||||
default_hud_gauges[j]->resetTimers();
|
||||
default_hud_gauges[j]->updateSexpOverride(false);
|
||||
}
|
||||
|
||||
Script_system.OnStateDestroy.add(hud_scripting_close);
|
||||
}
|
||||
|
||||
void hud_scripting_close(lua_State*) {
|
||||
// Clean up Lua references so that we don't have dangling references on to the lua state in the HUD gauges
|
||||
for (auto it = Ship_info.begin(); it != Ship_info.end(); ++it) {
|
||||
for (const auto& gauge : it->hud_gauges) {
|
||||
if (gauge->getObjectType() == HUD_OBJECT_SCRIPTING) {
|
||||
static_cast<HudGaugeScripting*>(gauge.get())->setRenderFunction(luacpp::LuaFunction());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& gauge : default_hud_gauges) {
|
||||
if (gauge->getObjectType() == HUD_OBJECT_SCRIPTING) {
|
||||
static_cast<HudGaugeScripting*>(gauge.get())->setRenderFunction(luacpp::LuaFunction());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3911,7 +3945,7 @@ void HudGaugeSupernova::render(float /*frametime*/)
|
||||
if (Lcl_pl) {
|
||||
renderPrintf(position[0], position[1], "Wybuch supernowej: %.2f s", time_left);
|
||||
} else {
|
||||
renderPrintf(position[0], position[1], "Supernova Warning: %.2f s", time_left);
|
||||
renderPrintf(position[0], position[1], XSTR( "Supernova Warning: %.2f s", 1639), time_left);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -110,6 +110,7 @@ extern int Hud_max_targeting_range;
|
||||
|
||||
void HUD_init_colors();
|
||||
void HUD_init();
|
||||
void hud_scripting_close(lua_State*);
|
||||
void hud_close();
|
||||
void hud_level_close();
|
||||
void hud_update_frame(float frametime); // updates hud systems not dependant on rendering
|
||||
@@ -223,6 +224,7 @@ protected:
|
||||
int flash_duration;
|
||||
int flash_next;
|
||||
bool flash_status;
|
||||
bool only_render_in_chase_view;
|
||||
|
||||
// custom gauge specific stuff
|
||||
bool custom_gauge;
|
||||
@@ -268,7 +270,7 @@ public:
|
||||
void updateActive(bool show);
|
||||
void updatePopUp(bool pop_up_flag);
|
||||
void updateSexpOverride(bool sexp);
|
||||
|
||||
void initChase_view_only(bool chase_view_only);
|
||||
|
||||
// SEXP interfacing functions
|
||||
// For flashing gauges in training missions
|
||||
@@ -316,7 +318,7 @@ public:
|
||||
void renderLine(int x1, int y1, int x2, int y2);
|
||||
void renderGradientLine(int x1, int y1, int x2, int y2);
|
||||
void renderRect(int x, int y, int w, int h);
|
||||
void renderCircle(int x, int y, int diameter);
|
||||
void renderCircle(int x, int y, int diameter, bool filled = true);
|
||||
|
||||
void unsize(int *x, int *y);
|
||||
void unsize(float *x, float *y);
|
||||
|
||||
@@ -95,6 +95,32 @@ void parse_ssm(const char *filename)
|
||||
s.max_count = -1;
|
||||
}
|
||||
|
||||
if (optional_string("+WarpEffect:")) {
|
||||
int temp;
|
||||
if (stuff_int_optional(&temp) != 2) {
|
||||
// We have a string to parse instead.
|
||||
char unique_id[NAME_LENGTH];
|
||||
memset(unique_id, 0, NAME_LENGTH);
|
||||
stuff_string(unique_id, F_NAME, NAME_LENGTH);
|
||||
int fireball_type = fireball_info_lookup(unique_id);
|
||||
if (fireball_type < 0) {
|
||||
error_display(1, "Unknown fireball [%s] to use as warp effect for SSM strike [%s]", unique_id, s.name);
|
||||
s.fireball_idx = FIREBALL_WARP;
|
||||
} else {
|
||||
s.fireball_idx = fireball_type;
|
||||
}
|
||||
} else {
|
||||
if ((temp < 0) || (temp >= Num_fireball_types)) {
|
||||
error_display(1, "Fireball index [%d] out of range (should be 0-%d) for SSM strike [%s]", temp, Num_fireball_types - 1, s.name);
|
||||
s.fireball_idx = FIREBALL_WARP;
|
||||
} else {
|
||||
s.fireball_idx = temp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.fireball_idx = FIREBALL_WARP;
|
||||
}
|
||||
|
||||
required_string("+WarpRadius:");
|
||||
stuff_float(&s.warp_radius);
|
||||
|
||||
@@ -422,7 +448,7 @@ void ssm_process()
|
||||
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &moveup->sinfo.start_pos[idx]);
|
||||
vm_vec_normalize(&temp);
|
||||
vm_vector_2_matrix(&orient, &temp, NULL, NULL);
|
||||
moveup->fireballs[idx] = fireball_create(&moveup->sinfo.start_pos[idx], FIREBALL_WARP, FIREBALL_WARP_EFFECT, -1, si->warp_radius, 0, &vmd_zero_vector, si->warp_time, 0, &orient);
|
||||
moveup->fireballs[idx] = fireball_create(&moveup->sinfo.start_pos[idx], si->fireball_idx, FIREBALL_WARP_EFFECT, -1, si->warp_radius, false, &vmd_zero_vector, si->warp_time, 0, &orient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ typedef struct ssm_info {
|
||||
int count; // # of missiles in this type of strike
|
||||
int max_count; // Maximum # of missiles in this type of strike (-1 for no variance)
|
||||
int weapon_info_index; // missile type
|
||||
int fireball_idx; // Type of fireball to use for warp effect (defaults to FIREBALL_WARP)
|
||||
float warp_radius; // radius of associated warp effect
|
||||
float warp_time; // how long the warp effect lasts
|
||||
float radius; // radius around the target ship
|
||||
@@ -49,7 +50,7 @@ typedef struct ssm_firing_info {
|
||||
SCP_vector<vec3d> start_pos; // start positions
|
||||
|
||||
int count; // The ssm_info count may be variable; this stores the actual number of projectiles for this strike.
|
||||
size_t ssm_index; // index info ssm_info array
|
||||
size_t ssm_index; // index into ssm_info array
|
||||
class object* target; // target for the strike
|
||||
int ssm_team; // team that fired the ssm.
|
||||
float duration; // how far into the warp effect to fire
|
||||
|
||||
Loaded 100 of 371 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user