mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
197
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17b01fa8eb | ||
|
|
45ea62a9a2 | ||
|
|
979a4b0924 | ||
|
|
e1db71fb69 | ||
|
|
c33d406942 | ||
|
|
30baac39a9 | ||
|
|
50dbbc4687 | ||
|
|
e19a6f9e01 | ||
|
|
d9184545f7 | ||
|
|
5c07d181ad | ||
|
|
140fed2812 | ||
|
|
dd2fd3ee5c | ||
|
|
dd7c36e43d | ||
|
|
409c7da2d7 | ||
|
|
791e22bc1d | ||
|
|
6a93715c9b | ||
|
|
8fee9804df | ||
|
|
2dc6d64c37 | ||
|
|
a8142b8f80 | ||
|
|
53f98cda99 | ||
|
|
115d06a051 | ||
|
|
485af1bad3 | ||
|
|
0ca5ade5ef | ||
|
|
ff601db6fc | ||
|
|
686bc35cff | ||
|
|
ffe9a085b6 | ||
|
|
33df766edf | ||
|
|
9a6227e7b0 | ||
|
|
c664eac1ee | ||
|
|
a7a9514fd1 | ||
|
|
b402d9158c | ||
|
|
c1b055a685 | ||
|
|
412197d3e9 | ||
|
|
98f1d690f6 | ||
|
|
842dbb1b75 | ||
|
|
df8e85f22e | ||
|
|
73482a6d62 | ||
|
|
afa7976018 | ||
|
|
0d355982d4 | ||
|
|
7f9021cbdb | ||
|
|
1450c71e2e | ||
|
|
d80e6d0f71 | ||
|
|
f6dd3b09ab | ||
|
|
bc5ef0b28d | ||
|
|
8e618ffaec | ||
|
|
889474688c | ||
|
|
d56cb8fc62 | ||
|
|
98f196ee48 | ||
|
|
9f4ad9d1eb | ||
|
|
a69e1d7308 | ||
|
|
34d1bf03f9 | ||
|
|
9fcd96ff97 | ||
|
|
2b77721c79 | ||
|
|
95fafa50c4 | ||
|
|
cac07391ca | ||
|
|
9daeb7f417 | ||
|
|
f0ba0265fd | ||
|
|
5b77cad5ac | ||
|
|
3f024cb324 | ||
|
|
1d60d25cf5 | ||
|
|
be5c98c7e2 | ||
|
|
6212ad29f1 | ||
|
|
5ec30bdaee | ||
|
|
b9b74a3201 | ||
|
|
09c24313d7 | ||
|
|
afdaa3a3ee | ||
|
|
68dcef639d | ||
|
|
91f351b990 | ||
|
|
dd1def4f4c | ||
|
|
8b770792fb | ||
|
|
23f9cfc815 | ||
|
|
11f9175425 | ||
|
|
4fb9c27e71 | ||
|
|
4c7b7a0fef | ||
|
|
3dc1689936 | ||
|
|
94df2777e0 | ||
|
|
c9ebc33d98 | ||
|
|
9bd459d549 | ||
|
|
d9db8bdb71 | ||
|
|
f3cdfcc229 | ||
|
|
44e3f1f9b5 | ||
|
|
da5e7f1510 | ||
|
|
d830a01381 | ||
|
|
d24d536731 | ||
|
|
6d0e166dea | ||
|
|
e0301da596 | ||
|
|
a815c0247c | ||
|
|
f42eaf9637 | ||
|
|
01fb2c1243 | ||
|
|
408f259368 | ||
|
|
a9b8e5c043 | ||
|
|
cfb9540e2c | ||
|
|
88115c7703 | ||
|
|
8dba6770ae | ||
|
|
8f4d51b14a | ||
|
|
185aece470 | ||
|
|
0e962e269b | ||
|
|
095a2efc56 | ||
|
|
944a254551 | ||
|
|
f628999ef9 | ||
|
|
e2fb4d84d7 | ||
|
|
ff952298a2 | ||
|
|
66b3fdfed8 | ||
|
|
451c03f76a | ||
|
|
da30c5a38e | ||
|
|
5206aaabdf | ||
|
|
f6ed93f7a9 | ||
|
|
4f0e2ae9f1 | ||
|
|
c3f595ba0e | ||
|
|
d02d98681a | ||
|
|
98e37b2570 | ||
|
|
3c8b87c958 | ||
|
|
8d44946b2b | ||
|
|
98b9d5c899 | ||
|
|
2f5079fcd1 | ||
|
|
59a8a347a1 | ||
|
|
e04f1b4ca4 | ||
|
|
7da41c32e3 | ||
|
|
73770845b6 | ||
|
|
5828d7f634 | ||
|
|
45f6cdc687 | ||
|
|
13fe34a3c7 | ||
|
|
da64f285bc | ||
|
|
45f9ea2ea4 | ||
|
|
eb73328c14 | ||
|
|
380ca12b0d | ||
|
|
c7e66e26fb | ||
|
|
ff911e666d | ||
|
|
c8619ddd0d | ||
|
|
721b2da37b | ||
|
|
e9f4c1618e | ||
|
|
4eef54c10b | ||
|
|
f5ba1e470c | ||
|
|
94a00ca6ee | ||
|
|
3a8c10bec5 | ||
|
|
e92cc5161e | ||
|
|
ea73ea33ca | ||
|
|
8fe7dc4a1b | ||
|
|
f5bbb21199 | ||
|
|
c2761a6142 | ||
|
|
88b0dba208 | ||
|
|
7173299ca7 | ||
|
|
e35fc10530 | ||
|
|
46e8e735b6 | ||
|
|
e3e40ee576 | ||
|
|
f0b99e24ff | ||
|
|
e0f76e0cfa | ||
|
|
5303440dfb | ||
|
|
138a1d01d4 | ||
|
|
0814bf0ae1 | ||
|
|
39a0cfecbb | ||
|
|
b78d940136 | ||
|
|
bc03442a3c | ||
|
|
8ce1a6f490 | ||
|
|
18d2ef8580 | ||
|
|
4a86b70a69 | ||
|
|
f717c41083 | ||
|
|
92aacc8479 | ||
|
|
2ae7990c61 | ||
|
|
4e8ebedfa0 | ||
|
|
01f418f2fb | ||
|
|
0ed47de357 | ||
|
|
f5f1c97c0f | ||
|
|
b0d3957df7 | ||
|
|
332bd01f0f | ||
|
|
eb8717f051 | ||
|
|
af8ae03d9e | ||
|
|
0ca7299bbc | ||
|
|
98234c3bc2 | ||
|
|
50691c41da | ||
|
|
4a66cb190a | ||
|
|
9ba3a0ccf9 | ||
|
|
b625f51645 | ||
|
|
c2c8acbf13 | ||
|
|
ac58950ac5 | ||
|
|
8a84fffe12 | ||
|
|
0c216ede98 | ||
|
|
3e543729fc | ||
|
|
6385bf73be | ||
|
|
b7a32329db | ||
|
|
b363bda60d | ||
|
|
0b547d971e | ||
|
|
9ac04b9349 | ||
|
|
453b1ca619 | ||
|
|
e6f1332980 | ||
|
|
5840ca84d6 | ||
|
|
aa0e1c755f | ||
|
|
97469d65ef | ||
|
|
5834c01ca9 | ||
|
|
13076364d6 | ||
|
|
e2905e76ca | ||
|
|
accea7bb4d | ||
|
|
733b67ada3 | ||
|
|
de06d1e36f | ||
|
|
5b01036723 | ||
|
|
a737c7a373 | ||
|
|
7e399681cd |
No files matched your search
@@ -10,6 +10,7 @@ misc-*,\
|
||||
-misc-macro-parentheses,\
|
||||
-misc-misplaced-widening-cast,\
|
||||
-misc-static-assert,\
|
||||
-modernize-make-unique,\
|
||||
"
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: 'code/.*$|freespace2/.*$|qtfred/.*$|test/src/.*$|build/.*$'
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
*.unsuccessfulbuild
|
||||
ipch/
|
||||
[Oo]bj/
|
||||
[Bb]in
|
||||
[Dd]ebug*/
|
||||
[Rr]elease*/
|
||||
Ankh.NoLoad
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
[submodule "cmake/external/rpavlik-cmake-modules"]
|
||||
path = cmake/external/rpavlik-cmake-modules
|
||||
url = https://github.com/asarium/cmake-modules.git
|
||||
[submodule "lib/libRocket"]
|
||||
path = lib/libRocket
|
||||
url = https://github.com/asarium/libRocket.git
|
||||
+164
-140
@@ -1,157 +1,181 @@
|
||||
language: generic
|
||||
language: bash
|
||||
sudo: required
|
||||
dist: trusty
|
||||
cache:
|
||||
directories:
|
||||
directories:
|
||||
- $HOME/cmake-3.8
|
||||
- $HOME/.ccache
|
||||
addons:
|
||||
apt:
|
||||
packages: &global_deps
|
||||
- ninja-build
|
||||
- libopenal-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libsdl2-dev
|
||||
- valgrind
|
||||
- qt57base
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
notification_email: niffiwan.scp@gmail.com
|
||||
build_command: "ci/travis/script.sh"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
apt:
|
||||
packages: &global_deps
|
||||
- ninja-build
|
||||
- libopenal-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libsdl2-dev
|
||||
- libfreetype6-dev
|
||||
- valgrind
|
||||
- qt57base
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
notification_email: [email protected]
|
||||
build_command: "ci/travis/script.sh"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
# also note that fork's don't get access to secure keys
|
||||
# you have to test using a branch in the main repo
|
||||
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
|
||||
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
|
||||
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
|
||||
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
|
||||
# These declarations set FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
|
||||
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
|
||||
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
# also note that fork's don't get access to secure keys
|
||||
# you have to test using a branch in the main repo
|
||||
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
|
||||
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
|
||||
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
|
||||
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
|
||||
# These declarations set FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
|
||||
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
|
||||
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
on:
|
||||
condition: '"$RELEASE_BUILD" == true'
|
||||
tags: true
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
on:
|
||||
condition: '"$RELEASE_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: script
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: '"$NIGHTLY_BUILD" == true'
|
||||
tags: true
|
||||
- provider: script
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: '"$NIGHTLY_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: $TEST_BUILD = true
|
||||
all_branches: true
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: $TEST_BUILD = true
|
||||
all_branches: true
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# note that gcc Debug MUST be 1st for Coverity
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-8 CXX=g++-8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- g++-8
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- clang-4.0
|
||||
- clang-tidy-4.0
|
||||
- libc++-dev
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
- ./ci/travis/clang_tidy.sh
|
||||
- os: osx
|
||||
env: CONFIGURATION="Debug"
|
||||
include:
|
||||
# note that gcc Debug MUST be 1st for Coverity
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-8 CXX=g++-8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- g++-8
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- clang-4.0
|
||||
- clang-tidy-4.0
|
||||
- libc++-dev
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
- ./ci/travis/clang_tidy.sh
|
||||
- os: osx
|
||||
env: CONFIGURATION="Debug"
|
||||
|
||||
- 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: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-8 CXX=g++-8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- g++-8
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=clang-4.0 CXX=clang++-4.0
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- clang-4.0
|
||||
- libc++-dev
|
||||
- os: osx
|
||||
env: CONFIGURATION="Release"
|
||||
|
||||
- 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"
|
||||
# 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
|
||||
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-8 CXX=g++-8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- g++-8
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=clang-4.0 CXX=clang++-4.0
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- clang-4.0
|
||||
- libc++-dev
|
||||
- os: osx
|
||||
env: CONFIGURATION="Release"
|
||||
before_install:
|
||||
# ugly hack; if running a coverity scan abort all except the 1st build
|
||||
# see note re gcc compiler above needing to be 1st
|
||||
# also note that branch_pattern & the TRAVIS_BRANCH check must match
|
||||
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
|
||||
# build process
|
||||
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
|
||||
- source "./ci/travis/check_release.sh"
|
||||
- "./ci/travis/before_install.sh"
|
||||
# ugly hack; if running a coverity scan abort all except the 1st build
|
||||
# see note re gcc compiler above needing to be 1st
|
||||
# also note that branch_pattern & the TRAVIS_BRANCH check must match
|
||||
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
|
||||
# build process
|
||||
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
|
||||
- source "./ci/travis/check_release.sh"
|
||||
- "./ci/travis/before_install.sh"
|
||||
install:
|
||||
- "./ci/travis/install.sh"
|
||||
- export PATH=$HOME/cmake-3.6/bin:$PATH
|
||||
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then export PATH="/c/Program Files/CMake/bin":$PATH; fi
|
||||
- "./ci/travis/install.sh"
|
||||
- export PATH=$HOME/cmake-3.6/bin:$PATH
|
||||
before_script:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
|
||||
- "./ci/travis/before_script.sh"
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
|
||||
- "./ci/travis/before_script.sh"
|
||||
script:
|
||||
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
|
||||
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
|
||||
@@ -84,7 +84,6 @@ IF (WIN32)
|
||||
OPTION(FSO_BUILD_FRED2 "Build FRED2 binary" ON)
|
||||
elseif(UNIX)
|
||||
option(FSO_BUILD_APPIMAGE "Build an AppImage package" OFF)
|
||||
set(APPIMAGE_ASSISTANT "" CACHE STRING "The root directory of an AppImage clone.")
|
||||
ENDIF(WIN32)
|
||||
|
||||
OPTION(FSO_BUILD_TOOLS "Build tools related to FSO" OFF)
|
||||
|
||||
@@ -133,6 +133,7 @@ if ($DeployBuild) {
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/../install" -DFSO_USE_SPEECH="ON" `
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$($buildConfig.SimdType)" `
|
||||
-DQT5_INSTALL_ROOT="$($buildConfig.QtDir)" -DFSO_BUILD_QTFRED=ON `
|
||||
-G "$($buildConfig.Generator)" -T "$($buildConfig.Toolset)" ..
|
||||
|
||||
$Configs = @("Release", "FastDebug")
|
||||
|
||||
@@ -8,4 +8,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
fi
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
mkdir -p /tmp/builds
|
||||
if [ "$RELEASE_BUILD" = true ]; then
|
||||
# Package the source code in release builds
|
||||
PARENT_DIR="$(basename "$PWD")"
|
||||
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
if [ "$RELEASE_BUILD" = true ]; then
|
||||
PARENT_DIR="$(basename $PWD)"
|
||||
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
|
||||
fi
|
||||
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
|
||||
@@ -27,8 +31,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
mkdir -p $config
|
||||
cd $config
|
||||
eval $CMAKE -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_BUILD_TYPE=$config -DCMAKE_INSTALL_PREFIX="/tmp/release/$config" \
|
||||
-DFSO_BUILD_APPIMAGE=ON -DAPPIMAGE_ASSISTANT="$HOME/AppImageAssistant" \
|
||||
-DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON ../..
|
||||
-DFSO_BUILD_APPIMAGE=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_QTFRED=OFF ../..
|
||||
cd ..
|
||||
done
|
||||
else
|
||||
@@ -40,4 +43,12 @@ elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
else
|
||||
cmake -G "Xcode" $CMAKE_OPTIONS ..
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -G "$CMAKE_GENERATOR" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "$CMAKE_GENERATOR" -T "$CMAKE_TOOLSET" ..
|
||||
fi
|
||||
fi
|
||||
@@ -58,6 +58,11 @@ if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
echo "Skipping non-release configuration";
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
echo "Skipping non-release platform"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
export RELEASE_BUILD
|
||||
|
||||
@@ -16,14 +16,19 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
cd $HOME
|
||||
|
||||
if [ "${BUILD_DEPLOYMENT}" = true ]; then
|
||||
wget -c "https://github.com/probonopd/AppImageKit/releases/download/5/AppImageAssistant" # (64-bit)
|
||||
chmod a+x ./AppImageAssistant
|
||||
wget -O appimagetool -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" # (64-bit)
|
||||
chmod a+x ./appimagetool
|
||||
|
||||
wget -O linuxdeployqt -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" # (64-bit)
|
||||
chmod a+x ./linuxdeployqt
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
gem install xcpretty
|
||||
|
||||
brew update
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
choco install mingw ninja
|
||||
fi
|
||||
|
||||
cmake --version
|
||||
+34
-1
@@ -8,7 +8,40 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
cd "$config"
|
||||
ninja appimage
|
||||
|
||||
# Compile all targets
|
||||
ninja all
|
||||
|
||||
# Install Freespace2 targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Freespace2 -P cmake_install.cmake
|
||||
|
||||
# We need to be a bit creative for determining the AppImage name since we don't want to hard-code the name
|
||||
FILENAME="$(find /tmp/release/$config/fso/bin -name 'fs2_open_*' -type f -printf "%f\n").AppImage"
|
||||
$HOME/appimagetool -n /tmp/release/$config/fso "/tmp/release/$config/fso/$FILENAME"
|
||||
|
||||
: <<'END'
|
||||
# Install qtFRED targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=qtFRED -P cmake_install.cmake
|
||||
|
||||
PREV="$(pwd)"
|
||||
cd /tmp/release/$config/qtfred
|
||||
|
||||
unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH
|
||||
$HOME/linuxdeployqt usr/qtfred.desktop -bundle-non-qt-libs
|
||||
# Move our AppRun script to the right location
|
||||
mv usr/AppRun AppRun
|
||||
|
||||
echo "Embed newer libstdc++ for distros that don't come with it (ubuntu 14.04)";
|
||||
mkdir -p usr/optional/; mkdir -p usr/optional/libstdc++/;
|
||||
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./usr/optional/libstdc++/;
|
||||
|
||||
$HOME/appimagetool -n . "$(find /tmp/release/$config/qtfred/usr/bin -name 'qtfred_*' -type f -printf "%f\n").AppImage"
|
||||
|
||||
cd "$PREV"
|
||||
END
|
||||
|
||||
cd ..
|
||||
done
|
||||
|
||||
|
||||
@@ -22,4 +22,10 @@ elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
curl --upload-file build.log.tar.gz "https://transfer.sh/build.log.tar.gz"
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
|
||||
cmake --build . --config "$CONFIGURATION"
|
||||
else
|
||||
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
|
||||
fi
|
||||
fi
|
||||
@@ -34,3 +34,10 @@
|
||||
fun:lua_rawget
|
||||
fun:_ZN12_GLOBAL__N_117ade_index_handlerEP9lua_State
|
||||
}
|
||||
{
|
||||
False-positive uninitialized variable warning
|
||||
Memcheck:Cond
|
||||
fun:_Z23cf_check_location_flagsjj
|
||||
fun:_Z29cf_create_default_path_stringPcjiPKcbj
|
||||
...
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=FreeSpace Open
|
||||
Exec=$<TARGET_FILE_NAME:Freespace2>
|
||||
Icon=app_icon.png
|
||||
Icon=app_icon
|
||||
Categories=Game;
|
||||
@@ -6,18 +6,16 @@ configure_file("${CMAKE_CURRENT_LIST_DIR}/AppRun.in" "${CMAKE_CURRENT_BINARY_DIR
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>"
|
||||
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun.gen")
|
||||
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun"
|
||||
COMPONENT "Freespace2")
|
||||
|
||||
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/AppImage.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen" @ONLY)
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop"
|
||||
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen")
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop"
|
||||
COMPONENT "Freespace2")
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION ".")
|
||||
|
||||
add_custom_target(appimage
|
||||
COMMAND "${APPIMAGE_ASSISTANT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/fs2_open_${FSO_BINARY_SUFFIX}.AppImage")
|
||||
|
||||
add_dependencies(appimage install)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION "."
|
||||
COMPONENT "Freespace2")
|
||||
@@ -36,6 +36,7 @@ set(WARNING_FLAGS
|
||||
/wd4592 # "symbol will be dynamically initialized" is being generated by a compiler bug, see https://stackoverflow.com/a/34027257 for an explanation - m!m
|
||||
$<$<CONFIG:Release>:/wd4101> # In release mode there are unreferenced variables because debug needs them
|
||||
/wd4995 # "'vsprintf': name was marked as #pragma deprecated" is being caused by our custom definition of vsprintf. I have no idea what causes this or how to fix it - m!m
|
||||
/wd4723 # "potential divide by 0" is caused by some code that definitely will not divide by zero - m!m
|
||||
)
|
||||
|
||||
target_compile_options(compiler INTERFACE ${WARNING_FLAGS})
|
||||
@@ -135,9 +136,9 @@ else()
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE
|
||||
_CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX "$<$<CONFIG:FastDebug>:_ITERATOR_DEBUG_LEVEL=0>")
|
||||
|
||||
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX
|
||||
"$<$<CONFIG:FastDebug>:_ITERATOR_DEBUG_LEVEL=0>" _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
|
||||
|
||||
if (FSO_FATAL_WARNINGS)
|
||||
# Make warnings fatal if the right variable is set
|
||||
target_compile_options(compiler INTERFACE "/WX")
|
||||
|
||||
@@ -39,6 +39,8 @@ target_link_libraries(code PUBLIC md5)
|
||||
|
||||
target_link_libraries(code PUBLIC discord-rpc)
|
||||
|
||||
target_link_libraries(code PUBLIC libRocket)
|
||||
|
||||
enable_clang_tidy(code)
|
||||
|
||||
IF (FSO_USE_SPEECH)
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace AI {
|
||||
Fix_heat_seeker_stealth_bug,
|
||||
Fix_linked_primary_bug,
|
||||
Force_beam_turret_fov,
|
||||
Free_afterburner_use,
|
||||
Glide_decay_requires_thrust,
|
||||
Hack_improve_non_homing_swarm_turret_fire_accuracy,
|
||||
Huge_turret_weapons_ignore_bombs,
|
||||
|
||||
@@ -357,6 +357,8 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$smart afterburner management:", AI::Profile_Flags::Smart_afterburner_management);
|
||||
|
||||
set_flag(profile, "$free afterburner use:", AI::Profile_Flags::Free_afterburner_use);
|
||||
|
||||
set_flag(profile, "$allow rapid secondary dumbfire:", AI::Profile_Flags::Allow_rapid_secondary_dumbfire);
|
||||
|
||||
set_flag(profile, "$huge turret weapons ignore bombs:", AI::Profile_Flags::Huge_turret_weapons_ignore_bombs);
|
||||
|
||||
+2
-2
@@ -642,7 +642,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
accelerate_ship(aip, 1.0f);
|
||||
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (dot_to_enemy > 0.75f)) {
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (dot_to_enemy > 0.75f)) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
@@ -684,7 +684,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
accelerate_ship(aip, accel);
|
||||
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
|
||||
+8
-6
@@ -745,6 +745,8 @@ void parse_ai_class()
|
||||
|
||||
set_aic_flag(aicp, "$smart afterburner management:", AI::Profile_Flags::Smart_afterburner_management);
|
||||
|
||||
set_aic_flag(aicp, "$free afterburner use:", AI::Profile_Flags::Free_afterburner_use);
|
||||
|
||||
set_aic_flag(aicp, "$allow rapid secondary dumbfire:", AI::Profile_Flags::Allow_rapid_secondary_dumbfire);
|
||||
|
||||
set_aic_flag(aicp, "$huge turret weapons ignore bombs:", AI::Profile_Flags::Huge_turret_weapons_ignore_bombs);
|
||||
@@ -1791,7 +1793,7 @@ float get_wing_lowest_av_ab_speed(object *objp)
|
||||
|
||||
wingnum = aip->wing;
|
||||
|
||||
if (((shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(sip->flags[Ship::Info_Flags::Afterburner])) || (shipp->current_max_speed < 5.0f) || (objp->phys_info.afterburner_max_vel.xyz.z <= shipp->current_max_speed) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
|
||||
if (((shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(sip->flags[Ship::Info_Flags::Afterburner])) || (shipp->current_max_speed < 5.0f) || (objp->phys_info.afterburner_max_vel.xyz.z <= shipp->current_max_speed) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
|
||||
lowest_max_av_ab_speed = shipp->current_max_speed;
|
||||
}
|
||||
else
|
||||
@@ -1816,7 +1818,7 @@ float get_wing_lowest_av_ab_speed(object *objp)
|
||||
if ((oaip->mode == AIM_WAYPOINTS) && (oaip->wing == wingnum) && (oaip->ai_flags[AI::AI_Flags::Formation_object, AI::AI_Flags::Formation_wing])) {
|
||||
|
||||
float cur_max;
|
||||
if ((oshipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(osip->flags[Ship::Info_Flags::Afterburner]) || (o->phys_info.afterburner_max_vel.xyz.z <= oshipp->current_max_speed) || !(oaip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
|
||||
if ((oshipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(osip->flags[Ship::Info_Flags::Afterburner]) || (o->phys_info.afterburner_max_vel.xyz.z <= oshipp->current_max_speed) || !(oaip->ai_flags[AI::AI_Flags::Free_afterburner_use] || oaip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
|
||||
cur_max = oshipp->current_max_speed;
|
||||
}
|
||||
else
|
||||
@@ -4413,7 +4415,7 @@ void ai_fly_to_target_position(vec3d* target_pos, bool* pl_done_p=NULL, bool* pl
|
||||
ab_allowed = false;
|
||||
}
|
||||
|
||||
if (!(sip->flags[Ship::Info_Flags::Afterburner]) || (shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
|
||||
if (!(sip->flags[Ship::Info_Flags::Afterburner]) || (shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
|
||||
ab_allowed = false;
|
||||
}
|
||||
|
||||
@@ -9943,7 +9945,7 @@ void ai_big_guard()
|
||||
ai_turn_towards_vector(&goal_pt, Pl_objp, Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time, nullptr, nullptr, 0.0f, 0);
|
||||
accelerate_ship(aip, 1.0f);
|
||||
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (cur_guard_rad > 1.1f * max_guard_dist)) {
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (cur_guard_rad > 1.1f * max_guard_dist)) {
|
||||
vec3d v2g;
|
||||
float dot_to_goal_point;
|
||||
|
||||
@@ -10066,7 +10068,7 @@ void ai_guard()
|
||||
compute_desired_rvec(&rvec, &goal_point, &Pl_objp->pos);
|
||||
ai_turn_towards_vector(&goal_point, Pl_objp, Ship_info[shipp->ship_info_index].srotation_time, nullptr, nullptr, 0.0f, 0, &rvec);
|
||||
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel_scale * (0.25f + dist_to_goal_point/700.0f) > 0.8f)) {
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel_scale * (0.25f + dist_to_goal_point/700.0f) > 0.8f)) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
@@ -11784,7 +11786,7 @@ int ai_formation()
|
||||
|
||||
ship_info *sip = &Ship_info[shipp->ship_info_index];
|
||||
bool ab_allowed = false;
|
||||
if ((sip->flags[Ship::Info_Flags::Afterburner]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (aip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
|
||||
if ((sip->flags[Ship::Info_Flags::Afterburner]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
|
||||
ab_allowed = true;
|
||||
} else {
|
||||
if (Pl_objp->phys_info.flags & PF_AFTERBURNER_ON)
|
||||
|
||||
@@ -1874,7 +1874,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
turret->last_fired_weapon_info_index = turret_weapon_class;
|
||||
|
||||
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", nullptr, "Beam", objp, "Target", &Objects[turret->turret_enemy_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[parent_objnum]);
|
||||
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
|
||||
}
|
||||
|
||||
@@ -2009,7 +2009,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
wp->turret_subsys = turret;
|
||||
|
||||
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", objp, "Beam", nullptr, "Target", &Objects[turret->turret_enemy_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[parent_objnum]);
|
||||
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
|
||||
|
||||
// if the gun is a flak gun
|
||||
@@ -2126,7 +2126,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
tsi->turret->last_fired_weapon_info_index = tsi->weapon_class;
|
||||
|
||||
Script_system.SetHookObjects(4, "Ship", &Objects[tsi->parent_objnum], "Weapon", &Objects[weapon_objnum], "Beam", nullptr, "Target", &Objects[tsi->turret->turret_enemy_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[tsi->parent_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[tsi->parent_objnum]);
|
||||
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
|
||||
|
||||
// muzzle flash?
|
||||
|
||||
@@ -1547,7 +1547,7 @@ static void asteroid_maybe_break_up(object *pasteroid_obj)
|
||||
}
|
||||
asp->final_death_time = timestamp(-1);
|
||||
}
|
||||
Script_system.RunCondition(CHA_DEATH, '\0', NULL, pasteroid_obj);
|
||||
Script_system.RunCondition(CHA_DEATH, pasteroid_obj);
|
||||
Script_system.RemHookVar("Self");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1892,6 +1892,7 @@ int bm_load_sub_slow(const char *real_filename, const int num_ext, const char **
|
||||
}
|
||||
|
||||
// umm, that's not good...
|
||||
Warning(LOCATION, "Could not open file %s!", res.full_name.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -962,7 +962,7 @@ size_t cam_get_num()
|
||||
/**
|
||||
* Looks up camera by name, returns -1 on failure
|
||||
*/
|
||||
camid cam_lookup(char *name)
|
||||
camid cam_lookup(const char* name)
|
||||
{
|
||||
size_t i, size=Cameras.size();
|
||||
for(i = 0; i < size; i++)
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time = 0.0f);
|
||||
|
||||
//Get
|
||||
char *get_name() {return name;}
|
||||
const char* get_name() { return name; }
|
||||
int get_signature() {return sig;}
|
||||
object *get_object_host();
|
||||
int get_object_host_submodel();
|
||||
@@ -163,7 +163,7 @@ camid cam_create(const char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_obje
|
||||
void cam_delete(camid cid);
|
||||
bool cam_set_camera(camid cid);
|
||||
void cam_reset_camera();
|
||||
camid cam_lookup(char *name);
|
||||
camid cam_lookup(const char* name);
|
||||
camid cam_get_camera(uint index);
|
||||
camid cam_get_current();
|
||||
size_t cam_get_num();
|
||||
|
||||
+47
-2
@@ -77,8 +77,8 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_PLAYERS, "data" DIR_SEPARATOR_STR "players", ".hcf", CF_TYPE_DATA },
|
||||
{ CF_TYPE_PLAYER_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "images", ".pcx .png .dds", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css .json", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr .json", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
|
||||
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .dds .fs2 .txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
|
||||
@@ -89,6 +89,8 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FREDDOCS, "data" DIR_SEPARATOR_STR "freddocs", ".html", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTERFACE_MARKUP, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "markup", ".rml", CF_TYPE_INTERFACE },
|
||||
{ CF_TYPE_INTERFACE_CSS, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "css", ".rcss", CF_TYPE_INTERFACE },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -1348,6 +1350,19 @@ void cfread_string_len(char *buf,int n, CFILE *file)
|
||||
buf[len] = 0;
|
||||
}
|
||||
|
||||
SCP_string cfread_string_len(CFILE *file)
|
||||
{
|
||||
int len = cfread_int(file);
|
||||
|
||||
SCP_string str;
|
||||
str.resize(len);
|
||||
|
||||
if (len)
|
||||
cfread(&str[0], len, 1, file);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// equivalent write functions of above read functions follow
|
||||
|
||||
int cfwrite_float(float f, CFILE *file)
|
||||
@@ -1961,3 +1976,33 @@ int cflush(CFILE *cfile)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int cfile_get_path_type(const SCP_string& dir)
|
||||
{
|
||||
SCP_string buf = dir;
|
||||
|
||||
// Remove trailing slashes; avoid buffer overflow on 1-char strings
|
||||
while (buf.size() > 0 && (buf[buf.size() - 1] == '\\' || buf[buf.size() - 1] == '/')) {
|
||||
buf.resize(buf.size() - 1);
|
||||
}
|
||||
|
||||
// Remove leading slashes
|
||||
while (buf.size() > 0 && (buf[0] == '\\' || buf[0] == '/')) {
|
||||
buf = buf.substr(1);
|
||||
}
|
||||
|
||||
// Use official DIR_SEPARATOR_CHAR
|
||||
for (char& c : buf) {
|
||||
if (c == '\\' || c == '/') {
|
||||
c = DIR_SEPARATOR_CHAR;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Pathtype : Pathtypes) {
|
||||
if (Pathtype.path != nullptr && buf == Pathtype.path) {
|
||||
return Pathtype.index;
|
||||
}
|
||||
}
|
||||
|
||||
return CF_TYPE_INVALID;
|
||||
}
|
||||
+13
-2
@@ -79,9 +79,11 @@ typedef struct {
|
||||
#define CF_TYPE_SCRIPTS 35
|
||||
#define CF_TYPE_FICTION 36
|
||||
#define CF_TYPE_FREDDOCS 37
|
||||
#define CF_TYPE_INTERFACE_MARKUP 38
|
||||
#define CF_TYPE_INTERFACE_CSS 39
|
||||
|
||||
#define CF_MAX_PATH_TYPES 38 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
#define CF_MAX_PATH_TYPES \
|
||||
40 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
// TRUE if type is specified and valid
|
||||
#define CF_TYPE_SPECIFIED(path_type) (((path_type)>CF_TYPE_INVALID) && ((path_type)<CF_MAX_PATH_TYPES))
|
||||
@@ -343,6 +345,13 @@ void cfread_string(char *buf,int n, CFILE *file);
|
||||
*/
|
||||
void cfread_string_len(char *buf,int n, CFILE *file);
|
||||
|
||||
/**
|
||||
* @brief Read a string from the file where the length is stored in the file
|
||||
* @param file The file to read the string from
|
||||
* @return The string that was read
|
||||
*/
|
||||
SCP_string cfread_string_len(CFILE *file);
|
||||
|
||||
// functions for writing cfiles
|
||||
int cfwrite_char(char c, CFILE *file);
|
||||
int cfwrite_float(float f, CFILE *file);
|
||||
@@ -434,6 +443,8 @@ int cfile_push_chdir(int type);
|
||||
// restore directory on top of the stack
|
||||
int cfile_pop_dir();
|
||||
|
||||
int cfile_get_path_type(const SCP_string& dir);
|
||||
|
||||
namespace cfile
|
||||
{
|
||||
// exceptions and other errors
|
||||
|
||||
@@ -232,7 +232,6 @@ Flag exe_params[] =
|
||||
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
|
||||
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
|
||||
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
|
||||
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
|
||||
{ "-pofspew", "Generate all ibx files immediately", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
|
||||
{ "-tablecrcs", "Dump table CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
|
||||
{ "-missioncrcs", "Dump mission CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
|
||||
@@ -247,7 +246,6 @@ Flag exe_params[] =
|
||||
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
|
||||
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
|
||||
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
|
||||
{ "-json_pilot", "Dump pilot files in JSON format", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_pilot", },
|
||||
{ "-json_profiling", "Generate JSON profiling output", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_profiling", },
|
||||
{ "-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", },
|
||||
@@ -490,7 +488,6 @@ cmdline_parm frame_profile_write_file("-profile_write_file", NULL, AT_NONE); //
|
||||
cmdline_parm no_unfocused_pause_arg("-no_unfocused_pause", NULL, AT_NONE); //Cmdline_no_unfocus_pause
|
||||
cmdline_parm benchmark_mode_arg("-benchmark_mode", NULL, AT_NONE); //Cmdline_benchmark_mode
|
||||
cmdline_parm noninteractive_arg("-noninteractive", NULL, AT_NONE); //Cmdline_noninteractive
|
||||
cmdline_parm json_pilot("-json_pilot", NULL, AT_NONE); //Cmdline_json_pilot
|
||||
cmdline_parm json_profiling("-json_profiling", NULL, AT_NONE); //Cmdline_json_profiling
|
||||
cmdline_parm show_video_info("-show_video_info", NULL, AT_NONE); //Cmdline_show_video_info
|
||||
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
|
||||
@@ -521,7 +518,6 @@ bool Cmdline_profile_write_file = false;
|
||||
bool Cmdline_no_unfocus_pause = false;
|
||||
bool Cmdline_benchmark_mode = false;
|
||||
bool Cmdline_noninteractive = false;
|
||||
bool Cmdline_json_pilot = false;
|
||||
bool Cmdline_json_profiling = false;
|
||||
bool Cmdline_frame_profile = false;
|
||||
bool Cmdline_show_video_info = false;
|
||||
@@ -2088,11 +2084,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_noninteractive = true;
|
||||
}
|
||||
|
||||
if (json_pilot.found())
|
||||
{
|
||||
Cmdline_json_pilot = true;
|
||||
}
|
||||
|
||||
if (json_profiling.found())
|
||||
{
|
||||
Cmdline_json_profiling = true;
|
||||
|
||||
@@ -156,7 +156,6 @@ extern bool Cmdline_profile_write_file;
|
||||
extern bool Cmdline_no_unfocus_pause;
|
||||
extern bool Cmdline_benchmark_mode;
|
||||
extern bool Cmdline_noninteractive;
|
||||
extern bool Cmdline_json_pilot;
|
||||
extern bool Cmdline_json_profiling;
|
||||
extern bool Cmdline_frame_profile;
|
||||
extern bool Cmdline_show_video_info;
|
||||
|
||||
@@ -2345,7 +2345,7 @@ int check_control(int id, int key)
|
||||
// which has just been released
|
||||
|
||||
Script_system.SetHookVar("Action", 's', Control_config[id].text);
|
||||
Script_system.RunCondition(CHA_ONACTIONSTOPPED, '\0', NULL, NULL, id);
|
||||
Script_system.RunCondition(CHA_ONACTIONSTOPPED, nullptr, id);
|
||||
Script_system.RemHookVar("Action");
|
||||
|
||||
Control_config[id].continuous_ongoing = false;
|
||||
@@ -2419,7 +2419,7 @@ void control_used(int id)
|
||||
if (Control_config[id].used < Last_frame_timestamp) {
|
||||
if (!Control_config[id].continuous_ongoing) {
|
||||
Script_system.SetHookVar("Action", 's', Control_config[id].text);
|
||||
Script_system.RunCondition(CHA_ONACTION, '\0', NULL, NULL, id);
|
||||
Script_system.RunCondition(CHA_ONACTION, nullptr, id);
|
||||
Script_system.RemHookVar("Action");
|
||||
|
||||
if (Control_config[id].type == CC_TYPE_CONTINUOUS)
|
||||
|
||||
@@ -314,6 +314,11 @@ std::unique_ptr<DecoderStatus> initializeStatus(std::unique_ptr<InputStream>& st
|
||||
|
||||
status->videoCodecPars = getCodecParameters(status->videoStream);
|
||||
|
||||
if (properties.looping && status->videoCodecPars.codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {
|
||||
mprintf(("FFmpeg: Looping is not supported for inteplay (MVE) movies!\n"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int err;
|
||||
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(57, 24, 255)
|
||||
status->videoCodecCtx = avcodec_alloc_context3(status->videoCodec);
|
||||
@@ -448,7 +453,7 @@ bool FFMPEGDecoder::initialize(const SCP_string& fileName, const PlaybackPropert
|
||||
{
|
||||
SCP_string movieName = fileName;
|
||||
// First make the file name lower case
|
||||
std::transform(movieName.begin(), movieName.end(), movieName.begin(), ::tolower);
|
||||
std::transform(movieName.begin(), movieName.end(), movieName.begin(), [](char c) { return (char)::tolower(c); });
|
||||
|
||||
// Then remove the extension
|
||||
size_t dotPos = movieName.find('.');
|
||||
@@ -518,13 +523,18 @@ void FFMPEGDecoder::startDecoding() {
|
||||
auto ctx = m_input->m_ctx->ctx();
|
||||
AVPacket packet;
|
||||
do {
|
||||
auto seek_err = av_seek_frame(ctx, -1, 0, AVSEEK_FLAG_BACKWARD);
|
||||
if (seek_err < 0) {
|
||||
char errorStr[512];
|
||||
av_strerror(seek_err, errorStr, sizeof(errorStr));
|
||||
mprintf(("FFMPEG: Failed to seek to start of movie file! Error: %s\n", errorStr));
|
||||
break;
|
||||
if (m_properties.looping) {
|
||||
// Only seek if we are looping the movie. The MVE code doesn't support seeking to this function may not be
|
||||
// called there
|
||||
auto seek_err = av_seek_frame(ctx, -1, 0, AVSEEK_FLAG_BACKWARD);
|
||||
if (seek_err < 0) {
|
||||
char errorStr[512];
|
||||
av_strerror(seek_err, errorStr, sizeof(errorStr));
|
||||
mprintf(("FFMPEG: Failed to seek to start of movie file! Error: %s\n", errorStr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
videoDecoder->flushBuffers();
|
||||
if (audioDecoder) {
|
||||
audioDecoder->flushBuffers();
|
||||
|
||||
+20
-13
@@ -44,21 +44,11 @@ struct PlaybackState {
|
||||
int subtitle_font = -1;
|
||||
};
|
||||
|
||||
void processEvents(PlaybackState* state) {
|
||||
void processEvents()
|
||||
{
|
||||
io::mouse::CursorManager::get()->showCursor(false);
|
||||
|
||||
os_poll();
|
||||
|
||||
int k = key_inkey();
|
||||
switch (k) {
|
||||
case KEY_ESC:
|
||||
case KEY_ENTER:
|
||||
case KEY_SPACEBAR:
|
||||
state->playing = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@@ -193,6 +183,21 @@ void movie_display_loop(Player* player, PlaybackState* state) {
|
||||
// We will sleep at most half the time a frame would be displayed
|
||||
auto sleepTime = static_cast<std::uint64_t>((1. / (4. * player->getMovieProperties().fps)) * 1000.);
|
||||
|
||||
auto listener = [state](const SDL_Event& event) {
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_KP_ENTER:
|
||||
case SDLK_RETURN:
|
||||
case SDLK_SPACE:
|
||||
state->playing = false;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
// Use a dedicated listener here since we want to listen for the KEYUP event
|
||||
auto key_handle = os::events::addEventListener(SDL_KEYUP, os::events::DEFAULT_LISTENER_WEIGHT - 10, listener);
|
||||
|
||||
auto lastDisplayTimestamp = timer_get_microseconds();
|
||||
while (state->playing) {
|
||||
TRACE_SCOPE(tracing::CutsceneStep);
|
||||
@@ -209,7 +214,7 @@ void movie_display_loop(Player* player, PlaybackState* state) {
|
||||
displayVideo(player, state);
|
||||
}
|
||||
|
||||
processEvents(state);
|
||||
processEvents();
|
||||
|
||||
if (passed < sleepTime) {
|
||||
auto sleep = sleepTime - passed;
|
||||
@@ -217,6 +222,8 @@ void movie_display_loop(Player* player, PlaybackState* state) {
|
||||
os_sleep(static_cast<uint>(sleep));
|
||||
}
|
||||
}
|
||||
|
||||
os::events::removeEventListener(key_handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,11 +24,15 @@ void main()
|
||||
// Now we compute the depth value in projection space using the clipping plane information
|
||||
float view_depth = 2.0 * zNear * zFar / (zFar + zNear - depth_normalized * (zFar - zNear));
|
||||
|
||||
// This is the same formula that is also used by the main shader
|
||||
float fog_dist = isinf(view_depth) ? 1.0 : clamp((view_depth - fog_start) * 0.75 * fog_scale, 0.0, 1.0);
|
||||
if (isinf(view_depth)) {
|
||||
fragOut0.rgb = color_in.rgb;
|
||||
} else {
|
||||
// This is the same formula that is also used by the main shader
|
||||
float fog_dist = clamp((view_depth - fog_start) * 0.75 * fog_scale, 0.0, 1.0);
|
||||
|
||||
vec3 finalFogColor = srgb_to_linear(fog_color);
|
||||
vec3 finalFogColor = srgb_to_linear(fog_color);
|
||||
|
||||
fragOut0.rgb = mix(color_in.rgb, finalFogColor, fog_dist);
|
||||
fragOut0.rgb = mix(color_in.rgb, finalFogColor, fog_dist);
|
||||
}
|
||||
fragOut0.a = 1.0;
|
||||
}
|
||||
@@ -280,11 +280,11 @@ void main()
|
||||
}
|
||||
if(gammaSpec) {
|
||||
specColor.rgb = max(specColor.rgb, vec3(0.03f)); // hardcoded minimum specular value. read John Hable's blog post titled 'Everything Is Shiny'.
|
||||
#ifdef FLAG_HDR
|
||||
specColor.rgb = srgb_to_linear(specColor.rgb);
|
||||
#endif
|
||||
fresnelFactor = 1.0;
|
||||
}
|
||||
#ifdef FLAG_HDR
|
||||
specColor.rgb = srgb_to_linear(specColor.rgb);
|
||||
#endif
|
||||
#endif
|
||||
baseColor.rgb *= aoFactors.y;
|
||||
specColor.rgb *= aoFactors.y;
|
||||
@@ -292,20 +292,29 @@ void main()
|
||||
#ifdef FLAG_TEAMCOLOR
|
||||
vec4 teamMask = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
teamMask = texture(sMiscmap, vec3(texCoord, float(sMiscmapIndex)));
|
||||
|
||||
//For team colors applied to a diffuse or spec map, we assume that the base color of the diffuse
|
||||
//at this point is vec3(0.5). To get accurate results, we subtract 0.5 from the team colors
|
||||
vec3 team_color = ((base_color - vec3(0.5)) * teamMask.x) + ((stripe_color - vec3(0.5)) * teamMask.y);
|
||||
vec3 color_offset = vec3(-0.5) * (teamMask.x + teamMask.y);
|
||||
|
||||
vec3 team_color = base_color * teamMask.x + stripe_color * teamMask.y + color_offset;
|
||||
vec3 team_color_glow = (base_color * teamMask.b) + (stripe_color * teamMask.a);
|
||||
|
||||
#ifdef FLAG_HDR
|
||||
team_color = srgb_to_linear(team_color);
|
||||
team_color_glow = srgb_to_linear(team_color_glow) * GLOW_MAP_SRGB_MULTIPLIER;
|
||||
baseColor.rgb = linear_to_srgb(baseColor.rgb);
|
||||
specColor.rgb = linear_to_srgb(specColor.rgb);
|
||||
#endif
|
||||
|
||||
baseColor.rgb += team_color;
|
||||
baseColor.rgb = max(baseColor.rgb, vec3(0.0)); // We need to make sure that nothing here ever goes negative
|
||||
specColor.rgb += team_color;
|
||||
specColor.rgb = max(specColor.rgb, vec3(0.03));
|
||||
|
||||
#ifdef FLAG_HDR
|
||||
baseColor.rgb = srgb_to_linear(baseColor.rgb);
|
||||
specColor.rgb = srgb_to_linear(specColor.rgb);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// Lights aren't applied when we are rendering to the G-buffers since that gets handled later
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform bool textured;
|
||||
uniform sampler2DArray baseMap;
|
||||
uniform int baseMapIndex;
|
||||
|
||||
void main() {
|
||||
if (textured) {
|
||||
fragOut0 = texture(baseMap, vec3(fragTexCoord, float(baseMapIndex))) * fragColor;
|
||||
} else {
|
||||
fragOut0 = fragColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
in vec2 vertPosition;
|
||||
in vec4 vertColor;
|
||||
in vec2 vertTexCoord;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertTexCoord;
|
||||
fragColor = vertColor;
|
||||
|
||||
gl_Position = projMatrix * modelViewMatrix * vec4(vertPosition, 0.0, 1.0);
|
||||
}
|
||||
@@ -53,8 +53,11 @@ else()
|
||||
file(TO_NATIVE_PATH "${PATH_TYPE}" PATH_TYPE)
|
||||
if (MINGW)
|
||||
# There is a bug in CMake where it thinks MinGW uses forward slashes for paths but we need backslashes for Windows builds
|
||||
string(REPLACE "/" "\\\\" PATH_TYPE "${PATH_TYPE}")
|
||||
string(REPLACE "/" "\\" PATH_TYPE "${PATH_TYPE}")
|
||||
endif()
|
||||
# Properly escape back slashes in strings
|
||||
string(REPLACE "\\" "\\\\" PATH_TYPE "${PATH_TYPE}")
|
||||
|
||||
GET_FILENAME_COMPONENT(FILE_NAME "${RELATIVE_FILE_PATH}" NAME)
|
||||
|
||||
string(MAKE_C_IDENTIFIER "${RELATIVE_FILE_PATH}" FIELD_NAME)
|
||||
|
||||
+230
-166
@@ -26,18 +26,10 @@
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
// make use of the LOD checker for tbl/tbm parsing (from weapons.cpp)
|
||||
extern SCP_vector<lod_checker> LOD_checker;
|
||||
|
||||
static SCP_vector<color> LOD_color;
|
||||
|
||||
int Warp_model;
|
||||
int Knossos_warp_ani_used;
|
||||
|
||||
#define WARPHOLE_GROW_TIME (2.35f) // time for warphole to reach max size (also time to shrink to nothing once it begins to shrink)
|
||||
|
||||
#define MAX_FIREBALL_LOD 4
|
||||
|
||||
#define MAX_FIREBALLS 200
|
||||
|
||||
#define MAX_WARP_LOD 0
|
||||
@@ -51,10 +43,8 @@ int fireball_used[MAX_FIREBALL_TYPES];
|
||||
int Num_fireballs = 0;
|
||||
int Num_fireball_types = 0;
|
||||
|
||||
int fireballs_inited = 0;
|
||||
|
||||
int Warp_glow_bitmap = -1;
|
||||
int Warp_ball_bitmap = -1;
|
||||
bool fireballs_inited = false;
|
||||
bool fireballs_parsed = false;
|
||||
|
||||
#define FB_INDEX(fb) (fb-Fireballs)
|
||||
|
||||
@@ -114,12 +104,53 @@ void fireball_play_warphole_close_sound(fireball *fb)
|
||||
snd_play_3d(gamesnd_get_game_sound(sound_index), &fireball_objp->pos, &Eye_position, fireball_objp->radius); // play warp sound effect
|
||||
}
|
||||
|
||||
static void fireball_generate_unique_id(char *unique_id, int buffer_len, int fireball_index)
|
||||
{
|
||||
Assert((fireball_index >= 0) && (fireball_index < MAX_FIREBALL_TYPES));
|
||||
|
||||
switch (fireball_index)
|
||||
{
|
||||
// use sensible names for the fireball.tbl default entries
|
||||
case FIREBALL_EXPLOSION_MEDIUM:
|
||||
strncpy(unique_id, "Medium Explosion", buffer_len);
|
||||
break;
|
||||
|
||||
case FIREBALL_WARP:
|
||||
strncpy(unique_id, "Warp Effect", buffer_len);
|
||||
break;
|
||||
|
||||
case FIREBALL_KNOSSOS:
|
||||
strncpy(unique_id, "Knossos Effect", buffer_len);
|
||||
break;
|
||||
|
||||
case FIREBALL_ASTEROID:
|
||||
strncpy(unique_id, "Asteroid Explosion", buffer_len);
|
||||
break;
|
||||
|
||||
case FIREBALL_EXPLOSION_LARGE1:
|
||||
strncpy(unique_id, "Large Explosion 1", buffer_len);
|
||||
break;
|
||||
|
||||
case FIREBALL_EXPLOSION_LARGE2:
|
||||
strncpy(unique_id, "Large Explosion 2", buffer_len);
|
||||
break;
|
||||
|
||||
// base the id on the index
|
||||
default:
|
||||
snprintf(unique_id, buffer_len, "Custom Fireball %d", fireball_index - NUM_DEFAULT_FIREBALLS + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// null-terminate
|
||||
unique_id[buffer_len - 1] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default colors for each explosion type (original values from object.cpp)
|
||||
*/
|
||||
static void fireball_set_default_color(int idx)
|
||||
{
|
||||
Assert( (idx >= 0) && (idx < MAX_FIREBALL_TYPES) );
|
||||
Assert((idx >= 0) && (idx < MAX_FIREBALL_TYPES));
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
@@ -153,71 +184,148 @@ static void fireball_set_default_color(int idx)
|
||||
}
|
||||
}
|
||||
|
||||
static void fireball_set_default_warp_attributes(int idx)
|
||||
{
|
||||
Assert((idx >= 0) && (idx < MAX_FIREBALL_TYPES));
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case FIREBALL_WARP:
|
||||
case FIREBALL_KNOSSOS:
|
||||
strcpy_s(Fireball_info[idx].warp_glow, "warpglow01");
|
||||
strcpy_s(Fireball_info[idx].warp_ball, "warpball01");
|
||||
strcpy_s(Fireball_info[idx].warp_model, "warp.pof");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fireball_info_clear(fireball_info *fb)
|
||||
{
|
||||
Assert(fb != nullptr);
|
||||
memset(fb, 0, sizeof(fireball_info));
|
||||
|
||||
for (int i = 0; i < MAX_FIREBALL_LOD; ++i)
|
||||
fb->lod[i].bitmap_id = -1;
|
||||
|
||||
fb->warp_glow_bitmap = -1;
|
||||
fb->warp_ball_bitmap = -1;
|
||||
fb->warp_model_id = -1;
|
||||
}
|
||||
|
||||
int fireball_info_lookup(const char *unique_id)
|
||||
{
|
||||
for (int i = 0; i < Num_fireball_types; ++i)
|
||||
if (!stricmp(Fireball_info[i].unique_id, unique_id))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse fireball tbl
|
||||
*
|
||||
* NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
|
||||
*/
|
||||
void parse_fireball_tbl(const char *filename)
|
||||
static void parse_fireball_tbl(const char *table_filename)
|
||||
{
|
||||
lod_checker lod_check;
|
||||
color fb_color;
|
||||
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
read_file_text(table_filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Start");
|
||||
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
memset(&lod_check, 0, sizeof(lod_checker));
|
||||
while (required_string_one_of(3, "#End", "$Name:", "$Unique ID:"))
|
||||
{
|
||||
fireball_info *fi;
|
||||
int existing_idx = -1;
|
||||
char unique_id[NAME_LENGTH];
|
||||
char fireball_filename[MAX_FILENAME_LEN];
|
||||
|
||||
// unique ID, because indexes are unpredictable
|
||||
memset(unique_id, 0, NAME_LENGTH);
|
||||
if (optional_string("$Unique ID:"))
|
||||
stuff_string(unique_id, F_NAME, NAME_LENGTH);
|
||||
|
||||
// base filename
|
||||
required_string("$Name:");
|
||||
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
stuff_string(fireball_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
lod_check.override = -1;
|
||||
// find out if we are overriding a previous entry;
|
||||
// per precedent, these strings should only be in TBMs
|
||||
// UNLIKE precedent, we can now add fireballs in modular tables, not just replace them
|
||||
if (Parsing_modular_table)
|
||||
{
|
||||
if (optional_string("+Explosion_Medium"))
|
||||
existing_idx = FIREBALL_EXPLOSION_MEDIUM;
|
||||
else if (optional_string("+Warp_Effect"))
|
||||
existing_idx = FIREBALL_WARP;
|
||||
else if (optional_string("+Knossos_Effect"))
|
||||
existing_idx = FIREBALL_KNOSSOS;
|
||||
else if (optional_string("+Asteroid"))
|
||||
existing_idx = FIREBALL_ASTEROID;
|
||||
else if (optional_string("+Explosion_Large1"))
|
||||
existing_idx = FIREBALL_EXPLOSION_LARGE1;
|
||||
else if (optional_string("+Explosion_Large2"))
|
||||
existing_idx = FIREBALL_EXPLOSION_LARGE2;
|
||||
else if (optional_string("+Custom_Fireball"))
|
||||
stuff_int(&existing_idx);
|
||||
|
||||
// these entries should only be in TBMs, and it has to include at least one
|
||||
if (Parsing_modular_table) {
|
||||
if (optional_string("+Explosion_Medium")) {
|
||||
lod_check.override = FIREBALL_EXPLOSION_MEDIUM;
|
||||
}
|
||||
else if (optional_string("+Warp_Effect")) {
|
||||
lod_check.override = FIREBALL_WARP;
|
||||
}
|
||||
else if (optional_string("+Knossos_Effect")) {
|
||||
lod_check.override = FIREBALL_KNOSSOS;
|
||||
}
|
||||
else if (optional_string("+Asteroid")) {
|
||||
lod_check.override = FIREBALL_ASTEROID;
|
||||
}
|
||||
else if (optional_string("+Explosion_Large1")) {
|
||||
lod_check.override = FIREBALL_EXPLOSION_LARGE1;
|
||||
}
|
||||
else if (optional_string("+Explosion_Large2")){
|
||||
lod_check.override = FIREBALL_EXPLOSION_LARGE2;
|
||||
}
|
||||
else {
|
||||
required_string("+Custom_Fireball");
|
||||
stuff_int(&lod_check.override);
|
||||
// we can ALSO override a previous entry by specifying a previously used unique ID
|
||||
// either way will work, but if both are specified, unique ID takes precedence
|
||||
if (strlen(unique_id) > 0)
|
||||
{
|
||||
int temp_idx = fireball_info_lookup(unique_id);
|
||||
if (temp_idx >= 0)
|
||||
existing_idx = temp_idx;
|
||||
}
|
||||
}
|
||||
|
||||
lod_check.num_lods = 1;
|
||||
// now select our entry accordingly...
|
||||
// are we using a previous entry?
|
||||
if (existing_idx >= 0)
|
||||
{
|
||||
fi = &Fireball_info[existing_idx];
|
||||
}
|
||||
// we are creating a new entry, so set some defaults
|
||||
else
|
||||
{
|
||||
// make sure we don't exceed the max
|
||||
if (Num_fireball_types >= MAX_FIREBALL_TYPES)
|
||||
{
|
||||
error_display(0, "Too many fireball entries! Max is %d", MAX_FIREBALL_TYPES);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do we have an LOD num
|
||||
if (optional_string("$LOD:")) {
|
||||
stuff_int(&lod_check.num_lods);
|
||||
fi = &Fireball_info[Num_fireball_types];
|
||||
fireball_info_clear(fi);
|
||||
|
||||
// If the table didn't specify a unique ID, generate one. This will be assigned a few lines later.
|
||||
if (strlen(unique_id) == 0)
|
||||
fireball_generate_unique_id(unique_id, NAME_LENGTH, Num_fireball_types);
|
||||
|
||||
// Set remaining fireball defaults
|
||||
fireball_set_default_color(Num_fireball_types);
|
||||
fireball_set_default_warp_attributes(Num_fireball_types);
|
||||
|
||||
Num_fireball_types++;
|
||||
}
|
||||
|
||||
if (lod_check.num_lods > MAX_FIREBALL_LOD) {
|
||||
lod_check.num_lods = MAX_FIREBALL_LOD;
|
||||
// copy over what we already parsed
|
||||
if (strlen(unique_id) > 0)
|
||||
strcpy_s(fi->unique_id, unique_id);
|
||||
strcpy_s(fi->lod[0].filename, fireball_filename);
|
||||
|
||||
// Do we have a LOD num?
|
||||
if (optional_string("$LOD:"))
|
||||
{
|
||||
stuff_int(&fi->lod_count);
|
||||
|
||||
if (fi->lod_count > MAX_FIREBALL_LOD)
|
||||
fi->lod_count = MAX_FIREBALL_LOD;
|
||||
}
|
||||
|
||||
// check for particular lighting color
|
||||
if (optional_string("$Light color:")) {
|
||||
if (optional_string("$Light color:"))
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
stuff_int(&r);
|
||||
@@ -228,90 +336,57 @@ void parse_fireball_tbl(const char *filename)
|
||||
CLAMP(g, 0, 255);
|
||||
CLAMP(b, 0, 255);
|
||||
|
||||
gr_init_color(&fb_color, r, g, b);
|
||||
}
|
||||
else {
|
||||
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
|
||||
memset(&fb_color, 0, sizeof(color));
|
||||
fi->exp_color[0] = (r / 255.0f);
|
||||
fi->exp_color[1] = (g / 255.0f);
|
||||
fi->exp_color[2] = (b / 255.0f);
|
||||
}
|
||||
|
||||
// we may use one filename for multiple entries so we'll have to handle dupes post parse
|
||||
LOD_checker.push_back(lod_check);
|
||||
LOD_color.push_back(fb_color);
|
||||
// check for custom warp glow
|
||||
if (optional_string("$Warp glow:"))
|
||||
stuff_string(fi->warp_glow, F_NAME, NAME_LENGTH);
|
||||
|
||||
// check for custom warp ball
|
||||
if (optional_string("$Warp ball:"))
|
||||
stuff_string(fi->warp_ball, F_NAME, NAME_LENGTH);
|
||||
|
||||
// check for custom warp model
|
||||
if (optional_string("$Warp model:"))
|
||||
stuff_string(fi->warp_model, F_NAME, NAME_LENGTH);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", table_filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void fireball_parse_tbl()
|
||||
{
|
||||
int i = 0, j;
|
||||
SCP_vector<lod_checker>::iterator lod;
|
||||
|
||||
memset( &Fireball_info, 0, sizeof(fireball_info) * MAX_FIREBALL_TYPES );
|
||||
if (fireballs_parsed)
|
||||
return;
|
||||
|
||||
// every newly parsed fireball_info will get cleared before being added
|
||||
// must do this outside of parse_fireball_tbl because it's called twice
|
||||
Num_fireball_types = 0;
|
||||
|
||||
parse_fireball_tbl("fireball.tbl");
|
||||
|
||||
// look for any modular tables
|
||||
parse_modular_table(NOX("*-fbl.tbm"), parse_fireball_tbl);
|
||||
|
||||
// we've got our list so pass it off for final checking and loading.
|
||||
// we assume that entries in fireball.tbl are in the correct order
|
||||
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
|
||||
if ( (i < MAX_FIREBALL_TYPES) && (lod->override < 0) ) {
|
||||
strcpy_s( Fireball_info[i].lod[0].filename, lod->filename );
|
||||
Fireball_info[i].lod_count = lod->num_lods;
|
||||
Num_fireball_types++;
|
||||
|
||||
if (LOD_color[i].alpha == 255) {
|
||||
Fireball_info[i].exp_color[0] = (LOD_color[i].red / 255.0f);
|
||||
Fireball_info[i].exp_color[1] = (LOD_color[i].green / 255.0f);
|
||||
Fireball_info[i].exp_color[2] = (LOD_color[i].blue / 255.0f);
|
||||
} else {
|
||||
fireball_set_default_color(i);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// having to do this twice is less than optimal, but less error prone too.
|
||||
// this handles (and should only have to handle) TBM related entries
|
||||
i = 0;
|
||||
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
|
||||
// try entry replacement
|
||||
if ( (lod->override >= 0) && (lod->override < Num_fireball_types) ) {
|
||||
strcpy_s( Fireball_info[lod->override].lod[0].filename, lod->filename );
|
||||
Fireball_info[lod->override].lod_count = lod->num_lods;
|
||||
|
||||
if (LOD_color[i].alpha == 255) {
|
||||
Fireball_info[lod->override].exp_color[0] = (LOD_color[i].red / 255.0f);
|
||||
Fireball_info[lod->override].exp_color[1] = (LOD_color[i].green / 255.0f);
|
||||
Fireball_info[lod->override].exp_color[2] = (LOD_color[i].blue / 255.0f);
|
||||
} else {
|
||||
fireball_set_default_color(lod->override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill in extra LOD filenames
|
||||
for (i = 0; i < Num_fireball_types; i++) {
|
||||
for (j = 1; j < Fireball_info[i].lod_count; j++) {
|
||||
for (int i = 0; i < Num_fireball_types; i++)
|
||||
{
|
||||
for (int j = 1; j < Fireball_info[i].lod_count; j++)
|
||||
sprintf( Fireball_info[i].lod[j].filename, "%s_%d", Fireball_info[i].lod[0].filename, j);
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
LOD_checker.clear();
|
||||
fireballs_parsed = true;
|
||||
}
|
||||
|
||||
|
||||
void fireball_load_data()
|
||||
{
|
||||
int i, idx;
|
||||
@@ -330,13 +405,20 @@ void fireball_load_data()
|
||||
Error(LOCATION, "Could not load %s anim file\n", fd->lod[idx].filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( Warp_glow_bitmap == -1 ) {
|
||||
Warp_glow_bitmap = bm_load( NOX("warpglow01") );
|
||||
}
|
||||
if ( Warp_ball_bitmap == -1 ) {
|
||||
Warp_ball_bitmap = bm_load( NOX("warpball01") );
|
||||
if (strlen(fd->warp_glow) > 0) {
|
||||
mprintf(("Loading warp glow '%s'\n", fd->warp_glow));
|
||||
fd->warp_glow_bitmap = bm_load(fd->warp_glow);
|
||||
} else {
|
||||
fd->warp_glow_bitmap = -1;
|
||||
}
|
||||
|
||||
if (strlen(fd->warp_ball) > 0) {
|
||||
mprintf(("Loading warp ball '%s'\n", fd->warp_ball));
|
||||
fd->warp_ball_bitmap = bm_load(fd->warp_ball);
|
||||
} else {
|
||||
fd->warp_ball_bitmap = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,11 +428,11 @@ void fireball_init()
|
||||
int i;
|
||||
|
||||
if ( !fireballs_inited ) {
|
||||
fireballs_inited = 1;
|
||||
|
||||
// Do all the processing that happens only once
|
||||
fireball_parse_tbl();
|
||||
fireball_load_data();
|
||||
|
||||
fireballs_inited = true;
|
||||
}
|
||||
|
||||
// Reset everything between levels
|
||||
@@ -361,17 +443,6 @@ void fireball_init()
|
||||
|
||||
// Goober5000 - reset Knossos warp flag
|
||||
Knossos_warp_ani_used = 0;
|
||||
|
||||
mprintf(("Loading warp model\n"));
|
||||
Warp_model = -1;
|
||||
|
||||
// Goober5000 - check for existence of file before trying to load it
|
||||
if (cf_exists_full("warp.pof", CF_TYPE_MODELS))
|
||||
{
|
||||
Warp_model = model_load("warp.pof", 0, NULL, 0);
|
||||
}
|
||||
|
||||
mprintf((" %d\n", Warp_model));
|
||||
}
|
||||
|
||||
MONITOR( NumFireballsRend )
|
||||
@@ -543,7 +614,7 @@ void fireball_maybe_play_warp_close_sound(fireball *fb)
|
||||
|
||||
life_left = fb->total_time - fb->time_elapsed;
|
||||
|
||||
if ( life_left < WARPHOLE_GROW_TIME ) {
|
||||
if ( life_left < fb->warp_close_duration ) {
|
||||
fireball_play_warphole_close_sound(fb);
|
||||
fb->flags |= FBF_WARP_CLOSE_SOUND_PLAYED;
|
||||
}
|
||||
@@ -696,7 +767,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)
|
||||
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 n, objnum, fb_lod;
|
||||
object *obj;
|
||||
@@ -757,6 +828,8 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
fb->flags = extra_flags;
|
||||
fb->warp_open_sound_index = warp_open_sound;
|
||||
fb->warp_close_sound_index = warp_close_sound;
|
||||
fb->warp_open_duration = (warp_open_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_open_duration;
|
||||
fb->warp_close_duration = (warp_close_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_close_duration;
|
||||
|
||||
matrix orient;
|
||||
if(orient_override != NULL){
|
||||
@@ -861,9 +934,9 @@ void fireballs_page_in()
|
||||
fireball_info *fd;
|
||||
|
||||
for ( i = 0; i < Num_fireball_types; i++ ) {
|
||||
if((i < NUM_DEFAULT_FIREBALLS) || fireball_used[i]){
|
||||
fd = &Fireball_info[i];
|
||||
fd = &Fireball_info[i];
|
||||
|
||||
if((i < NUM_DEFAULT_FIREBALLS) || fireball_used[i]) {
|
||||
// if this is a Knossos ani, only load if Knossos_warp_ani_used is true
|
||||
if ( (i == FIREBALL_KNOSSOS) && !Knossos_warp_ani_used)
|
||||
continue;
|
||||
@@ -876,10 +949,19 @@ void fireballs_page_in()
|
||||
bm_page_in_texture( fd->lod[idx].bitmap_id, fd->lod[idx].num_frames );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bm_page_in_texture( Warp_glow_bitmap );
|
||||
bm_page_in_texture( Warp_ball_bitmap );
|
||||
// page in glow and ball bitmaps, if we have any
|
||||
bm_page_in_texture(fd->warp_glow_bitmap);
|
||||
bm_page_in_texture(fd->warp_ball_bitmap);
|
||||
|
||||
// load the warp model, if we have one
|
||||
if (strlen(fd->warp_model) > 0 && cf_exists_full(fd->warp_model, CF_TYPE_MODELS)) {
|
||||
mprintf(("Loading warp model '%s'\n", fd->warp_model));
|
||||
fd->warp_model_id = model_load(fd->warp_model, 0, nullptr, 0);
|
||||
} else {
|
||||
fd->warp_model_id = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fireball_get_color(int idx, float *red, float *green, float *blue)
|
||||
@@ -941,30 +1023,23 @@ int fireball_asteroid_explosion_type(asteroid_info *aip)
|
||||
return index;
|
||||
}
|
||||
|
||||
float fireball_wormhole_intensity( object *obj )
|
||||
float fireball_wormhole_intensity(fireball *fb)
|
||||
{
|
||||
int num, objnum;
|
||||
fireball *fb;
|
||||
|
||||
num = obj->instance;
|
||||
objnum = OBJ_INDEX(obj);
|
||||
Assertion( Fireballs[num].objnum == objnum, "Basic sanity check. Fireballs[num].objnum (%d) should == objnum (%d)", Fireballs[num].objnum, objnum );
|
||||
|
||||
fb = &Fireballs[num];
|
||||
|
||||
float t = fb->time_elapsed;
|
||||
float rad;
|
||||
|
||||
if ( t < WARPHOLE_GROW_TIME ) {
|
||||
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f);
|
||||
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
|
||||
rad = 1;
|
||||
if ( t < fb->warp_open_duration ) {
|
||||
rad = (float)pow(t / fb->warp_open_duration, 0.4f);
|
||||
} else if ( t < fb->total_time - fb->warp_close_duration ) {
|
||||
rad = 1.0f;
|
||||
} else {
|
||||
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f);
|
||||
rad = (float)pow((fb->total_time - t) / fb->warp_close_duration, 0.4f);
|
||||
}
|
||||
return rad;
|
||||
}
|
||||
|
||||
extern void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, bool warp_3d, int warp_glow_bitmap, int warp_ball_bitmap, int warp_model_id);
|
||||
|
||||
void fireball_render(object* obj, model_draw_list *scene)
|
||||
{
|
||||
int num;
|
||||
@@ -996,21 +1071,10 @@ void fireball_render(object* obj, model_draw_list *scene)
|
||||
|
||||
case FIREBALL_WARP_EFFECT: {
|
||||
float percent_life = fb->time_elapsed / fb->total_time;
|
||||
float rad = obj->radius * fireball_wormhole_intensity(fb);
|
||||
|
||||
float rad;
|
||||
|
||||
// Code to make effect grow/shrink.
|
||||
float t = fb->time_elapsed;
|
||||
|
||||
if ( t < WARPHOLE_GROW_TIME ) {
|
||||
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
|
||||
rad = obj->radius;
|
||||
} else {
|
||||
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
}
|
||||
|
||||
warpin_queue_render(scene, obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
|
||||
fireball_info *fi = &Fireball_info[fb->fireball_info_index];
|
||||
warpin_queue_render(scene, obj, &obj->orient, &obj->pos, fb->current_bitmap, rad, percent_life, obj->radius, (fb->flags & FBF_WARP_3D) != 0, fi->warp_glow_bitmap, fi->warp_ball_bitmap, fi->warp_model_id);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+28
-14
@@ -36,10 +36,11 @@ class asteroid_info;
|
||||
#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
|
||||
#define NUM_DEFAULT_FIREBALLS 6
|
||||
|
||||
#define MAX_FIREBALL_LOD 4
|
||||
|
||||
#define FIREBALL_NUM_LARGE_EXPLOSIONS 2
|
||||
|
||||
extern int fireball_used[MAX_FIREBALL_TYPES];
|
||||
extern int Num_fireball_types;
|
||||
|
||||
// all this moved here by Goober5000 because it makes more sense in the H file
|
||||
typedef struct fireball_lod {
|
||||
@@ -50,11 +51,22 @@ typedef struct fireball_lod {
|
||||
} fireball_lod;
|
||||
|
||||
typedef struct fireball_info {
|
||||
char unique_id[NAME_LENGTH];
|
||||
int lod_count;
|
||||
float exp_color[3];
|
||||
fireball_lod lod[4];
|
||||
fireball_lod lod[MAX_FIREBALL_LOD];
|
||||
float exp_color[3]; // red, green, blue
|
||||
|
||||
char warp_glow[NAME_LENGTH];
|
||||
int warp_glow_bitmap;
|
||||
char warp_ball[NAME_LENGTH];
|
||||
int warp_ball_bitmap;
|
||||
char warp_model[NAME_LENGTH];
|
||||
int warp_model_id;
|
||||
} fireball_info;
|
||||
|
||||
extern fireball_info Fireball_info[MAX_FIREBALL_TYPES];
|
||||
extern int Num_fireball_types;
|
||||
|
||||
// flag values for fireball struct flags member
|
||||
#define FBF_WARP_CLOSE_SOUND_PLAYED (1<<0)
|
||||
#define FBF_WARP_CAPITAL_SIZE (1<<1)
|
||||
@@ -72,8 +84,12 @@ typedef struct fireball {
|
||||
char lod; // current LOD
|
||||
float time_elapsed; // in seconds
|
||||
float total_time; // total lifetime of animation in seconds
|
||||
gamesnd_id warp_open_sound_index; // for warp-effect - Goober5000
|
||||
gamesnd_id warp_close_sound_index; // for warp-effect - Goober5000
|
||||
|
||||
// for warp-effect - Goober5000
|
||||
gamesnd_id warp_open_sound_index;
|
||||
gamesnd_id warp_close_sound_index;
|
||||
float warp_open_duration;
|
||||
float warp_close_duration;
|
||||
} fireball;
|
||||
// end move
|
||||
|
||||
@@ -82,10 +98,15 @@ void fireball_render(object* obj, model_draw_list *scene);
|
||||
void fireball_delete( object * obj );
|
||||
void fireball_process_post(object * obj, float frame_time);
|
||||
|
||||
// This does not load all the data, just the filenames and such. Only used by FRED.
|
||||
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.
|
||||
// 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=NULL, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=NULL, int low_res=0, int extra_flags=0, gamesnd_id warp_open_sound=gamesnd_id(), gamesnd_id warp_close_sound=gamesnd_id());
|
||||
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);
|
||||
void fireball_close();
|
||||
|
||||
@@ -111,14 +132,7 @@ int fireball_ship_explosion_type(ship_info *sip);
|
||||
int fireball_asteroid_explosion_type(asteroid_info *aip);
|
||||
|
||||
// returns the intensity of a wormhole
|
||||
float fireball_wormhole_intensity( object *obj );
|
||||
|
||||
// internal function to draw warp grid.
|
||||
extern void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d = 0 );
|
||||
|
||||
extern void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d);
|
||||
|
||||
extern int Warp_model;
|
||||
float fireball_wormhole_intensity( fireball *fb );
|
||||
|
||||
// Goober5000
|
||||
extern int Knossos_warp_ani_used;
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
#include "render/batching.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
extern int Warp_model;
|
||||
extern int Warp_glow_bitmap;
|
||||
extern int Warp_ball_bitmap;
|
||||
|
||||
void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
|
||||
{
|
||||
vec3d norm;
|
||||
@@ -45,7 +41,7 @@ void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
|
||||
batching_add_tri(texture, vertlist); // TODO render as emissive
|
||||
}
|
||||
|
||||
void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, bool warp_3d, int warp_glow_bitmap, int warp_ball_bitmap, int warp_model_id)
|
||||
{
|
||||
vec3d center;
|
||||
vec3d vecs[5];
|
||||
@@ -60,7 +56,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
|
||||
|
||||
verts[1] = verts[2] = verts[3] = verts[4] = verts[0];
|
||||
|
||||
if (Warp_glow_bitmap >= 0) {
|
||||
if (warp_glow_bitmap >= 0) {
|
||||
float r = radius;
|
||||
bool render_it = true;
|
||||
|
||||
@@ -99,12 +95,12 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
|
||||
|
||||
float alpha = (The_mission.flags[Mission::Mission_Flags::Fullneb]) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
|
||||
|
||||
//batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
|
||||
batching_add_bitmap(Warp_glow_bitmap, &verts[4], 0, r, alpha);
|
||||
//batch_add_bitmap(warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
|
||||
batching_add_bitmap(warp_glow_bitmap, &verts[4], 0, r, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
if ( (warp_model_id >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
model_render_params render_info;
|
||||
|
||||
float scale = radius / 25.0f;
|
||||
@@ -119,7 +115,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
|
||||
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
|
||||
|
||||
model_render_queue( &render_info, scene, Warp_model, orient, pos);
|
||||
model_render_queue( &render_info, scene, warp_model_id, orient, pos);
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
@@ -171,14 +167,14 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[3], &verts[4] );
|
||||
}
|
||||
|
||||
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
|
||||
if (warp_ball_bitmap >= 0 && Cmdline_warp_flash) {
|
||||
flash_ball warp_ball(20, .1f,.25f, &orient->vec.fvec, pos, 4.0f, 0.5f);
|
||||
|
||||
float adg = (2.0f * life_percent) - 1.0f;
|
||||
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
|
||||
|
||||
if (pct > 0.00001f) {
|
||||
warp_ball.render(Warp_ball_bitmap, max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
warp_ball.render(warp_ball_bitmap, max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,9 +404,9 @@ int gameseq_process_events()
|
||||
state_reentry--;
|
||||
|
||||
return gs[gs_current_stack].current_state;
|
||||
}
|
||||
}
|
||||
|
||||
int gameseq_get_event_idx(char *s)
|
||||
int gameseq_get_event_idx(const char* s)
|
||||
{
|
||||
for(int i = 0; i < Num_gs_event_text; i++)
|
||||
{
|
||||
@@ -418,7 +418,7 @@ int gameseq_get_event_idx(char *s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gameseq_get_state_idx(char *s)
|
||||
int gameseq_get_state_idx(const char* s)
|
||||
{
|
||||
for(int i = 0; i < Num_gs_state_text; i++)
|
||||
{
|
||||
|
||||
@@ -197,8 +197,8 @@ void game_do_state(int current_state);
|
||||
bool GameState_Stack_Valid();
|
||||
|
||||
//WMC
|
||||
int gameseq_get_event_idx(char *s);
|
||||
int gameseq_get_state_idx(char *s);
|
||||
int gameseq_get_event_idx(const char* s);
|
||||
int gameseq_get_state_idx(const char* s);
|
||||
|
||||
//zookeeper
|
||||
int gameseq_get_state_idx(int state);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#define MISSION_DESC_LENGTH 512
|
||||
|
||||
// from player.h
|
||||
#define CALLSIGN_LEN 28 // shortened from 32 to allow .plr to be attached without exceeding MAX_FILENAME_LEN
|
||||
#define CALLSIGN_LEN (MAX_FILENAME_LEN - 4 - 1) // shortened from 32 to allow .json to be attached without exceeding MAX_FILENAME_LEN
|
||||
#define SHORT_CALLSIGN_PIXEL_W 80 // max width of short_callsign[] in pixels
|
||||
|
||||
#define MAX_IFFS 10
|
||||
|
||||
@@ -389,7 +389,7 @@ template <class T> void CAP( T& v, T mn, T mx )
|
||||
}
|
||||
|
||||
// faster version of CAP()
|
||||
#define CLAMP(x, min, max) do { if ( (x) < (min) ) (x) = (min); else if ((x) > (max)) (x) = (max); } while(0)
|
||||
#define CLAMP(x, min, max) do { if ( (x) < (min) ) (x) = (min); else if ((x) > (max)) (x) = (max); } while(false)
|
||||
|
||||
//=========================================================
|
||||
// Memory management functions
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
#define SIZE_T_ARG "%Iu"
|
||||
#define PTRDIFF_T_ARG "%Id"
|
||||
|
||||
#define likely(x)
|
||||
#define unlikely(x)
|
||||
#define likely(x) (x)
|
||||
#define unlikely(x) (x)
|
||||
|
||||
#define USED_VARIABLE
|
||||
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/2d.h"
|
||||
|
||||
#include "parse/parselo.h"
|
||||
|
||||
@@ -130,5 +131,24 @@ bool version::operator!=(const version& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
SCP_string get_version_string()
|
||||
{
|
||||
SCP_string str;
|
||||
|
||||
sprintf(str, "FreeSpace 2 Open v%s", FS_VERSION_FULL);
|
||||
|
||||
#ifndef NDEBUG
|
||||
str += " Debug";
|
||||
#endif
|
||||
|
||||
// Lets get some more info in here
|
||||
switch (gr_screen.mode) {
|
||||
case GR_OPENGL:
|
||||
str += " OpenGL";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,13 @@ bool check_at_least(const version& v);
|
||||
*/
|
||||
SCP_string format_version(const version& v);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @return
|
||||
*/
|
||||
SCP_string get_version_string();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
+12
-1
@@ -49,6 +49,7 @@ class movie_material;
|
||||
class batched_bitmap_material;
|
||||
class nanovg_material;
|
||||
class decal_material;
|
||||
class interface_material;
|
||||
|
||||
class transform_stack {
|
||||
|
||||
@@ -154,13 +155,15 @@ enum shader_type {
|
||||
SDR_TYPE_DEFERRED_LIGHTING,
|
||||
SDR_TYPE_DEFERRED_CLEAR,
|
||||
SDR_TYPE_VIDEO_PROCESS,
|
||||
SDR_TYPE_PASSTHROUGH_RENDER, //!< Shader for doing the old style fixed-function rendering. Only used internally, use SDR_TYPE_DEFAULT_MATERIAL.
|
||||
SDR_TYPE_PASSTHROUGH_RENDER, //!< Shader for doing the old style fixed-function rendering. Only used internally, use
|
||||
//!< SDR_TYPE_DEFAULT_MATERIAL.
|
||||
SDR_TYPE_SHIELD_DECAL,
|
||||
SDR_TYPE_BATCHED_BITMAP,
|
||||
SDR_TYPE_DEFAULT_MATERIAL,
|
||||
SDR_TYPE_NANOVG,
|
||||
SDR_TYPE_DECAL,
|
||||
SDR_TYPE_SCENE_FOG,
|
||||
SDR_TYPE_ROCKET_UI,
|
||||
NUM_SHADER_TYPES
|
||||
};
|
||||
|
||||
@@ -780,6 +783,8 @@ typedef struct screen {
|
||||
void (*gf_render_primitives_batched)(batched_bitmap_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
|
||||
void (*gf_render_nanovg)(nanovg_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
|
||||
void (*gf_render_decals)(decal_material* material_info, primitive_type prim_type, vertex_layout* layout, int num_elements, const indexed_vertex_source& buffers);
|
||||
void (*gf_render_rocket_primitives)(interface_material* material_info, primitive_type prim_type,
|
||||
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer);
|
||||
|
||||
bool (*gf_is_capable)(gr_capability capability);
|
||||
bool (*gf_get_property)(gr_property property, void* destination);
|
||||
@@ -1039,6 +1044,12 @@ __inline void gr_render_model(model_material* material_info, indexed_vertex_sour
|
||||
(*gr_screen.gf_render_model)(material_info, vert_source, bufferp, texi);
|
||||
}
|
||||
|
||||
__inline void gr_render_rocket_primitives(interface_material* material_info, primitive_type prim_type,
|
||||
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer)
|
||||
{
|
||||
(*gr_screen.gf_render_rocket_primitives)(material_info, prim_type, layout, n_indices, vertex_buffer, index_buffer);
|
||||
}
|
||||
|
||||
__inline bool gr_is_capable(gr_capability capability)
|
||||
{
|
||||
return (*gr_screen.gf_is_capable)(capability);
|
||||
|
||||
@@ -351,6 +351,12 @@ void gr_stub_render_primitives_batched(batched_bitmap_material* /*material_info
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_render_rocket_primitives(interface_material* /*material_info*/, primitive_type /*prim_type*/,
|
||||
vertex_layout* /*layout*/, int /*n_indices*/, int /*vertex_buffer*/,
|
||||
int /*index_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool gr_stub_is_capable(gr_capability /*capability*/)
|
||||
{
|
||||
return false;
|
||||
@@ -511,6 +517,7 @@ bool gr_stub_init()
|
||||
gr_screen.gf_render_movie = gr_stub_render_movie;
|
||||
gr_screen.gf_render_nanovg = gr_stub_render_nanovg;
|
||||
gr_screen.gf_render_primitives_batched = gr_stub_render_primitives_batched;
|
||||
gr_screen.gf_render_rocket_primitives = gr_stub_render_rocket_primitives;
|
||||
|
||||
gr_screen.gf_is_capable = gr_stub_is_capable;
|
||||
gr_screen.gf_get_property = [](gr_property,void*) { return false; };
|
||||
|
||||
@@ -55,7 +55,18 @@ void line_draw_list::add_vertex(int x, int y, int resize_mode, const color* colo
|
||||
vtx.position.x = i2fl(x);
|
||||
vtx.position.y = i2fl(y);
|
||||
|
||||
gr_resize_screen_posf(&vtx.position.x, &vtx.position.y, nullptr, nullptr, resize_mode);
|
||||
float w_scale = 1.0f;
|
||||
float h_scale = 1.0f;
|
||||
|
||||
bool do_resize = gr_resize_screen_posf(&vtx.position.x, &vtx.position.y, &w_scale, &h_scale, resize_mode);
|
||||
|
||||
int offset_x = ((do_resize) ? gr_screen.offset_x_unscaled : gr_screen.offset_x);
|
||||
int offset_y = ((do_resize) ? gr_screen.offset_y_unscaled : gr_screen.offset_y);
|
||||
|
||||
// m!m - This is silly but there is no better solution at the moment...
|
||||
vtx.position.x += i2fl(offset_x) * w_scale;
|
||||
vtx.position.y += i2fl(offset_y) * h_scale;
|
||||
|
||||
vtx.color.xyzw.x = color->red / 255.f;
|
||||
vtx.color.xyzw.y = color->green / 255.f;
|
||||
vtx.color.xyzw.z = color->blue / 255.f;
|
||||
|
||||
@@ -123,6 +123,18 @@ void material_set_distortion(distortion_material *mat_info, int texture, bool th
|
||||
mat_info->set_cull_mode(false);
|
||||
mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
void material_set_rocket_interface(interface_material* mat_info, int texture, const vec2d& offset)
|
||||
{
|
||||
mat_info->set_texture_map(TM_BASE_TYPE, texture);
|
||||
mat_info->set_offset(offset);
|
||||
|
||||
mat_info->set_cull_mode(false);
|
||||
mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
|
||||
|
||||
mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
|
||||
}
|
||||
|
||||
void material_set_movie(movie_material* mat_info, int y_bm, int u_bm, int v_bm) {
|
||||
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
|
||||
@@ -890,3 +902,13 @@ uint decal_material::get_shader_flags() const {
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
interface_material::interface_material()
|
||||
{
|
||||
set_shader_type(SDR_TYPE_ROCKET_UI);
|
||||
|
||||
offset.x = 0;
|
||||
offset.y = 0;
|
||||
}
|
||||
void interface_material::set_offset(const vec2d& new_offset) { this->offset = new_offset; }
|
||||
vec2d interface_material::get_offset() { return offset; }
|
||||
@@ -315,9 +315,8 @@ class movie_material : public material {
|
||||
void setVtex(int _Vtex);
|
||||
};
|
||||
|
||||
class batched_bitmap_material : public material
|
||||
{
|
||||
public:
|
||||
class batched_bitmap_material : public material {
|
||||
public:
|
||||
batched_bitmap_material();
|
||||
};
|
||||
|
||||
@@ -326,19 +325,29 @@ class nanovg_material : public material {
|
||||
nanovg_material();
|
||||
};
|
||||
|
||||
class decal_material : public material
|
||||
{
|
||||
public:
|
||||
class decal_material : public material {
|
||||
public:
|
||||
decal_material();
|
||||
|
||||
uint get_shader_flags() const override;
|
||||
};
|
||||
|
||||
class interface_material : public material {
|
||||
vec2d offset;
|
||||
|
||||
public:
|
||||
interface_material();
|
||||
|
||||
void set_offset(const vec2d& new_offset);
|
||||
vec2d get_offset();
|
||||
};
|
||||
|
||||
gr_alpha_blend material_determine_blend_mode(int base_bitmap, bool is_transparent);
|
||||
|
||||
gr_zbuffer_type material_determine_depth_mode(bool depth_testing, bool is_transparent);
|
||||
|
||||
void material_set_interface(material* mat_info, int texture, bool blended, float alpha);
|
||||
void material_set_rocket_interface(interface_material* mat_info, int texture, const vec2d& offset);
|
||||
void material_set_unlit(material* mat_info, int texture, float alpha, bool blending, bool depth_testing);
|
||||
void material_set_unlit_emissive(material* mat_info, int texture, float alpha, float color_scale);
|
||||
void material_set_unlit_color(material* mat_info, int texture, color *clr, bool blending, bool depth_testing);
|
||||
|
||||
@@ -1174,6 +1174,7 @@ void opengl_setup_function_pointers()
|
||||
gr_screen.gf_render_movie = gr_opengl_render_movie;
|
||||
gr_screen.gf_render_nanovg = gr_opengl_render_nanovg;
|
||||
gr_screen.gf_render_decals = gr_opengl_render_decals;
|
||||
gr_screen.gf_render_rocket_primitives = gr_opengl_render_rocket_primitives;
|
||||
|
||||
gr_screen.gf_is_capable = gr_opengl_is_capable;
|
||||
gr_screen.gf_get_property = gr_opengl_get_property;
|
||||
|
||||
@@ -825,6 +825,22 @@ void gr_opengl_render_primitives_batched(batched_bitmap_material* material_info,
|
||||
|
||||
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, offset, 0);
|
||||
}
|
||||
void gr_opengl_render_rocket_primitives(interface_material* material_info, primitive_type prim_type,
|
||||
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer)
|
||||
{
|
||||
GR_DEBUG_SCOPE("Render rocket ui primitives");
|
||||
|
||||
gr_set_2d_matrix();
|
||||
|
||||
opengl_tnl_set_rocketui_material(material_info);
|
||||
|
||||
opengl_bind_vertex_layout(*layout, opengl_buffer_get_id(GL_ARRAY_BUFFER, vertex_buffer),
|
||||
opengl_buffer_get_id(GL_ELEMENT_ARRAY_BUFFER, index_buffer));
|
||||
|
||||
glDrawElements(opengl_primitive_type(prim_type), n_indices, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
gr_end_2d_matrix();
|
||||
}
|
||||
|
||||
void opengl_draw_textured_quad(GLfloat x1,
|
||||
GLfloat y1,
|
||||
|
||||
@@ -58,6 +58,8 @@ void gr_opengl_render_primitives_distortion(distortion_material* material_info,
|
||||
void gr_opengl_render_movie(movie_material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, int buffer, size_t buffer_offset);
|
||||
void gr_opengl_render_nanovg(nanovg_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
|
||||
void gr_opengl_render_decals(decal_material* material_info, primitive_type prim_type, vertex_layout* layout, int num_elements, const indexed_vertex_source& binding);
|
||||
void gr_opengl_render_rocket_primitives(interface_material* material_info, primitive_type prim_type,
|
||||
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer);
|
||||
|
||||
void opengl_draw_textured_quad(GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
|
||||
GLfloat x2, GLfloat y2, GLfloat u2, GLfloat v2 );
|
||||
|
||||
@@ -73,9 +73,6 @@ static GLuint Bloom_framebuffer = 0;
|
||||
static GLuint Bloom_textures[2] = { 0 };
|
||||
|
||||
static GLuint Post_framebuffer_id[2] = { 0 };
|
||||
static GLuint Post_shadow_framebuffer_id = 0;
|
||||
static GLuint Post_shadow_texture_id = 0;
|
||||
static GLuint Post_shadow_depth_texture_id = 0;
|
||||
|
||||
static int Post_texture_width = 0;
|
||||
static int Post_texture_height = 0;
|
||||
@@ -864,76 +861,6 @@ void opengl_setup_bloom_textures()
|
||||
GL_state.BindFrameBuffer(0);
|
||||
}
|
||||
|
||||
static bool opengl_init_shadow_framebuffer(int size, GLenum color_format) {
|
||||
mprintf(("Trying to create %dx%d %d-bit shadow framebuffer\n", size, size, color_format == GL_RGBA32F ? 32 : 16));
|
||||
|
||||
glGenFramebuffers(1, &Post_shadow_framebuffer_id);
|
||||
GL_state.BindFrameBuffer(Post_shadow_framebuffer_id);
|
||||
|
||||
glGenTextures(1, &Post_shadow_texture_id);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
|
||||
GL_state.Texture.Enable(Post_shadow_texture_id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, color_format, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Post_shadow_texture_id, 0);
|
||||
|
||||
glGenTextures(1, &Post_shadow_depth_texture_id);
|
||||
|
||||
GL_state.Texture.Enable(Post_shadow_depth_texture_id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Post_shadow_depth_texture_id, 0);
|
||||
|
||||
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE) {
|
||||
// Everything is fine
|
||||
mprintf(("Shadow framebuffer created successfully.\n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clean up resources
|
||||
glDeleteTextures(1, &Post_shadow_texture_id);
|
||||
glDeleteTextures(1, &Post_shadow_depth_texture_id);
|
||||
glDeleteFramebuffers(1, &Post_shadow_framebuffer_id);
|
||||
|
||||
Post_shadow_texture_id = 0;
|
||||
Post_shadow_depth_texture_id = 0;
|
||||
Post_shadow_framebuffer_id = 0;
|
||||
|
||||
const char* error;
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
error = "Incomplete framebuffer attachment";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
error = "Framebuffer is missing an attachment";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
error = "Framebuffer configuration is unsupported";
|
||||
break;
|
||||
default:
|
||||
error = "Unknown framebuffer status";
|
||||
break;
|
||||
}
|
||||
|
||||
mprintf(("Failed to create framebuffer: %s\n", error));
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate and test the framebuffer and textures that we are going to use
|
||||
static bool opengl_post_init_framebuffer()
|
||||
{
|
||||
@@ -953,17 +880,6 @@ static bool opengl_post_init_framebuffer()
|
||||
|
||||
opengl_setup_bloom_textures();
|
||||
|
||||
if ( Cmdline_shadow_quality ) {
|
||||
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL_state.BindFrameBuffer(0);
|
||||
|
||||
rval = true;
|
||||
|
||||
@@ -64,6 +64,7 @@ opengl_uniform_block_binding GL_uniform_blocks[] = {
|
||||
* Static lookup reference for shader uniforms
|
||||
* When adding a new shader, list all associated uniforms and attributes here
|
||||
*/
|
||||
// clang-format off
|
||||
static opengl_shader_type_t GL_shader_types[] = {
|
||||
{ SDR_TYPE_MODEL, "main-v.sdr", "main-f.sdr", "main-g.sdr",
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::NORMAL, opengl_vert_attrib::TANGENT, opengl_vert_attrib::MODEL_ID }, "Model Rendering" },
|
||||
@@ -100,7 +101,7 @@ static opengl_shader_type_t GL_shader_types[] = {
|
||||
|
||||
{ SDR_TYPE_DEFERRED_LIGHTING, "deferred-v.sdr", "deferred-f.sdr", 0,
|
||||
{ opengl_vert_attrib::POSITION }, "Deferred Lighting" },
|
||||
|
||||
|
||||
{ SDR_TYPE_DEFERRED_CLEAR, "deferred-clear-v.sdr", "deferred-clear-f.sdr", 0,
|
||||
{ opengl_vert_attrib::POSITION }, "Clear Deferred Lighting Buffer" },
|
||||
|
||||
@@ -127,7 +128,11 @@ static opengl_shader_type_t GL_shader_types[] = {
|
||||
|
||||
{ SDR_TYPE_SCENE_FOG, "post-v.sdr", "fog-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Scene fogging" },
|
||||
|
||||
{ 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" },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* Static lookup reference for shader variant uniforms
|
||||
|
||||
@@ -412,70 +412,92 @@ void opengl_destroy_all_buffers()
|
||||
GL_vertex_buffers_in_use = 0;
|
||||
}
|
||||
|
||||
static bool opengl_init_shadow_framebuffer(int size, GLenum color_format)
|
||||
{
|
||||
mprintf(("Trying to create %dx%d %d-bit shadow framebuffer\n", size, size, color_format == GL_RGBA32F ? 32 : 16));
|
||||
|
||||
glGenFramebuffers(1, &shadow_fbo);
|
||||
GL_state.BindFrameBuffer(shadow_fbo);
|
||||
|
||||
glGenTextures(1, &Shadow_map_depth_texture);
|
||||
|
||||
GL_state.Texture.Enable(Shadow_map_depth_texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Shadow_map_depth_texture, 0);
|
||||
|
||||
glGenTextures(1, &Shadow_map_texture);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
|
||||
GL_state.Texture.Enable(Shadow_map_texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, color_format, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Shadow_map_texture, 0);
|
||||
|
||||
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
GL_state.BindFrameBuffer(0);
|
||||
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE) {
|
||||
// Everything is fine
|
||||
mprintf(("Shadow framebuffer created successfully.\n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clean up resources
|
||||
glDeleteTextures(1, &Shadow_map_texture);
|
||||
glDeleteTextures(1, &Shadow_map_depth_texture);
|
||||
glDeleteFramebuffers(1, &shadow_fbo);
|
||||
|
||||
Shadow_map_texture = 0;
|
||||
Shadow_map_depth_texture = 0;
|
||||
shadow_fbo = 0;
|
||||
|
||||
const char* error;
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
error = "Incomplete framebuffer attachment";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
error = "Framebuffer is missing an attachment";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
error = "Framebuffer configuration is unsupported";
|
||||
break;
|
||||
default:
|
||||
error = "Unknown framebuffer status";
|
||||
break;
|
||||
}
|
||||
|
||||
mprintf(("Failed to create framebuffer: %s\n", error));
|
||||
return false;
|
||||
}
|
||||
|
||||
void opengl_tnl_init()
|
||||
{
|
||||
Transform_buffer_handle = opengl_create_texture_buffer_object();
|
||||
|
||||
if(Cmdline_shadow_quality)
|
||||
{
|
||||
//Setup shadow map framebuffer
|
||||
glGenFramebuffers(1, &shadow_fbo);
|
||||
GL_state.BindFrameBuffer(shadow_fbo);
|
||||
|
||||
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);
|
||||
opengl_set_object_label(GL_TEXTURE, Shadow_map_depth_texture, "Scene shadow depth map");
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// 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_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
//glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT);
|
||||
//glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
//glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
|
||||
if (Cmdline_shadow_quality) {
|
||||
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Shadow_map_depth_texture, 0);
|
||||
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Shadow_map_depth_texture, 0);
|
||||
|
||||
glGenTextures(1, &Shadow_map_texture);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
|
||||
GL_state.Texture.Enable(Shadow_map_texture);
|
||||
opengl_set_object_label(GL_TEXTURE, Shadow_map_texture, "Scene shadow map");
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// 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_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB32F, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, size, size, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Shadow_map_texture, 0);
|
||||
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Shadow_map_texture, 0);
|
||||
|
||||
GL_state.BindFrameBuffer(0);
|
||||
|
||||
opengl_check_for_errors("post_init_framebuffer()");
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gr_opengl_deferred_init();
|
||||
@@ -974,6 +996,7 @@ void opengl_tnl_set_material_nanovg(nanovg_material* material_info) {
|
||||
|
||||
Current_shader->program->Uniforms.setUniformi("nvg_tex", 0);
|
||||
}
|
||||
|
||||
void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
opengl_tnl_set_material(material_info, false);
|
||||
|
||||
@@ -1016,6 +1039,34 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_tnl_set_rocketui_material(interface_material* material_info)
|
||||
{
|
||||
vec3d offset = vmd_zero_vector;
|
||||
offset.xyz.x = material_info->get_offset().x;
|
||||
offset.xyz.y = material_info->get_offset().y;
|
||||
|
||||
matrix4 modelViewMatrix;
|
||||
vm_matrix4_set_transform(&modelViewMatrix, &vmd_identity_matrix, &offset);
|
||||
|
||||
opengl_tnl_set_material(material_info, false);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", modelViewMatrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformi("textured", material_info->is_textured() ? GL_TRUE : GL_FALSE);
|
||||
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
|
||||
|
||||
if (material_info->is_textured()) {
|
||||
float u_scale, v_scale;
|
||||
uint32_t array_index;
|
||||
if (!gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(),
|
||||
&u_scale, &v_scale, &array_index)) {
|
||||
mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->get_texture_map(TM_BASE_TYPE)));
|
||||
}
|
||||
Current_shader->program->Uniforms.setUniformi("baseMapIndex", array_index);
|
||||
}
|
||||
}
|
||||
|
||||
void gr_opengl_set_viewport(int x, int y, int width, int height) {
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ void opengl_tnl_set_material_movie(movie_material* material_info);
|
||||
void opengl_tnl_set_material_batched(batched_bitmap_material * material_info);
|
||||
void opengl_tnl_set_material_nanovg(nanovg_material * material_info);
|
||||
void opengl_tnl_set_material_decal(decal_material * material_info);
|
||||
void opengl_tnl_set_rocketui_material(interface_material* material_info);
|
||||
|
||||
void opengl_tnl_set_model_material(model_material *material_info);
|
||||
|
||||
|
||||
@@ -21,6 +21,23 @@
|
||||
#include "NanoVGRenderer.h"
|
||||
#include "tracing/tracing.h"
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
// That is a wrapper function for log prints to be availiable for nanovg components. For now it is stb_truetype.h
|
||||
// Planted by ksotar with blessing from asarium
|
||||
extern "C" {
|
||||
void nvgOldCPrintf(SCP_FORMAT_STRING const char *message, ...) {
|
||||
SCP_string buf;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(buf, message, args);
|
||||
va_end(args);
|
||||
outwnd_printf2("%s", message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
using namespace graphics::paths;
|
||||
|
||||
|
||||
@@ -6,3 +6,7 @@ Changes to fontstash.h
|
||||
- Increased memory size for newer stb_truetype version
|
||||
- Removed pixel snapping from fons__getQuad
|
||||
- Include <malloc.h> as malloc and free weren't found for some reason
|
||||
|
||||
Changes to stb_truetype.h
|
||||
- Added extern function to print in log. Made Assert on missed glyph a bit more friendly
|
||||
- Explicit fallthrough comment for gcc
|
||||
+3919
-2246
File diff suppressed because it is too large.
Load diff
@@ -1633,6 +1633,9 @@ void hud_config_as_observer(ship *shipp,ai_info *aif)
|
||||
|
||||
void hud_config_as_player()
|
||||
{
|
||||
if (HUD_config.is_observer) { // If he was observer before
|
||||
hud_config_restore();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -615,7 +615,7 @@ void hud_sourced_print(int source, const char *msg)
|
||||
|
||||
// Invoke the scripting hook
|
||||
Script_system.SetHookVar("Text", 's', const_cast<char*>(msg));
|
||||
Script_system.SetHookVar("SourceType", 'i', &source);
|
||||
Script_system.SetHookVar("SourceType", 'i', source);
|
||||
|
||||
Script_system.RunCondition(CHA_HUDMSGRECEIVED);
|
||||
|
||||
|
||||
@@ -1991,6 +1991,7 @@ void load_gauge_center_reticle(gauge_settings* settings)
|
||||
int scaleX = 15;
|
||||
int scaleY = 10;
|
||||
int size = 5;
|
||||
int autoaim_frame = -1;
|
||||
|
||||
settings->origin[0] = 0.5f;
|
||||
settings->origin[1] = 0.5f;
|
||||
@@ -2040,8 +2041,12 @@ void load_gauge_center_reticle(gauge_settings* settings)
|
||||
if (optional_string("Firepoint Y coordinate multiplier:"))
|
||||
stuff_int(&scaleY);
|
||||
|
||||
if(optional_string("Autoaim Frame:"))
|
||||
stuff_int(&autoaim_frame);
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initFirepointDisplay(firepoints, scaleX, scaleY, size);
|
||||
hud_gauge->setAutoaimFrame(autoaim_frame);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
|
||||
+40
-1
@@ -229,6 +229,7 @@ static int Threat_lock_frame; // frame offset of current lock flashing warnin
|
||||
HudGaugeReticle::HudGaugeReticle():
|
||||
HudGauge(HUD_OBJECT_CENTER_RETICLE, HUD_CENTER_RETICLE, true, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_TOPDOWN | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
has_autoaim_lock = false;
|
||||
}
|
||||
|
||||
void HudGaugeReticle::initBitmaps(char *fname)
|
||||
@@ -248,9 +249,40 @@ void HudGaugeReticle::initFirepointDisplay(bool firepoint, int scaleX, int scale
|
||||
|
||||
void HudGaugeReticle::render(float /*frametime*/)
|
||||
{
|
||||
ship_info *sip = &Ship_info[Player_ship->ship_info_index];
|
||||
|
||||
if (autoaim_frame_offset > 0 || sip->autoaim_lock_snd.isValid() || sip->autoaim_lost_snd.isValid()) {
|
||||
ship *shipp = &Ships[Objects[Player->objnum].instance];
|
||||
ship_weapon *swp = &shipp->weapons;
|
||||
ai_info *aip = &Ai_info[shipp->ai_index];
|
||||
|
||||
if (aip->target_objnum != -1) {
|
||||
bool autoaiming = false;
|
||||
|
||||
autoaiming = in_autoaim_fov(shipp, swp->current_primary_bank, &Objects[aip->target_objnum]);
|
||||
|
||||
if (autoaiming) {
|
||||
if (!has_autoaim_lock && sip->autoaim_lock_snd.isValid()) {
|
||||
snd_play(gamesnd_get_game_sound(sip->autoaim_lock_snd));
|
||||
//snd_play( gamesnd_get_game_sound(ship_get_sound(Player_obj, GameSounds::THREAT_FLASH)));
|
||||
}
|
||||
has_autoaim_lock = true;
|
||||
}
|
||||
else {
|
||||
if (has_autoaim_lock && sip->autoaim_lost_snd.isValid()) {
|
||||
snd_play(gamesnd_get_game_sound(sip->autoaim_lost_snd));
|
||||
}
|
||||
has_autoaim_lock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setGaugeColor(HUD_C_BRIGHT);
|
||||
|
||||
renderBitmap(crosshair.first_frame, position[0], position[1]);
|
||||
if (has_autoaim_lock)
|
||||
renderBitmap(crosshair.first_frame + autoaim_frame_offset, position[0], position[1]);
|
||||
else
|
||||
renderBitmap(crosshair.first_frame, position[0], position[1]);
|
||||
|
||||
if (firepoint_display) {
|
||||
fp.clear();
|
||||
@@ -342,6 +374,13 @@ void HudGaugeReticle::getFirepointStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
void HudGaugeReticle::setAutoaimFrame(int framenum) {
|
||||
if (framenum < 0 || framenum > crosshair.num_frames - 1)
|
||||
autoaim_frame_offset = 0;
|
||||
else
|
||||
autoaim_frame_offset = framenum;
|
||||
}
|
||||
|
||||
void HudGaugeReticle::pageIn()
|
||||
{
|
||||
bm_page_in_aabitmap( crosshair.first_frame, crosshair.num_frames);
|
||||
|
||||
@@ -42,6 +42,8 @@ protected:
|
||||
int firepoint_size;
|
||||
int firepoint_scale_x;
|
||||
int firepoint_scale_y;
|
||||
int autoaim_frame_offset;
|
||||
bool has_autoaim_lock;
|
||||
public:
|
||||
HudGaugeReticle();
|
||||
void render(float frametime) override;
|
||||
@@ -49,6 +51,7 @@ public:
|
||||
void pageIn() override;
|
||||
void initFirepointDisplay(bool firepoint, int scaleX, int scaleY, int size);
|
||||
void getFirepointStatus();
|
||||
void setAutoaimFrame(int framenum);
|
||||
};
|
||||
|
||||
class HudGaugeThrottle: public HudGauge
|
||||
|
||||
+16
-16
@@ -105,7 +105,7 @@ int Menu_pgdn_coords[GR_NUM_RESOLUTIONS][2] = {
|
||||
typedef struct mmode_item {
|
||||
int instance; // instance in Ships/Wings array of this menu item
|
||||
int active; // active items are in bold text -- inactive items greyed out
|
||||
char text[NAME_LENGTH]; // text to display on the menu
|
||||
SCP_string text; // text to display on the menu
|
||||
} mmode_item;
|
||||
|
||||
#define MAX_MENU_ITEMS 50 // max number of items in the menu
|
||||
@@ -154,7 +154,7 @@ int keys_used[] = { KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_
|
||||
#define TYPE_REPAIR_REARM_ABORT_ITEM 5
|
||||
|
||||
|
||||
char Comm_order_types[NUM_COMM_ORDER_TYPES][NAME_LENGTH];
|
||||
SCP_string Comm_order_types[NUM_COMM_ORDER_TYPES];
|
||||
comm_order Comm_orders[NUM_COMM_ORDER_ITEMS];
|
||||
|
||||
|
||||
@@ -207,25 +207,25 @@ void hud_init_comm_orders()
|
||||
|
||||
for (i = 0; i < NUM_COMM_ORDER_TYPES; i++)
|
||||
{
|
||||
strcpy_s(Comm_order_types[i], temp_comm_order_types[i]);
|
||||
Comm_order_types[i] = temp_comm_order_types[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_COMM_ORDER_ITEMS; i++)
|
||||
{
|
||||
strcpy_s(Comm_orders[i].name, XSTR(Sexp_comm_orders[i].name, Sexp_comm_orders[i].xstring));
|
||||
Comm_orders[i].name = XSTR(Sexp_comm_orders[i].name, Sexp_comm_orders[i].xstring);
|
||||
Comm_orders[i].item = Sexp_comm_orders[i].item;
|
||||
}
|
||||
}
|
||||
|
||||
// Text to display on the messaging menu when using the shortcut keys
|
||||
char *comm_order_get_text(int item)
|
||||
const char *comm_order_get_text(int item)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_COMM_ORDER_ITEMS; i++)
|
||||
{
|
||||
if (Comm_orders[i].item == item)
|
||||
return Comm_orders[i].name;
|
||||
return Comm_orders[i].name.c_str();
|
||||
}
|
||||
|
||||
// not found
|
||||
@@ -404,7 +404,7 @@ int hud_squadmsg_count_ships(int add_to_menu)
|
||||
if (add_to_menu)
|
||||
{
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s( MsgItems[Num_menu_items].text, shipp->get_display_string() );
|
||||
MsgItems[Num_menu_items].text = shipp->get_display_string();
|
||||
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text); // truncate the name if it has a # in it
|
||||
MsgItems[Num_menu_items].instance = SHIP_INDEX(shipp);
|
||||
MsgItems[Num_menu_items].active = 1;
|
||||
@@ -485,7 +485,7 @@ int hud_squadmsg_count_wings( int add_to_menu )
|
||||
count++;
|
||||
if ( add_to_menu ) {
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s( MsgItems[Num_menu_items].text, Wings[wingnum].name );
|
||||
MsgItems[Num_menu_items].text = Wings[wingnum].name;
|
||||
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text);
|
||||
MsgItems[Num_menu_items].instance = wingnum;
|
||||
MsgItems[Num_menu_items].active = 1;
|
||||
@@ -507,7 +507,7 @@ int hud_squadmsg_count_wings( int add_to_menu )
|
||||
count++;
|
||||
if ( add_to_menu ) {
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s( MsgItems[Num_menu_items].text, Wings[i].name );
|
||||
MsgItems[Num_menu_items].text = Wings[i].name;
|
||||
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text);
|
||||
MsgItems[Num_menu_items].instance = i;
|
||||
MsgItems[Num_menu_items].active = 1;
|
||||
@@ -1625,7 +1625,7 @@ void hud_squadmsg_type_select( )
|
||||
// Add the items
|
||||
for (i = 0; i < NUM_COMM_ORDER_TYPES; i++)
|
||||
{
|
||||
strcpy_s(MsgItems[i].text, Comm_order_types[i]);
|
||||
MsgItems[i].text = Comm_order_types[i];
|
||||
MsgItems[i].active = 1; // assume active
|
||||
}
|
||||
Num_menu_items = NUM_COMM_ORDER_TYPES;
|
||||
@@ -1916,7 +1916,7 @@ void hud_squadmsg_reinforcement_select()
|
||||
}
|
||||
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s( MsgItems[Num_menu_items].text, rp->name );
|
||||
MsgItems[Num_menu_items].text = rp->name;
|
||||
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text);
|
||||
MsgItems[Num_menu_items].instance = i;
|
||||
MsgItems[Num_menu_items].active = 0;
|
||||
@@ -1984,7 +1984,7 @@ void hud_squadmsg_ship_command()
|
||||
// the order will be activated if the bit is set for the ship.
|
||||
if ( default_orders & Comm_orders[i].item ) {
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s(MsgItems[Num_menu_items].text, Comm_orders[i].name);
|
||||
MsgItems[Num_menu_items].text = Comm_orders[i].name.c_str();
|
||||
MsgItems[Num_menu_items].instance = Comm_orders[i].item;
|
||||
MsgItems[Num_menu_items].active = 0;
|
||||
// check the bit to see if the command is active
|
||||
@@ -2027,7 +2027,7 @@ void hud_squadmsg_ship_command()
|
||||
if ( !all_accept ) {
|
||||
// either modify the text if a partial accept, or grey it out if no one accepts
|
||||
if ( partial_accept ) {
|
||||
strcat_s( MsgItems[Num_menu_items].text, XSTR( "(*)", 320) );
|
||||
MsgItems[Num_menu_items].text += XSTR("(*)", 320);
|
||||
} else {
|
||||
MsgItems[Num_menu_items].active = 0;
|
||||
}
|
||||
@@ -2085,7 +2085,7 @@ void hud_squadmsg_wing_command()
|
||||
// to be available in the wing.
|
||||
if ( default_orders & Comm_orders[i].item ) {
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s(MsgItems[Num_menu_items].text, Comm_orders[i].name);
|
||||
MsgItems[Num_menu_items].text = Comm_orders[i].name;
|
||||
MsgItems[Num_menu_items].instance = Comm_orders[i].item;
|
||||
MsgItems[Num_menu_items].active = 0;
|
||||
|
||||
@@ -2445,7 +2445,7 @@ int hud_query_order_issued(char *to, char *order_name, char *target_name, int ti
|
||||
|
||||
|
||||
for (i = 0; i < NUM_COMM_ORDER_ITEMS; i++)
|
||||
if (!stricmp(order_name, Comm_orders[i].name))
|
||||
if (!stricmp(order_name, Comm_orders[i].name.c_str()))
|
||||
order = Comm_orders[i].item;
|
||||
|
||||
// Goober5000 - if not found, check compatibility
|
||||
@@ -2679,7 +2679,7 @@ void HudGaugeSquadMessage::render(float /*frametime*/)
|
||||
|
||||
for ( i = 0; i < nitems; i++ ) {
|
||||
int item_num;
|
||||
char *text = MsgItems[First_menu_item+i].text;
|
||||
const char *text = MsgItems[First_menu_item+i].text.c_str();
|
||||
|
||||
// blit the background
|
||||
// hud_set_default_color();
|
||||
|
||||
@@ -63,7 +63,7 @@ class object;
|
||||
|
||||
// data structure to hold character string of commands for comm menu
|
||||
typedef struct comm_order {
|
||||
char name[NAME_LENGTH];
|
||||
SCP_string name;
|
||||
int item;
|
||||
} comm_order;
|
||||
|
||||
|
||||
+10
-8
@@ -4364,7 +4364,7 @@ void HudGaugeLeadSight::render(float /*frametime*/)
|
||||
|
||||
// hud_cease_subsystem_targeting() will cease targeting the current targets subsystems
|
||||
//
|
||||
void hud_cease_subsystem_targeting(int print_message)
|
||||
void hud_cease_subsystem_targeting(bool print_message)
|
||||
{
|
||||
int ship_index;
|
||||
|
||||
@@ -4383,15 +4383,17 @@ void hud_cease_subsystem_targeting(int print_message)
|
||||
hud_lock_reset();
|
||||
}
|
||||
|
||||
// hud_cease_targeting() will cease all targeting (main target and subsystem)
|
||||
//
|
||||
void hud_cease_targeting()
|
||||
// hud_cease_targeting() will cease targeting main target and subsystem
|
||||
// does not turn off auto-targeting by default
|
||||
void hud_cease_targeting(bool deliberate)
|
||||
{
|
||||
set_target_objnum( Player_ai, -1 );
|
||||
Players[Player_num].flags &= ~PLAYER_FLAGS_AUTO_TARGETING;
|
||||
hud_cease_subsystem_targeting(0);
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR( "Deactivating targeting system", 325));
|
||||
hud_lock_reset();
|
||||
hud_cease_subsystem_targeting(false);
|
||||
|
||||
if (deliberate) {
|
||||
Players[Player_num].flags &= ~PLAYER_FLAGS_AUTO_TARGETING;
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR("Deactivating targeting system", 325));
|
||||
}
|
||||
}
|
||||
|
||||
// hud_restore_subsystem_target() will remember the last targeted subsystem
|
||||
|
||||
@@ -26,6 +26,7 @@ struct weapon_info;
|
||||
#define MATCH_SPEED_THRESHOLD 0.1f // minimum speed target must be moving for match speed to apply
|
||||
#define CARGO_RADIUS_DELTA 100 // distance added to radius required for cargo scanning
|
||||
#define CAPITAL_CARGO_RADIUS_DELTA 250 // distance added to radius required for cargo scanning
|
||||
const int CARGO_RADIUS_REAL_DELTA = 50; // difference in distances used for cargo scanning of subsystems (which also uses object radius), vs whole-ship scanning
|
||||
#define CARGO_REVEAL_MIN_DIST 150 // minimum distance for reveal cargo (used if radius+CARGO_RADIUS_DELTA < CARGO_REVEAL_MIN_DIST)
|
||||
#define CAP_CARGO_REVEAL_MIN_DIST 300 // minimum distance for reveal cargo (used if radius+CARGO_RADIUS_DELTA < CARGO_REVEAL_MIN_DIST)
|
||||
#define CARGO_MIN_DOT_TO_REVEAL 0.95 // min dot to proceed to have cargo scanning take place
|
||||
@@ -113,8 +114,8 @@ void hud_target_random_ship();
|
||||
|
||||
void hud_target_next_subobject();
|
||||
void hud_target_prev_subobject();
|
||||
void hud_cease_subsystem_targeting(int print_message=1);
|
||||
void hud_cease_targeting();
|
||||
void hud_cease_subsystem_targeting(bool print_message = true);
|
||||
void hud_cease_targeting(bool deliberate = false);
|
||||
void hud_restore_subsystem_target(ship* shipp);
|
||||
int subsystem_in_sight(object* objp, ship_subsys* subsys, vec3d *eye, vec3d* subsystem);
|
||||
vec3d* get_subsystem_world_pos(object* parent_obj, ship_subsys* subsys, vec3d* world_pos);
|
||||
|
||||
+3
-2
@@ -81,7 +81,8 @@ SCP_string getJoystickGUID(SDL_Joystick *stick)
|
||||
joystickGUID.resize(GUID_STR_SIZE - 1);
|
||||
|
||||
// Make sure the GUID is upper case
|
||||
std::transform(begin(joystickGUID), end(joystickGUID), begin(joystickGUID), toupper);
|
||||
std::transform(begin(joystickGUID), end(joystickGUID), begin(joystickGUID),
|
||||
[](char c) { return (char)::toupper(c); });
|
||||
|
||||
return joystickGUID;
|
||||
}
|
||||
@@ -96,7 +97,7 @@ bool isCurrentJoystick(Joystick* testStick) {
|
||||
}
|
||||
|
||||
SCP_string guidStr(currentGUID);
|
||||
std::transform(begin(guidStr), end(guidStr), begin(guidStr), toupper);
|
||||
std::transform(begin(guidStr), end(guidStr), begin(guidStr), [](char c) { return (char)::toupper(c); });
|
||||
|
||||
if (testStick->getGUID() != guidStr) {
|
||||
return false; // GUID doesn't match
|
||||
|
||||
@@ -2667,7 +2667,7 @@ int button_function(int n)
|
||||
|
||||
// stop targeting ship
|
||||
case STOP_TARGETING_SHIP:
|
||||
hud_cease_targeting();
|
||||
hud_cease_targeting(true);
|
||||
break;
|
||||
|
||||
// stop targeting subsystems on ship
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ void mouse_mark_button( uint flags, int set)
|
||||
|
||||
SDL_UnlockMutex( mouse_lock );
|
||||
|
||||
Script_system.SetHookVar("MouseButton", 'i', &flags);
|
||||
Script_system.SetHookVar("MouseButton", 'i', flags);
|
||||
|
||||
//WMC - On Mouse Pressed and On Mouse Released hooks
|
||||
if (set == 1)
|
||||
|
||||
+14
-11
@@ -192,13 +192,6 @@ void labviewer_change_model(char *model_fname, int lod = 0, int sel_index = -1)
|
||||
|
||||
Lab_model_num = model_load(model_fname, (valid_ship) ? Ship_info[sel_index].n_subsystems : 0, subsystems, 0);
|
||||
|
||||
if (Lab_model_num >= 0) {
|
||||
strcpy_s(Lab_model_filename, model_fname);
|
||||
}
|
||||
else {
|
||||
memset(Lab_model_filename, 0, sizeof(Lab_model_filename));
|
||||
}
|
||||
|
||||
if (valid_ship) {
|
||||
if (Lab_model_num >= 0) {
|
||||
model_page_in_textures(Lab_model_num, sel_index);
|
||||
@@ -1289,7 +1282,7 @@ void labviewer_make_desc_window(Button * /*caller*/)
|
||||
void labviewer_make_ship_window(Button * /*caller*/)
|
||||
{
|
||||
GUIObject *cbp;
|
||||
TreeItem *ctip, *stip;
|
||||
TreeItem *stip;
|
||||
int x, idx;
|
||||
|
||||
if (Lab_mode == LAB_MODE_SHIP) {
|
||||
@@ -1349,8 +1342,7 @@ void labviewer_make_ship_window(Button * /*caller*/)
|
||||
stip = Lab_species_nodes[Species_info.size()];
|
||||
}
|
||||
|
||||
ctip = cmp->AddItem(stip, it->name, (int)std::distance(Ship_info.cbegin(), it), false, labviewer_change_ship);
|
||||
cmp->AddItem(ctip, "Model", 0, false, labviewer_change_ship_lod);
|
||||
cmp->AddItem(stip, it->name, (int)std::distance(Ship_info.cbegin(), it), false, labviewer_change_ship);
|
||||
//cmp->AddItem(ctip, "Debris", 99, false, labviewer_change_ship_lod);
|
||||
}
|
||||
|
||||
@@ -1393,7 +1385,7 @@ void labviewer_make_ship_window(Button * /*caller*/)
|
||||
|
||||
void labviewer_change_ship_lod(Tree* caller)
|
||||
{
|
||||
int ship_index = (int)(caller->GetSelectedItem()->GetParentItem()->GetData());
|
||||
int ship_index = caller->GetSelectedItem()->GetData();
|
||||
Assert(ship_index >= 0);
|
||||
|
||||
if (Lab_selected_object == -1)
|
||||
@@ -1418,6 +1410,16 @@ void labviewer_change_ship_lod(Tree* caller)
|
||||
|
||||
Lab_last_selected_ship = Lab_selected_index;
|
||||
labviewer_change_model(Ship_info[ship_index].pof_file, caller->GetSelectedItem()->GetData(), ship_index);
|
||||
|
||||
//update the displayed POF filename
|
||||
//moved out of labviewer_change_model which apparently doesn't do much after the first ship is loaded
|
||||
if (Lab_model_num >= 0) {
|
||||
strcpy_s(Lab_model_filename, Ship_info[ship_index].pof_file);
|
||||
}
|
||||
else {
|
||||
memset(Lab_model_filename, 0, sizeof(Lab_model_filename));
|
||||
}
|
||||
|
||||
if (Ship_info[ship_index].uses_team_colors) {
|
||||
Lab_team_color = Ship_info[ship_index].default_team_name;
|
||||
}
|
||||
@@ -1438,6 +1440,7 @@ void labviewer_change_ship(Tree *caller)
|
||||
labviewer_update_desc_window();
|
||||
labviewer_update_flags_window();
|
||||
labviewer_update_variables_window();
|
||||
labviewer_change_ship_lod(caller);
|
||||
}
|
||||
|
||||
// --------------------------- Weapons Window --------------------------------
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
#include "libs/jansson.h"
|
||||
|
||||
namespace {
|
||||
int json_write_callback(const char *buffer, size_t size, void *data) {
|
||||
auto* cfp = (CFILE*)data;
|
||||
|
||||
if ((size_t)cfwrite(buffer, 1, (int)size, cfp) != size) {
|
||||
return -1; // Error
|
||||
} else {
|
||||
return 0; // Success
|
||||
}
|
||||
}
|
||||
|
||||
size_t json_read_callback(void *buffer, size_t buflen, void *data) {
|
||||
auto fp = (CFILE*)data;
|
||||
|
||||
return (size_t)cfread(buffer, 1, (int)buflen, fp);
|
||||
}
|
||||
}
|
||||
|
||||
int json_dump_cfile(const json_t* json, CFILE* file, size_t flags) {
|
||||
return json_dump_callback(json, json_write_callback, file, flags);
|
||||
}
|
||||
json_t* json_load_cfile(CFILE* cfile, size_t flags, json_error_t* error) {
|
||||
return json_load_callback(json_read_callback, cfile, flags, error);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
int json_dump_cfile(const json_t *json, CFILE* file, size_t flags);
|
||||
|
||||
json_t *json_load_cfile(CFILE* cfile, size_t flags, json_error_t *error);
|
||||
@@ -2397,6 +2397,12 @@ void vm_vec_random_cone(vec3d *out, const vec3d *in, float min_angle, float max_
|
||||
const matrix *rot;
|
||||
matrix m;
|
||||
|
||||
if (max_angle < min_angle) {
|
||||
auto tmp = min_angle;
|
||||
min_angle = max_angle;
|
||||
max_angle = tmp;
|
||||
}
|
||||
|
||||
// get an orientation matrix
|
||||
if(orient != NULL){
|
||||
rot = orient;
|
||||
|
||||
+68
-32
@@ -32,16 +32,13 @@
|
||||
#include "popup/popup.h"
|
||||
#include "ship/ship.h"
|
||||
#include "ui/ui.h"
|
||||
#include "barracks.h"
|
||||
#include "mod_table/mod_table.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//Returns 0 on failure, 1 on success
|
||||
int delete_pilot_file( char *pilot_name ); // manage_pilot.cpp
|
||||
|
||||
// stats defines
|
||||
//#define NUM_STAT_LINES (21 + MAX_SHIP_CLASSES) // Goober5000
|
||||
#define STAT_COLUMN1_W 40
|
||||
#define STAT_COLUMN1_W 40*2 // as we might use Unicode //ksotar
|
||||
#define STAT_COLUMN2_W 10
|
||||
|
||||
static int Stat_column1_w[GR_NUM_RESOLUTIONS] =
|
||||
@@ -84,6 +81,7 @@ static int Barracks_stats_coords[GR_NUM_RESOLUTIONS][4] = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static int Barracks_stats2_coords[GR_NUM_RESOLUTIONS][3] = {
|
||||
{ // GR_640
|
||||
276, 212, 81 // X2, , W2
|
||||
@@ -270,6 +268,9 @@ UI_XSTR Barracks_text[GR_NUM_RESOLUTIONS][BARRACKS_NUM_TEXT] = {
|
||||
static size_t Num_stat_lines;
|
||||
static char (*Stat_labels)[STAT_COLUMN1_W];
|
||||
static char (*Stats)[STAT_COLUMN2_W];
|
||||
static uint16_t Stats_max_width; // If Unicode language is used then we adapt stats width for new words/strings length
|
||||
static uint16_t Stats_X2; // And numbers position adapted as well
|
||||
|
||||
|
||||
static int Player_sel_mode;
|
||||
|
||||
@@ -303,7 +304,7 @@ void barracks_squad_change_popup();
|
||||
#define STRCPY1(a, b) do { \
|
||||
Assert(strlen(b) < STAT_COLUMN1_W); \
|
||||
strcpy_s(a, b); \
|
||||
} while (0)
|
||||
} while (false)
|
||||
|
||||
void barracks_init_stats(scoring_struct *stats)
|
||||
{
|
||||
@@ -388,28 +389,30 @@ void barracks_init_stats(scoring_struct *stats)
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hits:", 59));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Secondary friendly hits:", 59));
|
||||
sprintf(Stats[Num_stat_lines], "%u", stats->s_bonehead_hits);
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary hit %:", 60));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Secondary hit %:", 60));
|
||||
if (stats->s_shots_fired > 0) {
|
||||
f = (float) stats->s_shots_hit * 100.0f / (float) stats->s_shots_fired;
|
||||
} else {
|
||||
f = (float)stats->s_shots_hit * 100.0f / (float)stats->s_shots_fired;
|
||||
}
|
||||
else {
|
||||
f = 0.0f;
|
||||
}
|
||||
sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
|
||||
sprintf(Stats[Num_stat_lines], XSTR("%.1f%%", 55), f);
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hit %:", 61));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Secondary friendly hit %:", 61));
|
||||
if (stats->s_shots_fired > 0) {
|
||||
f = (float) stats->s_bonehead_hits * 100.0f / (float) stats->s_shots_fired;
|
||||
} else {
|
||||
f = (float)stats->s_bonehead_hits * 100.0f / (float)stats->s_shots_fired;
|
||||
}
|
||||
else {
|
||||
f = 0.0f;
|
||||
}
|
||||
sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
|
||||
sprintf(Stats[Num_stat_lines], XSTR("%.1f%%", 55), f);
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
@@ -418,12 +421,12 @@ void barracks_init_stats(scoring_struct *stats)
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Total kills:", 62));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Total kills:", 62));
|
||||
sprintf(Stats[Num_stat_lines], "%d", stats->kill_count_ok);
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Assists:", 63));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Assists:", 63));
|
||||
sprintf(Stats[Num_stat_lines], "%d", stats->assists);
|
||||
Num_stat_lines++;
|
||||
|
||||
@@ -433,7 +436,7 @@ void barracks_init_stats(scoring_struct *stats)
|
||||
Num_stat_lines++;
|
||||
|
||||
Assert(Num_stat_lines < Max_stat_lines);
|
||||
strcpy_s(Stat_labels[Num_stat_lines], XSTR( "Current Score:", 1583));
|
||||
strcpy_s(Stat_labels[Num_stat_lines], XSTR("Current Score:", 1583));
|
||||
sprintf(Stats[Num_stat_lines], "%d", stats->score);
|
||||
Num_stat_lines++;
|
||||
|
||||
@@ -447,7 +450,7 @@ void barracks_init_stats(scoring_struct *stats)
|
||||
Stats[Num_stat_lines][0] = 0;
|
||||
Num_stat_lines++;
|
||||
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "*Kills by Ship Type", 64));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("*Kills by Ship Type", 64));
|
||||
Stats[Num_stat_lines][0] = 0;
|
||||
Num_stat_lines++;
|
||||
|
||||
@@ -482,13 +485,29 @@ void barracks_init_stats(scoring_struct *stats)
|
||||
|
||||
// add the score from kills
|
||||
Assert((Num_stat_lines + 1) < Max_stat_lines);
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Score from kills only:", 1636));
|
||||
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Score from kills only:", 1636));
|
||||
sprintf(Stats[Num_stat_lines], "%d", score_from_kills);
|
||||
Num_stat_lines++;
|
||||
|
||||
for (i=0; i<Num_stat_lines; i++) {
|
||||
font::force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD]);
|
||||
font::force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
|
||||
int w;
|
||||
Stats_max_width = 0;
|
||||
Stats_X2 = 0;
|
||||
if (Unicode_text_mode && (gr_screen.res != GR_640)) {
|
||||
for (i = 0; i < Num_stat_lines; i++) { // Find the longest string in labels to base list appearance on that
|
||||
gr_get_string_size(&w, nullptr, Stat_labels[i]);
|
||||
if (Stats_max_width < w)
|
||||
Stats_max_width = (uint16_t)w;
|
||||
}
|
||||
Stats_max_width += 20;
|
||||
Stats_X2 = Stats_max_width + 46;
|
||||
}
|
||||
else {
|
||||
Stats_max_width = (uint16_t) Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD];
|
||||
Stats_X2 = (uint16_t) Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD];
|
||||
for (i = 0; i < Num_stat_lines; i++) {
|
||||
font::force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Stats_max_width);
|
||||
font::force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,7 +558,7 @@ int barracks_new_pilot_selected()
|
||||
Cur_pilot->callsign[0] = 0; // this indicates no pilot active
|
||||
return -1;
|
||||
} else {
|
||||
if (!Pilot.load_savefile(Cur_pilot->current_campaign)) {
|
||||
if (!Pilot.load_savefile(Cur_pilot, Cur_pilot->current_campaign)) {
|
||||
// set single player squad image to multi if campaign can't be loaded
|
||||
strcpy_s(Cur_pilot->s_squad_filename, Cur_pilot->m_squad_filename);
|
||||
}
|
||||
@@ -667,6 +686,24 @@ int barracks_pilot_accepted()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void barracks_accept_pilot(player* plr) {
|
||||
// set pilot image
|
||||
if (Game_mode & GM_MULTIPLAYER) {
|
||||
player_set_squad_bitmap(plr, plr->m_squad_filename, true);
|
||||
} else {
|
||||
player_set_squad_bitmap(plr, plr->s_squad_filename, false);
|
||||
}
|
||||
|
||||
// MWA -- I think that we should be writing plr here.
|
||||
Pilot.save_player(plr);
|
||||
|
||||
Player = &Players[Player_num];
|
||||
Player->assign(plr);
|
||||
|
||||
os_config_write_string(nullptr, "LastPlayer", plr->callsign);
|
||||
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
||||
}
|
||||
|
||||
// scroll up barracks pilot list one line
|
||||
void barracks_scroll_callsign_up()
|
||||
{
|
||||
@@ -831,7 +868,6 @@ void barracks_delete_pilot()
|
||||
{
|
||||
char buf[MAX_FILENAME_LEN];
|
||||
int active = 0;
|
||||
int del_rval;
|
||||
|
||||
if (!Num_pilots) {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
@@ -857,7 +893,7 @@ void barracks_delete_pilot()
|
||||
|
||||
strcpy_s(buf, Pilots[Selected_line]);
|
||||
|
||||
del_rval = delete_pilot_file(buf);
|
||||
auto del_rval = delete_pilot_file(buf);
|
||||
|
||||
if ( !del_rval ) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, XSTR("Error\nFailed to delete pilot file. File may be read-only.", 1599));
|
||||
@@ -953,7 +989,7 @@ void barracks_init_player_stuff(int mode)
|
||||
Get_file_list_filter = barracks_pilot_filter;
|
||||
|
||||
Num_pilots =
|
||||
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.plr"), CF_SORT_TIME,
|
||||
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.json"), CF_SORT_TIME,
|
||||
nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
|
||||
int ranks[MAX_PILOTS];
|
||||
@@ -1190,18 +1226,18 @@ void barracks_display_pilot_stats()
|
||||
|
||||
gr_get_string_size(&w, &h, str);
|
||||
i = Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y + h / 2 - 1;
|
||||
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD], i, Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] - w - 2, i, GR_RESIZE_MENU);
|
||||
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] + 1, i, Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD], i, GR_RESIZE_MENU);
|
||||
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD], i, Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width - w - 2, i, GR_RESIZE_MENU);
|
||||
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width + 1, i, Stats_X2 + Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD], i, GR_RESIZE_MENU);
|
||||
|
||||
} else {
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
}
|
||||
|
||||
gr_get_string_size(&w, NULL, str);
|
||||
gr_printf_menu(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] - w, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
|
||||
gr_printf_menu(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width - w, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
|
||||
str = Stats[z];
|
||||
if (*str) {
|
||||
gr_printf_menu(Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
|
||||
gr_printf_menu(Stats_X2, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
|
||||
}
|
||||
|
||||
y += font_height;
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#ifndef _BARRACKS_H
|
||||
#define _BARRACKS_H
|
||||
|
||||
#include "playerman/player.h"
|
||||
|
||||
extern int Barracks_overlay_id;
|
||||
|
||||
// initialize the barracks
|
||||
@@ -23,4 +25,6 @@ void barracks_do_frame(float frametime);
|
||||
// close the barracks
|
||||
void barracks_close();
|
||||
|
||||
void barracks_accept_pilot(player* plr);
|
||||
|
||||
#endif // _BARRACKS_H
|
||||
@@ -10,15 +10,16 @@
|
||||
#include <cstdlib>
|
||||
#include <climits>
|
||||
|
||||
#include "freespace.h"
|
||||
#include "anim/animplay.h"
|
||||
#include "anim/packunpack.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "freespace.h"
|
||||
#include "gamehelp/contexthelp.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "graphics/generic.h"
|
||||
#include "io/key.h"
|
||||
#include "io/mouse.h"
|
||||
@@ -33,9 +34,9 @@
|
||||
#include "network/multiui.h"
|
||||
#include "network/multiutil.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "playerman/player.h"
|
||||
#include "popup/popup.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "sound/audiostr.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -410,6 +411,8 @@ void main_hall_init(const SCP_string &main_hall_name)
|
||||
return;
|
||||
}
|
||||
|
||||
// gameseq_post_event(GS_EVENT_SCRIPTING);
|
||||
|
||||
int idx;
|
||||
SCP_string main_hall_to_load;
|
||||
|
||||
@@ -923,9 +926,10 @@ void main_hall_do(float frametime)
|
||||
// custom action
|
||||
case SCRIPT_REGION:
|
||||
const char *lua = it->lua_action.c_str();
|
||||
bool success = Script_system.EvalString(lua, NULL, NULL, lua);
|
||||
if(!success)
|
||||
Warning(LOCATION, "mainhall '+Door Action / $Script' failed to evaluate \"%s\"; check your syntax", lua);
|
||||
bool success = Script_system.EvalString(lua, lua);
|
||||
if (!success)
|
||||
Warning(LOCATION,
|
||||
"mainhall '+Door Action / $Script' failed to evaluate \"%s\"; check your syntax", lua);
|
||||
break;
|
||||
} // END switch (code)
|
||||
|
||||
@@ -1666,20 +1670,19 @@ void main_hall_reset_ambient_vol()
|
||||
void main_hall_blit_version()
|
||||
{
|
||||
int w, h;
|
||||
char version_string[100];
|
||||
|
||||
// format the version string
|
||||
get_version_string(version_string, sizeof(version_string));
|
||||
auto version_string = gameversion::get_version_string();
|
||||
|
||||
int old_font = font::get_current_fontnum();
|
||||
font::set_font(Main_hall->font);
|
||||
|
||||
// get the length of the string
|
||||
gr_get_string_size(&w,&h,version_string);
|
||||
gr_get_string_size(&w, &h, version_string.c_str());
|
||||
|
||||
// print the string near the lower left corner
|
||||
gr_set_color_fast(&Color_bright_white);
|
||||
gr_string(5, gr_screen.max_h_unscaled_zoomed - (h * 2 + 6), version_string, GR_RESIZE_MENU_ZOOMED);
|
||||
gr_string(5, gr_screen.max_h_unscaled_zoomed - (h * 2 + 6), version_string.c_str(), GR_RESIZE_MENU_ZOOMED);
|
||||
|
||||
font::set_font(old_font);
|
||||
}
|
||||
|
||||
+143
-28
@@ -11,14 +11,14 @@
|
||||
#include <climits>
|
||||
#include <cctype>
|
||||
|
||||
|
||||
#include "freespace.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "debugconsole/console.h"
|
||||
#include "freespace.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "io/key.h"
|
||||
#include "localization/localize.h"
|
||||
#include "menuui/mainhallmenu.h"
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "popup/popup.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include "playermenu.h"
|
||||
#include "graphics/paths/PathRenderer.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
@@ -203,20 +204,18 @@ void player_select_eval_very_first_pilot();
|
||||
void player_select_commit();
|
||||
void player_select_cancel_create();
|
||||
|
||||
extern int delete_pilot_file(char *pilot_name);
|
||||
|
||||
/*
|
||||
* validate that a pilot/player was created with the same language FSO is currently using
|
||||
*
|
||||
* @param pilots callsign
|
||||
* @note not longer needed if intel entry "primary keys" change to a non-translated value
|
||||
*/
|
||||
bool valid_pilot_lang(char *callsign)
|
||||
bool valid_pilot_lang(const char *callsign)
|
||||
{
|
||||
char pilot_lang[LCL_LANG_NAME_LEN+1], current_lang[LCL_LANG_NAME_LEN+1];
|
||||
SCP_string filename = callsign;
|
||||
|
||||
filename += ".plr";
|
||||
filename += ".json";
|
||||
lcl_get_language_name(current_lang);
|
||||
|
||||
if (Pilot.verify(filename.c_str(), NULL, pilot_lang)) {
|
||||
@@ -353,7 +352,7 @@ void player_select_do()
|
||||
// Goober5000 - display a popup warning about problems in the mod
|
||||
if ((Global_warning_count > 10 || Global_error_count > 0) && !Startup_warning_dialog_displayed) {
|
||||
char text[512];
|
||||
sprintf(text, "Warning!\n\nThe currently active mod has generated %d warnings and/or errors during program startup. These could have been caused by anything from incorrectly formated table files to corrupt models. While FreeSpace Open will attempt to compensate for these issues, it cannot guarantee a trouble-free gameplay experience. Source Code Project staff cannot provide assistance or support for these problems, as they are caused by the mod's data files, not FreeSpace Open's source code.", Global_warning_count + Global_error_count);
|
||||
sprintf(text, "Warning!\n\nThe currently active mod has generated %d warnings and/or errors during program startup. These could have been caused by anything from incorrectly formated table files to corrupt models.\n\nWhile FreeSpace Open will attempt to compensate for these issues, it cannot guarantee a trouble-free gameplay experience.\n\nPlease contact the authors of the mod for assistance.", Global_warning_count + Global_error_count);
|
||||
popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, text);
|
||||
Startup_warning_dialog_displayed = true;
|
||||
}
|
||||
@@ -476,7 +475,7 @@ void player_select_close()
|
||||
}
|
||||
// if(Player_select_palette >= 0){
|
||||
// bm_release(Player_select_palette);
|
||||
//Player_select_palette = -1;
|
||||
//Player_select_palette = -1;GS_EVENT_MAIN_MENU
|
||||
// }
|
||||
|
||||
// setup the player struct
|
||||
@@ -502,9 +501,11 @@ void player_select_close()
|
||||
Player = NULL;
|
||||
} else {
|
||||
// NOTE: this may fail if there is no current campaign, it's not fatal
|
||||
Pilot.load_savefile(Player->current_campaign);
|
||||
Pilot.load_savefile(Player, Player->current_campaign);
|
||||
}
|
||||
|
||||
os_config_write_string(nullptr, "LastPlayer", Player->callsign);
|
||||
|
||||
if (Player_select_force_main_hall != "") {
|
||||
main_hall_init(Player_select_force_main_hall);
|
||||
}
|
||||
@@ -750,14 +751,14 @@ int player_select_create_new_pilot()
|
||||
void player_select_delete_pilot()
|
||||
{
|
||||
char filename[MAX_PATH_LEN + 1];
|
||||
int i, del_rval;
|
||||
int i;
|
||||
|
||||
// tack on the full path and the pilot file extension
|
||||
// build up the path name length
|
||||
// make sure we do this based upon whether we're in single or multiplayer mode
|
||||
strcpy_s( filename, Pilots[Player_select_pilot] );
|
||||
|
||||
del_rval = delete_pilot_file(filename);
|
||||
auto del_rval = delete_pilot_file(filename);
|
||||
|
||||
if ( !del_rval ) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, XSTR("Error\nFailed to delete pilot file. File may be read-only.", 1599));
|
||||
@@ -816,8 +817,6 @@ void player_select_scroll_list_down()
|
||||
// fill in the data on the last played pilot (callsign and is_multi or not)
|
||||
int player_select_get_last_pilot_info()
|
||||
{
|
||||
// TODO: Replace this with a function that does this properly for the new pilot code.
|
||||
|
||||
const char *last_player = os_config_read_string( NULL, "LastPlayer", NULL);
|
||||
|
||||
if (last_player == NULL) {
|
||||
@@ -850,11 +849,15 @@ int player_select_get_last_pilot()
|
||||
return 0;
|
||||
}
|
||||
|
||||
Get_file_list_filter = player_select_pilot_file_filter;
|
||||
|
||||
Player_select_num_pilots = cf_get_file_list_preallocated(
|
||||
MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.plr"), CF_SORT_TIME, nullptr,
|
||||
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
auto pilots = player_select_enumerate_pilots();
|
||||
// Copy the enumerated pilots into the appropriate local variables
|
||||
Player_select_num_pilots = static_cast<int>(pilots.size());
|
||||
for (auto i = 0; i < MAX_PILOTS; ++i) {
|
||||
if (i < static_cast<int>(pilots.size())) {
|
||||
strcpy_s(Pilots_arr[i], pilots[i].c_str());
|
||||
}
|
||||
Pilots[i] = Pilots_arr[i];
|
||||
}
|
||||
|
||||
Player_select_pilot = -1;
|
||||
idx = 0;
|
||||
@@ -889,12 +892,15 @@ void player_select_init_player_stuff(int mode)
|
||||
// set the select mode to single player for default
|
||||
Player_select_mode = mode;
|
||||
|
||||
// load up the list of players based upon the Player_select_mode (single or multiplayer)
|
||||
Get_file_list_filter = player_select_pilot_file_filter;
|
||||
|
||||
Player_select_num_pilots =
|
||||
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.plr"), CF_SORT_TIME,
|
||||
nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
auto pilots = player_select_enumerate_pilots();
|
||||
// Copy the enumerated pilots into the appropriate local variables
|
||||
Player_select_num_pilots = static_cast<int>(pilots.size());
|
||||
for (auto i = 0; i < MAX_PILOTS; ++i) {
|
||||
if (i < static_cast<int>(pilots.size())) {
|
||||
strcpy_s(Pilots_arr[i], pilots[i].c_str());
|
||||
}
|
||||
Pilots[i] = Pilots_arr[i];
|
||||
}
|
||||
|
||||
// if we have a "last_player", and they're in the list, bash them to the top of the list
|
||||
if (Player_select_last_pilot[0] != '\0') {
|
||||
@@ -1126,13 +1132,13 @@ void player_select_process_input(int k)
|
||||
void player_select_display_copyright()
|
||||
{
|
||||
int sx, sy, w;
|
||||
char Copyright_msg1[256], Copyright_msg2[256];
|
||||
char Copyright_msg2[256];
|
||||
|
||||
// strcpy_s(Copyright_msg1, XSTR("Descent: FreeSpace - The Great War, Copyright c 1998, Volition, Inc.", -1));
|
||||
gr_set_color_fast(&Color_white);
|
||||
|
||||
// sprintf(Copyright_msg1, NOX("FreeSpace 2"));
|
||||
get_version_string(Copyright_msg1, sizeof(Copyright_msg1));
|
||||
auto Copyright_msg1 = gameversion::get_version_string();
|
||||
if (Unicode_text_mode) {
|
||||
// Use a Unicode character if we are in unicode mode instead of using special characters
|
||||
strcpy_s(Copyright_msg2, XSTR("Copyright \xC2\xA9 1999, Volition, Inc. All rights reserved.", 385));
|
||||
@@ -1140,10 +1146,10 @@ void player_select_display_copyright()
|
||||
sprintf(Copyright_msg2, XSTR("Copyright %c 1999, Volition, Inc. All rights reserved.", 385), lcl_get_font_index(font::get_current_fontnum()) + 4);
|
||||
}
|
||||
|
||||
gr_get_string_size(&w, NULL, Copyright_msg1);
|
||||
gr_get_string_size(&w, nullptr, Copyright_msg1.c_str());
|
||||
sx = (int)std::lround((gr_screen.max_w_unscaled / 2) - w/2.0f);
|
||||
sy = (gr_screen.max_h_unscaled - 2) - 2*gr_get_font_height();
|
||||
gr_string(sx, sy, Copyright_msg1, GR_RESIZE_MENU);
|
||||
gr_string(sx, sy, Copyright_msg1.c_str(), GR_RESIZE_MENU);
|
||||
|
||||
gr_get_string_size(&w, NULL, Copyright_msg2);
|
||||
sx = (int)std::lround((gr_screen.max_w_unscaled / 2) - w/2.0f);
|
||||
@@ -1384,3 +1390,112 @@ void player_tips_popup()
|
||||
}
|
||||
} while(ret > 0);
|
||||
}
|
||||
|
||||
SCP_vector<SCP_string> player_select_enumerate_pilots() {
|
||||
// load up the list of players based upon the Player_select_mode (single or multiplayer)
|
||||
Get_file_list_filter = player_select_pilot_file_filter;
|
||||
|
||||
SCP_vector<SCP_string> pilots;
|
||||
cf_get_file_list(pilots, CF_TYPE_PLAYERS, "*.json", CF_SORT_TIME, nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
|
||||
return pilots;
|
||||
}
|
||||
|
||||
SCP_string player_get_last_player()
|
||||
{
|
||||
const char* last_player = os_config_read_string(nullptr, "LastPlayer", nullptr);
|
||||
|
||||
if (last_player == nullptr) {
|
||||
// No last player stored
|
||||
return SCP_string();
|
||||
}
|
||||
return SCP_string(last_player);
|
||||
}
|
||||
|
||||
void player_finish_select(const char* callsign, bool is_multi) {
|
||||
Player_num = 0;
|
||||
Player = &Players[0];
|
||||
Player->flags |= PLAYER_FLAGS_STRUCTURE_IN_USE;
|
||||
|
||||
// New pilot file makes no distinction between multi pilots and regular ones, so let's do this here.
|
||||
if (is_multi) {
|
||||
Player->flags |= PLAYER_FLAGS_IS_MULTI;
|
||||
}
|
||||
|
||||
// WMC - Set appropriate game mode
|
||||
if ( Player->flags & PLAYER_FLAGS_IS_MULTI ) {
|
||||
Game_mode = GM_MULTIPLAYER;
|
||||
} else {
|
||||
Game_mode = GM_NORMAL;
|
||||
}
|
||||
|
||||
// now read in a the pilot data
|
||||
if ( !Pilot.load_player(callsign, Player) ) {
|
||||
Error(LOCATION,"Couldn't load pilot file, bailing");
|
||||
Player = nullptr;
|
||||
} else {
|
||||
// NOTE: this may fail if there is no current campaign, it's not fatal
|
||||
Pilot.load_savefile(Player, Player->current_campaign);
|
||||
}
|
||||
os_config_write_string(nullptr, "LastPlayer", Player->callsign);
|
||||
|
||||
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
||||
}
|
||||
bool player_create_new_pilot(const char* callsign, bool is_multi, const char* copy_from_callsign) {
|
||||
SCP_string buf = callsign;
|
||||
|
||||
drop_white_space(buf);
|
||||
auto invalid_name = false;
|
||||
if (!isalpha(buf[0])) {
|
||||
invalid_name = true;
|
||||
} else {
|
||||
for (auto idx=1; buf[idx]; idx++) {
|
||||
if (!isalpha(buf[idx]) && !isdigit(buf[idx]) && !strchr(VALID_PILOT_CHARS, buf[idx])) {
|
||||
invalid_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buf.empty()) {
|
||||
invalid_name = true;
|
||||
}
|
||||
|
||||
if (invalid_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the new pilot, and write out his file
|
||||
// if this is the first guy, we should set the Player struct
|
||||
if (Player == nullptr) {
|
||||
Player = &Players[0];
|
||||
Player->reset();
|
||||
Player->flags |= PLAYER_FLAGS_STRUCTURE_IN_USE;
|
||||
}
|
||||
|
||||
if (copy_from_callsign != nullptr) {
|
||||
// attempt to read in the pilot file of the guy to be cloned
|
||||
if (!Pilot.load_player(copy_from_callsign, Player)) {
|
||||
Error(LOCATION, "Couldn't load pilot file, bailing");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy_s(Player->callsign, buf.c_str());
|
||||
init_new_pilot(Player, copy_from_callsign == nullptr);
|
||||
|
||||
// set him as being a multiplayer pilot if we're in the correct mode
|
||||
if (is_multi) {
|
||||
Player->flags |= PLAYER_FLAGS_IS_MULTI;
|
||||
Player->stats.flags |= STATS_FLAG_MULTIPLAYER;
|
||||
}
|
||||
|
||||
// create his pilot file
|
||||
Pilot.save_player(Player);
|
||||
|
||||
// unset the player
|
||||
Player->reset();
|
||||
Player = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -12,6 +12,8 @@
|
||||
#ifndef _PLAYER_SELECT_MENU_HEADER_FILE
|
||||
#define _PLAYER_SELECT_MENU_HEADER_FILE
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
// general defines
|
||||
#define PLAYER_SELECT_MODE_SINGLE 0 // looking through single player pilots
|
||||
#define PLAYER_SELECT_MODE_MULTI 1 // looking through multi player pilots
|
||||
@@ -39,6 +41,14 @@ void player_tips_close();
|
||||
extern int Player_select_screen_active;
|
||||
|
||||
// check the pilots language
|
||||
bool valid_pilot_lang(char *callsign);
|
||||
bool valid_pilot_lang(const char *callsign);
|
||||
|
||||
SCP_vector<SCP_string> player_select_enumerate_pilots();
|
||||
|
||||
SCP_string player_get_last_player();
|
||||
|
||||
void player_finish_select(const char* callsign, bool is_multi);
|
||||
|
||||
bool player_create_new_pilot(const char* callsign, bool is_multi, const char* copy_from_callsign = nullptr);
|
||||
|
||||
#endif
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "menuui/mainhallmenu.h"
|
||||
#include "menuui/readyroom.h"
|
||||
#include "menuui/techmenu.h" // for tech menu reset stuff
|
||||
#include "mission/missionload.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "mission/missioncampaign.h"
|
||||
#include "missionui/missionscreencommon.h"
|
||||
@@ -471,7 +472,9 @@ int build_standalone_mission_list_do_frame()
|
||||
|
||||
// tack on an extension
|
||||
strcat_s(filename, FS_MISSION_FILE_EXT);
|
||||
if (!get_mission_info(filename)) {
|
||||
|
||||
// check if we can list the mission and if loading basic info didn't return an error code
|
||||
if (!mission_is_ignored(filename) && !get_mission_info(filename)) {
|
||||
Standalone_mission_names[Num_standalone_missions_with_info] = vm_strdup(The_mission.name);
|
||||
Standalone_mission_flags[Num_standalone_missions_with_info] = The_mission.game_type;
|
||||
int y = Num_lines * (font_height + 2);
|
||||
@@ -481,7 +484,7 @@ int build_standalone_mission_list_do_frame()
|
||||
fs_builtin_mission *fb = game_find_builtin_mission(filename);
|
||||
if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)){
|
||||
flags |= READYROOM_FLAG_FROM_VOLITION;
|
||||
}
|
||||
}
|
||||
|
||||
// add the line
|
||||
sim_room_line_add(READYROOM_LINE_MISSION, Standalone_mission_names[Num_standalone_missions_with_info], Mission_filenames[Num_standalone_missions_with_info], list_x1 + M_TEXT_X, y, flags);
|
||||
|
||||
@@ -609,7 +609,8 @@ void brief_preload_icon_anim(brief_icon *bi)
|
||||
// force read of data from disk, so we don't glitch on initial playback
|
||||
if ( ga->first_frame == -1 ) {
|
||||
ga->first_frame = bm_load_animation(ga->filename, &ga->num_frames);
|
||||
Assert(ga->first_frame >= 0);
|
||||
if ( ga->first_frame < 0 )
|
||||
Warning(LOCATION, "Failed to load icon %s!", ga->filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,13 +625,13 @@ void brief_preload_fade_anim(brief_icon *bi)
|
||||
return;
|
||||
|
||||
// force read of data from disk, so we don't glitch on initial playback
|
||||
if ( ha->first_frame == -1 ) {
|
||||
if ( ha->first_frame == -1 )
|
||||
hud_anim_load(ha);
|
||||
Assert(ha->first_frame >= 0);
|
||||
}
|
||||
|
||||
gr_set_bitmap(ha->first_frame);
|
||||
gr_aabitmap(0, 0);
|
||||
if ( ha->first_frame >= 0 ) {
|
||||
gr_set_bitmap(ha->first_frame);
|
||||
gr_aabitmap(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void brief_preload_highlight_anim(brief_icon *bi)
|
||||
@@ -644,15 +645,15 @@ void brief_preload_highlight_anim(brief_icon *bi)
|
||||
return;
|
||||
|
||||
// force read of data from disk, so we don't glitch on initial playback
|
||||
if ( ha->first_frame == -1 ) {
|
||||
if ( ha->first_frame == -1 )
|
||||
hud_anim_load(ha);
|
||||
Assert(ha->first_frame >= 0);
|
||||
|
||||
if ( ha->first_frame >= 0 ) {
|
||||
bi->highlight_anim = *ha;
|
||||
|
||||
gr_set_bitmap(ha->first_frame);
|
||||
gr_aabitmap(0, 0);
|
||||
}
|
||||
|
||||
bi->highlight_anim = *ha;
|
||||
|
||||
gr_set_bitmap(ha->first_frame);
|
||||
gr_aabitmap(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -920,7 +921,6 @@ void brief_render_icon(int stage_num, int icon_num, float frametime, int selecte
|
||||
|
||||
ga = &bii->regular;
|
||||
if (ga->first_frame < 0) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "pilotfile/pilotfile.h"
|
||||
#include "playerman/player.h"
|
||||
#include "popup/popup.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "ship/ship.h"
|
||||
#include "starfield/supernova.h"
|
||||
#include "ui/ui.h"
|
||||
@@ -91,8 +92,6 @@ LOCAL UI_BUTTON Campaign_okb, Campaign_cancelb;
|
||||
campaign Campaign;
|
||||
|
||||
|
||||
bool campaign_is_ignored(const char *filename);
|
||||
|
||||
/**
|
||||
* Returns a string (which is malloced in this routine) of the name of the given freespace campaign file.
|
||||
* In the type field, we return if the campaign is a single player or multiplayer campaign.
|
||||
@@ -247,10 +246,10 @@ int mission_campaign_maybe_add(const char *filename)
|
||||
char *desc = NULL;
|
||||
int type, max_players;
|
||||
|
||||
// don't add ignored campaigns
|
||||
if (campaign_is_ignored(filename)) {
|
||||
return 0;
|
||||
}
|
||||
// don't add ignored campaigns
|
||||
if (campaign_is_ignored(filename)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( mission_campaign_get_info( filename, name, &type, &max_players, &desc) ) {
|
||||
if ( !MC_multiplayer && (type == CAMPAIGN_TYPE_SINGLE) ) {
|
||||
@@ -678,7 +677,7 @@ int mission_campaign_load( char *filename, player *pl, int load_savefile, bool r
|
||||
if (!Fred_running && load_savefile && (Campaign.type == CAMPAIGN_TYPE_SINGLE)) {
|
||||
// savefile can fail to load for numerous otherwise non-fatal reasons
|
||||
// if it doesn't load in that case then it will be (re)created at save
|
||||
if ( !Pilot.load_savefile(Campaign.filename) ) {
|
||||
if ( !Pilot.load_savefile(pl, Campaign.filename) ) {
|
||||
// but if the data is invalid for the savefile then it is fatal
|
||||
if ( Pilot.is_invalid() ) {
|
||||
Campaign.filename[0] = 0;
|
||||
@@ -892,23 +891,6 @@ void mission_campaign_delete_all_savefiles(char *pilot_name)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The following code only ever called by CSFE!!!!
|
||||
*/
|
||||
void campaign_savefile_load(char *fname, char *pname)
|
||||
{
|
||||
if (Campaign.type == CAMPAIGN_TYPE_SINGLE) {
|
||||
Game_mode &= ~GM_MULTIPLAYER;
|
||||
Game_mode &= GM_NORMAL;
|
||||
}
|
||||
else
|
||||
Game_mode |= GM_MULTIPLAYER;
|
||||
|
||||
strcpy_s(Player->callsign, pname);
|
||||
|
||||
Pilot.load_savefile(fname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the internal veriables of the campaign structure so the player can play the next mission.
|
||||
* If there are no more missions available in the campaign, this function returns -1, else 0 if the mission was
|
||||
@@ -1220,6 +1202,9 @@ void mission_campaign_mission_over(bool do_next_mission)
|
||||
Pilot.save_savefile();
|
||||
}
|
||||
|
||||
// runs the new scripting conditional hook, "On Campaign Mission Accept" --wookieejedi
|
||||
Script_system.RunCondition(CHA_CMISSIONACCEPT);
|
||||
|
||||
} else {
|
||||
// free up the goals and events which were just malloced. It's kind of like erasing any fact
|
||||
// that the player played this mission in the campaign.
|
||||
@@ -1244,7 +1229,7 @@ void mission_campaign_mission_over(bool do_next_mission)
|
||||
|
||||
Sexp_nodes[mission_obj->formula].value = SEXP_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
if (do_next_mission)
|
||||
mission_campaign_next_mission(); // sets up whatever needs to be set to actually play next mission
|
||||
}
|
||||
@@ -1659,9 +1644,11 @@ bool campaign_is_ignored(const char *filename)
|
||||
{
|
||||
SCP_string filename_no_ext = filename;
|
||||
drop_extension(filename_no_ext);
|
||||
std::transform(filename_no_ext.begin(), filename_no_ext.end(), filename_no_ext.begin(),
|
||||
[](char c) { return (char)::tolower(c); });
|
||||
|
||||
for (SCP_vector<SCP_string>::iterator ii = Ignored_campaigns.begin(); ii != Ignored_campaigns.end(); ++ii) {
|
||||
if (*ii == filename_no_ext) {
|
||||
for (auto &ii: Ignored_campaigns) {
|
||||
if (ii == filename_no_ext) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1841,7 +1828,7 @@ void mission_campaign_exit_loop()
|
||||
* all previous missions marked skipped
|
||||
* this relies on correct mission ordering in the campaign file
|
||||
*/
|
||||
void mission_campaign_jump_to_mission(char *name, bool no_skip)
|
||||
void mission_campaign_jump_to_mission(const char* name, bool no_skip)
|
||||
{
|
||||
int i = 0, mission_num = -1;
|
||||
char dest_name[64], *p;
|
||||
|
||||
@@ -182,6 +182,8 @@ int mission_campaign_load_by_name_csfe( char *filename, char *callsign );
|
||||
// load up and initialize a new campaign
|
||||
int mission_campaign_load( char *filename, player *pl = NULL, int load_savefile = 1, bool reset_stats = true );
|
||||
|
||||
bool campaign_is_ignored(const char *filename);
|
||||
|
||||
// function to save the state of the campaign between missions or to load a campaign save file
|
||||
extern int mission_campaign_save( void );
|
||||
|
||||
@@ -230,8 +232,6 @@ int mission_campaign_savefile_save();
|
||||
int campaign_savefile_save(char *pname);
|
||||
// Deletes the campaign save camp under the player name pname
|
||||
void campaign_delete_save( char *cfn, char *pname);
|
||||
// Loads campaign camp from fname under player name pname
|
||||
void campaign_savefile_load(char *fname, char *pname);
|
||||
|
||||
// get name and type of specified campaign file
|
||||
int mission_campaign_get_info(const char *filename, char *name, int *type, int *max_players, char **desc = NULL);
|
||||
@@ -264,7 +264,7 @@ void mission_campaign_skip_to_next(int start_game = 1);
|
||||
void mission_campaign_exit_loop();
|
||||
|
||||
// jump to specified mission
|
||||
void mission_campaign_jump_to_mission(char *name, bool no_skip = false);
|
||||
void mission_campaign_jump_to_mission(const char* name, bool no_skip = false);
|
||||
|
||||
// stuff for the end of the campaign of the single player game
|
||||
void mission_campaign_end_init();
|
||||
|
||||
@@ -29,6 +29,8 @@ extern mission The_mission; // need to send this info to the briefing
|
||||
extern int shifted_ascii_table[];
|
||||
extern int ascii_table[];
|
||||
|
||||
SCP_vector<SCP_string> Ignored_missions;
|
||||
|
||||
// -----------------------------------------------
|
||||
// For recording most recent missions played
|
||||
// -----------------------------------------------
|
||||
@@ -41,9 +43,9 @@ int Num_recent_missions;
|
||||
//
|
||||
// Update the Recent_missions[][] array
|
||||
//
|
||||
void ml_update_recent_missions(char *filename)
|
||||
void ml_update_recent_missions(const char* filename)
|
||||
{
|
||||
char tmp[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN], *p;
|
||||
char tmp[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN];
|
||||
int i,j;
|
||||
|
||||
|
||||
@@ -52,7 +54,7 @@ void ml_update_recent_missions(char *filename)
|
||||
}
|
||||
|
||||
// get a pointer to just the basename of the filename (including extension)
|
||||
p = strrchr(filename, DIR_SEPARATOR_CHAR);
|
||||
const char* p = strrchr(filename, DIR_SEPARATOR_CHAR);
|
||||
if ( p == NULL ) {
|
||||
p = filename;
|
||||
} else {
|
||||
@@ -76,12 +78,28 @@ void ml_update_recent_missions(char *filename)
|
||||
Assert(Num_recent_missions <= MAX_RECENT_MISSIONS);
|
||||
}
|
||||
|
||||
bool mission_is_ignored(const char *filename)
|
||||
{
|
||||
SCP_string filename_no_ext = filename;
|
||||
drop_extension(filename_no_ext);
|
||||
std::transform(filename_no_ext.begin(), filename_no_ext.end(), filename_no_ext.begin(),
|
||||
[](char c) { return (char)::tolower(c); });
|
||||
|
||||
for (auto &ii: Ignored_missions) {
|
||||
if (ii == filename_no_ext) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mission_load takes no parameters.
|
||||
// It sets the following global variables
|
||||
// Game_current_mission_filename
|
||||
|
||||
// returns -1 if failed, 0 if successful
|
||||
int mission_load(char *filename_ext)
|
||||
int mission_load(const char* filename_ext)
|
||||
{
|
||||
TRACE_SCOPE(tracing::LoadMissionLoad);
|
||||
|
||||
@@ -100,6 +118,11 @@ int mission_load(char *filename_ext)
|
||||
*ext = 0; // remove any extension!
|
||||
}
|
||||
|
||||
if (mission_is_ignored(filename)) {
|
||||
mprintf(("MISSION LOAD: Tried to load an ignored mission! Aborting..."));
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcat_s(filename, FS_MISSION_FILE_EXT);
|
||||
|
||||
// does the magical mission parsing
|
||||
|
||||
@@ -21,11 +21,16 @@
|
||||
extern char Recent_missions[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN];
|
||||
extern int Num_recent_missions;
|
||||
|
||||
extern SCP_vector<SCP_string> Ignored_missions;
|
||||
|
||||
// Mission_load takes no parameters.
|
||||
// It sets the following global variables:
|
||||
// Game_current_mission_filename
|
||||
|
||||
int mission_load(char *filename_ext);
|
||||
int mission_load(const char* filename_ext);
|
||||
|
||||
bool mission_is_ignored(const char *filename);
|
||||
|
||||
|
||||
// Functions for mission load menu
|
||||
void mission_load_menu_init();
|
||||
|
||||
@@ -1602,14 +1602,14 @@ void message_queue_process()
|
||||
Script_system.SetHookVar("SenderString", 's', who_from);
|
||||
|
||||
builtinMessage = q->builtin_type != -1;
|
||||
Script_system.SetHookVar("Builtin", 'b', &builtinMessage);
|
||||
Script_system.SetHookVar("Builtin", 'b', builtinMessage);
|
||||
|
||||
if (Message_shipnum >= 0) {
|
||||
sender = &Objects[Ships[Message_shipnum].objnum];
|
||||
}
|
||||
Script_system.SetHookObject("Sender", sender);
|
||||
|
||||
Script_system.RunCondition(CHA_MSGRECEIVED, 0, NULL, sender);
|
||||
Script_system.RunCondition(CHA_MSGRECEIVED, sender);
|
||||
|
||||
Script_system.RemHookVars(5, "Name", "Message", "SenderString", "Builtin", "Sender");
|
||||
|
||||
@@ -2155,7 +2155,7 @@ int message_is_playing()
|
||||
// Functions below pertain only to personas!!!!
|
||||
|
||||
// given a character string, try to find the persona index
|
||||
int message_persona_name_lookup( char *name )
|
||||
int message_persona_name_lookup(const char* name)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -2342,7 +2342,7 @@ void message_pagein_mission_messages()
|
||||
// ---------------------------------------------------
|
||||
// Add and remove messages - used by autopilot code now, but useful elswhere
|
||||
|
||||
bool add_message(const char *name, char *message, int persona_index, int multi_team)
|
||||
bool add_message(const char* name, const char* message, int persona_index, int multi_team)
|
||||
{
|
||||
MissionMessage msg;
|
||||
strcpy_s(msg.name, name);
|
||||
@@ -2357,7 +2357,7 @@ bool add_message(const char *name, char *message, int persona_index, int multi_t
|
||||
return true;
|
||||
}
|
||||
|
||||
bool change_message(const char *name, char *message, int persona_index, int multi_team)
|
||||
bool change_message(const char* name, const char* message, int persona_index, int multi_team)
|
||||
{
|
||||
for (int i = Num_builtin_messages; i < Num_messages; i++)
|
||||
{
|
||||
|
||||
@@ -211,7 +211,7 @@ void message_send_unique_to_player( char *id, void *data, int source, int priori
|
||||
void message_send_builtin_to_player( int type, ship *shipp, int priority, int timing, int group, int delay, int multi_target, int multi_team_filter );
|
||||
|
||||
// functions to deal with personas
|
||||
int message_persona_name_lookup( char *name );
|
||||
int message_persona_name_lookup(const char* name);
|
||||
|
||||
// preload mission messages (this is called by the level paging code when running with low memory)
|
||||
void message_pagein_mission_messages();
|
||||
@@ -231,7 +231,7 @@ void message_load_wave(int index, const char *filename);
|
||||
|
||||
// these two are probably safe
|
||||
// if change_message fails to find the message it'll fall through to add_message
|
||||
bool add_message(const char *name, char *message, int persona_index, int multi_team);
|
||||
bool change_message(const char *name, char *message, int persona_index, int multi_team);
|
||||
bool add_message(const char* name, const char* message, int persona_index, int multi_team);
|
||||
bool change_message(const char* name, const char* message, int persona_index, int multi_team);
|
||||
|
||||
#endif
|
||||
@@ -1837,6 +1837,7 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
{
|
||||
int i, j, k, objnum, shipnum;
|
||||
int anchor_objnum = -1;
|
||||
bool brought_in_docked_wing = false;
|
||||
ai_info *aip;
|
||||
ship_subsys *ptr;
|
||||
ship *shipp;
|
||||
@@ -1865,7 +1866,10 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
if (object_is_docked(p_objp) && !(p_objp->flags[Mission::Parse_Object_Flags::SF_Dock_leader]) && (p_objp->wingnum >= 0))
|
||||
{
|
||||
if (!Fred_running)
|
||||
{
|
||||
parse_bring_in_docked_wing(p_objp, p_objp->wingnum, shipnum);
|
||||
brought_in_docked_wing = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if arriving through knossos, adjust objpj->pos to plane of knossos and set flag
|
||||
@@ -2439,13 +2443,14 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
}
|
||||
|
||||
// If the ship is in a wing, this will be done in mission_set_wing_arrival_location() instead
|
||||
if (Game_mode & GM_IN_MISSION && shipp->wingnum == -1) {
|
||||
// If the ship is in a wing, but the wing is docked then addition of bool brought_in_docked_wing accounts for that status --wookieejedi
|
||||
if (Game_mode & GM_IN_MISSION && ((shipp->wingnum == -1) || (brought_in_docked_wing))) {
|
||||
if (anchor_objnum >= 0)
|
||||
Script_system.SetHookObjects(2, "Ship", &Objects[objnum], "Parent", &Objects[anchor_objnum]);
|
||||
else
|
||||
Script_system.SetHookObjects(2, "Ship", &Objects[objnum], "Parent", NULL);
|
||||
|
||||
Script_system.RunCondition(CHA_ONSHIPARRIVE, 0, NULL, &Objects[objnum]);
|
||||
Script_system.RunCondition(CHA_ONSHIPARRIVE, &Objects[objnum]);
|
||||
Script_system.RemHookVars(2, "Ship", "Parent");
|
||||
}
|
||||
|
||||
@@ -6142,7 +6147,7 @@ void mission_set_wing_arrival_location( wing *wingp, int num_to_set )
|
||||
else
|
||||
Script_system.SetHookObjects(2, "Ship", objp, "Parent", NULL);
|
||||
|
||||
Script_system.RunCondition(CHA_ONSHIPARRIVE, 0, NULL, objp);
|
||||
Script_system.RunCondition(CHA_ONSHIPARRIVE, objp);
|
||||
Script_system.RemHookVars(2, "Ship", "Parent");
|
||||
|
||||
if (wingp->arrival_location != ARRIVE_FROM_DOCK_BAY) {
|
||||
@@ -6232,9 +6237,12 @@ void reset_arrival_to_false(p_object *pobjp, bool reset_wing)
|
||||
|
||||
/**
|
||||
* In both retail and SCP, the dock "leader" is defined as the only guy in his
|
||||
* group with a non-false arrival cue
|
||||
* group with a non-false arrival cue.
|
||||
*
|
||||
* If we are forcing a leader, that means *none* of the ships in this dock group
|
||||
* have a non-false arrival cue, so we just need to pick one
|
||||
*/
|
||||
void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info *infop)
|
||||
void parse_object_mark_dock_leader_sub(p_object *pobjp, p_dock_function_info *infop, bool force_a_leader)
|
||||
{
|
||||
int cue_to_check;
|
||||
|
||||
@@ -6250,7 +6258,7 @@ void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info
|
||||
}
|
||||
|
||||
// is he a leader (using the definition above)?
|
||||
if (!sexp_is_locked_false(cue_to_check))
|
||||
if (!sexp_is_locked_false(cue_to_check) || force_a_leader)
|
||||
{
|
||||
p_object *existing_leader;
|
||||
|
||||
@@ -6280,6 +6288,16 @@ void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info
|
||||
}
|
||||
}
|
||||
|
||||
void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info *infop)
|
||||
{
|
||||
parse_object_mark_dock_leader_sub(pobjp, infop, false);
|
||||
}
|
||||
|
||||
void parse_object_choose_arbitrary_dock_leader_helper(p_object *pobjp, p_dock_function_info *infop)
|
||||
{
|
||||
parse_object_mark_dock_leader_sub(pobjp, infop, true);
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
void parse_object_set_handled_flag_helper(p_object *pobjp, p_dock_function_info * /*infop*/)
|
||||
{
|
||||
@@ -6389,6 +6407,10 @@ void mission_parse_set_up_initial_docks()
|
||||
if (dfi.maintained_variables.int_value == 0)
|
||||
{
|
||||
Warning(LOCATION, "No dock leaders found in the docking group containing %s. The group will not appear in-mission!\n", pobjp->name);
|
||||
|
||||
// for FRED, we must arbitrarily choose a dock leader, otherwise the entire docked group will not be loaded
|
||||
if (Fred_running)
|
||||
dock_evaluate_all_docked_objects(pobjp, &dfi, parse_object_choose_arbitrary_dock_leader_helper);
|
||||
}
|
||||
else if (dfi.maintained_variables.int_value > 1)
|
||||
{
|
||||
|
||||
@@ -839,9 +839,9 @@ void message_training_setup(int m, int length, char *special_message)
|
||||
training_process_message(Training_buf);
|
||||
Training_num_lines = split_str(Training_buf, TRAINING_LINE_WIDTH, Training_line_lengths, Training_lines, MAX_TRAINING_MESSAGE_LINES);
|
||||
|
||||
Assert( Training_num_lines >= 0 );
|
||||
Assert(Training_num_lines >= 0);
|
||||
|
||||
if (message_play_training_voice(Messages[m].wave_info.index) < 0) {
|
||||
if ((message_play_training_voice(Messages[m].wave_info.index) < 0) || (Master_voice_volume <= 0)) {
|
||||
if (length > 0)
|
||||
Training_message_timestamp = timestamp(length * 1000);
|
||||
else
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "popup/popup.h"
|
||||
#include "render/3d.h"
|
||||
#include "ship/ship.h"
|
||||
#include "sound/fsspeech.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
@@ -1929,6 +1930,11 @@ void commit_pressed()
|
||||
if (!(The_mission.flags[Mission::Mission_Flags::No_briefing]))
|
||||
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
|
||||
|
||||
// plieblang - resume simulated speech if necessary
|
||||
if (!Player->auto_advance) {
|
||||
fsspeech_pause(false);
|
||||
}
|
||||
|
||||
// save the player loadout
|
||||
if ( !(Game_mode & GM_MULTIPLAYER) ) {
|
||||
strcpy_s(Player_loadout.filename, Game_current_mission_filename);
|
||||
|
||||
@@ -4082,8 +4082,7 @@ void wl_apply_current_loadout_to_all_ships_in_current_wing()
|
||||
if ((result == 0) || (result == 2))
|
||||
{
|
||||
SCP_string temp;
|
||||
sprintf(temp, XSTR("Insufficient %s available to arm %s", 1632),
|
||||
Weapon_info[weapon_type_to_add].get_display_string());
|
||||
sprintf(temp, XSTR("Insufficient %s available to arm %s", 1632), Weapon_info[weapon_type_to_add].get_display_string(), ship_name);
|
||||
error_messages.push_back(temp);
|
||||
|
||||
error_flag = true;
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
#include "globalincs/version.h"
|
||||
#include "localization/localize.h"
|
||||
#include "mission/missioncampaign.h"
|
||||
#include "mission/missionload.h"
|
||||
#include "mission/missionmessage.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "mod_table/mod_table.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "sound/sound.h"
|
||||
#include "playerman/player.h"
|
||||
|
||||
int Directive_wait_time;
|
||||
bool True_loop_argument_sexps;
|
||||
@@ -121,10 +123,34 @@ void parse_mod_table(const char *filename)
|
||||
mprintf(("Game Settings Table: Removed extension on ignored campaign file name %s\n", campaign_name.c_str()));
|
||||
}
|
||||
|
||||
// we want case-insensitive matching, so make this lowercase
|
||||
std::transform(campaign_name.begin(), campaign_name.end(), campaign_name.begin(),
|
||||
[](char c) { return (char)::tolower(c); });
|
||||
|
||||
Ignored_campaigns.push_back(campaign_name);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this feature does not ignore missions that are contained in campaigns
|
||||
if (optional_string("#Ignored Mission File Names")) {
|
||||
SCP_string mission_name;
|
||||
|
||||
while (optional_string("$Mission File Name:")) {
|
||||
stuff_string(mission_name, F_NAME);
|
||||
|
||||
// remove extension?
|
||||
if (drop_extension(mission_name)) {
|
||||
mprintf(("Game Settings Table: Removed extension on ignored mission file name %s\n", mission_name.c_str()));
|
||||
}
|
||||
|
||||
// we want case-insensitive matching, so make this lowercase
|
||||
std::transform(mission_name.begin(), mission_name.end(), mission_name.begin(),
|
||||
[](char c) { return (char)::tolower(c); });
|
||||
|
||||
Ignored_missions.push_back(mission_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Red-alert applies to delayed ships:")) {
|
||||
stuff_boolean(&Red_alert_applies_to_delayed_ships);
|
||||
if (Red_alert_applies_to_delayed_ships) {
|
||||
@@ -376,6 +402,18 @@ void parse_mod_table(const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Player warpout speed:")) {
|
||||
stuff_float(&Player_warpout_speed);
|
||||
}
|
||||
|
||||
if (optional_string("$Target warpout match percent:")) {
|
||||
stuff_float(&Target_warpout_match_percent);
|
||||
}
|
||||
|
||||
if (optional_string("$Minimum player warpout time:")) {
|
||||
stuff_float(&Minimum_player_warpout_time);
|
||||
}
|
||||
|
||||
required_string("#END");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
|
||||
+2
-2
@@ -642,7 +642,7 @@ public:
|
||||
bool is_transparent;
|
||||
|
||||
int FindTexture(int bm_handle);
|
||||
int FindTexture(char *name);
|
||||
int FindTexture(const char* name);
|
||||
|
||||
void PageIn();
|
||||
void PageOut(bool release);
|
||||
@@ -1005,7 +1005,7 @@ extern void submodel_get_two_random_points_better(int model_num, int submodel_nu
|
||||
// Returns the index. second functions returns the index of the docking bay with
|
||||
// the specified name
|
||||
extern int model_find_dock_index(int modelnum, int dock_type, int index_to_start_at = 0);
|
||||
extern int model_find_dock_name_index(int modelnum, char *name);
|
||||
extern int model_find_dock_name_index(int modelnum, const char* name);
|
||||
|
||||
// returns the actual name of a docking point on a model, needed by Fred.
|
||||
char *model_get_dock_name(int modelnum, int index);
|
||||
|
||||
@@ -35,7 +35,7 @@ const char *Animation_type_names[MAX_TRIGGER_ANIMATION_TYPES] =
|
||||
"turret-fired"
|
||||
};
|
||||
|
||||
int model_anim_match_type(char *p)
|
||||
int model_anim_match_type(const char* p)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#ifndef _MODELANIM_H
|
||||
#define _MODELANIM_H
|
||||
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include <climits>
|
||||
|
||||
#define MAX_TRIGGERED_ANIMATIONS 15
|
||||
@@ -149,7 +151,7 @@ void model_anim_set_initial_states(ship *shipp);
|
||||
void model_anim_fix_reverse_times(ship_info *sip);
|
||||
|
||||
// gets animation type index from string name
|
||||
int model_anim_match_type(char *p);
|
||||
int model_anim_match_type(const char* p);
|
||||
|
||||
// starts an animation of a certan type that may be assosiated with a submodel of a ship (returns true if an animation was started)
|
||||
bool model_anim_start_type(ship_subsys *pss, int animation_type, int subtype, int direction, bool instant = false); // for a specific subsystem
|
||||
|
||||
Loaded 100 of 291 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user