Compare commits

..
Author SHA1 Message Date
John Fernandez ce28f60cf1 Whoops 2023-12-19 11:48:21 -05:00
John Fernandez 3e858b601e Attempt without downloading Vulkan SDK 2023-12-19 11:36:43 -05:00
John Fernandez f2314970bb Test Changes To coverity workflow 2023-12-19 11:30:04 -05:00
2679 changed files with 198959 additions and 348722 deletions

No files matched your search

+1 -14
View File
@@ -4,28 +4,20 @@ modernize-*,\
-modernize-avoid-c-arrays,\
-modernize-make-unique,\
-modernize-raw-string-literal,\
-modernize-use-default-member-init,\
-modernize-use-nodiscard,\
-modernize-use-trailing-return-type,\
-modernize-use-using,\
performance-*,\
-performance-no-int-to-ptr,\
-performance-type-promotion-in-math-fn,\
misc-*,\
-misc-include-cleaner,\
-misc-macro-parentheses,\
-misc-misplaced-widening-cast,\
-misc-no-recursion,\
-misc-non-private-member-variables-in-classes,\
-misc-static-assert,\
-misc-unused-parameters,\
-misc-use-anonymous-namespace,\
readability-*,\
-readability-avoid-const-params-in-decls,\
-readability-else-after-return,\
-readability-function-cognitive-complexity,\
-readability-function-size,\
-readability-identifier-length,\
-readability-identifier-naming,\
-readability-implicit-bool-conversion,\
-readability-inconsistent-declaration-parameter-name,\
@@ -37,18 +29,13 @@ readability-*,\
"
WarningsAsErrors: ''
HeaderFilterRegex: 'code/.*$|freespace2/.*$|qtfred/.*$|test/src/.*$|build/.*$'
AnalyzeTemporaryDtors: false
CheckOptions:
- key: 'misc-assert-side-effect.AssertMacros'
value: 'assert,Assert,Assertion'
- key: 'misc-const-correctness.AnalyzeValues'
value: 'false'
- key: 'misc-const-correctness.TransformValues'
value: 'false'
- key: 'modernize-use-emplace.ContainersWithPushBack'
value: 'std::vector;std::deque;std::list;SCP_vector;SCP_deque;SCP_list'
- key: 'readability-braces-around-statements.ShortStatementLines'
value: '4' # Avoid flagging simple if (...) return false; statements
- key: 'performance-move-const-arg.CheckTriviallyCopyableMove' # This isn't actually performance relevant, but using move on trivially copyable types can well indicate that the variable should not be used anymore, such as when passing a builder type to the finialization function
value: 'false'
...
+119 -181
View File
@@ -5,38 +5,34 @@ on:
tags:
- 'nightly_*'
env:
QT_VERSION: 5.12.12
jobs:
build_linux:
strategy:
matrix:
configuration: [FastDebug, Release]
os: [ubuntu-latest, ubuntu-24.04-arm]
include:
- os: ubuntu-latest
arch: x86_64
- os: ubuntu-24.04-arm
arch: arm64
name: Linux
runs-on: ${{ matrix.os }}
container: ghcr.io/scp-fs2open/linux_build:sha-ab87451
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: gcc-9
COMPILER: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
run: ninja -k 20 all
run: |
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
- name: Run Tests
working-directory: ./build
env:
@@ -49,45 +45,33 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: linux-${{ matrix.configuration }}-${{ matrix.arch }}
name: linux-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/install/*.AppImage
linux_zip:
name: Build Linux distribution zip
needs: build_linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
strategy:
matrix:
arch: [x86_64, arm64]
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: '0'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: linux-Release-${{ matrix.arch }}
name: linux-Release
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: linux-FastDebug-${{ matrix.arch }}
name: linux-FastDebug
path: builds
- name: Fix permissions
working-directory: ./builds
shell: bash
run: chmod 755 *.AppImage
- name: Create Distribution package
working-directory: ./builds
env:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
- name: Upload result package
working-directory: ./builds
@@ -102,169 +86,119 @@ jobs:
strategy:
matrix:
configuration: [FastDebug, Release]
os: [windows-2025, windows-11-arm]
arch: [Win32, x64, ARM64]
simd: [SSE2, ""]
exclude:
- arch: Win32
os: windows-11-arm
- arch: x64
os: windows-11-arm
- arch: ARM64
os: windows-2025
- os: windows-2025
simd: ""
- os: windows-11-arm
simd: SSE2
arch: [Win32, x64]
simd: [SSE2]
name: Windows
runs-on: ${{ matrix.os }}
runs-on: windows-2019
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Install v143 ATL/MFC
shell: pwsh
run: ci/windows/install_v143_atlmfc.ps1
# Tree A: static CRT (/MT) for FSO + FRED2 (no Qt dependency needed)
- name: Configure CMake (static CRT /MT - FSO + FRED2)
# - name: Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCHITECTURE: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
shell: bash
run: |
mkdir build-mt
cd build-mt
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_TESTS=ON -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
-DFSO_BUILD_QTFRED=OFF -G "Visual Studio 18 2026" -T "v143" \
-DCMAKE_BUILD_TYPE=$CONFIGURATION ..
- name: Compile (static CRT)
working-directory: ./build-mt
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
cmake --install . --config "$CONFIGURATION"
ls -alR "$(pwd)/install"
# Tree B: dynamic CRT (/MD) for QtFRED only (matches Qt's prebuilt /MD runtime)
# Skipped on Win32: Qt6 has no 32-bit Windows support, so CMake force-disables
# FSO_BUILD_QTFRED there and the qtfred target would not exist
- name: Configure CMake (dynamic CRT /MD - QtFRED)
if: matrix.arch != 'Win32'
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCHITECTURE: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
shell: bash
run: |
mkdir build-md
cd build-md
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_TESTS=OFF -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_FRED2=OFF -DQT_USE_PRECOMPILED=ON \
-G "Visual Studio 18 2026" -T "v143" -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
- name: Compile (dynamic CRT)
if: matrix.arch != 'Win32'
working-directory: ./build-md
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
cmake --build . --config "$CONFIGURATION" --target qtfred -- /verbosity:minimal
cmake --install . --config "$CONFIGURATION" --component qtFRED
ls -alR "$(pwd)/install"
# Merge both trees into the single install dir the zip job consumes
- name: Merge installs
shell: bash
run: |
mkdir -p build/install
# build-md does not exist on Win32 (no QtFRED there)
if [ -d build-md/install ]; then
cp -r build-md/install/. build/install/
mkdir build
cd build
if [ "$ARCHITECTURE" = "Win32" ]; then
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
else
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
fi
cp -r build-mt/install/. build/install/
ls -alR build/install
- name: Compile
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
cmake --build . --config "$CONFIGURATION" --target INSTALL -- /verbosity:minimal
ls -alR "$(pwd)/install"
- name: Run Tests
working-directory: ./build-mt
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
shell: bash
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
- name: Set artifact id
shell: bash
run: |
id=
if [ -n "${{ matrix.simd }}" ]; then
id="${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}"
else
id="${{ matrix.configuration }}-${{ matrix.arch }}"
fi
echo "artifact_id=${id}" >> $GITHUB_ENV
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: windows-${{ env.artifact_id }}
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
path: ${{ github.workspace }}/build/install/*
windows_zip:
name: Build Windows distribution zip
needs: build_windows
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [Win32, x64, ARM64]
simd: [SSE2, ""]
exclude:
- arch: Win32
simd: ""
- arch: x64
simd: ""
- arch: ARM64
simd: SSE2
arch: [Win32, x64]
simd: [SSE2]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: '0'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Set artifact id
shell: bash
run: |
id=
if [ -n "${{ matrix.simd }}" ]; then
id="${{ matrix.arch }}-${{ matrix.simd }}"
else
id="${{ matrix.arch }}"
fi
echo "artifact_id=${id}" >> $GITHUB_ENV
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: windows-Release-${{ env.artifact_id }}
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: windows-FastDebug-${{ env.artifact_id }}
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Create Distribution package
working-directory: ./builds
shell: bash
env:
ID: ${{ env.artifact_id }}
ARCH: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
- name: Upload result package
working-directory: ./builds
@@ -285,14 +219,32 @@ jobs:
name: Mac
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
# - name: Cache Qt
# id: cache-qt-mac
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
# py7zrversion: '==0.19.*'
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: 0
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Set up test version
shell: bash
run: |
@@ -305,10 +257,11 @@ jobs:
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja all
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
- name: Run Tests
working-directory: ./build
env:
@@ -316,25 +269,13 @@ jobs:
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Sign builds
working-directory: ./build/bin
run: |
# make sure OpenAL framework is signed
find . -name OpenAL -type f | while read xx; do codesign --force -s - $xx; done
find . -name OpenAL.framework -type d | while read xx; do codesign --force -s - $xx; done
# make sure dylibs are signed
find . -name \*.dylib -type f | while read xx; do codesign --force -s - $xx; done
# sign binaries
find . -perm +111 -type f | grep MacOS | while read xx; do codesign --force -s - $xx; done
# sign apps
find . -name \*.app -maxdepth 1 | while read xx; do codesign --force -s - $xx; done
- name: Package build result
working-directory: ./build/bin
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
# Ref: https://github.com/actions/runner-images/issues/2619
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
@@ -342,27 +283,24 @@ jobs:
name: Build Mac distribution zip
needs: build_mac
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v2
name: Checkout
with:
submodules: true
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: mac-Release-${{ matrix.arch }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: mac-FastDebug-${{ matrix.arch }}
path: builds
+125 -189
View File
@@ -5,6 +5,9 @@ on:
tags:
- 'release_*'
env:
QT_VERSION: 5.12.12
jobs:
create_release:
name: Create GitHub release
@@ -38,36 +41,29 @@ jobs:
# Run this job for each configuration
# The current config running is accesible with `matrix.configuration`
configuration: [FastDebug, Release]
os: [ubuntu-latest, ubuntu-24.04-arm]
include:
- os: ubuntu-latest
arch: x86_64
- os: ubuntu-24.04-arm
arch: arm64
name: Linux
needs: create_release # Don't run this job until create_release is done and successful
runs-on: ${{ matrix.os }}
container: ghcr.io/scp-fs2open/linux_build:sha-ab87451
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
# checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
name: Checkout
with:
submodules: true # `true` to checkout submodules, `recursive` to recursively checkout submodules
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: gcc-9
COMPILER: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
run: ninja -k 20 all
run: |
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
- name: Run Tests
working-directory: ./build
env:
@@ -80,7 +76,7 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
# Upload the url file for use with other runners
# upload-artifact.inputs:
# if-no-files-found=warn What to do if path fails to find any files.
@@ -91,52 +87,40 @@ jobs:
# 0 Use default retention policy of the repo
# 1~90 Min 1, Max 90 days to keep the artifact unless changed by repo settings page
with:
name: linux-${{ matrix.configuration }}-${{ matrix.arch }}
name: linux-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/install/*.AppImage
linux_zip:
name: Build Linux distribution zip
needs: build_linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
strategy:
matrix:
arch: [x86_64, arm64]
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: '0' # value 0 to fetch all history and tags for all branches
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Download Release builds
# Grab the release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: linux-Release-${{ matrix.arch }}
name: linux-Release
path: builds
- name: Download FastDebug builds
# Grab the debug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: linux-FastDebug-${{ matrix.arch }}
name: linux-FastDebug
path: builds
- name: Fix permissions
working-directory: ./builds
shell: bash
run: chmod 755 *.AppImage
- name: Create Distribution package
# Zip both builds together
id: generate_package
working-directory: ./builds
env:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
- name: Upload result package
# Stash the result to artifact filespace
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.package_name }}
path: ${{ steps.generate_package.outputs.package_path }}
@@ -152,175 +136,123 @@ jobs:
strategy:
matrix:
configuration: [FastDebug, Release]
os: [windows-2025, windows-11-arm]
arch: [Win32, x64, ARM64]
simd: [SSE2, AVX, ""]
exclude:
- arch: Win32
os: windows-11-arm
- arch: x64
os: windows-11-arm
- arch: ARM64
os: windows-2025
- os: windows-2025
simd: ""
- os: windows-11-arm
simd: SSE2
- os: windows-11-arm
simd: AVX
arch: [Win32, x64]
simd: [SSE2, AVX]
needs: create_release
name: Windows
runs-on: ${{ matrix.os }}
runs-on: windows-2019
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
# Checkout repo
name: Checkout
with:
submodules: true
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Install v143 ATL/MFC
shell: pwsh
run: ci/windows/install_v143_atlmfc.ps1
# Tree A: static CRT (/MT) for FSO + FRED2 (no Qt dependency needed)
- name: Configure CMake (static CRT /MT - FSO + FRED2)
# - name: Cache Qt
# # Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# # Install Qt 32bit if matrix.arch == Win32
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# # Install Qt 64bit if matrix.arch == x64
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCHITECTURE: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
shell: bash
run: |
mkdir build-mt
cd build-mt
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_TESTS=ON -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
-DFSO_BUILD_QTFRED=OFF -G "Visual Studio 18 2026" -T "v143" \
-DCMAKE_BUILD_TYPE=$CONFIGURATION ..
- name: Compile (static CRT)
working-directory: ./build-mt
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
cmake --install . --config "$CONFIGURATION"
ls -alR "$(pwd)/install"
# Tree B: dynamic CRT (/MD) for QtFRED only (matches Qt's prebuilt /MD runtime)
# Skipped on Win32: Qt6 has no 32-bit Windows support, so CMake force-disables
# FSO_BUILD_QTFRED there and the qtfred target would not exist
- name: Configure CMake (dynamic CRT /MD - QtFRED)
if: matrix.arch != 'Win32'
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCHITECTURE: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
shell: bash
run: |
mkdir build-md
cd build-md
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_TESTS=OFF -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_FRED2=OFF -DQT_USE_PRECOMPILED=ON \
-G "Visual Studio 18 2026" -T "v143" -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
- name: Compile (dynamic CRT)
if: matrix.arch != 'Win32'
working-directory: ./build-md
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
cmake --build . --config "$CONFIGURATION" --target qtfred -- /verbosity:minimal
cmake --install . --config "$CONFIGURATION" --component qtFRED
ls -alR "$(pwd)/install"
# Merge both trees into the single install dir the zip job consumes
- name: Merge installs
shell: bash
run: |
mkdir -p build/install
# build-md does not exist on Win32 (no QtFRED there)
if [ -d build-md/install ]; then
cp -r build-md/install/. build/install/
mkdir build
cd build
if [ "$ARCHITECTURE" = "Win32" ]; then
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
else
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
fi
cp -r build-mt/install/. build/install/
ls -alR build/install
- name: Compile
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
cmake --build . --config "$CONFIGURATION" --target INSTALL -- /verbosity:minimal
ls -alR "$(pwd)/install"
- name: Run Tests
working-directory: ./build-mt
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
shell: bash
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
- name: Set artifact id
shell: bash
run: |
id=
if [ -n "${{ matrix.simd }}" ]; then
id="${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}"
else
id="${{ matrix.configuration }}-${{ matrix.arch }}"
fi
echo "artifact_id=${id}" >> $GITHUB_ENV
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: windows-${{ env.artifact_id }}
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
path: ${{ github.workspace }}/build/install/*
windows_zip:
name: Build Windows distribution zip
needs: build_windows
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
fail-fast: false # Run the other jobs in the matrix instead of failing them
matrix:
arch: [Win32, x64, ARM64]
simd: [SSE2, AVX, ""]
exclude:
- arch: Win32
simd: ""
- arch: x64
simd: ""
- arch: ARM64
simd: SSE2
- arch: ARM64
simd: AVX
arch: [Win32, x64]
simd: [SSE2, AVX]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Set artifact id
shell: bash
run: |
id=
if [ -n "${{ matrix.simd }}" ]; then
id="${{ matrix.arch }}-${{ matrix.simd }}"
else
id="${{ matrix.arch }}"
fi
echo "artifact_id=${id}" >> $GITHUB_ENV
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: windows-Release-${{ env.artifact_id }}
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: windows-FastDebug-${{ env.artifact_id }}
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Create Distribution package
@@ -328,17 +260,18 @@ jobs:
working-directory: ./builds
shell: bash
env:
ID: ${{ env.artifact_id }}
ARCH: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
- name: Upload result package
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.package_name }}
path: ${{ steps.generate_package.outputs.package_path }}
- name: Upload debug package
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.debug_name }}
path: ${{ steps.generate_package.outputs.debug_path }}
@@ -362,25 +295,43 @@ jobs:
needs: create_release
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
# - name: Cache Qt
# id: cache-qt-mac
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: 0
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja all
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
- name: Run Tests
working-directory: ./build
env:
@@ -388,25 +339,13 @@ jobs:
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Sign builds
working-directory: ./build/bin
run: |
# make sure OpenAL framework is signed
find . -name OpenAL -type f | while read xx; do codesign --force -s - $xx; done
find . -name OpenAL.framework -type d | while read xx; do codesign --force -s - $xx; done
# make sure dylibs are signed
find . -name \*.dylib -type f | while read xx; do codesign --force -s - $xx; done
# sign binaries
find . -perm +111 -type f | grep MacOS | while read xx; do codesign --force -s - $xx; done
# sign apps
find . -name \*.app -maxdepth 1 | while read xx; do codesign --force -s - $xx; done
- name: Package build result
working-directory: ./build/bin
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
# Ref: https://github.com/actions/runner-images/issues/2619
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
@@ -414,27 +353,24 @@ jobs:
name: Build Mac distribution zip
needs: build_mac
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v2
name: Checkout
with:
submodules: true
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: mac-Release-${{ matrix.arch }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: mac-FastDebug-${{ matrix.arch }}
path: builds
@@ -450,7 +386,7 @@ jobs:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
- name: Upload result package
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.package_name }}
path: ${{ steps.generate_package.outputs.package_path }}
+53
View File
@@ -0,0 +1,53 @@
name: Publish Standalone docker image
on:
push:
tags:
- 'nightly_*'
- 'release_*'
jobs:
build_images:
if: github.repository == 'scp-fs2open/fs2open.github.com'
strategy:
matrix:
configuration: [FastDebug, Release]
include:
- configuration: FastDebug
tag_suffix: -debug
- configuration: Release
tag_suffix: ""
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: ghcr.io/scp-fs2open/standalone_server
tag-latest: false
- name: Login to GitHub Docker Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./docker/standalone/Dockerfile
push: true
tags: ${{ steps.docker_meta.outputs.tags }}${{ matrix.tag_suffix }}
labels: ${{ steps.docker_meta.outputs.labels }}
build-args: |
build_type=${{ matrix.configuration }}
+107 -127
View File
@@ -5,28 +5,22 @@ on:
branches:
- 'test/*'
env:
QT_VERSION: 5.12.12
jobs:
build_linux:
strategy:
matrix:
configuration: [FastDebug, Release]
os: [ubuntu-latest, ubuntu-24.04-arm]
include:
- os: ubuntu-latest
arch: x86_64
- os: ubuntu-24.04-arm
arch: arm64
name: Linux
runs-on: ${{ matrix.os }}
container: ghcr.io/scp-fs2open/linux_build:sha-ab87451
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Set up test version
shell: bash
run: |
@@ -36,13 +30,15 @@ jobs:
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: gcc-9
COMPILER: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
run: ninja -k 20 all
run: |
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
- name: Run Tests
working-directory: ./build
env:
@@ -55,46 +51,34 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: linux-${{ matrix.configuration }}-${{ matrix.arch }}
name: linux-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/install/*.AppImage
linux_zip:
name: Build Linux distribution zip
needs: build_linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
strategy:
matrix:
arch: [x86_64, arm64]
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v2
name: Checkout
with:
submodules: true
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: linux-Release-${{ matrix.arch }}
name: linux-Release
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: linux-FastDebug-${{ matrix.arch }}
name: linux-FastDebug
path: builds
- name: Fix permissions
working-directory: ./builds
shell: bash
run: chmod 755 *.AppImage
- name: Create Distribution package
working-directory: ./builds
env:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
- name: Upload result package
working-directory: ./builds
@@ -109,39 +93,51 @@ jobs:
strategy:
matrix:
configuration: [FastDebug, Release]
os: [windows-2025, windows-11-arm]
arch: [Win32, x64, ARM64]
simd: [SSE2, ""]
exclude:
- arch: Win32
os: windows-11-arm
- arch: x64
os: windows-11-arm
- arch: ARM64
os: windows-2025
- os: windows-2025
simd: ""
- os: windows-11-arm
simd: SSE2
arch: [Win32, x64]
simd: [SSE2]
name: Windows
runs-on: ${{ matrix.os }}
runs-on: windows-2019
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Set up test version
shell: bash
run: |
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
# Override the revision string so that the builds are named correctly
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
- name: Install v143 ATL/MFC
shell: pwsh
run: ci/windows/install_v143_atlmfc.ps1
# - name: Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
@@ -151,11 +147,20 @@ jobs:
run: |
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_TESTS=ON -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
-DQT_USE_PRECOMPILED=ON -G "Visual Studio 18 2026" -T "v143" \
-DCMAKE_BUILD_TYPE=$CONFIGURATION ..
if [ "$ARCHITECTURE" = "Win32" ]; then
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
else
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
fi
- name: Compile
working-directory: ./build
env:
@@ -171,72 +176,43 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
shell: bash
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
- name: Set artifact id
shell: bash
run: |
id=
if [ -n "${{ matrix.simd }}" ]; then
id="${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}"
else
id="${{ matrix.configuration }}-${{ matrix.arch }}"
fi
echo "artifact_id=${id}" >> $GITHUB_ENV
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: windows-${{ env.artifact_id }}
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
path: ${{ github.workspace }}/build/install/*
windows_zip:
name: Build Windows distribution zip
needs: build_windows
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [Win32, x64, ARM64]
simd: [SSE2, ""]
exclude:
- arch: Win32
simd: ""
- arch: x64
simd: ""
- arch: ARM64
simd: SSE2
arch: [Win32, x64]
simd: [SSE2]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v2
name: Checkout
with:
submodules: true
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Set artifact id
shell: bash
run: |
id=
if [ -n "${{ matrix.simd }}" ]; then
id="${{ matrix.arch }}-${{ matrix.simd }}"
else
id="${{ matrix.arch }}"
fi
echo "artifact_id=${id}" >> $GITHUB_ENV
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: windows-Release-${{ env.artifact_id }}
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: windows-FastDebug-${{ env.artifact_id }}
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Create Distribution package
working-directory: ./builds
shell: bash
env:
ID: ${{ env.artifact_id }}
ARCH: ${{ matrix.arch }}
SIMD: ${{ matrix.simd }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
- name: Upload result package
working-directory: ./builds
@@ -257,14 +233,32 @@ jobs:
name: Mac
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
# - name: Cache Qt
# id: cache-qt-mac
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
# py7zrversion: '==0.19.*'
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: 0
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Set up test version
shell: bash
run: |
@@ -276,10 +270,11 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja all
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
- name: Run Tests
working-directory: ./build
env:
@@ -287,25 +282,13 @@ jobs:
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Sign builds
working-directory: ./build/bin
run: |
# make sure OpenAL framework is signed
find . -name OpenAL -type f | while read xx; do codesign --force -s - $xx; done
find . -name OpenAL.framework -type d | while read xx; do codesign --force -s - $xx; done
# make sure dylibs are signed
find . -name \*.dylib -type f | while read xx; do codesign --force -s - $xx; done
# sign binaries
find . -perm +111 -type f | grep MacOS | while read xx; do codesign --force -s - $xx; done
# sign apps
find . -name \*.app -maxdepth 1 | while read xx; do codesign --force -s - $xx; done
- name: Package build result
working-directory: ./build/bin
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
# Ref: https://github.com/actions/runner-images/issues/2619
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
- name: Upload build result
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v3
with:
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
@@ -313,27 +296,24 @@ jobs:
name: Build Mac distribution zip
needs: build_mac
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-ab87451
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v2
name: Checkout
with:
submodules: true
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Download Release builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: mac-Release-${{ matrix.arch }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: mac-FastDebug-${{ matrix.arch }}
path: builds
+11 -53
View File
@@ -5,13 +5,15 @@ on:
branches:
- master
env:
QT_VERSION: 5.12.12
jobs:
build_linux:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [gcc-9, gcc-13, clang-16]
arch: [x86_64]
compiler: [gcc-5, gcc-13, clang-16]
cmake_options: [""]
include:
# Also include configurations that check if the code compiles without the graphics backends
@@ -23,20 +25,16 @@ jobs:
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
name: Linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-ab87451
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.23
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}-${{ matrix.arch }}
max-size: 750MB
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
- name: Configure ccache
run: |
ccache --set-config=sloppiness=pch_defines,time_macros
@@ -48,51 +46,11 @@ jobs:
COMPILER: ${{ matrix.compiler }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
CCACHE_PATH: /usr/local/bin/ccache
ENABLE_QTFRED: ON
Qt5_DIR: /qt/${{ env.QT_VERSION }}/gcc_64/lib/cmake/Qt5
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja -k 20 all
- name: Show CCache statistics
run: ccache --show-stats
build_mac:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [clang]
arch: [x86_64, arm64]
cmake_options: [""]
name: Mac
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: ccache
uses: hendrikmuhs/[email protected]
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.arch }}
max-size: 750MB
- name: Configure ccache
run: |
ccache --set-config=sloppiness=pch_defines,time_macros
ccache -p
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
CCACHE_PATH: /usr/local/bin/ccache
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja -k 20 all
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
- name: Show CCache statistics
run: ccache --show-stats
+2 -6
View File
@@ -33,7 +33,6 @@ env:
NEBULA_PASSWORD: ${{ secrets.NEBULA_PASSWORD }}
HLP_API: ${{ secrets.HLP_API }}
HLP_KEY: ${{ secrets.HLP_KEY }}
FORUM_SECRET: ${{ secrets.FORUM_SECRET }}
RELEASE_TAG: ${{ inputs.releaseTag }}
jobs:
@@ -46,13 +45,11 @@ jobs:
run: echo "github.event_name= ${{ github.event_name }}"
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v3
with:
fetch-depth: '0'
ref: ${{ env.RELEASE_TAG }}
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Install Python dependencies
run: pip install -r ci/post/requirements.txt
@@ -70,7 +67,6 @@ jobs:
HLP_API: ${{ secrets.HLP_API }}
HLP_KEY: ${{ secrets.HLP_KEY }}
RELEASE_TAG: ${{ inputs.releaseTag }}
FORUM_SECRET: ${{ secrets.FORUM_SECRET }}
run: python ci/post/main.py release
- name: Post Builds (Manual trigger)
+86 -52
View File
@@ -2,12 +2,15 @@ name: Check a pull request
on: [pull_request]
env:
QT_VERSION: 5.12.12
jobs:
build_linux:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [gcc-9, gcc-13, clang-16]
compiler: [gcc-5, gcc-13, clang-16]
cmake_options: [""]
include:
# Also include configurations that check if the code compiles without the graphics backends
@@ -17,26 +20,17 @@ jobs:
- configuration: Release
compiler: gcc-13
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
# - configuration: Debug
# compiler: gcc-13
# cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=ON
# - configuration: Release
# compiler: gcc-13
# cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=ON
name: Linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-ab87451
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: 0
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.23
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
save: false # Caches are created by a separate job and only restored for PRs
@@ -49,10 +43,12 @@ jobs:
COMPILER: ${{ matrix.compiler }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
CCACHE_PATH: /usr/local/bin/ccache
ENABLE_QTFRED: ON
Qt5_DIR: /qt/${{ env.QT_VERSION }}/gcc_64/lib/cmake/Qt5
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja -k 20 all
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
- name: Run Tests
working-directory: ./build
env:
@@ -74,25 +70,48 @@ jobs:
build_windows:
strategy:
matrix:
configuration: [Debug, FastDebug, Release]
configuration: [Debug, Release]
compiler: [MSVC]
arch: [Win32, x64]
name: Windows
runs-on: windows-2025
runs-on: windows-2019
steps:
- name: Prepare Environment
run: choco install ninja
- uses: actions/checkout@v7
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Install v143 ATL/MFC
if: matrix.compiler == 'MSVC'
shell: pwsh
run: ci/windows/install_v143_atlmfc.ps1
# - name: Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
@@ -104,12 +123,23 @@ jobs:
cd build
if [ "$COMPILER" = "MinGW" ]; then
cmake -DFSO_USE_SPEECH=OFF -DFSO_FATAL_WARNINGS=ON -DFSO_USE_VOICEREC=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_BUILD_FRED2=OFF -DQT_USE_PRECOMPILED=ON -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
if [ "$ARCHITECTURE" = "Win32" ]; then
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DFSO_BUILD_FRED2="OFF" -DFSO_BUILD_WITH_VULKAN="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
else
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DFSO_BUILD_FRED2="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
fi
else
cmake -DFSO_USE_SPEECH=ON -DFSO_FATAL_WARNINGS=ON -DFSO_USE_VOICEREC=OFF -DFSO_BUILD_TESTS=ON \
-DFORCED_SIMD_INSTRUCTIONS=SSE2 -G "Visual Studio 18 2026" -T "v143" -A "$ARCHITECTURE" \
-DQT_USE_PRECOMPILED=ON -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
if [ "$ARCHITECTURE" = "Win32" ]; then
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" -DFSO_BUILD_WITH_VULKAN="OFF" -G "Visual Studio 16 2019" \
-DFSO_BUILD_QTFRED=OFF -T "v142" -A "$ARCHITECTURE" ..
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 "Visual Studio 16 2019" \
-DFSO_BUILD_QTFRED=OFF -T "v142" -A "$ARCHITECTURE" ..
fi
fi
- name: Compile
working-directory: ./build
@@ -146,32 +176,48 @@ jobs:
name: Mac
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
# - name: Cache Qt
# id: cache-qt-mac
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
# py7zrversion: '==0.19.*'
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
fetch-depth: 0
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.23
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}-${{ matrix.arch }}
save: false # Caches are created by a separate job and only restored for PRs
- name: Configure ccache
run: ccache --set-config=sloppiness=pch_defines,time_macros
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
CCACHE_PATH: /usr/local/bin/ccache
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: ninja all
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
- name: Run Tests
working-directory: ./build
env:
@@ -179,24 +225,12 @@ jobs:
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Show CCache statistics
run: ccache --show-stats
- name: Install clang-tidy
# macOS runners don't ship clang-tidy; pin to the same version as the Linux
# container's clang-tidy-16 for consistent diagnostics. pyyaml is required
# too: clang-tidy-diff.py only accepts -export-fixes when it can import yaml.
# --break-system-packages is required since the runner's Homebrew Python
# is externally managed (PEP 668); the runner is ephemeral so this is safe.
if: startsWith(matrix.compiler, 'clang')
run: pip3 install --break-system-packages clang-tidy==16.0.4 pyyaml
- name: Run Clang Tidy
# Clang-tidy reuses the precompiled headers so this only makes sense for the clang compilers
if: startsWith(matrix.compiler, 'clang')
env:
CLANG_TIDY_BINARY: clang-tidy
if: startsWith(matrix.compiler, 'clang-')
run: $GITHUB_WORKSPACE/ci/linux/clang_tidy.sh ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
- name: Process clang-tidy warnings
if: startsWith(matrix.compiler, 'clang')
if: startsWith(matrix.compiler, 'clang-')
uses: asarium/clang-tidy-action@v1
with:
fixesFile: clang-fixes.yaml
+10 -16
View File
@@ -3,23 +3,23 @@ name: Weekly Coverity Scan for Freespace Open
# many thanks for figuring this out first so it could be less painful for us!
#This mode is for testing
#on: [push, pull_request]
on: [push, pull_request]
# In production, push on a specific schedule
on:
schedule:
- cron: "5 0 * * 5" # Run once per a week on Friday morning (midnight UTC, 4 AM EST), to avoid Coverity's submission limits
#on:
# schedule:
# - cron: "5 0 * * 5" # Run once per a week on Friday morning (midnight UTC, 4 AM EST), to avoid Coverity's submission limits
env:
QT_VERSION: 5.12.12
coverity_email: [email protected]
coverity_token: ${{ secrets.COVERITY_TOKEN }}
jobs:
build:
name: Build FSO With Coverity Wrapper
if: github.repository == 'scp-fs2open/fs2open.github.com'
runs-on: ${{ matrix.config.os }}
container: ghcr.io/scp-fs2open/linux_build:sha-ab87451
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
strategy:
fail-fast: false
matrix:
@@ -28,12 +28,9 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v1
with:
submodules: recursive # `true` to checkout submodules, `recursive` to recursively checkout submodules
- name: Set workspace as safe
# This appears to be broken in current actions, so do it manually
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
# pipe results of wget to a log file because it's very verbose and rarely fails
- name: Install Coverity
@@ -50,7 +47,8 @@ jobs:
- name: Configure CMake for FSO
env:
CONFIGURATION: Release
COMPILER: gcc-9
compiler: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Build FSO with Coverity Wrapper
@@ -67,8 +65,4 @@ jobs:
- name: Upload to Coverity
run: |
cd build
curl -X POST -d token=${{ env.coverity_token }} -d email=${{ env.coverity_email }} -d file_name="'cov-scan.tgz'" -d version=${{ github.ref }} -d description="Automatic GHA scan" 'https://scan.coverity.com/projects/870/builds/init' | tee response
upload_url=$(jq -r '.url' response)
build_id=$(jq -r '.build_id' response)
curl -X PUT --header 'Content-Type: application/json' --upload-file cov-scan.tgz $upload_url
curl -X PUT -d token=${{ env.coverity_token }} https://scan.coverity.com/projects/870/builds/$build_id/enqueue
curl --form token=${{ env.coverity_token }} --form email=${{ env.coverity_email }} --form file=@cov-scan.tgz --form version="$(git rev-parse HEAD)" --form description="Automatic GHA scan" 'https://scan.coverity.com/builds?project=scp-fs2open/fs2open.github.com'
-8
View File
@@ -42,7 +42,6 @@ _ReSharper*/
#Project files
[Bb]uild/
[Oo]ut/
#Subversion files
.svn
@@ -260,10 +259,3 @@ CMakePresets.json
!/code/scripting/lua/LuaConvert.h
!/code/debugconsole/
!/docker/build
CMakeFiles/cmake.check_cache
CMakeCache.txt
# Written by the unittests binary at runtime
test/test_data/**/*_settings.ini
test/test_data/data/players/presets/asdf.json
test/test_data/pilotfile/data/asdf.hdp
+5 -1
View File
@@ -1,3 +1,7 @@
[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/scp-fs2open/libRocket.git
url = https://github.com/asarium/libRocket.git
+37 -95
View File
@@ -1,5 +1,5 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.21)
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Make sure the source and binary directory are not the sample
@@ -8,12 +8,12 @@ if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
endif()
include(cmake/util.cmake)
include(cmake/embed_file.cmake)
# Set a few policies
set_policy(CMP0051 NEW)
set_policy(CMP0053 NEW)
set_policy(CMP0054 NEW)
set_policy(CMP0091 NEW) # Enable use of CMAKE_MSVC_RUNTIME_LIBRARY
SET(FSO_PROJECT_DESCRIPTION "Open source project based on the original FreeSpace 2 source code.")
@@ -29,68 +29,45 @@ ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
SET(TARGET_COPY_FILES "" CACHE INTERNAL "" FORCE)
SET(TARGET_COPY_DIRS "" CACHE INTERNAL "" FORCE)
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
# Override standard CMake configurations
set(FSO_BUILD_TYPES Debug Release FastDebug)
if(is_multi_config)
set(CMAKE_CONFIGURATION_TYPES "${FSO_BUILD_TYPES}" CACHE STRING "Configuration types" FORCE)
elseif(NOT CMAKE_BUILD_TYPE)
### Define options and editable variables in the section below:
# This is only needed for single configuration generators so don't annoy others
if(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Default build configuration used." FORCE)
message(WARNING "CMAKE_BUILD_TYPE was not specified, defaulting to Release configuration.")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${FSO_BUILD_TYPES}")
endif()
endif(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
# Override standard CMake configurations
set(CMAKE_CONFIGURATION_TYPES Debug Release FastDebug CACHE STRING "Available configurations" FORCE)
set(FSO_LANGUAGES C CXX)
if(APPLE)
set(FSO_LANGUAGES ${FSO_LANGUAGES} OBJC OBJCXX)
# 10.15 for c++17 std::filesystem
# NOTE: this must be set *before* the project() call to work properly!!
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "macOS deployment target")
# fix all targets in scheme (so it's not just qtfred)
set(CMAKE_XCODE_GENERATE_SCHEME TRUE)
endif()
PROJECT(FS2_Open LANGUAGES ${FSO_LANGUAGES})
if (ANDROID)
message(STATUS "Building for Android (NDK)")
set(FSO_BUILD_INCLUDED_LIBS ON CACHE BOOL "" FORCE)
set(USING_PREBUILT_LIBS ON CACHE BOOL "" FORCE)
set(SDL3_USE_PRECOMPILED ON CACHE BOOL "" FORCE)
set(OPENAL_USE_PRECOMPILED ON CACHE BOOL "" FORCE)
set(USING_PREBUILT_VULKAN ON CACHE BOOL "" FORCE)
endif()
IF(CMAKE_CROSSCOMPILING)
SET(IMPORT_EXE_DIR "IMPORT_EXE_DIR-NOTFOUND" CACHE FILEPATH "Required for a cross compiling build, point to binary directory of a cmake build for the real OS")
INCLUDE(${IMPORT_EXE_DIR}/ImportExecutables.cmake)
ENDIF(CMAKE_CROSSCOMPILING)
# Check if the external modules exists
IF(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib/libRocket/Build")
IF(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/external/rpavlik-cmake-modules/launcher-templates")
message(FATAL_ERROR "External submodules could not be found. Please make sure you have updated your submodules.")
endif()
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/finder")
# this must be set before include(toolchain)
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FSO_BUILD_QTFRED OFF CACHE INTERNAL "" FORCE)
else()
OPTION(FSO_BUILD_QTFRED "Build qtFRED2 binary" ON)
endif()
INCLUDE(globals)
INCLUDE(toolchain)
include(embed_file)
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/external/rpavlik-cmake-modules")
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/external/cotire")
IF(RESET_INSTALL_PREFIX)
IF(NOT $ENV{FS2PATH} STREQUAL "")
IF(NOT IS_DIRECTORY $ENV{FS2PATH})
MESSAGE(WARNING "The path '$ENV{FS2PATH}' of the environment variable FS2PATH does not point to a directory! Install prefix wasn't set.")
ELSE(NOT IS_DIRECTORY $ENV{FS2PATH})
SET(CMAKE_INSTALL_PREFIX "$ENV{FS2PATH}" CACHE PATH "Install path" FORCE)
SET(CMAKE_INSTALL_PREFIX "$ENV{FS2PATH}" CACHE FILEPATH "Install path" FORCE)
FILE(TO_CMAKE_PATH ${CMAKE_INSTALL_PREFIX} CMAKE_INSTALL_PREFIX)
ENDIF(NOT IS_DIRECTORY $ENV{FS2PATH})
ELSE(NOT $ENV{FS2PATH} STREQUAL "")
@@ -98,11 +75,9 @@ IF(RESET_INSTALL_PREFIX)
ENDIF(NOT $ENV{FS2PATH} STREQUAL "")
ENDIF(RESET_INSTALL_PREFIX)
IF(WIN32 OR APPLE OR ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
IF(WIN32 OR APPLE)
OPTION(FSO_USE_SPEECH "Use text-to-speach libraries" ON)
ELSE()
OPTION(FSO_USE_SPEECH "Use text-to-speach libraries" OFF)
ENDIF()
ENDIF(WIN32 OR APPLE)
IF (WIN32)
OPTION(FSO_USE_VOICEREC "Enable voice recognition support" ON)
@@ -118,8 +93,10 @@ OPTION(FSO_BUILD_TESTS "Build unit tests" OFF)
OPTION(FSO_DEVELOPMENT_MODE "Generate binaries in development mode, only use if you know what you're doing!" OFF)
IF(WIN32 OR APPLE OR ANDROID)
# On windows, mac and android the default should be to always build the included libraries
OPTION(FSO_BUILD_QTFRED "Build qtFRED2 binary" OFF)
IF(WIN32 OR APPLE)
# On windows and mac the default should be to always build the included libraries
SET(FSO_BUILD_INCLUDED_LIBS_DEFAULT ON)
ELSE()
SET(FSO_BUILD_INCLUDED_LIBS_DEFAULT OFF)
@@ -133,53 +110,25 @@ OPTION(FSO_USE_OPENALSOFT "Download and build OpenAL Soft instead of using the s
OPTION(FSO_FATAL_WARNINGS "Determines if warnings in the build are considered fatal errors, primarily used for CI" OFF)
SET(FSO_FREESPACE_PATH "${CMAKE_INSTALL_PREFIX}" CACHE PATH "The path of the FreeSpace directory you want to use. Please note that you will have to change CMAKE_INSTALL_PREFIX if you change this at some point.")
SET(FSO_FREESPACE_PATH "${CMAKE_INSTALL_PREFIX}" CACHE FILEPATH "The path of the FreeSpace directory you want to use. Please note that you will have to change CMAKE_INSTALL_PREFIX if you change this at some point.")
SET(FSO_RUN_ARGUMENTS "" CACHE STRING "Additional arguments passed to a generated executable when run with the generated build files.")
option(FSO_INSTALL_DEBUG_FILES "Install some debug files (currently only PDB files on windows)" OFF)
option(ENABLE_COTIRE "Enable cotire for faster compilation. Enabled by default." ON)
option(FSO_RELEASE_LOGGING "Enable logging output for release builds" OFF)
OPTION(FSO_BUILD_WITH_FFMPEG "Enable the usage of FFmpeg for sound and custscenes" ON)
OPTION(FSO_BUILD_WITH_DISCORD "Build with Discord support" ON)
OPTION(FSO_BUILD_WITH_OPENGL "Enable compilation of the OpenGL renderer" ON)
OPTION(FSO_BUILD_WITH_OPENGL_DEBUG "Enables debug option for OpenGL" OFF)
OPTION(FSO_BUILD_WITH_OPENGL_ES "When building OpenGL, use OpenGL ES compatibility layer" OFF)
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" ON)
if(NOT FSO_BUILD_WITH_OPENGL AND FSO_BUILD_WITH_OPENGL_ES)
# Disable GLES if not building with OpenGL
set(FSO_BUILD_WITH_OPENGL_ES OFF CACHE BOOL "" FORCE)
endif()
if(FSO_BUILD_WITH_OPENGL_ES)
add_definitions(-DUSE_OPENGL_ES)
IF(FSO_BUILD_WITH_OPENXR)
MESSAGE(WARNING "FSO_BUILD_WITH_OPENXR is ON. But not supported on OpenGL ES for now - setting to OFF.")
SET(FSO_BUILD_WITH_OPENXR OFF CACHE BOOL "" FORCE)
endif()
endif()
IF(NOT APPLE AND NOT FSO_BUILD_WITH_OPENGL_ES)
SET(OPENXR_BUILD_DEFAULT ON)
ELSE()
SET(OPENXR_BUILD_DEFAULT OFF)
ENDIF()
OPTION(FSO_BUILD_WITH_OPENXR "Build with OpenXR support" ${OPENXR_BUILD_DEFAULT})
IF(FSO_BUILD_WITH_OPENXR AND APPLE)
MESSAGE(WARNING "FSO_BUILD_WITH_OPENXR is ON. Not supported on macOS - setting to OFF.")
SET(FSO_BUILD_WITH_OPENXR OFF CACHE BOOL "" FORCE)
ENDIF()
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" OFF)
OPTION(FSO_BUILD_WITH_OPENXR_DEBUG "Enables debug option for OpenXR" OFF)
OPTION(FSO_USE_LTO "Build using LTO (only for release builds)" ON)
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
MARK_AS_ADVANCED(FORCE FSO_USE_OPENALSOFT)
@@ -187,16 +136,19 @@ MARK_AS_ADVANCED(FORCE FSO_USE_LUAJIT)
MARK_AS_ADVANCED(FORCE FSO_DEVELOPMENT_MODE)
MARK_AS_ADVANCED(FORCE FSO_FATAL_WARNINGS)
mark_as_advanced(FORCE FSO_INSTALL_DEBUG_FILES)
mark_as_advanced(FORCE ENABLE_COTIRE)
mark_as_advanced(FORCE FSO_RELEASE_LOGGING)
mark_as_advanced(FORCE FSO_BUILD_WITH_FFMPEG)
mark_as_advanced(FORCE FSO_BUILD_WITH_DISCORD)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL_DEBUG)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL_ES)
mark_as_advanced(FORCE FSO_BUILD_WITH_VULKAN)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENXR)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENXR_DEBUG)
# Include cotire file from https://github.com/sakra/cotire/
include(cotire)
INCLUDE(globals)
INCLUDE(toolchain)
INCLUDE(platforms)
include(version)
@@ -207,20 +159,11 @@ SET(GENERATED_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated_source)
include(generateHeaders)
if(FSO_BUILD_APPIMAGE)
SET(BINARY_DESTINATION "bin")
SET(LIBRAY_DESTINATION "lib")
include(appimage)
endif()
include(clang-tidy)
include(CheckIPOSupported)
check_ipo_supported(RESULT LTO_AVAILABLE)
if (FSO_USE_LTO AND LTO_AVAILABLE)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
message("Enabled LTO for Release builds")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
endif (FSO_USE_LTO AND LTO_AVAILABLE)
# This includes source code for some tools, either used in the build or also for something else
ADD_SUBDIRECTORY(tools)
@@ -264,7 +207,9 @@ include(package)
include(doxygen)
# Print used options to log
message(STATUS "Using text to speech: ${FSO_USE_SPEECH}")
IF(WIN32 OR APPLE)
message(STATUS "Using text to speech: ${FSO_USE_SPEECH}")
ENDIF()
IF (WIN32)
message(STATUS "Using voice recogition: ${FSO_USE_VOICEREC}")
message(STATUS "Building FRED2: ${FSO_BUILD_FRED2}")
@@ -276,8 +221,5 @@ message(STATUS "Building qtFRED: ${FSO_BUILD_QTFRED}")
message(STATUS "Fatal warnings: ${FSO_FATAL_WARNINGS}")
message(STATUS "Release logging: ${FSO_RELEASE_LOGGING}")
message(STATUS "With FFmpeg: ${FSO_BUILD_WITH_FFMPEG}")
message(STATUS "With Discord: ${FSO_BUILD_WITH_DISCORD}")
message(STATUS "With OpenGL: ${FSO_BUILD_WITH_OPENGL}")
message(STATUS "With OpenGL ES: ${FSO_BUILD_WITH_OPENGL_ES}")
message(STATUS "With Vulkan: ${FSO_BUILD_WITH_VULKAN}")
message(STATUS "With OpenXR: ${FSO_BUILD_WITH_OPENXR}")
+2 -12
View File
@@ -5,8 +5,6 @@ set -e
SCRIPT=$(readlink -f "$0")
HERE=$(dirname "$SCRIPT")
git config --global --add safe.directory "$GITHUB_WORKSPACE"
COMMIT_RANGE=$1..$2
if ! git rev-list $COMMIT_RANGE 2>&1 >/dev/null; then
@@ -18,16 +16,8 @@ fi
# branch
BASE_COMMIT=$(git merge-base $1 $2)
# Allow the caller to override the clang-tidy binary and job count, since neither
# /usr/bin/clang-tidy-16 nor nproc are available outside the Linux CI container
# (e.g. macOS runners install clang-tidy via pip and use sysctl for core count).
CLANG_TIDY_BINARY="${CLANG_TIDY_BINARY:-/usr/bin/clang-tidy-16}"
NUM_JOBS="${NUM_JOBS:-$( (command -v nproc >/dev/null 2>&1 && nproc) || sysctl -n hw.ncpu )}"
# Note: Manually passing in the Vulkan flags that are normally provided by cmake (but are not so, here), to ensure
# that the source files are checked with the actual configuration used.
echo "Running clang-tidy on changed files"
git diff -U0 --no-color "$BASE_COMMIT..$2" | \
$HERE/clang-tidy-diff.py -path "$(pwd)/build" -p1 \
-regex '(code(?!((\/graphics\/shaders\/compiled)|(\/globalincs\/windebug)|(\/def_files\/data)))|freespace2|qtfred|test\/src|build|tools)\/.*\.(cpp|h)' \
-clang-tidy-binary "$CLANG_TIDY_BINARY" -j"$NUM_JOBS" -export-fixes "$(pwd)/clang-fixes.yaml"
-regex '(code(?!((\/graphics\/shaders\/compiled)|(\/globalincs\/windebug)))|freespace2|qtfred|test|build|tools)\/.*\.(cpp|h)' \
-clang-tidy-binary /usr/bin/clang-tidy-9 -j$(nproc) -export-fixes "$(pwd)/clang-fixes.yaml"
+16 -28
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
if [ "$COMPILER" = "gcc-9" ]; then
export CC=gcc-9
export CXX=g++-9
if [ "$COMPILER" = "gcc-5" ]; then
export CC=gcc-5
export CXX=g++-5
fi
if [ "$COMPILER" = "gcc-13" ]; then
export CC=gcc-13
@@ -13,32 +13,24 @@ if [ "$COMPILER" = "clang-16" ]; then
export CXX=clang++-16
fi
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH
if [ "$RUNNER_OS" = "macOS" ]; then
CXXFLAGS="-mtune=generic -pipe -Wno-unknown-pragmas"
CFLAGS="-mtune=generic -pipe -Wno-unknown-pragmas"
# TODO: Vulkan support is disabled on MacOS due to issues with the test suite not linking correctly
PLATFORM_CMAKE_OPTIONS="-DFSO_BUILD_WITH_VULKAN=OFF"
export CMAKE_OSX_ARCHITECTURES="$ARCHITECTURE"
else
PLATFORM_CMAKE_OPTIONS="-DFSO_BUILD_APPIMAGE=ON -DFORCED_SIMD_INSTRUCTIONS=SSE2"
# Optionally use static libstdc++/libc++ on Linux, but default to off
# (Issue #5571 enabled it as a fix for 20.04 compatibility, but we've moved to 22.04)
PLATFORM_CMAKE_OPTIONS="$PLATFORM_CMAKE_OPTIONS -DUSE_STATIC_LIBCXX=${USE_STATIC_LIBCXX:-OFF}"
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas -static-libstdc++"
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
PLATFORM_CMAKE_OPTIONS="-DFSO_BUILD_APPIMAGE=ON"
fi
CMAKE_OPTIONS="$JOB_CMAKE_OPTIONS"
if [[ "$COMPILER" =~ ^clang.*$ ]]; then
# Default to allowing system standard c++ library be used. On Linux, which
# typically uses libstdc++ by default, using libc++ causes a conflict with
# Qt6 libs. So an error/warning is in place to catch that case when QtFRED
# is enabled.
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCLANG_USE_LIBCXX=${CLANG_USE_LIBCXX:-OFF}"
fi
if [ ! "$CCACHE_PATH" = "" ] && [ ! -x "$CCACHE_PATH" ]; then
# The configured path doesn't exist on this runner (e.g. macOS runners on Apple
# Silicon hosts install Homebrew under /opt/homebrew instead of /usr/local),
# so fall back to whatever ccache is actually on PATH.
CCACHE_PATH="$(command -v ccache || true)"
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCLANG_USE_LIBCXX=ON"
# force clang to silently allow -static-libstdc++ flag
CXXFLAGS="$CXXFLAGS -Qunused-arguments"
fi
if [ ! "$CCACHE_PATH" = "" ]; then
@@ -46,10 +38,6 @@ if [ ! "$CCACHE_PATH" = "" ]; then
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCMAKE_C_COMPILER_LAUNCHER=$CCACHE_PATH -DCMAKE_CXX_COMPILER_LAUNCHER=$CCACHE_PATH"
fi
if [ -n "${ENABLE_QTFRED:-}" ]; then
CMAKE_OPTIONS="$CMAKE_OPTIONS -DFSO_BUILD_QTFRED=${ENABLE_QTFRED}"
fi
mkdir build
cd build
@@ -57,7 +45,7 @@ export CXXFLAGS
export CFLAGS
export LD_LIBRARY_PATH
if [ "$RUNNER_OS" = "macOS" ] && [ ! -x "$(which ninja)" ]; then
if [ "$RUNNER_OS" = "macOS" ]; then
brew install ninja
fi
@@ -65,6 +53,6 @@ fi
# we have some build rules that do not play nice with parallel invocation and that fixes these issues
cmake -G Ninja -DFSO_FATAL_WARNINGS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $CMAKE_OPTIONS $PLATFORM_CMAKE_OPTIONS \
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DCMAKE_BUILD_TYPE=$CONFIGURATION -DQT_USE_PRECOMPILED=ON \
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON \
-DCMAKE_JOB_POOLS=link=1 -DCMAKE_JOB_POOL_LINK=link ..
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DCMAKE_BUILD_TYPE=$CONFIGURATION \
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=${ENABLE_QTFRED:-OFF} \
-DSHADERS_ENABLE_COMPILATION=ON -DCMAKE_JOB_POOLS=link=1 -DCMAKE_JOB_POOL_LINK=link ..
+12 -12
View File
@@ -8,23 +8,23 @@ OS="$1"
source $HERE/dist_functions.sh
if [ "$OS" = "Linux" ]; then
tar -cvzf "$(get_package_name)-builds-Linux-$ARCH.tar.gz" *
tar -cvzf "$(get_package_name)-builds-Linux.tar.gz" *
echo "package_path=$(pwd)/$(get_package_name)-builds-Linux-$ARCH.tar.gz" >> $GITHUB_OUTPUT
echo "package_name=$(get_package_name)-builds-Linux-$ARCH.tar.gz" >> $GITHUB_OUTPUT
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Linux-$ARCH.tar.gz")" >> $GITHUB_OUTPUT
echo "package_path=$(pwd)/$(get_package_name)-builds-Linux.tar.gz" >> $GITHUB_OUTPUT
echo "package_name=$(get_package_name)-builds-Linux.tar.gz" >> $GITHUB_OUTPUT
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Linux.tar.gz")" >> $GITHUB_OUTPUT
elif [ "$OS" = "Windows" ]; then
7z a -xr'!*.pdb' "$(get_package_name)-builds-$ID.zip" "*"
7z a -xr'!*.pdb' "$(get_package_name)-builds-$ARCH-$SIMD.zip" "*"
echo "package_path=$(pwd)/$(get_package_name)-builds-$ID.zip" >> $GITHUB_OUTPUT
echo "package_name=$(get_package_name)-builds-$ID.zip" >> $GITHUB_OUTPUT
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-$ID.zip")" >> $GITHUB_OUTPUT
echo "package_path=$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip" >> $GITHUB_OUTPUT
echo "package_name=$(get_package_name)-builds-$ARCH-$SIMD.zip" >> $GITHUB_OUTPUT
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip")" >> $GITHUB_OUTPUT
7z a "$(get_package_name)-debug-$ID.7z" "*.pdb"
7z a "$(get_package_name)-debug-$ARCH-$SIMD.7z" "*.pdb"
echo "debug_path=$(pwd)/$(get_package_name)-debug-$ID.7z" >> $GITHUB_OUTPUT
echo "debug_name=$(get_package_name)-debug-$ID.7z" >> $GITHUB_OUTPUT
echo "debug_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-debug-$ID.7z")" >> $GITHUB_OUTPUT
echo "debug_path=$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z" >> $GITHUB_OUTPUT
echo "debug_name=$(get_package_name)-debug-$ARCH-$SIMD.7z" >> $GITHUB_OUTPUT
echo "debug_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z")" >> $GITHUB_OUTPUT
elif [ "$OS" = "Mac" ]; then
tar -cvzf "$(get_package_name)-builds-Mac-$ARCH.tar.gz" *.app
+4 -39
View File
@@ -2,48 +2,13 @@
INSTALL_FOLDER=$1
# safety check
if [ ! -d bin -o ! -f cmake_install.cmake ]; then
echo "ERROR! This script must be run from within the build root!"
exit 1
fi
if [ ! -x "$(which wget)" ]; then
echo "ERROR! Required utility is not available: wget"
exit 1
fi
# install newest appimagetool if it's not already available
if [ ! -x ./bin/appimagetool ]; then
APPIMAGE_TOOL_URL="https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$(uname -m).AppImage"
wget -O ./bin/appimagetool "$APPIMAGE_TOOL_URL" || { echo "ERROR! Failed to get appimagetool!" && exit 1; }
chmod +x ./bin/appimagetool
fi
# This shouldn't be needed with newer runtimes, but they still generate an
# error if fusermount is missing even though it works. So to skip error msg
# and have max compatibility with runtimes and containers we'll use it.
export APPIMAGE_EXTRACT_AND_RUN=1
# Install Freespace2 targets
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER/Freespace2 -DCOMPONENT=Unspecified -P cmake_install.cmake
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER/Freespace2 -DCOMPONENT=Freespace2 -P cmake_install.cmake
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER -DCOMPONENT=Unspecified -P cmake_install.cmake
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER -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 $INSTALL_FOLDER/Freespace2/bin -maxdepth 1 -name 'fs2_open_*' -type f -executable -printf "%f\n").AppImage"
./bin/appimagetool -n "$INSTALL_FOLDER/Freespace2" "$INSTALL_FOLDER/$FILENAME"
FILENAME="$(find $INSTALL_FOLDER/bin -name 'fs2_open_*' -type f -printf "%f\n").AppImage"
appimagetool -n $INSTALL_FOLDER "$INSTALL_FOLDER/$FILENAME"
chmod +x "$INSTALL_FOLDER/$FILENAME"
# Maybe install qtFRED targets
if [ -f qtfred/cmake_install.cmake ]; then
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER/qtFRED -DCOMPONENT=Unspecified -P cmake_install.cmake
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER/qtFRED -DCOMPONENT=qtFRED -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 $INSTALL_FOLDER/qtFRED/bin -maxdepth 1 -iname 'qtfred_*' -type f -executable -printf "%f\n").AppImage"
./bin/appimagetool -n "$INSTALL_FOLDER/qtFRED" "$INSTALL_FOLDER/$FILENAME"
chmod +x "$INSTALL_FOLDER/$FILENAME"
fi
ls -al $INSTALL_FOLDER
+1 -9
View File
@@ -5,14 +5,6 @@ HERE=$(dirname "$SCRIPT")
export LD_LIBRARY_PATH=$(pwd)/bin/lib:$LD_LIBRARY_PATH
# The unit tests never open a window, but a few of them reach code that brings SDL's video
# subsystem up (os_init() and resolution_default(), the latter via gr_init()). Left to itself SDL
# probes its real backends and dlopens libX11, which leaks a handful of blocks per init/quit cycle
# that SDL_QuitSubSystem() does not reclaim -- those are the "definitely lost" contexts memcheck
# fails the Debug legs on. Pinning the dummy driver skips the probing entirely, so the leaks never
# happen, and it makes the tests behave the same way whether or not the runner has a display.
export SDL_VIDEODRIVER=dummy
# if on mac and building for architecture that doesn't match host
# then unittests will fail so we just need to skip it (for now)
if [ "$RUNNER_OS" = "macOS" ] && [ "$ARCH" != "$(uname -m)" ]; then
@@ -20,7 +12,7 @@ if [ "$RUNNER_OS" = "macOS" ] && [ "$ARCH" != "$(uname -m)" ]; then
exit 0
fi
if [ "$CONFIGURATION" = "Debug" ] && [[ "$RUNNER_OS" != "macOS" ]] ; then
if [ "$CONFIGURATION" = "Debug"] && [[ "$RUNNER_OS" != "macOS" ]] ; then
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
--suppressions="$HERE/valgrind.supp" ./bin/unittests --gtest_shuffle
else
+47 -23
View File
@@ -8,6 +8,24 @@
obj:*
obj:*
}
{
Travis memleak
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:_dl_signal_error
fun:_dl_open
fun:dlopen_doit
fun:_dl_catch_error
fun:_dlerror_run
fun:dlopen@@GLIBC_2.2.5
obj:/usr/lib/x86_64-linux-gnu/libmirclient.so.7
fun:call_init.part.0
fun:call_init
fun:_dl_init
fun:dl_open_worker
fun:_dl_catch_error
}
{
CLang Lua unitialized value error
Memcheck:Cond
@@ -109,31 +127,37 @@
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
}
{
SDL_Init one-time internal allocation via os_init
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
obj:*
obj:*
obj:*
obj:*
fun:_Z7os_initPKcS0_S0_
fun:_ZN4test13FSTestFixture5SetUpEv
}
# Kept only as a backstop for running memcheck by hand. run_tests.sh pins SDL_VIDEODRIVER=dummy, so
# the X11 backend is never created there; this block also cannot match the prebuilt libSDL3 anymore,
# since that library is now stripped and X11_CreateDevice is a static symbol.
{
SDL3 X11 video backend internal allocations, not freed by SDL_VideoQuit
Memcheck:Leak
match-leak-kinds: definite,possible
...
fun:X11_CreateDevice
}
{
glibc loader bookkeeping and library constructor allocations retained across dlopen
Memcheck:Leak
match-leak-kinds: definite,possible
...
fun:_dl_signal_error
fun:_dl_open
fun:dlopen_doit
fun:_dl_catch_error
fun:_dlerror_run
fun:dlopen@@GLIBC_2.2.5
obj:*
obj:*
fun:call_init.part.0
fun:call_init
fun:_dl_init
fun:dl_open_worker
}
{
dlopen leak
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:_dl_exception_create
fun:_dl_signal_error
fun:_dl_map_object
fun:dl_open_worker
fun:_dl_catch_exception
fun:_dl_open
fun:dlopen_doit
fun:_dl_catch_exception
fun:_dl_catch_error
fun:_dlerror_run
fun:dlopen@@GLIBC_2.2.5
}
+5 -95
View File
@@ -12,61 +12,6 @@ from subprocess import check_output
MAX_PAGES = 100 # maximum number of PR pages to go through
warnings = 0
label_scores = {
"fred" : 6,
"qtfred" : 6,
"vr" : 6,
"multi" : 6,
"Lab" : 6,
"pilot file" : 6,
"scripting" : 6,
"sexps" : 6,
"ai" : 6,
"controls" : 6,
"HUD" : 6,
"models" : 6,
"sound" : 6,
"graphics" : 6,
"physics" : 6,
"ui" : 6,
"localization / translation" : 6,
"optimization" : 6,
"gameplay" : 5,
"general modding" : 4,
"fix" : 3,
"enhancement" : 2,
"backport" : 1,
"cleanup" : 0
}
label_to_category = {
"fred" : "FRED",
"qtfred" : "QtFRED",
"vr" : "VR",
"multi" : "Multiplayer",
"Lab" : "Lab",
"pilot file" : "Pilot File",
"scripting" : "Scripting",
"sexps" : "SEXPs",
"ai" : "AI",
"controls" : "Controls",
"HUD" : "HUD",
"models" : "Models",
"sound" : "Sound",
"graphics" : "Graphics",
"physics" : "Physics",
"ui" : "UI",
"localization / translation" : "Localization",
"optimization" : "Optimization",
"gameplay" : "Gameplay",
"general modding" : "General Modding",
"fix" : "Fix",
"enhancement" : "Enhancement",
"backport" : "Backport",
"cleanup" : "Cleanup",
"misc" : "Misc."
}
def get_last_page(response: requests.Response) -> int:
"""
@brief Extract the last page number from the response header
@@ -95,33 +40,7 @@ def get_last_page(response: requests.Response) -> int:
return MAX_PAGES
else:
return last_page
def label_score(label):
try:
return label_scores[label['name']]
except KeyError:
return -1
def get_label(labels) -> str:
"""
@brief Get the primary label from a list of labels
@param[in] labels The list of labels from a pull request
@returns The primary label to be used for sorting in the changelog
"""
if len(labels) < 1:
return "misc"
# Sort the labels based on their score and grab the highest valued label
name = sorted(labels, key=label_score, reverse=True)[0]['name']
# If a label couldn't be found, toss it into a miscellaneous bin
if name not in label_scores:
name = "misc"
return name
def main():
parser = argparse.ArgumentParser(description="Retrieves a log of commit messages and attempts to pretty them into a human-readable format")
@@ -219,16 +138,11 @@ def main():
print("Found old pull #{} ({}), stopping loop...".format(pull['number'], pull['updated_at']))
page = last_page + 1
break
# If a label isn't in the changelog, create a bin for it
label = get_label(pull['labels'])
if label not in changelog:
changelog[label] = {}
# Add the pull to the changelog, indexed by its pull.number
if pull['number'] not in changelog[label]:
if pull['number'] not in changelog:
# only add if the key isn't there already
changelog[label][pull['number']] = {
changelog[pull['number']] = {
"date": merge_date,
"title": pull['title'],
"labels": pull['labels'],
@@ -244,13 +158,9 @@ def main():
# 2021-09-28 | (#3661) Fix homing child weapons in niche circumstances
print("Writing to change.log...")
str = ''
for label, pulls in dict(sorted(changelog.items())).items():
str += "[size=18pt]{}[/size]\n".format(label_to_category[label])
str += "[list]\n"
for key, value in pulls.items():
str += "[li](#{}) {} [/li]\n".format(key, value['title'])
str += "[/list]\n\n"
for key, value in changelog.items():
str += "{} | (#{}) {} \n".format(value['date'].strftime("%Y-%m-%d"), key, value['title'])
with open("change.log", "w") as file:
file.write(str)
+1 -5
View File
@@ -149,8 +149,6 @@ def get_release_files(tag_name, config) -> Tuple[List[ReleaseFile], Dict[str, So
# x64 is the Visual Studio name but for consistency we need Win64
if platform == "x64":
platform = "Win64"
elif platform == "ARM64":
platform = "WinARM64"
binary_files.append(ReleaseFile(name, url, platform, group_match.group(3)))
else:
@@ -215,8 +213,6 @@ def get_ftp_files(build_type, tag_name, config) -> List[ReleaseFile] :
# x64 is the name Visual Studio uses but Win64 works better for us since that gets displayed in the nightly post
if "x64" in group_match:
group_match = group_match.replace("x64", "Win64")
elif "ARM64" in group_match:
group_match = group_match.replace("ARM64", "WinARM64")
# construct the download URL list for all mirrors. The first listed ftp location is taken as the Primary
for mirror in config["ftp"]["mirrors"]:
@@ -229,4 +225,4 @@ def get_ftp_files(build_type, tag_name, config) -> List[ReleaseFile] :
# Form the List[ReleaseFile] list with the download URL links
out_data.append(ReleaseFile(file, primary_url, group_match, None, mirrors))
return out_data
return out_data
+6 -9
View File
@@ -1,4 +1,3 @@
import os
from typing import List
import requests
@@ -34,14 +33,12 @@ class ForumAPI:
print("Post failed! No API or API_KEY given!")
return
resp = requests.post(self.config["hlp"]["api"],
headers={"X-HLP-Bot": os.environ["FORUM_SECRET"]},
data={
"api_key": self.config["hlp"]["key"],
"board": str(board),
"subject": title,
"body": content
})
resp = requests.post(self.config["hlp"]["api"], data={
"api_key": self.config["hlp"]["key"],
"board": str(board),
"subject": title,
"body": content
})
if resp.status_code != 200:
print("Post failed! Response: %s" %resp.text)
-5
View File
@@ -18,7 +18,6 @@
# Credentials into hard-light.net for forum post
# HLP_API:
# HLP_KEY:
# FORUM_SECRET:
# LINUX_RESULT: bool, if the linux builds were successfully uploaded
# WINDOWS_RESULT: bool, if the windows builds were successfully uploaded
@@ -125,10 +124,6 @@ def get_source_version(date_version: datetime, tag_name: str) -> semantic_versio
def main():
if "FORUM_SECRET" not in os.environ or not os.environ["FORUM_SECRET"]:
print(" ERROR: FORUM_SECRET environment variable not set")
sys.exit(1)
os.chdir(os.path.dirname(__file__)) # Change working directory to this file's directory
# Aggregate configuration data in a dictionary
+7 -15
View File
@@ -7,15 +7,13 @@ import requests
from file_list import ReleaseFile
from util import retry_multi, GLOBAL_TIMEOUT
LINUX_X64_KEY = "Linux-x86_64"
LINUX_ARM64_KEY = "Linux-arm64"
LINUX_KEY = "Linux"
MACOSX_X64_KEY = "Mac-x86_64"
MACOSX_ARM64_KEY = "Mac-arm64"
WIN32_SSE2_KEY = "Win32-SSE2"
WIN64_SSE2_KEY = "Win64-SSE2"
WIN32_AVX_KEY = "Win32-AVX"
WIN64_AVX_KEY = "Win64-AVX"
WINARM64_KEY = "WinARM64"
metadata = {
'type': 'engine',
@@ -36,27 +34,23 @@ metadata = {
}
platforms = {
LINUX_X64_KEY: 'linux',
LINUX_ARM64_KEY: 'linux',
LINUX_KEY: 'linux',
MACOSX_X64_KEY: 'macosx',
MACOSX_ARM64_KEY: 'macosx',
WIN32_SSE2_KEY: 'windows',
WIN64_SSE2_KEY: 'windows',
WIN32_AVX_KEY: 'windows',
WIN64_AVX_KEY: 'windows',
WINARM64_KEY: 'windows',
WIN64_AVX_KEY: 'windows'
}
envs = {
LINUX_X64_KEY: 'linux && x86_64',
LINUX_ARM64_KEY: 'linux && arm64',
LINUX_KEY: 'linux && x86_64', # Linux only has 64bit builds
MACOSX_X64_KEY: 'macosx && x86_64',
MACOSX_ARM64_KEY: 'macosx && arm64',
WIN32_SSE2_KEY: 'windows',
WIN64_SSE2_KEY: 'windows && x86_64',
WIN32_AVX_KEY: 'windows && avx',
WIN64_AVX_KEY: 'windows && avx && x86_64',
WINARM64_KEY: 'windows && arm64'
WIN64_AVX_KEY: 'windows && avx && x86_64'
}
subdirs = {
@@ -119,7 +113,7 @@ def render_nebula_release(version, stability, files, config):
'filename': dest_fn
})
if group.startswith('Linux') and fn.endswith('.AppImage'):
if group == LINUX_KEY and fn.endswith('.AppImage'):
if 'qtfred' in fn:
if '-FASTDBG' in fn:
label = 'QtFRED Debug'
@@ -133,8 +127,7 @@ def render_nebula_release(version, stability, files, config):
label = None
props = {
"arm64": "arm64" in fn,
"x64": "x64" in fn,
"x64": True, # All Linux builds are 64-bit
"sse2": True, # Linux builds are forced to compile with SSE2 but not AVX
"avx": False,
"avx2": False,
@@ -194,7 +187,6 @@ def render_nebula_release(version, stability, files, config):
"sse2": "SSE2" in fn or "AVX" in fn, # AVX implies SSE2
"avx": "AVX" in fn, # This conveniently also covers the AVX2 case since AVX2 implies AVX
"avx2": "AVX2" in fn,
"arm64": "arm64" in fn,
}
pkg['executables'].append({
+9 -12
View File
@@ -7,22 +7,22 @@ PLACEHOLDER
[b]Deprecations:[/b]
PLACEHOLDER
Deprecations are a mechanism in FSO where a certain feature or aspect of the engine has changed or is no longer supported. Since this would normally break existing mods, we have the mod table feature "[tt]$Target Version:[/tt]" with which a mod can specify what version of FSO it was developed with. Any features listed under Deprecations will be removed or changed when the target version of a mod is at least the version released in this post.
Deprecations are a mechanism in FSO where a certain feature or aspect of the engine has changed or is no longer supported. Since this would normally break existing mods we have the mod table feature "[tt]$Target Version:[/tt]" with which a mod can specify what version of FSO it was developed with. The features listed above will be removed or changed when the target version of a mod is at least the version released in this post.
[size=5pt]Previous [url=https://www.hard-light.net/forums/index.php?topic=99015.0]23.2.1 Release Thread[/url][/size]
[size=5pt]Previous [url=https://www.hard-light.net/forums/index.php?topic=98682.0]23.0.0 Release Thread[/url][/size]
Launchers, if you don't have one already:
[b]All platforms: [/b] For every day use, we recommend [url=https://knossosnet.github.io/Knossos-Release-Page/]Knossos.NET[/url], an integrated solution for downloading and launching mods.
[b]All platforms: [/b] For every day use, we recommend [url=https://www.hard-light.net/forums/index.php?topic=94068.0]Knossos[/url], an integrated solution for downloading and launching mods.
[hidden=Alternative Launchers]
Cross-platform: [url=https://www.hard-light.net/forums/index.php?topic=89162]wxLauncher 0.12.x Test Build[/url] (legacy project for a unified launcher)
Cross-platform: [url=https://www.hard-light.net/forums/index.php?topic=89162]wxLauncher 0.12.x Test Build[/url] (ongoing project for a unified launcher, you should upgrade to the latest RC/test build if you have not yet)
[b]Important:[/b] For best compatibility with FSO 3.8 and later you should use at least wxLauncher 0.12.
Windows: [url=http://scp.fsmods.net/builds/Launcher55g.zip]Launcher 5.5g[/url] ([url=https://scp.indiegames.us/builds/Launcher55g.zip]Mirror[/url]) ([url=https://www.mediafire.com/?wdvzn7hhhzh418m]Mirror[/url]) Not compatible with Windows 8+, use wxLauncher above
OS X: Soulstorm's [url=https://www.hard-light.net/forums/index.php/topic,51391.0.html]OS X Launcher 3.0[/url]
Linux: [url=https://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[/url] or [url=https://www.hard-light.net/wiki/index.php/Fs2_open_on_Linux/Graphics_Settings]by hand[/url] or whatever you can figure out.[/hidden]
[img]https://scp.indiegames.us/img/windows-icon.png[/img] [color=green][size=12pt]Windows (32/64-bit/ARM64)[/size][/color]
[img]https://scp.indiegames.us/img/windows-icon.png[/img] [color=green][size=12pt]Windows (32/64-bit)[/size][/color]
[size=8pt]Compiled using GitHub Actions on Windows Server 2019 (10.0.17763), Visual Studio Enterprise 2019[/size]
[b]64-bit:[/b] ${build(groups["Win64"].mainFile)}
@@ -30,8 +30,6 @@ Linux: [url=https://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[
[b]32-bit:[/b] ${build(groups["Win32"].mainFile)}
[size=8pt]This one is based on the SSE2 Optimizations from the MSVC Compiler.[/size]
[b]ARM64:[/b] ${build(groups["WinARM64"].mainFile)}
[hidden=Alternative builds]
[b]64-bit AVX:[/b] ${build(groups["Win64"].subFiles["AVX"])}
@@ -43,13 +41,12 @@ Linux: [url=https://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[
[b]What are those SSE, SSE2 and AVX builds I keep seeing everywhere?[/b]
[url=https://www.hard-light.net/forums/index.php?topic=65628.0]Your answer is in this topic.[/url]
Don't want to deal with that? Use [url=https://knossosnet.github.io/Knossos-Release-Page/]Knossos.NET[/url] and it will download the best build specifically for your PC!
Don't want to deal with that? Use [url=https://www.hard-light.net/forums/index.php?topic=94068.0]Knossos[/url] and it will download the best build specifically for your PC!
[/hidden]
[img]https://scp.indiegames.us/img/linux-icon.png[/img] [color=green][size=12pt]Linux[/size][/color]
[size=8pt]Compiled with Ubuntu 20.04 LTS, GCC 9[/size]
[b]x86_64:[/b] ${build(groups["Linux"].subFiles["x86_64"])}
[b]arm64:[/b] ${build(groups["Linux"].subFiles["arm64"])}
[img]https://scp.indiegames.us/img/linux-icon.png[/img] [color=green][size=12pt]Linux 64-bit[/size][/color]
[size=8pt]Compiled with Ubuntu 16.04 LTS 64-bit, GCC 5[/size]
${build(groups["Linux"].mainFile)}
These builds use a mechanism called [url=https://appimage.org/]AppImage[/url] which should allow these builds to run on most Linux distributions. However, we recommend that you compile your own builds which will result in less issues.
Alternatively, if there is a package in your software repository then you should use that. If you are the maintainer of such a package for a distribution then let us know and we will include that here.
+2 -2
View File
@@ -1,3 +1,3 @@
Mako==1.4.2
requests==2.33.0
Mako==1.2.2
requests==2.31.0
semantic-version==2.8.5
-34
View File
@@ -1,34 +0,0 @@
# Installs ATL and MFC for the v143 toolset, which the Visual Studio 2026 runner images
# only ship for the latest toolset. ATL is needed by SAPI speech (sphelper.h) and MFC by FRED2.
$ErrorActionPreference = 'Stop'
$msvcVersion = '14.44'
$component = 'Microsoft.VisualStudio.Component.VC.14.44.17.14'
$suffix = if ($env:RUNNER_ARCH -eq 'ARM64') { '.ARM64' } else { '' }
$installerDir = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"
$installPath = & "$installerDir\vswhere.exe" -version '[18.0,19.0)' -latest -property installationPath
if (-not $installPath) {
Write-Error 'Visual Studio 2026 was not found'
}
$arguments = @(
'/c', 'vs_installer.exe', 'modify',
'--installPath', "`"$installPath`"",
'--add', "$component.ATL$suffix",
'--add', "$component.MFC$suffix",
'--quiet', '--norestart', '--nocache'
)
$process = Start-Process -FilePath cmd.exe -ArgumentList $arguments -WorkingDirectory $installerDir -Wait -PassThru -NoNewWindow
# 3010 = success, reboot required
if ($process.ExitCode -notin 0, 3010) {
Write-Error "vs_installer exited with code $($process.ExitCode)"
}
# fail here rather than with a confusing compile error if the components didn't install
foreach ($header in 'atlbase.h', 'afxwin.h') {
if (-not (Test-Path "$installPath\VC\Tools\MSVC\$msvcVersion.*\atlmfc\include\$header")) {
Write-Error "$header for MSVC $msvcVersion is missing after install"
}
}
File renamed without changes.
File renamed without changes.
-48
View File
@@ -1,48 +0,0 @@
# - Removes duplicate entries and non-directories from a provided list
#
# clean_directory_list(<listvar> [<additional list items>...])
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <[email protected]> <[email protected]>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__clean_directory_list)
return()
endif()
set(__clean_directory_list YES)
function(clean_directory_list _var)
# combine variable's current value with additional list items
set(_in ${${_var}} ${ARGN})
if(_in)
# Initial list cleaning
list(REMOVE_DUPLICATES _in)
# Grab the absolute path of each actual directory
set(_out)
foreach(_dir ${_in})
if(IS_DIRECTORY "${_dir}")
get_filename_component(_dir "${_dir}" ABSOLUTE)
file(TO_CMAKE_PATH "${_dir}" _dir)
list(APPEND _out "${_dir}")
endif()
endforeach()
if(_out)
# Clean up the output list now
list(REMOVE_DUPLICATES _out)
endif()
# return _out
set(${_var} "${_out}" PARENT_SCOPE)
endif()
endfunction()
-311
View File
@@ -1,311 +0,0 @@
# - Create launchers to set working directory, env. vars, etc.
#
# include(CreateLaunchers) - to make these available
# guess_runtime_library_dirs(<outputvarname> [<extralibrary> ...])
# create_default_target_launcher(<targetname>
# [ARGS <args...>]
# [FORWARD_ARGS]
# [RUNTIME_LIBRARY_DIRS <dir...>]
# [WORKING_DIRECTORY <dir>]
# [ENVIRONMENT <VAR=value> [<VAR=value>...]])
#
# create_target_launcher(<targetname>
# [ARGS <args...>]
# [FORWARD_ARGS]
# [RUNTIME_LIBRARY_DIRS <dir...>]
# [WORKING_DIRECTORY <dir>]
# [ENVIRONMENT <VAR=value> [<VAR=value>...]])
#
# create_generic_launcher(<launchername>
# [RUNTIME_LIBRARY_DIRS <dir...>]
# [WORKING_DIRECTORY <dir>]
# [ENVIRONMENT <VAR=value> [<VAR=value>...]])
# - sets GENERIC_LAUNCHER_COMMAND and GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION
#
# Requires these CMake modules:
# ListFilter
# ProgramFilesGlob
# CleanDirectoryList
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <[email protected]> <[email protected]>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__create_launchers)
return()
endif()
set(__create_launchers YES)
include(CleanDirectoryList)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_launchermoddir
${CMAKE_CURRENT_LIST_FILE}
PATH)
set(_launchermoddir "${_launchermoddir}/launcher-templates")
macro(_launcher_system_settings)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(BITS 64)
else()
set(BITS 32)
endif()
if(WIN32)
# Find user and system name
set(SYSTEM_NAME $ENV{USERDOMAIN})
set(USER_NAME $ENV{USERNAME})
set(VCPROJ_TYPE vcproj)
set(USERFILE_EXTENSION ${SYSTEM_NAME}.${USER_NAME}.user)
set(LAUNCHER_LINESEP "&#x0A;")
if(MSVC90)
set(USERFILE_VC_VERSION 9.00)
elseif(MSVC80)
set(USERFILE_VC_VERSION 8.00)
elseif(MSVC71)
set(USERFILE_VC_VERSION 7.10)
elseif(MSVC10 OR (MSVC AND MSVC_VERSION GREATER 1600)) # 2010 or newer
set(LAUNCHER_LINESEP "\n")
set(USERFILE_VC_VERSION 10.00)
set(USERFILE_EXTENSION user)
set(VCPROJ_TYPE vcxproj)
endif()
if(BITS EQUAL 64)
set(USERFILE_PLATFORM x64)
else()
set(USERFILE_PLATFORM Win${BITS})
endif()
set(_pathdelim ";")
set(_suffix "cmd")
else()
set(_pathdelim ":")
set(USERFILE_PLATFORM ${CMAKE_SYSTEM_NAME}${BITS})
set(_suffix "sh")
find_package(GDB QUIET)
if(GDB_FOUND)
set(LAUNCHERS_GOT_GDB YES)
if(GDB_HAS_RETURN_CHILD_RESULT)
set(LAUNCHERS_GDB_ARG --return-child-result)
endif()
else()
set(LAUNCHERS_GOT_GDB)
endif()
endif()
if(WIN32 AND NOT USERFILE_REMOTE_MACHINE)
site_name(USERFILE_REMOTE_MACHINE)
mark_as_advanced(USERFILE_REMOTE_MACHINE)
endif()
endmacro()
macro(_launcher_process_args)
set(_nowhere)
set(_curdest _nowhere)
set(_val_args
ARGS
RUNTIME_LIBRARY_DIRS
WORKING_DIRECTORY
ENVIRONMENT)
set(_bool_args FORWARD_ARGS)
foreach(_arg ${_val_args} ${_bool_args})
set(${_arg})
endforeach()
foreach(_element ${ARGN})
list(FIND _val_args "${_element}" _val_arg_find)
list(FIND _bool_args "${_element}" _bool_arg_find)
if("${_val_arg_find}" GREATER "-1")
set(_curdest "${_element}")
elseif("${_bool_arg_find}" GREATER "-1")
set("${_element}" ON)
set(_curdest _nowhere)
else()
list(APPEND ${_curdest} "${_element}")
endif()
endforeach()
if(_nowhere)
message(FATAL_ERROR
"Syntax error in use of a function in CreateLaunchers!")
endif()
# Turn into a list of native paths
set(_runtime_lib_dirs)
foreach(_dlldir ${RUNTIME_LIBRARY_DIRS})
file(TO_NATIVE_PATH "${_dlldir}" _path)
set(_runtime_lib_dirs "${_runtime_lib_dirs}${_path}${_pathdelim}")
endforeach()
if(NOT WORKING_DIRECTORY)
set(WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
if(FORWARD_ARGS)
if(WIN32)
set(FWD_ARGS %*)
else()
set(FWD_ARGS $*)
endif()
else()
set(FWD_ARGS)
endif()
set(USERFILE_WORKING_DIRECTORY "${WORKING_DIRECTORY}")
set(USERFILE_COMMAND_ARGUMENTS "${ARGS}")
set(LAUNCHERSCRIPT_COMMAND_ARGUMENTS "${ARGS} ${FWD_ARGS}")
if(WIN32)
set(RUNTIME_LIBRARIES_ENVIRONMENT "PATH=${_runtime_lib_dirs};%PATH%")
file(READ
"${_launchermoddir}/launcher.env.cmd.in"
_cmdenv)
else()
if(APPLE)
set(RUNTIME_LIBRARIES_ENVIRONMENT
"DYLD_LIBRARY_PATH=${_runtime_lib_dirs}:$DYLD_LIBRARY_PATH")
else()
set(RUNTIME_LIBRARIES_ENVIRONMENT
"LD_LIBRARY_PATH=${_runtime_lib_dirs}:$LD_LIBRARY_PATH")
endif()
file(READ
"${_launchermoddir}/launcher.env.sh.in"
_cmdenv)
endif()
set(USERFILE_ENVIRONMENT "${RUNTIME_LIBRARIES_ENVIRONMENT}")
set(USERFILE_ENV_COMMANDS)
foreach(_arg "${RUNTIME_LIBRARIES_ENVIRONMENT}" ${ENVIRONMENT})
string(CONFIGURE
"@USERFILE_ENVIRONMENT@@LAUNCHER_LINESEP@@_arg@"
USERFILE_ENVIRONMENT
@ONLY)
string(CONFIGURE
"@USERFILE_ENV_COMMANDS@${_cmdenv}"
USERFILE_ENV_COMMANDS
@ONLY)
endforeach()
endmacro()
macro(_launcher_produce_vcproj_user)
if(MSVC)
file(READ
"${_launchermoddir}/perconfig.${VCPROJ_TYPE}.user.in"
_perconfig)
file(TO_NATIVE_PATH "${USERFILE_WORKING_DIRECTORY}" NATIVE_WORKING_DIRECTORY)
set(USERFILE_CONFIGSECTIONS)
foreach(USERFILE_CONFIGNAME ${CMAKE_CONFIGURATION_TYPES})
string(CONFIGURE "${_perconfig}" _temp @ONLY ESCAPE_QUOTES)
set(USERFILE_CONFIGSECTIONS "${USERFILE_CONFIGSECTIONS}${_temp}")
endforeach()
configure_file("${_launchermoddir}/${VCPROJ_TYPE}.user.in"
"${VCPROJNAME}.${VCPROJ_TYPE}.${USERFILE_EXTENSION}"
@ONLY)
endif()
endmacro()
macro(_launcher_configure_executable _src _tmp _target)
# get_filename_component(_targetname "${_target}" NAME)
get_filename_component(_targetpath "${_target}" PATH)
configure_file("${_src}"
"${_tmp}"
@ONLY)
file(COPY "${_tmp}"
DESTINATION "${_targetpath}"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endmacro()
macro(_launcher_create_target_launcher)
set(TARGET_NAME ${_targetname})
set(_fn "launch-${_targetname}-generator.${_suffix}")
configure_file("${_launchermoddir}/targetlauncher.${_suffix}.in"
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_fn}"
@ONLY)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/launch-${_targetname}-$<CONFIGURATION>.${_suffix}"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_fn}")
endmacro()
function(create_default_target_launcher _targetname)
_launcher_system_settings()
_launcher_process_args(${ARGN})
set(VCPROJNAME "${CMAKE_BINARY_DIR}/ALL_BUILD")
_launcher_produce_vcproj_user()
_launcher_create_target_launcher()
endfunction()
function(create_target_launcher _targetname)
_launcher_system_settings()
_launcher_process_args(${ARGN})
set(VCPROJNAME "${CMAKE_CURRENT_BINARY_DIR}/${_targetname}")
_launcher_produce_vcproj_user()
_launcher_create_target_launcher()
endfunction()
function(create_generic_launcher _launchername)
_launcher_system_settings()
_launcher_process_args(${ARGN})
if(NOT IS_ABSOLUTE _launchername)
set(_launchername
"${CMAKE_CURRENT_BINARY_DIR}/${_launchername}.${_suffix}")
else()
set(_launchername "${_launchername}.${_suffix}")
endif()
if(WIN32)
set(GENERIC_LAUNCHER_COMMAND "${_launchername}" PARENT_SCOPE)
set(GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION)
else()
set(GENERIC_LAUNCHER_COMMAND sh "${_launchername}" PARENT_SCOPE)
set(GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION
"Program terminated with signal")
endif()
_launcher_configure_executable("${_launchermoddir}/genericlauncher.${_suffix}.in"
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/genericlauncher.${_suffix}.in"
"${_launchername}")
endfunction()
function(guess_runtime_library_dirs _var)
# Start off with the link directories of the calling listfile's directory
get_directory_property(_libdirs LINK_DIRECTORIES)
# Add additional libraries passed to the function
foreach(_lib ${ARGN})
get_filename_component(_libdir "${_lib}" PATH)
list(APPEND _libdirs "${_libdir}")
endforeach()
# Now, build a list of potential dll directories
set(_dlldirs)
foreach(_libdir ${_libdirs})
# Add the libdir itself
list(APPEND _dlldirs "${_libdir}")
# Look also in libdir/../bin since the dll might not be with the lib
get_filename_component(_libdir "${_libdir}/../bin" ABSOLUTE)
list(APPEND _dlldirs "${_libdir}")
endforeach()
# Only keep the valid, unique directories
clean_directory_list(_dlldirs)
# Return _dlldirs
set(${_var} "${_dlldirs}" PARENT_SCOPE)
endfunction()
-88
View File
@@ -1,88 +0,0 @@
# - Add flags to compile with extra warnings
#
# enable_extra_compiler_warnings(<targetname>)
# globally_enable_extra_compiler_warnings() - to modify CMAKE_CXX_FLAGS, etc
# to change for all targets declared after the command, instead of per-command
#
#
# Original Author:
# 2010 Ryan Pavlik <[email protected]> <[email protected]>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__enable_extra_compiler_warnings)
return()
endif()
set(__enable_extra_compiler_warnings YES)
macro(_enable_extra_compiler_warnings_flags)
set(_flags)
if(MSVC)
option(COMPILER_WARNINGS_EXTREME
"Use compiler warnings that are probably overkill."
off)
mark_as_advanced(COMPILER_WARNINGS_EXTREME)
set(_flags "/W4")
if(COMPILER_WARNINGS_EXTREME)
set(_flags "${_flags} /Wall /wd4619 /wd4668 /wd4820 /wd4571 /wd4710")
endif()
else()
include(CheckCXXCompilerFlag)
set(_flags)
check_cxx_compiler_flag(-W SUPPORTS_W_FLAG)
if(SUPPORTS_W_FLAG)
set(_flags "${_flags} -W")
endif()
check_cxx_compiler_flag(-Wall SUPPORTS_WALL_FLAG)
if(SUPPORTS_WALL_FLAG)
set(_flags "${_flags} -Wall")
endif()
check_cxx_compiler_flag(-Wextra SUPPORTS_WEXTRA_FLAG)
if(SUPPORTS_WEXTRA_FLAG)
set(_flags "${_flags} -Wextra")
endif()
if(SUPPORTS_WALL_FLAG)
# At least GCC includes -Wmaybe-uninitialized in -Wall, which
# unneccesarily whines about boost::optional (by it's nature
# it's a "maybe" warning - prone to noisy false-positives)
check_cxx_compiler_flag(-Wno-maybe-uninitialized SUPPORTS_WNO_MAYBE_UNINITIALIZED_FLAG)
if(SUPPORTS_WNO_MAYBE_UNINITIALIZED_FLAG)
set(_flags "${_flags} -Wno-maybe-uninitialized")
endif()
endif()
endif()
endmacro()
function(enable_extra_compiler_warnings _target)
_enable_extra_compiler_warnings_flags()
get_target_property(_origflags ${_target} COMPILE_FLAGS)
if(_origflags)
set_property(TARGET
${_target}
PROPERTY
COMPILE_FLAGS
"${_flags} ${_origflags}")
else()
set_property(TARGET
${_target}
PROPERTY
COMPILE_FLAGS
"${_flags}")
endif()
endfunction()
function(globally_enable_extra_compiler_warnings)
_enable_extra_compiler_warnings_flags()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flags}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flags}" PARENT_SCOPE)
endfunction()
-53
View File
@@ -1,53 +0,0 @@
# - Combine lists of prefixes and suffixes in all combinations
#
# list_combinations(var PREFIXES listitems... SUFFIXES listitems...) -
# where var is the name of your desired output variable and PREFIXES
# and SUFFIXES are special arguments that indicate the start of your
# list of prefixes or suffixes respectively.
#
# Original Author:
# 2009-2010 Ryan Pavlik <[email protected]> <[email protected]>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__list_combinations)
return()
endif()
set(__list_combinations YES)
function(list_combinations var)
# Parse arguments
set(_prefixes)
set(_suffixes)
set(_nowhere)
set(_curdest _nowhere)
foreach(_element ${ARGN})
if("${_element}" STREQUAL "PREFIXES")
set(_curdest _prefixes)
elseif("${_element}" STREQUAL "SUFFIXES")
set(_curdest _suffixes)
else()
list(APPEND ${_curdest} "${_element}")
endif()
endforeach()
if(_nowhere)
message(STATUS "_prefixes ${_prefixes}")
message(STATUS "_prefixes ${_suffixes}")
message(STATUS "_prefixes ${_nowhere}")
message(FATAL_ERROR
"Syntax error in use of ${CMAKE_CURRENT_LIST_FILE}")
endif()
foreach(_prefix ${_prefixes})
foreach(_suffix ${_suffixes})
list(APPEND _out "${_prefix}${_suffix}")
endforeach()
endforeach()
set(${var} "${_out}" PARENT_SCOPE)
endfunction()
-31
View File
@@ -1,31 +0,0 @@
# - Compile with multiple processes on MSVC
#
# include(MSVCMultipleProcessCompile)
#
# Requires these CMake modules:
# ListCombinations.cmake
#
# Original Author:
# 2009-2010 Ryan Pavlik <[email protected]> <[email protected]>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(MSVC AND NOT "${MSVC_VERSION}" LESS 1400)
# Only available in VS 2005 and newer
string(TOUPPER "${CMAKE_CONFIGURATION_TYPES}" _conftypesUC)
include(ListCombinations)
list_combinations(_varnames
PREFIXES
CMAKE_C_FLAGS_
CMAKE_CXX_FLAGS_
SUFFIXES
${_conftypesUC})
foreach(_var ${_varnames})
set(${_var} "${${_var}} /MP")
endforeach()
endif()
+21
View File
@@ -0,0 +1,21 @@
SET(BINARY_DESTINATION "bin")
SET(LIBRAY_DESTINATION "lib")
configure_file("${CMAKE_CURRENT_LIST_DIR}/AppRun.in" "${CMAKE_CURRENT_BINARY_DIR}/AppRun.gen" @ONLY)
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"
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"
COMPONENT "Freespace2")
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION "."
COMPONENT "Freespace2")
+14 -36
View File
@@ -2,72 +2,50 @@
#ifdef _WIN32
#include <intrin.h>
// Windows
#define cpuid __cpuidex
#define xgetbv _xgetbv
#define cpuid __cpuid
#else
#include <cstdint>
// GCC Inline Assembly
void cpuid(int CPUInfo[4], int InfoType, int SubType){
void cpuid(int CPUInfo[4],int InfoType){
__asm__ __volatile__ (
"cpuid":
"=a" (CPUInfo[0]),
"=b" (CPUInfo[1]),
"=c" (CPUInfo[2]),
"=d" (CPUInfo[3]) :
"a" (InfoType),
"c" (SubType)
"a" (InfoType)
);
}
uint64_t xgetbv(uint32_t xcr) {
uint32_t lower, higher;
__asm__ __volatile__ (
"xgetbv":
"=a"(lower),
"=d"(higher) :
"c"(xcr)
);
return (static_cast<uint64_t>(higher) << static_cast<uint64_t>(32)) | static_cast<uint64_t>(lower);
}
#endif
#include <iostream>
int main( int argc, char* argv[] )
{
bool SSE = false;
bool SSE2 = false;
bool OSXSAVE = false;
bool AVX = false;
bool AVX2 = false;
int SSE = false;
int SSE2 = false;
int AVX = false;
int AVX2 = false;
int info[4];
cpuid(info, 0, 0);
cpuid(info, 0);
int nIds = info[0];
// Detect Instruction Set
if (nIds >= 1){
cpuid(info, 0x00000001, 0);
SSE = (info[3] & ((int)1 << 25)) != 0;
SSE2 = (info[3] & ((int)1 << 26)) != 0;
OSXSAVE = (info[2] & ((int)1 << 27)) != 0;
AVX = (info[2] & ((int)1 << 28)) != 0;
cpuid(info,0x00000001);
SSE = (info[3] & ((int)1 << 25)) != 0;
SSE2 = (info[3] & ((int)1 << 26)) != 0;
AVX = (info[2] & ((int)1 << 28)) != 0;
}
if (nIds >= 7){
cpuid(info,0x00000007, 0);
cpuid(info,0x00000007);
AVX2 = (info[1] & ((int)1 << 5)) != 0;
}
// Detect OS Support
if (!OSXSAVE || (xgetbv(0) & 0x6) == 0) {
AVX = false;
AVX2 = false;
}
if (AVX2)
std::cout << "AVX2";
else if(AVX)
-16
View File
@@ -24,19 +24,3 @@ set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
if (FSO_BUILD_WITH_DISCORD)
message(WARNING "Discord support is not tested for cross-compilation. Here be dragons! To disable, set -DFSO_BUILD_WITH_DISCORD:BOOL=OFF")
endif()
if (FSO_BUILD_FRED2)
message(WARNING "FRED2 support is not tested for cross-compilation. Here be dragons! To disable, set -DFSO_BUILD_FRED2:BOOL=OFF")
endif()
if (FSO_USE_SPEECH)
message(WARNING "Speech support is not tested for cross-compilation. Here be dragons! To disable, set -DFSO_USE_SPEECH:BOOL=OFF")
endif()
if (FSO_USE_VOICEREC)
message(WARNING "Voice recognition support is not tested for cross-compilation. Here be dragons! To disable, set -DFSO_USE_VOICEREC:BOOL=OFF")
endif()
+1 -11
View File
@@ -97,19 +97,9 @@ function(handle_embedded_files _target)
set(INCLUDE_LIST "${INCLUDE_LIST}\n#include \"${HEADER_FILE}\"")
set(ARRAY_ELEMENTS "${ARRAY_ELEMENTS}\n\t{ \"${_pathType}\", \"${FILE_NAME}\" , ${FIELD_NAME} , ${FIELD_NAME}_size },")
IF(CMAKE_CROSSCOMPILING)
SET(EMBEDFILE_PATH "EMBEDFILE-NOTFOUND" CACHE FILEPATH "Required for a cross compiling build, point to an embedfile of a cmake build for the host OS")
IF(EMBEDFILE_PATH STREQUAL "EMBEDFILE-NOTFOUND")
#This could, possibly, be configured to compile an embedfile using host compilation automatically, but that seems to be a challenge.
message(FATAL_ERROR "A manual embedfile path must be configured for cross compilation. Set EMBEDFILE_PATH to the location of an embedfile executable, found in the build directories for the host OS.")
ENDIF()
ELSE(CMAKE_CROSSCOMPILING)
SET(EMBEDFILE_PATH "embedfile")
ENDIF(CMAKE_CROSSCOMPILING)
add_custom_command(
OUTPUT ${ALL_OUTPUTS}
COMMAND ${EMBEDFILE_PATH} "${_filePath}" "${_outputBasePath}" "${FIELD_NAME}"
COMMAND embedfile "${_filePath}" "${_outputBasePath}" "${FIELD_NAME}"
MAIN_DEPENDENCY "${_filePath}"
COMMENT "Generating string file for ${_filePath}"
)
+4054
View File
File diff suppressed because it is too large. Load diff
-4
View File
@@ -11,10 +11,6 @@ if (WIN32)
endif()
elseif(APPLE)
# it should just work
elseif(ANDROID)
# connects to a java TTS manager via SDL activity class
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# uses speech-dispatcher with dlopen
else()
message(SEND_ERROR "Text to Speech is not supported on this platform!")
endif()
+4 -32
View File
@@ -8,36 +8,8 @@ else()
set(IS_64BIT FALSE)
endif()
set(IS_ARM64 FALSE)
set(IS_ARMV7A FALSE)
if (NOT "${CMAKE_GENERATOR_PLATFORM}" STREQUAL "") # needed to cover Visual Studio generator
if(CMAKE_GENERATOR_PLATFORM MATCHES "^(aarch64|arm64|ARM64)")
set(IS_ARM64 TRUE)
elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^(armv7)")
set(IS_ARMV7A TRUE)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)")
set(IS_ARM64 TRUE)
else()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)")
set(IS_ARM64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7)")
set(IS_ARMV7A TRUE)
endif()
endif()
set(IS_RISCV FALSE)
if (NOT "${CMAKE_GENERATOR_PLATFORM}" STREQUAL "") # needed to cover Visual Studio generator
if(CMAKE_GENERATOR_PLATFORM MATCHES "^(riscv64|RISCV64|riscv32|RISCV32)")
set(IS_RISCV TRUE)
endif()
else()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(riscv64|RISCV64|riscv32|RISCV32)")
set(IS_RISCV TRUE)
endif()
endif()
set(IS_X86 FALSE)
if (NOT IS_ARM64 AND NOT IS_RISCV AND NOT IS_ARMV7A)
set(IS_X86 TRUE)
endif()
set(IS_ARM64 FALSE)
endif()
@@ -1,14 +0,0 @@
cd @USERFILE_WORKING_DIRECTORY@
@USERFILE_ENV_COMMANDS@
IF NOT [x%1]==[x--debugger] GOTO SkipDebuggingMess
ECHO Need to ditch the debugger!
SHIFT /1
%1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO EOF
:SkipDebuggingMess
%*
:EOF
@@ -1,18 +0,0 @@
#!/bin/sh
bindir=$(pwd)
cd @USERFILE_WORKING_DIRECTORY@
@USERFILE_ENV_COMMANDS@
if test "x$1" = "x--debugger"; then
shift
cmd="$1"
shift
if test "x@LAUNCHERS_GOT_GDB@" = "xYES"; then
echo "r $@" > $bindir/gdbscript
echo "bt" >> $bindir/gdbscript
@GDB_COMMAND@ -batch -command=$bindir/gdbscript @LAUNCHERS_GDB_ARG@ $cmd
else
$cmd $@
fi
else
$@
fi
@@ -1 +0,0 @@
set @_arg@
@@ -1 +0,0 @@
export @_arg@
@@ -1,28 +0,0 @@
<Configuration
Name="@USERFILE_CONFIGNAME@|@USERFILE_PLATFORM@"
>
<DebugSettings
Command="${USERFILE_@USERFILE_CONFIGNAME@_COMMAND}"
WorkingDirectory="@USERFILE_WORKING_DIRECTORY@"
CommandArguments="@USERFILE_COMMAND_ARGUMENTS@"
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="@USERFILE_REMOTE_MACHINE@"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment="@USERFILE_ENVIRONMENT@"
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
@@ -1,7 +0,0 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='@USERFILE_CONFIGNAME@|@USERFILE_PLATFORM@'">
<LocalDebuggerEnvironment>@USERFILE_ENVIRONMENT@</LocalDebuggerEnvironment>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>$(TargetPath)</LocalDebuggerCommand>
<LocalDebuggerCommandArguments>@USERFILE_COMMAND_ARGUMENTS@</LocalDebuggerCommandArguments>
<LocalDebuggerWorkingDirectory>@NATIVE_WORKING_DIRECTORY@</LocalDebuggerWorkingDirectory>
</PropertyGroup>
@@ -1,8 +0,0 @@
cd @USERFILE_WORKING_DIRECTORY@
@USERFILE_ENV_COMMANDS@
if [%1]==[--debugger] (
SHIFT
)
"@USERFILE_COMMAND@" @LAUNCHERSCRIPT_COMMAND_ARGUMENTS@
pause
@@ -1,16 +0,0 @@
#!/bin/sh
bindir=$(pwd)
cd @USERFILE_WORKING_DIRECTORY@
@USERFILE_ENV_COMMANDS@
if test "x$1" = "x--debugger"; then
shift
if test "x@LAUNCHERS_GOT_GDB@" = "xYES"; then
echo "r @LAUNCHERSCRIPT_COMMAND_ARGUMENTS@" > $bindir/gdbscript
echo "bt" >> $bindir/gdbscript
@GDB_COMMAND@ -batch -command=$bindir/gdbscript @LAUNCHERS_GDB_ARG@ @USERFILE_COMMAND@
else
"@USERFILE_COMMAND@" @LAUNCHERSCRIPT_COMMAND_ARGUMENTS@
fi
else
"@USERFILE_COMMAND@" @LAUNCHERSCRIPT_COMMAND_ARGUMENTS@
fi
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="@USERFILE_VC_VERSION@"
ShowAllFiles="false"
>
<Configurations>
@USERFILE_CONFIGSECTIONS@
</Configurations>
</VisualStudioUserFile>
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
@USERFILE_CONFIGSECTIONS@
</Project>
+2
View File
@@ -11,6 +11,8 @@ endif()
target_link_libraries(platform INTERFACE ${COCOA_LIBRARY})
SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
SET(CMAKE_SKIP_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH @loader_path/../Frameworks/)
-1
View File
@@ -10,7 +10,6 @@
#cmakedefine01 IS_64BIT
#cmakedefine01 IS_ARM64
#cmakedefine01 IS_RISCV
#cmakedefine01 SCP_HAVE_STRCASECMP
#cmakedefine01 SCP_HAVE_STRNCASECMP
+2 -2
View File
@@ -13,6 +13,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-char-subscripts")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wno-unused-variable -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wshadow")
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -Wshadow")
+13 -43
View File
@@ -10,40 +10,8 @@ option(CLANG_ENABLE_ADDRESS_SANITIZER "Enable -fsanitize=address" OFF)
option(CLANG_USE_LIBCXX "Use libc++" OFF)
# These are the default values
set(C_BASE_FLAGS "-pipe")
set(CXX_BASE_FLAGS "-pipe")
if(IS_X86)
if(FORCED_NATIVE_SIMD_INSTRUCTIONS)
set(CLANG_EXTENSIONS "-march=native")
elseif (FSO_INSTRUCTION_SET STREQUAL "")
set(CLANG_EXTENSIONS "-march=x86-64")
elseif (FSO_INSTRUCTION_SET STREQUAL "SSE")
set(CLANG_EXTENSIONS "-march=x86-64 -msse -mfpmath=sse")
elseif (FSO_INSTRUCTION_SET STREQUAL "SSE2")
set(CLANG_EXTENSIONS "-march=x86-64 -msse -msse2 -mfpmath=sse")
elseif (FSO_INSTRUCTION_SET STREQUAL "AVX")
set(CLANG_EXTENSIONS "-march=x86-64-v2 -msse -msse2 -mavx -mfpmath=sse")
elseif (FSO_INSTRUCTION_SET STREQUAL "AVX2")
set(CLANG_EXTENSIONS "-march=x86-64-v3 -msse -msse2 -mavx -mavx2 -mfpmath=sse")
else ()
message( FATAL_ERROR "Unknown instruction set encountered for clang. Update toolchain-clang.cmake!" )
endif()
set(C_BASE_FLAGS "${C_BASE_FLAGS} ${CLANG_EXTENSIONS}")
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} ${CLANG_EXTENSIONS}")
elseif(IS_ARM)
if(FORCED_NATIVE_SIMD_INSTRUCTIONS)
set(C_BASE_FLAGS "${C_BASE_FLAGS} -march=native")
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -march=native")
endif ()
elseif(IS_RISCV)
# Default C/CXX_BASE_FLAGS are fine for RISC-V
endif()
if (USE_STATIC_LIBCXX)
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -static-libstdc++ -Qunused-arguments")
endif()
set(C_BASE_FLAGS "-march=native -pipe")
set(CXX_BASE_FLAGS "-march=native -pipe")
# For C and C++, the values can be overwritten independently
if(DEFINED ENV{CXXFLAGS})
@@ -67,6 +35,10 @@ set(COMPILER_FLAGS "${COMPILER_FLAGS} ${_flags}")
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsigned-char -Wno-unknown-pragmas")
# Omit "argument unused during compilation" when clang is used with ccache.
if(${CMAKE_CXX_COMPILER} MATCHES "ccache")
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Qunused-arguments")
endif()
if ("${CMAKE_GENERATOR}" STREQUAL "Ninja")
# Force color diagnostics for Ninja generator
@@ -115,17 +87,17 @@ endif()
string(REGEX MATCH "-O[a-zA-Z|0-9]+" CXX_OPT_FLAG ${CXX_BASE_FLAGS})
string(REGEX MATCH "-O[a-zA-Z|0-9]+" C_OPT_FLAG ${C_BASE_FLAGS})
# If no user-set opt flag, set -O3 and -Og
# If no user-set opt flag, set -O2 and -Og
if ("${CXX_OPT_FLAG}" STREQUAL "")
set(CXX_OPT_FLAG_RELEASE "-O3")
set(CXX_OPT_FLAG_DEBUG "-O0")
set(CXX_OPT_FLAG_RELEASE "-O2")
set(CXX_OPT_FLAG_DEBUG "-Og")
else()
set(CXX_OPT_FLAG_RELEASE "${CXX_OPT_FLAG}")
set(CXX_OPT_FLAG_DEBUG "${CXX_OPT_FLAG}")
endif()
if ("${C_OPT_FLAG}" STREQUAL "")
set(C_OPT_FLAG_RELEASE "-O3")
set(C_OPT_FLAG_DEBUG "-O0")
set(C_OPT_FLAG_RELEASE "-O2")
set(C_OPT_FLAG_DEBUG "-Og")
else()
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
@@ -134,10 +106,8 @@ endif()
set(CXX_FLAGS_RELEASE "${CXX_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-parameter")
set(C_FLAGS_RELEASE "${C_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-parameter")
# Valgrind (as used by CI) does not understand the DWARF5 debug info that clang
# emits by default, so force DWARF4 to keep memcheck able to symbolize the binary.
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -gdwarf-4 -Wshadow")
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -gdwarf-4 -Wshadow")
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -Wshadow")
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -Wshadow")
# Always use the base flags and add our compiler flags at the back
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
+7 -48
View File
@@ -12,49 +12,8 @@ option(GCC_USE_GOLD "Use the gold linker instead of the standard linker" OFF)
option(GCC_GENERATE_GDB_INDEX "Adds linker option to generate the gdb index for debug builds" OFF)
# These are the default values
set(C_BASE_FLAGS "-pipe")
set(CXX_BASE_FLAGS "-pipe")
if(IS_X86)
if(FORCED_NATIVE_SIMD_INSTRUCTIONS)
set(GCC_EXTENSIONS "-march=native")
elseif (FSO_INSTRUCTION_SET STREQUAL "")
set(GCC_EXTENSIONS "-march=x86-64")
elseif (FSO_INSTRUCTION_SET STREQUAL "SSE")
set(GCC_EXTENSIONS "-march=x86-64 -msse -mfpmath=sse")
elseif (FSO_INSTRUCTION_SET STREQUAL "SSE2")
set(GCC_EXTENSIONS "-march=x86-64 -msse -msse2 -mfpmath=sse")
elseif (FSO_INSTRUCTION_SET STREQUAL "AVX")
set(GCC_EXTENSIONS "-march=x86-64-v2 -msse -msse2 -mavx -mfpmath=sse")
elseif (FSO_INSTRUCTION_SET STREQUAL "AVX2")
set(GCC_EXTENSIONS "-march=x86-64-v3 -msse -msse2 -mavx -mavx2 -mfpmath=sse")
else ()
message( FATAL_ERROR "Unknown instruction set encountered for GCC. Update toolchain-gcc.cmake!" )
endif()
set(C_BASE_FLAGS "${C_BASE_FLAGS} ${GCC_EXTENSIONS}")
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} ${GCC_EXTENSIONS}")
if (IS_64BIT)
set(C_BASE_FLAGS "${C_BASE_FLAGS} -m64")
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -m64")
endif()
elseif(IS_ARM)
if(FORCED_NATIVE_SIMD_INSTRUCTIONS)
set(C_BASE_FLAGS "${C_BASE_FLAGS} -march=native")
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -march=native")
endif ()
elseif(IS_RISCV)
# You do not need to pass a -march, passing nothing will make gcc to choose itself.
# If you want a specific set of instructions like vectors, set -march in CFLAGS and CXXFLAGS env variables
# Example for vectors: -march=rv64gcv
# https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html
# As such, default C/CXX_BASE_FLAGS are sufficient.
endif()
if (USE_STATIC_LIBCXX)
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -static-libstdc++")
endif()
set(C_BASE_FLAGS "-march=native -pipe")
set(CXX_BASE_FLAGS "-march=native -pipe")
# For C and C++, the values can be overwritten independently
if(DEFINED ENV{CFLAGS})
@@ -158,17 +117,17 @@ endif()
string(REGEX MATCH "-O[a-zA-Z|0-9]+" CXX_OPT_FLAG ${CXX_BASE_FLAGS})
string(REGEX MATCH "-O[a-zA-Z|0-9]+" C_OPT_FLAG ${C_BASE_FLAGS})
# If no user-set opt flag, set -O3 and -Og
# If no user-set opt flag, set -O2 and -Og
if ("${CXX_OPT_FLAG}" STREQUAL "")
set(CXX_OPT_FLAG_RELEASE "-O3")
set(CXX_OPT_FLAG_DEBUG "-O0")
set(CXX_OPT_FLAG_RELEASE "-O2")
set(CXX_OPT_FLAG_DEBUG "-Og")
else()
set(CXX_OPT_FLAG_RELEASE "${CXX_OPT_FLAG}")
set(CXX_OPT_FLAG_DEBUG "${CXX_OPT_FLAG}")
endif()
if ("${C_OPT_FLAG}" STREQUAL "")
set(C_OPT_FLAG_RELEASE "-O3")
set(C_OPT_FLAG_DEBUG "-O0")
set(C_OPT_FLAG_RELEASE "-O2")
set(C_OPT_FLAG_DEBUG "-Og")
else()
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
+56 -40
View File
@@ -13,13 +13,6 @@ option(MSVC_RELEASE_DEBUGGING "Set options that allow to debug release builds" O
MARK_AS_ADVANCED(FORCE MSVC_USE_RUNTIME_DLL)
MARK_AS_ADVANCED(FORCE MSVC_RELEASE_DEBUGGING)
# Qt is only available as DLL-runtime builds, so qtFRED forces the DLL runtime for the whole tree
if(MSVC_USE_RUNTIME_DLL OR FSO_BUILD_QTFRED)
set(FSO_MSVC_RUNTIME_DLL ON)
else()
set(FSO_MSVC_RUNTIME_DLL OFF)
endif()
# These are the warnings we disable
set(WARNING_FLAGS
/wd4100 # unreferenced formal parameters
@@ -53,13 +46,9 @@ target_compile_options(compiler INTERFACE ${WARNING_FLAGS})
set(CMAKE_C_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /Zc:forScope /Gd /EHsc /nologo /Zm200")
set(CMAKE_CXX_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /Zc:forScope /Gd /EHsc /nologo /Zm200")
set(CMAKE_EXE_LINKER_FLAGS "/MANIFEST /SAFESEH:NO /ERRORREPORT:PROMPT /NOLOGO")
set(CMAKE_EXE_LINKER_FLAGS "/MANIFEST /DYNAMICBASE:NO /SAFESEH:NO /ERRORREPORT:PROMPT /NOLOGO")
set(CMAKE_STATIC_LINKER_FLAGS "")
if(NOT IS_ARM64)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DYNAMICBASE:NO")
endif()
# Release
set(CMAKE_C_FLAGS_RELEASE "/GL /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
set(CMAKE_CXX_FLAGS_RELEASE "/GL /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
@@ -78,50 +67,77 @@ if (MSVC_RELEASE_DEBUGGING)
endif()
endif()
# The debug runtime is not redistributable (statically linked or not), so only Debug may use it
IF(FSO_MSVC_RUNTIME_DLL)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
add_compile_definitions(_AFXDLL)
ELSE()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
ENDIF()
IF(MSVC_USE_RUNTIME_DLL)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
ELSE(MSVC_USE_RUNTIME_DLL)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
ENDIF(MSVC_USE_RUNTIME_DLL)
# Debug
set(CMAKE_C_FLAGS_DEBUG "/W4 /Gy /Zi /Od /RTC1 /Gd /Oy-")
set(CMAKE_CXX_FLAGS_DEBUG "/W4 /Gy /Zi /Od /RTC1 /Gd /Oy-")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /INCREMENTAL:NO /MAPINFO:EXPORTS /NODEFAULTLIB:libcmt.lib")
IF(MSVC_USE_RUNTIME_DLL)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
ELSE(MSVC_USE_RUNTIME_DLL)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
ENDIF(MSVC_USE_RUNTIME_DLL)
INCLUDE(MSVCMultipleProcessCompile)
# Visual Studio supports compiling for multiple vector instruction sets
SET(POSSIBLE_INSTUCTION_SETS "" SSE SSE2 AVX AVX2)
if(IS_X86)
if(FORCED_NATIVE_SIMD_INSTRUCTIONS)
# MSVC has no direct -march=native equivalent, so just use the detected extensions.
SET(FSO_INSTRUCTION_SET ${DETECTED_SIMD_INSTRUCTIONS})
endif()
if (NOT DEFINED MSVC_SIMD_INSTRUCTIONS)
detect_simd_instructions(MSVC_DETECTED_SIMD_INSTRUCTIONS)
if(FSO_INSTRUCTION_SET STREQUAL "")
set(MSVC_SIMD_INSTRUCTIONS "IA32")
else()
set(MSVC_SIMD_INSTRUCTIONS ${FSO_INSTRUCTION_SET})
endif()
SET(MSVC_SIMD_INSTRUCTIONS "${MSVC_DETECTED_SIMD_INSTRUCTIONS}" CACHE FILEPATH "The SIMD instructions which will be used, possible values are ${POSSIBLE_INSTUCTION_SETS}")
MARK_AS_ADVANCED(FORCE MSVC_SIMD_INSTRUCTIONS)
endif()
set(FSO_INSTRUCTION_SET ${MSVC_SIMD_INSTRUCTIONS})
if (NOT (IS_64BIT AND (MSVC_SIMD_INSTRUCTIONS STREQUAL "IA32" OR MSVC_SIMD_INSTRUCTIONS STREQUAL "SSE" OR MSVC_SIMD_INSTRUCTIONS STREQUAL "SSE2")))
# 32-Bit and SSE(2) mustn't be set, as these are implied in x86_64 and thus MSVC does not support it for the /arch argument
CHECK_CXX_COMPILER_FLAG("/arch:${MSVC_SIMD_INSTRUCTIONS}" COMPILER_SUPPORTS_ARCH)
LIST(FIND POSSIBLE_INSTUCTION_SETS "${MSVC_SIMD_INSTRUCTIONS}" SET_INDEX)
IF(COMPILER_SUPPORTS_ARCH)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:${MSVC_SIMD_INSTRUCTIONS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:${MSVC_SIMD_INSTRUCTIONS}")
ELSE()
message( FATAL_ERROR "Your version of MSVC does not support the requested instruction set. Consider updating!" )
ENDIF()
endif()
if (SET_INDEX LESS 0)
MESSAGE(STATUS "An invalid instruction set was specified, defaulting to no special compiler options.")
else()
IF (NOT SET_INDEX EQUAL 0)
SET(FOUND)
FOREACH(list_index RANGE ${SET_INDEX} 1)
list(GET POSSIBLE_INSTUCTION_SETS ${list_index} _simd_set)
CHECK_CXX_COMPILER_FLAG("/arch:${_simd_set}" COMPILER_SUPPORTS_ARCH_${_simd_set})
IF(COMPILER_SUPPORTS_ARCH_${_simd_set})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:${_simd_set}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:${_simd_set}")
SET(FOUND TRUE)
BREAK()
ENDIF()
ENDFOREACH(list_index)
IF(NOT FOUND)
# Don't set anything, it will likely not work
MESSAGE(STATUS "Your compiler does not support any optimization flags, defaulting to none")
ENDIF(NOT FOUND)
ELSE()
CHECK_CXX_COMPILER_FLAG("/arch:IA32" COMPILER_SUPPORTS_ARCH_IA32)
IF(COMPILER_SUPPORTS_ARCH_IA32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:IA32")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:IA32")
ENDIF(COMPILER_SUPPORTS_ARCH_IA32)
ENDIF()
endif()
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
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
+10 -56
View File
@@ -3,62 +3,7 @@
add_library(compiler INTERFACE)
set(FSO_CONFIG_DEFINITIONS "$<$<CONFIG:Release>:NDEBUG>" "$<$<CONFIG:Debug>:_DEBUG>")
if(NOT MSVC)
# On MSVC the debug runtime flags (/MTd, /MDd) define _DEBUG themselves, and a FastDebug
# build on the release runtime must not have it
list(APPEND FSO_CONFIG_DEFINITIONS "$<$<CONFIG:FastDebug>:_DEBUG>")
endif()
target_compile_definitions(compiler INTERFACE ${FSO_CONFIG_DEFINITIONS})
set(FORCED_NATIVE_SIMD_INSTRUCTIONS ON CACHE BOOL "Override instruction set detection and compile with the maximum possible instructions for the current system.")
IF(IS_X86)
SET(POSSIBLE_INSTRUCTION_SETS "" SSE SSE2 AVX AVX2)
if (CMAKE_CROSSCOMPILING)
message("Cross-Compile cannot detect supported instruction sets. Defaulting to SSE2. Disabling host-optimization.")
set(FORCED_NATIVE_SIMD_INSTRUCTIONS OFF)
set(DETECTED_SIMD_INSTRUCTIONS SSE2)
else()
detect_simd_instructions(DETECTED_SIMD_INSTRUCTIONS)
endif()
set(FORCED_SIMD_INSTRUCTIONS "" CACHE STRING "Overrides any instruction set settings (including forced-native). Any of ${POSSIBLE_INSTRUCTION_SETS}.")
if (NOT FORCED_SIMD_INSTRUCTIONS STREQUAL "")
set(FORCED_NATIVE_SIMD_INSTRUCTIONS OFF)
LIST(FIND POSSIBLE_INSTRUCTION_SETS "${FORCED_SIMD_INSTRUCTIONS}" SET_INDEX)
if (SET_INDEX LESS 0)
MESSAGE(STATUS "An invalid instruction set was specified, defaulting to no special compiler options.")
set(FSO_INSTRUCTION_SET "")
else ()
LIST(FIND POSSIBLE_INSTRUCTION_SETS "${DETECTED_SIMD_INSTRUCTIONS}" SET_INDEX)
if (SET_INDEX LESS 0)
MESSAGE(STATUS "An instruction set was specified which is unsupported on this platform. Compiled binary might not be executable.")
endif()
set(FSO_INSTRUCTION_SET ${FORCED_SIMD_INSTRUCTIONS})
endif()
else()
SET(FSO_INSTRUCTION_SET ${DETECTED_SIMD_INSTRUCTIONS})
endif()
MESSAGE(STATUS "Using instruction set level ${FSO_INSTRUCTION_SET}. Optimizations for host-system specifically: ${FORCED_NATIVE_SIMD_INSTRUCTIONS}.")
if (FSO_INSTRUCTION_SET STREQUAL "SSE")
add_compile_definitions(FSO_SIMD_SSE)
elseif (FSO_INSTRUCTION_SET STREQUAL "SSE2")
add_compile_definitions(FSO_SIMD_SSE)
add_compile_definitions(FSO_SIMD_SSE2)
elseif (FSO_INSTRUCTION_SET STREQUAL "AVX")
add_compile_definitions(FSO_SIMD_SSE)
add_compile_definitions(FSO_SIMD_SSE2)
add_compile_definitions(FSO_SIMD_AVX)
elseif (FSO_INSTRUCTION_SET STREQUAL "AVX2")
add_compile_definitions(FSO_SIMD_SSE)
add_compile_definitions(FSO_SIMD_SSE2)
add_compile_definitions(FSO_SIMD_AVX)
add_compile_definitions(FSO_SIMD_AVX2)
endif()
ENDIF()
target_compile_definitions(compiler INTERFACE "$<$<CONFIG:Release>:NDEBUG>;$<$<CONFIG:Debug>:_DEBUG>;$<$<CONFIG:FastDebug>:_DEBUG>")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
include(toolchain-gcc)
@@ -80,3 +25,12 @@ set(CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS_FASTDEBUG "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
set(CMAKE_STATIC_LINKER_FLAGS_FASTDEBUG "${CMAKE_STATIC_LINKER_FLAGS_RELEASE}")
if (MSVC)
# Adjust runtime library
string(REPLACE "/MD" "/MDd" CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_FASTDEBUG}")
string(REPLACE "/MT" "/MTd" CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_FASTDEBUG}")
string(REPLACE "/MD" "/MDd" CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_FASTDEBUG}")
string(REPLACE "/MT" "/MTd" CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_FASTDEBUG}")
endif()
+35 -40
View File
@@ -66,37 +66,33 @@ ENDIF(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\")
SET(${OUTVAR} "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${NAME} PARENT_SCOPE)
ENDFUNCTION(EP_CHECK_FILE_EXISTS)
# Use rsync if possible for COPY_FILE_TO_TARGET macro in order to preserve
# symlinks as copy_if_different follows them which results in multiple copies
if(PLATFORM_UNIX AND NOT DEFINED RSYNC_BIN)
find_program(RSYNC_BIN rsync)
endif()
MACRO(COPY_FILE_TO_TARGET _target _file)
if(RSYNC_BIN)
ADD_CUSTOM_COMMAND(
TARGET ${_target} POST_BUILD
COMMAND ${RSYNC_BIN} -rlq "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}"
COMMENT "copying '${_file}'..."
VERBATIM
)
else()
if (IS_DIRECTORY "${_file}")
get_filename_component(_dirName "${_file}" NAME)
if (IS_DIRECTORY "${_file}")
get_filename_component(_dirName "${_file}" NAME)
if (PLATFORM_MAC AND ("${_file}" MATCHES ".framework$"))
# This is stupid, but it preserves symlinks, unlike copy_directory_if_different.
# Otherwise we end up creating duplicate files in the copied framework.
ADD_CUSTOM_COMMAND(
TARGET ${_target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/${_dirName}"
COMMAND rsync -rlq "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}"
COMMENT "copying '${_file}'..."
VERBATIM
)
else()
ADD_CUSTOM_COMMAND(
TARGET ${_target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/${_dirName}"
COMMENT "copying '${_file}'..."
VERBATIM
)
endif()
else()
ADD_CUSTOM_COMMAND(
TARGET ${_target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
COMMENT "copying '${_file}'..."
VERBATIM
)
endif()
endmacro(COPY_FILE_TO_TARGET)
@@ -162,17 +158,27 @@ function(set_precompiled_header _target _headerPath)
target_compile_definitions(${_target} PRIVATE CMAKE_PCH)
target_precompile_headers(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${_headerPath}>")
else()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:/FI ${_headerPath}>")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
ELSE()
MESSAGE("Unknown compiler for global includes. This will probably break the build.")
ENDIF()
if (ENABLE_COTIRE)
message("${_headerPath}")
set_target_properties(${_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${_headerPath}")
# Disable unity build as it doesn't work well for us
set_target_properties(${_target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
cotire(${_target})
else()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:/FI ${_headerPath}>")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
ELSE()
MESSAGE("Unknown compiler for global includes. This will probably break the build.")
ENDIF()
endif()
endif()
endfunction()
@@ -241,17 +247,6 @@ function(suppress_file_warnings)
endif()
endfunction(suppress_file_warnings)
# Suppress no symbols warnings in static libraries (on Xcode)
function(suppress_no_symbol_warnings _target)
if(XCODE)
get_target_property(target_type ${_target} TYPE)
if(target_type STREQUAL "STATIC_LIBRARY")
set_property(TARGET ${_target} APPEND PROPERTY
STATIC_LIBRARY_OPTIONS "-no_warning_for_no_symbols"
)
endif()
endif()
endfunction(suppress_no_symbol_warnings)
function(list_target_dependencies _target _out_var)
set(out_list)
+2 -8
View File
@@ -6,7 +6,7 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
include("${PROJECT_SOURCE_DIR}/version_override.cmake")
endif()
set_if_not_defined(FSO_VERSION_MAJOR 26)
set_if_not_defined(FSO_VERSION_MAJOR 23)
set_if_not_defined(FSO_VERSION_MINOR 3)
set_if_not_defined(FSO_VERSION_BUILD 0)
@@ -35,13 +35,7 @@ ELSE()
SET(FSO_BINARY_SUFFIX "${FSO_VERSION_MAJOR}_${FSO_VERSION_MINOR}_${FSO_VERSION_BUILD}_${FSO_VERSION_REVISION_STR}")
ENDIF()
IF(IS_RISCV)
IF(IS_64BIT)
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_riscv64")
ELSE()
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_riscv32")
ENDIF()
ELSEIF(IS_ARM64)
IF(IS_ARM64)
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_arm64")
ELSEIF(IS_64BIT)
# This is a 64-bit builds
+26 -22
View File
@@ -6,7 +6,7 @@ INCLUDE(voice_rec.cmake)
ADD_LIBRARY(code STATIC ${source_files} ${VOICE_REC_FILES})
target_compile_features(code PUBLIC cxx_std_17)
target_compile_features(code PUBLIC cxx_std_11)
if (MSVC)
target_compile_definitions(code PUBLIC "PDB_DEBUGGING=1")
@@ -25,11 +25,7 @@ if (FSO_BUILD_WITH_OPENGL)
endif()
endif()
if(FSO_BUILD_WITH_OPENXR)
add_definitions(-DFS_OPENXR)
endif()
if(FSO_BUILD_WITH_OPENXR_DEBUG AND FSO_BUILD_WITH_OPENXR)
if(FSO_BUILD_WITH_OPENXR_DEBUG)
add_definitions(-DFS_OPENXR_DEBUG)
endif()
@@ -39,7 +35,7 @@ TARGET_LINK_LIBRARIES(code PUBLIC ${PNG_LIBS})
TARGET_LINK_LIBRARIES(code PUBLIC ${JPEG_LIBS})
TARGET_LINK_LIBRARIES(code PUBLIC lz4)
TARGET_LINK_LIBRARIES(code PUBLIC sdl3)
TARGET_LINK_LIBRARIES(code PUBLIC sdl2)
if (FSO_BUILD_WITH_FFMPEG)
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
@@ -52,14 +48,11 @@ TARGET_LINK_LIBRARIES(code PUBLIC compiler)
target_link_libraries(code PUBLIC md5)
if (FSO_BUILD_WITH_DISCORD)
target_link_libraries(code PUBLIC discord-rpc)
add_definitions(-DWITH_DISCORD)
endif()
target_link_libraries(code PUBLIC discord-rpc)
target_link_libraries(code PUBLIC libRocket)
target_link_libraries(code PUBLIC pcpnatpmp)
target_link_libraries(code PUBLIC pcp)
target_link_libraries(code PUBLIC parsers)
@@ -74,12 +67,19 @@ ENDIF(FSO_USE_SPEECH)
TARGET_LINK_LIBRARIES(code PUBLIC jansson)
target_link_libraries(code PUBLIC variant)
target_link_libraries(code PUBLIC any)
target_link_libraries(code PUBLIC optional)
target_link_libraries(code PUBLIC anl)
target_link_libraries(code PUBLIC imgui)
target_link_libraries(code PUBLIC implot)
target_link_libraries(code PUBLIC hidapi::hidapi)
IF(FSO_BUILD_WITH_OPENXR)
target_link_libraries(code PUBLIC imgui)
IF(NOT APPLE)
target_link_libraries(code PUBLIC OpenXR::openxr_loader)
target_include_directories(code PUBLIC OpenXR::Headers)
ENDIF()
@@ -112,9 +112,16 @@ if (FSO_BUILD_WITH_OPENGL)
target_compile_definitions(code PUBLIC WITH_OPENGL)
endif()
if (FSO_BUILD_WITH_VULKAN)
target_compile_definitions(code PUBLIC WITH_VULKAN VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VK_NO_PROTOTYPES)
target_include_directories(code PUBLIC Vulkan::Headers)
target_link_libraries(code PUBLIC VulkanMemoryAllocator)
find_package(Vulkan REQUIRED)
if (Vulkan_FOUND)
target_compile_definitions(code PUBLIC WITH_VULKAN)
target_link_libraries(code PRIVATE Vulkan::Vulkan)
target_compile_definitions(code PUBLIC WITH_VULKAN VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VK_NO_PROTOTYPES)
else()
message(WARNING "FSO_BUILD_WITH_VULKAN was set, but the package was unable to be found. Forcing OFF.")
set(FSO_BUILD_WITH_VULKAN OFF CACHE BOOL "Enable compilation of the Vulkan renderer" FORCE)
endif()
endif()
include(shaders.cmake)
@@ -131,8 +138,5 @@ set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=D
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT[variant=Debug] "NO")
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN[variant=Debug] "NO")
# Prevent warnings on files with no symbols on Mac
suppress_no_symbol_warnings(code)
# Prevent GCC warnings in third-party BitOp... see GitHub #4366
suppress_file_warnings(scripting/lua/bitop/bit.c)
suppress_file_warnings(scripting/lua/bitop/bit.c)
+1 -1
View File
@@ -30,7 +30,7 @@ class BuiltinActionDefinition : public ActionDefinition {
// This should have been caught earlier
Assertion(paramIter != parameterExpressions.cend(), "Could not find built-in parameter!");
return std::make_unique<TAction>(paramIter->second.template asTyped<ActionValueType>());
return std::unique_ptr<Action>(new TAction(paramIter->second.template asTyped<ActionValueType>()));
}
};
+1 -1
View File
@@ -47,7 +47,7 @@ ProgramInstance::ProgramInstance(const actions::Program* program) : _program(pro
ProgramState ProgramInstance::step()
{
if (!_locals.host.isValid()) {
if (!_locals.host.IsValid()) {
return ProgramState::Done;
}
+1 -1
View File
@@ -19,7 +19,7 @@ expression::ProgramVariables getDefaultTableVariables()
expression::ProgramVariables vars;
vars.setValue({"locals", "position"}, expression::Value(vmd_zero_vector));
vars.setValue({"locals", "direction"}, expression::Value(vmd_z_vector));
vars.setValue({"locals", "direction"}, expression::Value(vmd_zero_vector));
return vars;
}
+2 -2
View File
@@ -24,7 +24,7 @@ ActionExpression ActionExpression::parseFromTable(ValueType expectedReturnType,
stuff_string(expressionText, F_NAME);
ExpressionParser parser(std::move(expressionText));
ExpressionParser parser(expressionText);
auto expression = parser.parse(context);
@@ -45,7 +45,7 @@ ActionExpression ActionExpression::parseFromTable(ValueType expectedReturnType,
}
// Everything is valid
return ActionExpression(std::move(expression));
return ActionExpression(expression);
}
Value ActionExpression::execute(const ProgramVariables& variables) const
+8 -8
View File
@@ -51,8 +51,8 @@ class ExpressionBuilderVisitor : public ActionExpressionVisitor {
operatorText = context->MINUS()->getText();
}
const auto leftExpr = std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(0)));
const auto rightExpr = std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(1)));
const auto leftExpr = visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>();
const auto rightExpr = visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto operatorExpression = std::make_shared<nodes::FunctionCallExpression>(operatorTok,
true,
@@ -88,8 +88,8 @@ class ExpressionBuilderVisitor : public ActionExpressionVisitor {
antlrcpp::Any visitRandom_range_expression(ActionExpressionParser::Random_range_expressionContext* context) override
{
auto expression = std::make_shared<nodes::RandomRangeExpression>(context->RAND_L_PAREN()->getSymbol(),
std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(0))),
std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(1))));
visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>(),
visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>());
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
}
antlrcpp::Any visitLiteral_expression(ActionExpressionParser::Literal_expressionContext* context) override
@@ -122,9 +122,9 @@ class ExpressionBuilderVisitor : public ActionExpressionVisitor {
}
antlrcpp::Any visitVec3d_constructor(ActionExpressionParser::Vec3d_constructorContext* context) override
{
const auto xExpression = std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(0)));
const auto yExpression = std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(1)));
const auto zExpression = std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(visit(context->expression(2)));
auto xExpression = visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto yExpression = visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto zExpression = visit(context->expression(2)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto expression = std::make_shared<nodes::VectorConstructorExpression>(context->L_PAREN()->getSymbol(),
xExpression,
@@ -157,7 +157,7 @@ std::shared_ptr<nodes::AbstractExpression> ExpressionParser::parse(const ParseCo
if (errListener.diagnostics.empty()) {
// Only do semantic checking if syntax is valid
ExpressionBuilderVisitor builder;
exprReturn = std::any_cast<std::shared_ptr<nodes::AbstractExpression>>(tree->accept(&builder));
exprReturn = tree->accept(&builder).as<std::shared_ptr<nodes::AbstractExpression>>();
if (!exprReturn->validate(&parser, context)) {
exprReturn = nullptr;
+1 -1
View File
@@ -6,7 +6,7 @@ namespace expression {
ProgramVariablesDefinition& ProgramVariablesDefinition::addScope(const SCP_string& name)
{
auto scope = std::make_unique<ProgramVariablesDefinition>();
auto scope = std::unique_ptr<ProgramVariablesDefinition>(new ProgramVariablesDefinition());
auto scopePtr = scope.get();
+1 -1
View File
@@ -38,7 +38,7 @@ const TypeDefinition& TypeDefinition::forValueType(ValueType type)
case ValueType::String:
return s_identifier;
default:
UNREACHABLE("Invalid value type %d!", static_cast<int>(type));
UNREACHABLE("Invalid value type!");
return s_integer; // Make compiler happy
}
}
+4 -4
View File
@@ -2,7 +2,7 @@
#include "globalincs/pstypes.h"
#include <variant>
#include <mpark/variant.hpp>
namespace actions {
namespace expression {
@@ -85,10 +85,10 @@ class Value {
if (currentType == expectedType) {
// No conversion necessary
return std::get<T>(m_value);
return mpark::get<T>(m_value);
}
return std::visit(detail::implicit_conversion<T>{}, m_value);
return mpark::visit(detail::implicit_conversion<T>{}, m_value);
}
friend bool operator==(const Value& lhs, const Value& rhs);
@@ -97,7 +97,7 @@ class Value {
friend std::ostream& operator<<(std::ostream& os, const Value& value);
private:
std::variant<std::monostate, int, float, vec3d, SCP_string> m_value;
mpark::variant<mpark::monostate, int, float, vec3d, SCP_string> m_value;
};
} // namespace expression
+6 -4
View File
@@ -26,8 +26,10 @@ ActionResult MoveToSubmodel::execute(ProgramLocals& locals) const
// The calling code should ensure that this never happens
Assertion(locals.hostSubobject >= 0, "Did not have a valid host subobject.");
auto pmi = object_get_model_instance(locals.host.objp());
Assertion(pmi != nullptr, "Model instances are required if a host subobject is specified.");
auto instance = object_get_model_instance(locals.host.objp);
Assertion(instance != -1, "Model instances are required if a host subobject is specified.");
auto pmi = model_get_instance(instance);
auto pm = model_get(pmi->model_num);
const auto destinationSubObject = m_subObjectExpression.execute(locals.variables);
@@ -55,7 +57,7 @@ ActionResult MoveToSubmodel::execute(ProgramLocals& locals) const
// We need to do a linear search for the right subobject
for (int i = 0; i < pm->n_models; ++i) {
const auto& submodel = pm->submodel[i];
const auto submodel = pm->submodel[i];
if (subsystem_stricmp(destinationSubObject.c_str(), submodel.name) == 0) {
// Found something!
@@ -70,7 +72,7 @@ ActionResult MoveToSubmodel::execute(ProgramLocals& locals) const
std::unique_ptr<Action> MoveToSubmodel::clone() const
{
return std::make_unique<MoveToSubmodel>(*this);
return std::unique_ptr<Action>(new MoveToSubmodel(*this));
}
} // namespace types
+9 -9
View File
@@ -3,8 +3,6 @@
#include "math/vecmat.h"
#include "parse/parselo.h"
#include "particle/hosts/EffectHostObject.h"
#include "particle/ParticleManager.h"
#include "ship/ship.h"
#include <utility>
@@ -39,8 +37,10 @@ ActionResult ParticleEffectAction::execute(ProgramLocals& locals) const
vec3d local_pos;
matrix local_orient;
if (locals.hostSubobject != -1) {
auto pmi = object_get_model_instance(locals.host.objp());
Assertion(pmi != nullptr, "Model instances are required if a host subobject is specified.");
auto instance = object_get_model_instance(locals.host.objp);
Assertion(instance != -1, "Model instances are required if a host subobject is specified.");
auto pmi = model_get_instance(instance);
auto pm = model_get(pmi->model_num);
model_instance_local_to_global_point_orient(&local_pos,
@@ -58,18 +58,18 @@ ActionResult ParticleEffectAction::execute(ProgramLocals& locals) const
local_pos += locals.variables.getValue({"locals", "position"}).getVector();
auto direction = locals.variables.getValue({"locals", "direction"}).getVector();
matrix orientation;
vm_vector_2_matrix_norm(&orientation, &direction); // direction is normalized in SetDirectionAction::execute
source->setHost(std::make_unique<EffectHostObject>(locals.host.objp(), local_pos, orientation, true));
source->finishCreation();
source.moveToObject(locals.host.objp, &local_pos);
source.setOrientationFromNormalizedVec(&direction, true);
source.finish();
return ActionResult::Finished;
}
std::unique_ptr<Action> ParticleEffectAction::clone() const
{
return std::make_unique<ParticleEffectAction>(*this);
return std::unique_ptr<Action>(new ParticleEffectAction(*this));
}
} // namespace types
@@ -2,6 +2,7 @@
#include "actions/Action.h"
#include "actions/expression/ActionExpression.h"
#include "particle/ParticleManager.h"
namespace actions {
namespace types {
+7 -5
View File
@@ -26,8 +26,10 @@ ActionResult PlaySoundAction::execute(ProgramLocals& locals) const
vec3d local_pos;
matrix local_orient;
if (locals.hostSubobject != -1) {
auto pmi = object_get_model_instance(locals.host.objp());
Assertion(pmi != nullptr, "Model instances are required if a host subobject is specified.");
auto instance = object_get_model_instance(locals.host.objp);
Assertion(instance != -1, "Model instances are required if a host subobject is specified.");
auto pmi = model_get_instance(instance);
auto pm = model_get(pmi->model_num);
model_instance_local_to_global_point_orient(&local_pos,
@@ -45,8 +47,8 @@ ActionResult PlaySoundAction::execute(ProgramLocals& locals) const
local_pos += locals.variables.getValue({"locals", "position"}).getVector();
vec3d global_pos;
vm_vec_unrotate(&global_pos, &local_pos, &locals.host.objp()->orient);
global_pos += locals.host.objp()->pos;
vm_vec_unrotate(&global_pos, &local_pos, &locals.host.objp->orient);
global_pos += locals.host.objp->pos;
const auto soundId = gamesnd_get_by_name(m_soundIdExpression.execute(locals.variables).c_str());
@@ -57,7 +59,7 @@ ActionResult PlaySoundAction::execute(ProgramLocals& locals) const
}
std::unique_ptr<Action> PlaySoundAction::clone() const
{
return std::make_unique<PlaySoundAction>(*this);
return std::unique_ptr<Action>(new PlaySoundAction(*this));
}
} // namespace types
} // namespace actions
+1 -1
View File
@@ -32,7 +32,7 @@ ActionResult SetDirectionAction::execute(ProgramLocals& locals) const
std::unique_ptr<Action> SetDirectionAction::clone() const
{
return std::make_unique<SetDirectionAction>(*this);
return std::unique_ptr<Action>(new SetDirectionAction(*this));
}
} // namespace types
+1 -1
View File
@@ -27,7 +27,7 @@ ActionResult SetPositionAction::execute(ProgramLocals& locals) const
std::unique_ptr<Action> SetPositionAction::clone() const
{
return std::make_unique<SetPositionAction>(*this);
return std::unique_ptr<Action>(new SetPositionAction(*this));
}
} // namespace types
+1 -1
View File
@@ -41,7 +41,7 @@ ActionResult WaitAction::execute(actions::ProgramLocals& locals) const
}
std::unique_ptr<Action> WaitAction::clone() const
{
return std::make_unique<WaitAction>(*this);
return std::unique_ptr<Action>(new WaitAction(*this));
}
} // namespace types
+12 -7
View File
@@ -16,11 +16,9 @@
#include "ai/ai.h"
#include "object/object.h"
#include "ship/ship.h"
#include "utils/string_utils.h"
// heap-allocated rather than SCP_string, so that the pointers held by ai goals stay valid when the vector grows
SCP_vector<SCP_vm_unique_ptr<char>> Goal_target_names;
SCP_vector<char *> Goal_target_names;
ai_info Ai_info[MAX_AI_INFO];
ai_info *Player_ai;
@@ -59,13 +57,20 @@ const char *ai_get_goal_target_name(const char *name, int *index)
Assertion(name != nullptr && index != nullptr, "Arguments cannot be null!");
for (int i = 0; i < static_cast<int>(Goal_target_names.size()); ++i) {
if (!stricmp(name, Goal_target_names[i].get())) {
if (!stricmp(name, Goal_target_names[i])) {
*index = i;
return Goal_target_names[i].get();
return Goal_target_names[i];
}
}
*index = static_cast<int>(Goal_target_names.size());
Goal_target_names.push_back(util::vm_unique_copy(name, false));
return Goal_target_names.back().get();
Goal_target_names.push_back(vm_strdup(name));
return Goal_target_names[*index];
}
void ai_clear_goal_target_names()
{
for (auto ptr : Goal_target_names)
vm_free(ptr);
Goal_target_names.clear();
}
+19 -25
View File
@@ -36,13 +36,12 @@ typedef struct ai_flag_name {
typedef struct ai_flag_description {
AI::AI_Flags flag;
const char *flag_desc;
SCP_string flag_desc;
} ai_flag_description;
extern ai_flag_name Ai_flag_names[];
extern ai_flag_description Ai_flag_descriptions[];
extern const int Num_ai_flag_names;
extern const size_t Num_ai_flag_descriptions;
// dock_orient_and_approach() modes.
#define DOA_APPROACH 1 // Approach the current point on the path (aip->path_cur)
@@ -97,7 +96,6 @@ extern const size_t Num_ai_flag_descriptions;
#define MAX_ENEMY_DISTANCE 2500.0f // Maximum distance from which a ship will pursue an enemy.
#define MAX_AI_GOALS 5
#define AI_ACTIVE_GOAL_NONE -1
#define AI_ACTIVE_GOAL_DYNAMIC 999
typedef struct ai_class {
@@ -278,8 +276,8 @@ typedef struct ai_info {
int ai_class; // Class. Might be override of default.
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
int wp_list_index; // index of waypoint list being followed
int wp_index; // index of waypoint in list
waypoint_list *wp_list; // waypoint list being followed
int wp_index; // waypoint index in list
int wp_flags; // waypoint flags, see WPF_xxxx
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
@@ -295,7 +293,6 @@ typedef struct ai_info {
vec3d path_create_pos; // Object's position at time of global path creation.
matrix path_create_orient; // Object's orientation at time of global path creation.
int mp_index; // Model path index. Index in polymodel:model_paths
int mp_randomized_vert; // Vertex of the model path that was given a random offset, or -1
fix path_next_check_time; // Last time checked to see if would collide with model.
int path_goal_dist; // minimum distance to first path point to consider path reached
int path_subsystem_next_check; // timestamp to next check if subsystem is still visible
@@ -320,7 +317,7 @@ typedef struct ai_info {
//Unlike the predicted position stuff, also takes into account velocity
//Only used against small ships
fix next_aim_pos_time;
vec3d last_aim_enemy_pos; // Normally this is the position of the enemy a turret is targeting but in the F3 Lab, this is used to pass raw target coordinates to the turret firing methods.
vec3d last_aim_enemy_pos;
vec3d last_aim_enemy_vel;
ai_goal goals[MAX_AI_GOALS];
@@ -332,7 +329,7 @@ typedef struct ai_info {
float time_enemy_near; // SUSHI: amount of time enemy continuously "near" the player
fix last_attack_time; // Missiontime of last time this ship attacked its enemy.
fix last_hit_time; // Missiontime of last time this ship was hit by anyone.
int danger_shield_quadrant; // Shield section AI will prefer to prioritize for recharging, it if possible.
int last_hit_quadrant; // Shield section of last hit.
fix last_hit_target_time; // Missiontime of last time this ship successfully hit target.
int hitter_objnum; // Object index of ship that hit this ship last time.
int hitter_signature; // Signature of hitter. Prevents stupidity if hitter gets killed.
@@ -487,7 +484,7 @@ typedef struct {
#define SUBSYS_PATH_DIST 500.0f
// Friendly damage defines
#define MAX_BURST_DAMAGE 20.0f // max damage that can be done in BURST_DURATION
#define MAX_BURST_DAMAGE 20 // max damage that can be done in BURST_DURATION
#define BURST_DURATION 500 // decay time over which Player->damage_this_burst falls from MAX_BURST_DAMAGE to 0
extern int Mission_all_attack; // !0 means all teams attack all teams.
@@ -495,8 +492,8 @@ extern int Mission_all_attack; // !0 means all teams attack all teams.
extern ai_info Ai_info[];
extern ai_info *Player_ai;
extern SCP_vector<ai_class> Ai_classes;
extern SCP_vector<const char*> Ai_class_names;
extern ai_class *Ai_classes;
extern char** Ai_class_names;
extern int Num_ai_classes;
extern int Ai_firing_enabled;
@@ -526,18 +523,18 @@ void ai_object_init(object * obj, int ai_index);
void ai_process( object * obj, int ai_index, float frametime );
const char *ai_get_goal_target_name(const char *name, int *index);
void ai_clear_goal_target_names();
extern void init_ai_system(void);
extern void ai_attack_object(object *attacker, object *attacked, int ship_info_index = -1, int class_type = -1);
extern void ai_attack_object(object *attacker, object *attacked, int ship_info_index = -1);
extern void ai_evade_object(object *evader, object *evaded);
extern void ai_ignore_object(object *ignorer, object *ignored, int ignore_new);
extern void ai_ignore_wing(object *ignorer, int wingnum);
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
extern void ai_do_default_behavior(object *obj);
extern void ai_reset_order_state(ai_info *aip);
extern void ai_start_waypoints(object *objp, int wl_index, int wp_flags, int start_index, bool force = false);
extern void ai_ship_hit(object *objp_ship, object *hit_objp, const vec3d *hit_normal);
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags, int start_index);
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hit_normal);
extern void ai_ship_destroy(int shipnum);
extern vec3d ai_get_acc_limit(vec3d* vel_limit, const object* objp);
extern void ai_turn_towards_vector(const vec3d *dest, object *objp, const vec3d *slide_vec, const vec3d *rel_pos, float bank_override, int flags, const vec3d *rvec = nullptr, const vec3d* turnrate_mod = nullptr);
@@ -561,7 +558,7 @@ extern void ai_set_guard_wing(object *objp, int wingnum);
extern void ai_warp_out(object *objp, vec3d *vp);
extern void ai_attack_wing(object *attacker, int wingnum);
extern void ai_deathroll_start(object *ship_obj);
extern int set_target_objnum(ai_info* aip, int objnum);
extern int set_target_objnum(ai_info *aip, int objnum);
extern void ai_form_on_wing(object *objp, object *goal_objp);
extern void ai_do_stay_near(object *objp, object *other_obj, float dist, int additional_data);
extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
@@ -598,16 +595,13 @@ extern int ai_maybe_fire_afterburner(object *objp, ai_info *aip);
extern void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip);
extern int is_instructor(object *objp);
extern int find_enemy(int objnum, float range, int max_attackers, bool for_pursuit, int ship_info_index = -1, int class_type = -1);
extern bool ai_targets_for_pursuit(const ai_info *aip);
extern bool ai_declines_pursuit(const object *attacker_objp, const object *target_objp);
extern int find_enemy(int objnum, float range, int max_attackers, int ship_info_index = -1);
float ai_get_weapon_speed(const ship_weapon *swp);
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, const vec3d *gun_pos, const object *pobjp, const vec3d *enemy_pos, const vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
float ai_get_weapon_speed(ship_weapon *swp);
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
// function to change rearm status for ai ships (called from sexpression code)
extern void ai_set_good_rearm_time( int team, int time );
extern void ai_set_bad_rearm_time(int team, int time);
extern void ai_set_rearm_status( int team, int new_status );
extern void ai_good_secondary_time( int team, int weapon_index, int num_weapons, const char *shipname );
extern void ai_do_objects_docked_stuff(object *docker, int docker_point, object *dockee, int dockee_point, bool update_clients = true);
@@ -621,7 +615,7 @@ extern float dock_orient_and_approach(object *docker_objp, int docker_index, obj
void ai_set_mode_warp_out(object *objp, ai_info *aip);
// prototyped by Goober5000
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, bool for_pursuit, int ship_info_index, int class_type = -1);
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index);
// moved to header file by Goober5000
void ai_announce_ship_dying(object *dying_objp);
@@ -640,6 +634,6 @@ void do_random_sidethrust(ai_info *aip, ship_info *sip);
void ai_formation_object_recalculate_slotnums(int form_objnum, int exiting_objnum = -1);
bool test_line_of_sight(const vec3d* from, const vec3d* to, SCP_unordered_set<int>&& excluded_object_ids = {}, float threshold = 10.0f, bool test_for_shields = false, bool test_for_hull = true, float* first_intersect_dist = nullptr, object** first_intersect_obj = nullptr);
bool test_line_of_sight(vec3d* from, vec3d* to, std::unordered_set<const object*>&& excluded_objects = {}, float threshold = 10.0f, bool test_for_shields = false, bool test_for_hull = true, float* first_intersect_dist = nullptr, object** first_intersect_obj = nullptr);
#endif
+4 -54
View File
@@ -32,8 +32,6 @@ namespace AI {
Unload_primaries, // Fire primaries as fast as possible!
Trying_unsuccessfully_to_warp, // Trying to warp, but can't warp at the moment
Free_afterburner_use, // Use afterburners while following waypoints or flying towards objects
Waypoints_no_formation, // wont get into formation when running waypoints as part of a wing
NUM_VALUES
};
@@ -43,16 +41,13 @@ namespace AI {
Dockee_index_valid, // when set, index field for dockee is valid
Goal_on_hold, // when set, this goal cannot currently be satisfied, although it could be in the future
Subsys_needs_fixup, // when set, the subsystem index (for a destroy subsystem goal) is invalid and must be gotten from the subsys name stored in docker.name field!!
Goal_override, // paired with ai_goal_type::DYNAMIC to mean this goal overrides any other goal
Want_override, // a goal should set this flag if Goal_override should be assigned when the goal is achievable
Goal_override, // paired with AIG_TYPE_DYNAMIC to mean this goal overrides any other goal
Purge, // purge this goal next time we process
Purge_when_new_goal_added, // this goal is perpetual until any other goal is added, at which time it sets its own Purge flag
Goals_purged, // this goal has already caused other goals to get purged (because it is something like ai-disarm that renders other goals invalid)
Goals_purged, // this goal has already caused other goals to get purged
Depart_sound_played,// Goober5000 - replacement for AL's hack ;)
Target_own_team, // this attack goal is allowed to target friendlies
Afterburn_hard, // afterburn as hard as possible to the goal
Waypoints_in_reverse, // decrement instead of increment
Clear_all_goals_first, // this goal wipes all goals (including itself) before it runs (handled separately, and in a different place, from purging invalid goals)
NUM_VALUES
};
@@ -104,10 +99,6 @@ namespace AI {
Fix_heat_seeker_stealth_bug,
Fix_linked_primary_bug,
Fix_ramming_stationary_targets_bug,
Fix_avoid_shockwave_bugs, // a) waiting until a homing weapon actually homes before evading;
// b) picking the correct expected impact position for capships;
// c) not clearing shockwave_object for ships;
// d) checking the explosion damage of the correct ship
Force_beam_turret_fov,
Free_afterburner_use,
Glide_decay_requires_thrust,
@@ -132,7 +123,6 @@ namespace AI {
Smart_shield_management,
Smart_subsystem_targeting_for_turrets,
Strict_turret_tagged_only_targeting,
Ships_intercept_mines, // all AI-controlled ships autonomously engage hostile mines within mine_targetable_range of themselves
Support_dont_add_primaries, //Prevents support ship from equipping new primary as requested in https://scp.indiegames.us/mantis/view.php?id=3198
Turrets_ignore_target_radius,
Use_actual_primary_range,
@@ -145,12 +135,10 @@ namespace AI {
All_nonshielded_ships_can_manage_ets,
Fightercraft_nonshielded_ships_can_manage_ets,
Ships_playing_dead_dont_manage_ets,
Better_combat_collision_avoidance,
Better_combat_collision_avoid_includes_target,
Better_guard_collision_avoidance,
Better_collision_avoidance,
Require_exact_los,
Improved_missile_avoidance,
Unify_usage_countermeasure_firechance,
Friendlies_use_countermeasure_firechance,
Improved_subsystem_attack_pathing,
Fixed_ship_weapon_collision,
No_shield_damage_from_ship_collisions,
@@ -169,45 +157,7 @@ namespace AI {
Whackable_debris,
Whackable_asteroids,
Dynamic_goals_afterburn_hard,
Player_orders_afterburn_hard,
Hudsquadmsg_tactical_disarm_disable,
Align_to_target_when_guarding_still,
Debris_respects_big_damage,
Dont_limit_change_in_speed_due_to_physics_whack,
Guards_ignore_protected_attackers,
Fix_standard_strafe,
Fix_ai_target_recovery, // a) strafing ships that lose their target re-process their orders, like chasing ships already do
// b) ships parked in AIM_NONE while holding a standing chase order (attack-any etc.) re-process their orders;
// c) target selection for pursuit (chasing, guard reactions, retaliation) skips ships outside the attacker's
// actively-pursues list; targets held while not chasing are unaffected, and explicitly ordered targets are
// still assigned but not chased or strafed;
// d) enemy_wing is reset when a new order takes over (shared with Fix_stale_ai_order_state)
Standard_strafe_used_more,
Unify_usage_ai_shield_manage_delay,
Fix_AI_shield_management_bug,
AI_balances_shields_when_attacked,
Disable_ai_transferring_energy,
Freespace_1_missile_behavior,
ETS_uses_power_output,
ETS_energy_same_regardless_of_system_presence,
Dont_form_on_wing_at_mission_start,
Do_not_clear_goals_when_running_form_on_wing,
Do_not_clear_goals_when_running_stay_still,
Do_not_set_override_when_assigning_form_on_wing,
Purge_player_issued_form_on_wing_after_subsequent_order,
Cancel_future_waves_of_any_wing_launched_from_an_exited_ship,
Fix_ignore_if_dead_flag,
Kamikaze_no_collision_avoidance,
Fix_big_ship_waypoint_completion, // a) big ships complete a waypoint within their radius rather than sqrt(radius);
// b) completion no longer requires moving 0.1m in a single frame (framerate-dependent)
Fix_shockwave_expire_before_do_damage, // shockwaves whose lifetime is shorter than one frame apply their area damage at least once before expiring
Fix_small_ai_recover_after_engines_repaired, // ensure small ship AI can switch back to useful AI modes if engines get repaired
Fix_model_path_refresh_randomization, // a subsystem path keeps its randomized point when the path is refreshed because the target moved
Fix_bay_speed_ramp, // the fighterbay speed ramp covers only the bay path itself, not points that route a departing ship around the carrier, and never exceeds max speed
Fix_stale_ai_order_state, // a) enemy_wing, guard_*, previous_mode, resume_goal_time, and the targeted subsystem (with its path) are reset when a new order takes over (enemy_wing is also reset under Fix_ai_target_recovery);
// b) a dynamic chase saves previous_mode/previous_submode; it and strafe entry leave them alone during an ongoing dynamic goal (evading a weapon still overwrites them, which is harmless since the evade resume re-processes orders);
// c) resuming guard duty discards any subsystem target and path left over from the interruption;
// d) a ship ordered to guard itself, or to guard a wing it leads (including one that becomes leader mid-mission), treats that goal as unachievable instead of holding it forever
NUM_VALUES
};
+14 -206
View File
@@ -42,7 +42,6 @@ void set_flag(ai_profile_t *profile, const char *name, AI::Profile_Flags flag)
const char *AI_path_types[] = {
"normal",
"alt1",
"alt2",
};
int Num_ai_path_types = sizeof(AI_path_types)/sizeof(char*);
@@ -140,7 +139,7 @@ void parse_ai_profiles_tbl(const char *filename)
// don't create multiple profiles with the same name
if (previous_profile != NULL)
{
Warning(LOCATION, "An AI profile named '%s' already exists! The new one will not be created.\n", profile_name);
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
}
else
{
@@ -185,14 +184,6 @@ void parse_ai_profiles_tbl(const char *filename)
if (optional_string("$Max Beam Friendly Fire Damage:"))
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
if (optional_string("$Max Weapon Friendly Fire Damage:")) {
parse_float_list(profile->weapon_friendly_damage_cap, NUM_SKILL_LEVELS);
}
if (optional_string("$Max Weapon Self Damage:")) {
parse_float_list(profile->weapon_self_damage_cap, NUM_SKILL_LEVELS);
}
if (optional_string("$Player Countermeasure Life Scale:"))
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
@@ -378,7 +369,7 @@ void parse_ai_profiles_tbl(const char *filename)
}
if (optional_string("$Detail Distance Multiplier:"))
parse_float_list(profile->detail_distance_mult, MAX_DETAIL_VALUE + 1);
parse_float_list(profile->detail_distance_mult, MAX_DETAIL_LEVEL + 1);
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AI::Profile_Flags::Big_ships_can_attack_beam_turrets_on_untargeted_ships);
@@ -412,7 +403,7 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$disable player secondary doublefire:", AI::Profile_Flags::Disable_player_secondary_doublefire);
set_flag(profile, "$disable AI secondary doublefire:", AI::Profile_Flags::Disable_ai_secondary_doublefire);
set_flag(profile, "$disable ai secondary doublefire:", AI::Profile_Flags::Disable_ai_secondary_doublefire);
set_flag(profile, "$disable weapon damage scaling:", AI::Profile_Flags::Disable_weapon_damage_scaling);
@@ -450,7 +441,7 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$force beam turrets to use normal fov:", AI::Profile_Flags::Force_beam_turret_fov);
set_flag(profile, "$fix AI class bug:", AI::Profile_Flags::Fix_ai_class_bug);
set_flag(profile, "$fix ai class bug:", AI::Profile_Flags::Fix_ai_class_bug);
set_flag(profile, "$turrets ignore targets radius in range checks:", AI::Profile_Flags::Turrets_ignore_target_radius);
@@ -478,25 +469,12 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$support don't add primaries:", AI::Profile_Flags::Support_dont_add_primaries);
if (optional_string("$max allies rearming threshold:"))
stuff_int(&profile->max_allies_rearming_threshold);
set_flag(profile, "$firing requires exact los:", AI::Profile_Flags::Require_exact_los);
if (optional_string("$exact los minimum detection radius:")) {
stuff_float(&profile->los_min_detection_radius);
}
set_flag(profile, "$fighterbay arrivals use carrier orientation:", AI::Profile_Flags::Fighterbay_arrivals_use_carrier_orient);
set_flag(profile, "$fighterbay departures use carrier orientation:", AI::Profile_Flags::Fighterbay_departures_use_carrier_orient);
set_flag(profile, "$debris damage respects 'big damage' flag:", AI::Profile_Flags::Debris_respects_big_damage);
set_flag(profile, "$don't limit change in speed due to physics whack:", AI::Profile_Flags::Dont_limit_change_in_speed_due_to_physics_whack);
set_flag(profile, "$guards ignore protected attackers:", AI::Profile_Flags::Guards_ignore_protected_attackers);
if (optional_string("$ai path mode:"))
{
stuff_string(buf, F_NAME, NAME_LENGTH);
@@ -505,13 +483,13 @@ void parse_ai_profiles_tbl(const char *filename)
profile->ai_path_mode = j;
}
else {
Warning(LOCATION, "Invalid AI path mode '%s' specified", buf);
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
}
}
set_flag(profile, "$no warp camera:", AI::Profile_Flags::No_warp_camera);
set_flag(profile, "$fix AI path order bug:", AI::Profile_Flags::Fix_ai_path_order_bug);
set_flag(profile, "$fix ai path order bug:", AI::Profile_Flags::Fix_ai_path_order_bug);
set_flag(profile, "$strict turret-tagged-only targeting:", AI::Profile_Flags::Strict_turret_tagged_only_targeting);
@@ -586,27 +564,11 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$ships playing dead don't manage ETS:", AI::Profile_Flags::Ships_playing_dead_dont_manage_ets);
set_flag(profile, "$better combat collision avoidance for fightercraft:", AI::Profile_Flags::Better_combat_collision_avoidance);
if (optional_string("+combat collision avoidance aggression for fightercraft:")) {
stuff_float(&profile->better_collision_avoid_aggression_combat);
}
set_flag(profile, "+combat collision avoidance for fightercraft includes target:", AI::Profile_Flags::Better_combat_collision_avoid_includes_target);
set_flag(profile, "$better guard collision avoidance for fightercraft:", AI::Profile_Flags::Better_guard_collision_avoidance);
if (optional_string("+guard collision avoidance aggression for fightercraft:")) {
stuff_float(&profile->better_collision_avoid_aggression_guard);
}
set_flag(profile, "$better combat collision avoidance for fightercraft:", AI::Profile_Flags::Better_collision_avoidance);
set_flag(profile, "$improved missile avoidance for fightercraft:", AI::Profile_Flags::Improved_missile_avoidance);
if (optional_string_either("$friendly ships use AI profile countermeasure chance:", "$unify usage of AI profile countermeasure chance:", true) >= 0) {
bool val;
stuff_boolean(&val);
profile->flags.set(AI::Profile_Flags::Unify_usage_countermeasure_firechance, val);
}
set_flag(profile, "$friendly ships use AI profile countermeasure chance:", AI::Profile_Flags::Friendlies_use_countermeasure_firechance);
set_flag(profile, "$improved subsystem attack pathing:", AI::Profile_Flags::Improved_subsystem_attack_pathing);
@@ -622,7 +584,7 @@ void parse_ai_profiles_tbl(const char *filename)
profile->ai_range_aware_secondary_select_mode = j;
}
else {
Warning(LOCATION, "Invalid AI secondary range awareness mode '%s' specified", buf);
Warning(LOCATION, "Invalid ai secondary range awareness mode '%s' specified", buf);
}
}
@@ -663,125 +625,15 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$dynamic goals afterburn hard:", AI::Profile_Flags::Dynamic_goals_afterburn_hard);
set_flag(profile, "$player orders afterburn hard:", AI::Profile_Flags::Player_orders_afterburn_hard);
set_flag(profile, "$hud squad messages use tactical disarm/disable:", AI::Profile_Flags::Hudsquadmsg_tactical_disarm_disable);
set_flag(profile, "$align to target when guarding stationary ship:", AI::Profile_Flags::Align_to_target_when_guarding_still);
if (optional_string("$rotation factor multiplier for player collisions:")) {
stuff_float(&profile->rot_fac_multiplier_ply_collisions);
}
set_flag(profile, "$fix avoid-shockwave bugs:", AI::Profile_Flags::Fix_avoid_shockwave_bugs);
set_flag(profile, "$fix standard strafe:", AI::Profile_Flags::Fix_standard_strafe);
set_flag(profile, "$fix AI target recovery:", AI::Profile_Flags::Fix_ai_target_recovery);
set_flag(profile, "$standard strafe used more:", AI::Profile_Flags::Standard_strafe_used_more);
if (optional_string("$standard strafe triggers under this speed:")) {
stuff_float(&profile->standard_strafe_when_below_speed);
}
if (optional_string("$strafe distance from target bounding box:")) {
stuff_float(&profile->strafe_retreat_box_dist);
}
if (optional_string("$strafe stops after time unhit:")) {
stuff_float(&profile->strafe_max_unhit_time);
}
if (optional_string("$strafe retreat collide time:")) {
stuff_float(&profile->strafe_retreat_collide_time);
}
if (optional_string("$strafe retreat collide distance:")) {
stuff_float(&profile->strafe_retreat_collide_distance);
}
if (optional_string("$guard uses big-orbit for target radius above:")) {
stuff_float(&profile->guard_big_orbit_above_target_radius);
}
if (optional_string("$guard with big-orbit uses max speed percent:")) {
float max_percent;
stuff_float(&max_percent);
if (max_percent > 0.0f && max_percent <= 1.0f) {
profile->guard_big_orbit_max_speed_percent = max_percent;
} else {
mprintf(("Warning: \"$guard with big-orbit uses max speed percent:\" should be > 0 and <= 1 (read %f). Value will not be used.\n", max_percent));
}
}
if (optional_string("$attack-any idle circle distance:")) {
stuff_float(&profile->attack_any_idle_circle_distance);
}
set_flag(profile, "$unify usage of AI Shield Manage Delay:", AI::Profile_Flags::Unify_usage_ai_shield_manage_delay);
set_flag(profile, "$fix AI shield management bug:", AI::Profile_Flags::Fix_AI_shield_management_bug);
set_flag(profile, "$AI balances shields instead of directs when attacked:", AI::Profile_Flags::AI_balances_shields_when_attacked);
set_flag(profile, "$disable AI transferring energy:", AI::Profile_Flags::Disable_ai_transferring_energy);
set_flag(profile, "$enable freespace 1 style missile behavior:", AI::Profile_Flags::Freespace_1_missile_behavior);
set_flag(profile, "$ETS uses ship class power output:", AI::Profile_Flags::ETS_uses_power_output);
set_flag(profile, "$ETS energy same regardless of system presence:", AI::Profile_Flags::ETS_energy_same_regardless_of_system_presence);
set_flag(profile, "$don't issue form-on-wing goals at mission start:", AI::Profile_Flags::Dont_form_on_wing_at_mission_start);
if (optional_string("$default form-on-wing priority:")) {
int priority;
stuff_int(&priority);
if (priority > 0) {
profile->default_form_on_wing_priority = priority;
} else {
mprintf(("Warning: $default form-on-wing priority: should be > 0 (read %d). Value will not be used.\n", priority));
}
}
set_flag(profile, "$do not clear goals when running form-on-wing:", AI::Profile_Flags::Do_not_clear_goals_when_running_form_on_wing);
set_flag(profile, "$do not clear goals when running stay-still:", AI::Profile_Flags::Do_not_clear_goals_when_running_stay_still);
set_flag(profile, "$do not set override when assigning form-on-wing:", AI::Profile_Flags::Do_not_set_override_when_assigning_form_on_wing);
set_flag(profile, "$purge player-issued form-on-wing after subsequent order:", AI::Profile_Flags::Purge_player_issued_form_on_wing_after_subsequent_order);
set_flag(profile, "$cancel future waves of any wing launched from an exited ship:", AI::Profile_Flags::Cancel_future_waves_of_any_wing_launched_from_an_exited_ship);
set_flag(profile, "$ships intercept mines:", AI::Profile_Flags::Ships_intercept_mines);
set_flag(profile, "$fix 'ignore if dead' flag:", AI::Profile_Flags::Fix_ignore_if_dead_flag);
set_flag(profile, "$no collision avoidance for kamikaze fighters:", AI::Profile_Flags::Kamikaze_no_collision_avoidance);
set_flag(profile, "$fix big ship waypoint completion:", AI::Profile_Flags::Fix_big_ship_waypoint_completion);
set_flag(profile, "$fix shockwave expiring before dealing damage:", AI::Profile_Flags::Fix_shockwave_expire_before_do_damage);
set_flag(profile, "$fix fighter/bomber AI recovers after engines repaired:", AI::Profile_Flags::Fix_small_ai_recover_after_engines_repaired);
set_flag(profile, "$fix subsystem path randomization on refresh:", AI::Profile_Flags::Fix_model_path_refresh_randomization);
set_flag(profile, "$fix fighterbay speed ramp:", AI::Profile_Flags::Fix_bay_speed_ramp);
set_flag(profile, "$fix stale AI order state:", AI::Profile_Flags::Fix_stale_ai_order_state);
// end of options ----------------------------------------
// if we've been through once already and are at the same place, force a move
if (saved_Mp && (saved_Mp == Mp))
{
char tmp[60];
memset(tmp, 0, 60);
strncpy(tmp, Mp, 59);
mprintf(("WARNING: Unrecognized parameter in %s: %s\n", filename, tmp));
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", tmp));
Mp++;
}
@@ -840,7 +692,7 @@ void ai_profiles_init()
Ai_profiles_initted = 1;
}
int ai_profile_lookup(const char *name)
int ai_profile_lookup(char *name)
{
for (int i = 0; i < Num_ai_profiles; i++)
if (!stricmp(name, Ai_profiles[i].profile_name))
@@ -855,7 +707,6 @@ void ai_profile_t::reset()
flags.reset();
los_min_detection_radius = 10.0f;
ai_path_mode = AI_PATH_MODE_NORMAL;
subsystem_path_radii = 0;
bay_arrive_speed_mult = 1.0f;
@@ -863,23 +714,6 @@ void ai_profile_t::reset()
second_order_lead_predict_factor = 0;
ai_range_aware_secondary_select_mode = AI_RANGE_AWARE_SEC_SEL_MODE_RETAIL;
turret_target_recheck_time = 2000.0f;
rot_fac_multiplier_ply_collisions = 0.0f;
max_allies_rearming_threshold = 2;
better_collision_avoid_aggression_combat = 3.5f;
better_collision_avoid_aggression_guard = 3.5f;
standard_strafe_when_below_speed = 3.0f;
strafe_retreat_box_dist = 300.0f;
strafe_max_unhit_time = 20.0f;
strafe_retreat_collide_time = 2.0f;
strafe_retreat_collide_distance = 100.0f;
guard_big_orbit_above_target_radius = 500.0f;
guard_big_orbit_max_speed_percent = 1.0f;
attack_any_idle_circle_distance = 100.0f;
default_form_on_wing_priority = 99; // as originally assigned in ai_add_goal_sub_sexp()
for (int i = 0; i < NUM_SKILL_LEVELS; ++i) {
max_incoming_asteroids[i] = 0;
@@ -902,12 +736,10 @@ void ai_profile_t::reset()
shield_energy_scale[i] = 0;
afterburner_recharge_scale[i] = 0;
player_damage_scale[i] = 0;
player_damage_inflicted_scale[i] = 0;
player_damage_inflicted_scale[i] = 0;
subsys_damage_scale[i] = 0;
beam_friendly_damage_cap[i] = -1.f;
weapon_friendly_damage_cap[i] = -1.f;
weapon_self_damage_cap[i] = -1.f;
beam_friendly_damage_cap[i] = 0;
turn_time_scale[i] = 0;
glide_attack_percent[i] = 0;
circle_strafe_percent[i] = 0;
@@ -938,7 +770,7 @@ void ai_profile_t::reset()
player_autoaim_fov[i] = 0;
}
for (int i = 0; i <= MAX_DETAIL_VALUE; ++i) {
for (int i = 0; i <= MAX_DETAIL_LEVEL; ++i) {
detail_distance_mult[i] = 0;
}
@@ -987,28 +819,4 @@ void ai_profile_t::reset()
if (mod_supports_version(23, 4, 0)) {
flags.set(AI::Profile_Flags::Hudsquadmsg_tactical_disarm_disable);
}
if (mod_supports_version(24, 2, 0)) {
flags.set(AI::Profile_Flags::Debris_respects_big_damage);
flags.set(AI::Profile_Flags::Force_beam_turret_fov);
flags.set(AI::Profile_Flags::Guards_ignore_protected_attackers);
}
if (mod_supports_version(25, 0, 0)) {
flags.set(AI::Profile_Flags::Fix_avoid_shockwave_bugs);
flags.set(AI::Profile_Flags::Purge_player_issued_form_on_wing_after_subsequent_order);
flags.set(AI::Profile_Flags::Cancel_future_waves_of_any_wing_launched_from_an_exited_ship);
}
if (mod_supports_version(26, 0, 0)) {
flags.set(AI::Profile_Flags::Fix_ignore_if_dead_flag);
}
if (mod_supports_version(26, 2, 0)) {
flags.set(AI::Profile_Flags::Kamikaze_no_collision_avoidance);
flags.set(AI::Profile_Flags::Fix_big_ship_waypoint_completion);
flags.set(AI::Profile_Flags::Fix_shockwave_expire_before_do_damage);
flags.set(AI::Profile_Flags::Fix_small_ai_recover_after_engines_repaired);
flags.set(AI::Profile_Flags::Fix_standard_strafe);
flags.set(AI::Profile_Flags::Fix_ai_target_recovery);
flags.set(AI::Profile_Flags::Fix_model_path_refresh_randomization);
flags.set(AI::Profile_Flags::Fix_bay_speed_ramp);
flags.set(AI::Profile_Flags::Fix_stale_ai_order_state);
}
}
+3 -40
View File
@@ -17,7 +17,6 @@
// AI Path types
#define AI_PATH_MODE_NORMAL 0
#define AI_PATH_MODE_ALT1 1
#define AI_PATH_MODE_ALT2 2
#define AI_RANGE_AWARE_SEC_SEL_MODE_RETAIL 0
#define AI_RANGE_AWARE_SEC_SEL_MODE_AWARE 1
@@ -58,8 +57,6 @@ public:
float subsys_damage_scale[NUM_SKILL_LEVELS]; // damage applied to a player subsystem
float beam_friendly_damage_cap[NUM_SKILL_LEVELS]; // damage cap values for friendly beam fire
float weapon_friendly_damage_cap[NUM_SKILL_LEVELS];
float weapon_self_damage_cap[NUM_SKILL_LEVELS];
float turn_time_scale[NUM_SKILL_LEVELS]; // speed at which enemy ships turn
float glide_attack_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "glide attack" move
float circle_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "circle strafe" move
@@ -100,13 +97,7 @@ public:
// Player-specific autoaim FOV override
float player_autoaim_fov[NUM_SKILL_LEVELS];
float detail_distance_mult[MAX_DETAIL_VALUE + 1]; //MAX_DETAIL_VALUE really needs to be 4
// max number of allies allowed to be rearming at the same time
int max_allies_rearming_threshold;
// minimum radius for the line-of-sight (los) detection --wookieejedi
float los_min_detection_radius;
float detail_distance_mult[MAX_DETAIL_LEVEL + 1]; //MAX_DETAIL_LEVEL really needs to be 4
int ai_path_mode;
@@ -127,34 +118,6 @@ public:
// how often turrets shoulds check for new targets, milliseconds
float turret_target_recheck_time;
// Multiplier value so the player can also experience rotational effects from collisions --wookieejedi
float rot_fac_multiplier_ply_collisions;
// Collision avoidance options --developed by asteroth, exposed by wookieejedi
// Velocity / turn rate gives us a vector which represents the minimum 'bug out' distance.
// However this will be a significant underestimate, it doesn't take into account acceleration
// with regards to its turn speed, nor already existing rotvel, nor the angular distance
// to the particular avoidance vector it comes up with.
// These would significantly complicate the calculation, so for now, it is all bundled into these magic numbers.
float better_collision_avoid_aggression_combat;
float better_collision_avoid_aggression_guard;
// AI strafing options --wookieejedi
float standard_strafe_when_below_speed; // Speed at which standard strafing large ships is possibly triggered
float strafe_retreat_box_dist; // Distance beyond the bounding box to retreat to strafing point
float strafe_max_unhit_time; // Maximum amount of time to stay in strafe mode if not hit
float strafe_retreat_collide_time; // When anticipated collision time is less than this, begin retreat from strafe
float strafe_retreat_collide_distance; // When perpendicular distance to *surface* is less than this, begin retreat from strafe
// AI guard options --wookieejedi
float guard_big_orbit_above_target_radius; // Radius of guardee that triggers ai_big_guard()
float guard_big_orbit_max_speed_percent; // Max percent of forward speed that is used in ai_big_guard()
// AI attack any option --wookieejedi
float attack_any_idle_circle_distance; // Radius that AI circles around a point while waiting for new enemies in attack-any mode
int default_form_on_wing_priority; // the priority used if not specified in the sexp
void reset();
};
@@ -163,10 +126,10 @@ extern int Num_ai_profiles;
extern int Default_ai_profile;
extern ai_profile_t Ai_profiles[MAX_AI_PROFILES];
#define AI_PROFILES_INDEX(ai_p) (static_cast<int>((ai_p)-Ai_profiles))
#define AI_PROFILES_INDEX(ai_p) ((int)((ai_p) - Ai_profiles))
void ai_profiles_init();
int ai_profile_lookup(const char *name);
int ai_profile_lookup(char *name);
#endif
+131 -170
View File
@@ -39,7 +39,11 @@
#define MIN_DOT_TO_ATTACK_MOVING_SUBSYS 0.97f
// AI BIG MAGIC NUMBERS
// Select strafing options are now exposed to modders --wookieejedi
#define STRAFE_RETREAT_COLLIDE_TIME 2.0 // when anticipated collision time is less than this, begin retreat
#define STRAFE_RETREAT_COLLIDE_DIST 100 // when perpendicular distance to *surface* is less than this, begin retreat
#define STRAFE_RETREAT_BOX_DIST 300 // distance beyond the bounding box to retreat
#define STRAFE_MAX_UNHIT_TIME 20 // Maximum amount of time to stay in strafe mode if not hit
#define EVADE_BOX_BASE_DISTANCE 300 // standard distance to end evade submode
#define EVADE_BOX_MIN_DISTANCE 200 // minimun distance to end evade submode, after long time
@@ -59,22 +63,12 @@
void ai_big_evade_ship();
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum);
void ai_big_avoid_ship();
bool ai_big_maybe_follow_subsys_path(bool do_dot_check=true);
int ai_big_maybe_follow_subsys_path(int do_dot_check=1);
void ai_big_strafe_position();
static bool ai_big_strafe_maybe_retreat(const vec3d *target_pos);
static int ai_big_strafe_maybe_retreat(const vec3d *target_pos);
extern void compute_desired_rvec(vec3d *rvec, const vec3d *goal_pos, const vec3d *cur_pos);
extern void big_ship_collide_recover_start(const object *objp, const object *big_objp, const vec3d *collision_normal);
// Record the mode being left as the one to return to, unless a dynamic goal is already in progress
// (in which case previous_mode still refers to the mode that goal interrupted).
static void ai_big_save_previous_mode(ai_info *aip)
{
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state] && aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC)
return;
aip->previous_mode = aip->mode;
}
extern void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos);
extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collision_normal);
// Called by ai_big_pick_attack_point.
@@ -82,7 +76,7 @@ static void ai_big_save_previous_mode(ai_info *aip)
// If truly_random flag set (haha), then generate a pretty random number. Otherwise, generate a static rand which
// tends to not change from frame to frame.
// Try four times and choose nearest point to increase chance of getting a good point.
void ai_bpap(const object *objp, const vec3d *attacker_objp_pos, const vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal, const ship_subsys *ss)
void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal, ship_subsys *ss)
{
float nearest_dist;
vec3d result_point, best_point;
@@ -153,10 +147,6 @@ done_1:
*attack_point = best_point;
//The following raycast tends to make up 10%(!) of total AI-frametime for basically no benefit, especially in the common case for turrets where the normal isn't even queried.
if (surface_normal == nullptr && Disable_expensive_turret_target_check)
return;
// Cast from attack_objp_pos to local_attack_pos and check for nearest collision.
// If no collision, cast to (0,0,0) [center of big ship]** [best_point initialized to 000]
@@ -203,7 +193,7 @@ done_1:
//
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
void ai_big_pick_attack_point_turret(const object *objp, ship_subsys *ssp, const vec3d *gpos, const vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
{
if (!timestamp_elapsed(ssp->turret_pick_big_attack_point_timestamp)) {
vec3d result_point;
@@ -223,7 +213,7 @@ void ai_big_pick_attack_point_turret(const object *objp, ship_subsys *ssp, const
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
// Note, attacker_objp can be a ship or a weapon.
void ai_big_pick_attack_point(const object *objp, const object *attacker_objp, vec3d *attack_point, float fov)
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
{
Assert(objp->instance > -1);
Assert(objp->type == OBJ_SHIP);
@@ -358,10 +348,10 @@ void ai_big_subsys_path_cleanup(ai_info *aip)
}
// Maybe Pl_objp needs to follow a path to get in line-of-sight to a subsystem
// input: do_dot_check => default value true, flag to indicate whether check should be done to ensure
// input: do_dot_check => default value 0, flag to indicate whether check should be done to ensure
// subsystem is within certain field of view. We don't want to check fov when
// strafing, since ship is weaving to avoid turret fire
bool ai_big_maybe_follow_subsys_path(bool do_dot_check)
int ai_big_maybe_follow_subsys_path(int do_dot_check)
{
ai_info *aip;
float dot = 1.0f, min_dot;
@@ -421,7 +411,7 @@ bool ai_big_maybe_follow_subsys_path(bool do_dot_check)
}
}
if ( ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, true) ) {
if ( ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, 1) ) {
subsys_in_sight = 1;
}
}
@@ -509,7 +499,7 @@ bool ai_big_maybe_follow_subsys_path(bool do_dot_check)
// for now, only follow the path to the first point
if ( aip->path_cur < (aip->path_start+aip->path_length-1) ) {
if ( aip->goal_objnum != aip->target_objnum ) {
ai_big_save_previous_mode(aip);
aip->previous_mode = aip->mode;
aip->mode = AIM_NONE;
aip->submode = -1;
aip->submode_start_time = Missiontime;
@@ -551,7 +541,7 @@ bool ai_new_maybe_reposition_attack_subsys() {
get_subsystem_pos(&gsubpos, target_objp, aip->targeted_subsys);
// you're in sight! shoot it!
if (ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, false))
if (ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, 0))
return false;
// not in sight, gotta get there
@@ -716,8 +706,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
if (vm_vec_dot(&in_vec, &objp->orient.vec.fvec) > 0.0f) {
dist = vm_vec_normalize(&in_vec);
if ((dist < 200.0f) && (vm_vec_dot(&in_vec, &objp->orient.vec.fvec) > 0.95f)) {
if ((Objects[objp->parent].signature == objp->parent_sig) && (vm_vec_dist_quick(&objp->pos, &Objects[objp->parent].pos) < 300.0f)
&& !ai_declines_pursuit(Pl_objp, &Objects[objp->parent])) {
if ((Objects[objp->parent].signature == objp->parent_sig) && (vm_vec_dist_quick(&objp->pos, &Objects[objp->parent].pos) < 300.0f)) {
set_target_objnum(aip, objp->parent);
aip->submode = SM_ATTACK;
aip->submode_start_time = Missiontime;
@@ -730,24 +719,22 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
}
}
}
// Since ship is moving slowly and attacking a large ship, scan if enemy fighters are near, if so
// then enter strafe mode
if ( ai_big_maybe_start_strafe(aip, sip) ) {
aip->previous_mode = aip->mode;
aip->mode = AIM_STRAFE;
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
ai_big_strafe_position();
return;
}
} // end if ( Pl_objp->phys_info.speed < 3.0f )
// if moving slowly and attacking a large ship,
// check if need to enter standard strafe mode
// including ai_profile flag and if enemy fighters are near
if (Pl_objp->phys_info.speed < The_mission.ai_profile->standard_strafe_when_below_speed &&
(The_mission.ai_profile->flags[AI::Profile_Flags::Standard_strafe_used_more] || ai_big_maybe_start_strafe(aip, sip))) {
ai_big_save_previous_mode(aip);
aip->mode = AIM_STRAFE;
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
ai_big_strafe_position();
return;
}
//Maybe enter glide strafe (check every 8 seconds, on a different schedule for each ship)
if ((sip->can_glide == true) && !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_glide_strafe_percent) {
ai_big_save_previous_mode(aip);
aip->previous_mode = aip->mode;
aip->mode = AIM_STRAFE;
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
aip->submode = AIS_STRAFE_GLIDE_ATTACK;
@@ -876,7 +863,7 @@ void ai_big_chase_ct()
extern bool ai_select_secondary_weapon(object *objp, ship_weapon *swp, int priority1 = -1, int priority2 = -1);
extern float set_secondary_fire_delay(ai_info *aip, ship *shipp, weapon_info *swip, bool burst);
extern bool ai_choose_secondary_weapon(object *objp, ai_info *aip, object *en_objp);
extern bool maybe_avoid_big_ship(object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time, float time_scale = 1.f);
extern int maybe_avoid_big_ship(object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time, float time_scale = 1.f);
extern void maybe_cheat_fire_synaptic(object *objp);
@@ -926,13 +913,13 @@ static void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy)
}
if (tswp->num_secondary_banks > 0) {
if ( !(En_objp->flags[Object::Object_Flags::Protected]) || ai_goal_is_disable_or_disarm(aip->goals[0].ai_mode) ) {
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISABLE_SHIP_TACTICAL | AI_GOAL_DISARM_SHIP | AI_GOAL_DISARM_SHIP_TACTICAL))) {
bool valid_secondary = ai_choose_secondary_weapon(Pl_objp, aip, En_objp);
int current_bank = tswp->current_secondary_bank;
if (current_bank > -1 && valid_secondary) {
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
if ( !(En_objp->flags[Object::Object_Flags::Protected]) || (ai_goal_is_disable_or_disarm(aip->goals[0].ai_mode) && swip->wi_flags[Weapon::Info_Flags::Puncture]) ) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
if(!(En_objp->flags[Object::Object_Flags::Protected]) || ((aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISABLE_SHIP_TACTICAL | AI_GOAL_DISARM_SHIP | AI_GOAL_DISARM_SHIP_TACTICAL)) && swip->wi_flags[Weapon::Info_Flags::Puncture] )) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
// If ship is protected and very low on hits, don't fire missiles.
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (En_objp->hull_strength > 10*swip->damage)) {
if (aip->ai_flags[AI::AI_Flags::Unload_secondaries]) {
@@ -1019,7 +1006,7 @@ static void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy)
// switch ai ship into chase mode
void ai_big_switch_to_chase_mode(ai_info *aip)
{
ai_big_save_previous_mode(aip);
aip->previous_mode = aip->mode;
aip->mode = AIM_CHASE;
aip->submode = SM_ATTACK;
aip->submode_start_time = Missiontime;
@@ -1047,7 +1034,7 @@ void ai_big_chase()
ai_big_pick_attack_point(En_objp, Pl_objp, &enemy_pos, 0.8f);
weapon_info* wip = ai_get_weapon(&shipp->weapons);
bool ballistic_aiming = !IS_VEC_NULL(&The_mission.gravity) && wip && wip->gravity_const != 0.0f;
bool ballistic_aiming = !IS_VEC_NULL(&The_mission.gravity) && wip->gravity_const != 0.0f;
bool valid_ballistic_trajectory = true;
if (!ballistic_aiming) {
@@ -1119,7 +1106,7 @@ void ai_big_chase()
} else if (En_objp->flags[Object::Object_Flags::Protected]) { // If protected and we're not attacking a subsystem, stop attacking!
update_aspect_lock_information(aip, &vec_to_enemy, dist_to_enemy - En_objp->radius, En_objp->radius);
aip->target_objnum = -1;
if (find_enemy(OBJ_INDEX(Pl_objp), MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level], ai_targets_for_pursuit(aip)) == -1) {
if (find_enemy(OBJ_INDEX(Pl_objp), MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]) == -1) {
ai_do_default_behavior(Pl_objp);
return;
}
@@ -1206,78 +1193,70 @@ void ai_big_chase()
}
// If a collision is expected, pull out!
if (!(The_mission.ai_profile->flags[AI::Profile_Flags::Kamikaze_no_collision_avoidance] && aip->ai_flags[AI::AI_Flags::Kamikaze])) {
float dist_normal_to_enemy;
float dist_normal_to_enemy;
if (vm_vec_mag_squared(&aip->big_attack_surface_normal) > 0.9) {
if (aip->ai_profile_flags[AI::Profile_Flags::Improved_subsystem_attack_pathing])
dist_normal_to_enemy = fl_abs((dist_to_enemy / vm_vec_dot(&vec_to_enemy, &aip->big_attack_surface_normal)));
else // I'm fairly sure this retail code VVV meant to use / instead of *
dist_normal_to_enemy = fl_abs((dist_to_enemy * vm_vec_dot(&vec_to_enemy, &aip->big_attack_surface_normal)));
}
else {
// don;t have normal so use a conservative value here
dist_normal_to_enemy = 0.3f * dist_to_enemy;
}
// float time_to_enemy = dist_normal_to_enemy / Pl_objp->phys_info.speed * fl_abs(vm_vec_dot(&Pl_objp->phys_info.vel, &aip->big_attack_surface_normal));
// if (Framecount % 30 == 1) {
// mprintf(("normal dist; %.1f, time: %.1f\n", dist_normal_to_enemy, time_to_enemy));
// }
// since we're not in strafe and we may get a bad normal, cap dist_normal_to_enemy as MIN(0.3*dist_to_enemy, self)
// this will allow us to get closer on a bad normal
dist_normal_to_enemy = MAX(0.3f * dist_to_enemy, dist_normal_to_enemy);
if (dist_to_enemy < ATTACK_COLLIDE_BASE_DIST) {
// within 50m or 1sec
float time_to_enemy;
if (vm_vec_mag_squared(&aip->big_attack_surface_normal) > 0.9) {
if (Pl_objp->phys_info.speed > 0.1) {
time_to_enemy = dist_normal_to_enemy / fl_abs(vm_vec_dot(&Pl_objp->phys_info.vel, &aip->big_attack_surface_normal));
}
else {
// a big time
time_to_enemy = 100.0f;
}
}
else {
if (Pl_objp->phys_info.speed > 0.1) {
time_to_enemy = dist_normal_to_enemy / Pl_objp->phys_info.speed;
}
else {
// a big time
time_to_enemy = 100.0f;
}
}
float speed_dist = MAX(0.0f, (Pl_objp->phys_info.speed - 50) * 2);
if ((dist_normal_to_enemy < ATTACK_COLLIDE_AVOID_DIST + speed_dist) || (time_to_enemy < ATTACK_COLLIDE_AVOID_TIME)) {
// get away, simulate crsh recovery (don't use avoid)
// accelerate_ship(aip, -1.0f);
big_ship_collide_recover_start(Pl_objp, En_objp, nullptr);
// aip->submode = SM_AVOID;
// aip->submode_start_time = Missiontime;
}
else if ((dist_normal_to_enemy < ATTACK_COLLIDE_SLOW_DIST) || (time_to_enemy < ATTACK_COLLIDE_SLOW_TIME)) {
// slow down
accelerate_ship(aip, -1.0f);
}
}
/*
if ((dot_to_enemy > 1.0f - 0.1f * En_objp->radius/(dist_to_enemy + 1.0f)) && (Pl_objp->phys_info.speed > dist_to_enemy/5.0f)) {
if (might_collide_with_ship(Pl_objp, En_objp, dot_to_enemy, dist_to_enemy, (aip->targeted_subsys == NULL)*2.0f + 1.5f)) {
if ((Missiontime - aip->last_hit_time > F1_0*4) && (dist_to_enemy < Pl_objp->radius*2 + En_objp->radius*2)) {
accelerate_ship(aip, -1.0f);
} else {
aip->submode = SM_AVOID;
aip->submode_start_time = Missiontime;
}
}
} */
if (vm_vec_mag_squared(&aip->big_attack_surface_normal) > 0.9) {
if (aip->ai_profile_flags[AI::Profile_Flags::Improved_subsystem_attack_pathing])
dist_normal_to_enemy = fl_abs((dist_to_enemy / vm_vec_dot(&vec_to_enemy, &aip->big_attack_surface_normal)));
else // I'm fairly sure this retail code VVV meant to use / instead of *
dist_normal_to_enemy = fl_abs((dist_to_enemy * vm_vec_dot(&vec_to_enemy, &aip->big_attack_surface_normal)));
} else {
// don;t have normal so use a conservative value here
dist_normal_to_enemy = 0.3f * dist_to_enemy;
}
// float time_to_enemy = dist_normal_to_enemy / Pl_objp->phys_info.speed * fl_abs(vm_vec_dot(&Pl_objp->phys_info.vel, &aip->big_attack_surface_normal));
// if (Framecount % 30 == 1) {
// mprintf(("normal dist; %.1f, time: %.1f\n", dist_normal_to_enemy, time_to_enemy));
// }
// since we're not in strafe and we may get a bad normal, cap dist_normal_to_enemy as MIN(0.3*dist_to_enemy, self)
// this will allow us to get closer on a bad normal
dist_normal_to_enemy = MAX(0.3f*dist_to_enemy, dist_normal_to_enemy);
if (dist_to_enemy < ATTACK_COLLIDE_BASE_DIST) {
// within 50m or 1sec
float time_to_enemy;
if (vm_vec_mag_squared(&aip->big_attack_surface_normal) > 0.9) {
if (Pl_objp->phys_info.speed > 0.1) {
time_to_enemy = dist_normal_to_enemy / fl_abs(vm_vec_dot(&Pl_objp->phys_info.vel, &aip->big_attack_surface_normal));
} else {
// a big time
time_to_enemy = 100.0f;
}
} else {
if (Pl_objp->phys_info.speed > 0.1) {
time_to_enemy = dist_normal_to_enemy / Pl_objp->phys_info.speed;
} else {
// a big time
time_to_enemy = 100.0f;
}
}
float speed_dist = MAX(0.0f, (Pl_objp->phys_info.speed-50) * 2);
if ((dist_normal_to_enemy < ATTACK_COLLIDE_AVOID_DIST + speed_dist) || (time_to_enemy < ATTACK_COLLIDE_AVOID_TIME) ) {
// get away, simulate crsh recovery (don't use avoid)
// accelerate_ship(aip, -1.0f);
big_ship_collide_recover_start(Pl_objp, En_objp, nullptr);
// aip->submode = SM_AVOID;
// aip->submode_start_time = Missiontime;
} else if ((dist_normal_to_enemy < ATTACK_COLLIDE_SLOW_DIST) || (time_to_enemy < ATTACK_COLLIDE_SLOW_TIME) ) {
// slow down
accelerate_ship(aip, -1.0f);
}
}
/*
if ((dot_to_enemy > 1.0f - 0.1f * En_objp->radius/(dist_to_enemy + 1.0f)) && (Pl_objp->phys_info.speed > dist_to_enemy/5.0f)) {
if (might_collide_with_ship(Pl_objp, En_objp, dot_to_enemy, dist_to_enemy, (aip->targeted_subsys == NULL)*2.0f + 1.5f)) {
if ((Missiontime - aip->last_hit_time > F1_0*4) && (dist_to_enemy < Pl_objp->radius*2 + En_objp->radius*2)) {
accelerate_ship(aip, -1.0f);
} else {
aip->submode = SM_AVOID;
aip->submode_start_time = Missiontime;
}
}
} */
}
switch (aip->submode) {
@@ -1436,7 +1415,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
// check to see if Pl_objp has gotten too close to attacking point.. if so, break off by entering
// AIS_STRAFE_RETREAT
static bool ai_big_strafe_maybe_retreat(const vec3d *target_pos)
static int ai_big_strafe_maybe_retreat(const vec3d *target_pos)
{
ai_info *aip;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -1444,54 +1423,37 @@ static bool ai_big_strafe_maybe_retreat(const vec3d *target_pos)
vec3d vec_to_target;
vm_vec_sub(&vec_to_target, target_pos, &Pl_objp->pos);
float dist_to_target = vm_vec_mag(&vec_to_target);
float dist_to_target, dist_normal_to_target, time_to_target;
dist_to_target = vm_vec_mag_quick(&vec_to_target);
if (vm_vec_mag_quick(&aip->big_attack_surface_normal) > 0.9) {
dist_normal_to_target = -vm_vec_dot(&vec_to_target, &aip->big_attack_surface_normal);
} else {
dist_normal_to_target = 0.2f * vm_vec_mag_quick(&vec_to_target);
}
dist_normal_to_target = MAX(0.2f*dist_to_target, dist_normal_to_target);
time_to_target = dist_normal_to_target / Pl_objp->phys_info.speed;
// add distance penalty for going too fast
float speed_to_dist_penalty = MAX(0.0f, (Pl_objp->phys_info.speed-50));
bool collide_time;
bool collide_distance;
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_standard_strafe]) {
// check if ship facing target, as likely will only collide if facing
vec3d vec_to_tpos;
vm_vec_normalized_dir(&vec_to_tpos, target_pos, &Pl_objp->pos);
float dot = vm_vec_dot(&vec_to_tpos, &Pl_objp->orient.vec.fvec);
if (dot <= 0.0f) {
collide_time = false;
collide_distance = false;
} else {
collide_time = (Pl_objp->phys_info.speed > 0.0f) && (dist_to_target / Pl_objp->phys_info.speed) < (The_mission.ai_profile->strafe_retreat_collide_time);
collide_distance = dist_to_target < ((The_mission.ai_profile->strafe_retreat_collide_distance) + speed_to_dist_penalty);
}
} else {
float dist_normal_to_target;
if (vm_vec_mag(&aip->big_attack_surface_normal) > 0.9) {
dist_normal_to_target =
MAX(0.2f * dist_to_target, -vm_vec_dot(&vec_to_target, &aip->big_attack_surface_normal));
} else {
dist_normal_to_target = 0.2f * dist_to_target;
}
collide_time = (Pl_objp->phys_info.speed > 0.0f) && (dist_normal_to_target / Pl_objp->phys_info.speed) < (The_mission.ai_profile->strafe_retreat_collide_time);
collide_distance = dist_normal_to_target < ((The_mission.ai_profile->strafe_retreat_collide_distance) + speed_to_dist_penalty);
}
//if ((dot_to_enemy > 1.0f - 0.1f * En_objp->radius/(dist_to_enemy + 1.0f)) && (Pl_objp->phys_info.speed > dist_to_enemy/5.0f))
// Inside 2 sec retreat, setting goal point to box point + strafe_retreat_box_dist
// Inside 2 sec retreat, setting goal point to box point + 300m
// If collision, use std collision resolution.
if ( !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && ((aip->ai_flags[AI::AI_Flags::Target_collision]) || (collide_time) || (collide_distance)) ) {
if ( !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && ((aip->ai_flags[AI::AI_Flags::Target_collision]) || (time_to_target < STRAFE_RETREAT_COLLIDE_TIME) || (dist_normal_to_target < STRAFE_RETREAT_COLLIDE_DIST + speed_to_dist_penalty)) ) {
if (aip->ai_flags[AI::AI_Flags::Target_collision]) {
// use standard collision resolution
aip->ai_flags.remove(AI::AI_Flags::Target_collision);
big_ship_collide_recover_start(Pl_objp, En_objp, nullptr);
} else {
// too close for comfort so fly to box point + strafe_retreat_box_dist
// too close for comfort so fly to box point + 300
aip->submode = AIS_STRAFE_RETREAT1;
aip->submode_start_time = Missiontime;
int is_inside;
vec3d goal_point;
get_world_closest_box_point_with_delta(&goal_point, En_objp, &Pl_objp->pos, &is_inside, The_mission.ai_profile->strafe_retreat_box_dist);
get_world_closest_box_point_with_delta(&goal_point, En_objp, &Pl_objp->pos, &is_inside, STRAFE_RETREAT_BOX_DIST);
// set goal point
aip->goal_point = goal_point;
@@ -1523,7 +1485,7 @@ void ai_big_strafe_attack()
if (aip->ai_profile_flags[AI::Profile_Flags::Improved_subsystem_attack_pathing]) {
if (ai_new_maybe_reposition_attack_subsys())
return;
} else if (ai_big_maybe_follow_subsys_path(false))
} else if (ai_big_maybe_follow_subsys_path(0))
return;
ai_big_attack_get_data(&target_pos, &target_dist, &target_dot);
@@ -1606,7 +1568,8 @@ void ai_big_strafe_attack()
accelerate_ship(aip, accel);
// if haven't been hit in quite a while, leave strafe mode
fix long_enough = fl2f(The_mission.ai_profile->strafe_max_unhit_time);
fix long_enough;
long_enough = F1_0 * STRAFE_MAX_UNHIT_TIME;
if ( (last_hit > long_enough) && ( (Missiontime - aip->submode_parm0) > long_enough) ) {
ai_big_switch_to_chase_mode(aip);
}
@@ -1643,7 +1606,7 @@ void ai_big_strafe_glide_attack()
if (aip->ai_profile_flags[AI::Profile_Flags::Improved_subsystem_attack_pathing]) {
if (ai_new_maybe_reposition_attack_subsys())
return;
} else if (ai_big_maybe_follow_subsys_path(false))
} else if (ai_big_maybe_follow_subsys_path(0))
return;
//Gets a point on the target ship to attack, as well as distance and the angle between the nose of the attacker and that point.
@@ -1653,11 +1616,11 @@ void ai_big_strafe_glide_attack()
//If we haven't chosen the goal point yet, do so now
if (aip->submode_parm1 == 0) {
//Pick goal point. This should be a random point that passes through the circle whose normal is the vector between attacker and target
vec3d targetToAttackerDir;
vm_vec_normalized_dir(&targetToAttackerDir, &Pl_objp->pos, &target_objp->pos);
matrix orient;
vm_vector_2_matrix_norm(&orient, &targetToAttackerDir, nullptr, nullptr);
vec3d targetToAttacker;
vec3d tangentPoint;
vm_vec_sub(&targetToAttacker, &Pl_objp->pos, &target_objp->pos);
matrix orient;
vm_vector_2_matrix(&orient, &targetToAttacker, NULL, NULL);
vm_vec_random_in_circle(&tangentPoint, &target_objp->pos, &orient, target_objp->radius + GLIDE_STRAFE_DISTANCE, true);
//Get tangent point in coords relative to ship, scale it up so the actual goal point is far away, then put back in world coords
vm_vec_sub2(&tangentPoint, &Pl_objp->pos);
@@ -1678,7 +1641,7 @@ void ai_big_strafe_glide_attack()
//Keep going until we are too far away.
//If we are still on approach but too far away, this will still trigger. This will allow us to reposition the target
//point and allow for a "jinking" effect.
if (target_ship_dist > (The_mission.ai_profile->strafe_retreat_box_dist + target_objp->radius) &&
if (target_ship_dist > (STRAFE_RETREAT_BOX_DIST + target_objp->radius) &&
Missiontime - aip->submode_start_time > i2f(GLIDE_STRAFE_MIN_TIME)) {
//This checks whether we are moving toward the target or away from it. If moving towards, we reset the stage so that we
//pick a new attack vector (jinking). If moving away, we're at the end of a run so do a full reset (possibly allowing a
@@ -1728,7 +1691,7 @@ void ai_big_strafe_glide_attack()
// if haven't been hit in quite a while, leave strafe mode
// (same as ai_big_strafe_attack)
fix long_enough = fl2f(The_mission.ai_profile->strafe_max_unhit_time);
fix long_enough = F1_0 * STRAFE_MAX_UNHIT_TIME;
if ( (Missiontime - aip->last_hit_time > long_enough) && ( (Missiontime - aip->submode_parm0) > long_enough) ) {
ai_big_switch_to_chase_mode(aip);
}
@@ -1878,7 +1841,7 @@ void ai_big_strafe()
/*
if ( aip->goal_objnum != aip->target_objnum ) {
Assertion(false, "The goal objnum does not match the target objnum in ai_big_strafe(), please report to the SCP!"); // what is going on here? - Get Alan
UNREACHABLE("The goal objnum does not match the target objnum in ai_big_strafe(), please report to the SCP!"); // what is going on here? - Get Alan
aip->mode = AIM_NONE;
return;
}
@@ -1924,7 +1887,7 @@ void ai_big_strafe()
{
//Re-roll for random sidethrust every 2 seconds
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent) {
do_random_sidethrust(aip, &Ship_info[Ships[aip->shipnum].ship_info_index]);
do_random_sidethrust(aip, &Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index]);
}
}
}
@@ -1970,34 +1933,32 @@ int ai_big_maybe_enter_strafe_mode(const object *pl_objp, int weapon_objnum)
weapon_objp = &Objects[weapon_objnum];
Assert(weapon_objp->type == OBJ_WEAPON);
if (weapon_objp->parent < 0) {
return 0;
}
Assert(weapon_objp->parent < MAX_OBJECTS);
Assert(weapon_objp->parent >= 0 && weapon_objp->parent < MAX_OBJECTS);
parent_objp = &Objects[weapon_objp->parent];
if ( (parent_objp->signature != weapon_objp->parent_sig) || (parent_objp->type != OBJ_SHIP) ) {
return 0;
}
if (ai_declines_pursuit(pl_objp, parent_objp)) {
return 0;
}
// Maybe the ship which fired the weapon isn't the current target
if ( OBJ_INDEX(parent_objp) != aip->target_objnum ) {
//JAS IMPOSSIBLE if (1) { // consider_target_only ) {
//JAS IMPOSSIBLE return 0;
//JAS IMPOSSIBLE } else {
// switch targets
sip = &Ship_info[Ships[parent_objp->instance].ship_info_index];
if ( !(sip->is_big_or_huge()) || (sip->flags[Ship::Info_Flags::Transport]) ) {
return 0;
}
set_target_objnum(aip, OBJ_INDEX(parent_objp));
//JAS IMPOSSIBLE }
}
ai_big_strafe_maybe_attack_turret(pl_objp, weapon_objp);
// if we've got this far, the weapon must have come from the player's target, and it is a
// big/capital ship... so enter strafe mode
ai_big_save_previous_mode(aip);
aip->previous_mode = aip->mode;
aip->mode = AIM_STRAFE;
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
aip->submode = AIS_STRAFE_AVOID;
+2 -2
View File
@@ -24,8 +24,8 @@ void ai_big_subsys_path_cleanup(ai_info *aip);
void ai_big_strafe();
int ai_big_maybe_enter_strafe_mode(const object *objp, int weapon_objnum);
void ai_big_strafe_maybe_attack_turret(const object *ship_objp, const object *weapon_objp);
void ai_big_pick_attack_point(const object *objp, const object *attacker_objp, vec3d *attack_point, float fov=1.0f);
void ai_big_pick_attack_point_turret(const object *objp, ship_subsys *ssp, const vec3d *gpos, const vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
// default distance for following subsystem path points --wookieejedi
// the value is 5 because that was the original value specified in ai_big_maybe_follow_subsys_path()
+365 -927
View File
File diff suppressed because it is too large. Load diff
View File
Whitespace-only changes.
+218 -488
View File
File diff suppressed because it is too large. Load diff
+74 -89
View File
@@ -24,92 +24,81 @@ struct ai_info;
// macros for goals which get set via sexpressions in the mission code
// types of ai goals -- these will help us to determine which goals should
// types of ai goals -- tyese types will help us to determination on which goals should
// have priority over others (i.e. when a player issues a goal to a wing, then a seperate
// goal to a ship in that wing). We would probably use this type in conjunction with
// goal priority to establish which goal to follow
enum class ai_goal_type
{
INVALID = 0,
EVENT_SHIP, // from mission event direct to ship
EVENT_WING, // from mission event direct to wing
PLAYER_SHIP, // from player direct to ship
PLAYER_WING, // from player direct to wing
DYNAMIC // created on the fly
};
#define AIG_TYPE_EVENT_SHIP 1 // from mission event direct to ship
#define AIG_TYPE_EVENT_WING 2 // from mission event direct to wing
#define AIG_TYPE_PLAYER_SHIP 3 // from player direct to ship
#define AIG_TYPE_PLAYER_WING 4 // from player direct to wing
#define AIG_TYPE_DYNAMIC 5 // created on the fly
// IMPORTANT! If you add a new AI_GOAL_x enum, be sure to update the functions
#define AI_GOAL_NONE -1
// IMPORTANT! If you add a new AI_GOAL_x define, be sure to update the functions
// ai_update_goal_references() and query_referenced_in_ai_goals() or else risk breaking
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
// Goober5000 - As well as Ai_goal_text and Ai_goal_list, if appropriate
enum ai_goal_mode : uint8_t
{
AI_GOAL_NONE = 0,
AI_GOAL_SCHROEDINGER, // used for FRED when multiple ships are selected with different orders
#define AI_GOAL_CHASE (1<<1) // 0x00000002
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
#define AI_GOAL_WARP (1<<5) // 0x00000020
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
#define AI_GOAL_GUARD (1<<10) // 0x00000400
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
AI_GOAL_CHASE,
AI_GOAL_DOCK, // used for undocking as well
AI_GOAL_WAYPOINTS,
AI_GOAL_WAYPOINTS_ONCE,
AI_GOAL_WARP,
AI_GOAL_DESTROY_SUBSYSTEM,
AI_GOAL_FORM_ON_WING,
AI_GOAL_UNDOCK,
AI_GOAL_CHASE_WING,
AI_GOAL_GUARD,
AI_GOAL_DISABLE_SHIP,
AI_GOAL_DISARM_SHIP,
AI_GOAL_CHASE_ANY,
AI_GOAL_IGNORE,
AI_GOAL_GUARD_WING,
AI_GOAL_EVADE_SHIP,
// the next goals are for support ships only
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
// the next goals are for support ships only
AI_GOAL_STAY_NEAR_SHIP,
AI_GOAL_KEEP_SAFE_DISTANCE,
AI_GOAL_REARM_REPAIR,
// resume regular goals
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
// resume regular goals
AI_GOAL_STAY_STILL,
AI_GOAL_PLAY_DEAD,
// added by SCP
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
#define AI_GOAL_CHASE_SHIP_CLASS (1<<25) // 0x02000000
#define AI_GOAL_PLAY_DEAD_PERSISTENT (1<<26) // 0x04000000
#define AI_GOAL_LUA (1<<27) // 0x08000000
#define AI_GOAL_DISARM_SHIP_TACTICAL (1<<28) // 0x10000000
#define AI_GOAL_DISABLE_SHIP_TACTICAL (1<<29) // 0x20000000
// added by SCP
AI_GOAL_CHASE_WEAPON,
AI_GOAL_FLY_TO_SHIP,
AI_GOAL_IGNORE_NEW,
AI_GOAL_CHASE_SHIP_CLASS,
AI_GOAL_CHASE_SHIP_TYPE,
AI_GOAL_PLAY_DEAD_PERSISTENT, // Disables subsystem rotation/translation among other things but there is a carveout for that in the lab in ship_move_subsystems() and ai_process_subobjects()
AI_GOAL_LUA,
AI_GOAL_DISARM_SHIP_TACTICAL,
AI_GOAL_DISABLE_SHIP_TACTICAL,
// now the masks for ship types
AI_GOAL_NUM_VALUES
};
// Goober5000: added AI_GOAL_STAY_NEAR_SHIP and AI_GOAL_KEEP_SAFE_DISTANCE as valid for fighters
//WMC - Don't need these anymore. Whee!
/*
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISABLE_SHIP_TACTICAL | AI_GOAL_DISARM_SHIP | AI_GOAL_DISARM_SHIP_TACTICAL | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
#define AI_GOAL_ACCEPT_BOMBER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_STEALTH ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_FREIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_CRUISER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FREIGHTER | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_CORVETTE ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_GAS_MINER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_AWACS ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_CAPITAL ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER & ~(AI_GOAL_DOCK | AI_GOAL_UNDOCK) | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_SUPERCAP ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CAPITAL | AI_GOAL_STAY_NEAR_SHIP )
#define AI_GOAL_ACCEPT_SUPPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_DOCK | AI_GOAL_UNDOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT )
#define AI_GOAL_ACCEPT_ESCAPEPOD ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT| AI_GOAL_STAY_NEAR_SHIP )
*/
inline ai_goal_mode int_to_ai_goal_mode(int int_mode)
{
if (int_mode >= 0 && int_mode < AI_GOAL_NUM_VALUES)
return static_cast<ai_goal_mode>(int_mode);
Warning(LOCATION, "ai_goal_mode %d out of range! Setting to AI_GOAL_NONE.", int_mode);
return AI_GOAL_NONE;
}
inline bool ai_goal_is_disable_or_disarm(ai_goal_mode ai_mode)
{
return ai_mode == AI_GOAL_DISABLE_SHIP || ai_mode == AI_GOAL_DISABLE_SHIP_TACTICAL || ai_mode == AI_GOAL_DISARM_SHIP || ai_mode == AI_GOAL_DISARM_SHIP_TACTICAL;
}
inline bool ai_goal_is_specific_chase(ai_goal_mode ai_mode)
{
return ai_mode == AI_GOAL_CHASE || ai_mode == AI_GOAL_CHASE_WING || ai_mode == AI_GOAL_CHASE_SHIP_CLASS || ai_mode == AI_GOAL_CHASE_SHIP_TYPE;
}
inline bool ai_goal_is_standing_chase(ai_goal_mode ai_mode)
{
return ai_mode == AI_GOAL_CHASE_ANY;
}
#define MAX_AI_DOCK_NAMES 25
enum class ai_achievability { ACHIEVABLE, NOT_ACHIEVABLE, NOT_KNOWN, SATISFIED };
@@ -121,16 +110,16 @@ struct ai_lua_parameters {
// structure for AI goals
typedef struct ai_goal {
int signature; // Unique identifier. All goals ever created (per mission) have a unique signature.
ai_goal_mode ai_mode; // one of the AI_GOAL_* modes for this goal
int ai_mode; // one of the AIM_* modes for this goal
int ai_submode; // maybe need a submode
ai_goal_type type; // one of the ai_goal_type (originally AIG_TYPE_*) values above
int type; // one of the AIG_TYPE_* values above
flagset<AI::Goal_Flags> flags; // one of the AIGF_* values above
fix time; // time at which this goal was issued.
int priority; // how important is this goal -- number 0 - 100
const char *target_name; // name of the thing that this goal acts upon
int target_name_index; // index of goal_target_name in Goal_target_names[][]
int wp_list_index; // waypoints that this ship might fly.
waypoint_list *wp_list; // waypoints that this ship might fly.
int target_instance; // instance of thing this ship might be chasing (currently only used for weapons; note, not the same as objnum!)
int target_signature; // signature of object this ship might be chasing (currently only used for weapons; paired with above value to confirm target)
@@ -155,22 +144,18 @@ typedef struct ai_goal {
} ai_goal;
extern void ai_goal_reset(ai_goal *aigp, bool adding_goal = false, ai_goal_mode ai_mode = AI_GOAL_NONE, int ai_submode = -1, ai_goal_type type = ai_goal_type::INVALID);
extern void ai_goal_reset(ai_goal *aigp, bool adding_goal = false, int ai_mode = AI_GOAL_NONE, int ai_submode = -1, int type = -1);
// Reset all path points. Used in the ship lab. Missions clean up path points with the garbage collector in garbage_collect_path_points()
extern void reset_ai_path_points();
typedef flag_def_list_templated<ai_goal_mode> ai_goal_list;
typedef flag_def_list ai_goal_list;
extern ai_goal_list Ai_goal_names[];
extern int Num_ai_goals;
#define MAX_AI_DOCK_NAMES 25
extern int Num_ai_dock_names;
extern char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
extern const char *Ai_goal_text(ai_goal_mode goal, int submode);
extern const char *Ai_goal_text(int goal, int submode);
// every goal in a mission gets a unique signature
extern int Ai_goal_signature;
@@ -183,17 +168,17 @@ extern void ai_process_mission_orders( int objnum, ai_info *aip );
extern int ai_goal_num(ai_goal *goals);
// adds goals to ships/wing through sexpressions
extern void ai_add_ship_goal_scripting(ai_goal_mode mode, int submode, int priority, const char *shipname, ai_info *aip, int int_data, float float_data, int docker_index = -1, int dockee_index = -1);
extern void ai_add_ship_goal_sexp(int sexp, ai_goal_type type, ai_info *aip);
extern void ai_add_wing_goal_sexp(int sexp, ai_goal_type type, wing *wingp);
extern void ai_add_goal_sub_sexp(int sexp, ai_goal_type type, ai_info *aip, ai_goal *aigp, const char *actor_name);
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, const char *shipname, ai_info *aip);
extern void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip );
extern void ai_add_wing_goal_sexp( int sexp, int type, wing *wingp );
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, const char *actor_name);
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp, bool &remove_more );
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp );
extern void ai_remove_wing_goal_sexp( int sexp, wing *wingp );
// adds goals to ships/sings through player orders
extern void ai_add_ship_goal_player(ai_goal_type type, ai_goal_mode mode, int submode, const char* shipname, ai_info* aip, int int_data = 0, float float_data = 0.0f, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_add_wing_goal_player(ai_goal_type type, ai_goal_mode mode, int submode, const char* shipname, int wingnum, int int_data = 0, float float_data = 0.0f, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_add_ship_goal_player(int type, int mode, int submode, const char* shipname, ai_info* aip, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_add_wing_goal_player(int type, int mode, int submode, const char* shipname, int wingnum, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_remove_ship_goal( ai_info *aip, int index );
extern void ai_clear_ship_goals( ai_info *aip );
@@ -208,7 +193,7 @@ extern void ai_update_goal_references(ai_goal *goals, sexp_ref_type type, const
extern bool query_referenced_in_ai_goals(ai_goal *goals, sexp_ref_type type, const char *name);
extern char *ai_add_dock_name(const char *str);
extern int ai_query_goal_valid( int ship, ai_goal_mode ai_mode );
extern int ai_query_goal_valid( int ship, int ai_goal_type );
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
+7 -7
View File
@@ -14,24 +14,24 @@
#include "weapon/weapon.h"
//Returns true if the specified object is a stealth ship, false if not
bool is_object_stealth_ship(const object* objp);
bool is_object_stealth_ship(object* objp);
//Number of live turrets on the object attacking
int num_turrets_attacking(const object *turret_parent, int target_objnum);
int num_turrets_attacking(object *turret_parent, int target_objnum);
//Determine whether an object is targetable within a nebula (checks for stealth)
bool object_is_targetable(const object *target, const ship *viewer);
int object_is_targetable(object *target, ship *viewer);
//Returns the number of enemy fighters within threshold of pos.
int num_nearby_fighters(int enemy_team_mask, const vec3d *pos, float threshold);
int num_nearby_fighters(int enemy_team_mask, vec3d *pos, float threshold);
//Returns true if OK for *aip to fire its current weapon at its current target.
bool check_ok_to_fire(int objnum, int target_objnum, const weapon_info *wip, int secondary_bank, const vec3d *firing_pos_global);
int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip, int secondary_bank, ship_subsys* turret);
//Returns true if *aip has a line of sight to its current target.
bool check_los(int objnum, int target_objnum, float threshold, int primary_bank, int secondary_bank, const vec3d *firing_pos_global);
bool check_los(int objnum, int target_objnum, float threshold, int primary_bank, int secondary_bank, ship_subsys* turret);
//Does all the stuff needed to aim and fire a turret.
void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss);
void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss);
#endif
+1 -1
View File
@@ -389,7 +389,7 @@ ai_achievability ai_lua_is_achievable(const ai_goal* aigp, int objnum){
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::USERDATA) {
scripting::api::enum_h enumData;
retVals[0].getValue(scripting::api::l_Enum.Get(&enumData));
if (!enumData.isValid()) {
if (!enumData.IsValid()) {
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
return ai_achievability::ACHIEVABLE;
}
+429 -460
View File
File diff suppressed because it is too large. Load diff
+17 -6
View File
@@ -667,10 +667,12 @@ void anim_read_header(anim *ptr, CFILE *fp)
*
* @param real_filename Filename of animation
* @param cf_dir_type
*
* @param file_mapped Whether to use memory-mapped file or not.
*
* @details Memory-mapped files will page in the animation from disk as it is needed, but performance is not as good.
* @return Pointer to anim that is loaded if success, NULL if failure.
*/
anim *anim_load(const char *real_filename, int cf_dir_type)
anim *anim_load(const char *real_filename, int cf_dir_type, int file_mapped)
{
anim *ptr;
CFILE *fp;
@@ -695,7 +697,7 @@ anim *anim_load(const char *real_filename, int cf_dir_type)
}
if (!ptr) {
fp = cfopen(name, "rb", cf_dir_type);
fp = cfopen(name, "rb", CFILE_NORMAL, cf_dir_type);
if ( !fp )
return NULL;
@@ -741,9 +743,18 @@ anim *anim_load(const char *real_filename, int cf_dir_type)
ptr->cfile_ptr = NULL;
// NOTE: mapped files no longer supported!!
ptr->flags |= ANF_STREAMED;
ptr->cfile_ptr = cfopen(name, "rb", cf_dir_type);
if ( file_mapped == PAGE_FROM_MEM) {
// Try mapping the file to memory
ptr->flags |= ANF_MEM_MAPPED;
ptr->cfile_ptr = cfopen(name, "rb", CFILE_MEMORY_MAPPED, cf_dir_type);
}
// couldn't memory-map file... must be in a packfile, so stream manually
if ( file_mapped == PAGE_FROM_MEM && !ptr->cfile_ptr ) {
ptr->flags &= ~ANF_MEM_MAPPED;
ptr->flags |= ANF_STREAMED;
ptr->cfile_ptr = cfopen(name, "rb", CFILE_NORMAL, cf_dir_type);
}
ptr->cache = NULL;
+7 -1
View File
@@ -38,6 +38,12 @@ typedef struct {
int ping_pong;
} anim_play_struct;
enum
{
PAGE_FROM_DISK = 0,
PAGE_FROM_MEM = 1
};
extern int Anim_paused;
void anim_init();
@@ -51,7 +57,7 @@ void anim_ignore_next_frametime();
int anim_show_next_frame(anim_instance *instance, float frametime);
void anim_release_all_instances(int screen_id = 0);
void anim_release_render_instance(anim_instance* instance);
anim *anim_load(const char *name, int cf_dir_type = CF_TYPE_ANY);
anim *anim_load(const char *name, int cf_dir_type = CF_TYPE_ANY, int file_mapped = PAGE_FROM_DISK);
int anim_free(anim *ptr);
void anim_read_header(anim *ptr, CFILE *fp);
void anim_reverse_direction(anim_instance *ai); // called automatically for ping-ponging, and can also be called externally
+10 -18
View File
@@ -142,15 +142,11 @@ int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bp
bit_16 = (ushort)pix;
break;
case 8:
// 8-bit-per-pixel HUD gauge ANI aabitmaps use the palette index directly as an alpha value —
// the actual RGB colors stored in the palette are completely ignored. The valid range is [0, 15]:
// [0]: fully transparent (alpha 0)
// [1-14]: black-to-white gradient (alpha = index * 18)
// [15]: special HUD background (alpha 18, matching index 1, for a dark transparent tint)
// [>15]: clamped to fully opaque (alpha 255)
// Because only the index value matters, the palette in the source file must be ordered so that
// index 0 is the transparent end and index 14 is the opaque end. A reversed palette causes the
// gauge to render as a solid white square (see GitHub issue #4148).
// 8 bit-per-pixel aa bitmaps are a bit special since they only use a palette index value in the range [0, 15]. These
// palette indexes must be remapped to alpha values between [0, 255] which is what graphics code expects. Palette
// range [0, 14] is a gradient from black to white, and palette index 15 is a special color which indicates the background
// area of a HUD gauge. Retail code uses the final alpha value for index 1 for this special index to give gauges a dark
// transparent background.
if (pix > 15) {
bit_8 = 255;
}
@@ -244,15 +240,11 @@ int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0,
bit_16 = (ushort)pix;
break;
case 8 :
// 8-bit-per-pixel HUD gauge ANI aabitmaps use the palette index directly as an alpha value —
// the actual RGB colors stored in the palette are completely ignored. The valid range is [0, 15]:
// [0]: fully transparent (alpha 0)
// [1-14]: black-to-white gradient (alpha = index * 18)
// [15]: special HUD background (alpha 18, matching index 1, for a dark transparent tint)
// [>15]: clamped to fully opaque (alpha 255)
// Because only the index value matters, the palette in the source file must be ordered so that
// index 0 is the transparent end and index 14 is the opaque end. A reversed palette causes the
// gauge to render as a solid white square (see GitHub issue #4148).
// 8 bit-per-pixel aa bitmaps are a bit special since they only use a palette index value in the range [0, 15]. These
// palette indexes must be remapped to alpha values between [0, 255] which is what graphics code expects. Palette
// range [0, 14] is a gradient from black to white, and palette index 15 is a special color which indicates the background
// area of a HUD gauge. Retail code uses the final alpha value for index 1 for this special index to give gauges a dark
// transparent background.
if (pix > 15) {
bit_8 = 255;
}
+252 -453
View File
File diff suppressed because it is too large. Load diff
+24 -49
View File
@@ -14,10 +14,7 @@
#include "globalincs/globals.h" // for NAME_LENGTH
#include "globalincs/pstypes.h"
#include "object/object_flags.h"
#include "io/timer.h"
#include "particle/ParticleSource.h"
#include "math/vecmat.h"
class object;
class polymodel;
@@ -27,14 +24,15 @@ class model_draw_list;
#define MAX_ASTEROIDS 2000 //Increased from 512 to 2000 in 2022
#define NUM_ASTEROID_SIZES 3
#define NUM_ASTEROID_POFS 3 // Number of POFs per debris size
#define ASTEROID_TYPE_DEBRIS -1
#define ASTEROID_TYPE_SMALL 0
#define ASTEROID_TYPE_MEDIUM 1
#define ASTEROID_TYPE_LARGE 2
// Only used for parsing & saving retail compatible mission files
#define MAX_RETAIL_DEBRIS_TYPES 3
// these should always be equal for the benefit of generic asteroids (c.f. asteroid_page_in)
#define MAX_ACTIVE_DEBRIS_TYPES NUM_ASTEROID_SIZES
// Goober5000 - currently same as MAX_SHIP_DETAIL_LEVELS (put here to avoid an #include)
#define MAX_ASTEROID_DETAIL_LEVELS 5
@@ -56,19 +54,13 @@ typedef struct asteroid_split_info {
int max; //maximum asteroids to spawn
} asteroid_split_info;
// Data structure for storing asteroid subtype info. POFs, model pointer, model num, etc.
typedef struct asteroid_subtype_info {
char pof_filename[MAX_FILENAME_LEN];
int model_number;
SCP_string type_name;
} asteroid_subtype_info;
class asteroid_info
{
public:
char name[NAME_LENGTH]; // name for the asteroid
int type; // type of asteroid, 0 = small, 1 = medium, 2 = large, -1 = debris
int num_detail_levels; // number of detail levels for this asteroid
char pof_files[NUM_ASTEROID_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
int num_detail_levels; // number of detail levels for this ship
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
float max_speed; // cap on speed for asteroid
float rotational_vel_multiplier; // rotational velocity multiplier for asteroid --wookieejedi
@@ -80,25 +72,31 @@ public:
float blast; // maximum blast impulse from area effect explosion
float initial_asteroid_strength; // starting strength of asteroid
SCP_vector< asteroid_split_info > split_info;
polymodel *modelp[NUM_ASTEROID_POFS];
int model_num[NUM_ASTEROID_POFS];
SCP_vector<int> explosion_bitmap_anims;
float fireball_radius_multiplier; // the model radius is multiplied by this to determine the fireball size
particle::ParticleEffectHandle end_particles;
std::optional<float> breakup_delay;
SCP_string display_name; // only used for hud targeting display and for debris
float spawn_weight; // debris only, relative proportion to spawn compared to other types in its asteroid field
float fireball_radius_multiplier; // the model radius is multiplied by this to determine the fireball size
SCP_string display_name; // only used for hud targeting display and for 'ship' asteroids
float spawn_weight; // ship asteroids only, relative proportion to spawn compared to other types in its asteroid field
float gravity_const; // multiplier for mission gravity
SCP_vector<asteroid_subtype_info> subtypes;
asteroid_info( )
: type(ASTEROID_TYPE_DEBRIS), num_detail_levels(0), max_speed(0),
rotational_vel_multiplier(1), damage_type_idx(0),
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
fireball_radius_multiplier( -1 ), end_particles( particle::ParticleEffectHandle::invalid() ), breakup_delay( std::nullopt ), spawn_weight( 1 ), gravity_const( 0 )
fireball_radius_multiplier( -1 ), spawn_weight( 1 ), gravity_const( 0 )
{
name[ 0 ] = 0;
display_name = "";
memset( detail_distance, 0, sizeof( detail_distance ) );
for (int i = 0; i < NUM_ASTEROID_POFS; i++)
{
modelp[i] = NULL;
model_num[i] = -1;
pof_files[i][0] = '\0';
}
}
};
@@ -107,7 +105,6 @@ public:
typedef struct asteroid {
int flags;
flagset<Object::Raw_Pof_Flags> render_flags; // Render flags
int objnum;
int model_instance_num;
int asteroid_type; // 0..MAX_DEBRIS_TYPES
@@ -134,7 +131,7 @@ typedef enum {
FT_PASSIVE
} field_type_t;
struct asteroid_field {
typedef struct asteroid_field {
vec3d min_bound; // Minimum range of field.
vec3d max_bound; // Maximum range of field.
float bound_rad;
@@ -146,29 +143,12 @@ struct asteroid_field {
int num_initial_asteroids; // Number of asteroids at creation.
field_type_t field_type; // active throws and wraps, passive does not
debris_genre_t debris_genre; // type of debris (ship or asteroid) [generic type]
SCP_vector<int> field_debris_type; // one of the debris type defines above
SCP_vector<SCP_string> field_asteroid_type; // one of the asteroid subtypes
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]; // one of the debris type defines above
int num_used_field_debris_types; // how many of the above are used
bool enhanced_visibility_checks; // if true then range checks are overridden for spawning and wrapping asteroids in the field
SCP_vector<SCP_string> target_names; // default retail behavior is to just throw at the first big ship in the field
asteroid_field()
{
num_initial_asteroids = 0; // disable the field by default
speed = 0.0f;
vm_vec_make(&min_bound, -1000.0f, -1000.0f, -1000.0f);
vm_vec_make(&max_bound, 1000.0f, 1000.0f, 1000.0f);
vm_vec_make(&inner_min_bound, -500.0f, -500.0f, -500.0f);
vm_vec_make(&inner_max_bound, 500.0f, 500.0f, 500.0f);
has_inner_bound = false;
field_type = FT_ACTIVE;
debris_genre = DG_ASTEROID;
enhanced_visibility_checks = false;
bound_rad = 0.0f;
vel = ZERO_VECTOR;
// the vectors default-construct to empty
}
};
} asteroid_field;
extern SCP_vector< asteroid_info > Asteroid_info;
extern asteroid Asteroids[MAX_ASTEROIDS];
@@ -185,8 +165,8 @@ bool asteroid_is_within_view(vec3d *pos, float range, bool range_override = f
void asteroid_level_init();
void asteroid_level_close();
void asteroid_create_all();
void asteroid_create_asteroid_field(int num_asteroids, int field_type, int asteroid_speed, vec3d o_min, vec3d o_max, bool inner_box, vec3d i_min, vec3d i_max, SCP_vector<SCP_string> asteroid_types);
void asteroid_create_debris_field(int num_asteroids, int asteroid_speed, SCP_vector<int> debris_types, vec3d o_min, vec3d o_max, bool enhanced);
void asteroid_create_asteroid_field(int num_asteroids, int field_type, int asteroid_speed, bool brown, bool blue, bool orange, vec3d o_min, vec3d o_max, bool inner_box, vec3d i_min, vec3d i_max, SCP_vector<SCP_string> targets);
void asteroid_create_debris_field(int num_asteroids, int asteroid_speed, int debris1, int debris2, int debris3, vec3d o_min, vec3d o_max, bool enhanced);
void asteroid_render(object* obj, model_draw_list* scene);
void asteroid_delete( object *asteroid_objp );
void asteroid_process_pre( object *asteroid_objp );
@@ -200,11 +180,6 @@ void asteroid_show_brackets();
void asteroid_target_closest_danger();
void asteroid_add_target(object* objp);
int get_asteroid_index(const char* asteroid_name);
const SCP_vector<SCP_string>& get_list_valid_asteroid_subtypes();
int get_asteroid_subtype_index_by_name(const SCP_string& name, int asteroid_idx);
// extern for the lab
void asteroid_load(int asteroid_info_index, int asteroid_subtype);
// need to extern for keycontrol debug commands
object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroid_subtype, bool check_visibility = false);
+27 -32
View File
@@ -30,7 +30,7 @@
#include <map>
// Extern functions/variables
extern bool Player_use_ai;
extern int Player_use_ai;
extern int get_wing_index(object *objp, int wingnum);
extern object * get_wing_leader(int wingnum);
extern int Cmdline_autopilot_interruptable;
@@ -66,7 +66,7 @@ int start_dist;
void autopilot_ai_waypoint_goal_fixup(ai_goal* aigp)
{
// this function sets wp_index properly;
aigp->wp_list_index = find_matching_waypoint_list_index(aigp->target_name);
aigp->wp_list = find_matching_waypoint_list(aigp->target_name);
}
@@ -111,15 +111,13 @@ const vec3d *NavPoint::GetPosition()
{
if (flags & NP_WAYPOINT)
{
auto wpt = find_waypoint_at_indexes(target_index, waypoint_num-1);
Assert(wpt != nullptr);
if (wpt == nullptr)
return &vmd_zero_vector;
waypoint *wpt = find_waypoint_at_index((waypoint_list*) target_obj, waypoint_num-1);
Assert(wpt != NULL);
return wpt->get_pos();
}
else
{
return &Objects[target_index].pos;
return &Objects[((ship*) target_obj)->objnum].pos;
}
}
@@ -241,7 +239,7 @@ bool StartAutopilot()
// is support ship trying to rearm-repair
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
// no, so tell it to depart
ai_add_ship_goal_player( ai_goal_type::PLAYER_SHIP, AI_GOAL_WARP, -1, nullptr, support_ship_aip );
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
} else {
// yes
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
@@ -270,7 +268,7 @@ bool StartAutopilot()
LockAPConv = _timestamp(); // lock convergence instantly
else
LockAPConv = _timestamp(3 * MILLISECONDS_PER_SECOND); // 3 seconds before we lock convergence
Player_use_ai = true;
Player_use_ai = 1;
set_time_compression(1);
lock_time_compression(true);
@@ -300,16 +298,15 @@ bool StartAutopilot()
autopilot_wings.clear();
// vars for usage w/ cinematic
vec3d pos, perp, tpos, rpos = Player_obj->pos, zero;
vec3d pos, norm1, perp, tpos, rpos = Player_obj->pos, zero;
memset(&zero, 0, sizeof(vec3d));
// instantly turn player toward tpos
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
{
vec3d norm1;
vm_vec_normalized_dir(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vector_2_matrix_norm(&Player_obj->orient, &norm1, nullptr, nullptr);
vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vector_2_matrix(&Player_obj->orient, &norm1, NULL, NULL);
}
for (i = 0; i < MAX_SHIPS; i++)
@@ -396,12 +393,10 @@ bool StartAutopilot()
radius = Objects[Ships[i].objnum].radius;
}
// instantly turn the ship to match the direction player is looking
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
{
vec3d norm1;
vm_vec_normalized_dir(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vector_2_matrix_norm(&Objects[Ships[i].objnum].orient, &norm1, nullptr, nullptr);
{// instantly turn the ship to match the direction player is looking
//vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
}
// snap wings into formation
@@ -467,12 +462,12 @@ bool StartAutopilot()
{
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
ai_add_ship_goal_player( ai_goal_type::PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, Waypoint_lists[Navs[CurrentNav].target_index].get_name(), &Ai_info[Ships[i].ai_index] );
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), &Ai_info[Ships[i].ai_index] );
//fixup has to wait until after wing goals
}
else
{
ai_add_ship_goal_player( ai_goal_type::PLAYER_SHIP, AI_GOAL_FLY_TO_SHIP, 0, Ships[Objects[Navs[CurrentNav].target_index].instance].ship_name, &Ai_info[Ships[i].ai_index] );
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_FLY_TO_SHIP, 0, ((ship*)Navs[CurrentNav].target_obj)->ship_name, &Ai_info[Ships[i].ai_index] );
}
}
@@ -488,15 +483,15 @@ bool StartAutopilot()
{
//ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );
//ai_add_wing_goal_player( ai_goal_type::PLAYER_WING, AI_GOAL_STAY_NEAR_SHIP, 0, target_shipname, wingnum );
//ai_add_wing_goal_player( ai_goal_type::PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, target_shipname, wingnum );
//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_STAY_NEAR_SHIP, 0, target_shipname, wingnum );
//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, target_shipname, wingnum );
//ai_clear_ship_goals( &(Ai_info[Ships[num].ai_index]) );
ai_clear_wing_goals( &Wings[i] );
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
ai_add_wing_goal_player( ai_goal_type::PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, Waypoint_lists[Navs[CurrentNav].target_index].get_name(), i );
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), i );
// "fix up" the goal
for (j = 0; j < MAX_AI_GOALS; j++)
@@ -510,7 +505,7 @@ bool StartAutopilot()
}
else
{
ai_add_wing_goal_player( ai_goal_type::PLAYER_WING, AI_GOAL_FLY_TO_SHIP, 0, Ships[Objects[Navs[CurrentNav].target_index].instance].ship_name, i );
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_FLY_TO_SHIP, 0, ((ship*)Navs[CurrentNav].target_obj)->ship_name, i );
}
}
@@ -858,7 +853,7 @@ void EndAutoPilot()
set_time_compression(1);
lock_time_compression(false);
Player_use_ai = false;
Player_use_ai = 0;
//Clear AI Goals
if (CinematicStarted) // clear cinematic if we need to
@@ -879,12 +874,12 @@ void EndAutoPilot()
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
goal = AI_GOAL_WAYPOINTS_ONCE;
goal_name = Waypoint_lists[Navs[CurrentNav].target_index].get_name();
goal_name = ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name();
}
else
{
goal = AI_GOAL_FLY_TO_SHIP;
goal_name = Ships[Objects[Navs[CurrentNav].target_index].instance].ship_name;
goal_name = ((ship*)Navs[CurrentNav].target_obj)->ship_name;
}
// assign ship goals
@@ -1099,9 +1094,9 @@ void NavSystem_Do()
for (i = 0; i < MAX_NAVPOINTS; i++)
{
if ((Navs[i].flags & NP_SHIP) && (Navs[i].target_index >= 0))
if ((Navs[i].flags & NP_SHIP) && (Navs[i].target_obj != NULL))
{
if (Objects[Navs[i].target_index].flags[Object::Object_Flags::Should_be_dead])
if (((ship*)Navs[i].target_obj)->objnum == -1)
{
if (CurrentNav == i)
CurrentNav = -1;
@@ -1113,7 +1108,7 @@ void NavSystem_Do()
// check if we're reached a Node
for (i = 0; i < MAX_NAVPOINTS; i++)
{
if (Navs[i].target_index >= 0)
if (Navs[i].target_obj != NULL)
{
if (Navs[i].flags & NP_VALIDTYPE && DistanceTo(i) < 1000)
Navs[i].flags |= NP_VISITED;
@@ -1397,7 +1392,7 @@ bool AddNav_Ship(const char *Nav, const char *TargetName, int flags)
{
if (Ships[i].objnum != -1 && !stricmp(TargetName, Ships[i].ship_name))
{
tnav.target_index = Ships[i].objnum;
tnav.target_obj = (void *)&Ships[i];
}
}
@@ -1438,7 +1433,7 @@ bool AddNav_Waypoint(const char *Nav, const char *WP_Path, int node, int flags)
Assert(!(tnav.flags & NP_SHIP));
tnav.target_index = find_matching_waypoint_list_index(WP_Path);
tnav.target_obj = find_matching_waypoint_list(WP_Path);
tnav.waypoint_num = node;
// copy it into it's location
+2 -2
View File
@@ -34,7 +34,7 @@ public:
ubyte normal_color[3] = { 0x80, 0x80, 0xFF };
ubyte visited_color[3] = { 0xFF, 0xFF, 0x00 };
int target_index = -1; //waypoint list index if NP_WAYPOINT, otherwise object index
const void *target_obj = nullptr;
int waypoint_num = -1; //only used when flags & NP_WAYPOINT
const vec3d *GetPosition();
@@ -53,7 +53,7 @@ public:
visited_color[1] = 0xFF;
visited_color[2] = 0x00;
target_index = -1;
target_obj = nullptr;
waypoint_num = -1;
}
};
+9 -10
View File
@@ -70,7 +70,7 @@ struct bitmap_entry {
// Stuff to keep track of usage
ubyte preloaded; //!< If set, then this was loaded from the lst file
int preload_count; //!< how many times this gets used in game, for unlocking
uint used_flags; //!< What flags it was accessed thru
ushort used_flags; //!< What flags it was accessed thru
int load_count;
bitmap bm; //!< Bitmap info
@@ -93,15 +93,14 @@ struct bitmap_slot {
};
// image specific lock functions
void bm_lock_ani( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_dds( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_png( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_apng( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_jpg( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_pcx( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_tga( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
void bm_lock_user( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags, bool convert = true );
void bm_lock_ktx1(int handle, bitmap_slot* bs, bitmap* bmp, int bpp, uint flags);
void bm_lock_ani( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_dds( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_png( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_apng( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_jpg( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_pcx( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_tga( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
void bm_lock_user( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags, bool convert = true );
const size_t BM_BLOCK_SIZE = 4096;
+61 -170
View File
@@ -13,7 +13,6 @@
#define WIN32_LEAN_AND_MEAN
#define BMPMAN_INTERNAL
#include "globalincs/pstypes.h"
#include "anim/animplay.h"
#include "anim/packunpack.h"
#include "bmpman/bm_internal.h"
@@ -33,7 +32,6 @@
#include "tgautils/tgautils.h"
#include "tracing/Monitor.h"
#include "tracing/tracing.h"
#include "ktxutils/ktxutils.h"
#include <cctype>
#include <climits>
@@ -61,8 +59,8 @@ size_t bm_texture_ram = 0;
int Bm_paging = 0;
// Extension type lists
const BM_TYPE bm_type_list[] = { BM_TYPE_DDS, BM_TYPE_TGA, BM_TYPE_PNG, BM_TYPE_JPG, BM_TYPE_PCX, BM_TYPE_KTX };
const char* bm_ext_list[] = { ".dds", ".tga", ".png", ".jpg", ".pcx", ".ktx" };
const BM_TYPE bm_type_list[] = { BM_TYPE_DDS, BM_TYPE_TGA, BM_TYPE_PNG, BM_TYPE_JPG, BM_TYPE_PCX };
const char *bm_ext_list[] = { ".dds", ".tga", ".png", ".jpg", ".pcx" };
const int BM_NUM_TYPES = sizeof(bm_type_list) / sizeof(bm_type_list[0]);
const BM_TYPE bm_ani_type_list[] = { BM_TYPE_EFF, BM_TYPE_ANI, BM_TYPE_PNG };
@@ -84,12 +82,7 @@ static bool bm_inited = false;
static uint Bm_next_signature = 0x1234;
static int Bm_low_mem = 0;
struct bm_lookup_cache_entry {
ubyte* data;
int width;
int height;
};
SCP_map<int, bm_lookup_cache_entry> bm_lookup_cache;
SCP_map<int,ubyte*> bm_lookup_cache;
/**
* How much RAM bmpman can use for textures.
@@ -150,31 +143,30 @@ bitmap_slot* bm_get_slot(int handle, bool separate_ani_frames) {
// Declaration of private functions and templates(declared as static type func(type param);)
bitmap_lookup::bitmap_lookup(int bitmap_num):
Bitmap_data(nullptr),
Width(0),
Height(0),
Num_channels(3)
Bitmap_data(NULL)
{
if ( !bm_is_valid(bitmap_num) ) return;
Num_channels = 3;
if ( bm_has_alpha_channel(bitmap_num) ) {
Num_channels = 4;
}
bitmap_entry *be = bm_get_entry(bitmap_num);
Width = be->bm.w;
Height = be->bm.h;
auto cache_search = bm_lookup_cache.find(bitmap_num);
if (cache_search == bm_lookup_cache.end()) {
// The texture in graphics memory may be smaller than the bitmap itself, e.g. when mipmap levels
// are culled at lower texture detail settings, so the readback reports the dimensions of the
// data it actually returns.
Bitmap_data = gr_get_bitmap_from_texture(bitmap_num, &Width, &Height);
Bitmap_data = (ubyte*)vm_malloc(Width * Height * Num_channels * sizeof(ubyte));
if (Bitmap_data != nullptr) {
bm_lookup_cache.insert({bitmap_num, {Bitmap_data, Width, Height}});
}
gr_get_bitmap_from_texture((void*)Bitmap_data, bitmap_num);
bm_lookup_cache.insert({bitmap_num, Bitmap_data});
} else {
Bitmap_data = cache_search->second.data;
Width = cache_search->second.width;
Height = cache_search->second.height;
Bitmap_data = cache_search->second;
}
}
@@ -197,11 +189,6 @@ float bitmap_lookup::get_channel_alpha(float u, float v)
{
Assert( Bitmap_data != NULL );
// without an alpha channel there is nothing to look up, and indexing channel 3 would read out of bounds
if ( Num_channels < 4 ) {
return 1.0f;
}
int x = fl2i(map_texture_address(u) * (Width-1));
int y = fl2i(map_texture_address(v) * (Height-1));
@@ -210,7 +197,7 @@ float bitmap_lookup::get_channel_alpha(float u, float v)
void clear_bm_lookup_cache() {
for(auto &iter: bm_lookup_cache) {
vm_free(iter.second.data);
free(iter.second);
}
bm_lookup_cache.clear();
}
@@ -218,7 +205,7 @@ void clear_bm_lookup_cache() {
/**
* Converts the bitmap referenced by bmp to the type specified by flags
*/
static void bm_convert_format(bitmap *bmp, uint flags);
static void bm_convert_format(bitmap *bmp, ushort flags);
/**
* Frees a bitmap's data if it can
@@ -611,8 +598,8 @@ int bm_create_3d(int bpp, int w, int h, int d, void* data) {
return -1;
// make sure that we have valid data
Assertion(data != nullptr, "No valid data received for 3D Bitmap creation!");
if (data == nullptr) {
UNREACHABLE("No valid data received for 3D Bitmap creation!");
return -1;
}
@@ -652,7 +639,7 @@ int bm_create_3d(int bpp, int w, int h, int d, void* data) {
return n;
}
void bm_convert_format(bitmap *bmp, uint flags) {
void bm_convert_format(bitmap *bmp, ushort flags) {
int idx;
// no transparency for 24 bpp images
@@ -914,7 +901,7 @@ void bm_get_frame_usage(int *ntotal, int *nnew) {
#endif
}
int bm_get_info(int handle, int *w, int * h, uint* flags, int *nframes, int *fps) {
int bm_get_info(int handle, int *w, int * h, ushort* flags, int *nframes, int *fps) {
bitmap * bmp;
if (!bm_inited) return -1;
@@ -1036,17 +1023,14 @@ void bm_init() {
bm_inited = true;
}
bool bm_is_cubemap(int handle)
{
const BM_TYPE type = bm_get_entry(handle)->comp_type;
return type == BM_TYPE_CUBEMAP_DDS || type == BM_TYPE_CUBEMAP_DXT1 || type == BM_TYPE_CUBEMAP_DXT3 ||
type == BM_TYPE_CUBEMAP_DXT5;
}
int bm_is_compressed(int num) {
auto entry = bm_get_entry(num);
BM_TYPE type = BM_TYPE_NONE;
//duh
if (!Use_compressed_textures)
return 0;
type = entry->comp_type;
switch (type) {
@@ -1075,24 +1059,6 @@ int bm_is_compressed(int num) {
case BM_TYPE_CUBEMAP_DXT5:
return DDS_CUBEMAP_DXT5;
case BM_TYPE_ETC2_RGB:
return KTX_ETC2_RGB;
case BM_TYPE_ETC2_SRGB:
return KTX_ETC2_SRGB;
case BM_TYPE_ETC2_RGBA_EAC:
return KTX_ETC2_RGBA_EAC;
case BM_TYPE_ETC2_SRGBA_EAC:
return KTX_ETC2_SRGBA_EAC;
case BM_TYPE_ETC2_RGBA1:
return KTX_ETC2_RGB_A1;
case BM_TYPE_ETC2_SRGBA1:
return KTX_ETC2_SRGB_A1;
default:
return 0;
}
@@ -1186,16 +1152,6 @@ static int bm_load_info(BM_TYPE type, const char *filename, CFILE *img_cfp, int
return -1;
}
}
// its a KTX file
else if (type == BM_TYPE_KTX) {
int ktx_ct;
int ktx_error = ktx1_read_header(filename, img_cfp, w, h, bpp, &ktx_ct, mm_lvl, size);
if (ktx_error != KTX1_ERROR_NONE) {
mprintf(("ktx: could not open '%s'\n", filename));
return -1;
}
*c_type = (BM_TYPE)ktx_ct;
}
// if its a tga file
else if (type == BM_TYPE_TGA) {
int tga_error = targa_read_header(filename, img_cfp, w, h, bpp, NULL);
@@ -1229,7 +1185,7 @@ static int bm_load_info(BM_TYPE type, const char *filename, CFILE *img_cfp, int
}
}
else {
UNREACHABLE("Unknown file type %d specified! This is probably a coding error.", type);
UNREACHABLE("Unknown file type specified! This is probably a coding error.");
return -1;
}
@@ -1409,8 +1365,6 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
c_type = BM_TYPE_JPG;
} else if (!stricmp(NOX("pcx"), ext)) {
c_type = BM_TYPE_PCX;
} else if (!stricmp(NOX("ktx"), ext)) {
c_type = BM_TYPE_KTX;
} else {
mprintf(("BMPMAN: Unknown file type in EFF parse!\n"));
return false;
@@ -1440,7 +1394,7 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
/**
* Lock an image files data into memory
*/
static int bm_load_image_data(int handle, int bpp, uint flags, bool nodebug)
static int bm_load_image_data(int handle, int bpp, ushort flags, bool nodebug)
{
BM_TYPE c_type = BM_TYPE_NONE;
int true_bpp;
@@ -1532,10 +1486,6 @@ static int bm_load_image_data(int handle, int bpp, uint flags, bool nodebug)
bm_lock_user(handle, bs, bmp, true_bpp, flags, false);
break;
case BM_TYPE_KTX:
bm_lock_ktx1(handle, bs, bmp, true_bpp, flags);
break;
default:
Warning(LOCATION, "Unsupported type in bm_lock -- %d\n", c_type);
return -1;
@@ -1995,7 +1945,7 @@ int bm_load_sub_slow(const char *real_filename, const int num_ext, const char **
return -1;
}
bitmap * bm_lock(int handle, int bpp, uint flags, bool nodebug) {
bitmap * bm_lock(int handle, int bpp, ushort flags, bool nodebug) {
bitmap *bmp;
Assertion(bm_inited, "bmpman must be initialized before this function can be called!");
@@ -2092,7 +2042,7 @@ bitmap * bm_lock(int handle, int bpp, uint flags, bool nodebug) {
return bmp;
}
void bm_lock_ani(int /*handle*/, bitmap_slot *bs, bitmap* /*bmp*/, int bpp, uint flags) {
void bm_lock_ani(int /*handle*/, bitmap_slot *bs, bitmap* /*bmp*/, int bpp, ushort flags) {
anim *the_anim;
anim_instance *the_anim_instance;
bitmap *bm;
@@ -2218,7 +2168,7 @@ void bm_lock_ani(int /*handle*/, bitmap_slot *bs, bitmap* /*bmp*/, int bpp, uint
}
void bm_lock_apng(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, uint /*flags*/) {
void bm_lock_apng(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort /*flags*/) {
auto be = &bs->entry;
int first_frame = be->info.ani.first_frame;
auto first_entry = bm_get_entry(first_frame);
@@ -2268,7 +2218,7 @@ void bm_lock_apng(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, uint /*
}
void bm_lock_dds(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, uint /*flags*/) {
void bm_lock_dds(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, ushort /*flags*/) {
ubyte *data = NULL;
int error;
ubyte dds_bpp = 0;
@@ -2332,7 +2282,7 @@ void bm_lock_dds(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, uint /*f
#endif
}
void bm_lock_jpg(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint /*flags*/) {
void bm_lock_jpg(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort /*flags*/) {
ubyte *data = NULL;
int d_size = 0;
int jpg_error = JPEG_ERROR_INVALID;
@@ -2379,7 +2329,7 @@ void bm_lock_jpg(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint /*flags
#endif
}
void bm_lock_pcx(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags) {
void bm_lock_pcx(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags) {
ubyte *data;
int pcx_error;
char filename[MAX_FILENAME_LEN];
@@ -2424,7 +2374,7 @@ void bm_lock_pcx(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags)
bm_convert_format(bmp, flags);
}
void bm_lock_png(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, uint /*flags*/) {
void bm_lock_png(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, ushort /*flags*/) {
ubyte *data = NULL;
//assume 32 bit - libpng should expand everything
int d_size;
@@ -2469,7 +2419,7 @@ void bm_lock_png(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, uint /*f
#endif
}
void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags) {
void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags) {
ubyte *data = NULL;
int byte_size;
char filename[MAX_FILENAME_LEN];
@@ -2528,7 +2478,7 @@ void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags)
bm_convert_format(bmp, flags);
}
void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags, bool convert) {
void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags, bool convert) {
auto be = &bs->entry;
// Unload any existing data
@@ -2821,21 +2771,6 @@ void bm_page_in_texture(int bitmapnum, int nframes) {
frame_entry->used_flags = BMP_TEX_CUBEMAP;
continue;
case BM_TYPE_ETC2_RGB:
case BM_TYPE_ETC2_SRGB:
frame_entry->used_flags = BMP_TEX_ETC2_RGB8;
continue;
case BM_TYPE_ETC2_RGBA1:
case BM_TYPE_ETC2_SRGBA1:
frame_entry->used_flags = BMP_TEX_ETC2_RGBA1;
continue;
case BM_TYPE_ETC2_RGBA_EAC:
case BM_TYPE_ETC2_SRGBA_EAC:
frame_entry->used_flags = BMP_TEX_ETC2_RGBA8;
continue;
default:
continue;
}
@@ -2881,21 +2816,6 @@ void bm_page_in_xparent_texture(int bitmapnum, int nframes) {
entry->used_flags = BMP_TEX_CUBEMAP;
continue;
case BM_TYPE_ETC2_RGB:
case BM_TYPE_ETC2_SRGB:
entry->used_flags = BMP_TEX_ETC2_RGB8;
continue;
case BM_TYPE_ETC2_RGBA1:
case BM_TYPE_ETC2_SRGBA1:
entry->used_flags = BMP_TEX_ETC2_RGBA1;
continue;
case BM_TYPE_ETC2_RGBA_EAC:
case BM_TYPE_ETC2_SRGBA_EAC:
entry->used_flags = BMP_TEX_ETC2_RGBA8;
continue;
default:
continue;
}
@@ -3481,67 +3401,38 @@ bool bm_validate_filename(const SCP_string& file, bool single_frame, bool animat
}
return false;
}
SDL_Surface* bm_to_sdl_surface(int handle)
{
SDL_Surface* bm_to_sdl_surface(int handle) {
Assertion(bm_is_valid(handle), "%d is no valid bitmap handle!", handle);
int w;
int h;
bm_get_info(handle, &w, &h, nullptr, nullptr);
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0x0000ff00;
gmask = 0x00ff0000;
bmask = 0xff000000;
amask = 0x000000ff;
#else
rmask = 0x00ff0000;
gmask = 0x0000ff00;
bmask = 0x000000ff;
amask = 0xff000000;
#endif
SDL_Surface* bitmapSurface = SDL_CreateRGBSurface(0, w, h, 32, rmask, gmask, bmask, amask);
if (SDL_LockSurface(bitmapSurface) < 0) {
return nullptr;
}
bitmap* bmp = bm_lock(handle, 32, BMP_TEX_XPARENT);
auto bitmapSurface = SDL_CreateSurface(bmp->w, bmp->h, SDL_PIXELFORMAT_BGRA32);
if (bitmapSurface) {
memcpy(bitmapSurface->pixels, reinterpret_cast<void *>(bmp->data),
bmp->w * bmp->h * (bmp->bpp >> 3));
}
memcpy(bitmapSurface->pixels, reinterpret_cast<void*>(bmp->data), static_cast<size_t>(w * h * 4));
bm_unlock(handle);
bm_unload(handle);
SDL_UnlockSurface(bitmapSurface);
return bitmapSurface;
}
// copied bm_lock_dds and adjusted for ktx. missing BIG_ENDIAN
void bm_lock_ktx1(int handle, bitmap_slot* bs, bitmap* bmp, int bpp, uint flags)
{
(void)bpp;
(void)flags;
ubyte* data = nullptr;
ubyte ktx_bpp = 0;
int ktx_error = KTX1_ERROR_NONE;
char filename[MAX_FILENAME_LEN];
auto be = &bs->entry;
bm_free_data(bs);
Assert(be->mem_taken > 0);
Assert(&be->bm == bmp);
data = (ubyte*)bm_malloc(handle, be->mem_taken);
if (!data)
return;
memset(data, 0, be->mem_taken);
// make sure we are using the correct filename in the case of an EFF.
// this will populate filename[] whether it's EFF or not
EFF_FILENAME_CHECK;
ktx_error = ktx1_read_bitmap(filename, data, &ktx_bpp);
if (ktx_error != KTX1_ERROR_NONE)
{
mprintf(("KTX: read_bitmap error=%d file='%s'\n", ktx_error, filename));
bm_free_data(bs);
return;
}
bmp->bpp = ktx_bpp;
bmp->data = (ptr_u)data;
bmp->flags = 0;
#ifdef BMPMAN_NDEBUG
Assert(be->data_size > 0);
#endif
}
+5 -28
View File
@@ -34,7 +34,6 @@
// Flag positions for bitmap.flags
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
// Update: bitmap.flags type changed to 16-bit
#define BMP_AABITMAP (1<<0) //!< antialiased bitmap
#define BMP_TEX_XPARENT (1<<1) //!< transparent texture
#define BMP_TEX_OTHER (1<<2) //!< so we can identify all "normal" textures
@@ -44,14 +43,9 @@
#define BMP_TEX_BC7 (1<<6) //!< BC7 compressed 8r8g8b8a (32bit)
#define BMP_TEX_CUBEMAP (1<<7) //!< a texture made for cubic environment map
#define BMP_MASK_BITMAP (1<<8) //!< a bitmap that will be used for masking mouse interaction. Typically not used in render operations
#define BMP_TEX_ETC2_RGB8 (1 << 9) //!< ETC2 RGB compressed (24bit, no alpha)
#define BMP_TEX_ETC2_RGBA1 (1 << 10) //!< ETC2 RGBA1 compressed (24bit, 1 alpha)
#define BMP_TEX_ETC2_RGBA8 (1 << 11) //!< ETC2 RGBA8 compressed (32bit, 8 alpha)
// Combined flags
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 | BMP_TEX_BC7 | BMP_TEX_ETC2_RGB8 |\
BMP_TEX_ETC2_RGBA1 | BMP_TEX_ETC2_RGBA8 ) //!< Compressed textures
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 | BMP_TEX_BC7 ) //!< Compressed textures
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER ) //!< Non-compressed textures
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP ) //!< Any texture
@@ -87,15 +81,7 @@ enum BM_TYPE
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT5, //!< 32-bit cubemap (compressed cubemap surface)
BM_TYPE_3D, //!< 3D in-memory
BM_TYPE_KTX, //!< generic identifier for KTX1
BM_TYPE_ETC2_RGB, //!< 24 bit, no alpha
BM_TYPE_ETC2_SRGB, //!< 24 bit, no alpha, signed
BM_TYPE_ETC2_RGBA1, //!< 24 bit, 1 bit alpha
BM_TYPE_ETC2_SRGBA1, //!< 24 bit, 1 bit alpha, signed
BM_TYPE_ETC2_RGBA_EAC, //!< 32 bit, 8 bit alpha
BM_TYPE_ETC2_SRGBA_EAC //!< 32 bit, 8 bit alpha, signed
BM_TYPE_3D //!< 3D in-memory
};
/**
@@ -110,7 +96,7 @@ struct bitmap
short rowsize; //!< What you need to add to go to next row
int bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
int true_bpp; //!< The image's actual bitdepth
uint flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
ushort flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
ptr_u data; //!< Pointer to data, or maybe offset into VRAM.
ubyte *palette; /**< @brief Pointer to this bitmap's palette (if it has one).
* @details If BMP_NO_PALETTE_MAP flag is cleared, this palette just points to the screen palette. (gr_palette)
@@ -149,7 +135,6 @@ void bm_close();
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1)
#define BMP_FLAG_CUBEMAP (1<<2)
#define BMP_FLAG_RENDER_TARGET_MIPMAP (1<<3)
#define BMP_FLAG_RENDER_TARGET_DEPTH_ATTACHMENT (1<<4)
/**
* @brief Allocates memory for the given handle.
@@ -359,7 +344,7 @@ int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, i
* @returns A pointer to the bitmap that's valid until bm_unlock is called if successful, or
* @returns NULL if unsuccessful
*/
bitmap* bm_lock(int handle, int bpp, uint flags, bool nodebug = false);
bitmap* bm_lock(int handle, int bpp, ushort flags, bool nodebug = false);
/**
* @brief Returns the image type of the given bitmap handle
@@ -402,7 +387,7 @@ int bm_is_valid(int handle);
* @returns The handle to the first frame on success, or
* @returns -1 on failure
*/
int bm_get_info(int handle, int *w = nullptr, int * h = nullptr, uint* flags = nullptr, int *nframes = nullptr, int *fps = nullptr);
int bm_get_info(int handle, int *w = nullptr, int * h = nullptr, ushort* flags = nullptr, int *nframes = nullptr, int *fps = nullptr);
/**
* @brief Gets 3D info on the bitmap indexed by handle.
@@ -594,14 +579,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
*/
int bm_is_compressed(int handle);
/**
* @brief Returns true if the bitmap indexed by handle was loaded from a cubemap image file
*
* @note Render targets return false, even cubemap ones, and so do BC7 (DX10) DDS cubemaps, whose cube flag the DDS
* loader does not keep
*/
bool bm_is_cubemap(int handle);
/**
* @brief Gets the correct TCACHE_TYPE for compressed graphics (uncompressed are assumed TCACHE_TYPE_NORMAL)
*/
Loaded 100 of 2679 files, more files were not shown because too many files have changed in this diff. Show more