mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
456ee79ab4 | ||
|
|
5238f65d7c | ||
|
|
47cd2a06a6 | ||
|
|
9ac617dd1a | ||
|
|
365ec2a14d | ||
|
|
1373a42719 |
No files matched your search
+1
-14
@@ -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'
|
||||
...
|
||||
|
||||
@@ -5,38 +5,53 @@ on:
|
||||
tags:
|
||||
- 'nightly_*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
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-3d30dc5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-lin
|
||||
# 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-lin.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
- 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: 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: gcc-9
|
||||
COMPILER: gcc-5
|
||||
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 +64,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@v2
|
||||
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@v1
|
||||
with:
|
||||
name: linux-Release-${{ matrix.arch }}
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v2
|
||||
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 +105,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@v2
|
||||
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@v1
|
||||
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@v2
|
||||
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
|
||||
@@ -281,18 +234,36 @@ jobs:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
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: |
|
||||
@@ -308,73 +279,52 @@ jobs:
|
||||
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:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
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
|
||||
run: gtar -cvzf macos-build-${{ matrix.configuration }}.tgz *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}.tgz
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
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@v2
|
||||
with:
|
||||
name: mac-Release-${{ matrix.arch }}
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug-${{ matrix.arch }}
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Unpack builds
|
||||
working-directory: ./builds
|
||||
run: |
|
||||
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-Release.tgz
|
||||
tar -xvzf macos-build-FastDebug.tgz
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
|
||||
@@ -5,6 +5,9 @@ on:
|
||||
tags:
|
||||
- 'release_*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
name: Create GitHub release
|
||||
@@ -38,36 +41,75 @@ 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-3d30dc5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-lin
|
||||
# uses: actions/cache@v1
|
||||
# cache the Qt directory so we don't have to reinstall it every time
|
||||
# cache.inputs:
|
||||
# path - A list of files, directories, and wildcard patterns to cache and restore. See @actions/glob for supported patterns.
|
||||
# key - An explicit key for restoring and saving the cache
|
||||
# restore-keys - An ordered list of keys to use for restoring the cache if no cache hit occurred for key
|
||||
# cache.outputs:
|
||||
# cache-hit true when an exact match was found for the key, false otherwise.
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# installs Qt in the action workflow
|
||||
# install-qt-action.inputs:
|
||||
# version desired qt version to install
|
||||
# host Host platform of Qt, default to platform used by runs-on
|
||||
# target target platform of Qt, default to desktop
|
||||
# arch target architecture of Qt, only used for windows or android builds
|
||||
# dir root dir Qt will be installed to
|
||||
# install-deps if true, auto-install dependencies on linux. Default true
|
||||
# modules whitespace delimited list string of additional addon modules to install
|
||||
# archives whitespace delimited list string of Qt archives to install
|
||||
# cached if true, Don't download Qt but set ENVARs; use with cache.outputs.cache-hit
|
||||
# setup-python Set to false to skip using setup-python to find/download a valid python version
|
||||
# set-env if true, set ENVARs; default = false
|
||||
# aqtversion version of aqtinstall to use; default = 2.0.0
|
||||
# py7zrversion version of py7zr to use; default = 0.16.1
|
||||
# extra additional arguments to pass to aqinstall
|
||||
# ENVARS set:
|
||||
# Qt5_DIR / Qt6_DIR
|
||||
# Qt bin dir appended to PATH
|
||||
# QT_PLUGIN_PATH, QML2_IMPORT_PATH, PKG_CONFIG_PATH, LD_LIBRARY_PATH
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
- 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: 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: gcc-9
|
||||
COMPILER: gcc-5
|
||||
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 +122,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@v2
|
||||
# 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 +133,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@v2
|
||||
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@v2
|
||||
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@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
@@ -152,175 +182,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@v2
|
||||
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@v2
|
||||
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@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ env.artifact_id }}
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
|
||||
- name: Create Distribution package
|
||||
@@ -328,17 +306,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@v2
|
||||
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@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.debug_name }}
|
||||
path: ${{ steps.generate_package.outputs.debug_path }}
|
||||
@@ -357,20 +336,37 @@ jobs:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
name: Mac
|
||||
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 }}
|
||||
@@ -380,77 +376,56 @@ jobs:
|
||||
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:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
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
|
||||
run: gtar -cvzf macos-build-${{ matrix.configuration }}.tgz *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}.tgz
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
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@v2
|
||||
with:
|
||||
name: mac-Release-${{ matrix.arch }}
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug-${{ matrix.arch }}
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Unpack builds
|
||||
working-directory: ./builds
|
||||
run: |
|
||||
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-Release.tgz
|
||||
tar -xvzf macos-build-FastDebug.tgz
|
||||
- name: Create Distribution package
|
||||
id: generate_package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
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@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
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: 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 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 }}
|
||||
+133
-141
@@ -5,44 +5,59 @@ on:
|
||||
branches:
|
||||
- 'test/*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
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-3d30dc5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-lin
|
||||
# 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-lin.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
- 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: 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: gcc-9
|
||||
COMPILER: gcc-5
|
||||
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 +70,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@v2
|
||||
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@v1
|
||||
with:
|
||||
name: linux-Release-${{ matrix.arch }}
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v2
|
||||
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 +112,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 +166,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 +195,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@v2
|
||||
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@v1
|
||||
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@v2
|
||||
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
|
||||
@@ -253,18 +248,36 @@ jobs:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
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: |
|
||||
@@ -279,73 +292,52 @@ jobs:
|
||||
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:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
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
|
||||
run: gtar -cvzf macos-build-${{ matrix.configuration }}.tgz *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}.tgz
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
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@v2
|
||||
with:
|
||||
name: mac-Release-${{ matrix.arch }}
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug-${{ matrix.arch }}
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Unpack builds
|
||||
working-directory: ./builds
|
||||
run: |
|
||||
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-Release.tgz
|
||||
tar -xvzf macos-build-FastDebug.tgz
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
|
||||
@@ -5,94 +5,58 @@ on:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-9, gcc-13, clang-16]
|
||||
arch: [x86_64]
|
||||
compiler: [gcc-5, gcc-10]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
- configuration: Debug
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
- configuration: Release
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
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-3d30dc5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-lin
|
||||
# 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-lin.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
|
||||
- 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
|
||||
- name: Configure ccache
|
||||
run: |
|
||||
ccache --set-config=sloppiness=pch_defines,time_macros
|
||||
ccache -p
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
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
|
||||
- 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
|
||||
- name: Show CCache statistics
|
||||
run: ccache --show-stats
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
@@ -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)
|
||||
|
||||
@@ -2,65 +2,72 @@ name: Check a pull request
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-9, gcc-13, clang-16]
|
||||
compiler: [gcc-5, gcc-10, clang-9]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
- configuration: Debug
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
- configuration: Release
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
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-3d30dc5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-lin
|
||||
# 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-lin.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
- 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
|
||||
verbose: 1
|
||||
- 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 }}
|
||||
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: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Show CCache statistics
|
||||
run: ccache --show-stats
|
||||
- name: Run Clang Tidy
|
||||
# Clang-tidy reuses the precompiled headers so this only makes sense for the clang compilers
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
@@ -74,25 +81,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 +134,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
|
||||
@@ -141,62 +182,63 @@ jobs:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
cmake_options: [""]
|
||||
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
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
- 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
|
||||
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:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
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
|
||||
@@ -1,74 +0,0 @@
|
||||
name: Weekly Coverity Scan for Freespace Open
|
||||
# adapted from code by "albert-github" on the doxygen repository
|
||||
# many thanks for figuring this out first so it could be less painful for us!
|
||||
|
||||
#This mode is for testing
|
||||
#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
|
||||
|
||||
env:
|
||||
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
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- { name: "GCC on ubuntu", os: ubuntu-latest, build_type: "Release" }
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
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
|
||||
run: |
|
||||
wget -o wgetlog.txt -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=${{ env.coverity_token }}&project=scp-fs2open/fs2open.github.com" -O coverity_tool.tgz
|
||||
mkdir cov-scan
|
||||
tar ax -f coverity_tool.tgz --strip-components=1 -C cov-scan
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
echo "$(pwd)/cov-scan/bin" >> $GITHUB_PATH
|
||||
echo "NPROC=$(getconf _NPROCESSORS_ONLN)" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake for FSO
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
COMPILER: gcc-9
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
|
||||
- name: Build FSO with Coverity Wrapper
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
run: cov-build --dir cov-int ninja -k 20 all
|
||||
|
||||
- name: Compress Results
|
||||
working-directory: ./build
|
||||
run: tar zcf cov-scan.tgz cov-int
|
||||
|
||||
#Comment this out when testing to keep from running into upload limits
|
||||
- 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
|
||||
@@ -42,7 +42,6 @@ _ReSharper*/
|
||||
|
||||
#Project files
|
||||
[Bb]uild/
|
||||
[Oo]ut/
|
||||
|
||||
#Subversion files
|
||||
.svn
|
||||
@@ -251,7 +250,6 @@ documentation/doxygen/*
|
||||
projects/*
|
||||
/.vs
|
||||
CMakeSettings.json
|
||||
CMakePresets.json
|
||||
|
||||
# Weird files created by Linux
|
||||
.fuse_hidden*
|
||||
@@ -260,10 +258,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
@@ -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
|
||||
|
||||
+50
-97
@@ -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,59 @@ 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)
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
# Currently only GCC support ccache properly without generating additional warnings
|
||||
# Enable ccache on Mac even for clang
|
||||
if(CCACHE_PROGRAM AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR APPLE))
|
||||
if(NOT CMAKE_C_COMPILER_LAUNCHER)
|
||||
message(STATUS "Using ccache for C compilation: ${CCACHE_PROGRAM}")
|
||||
SET(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
|
||||
endif()
|
||||
if(NOT CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
message(STATUS "Using ccache for C++ compilation: ${CCACHE_PROGRAM}")
|
||||
SET(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
|
||||
endif()
|
||||
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 +89,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 +107,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,52 +124,22 @@ 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_OPENXR_DEBUG "Enables debug option for OpenXR" OFF)
|
||||
|
||||
OPTION(FSO_USE_LTO "Build using LTO (only for release builds)" ON)
|
||||
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" OFF)
|
||||
|
||||
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
|
||||
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
|
||||
@@ -187,16 +148,18 @@ 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 +170,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 +218,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 +232,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
@@ -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"
|
||||
+23
-43
@@ -1,53 +1,37 @@
|
||||
#!/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
|
||||
export CXX=g++-13
|
||||
if [ "$COMPILER" = "gcc-10" ]; then
|
||||
export CC=gcc-10
|
||||
export CXX=g++-10
|
||||
fi
|
||||
if [ "$COMPILER" = "clang-16" ]; then
|
||||
export CC=clang-16
|
||||
export CXX=clang++-16
|
||||
if [ "$COMPILER" = "clang-9" ]; then
|
||||
# Work around bug in clang that uses the wrong installation directory: https://bugs.llvm.org/show_bug.cgi?id=47460
|
||||
export CC=$(readlink -f $(which clang-9))
|
||||
export CXX=$(readlink -f $(which clang++-9))
|
||||
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)"
|
||||
fi
|
||||
|
||||
if [ ! "$CCACHE_PATH" = "" ]; then
|
||||
echo "Using ccache at $CCACHE_PATH"
|
||||
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}"
|
||||
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCLANG_USE_LIBCXX=ON"
|
||||
# force clang to silently allow -static-libstdc++ flag
|
||||
CXXFLAGS="$CXXFLAGS -Qunused-arguments"
|
||||
fi
|
||||
|
||||
mkdir build
|
||||
@@ -57,14 +41,10 @@ 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
|
||||
|
||||
# CMAKE_JOB_POOLS and CMAKE_JOB_POOL_LINK ensure that when using ninja, link operations are done sequentially
|
||||
# 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=OFF \
|
||||
-DSHADERS_ENABLE_COMPILATION=ON ..
|
||||
@@ -8,29 +8,29 @@ 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
|
||||
tar -cvzf "$(get_package_name)-builds-Mac.tar.gz" *.app
|
||||
|
||||
echo "package_path=$(pwd)/$(get_package_name)-builds-Mac-$ARCH.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_name=$(get_package_name)-builds-Mac-$ARCH.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac-$ARCH.tar.gz")" >> $GITHUB_OUTPUT
|
||||
echo "package_path=$(pwd)/$(get_package_name)-builds-Mac.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_name=$(get_package_name)-builds-Mac.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac.tar.gz")" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Invalid OS: $OS"
|
||||
fi
|
||||
@@ -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
-16
@@ -5,22 +5,7 @@ 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
|
||||
echo "Skipping tests due to architecture mismatch!"
|
||||
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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
+1
-6
@@ -18,9 +18,8 @@
|
||||
# Credentials into hard-light.net for forum post
|
||||
# HLP_API:
|
||||
# HLP_KEY:
|
||||
# FORUM_SECRET:
|
||||
|
||||
# LINUX_RESULT: bool, if the linux builds were successfully uploaded
|
||||
# LINUX_RESULT: bool, if the linux builds were sucessfully uploaded
|
||||
# WINDOWS_RESULT: bool, if the windows builds were successfully uploaded
|
||||
|
||||
import sys
|
||||
@@ -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
|
||||
|
||||
+12
-24
@@ -7,15 +7,12 @@ 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"
|
||||
MACOSX_X64_KEY = "Mac-x86_64"
|
||||
MACOSX_ARM64_KEY = "Mac-arm64"
|
||||
LINUX_KEY = "Linux"
|
||||
MACOSX_KEY = "Mac"
|
||||
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 +33,21 @@ metadata = {
|
||||
}
|
||||
|
||||
platforms = {
|
||||
LINUX_X64_KEY: 'linux',
|
||||
LINUX_ARM64_KEY: 'linux',
|
||||
MACOSX_X64_KEY: 'macosx',
|
||||
MACOSX_ARM64_KEY: 'macosx',
|
||||
LINUX_KEY: 'linux',
|
||||
MACOSX_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',
|
||||
MACOSX_X64_KEY: 'macosx && x86_64',
|
||||
MACOSX_ARM64_KEY: 'macosx && arm64',
|
||||
LINUX_KEY: 'linux && x86_64', # Linux only has 64bit builds
|
||||
MACOSX_KEY: 'macosx',
|
||||
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 +110,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 +124,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,
|
||||
@@ -145,7 +135,7 @@ def render_nebula_release(version, stability, files, config):
|
||||
'label': label,
|
||||
'properties': props,
|
||||
})
|
||||
elif group.startswith('Mac') and fn.startswith(os.path.basename(fn) + '.app/'):
|
||||
elif group == MACOSX_KEY and fn.startswith(os.path.basename(fn) + '.app/'):
|
||||
if 'qtfred' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'QtFRED Debug'
|
||||
@@ -158,8 +148,7 @@ def render_nebula_release(version, stability, files, config):
|
||||
label = None
|
||||
|
||||
props = {
|
||||
"arm64": "arm64" in fn,
|
||||
"x64": "x64" in fn,
|
||||
"x64": True, # All Mac builds are 64-bit
|
||||
"sse2": True, # There are no forced options on mac but 64-bit always implies SSE2 so we set that here
|
||||
"avx": False,
|
||||
"avx2": False,
|
||||
@@ -194,7 +183,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({
|
||||
|
||||
+11
-15
@@ -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.2.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=98984.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,22 +41,20 @@ 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.
|
||||
|
||||
|
||||
[img]https://scp.indiegames.us/img/mac-icon.png[/img] [color=green][size=12pt]macOS[/size][/color]
|
||||
[size=8pt]macOS 10.9+[/size]
|
||||
[b]Intel (64-bit):[/b] ${build(groups["Mac"].subFiles["x86_64"])}
|
||||
[b]Apple Silicon:[/b] ${build(groups["Mac"].subFiles["arm64"])}
|
||||
[size=8pt]macOS 10.9+, 64-bit (Intel)[/size]
|
||||
${build(groups["Mac"].mainFile)}
|
||||
|
||||
These builds are not signed and so by default will fail to launch. To run them simply right-click on the app, click open, then click open again on the security confirmation dialog. You should only have to do this once for each app.
|
||||
If running the game through Knossos or Knossos.NET this step should not be necessary.
|
||||
|
||||
@@ -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
|
||||
@@ -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.
@@ -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()
|
||||
@@ -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 "
")
|
||||
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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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}"
|
||||
)
|
||||
|
||||
Vendored
+4054
File diff suppressed because it is too large.
Load diff
+1
Submodule cmake/external/rpavlik-cmake-modules added at 7cef9577d6.
@@ -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()
|
||||
|
||||
@@ -7,37 +7,3 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 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()
|
||||
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()
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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/)
|
||||
@@ -20,14 +22,6 @@ SET(LIBRAY_DESTINATION "../Frameworks")
|
||||
|
||||
set(PLATFORM_MAC TRUE CACHE INTERNAL "" FORCE)
|
||||
|
||||
# Maybe override arm64 setting if we are compiling for different architecture
|
||||
# If not specified, or if it's a universal build, then this should do nothing
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
||||
set(IS_ARM64 TRUE)
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
set(IS_ARM64 FALSE)
|
||||
endif()
|
||||
|
||||
# Generate and don't strip debug symbols
|
||||
# These settings don't seem to generate debug symbols for code and Freespace2
|
||||
# so those settings are set manually in code and Freespace2's CMakeLists.txt files
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
|
||||
|
||||
#cmakedefine01 IS_64BIT
|
||||
#cmakedefine01 IS_ARM64
|
||||
#cmakedefine01 IS_RISCV
|
||||
|
||||
#cmakedefine01 SCP_HAVE_STRCASECMP
|
||||
#cmakedefine01 SCP_HAVE_STRNCASECMP
|
||||
|
||||
@@ -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")
|
||||
+14
-65
@@ -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
|
||||
@@ -111,43 +83,20 @@ if(SUPPORTS_SHIFT_NEGATIVE_VALUE)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-shift-negative-value")
|
||||
endif()
|
||||
|
||||
# Check if there is a user-set optimisation flag
|
||||
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})
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-parameter")
|
||||
|
||||
# If no user-set opt flag, set -O3 and -Og
|
||||
if ("${CXX_OPT_FLAG}" STREQUAL "")
|
||||
set(CXX_OPT_FLAG_RELEASE "-O3")
|
||||
set(CXX_OPT_FLAG_DEBUG "-O0")
|
||||
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")
|
||||
else()
|
||||
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
|
||||
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
|
||||
endif()
|
||||
set(COMPILER_FLAGS_DEBUG "-Og -g -Wshadow")
|
||||
|
||||
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")
|
||||
|
||||
# Always use the base flags and add our compiler flags at the back
|
||||
# Always use the base flags and add our compiler flags at the bacl
|
||||
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${C_FLAGS_RELEASE})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
|
||||
|
||||
@@ -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})
|
||||
@@ -154,41 +113,19 @@ if(SUPPORTS_STRINGOP_TRUNCATION)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-stringop-overflow")
|
||||
endif()
|
||||
|
||||
# Check if there is a user-set optimisation flag
|
||||
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})
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
|
||||
# If no user-set opt flag, set -O3 and -Og
|
||||
if ("${CXX_OPT_FLAG}" STREQUAL "")
|
||||
set(CXX_OPT_FLAG_RELEASE "-O3")
|
||||
set(CXX_OPT_FLAG_DEBUG "-O0")
|
||||
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")
|
||||
else()
|
||||
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
|
||||
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
|
||||
endif()
|
||||
|
||||
set(CXX_FLAGS_RELEASE "${CXX_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
set(C_FLAGS_RELEASE "${C_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
|
||||
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -Wshadow")
|
||||
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -Wshadow")
|
||||
set(COMPILER_FLAGS_DEBUG "-Og -g -Wshadow")
|
||||
|
||||
# Always use the base flags and add our compiler flags at the back
|
||||
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${C_FLAGS_RELEASE})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS_DEBUG})
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")
|
||||
|
||||
|
||||
+56
-40
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
+3
-11
@@ -6,8 +6,8 @@ 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_MINOR 3)
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 23)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 1)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 0)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
@@ -35,15 +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)
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_arm64")
|
||||
ELSEIF(IS_64BIT)
|
||||
IF(IS_64BIT)
|
||||
# This is a 64-bit builds
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_x64")
|
||||
ENDIF()
|
||||
|
||||
+23
-33
@@ -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,21 +25,13 @@ 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)
|
||||
add_definitions(-DFS_OPENXR_DEBUG)
|
||||
endif()
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC openal)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${LUA_LIBS})
|
||||
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 +44,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,20 +63,17 @@ 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 hidapi::hidapi)
|
||||
|
||||
IF(FSO_BUILD_WITH_OPENXR)
|
||||
target_link_libraries(code PUBLIC OpenXR::openxr_loader)
|
||||
target_include_directories(code PUBLIC OpenXR::Headers)
|
||||
ENDIF()
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# On Linux, we need to access X11 window data.
|
||||
# On Windows, SDL already provides everything, so no need to do anything
|
||||
find_package(X11)
|
||||
target_link_libraries(code PUBLIC ${X11_LIBRARIES})
|
||||
ENDIF()
|
||||
target_link_libraries(code PUBLIC imgui)
|
||||
|
||||
# Headers for standalone "gui" on UNIX
|
||||
IF(UNIX)
|
||||
@@ -111,9 +97,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)
|
||||
@@ -130,8 +123,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)
|
||||
@@ -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>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
+38
-35
@@ -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)
|
||||
@@ -57,6 +56,12 @@ extern const size_t Num_ai_flag_descriptions;
|
||||
#define AIDO_DOCK_NOW 2 // Immediately move into dock position. For ships that start mission docked.
|
||||
#define AIDO_UNDOCK 3 // Set goal of undocking with object.
|
||||
|
||||
// Submodes for seeking safety.
|
||||
#define AISS_1 41 // Pick a spot to fly to.
|
||||
#define AISS_2 42 // Flying to spot.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_1a 44 // Pick a new nearby spot because we are endangered, then go to AISS_2
|
||||
|
||||
// Flags to ai_turn_towards_vector().
|
||||
#define AITTV_FAST (1<<0) // Turn fast, not slowed down based on skill level.
|
||||
#define AITTV_VIA_SEXP (1<<1) // Goober5000 - via sexp
|
||||
@@ -88,7 +93,7 @@ extern const size_t Num_ai_flag_descriptions;
|
||||
#define AIM_BAY_DEPART 18 // Departing to a fighter bay, following path to do so
|
||||
#define AIM_SENTRYGUN 19 // AI mode for sentry guns only (floating turrets)
|
||||
#define AIM_WARP_OUT 20 // Commence warp out sequence. Point in legal direction. Then call John's code.
|
||||
#define AIM_FLY_TO_SHIP 21 // Rendezvous with a ship. Like stay-near, but non-perpetual.
|
||||
#define AIM_FLY_TO_SHIP 21 // [Kazan] Fly to a ship, doesn't matter if it's hostile or friendly -- for Autopilot usage
|
||||
#define AIM_LUA 22 // Generic Lua-based AI mode
|
||||
|
||||
#define MAX_AI_BEHAVIORS 23 // Number of AIM_xxxx types
|
||||
@@ -97,7 +102,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 {
|
||||
@@ -182,12 +186,6 @@ typedef struct ai_class {
|
||||
#define AIS_UNDOCK_3 33
|
||||
#define AIS_UNDOCK_4 34
|
||||
|
||||
// Submodes for seeking safety.
|
||||
#define AISS_1 41 // Pick a spot to fly to.
|
||||
#define AISS_2 42 // Flying to spot.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_1a 44 // Pick a new nearby spot because we are endangered, then go to AISS_2. (Not implemented.)
|
||||
|
||||
// Submodes for Guard behavior
|
||||
#define AIS_GUARD_PATROL 101
|
||||
#define AIS_GUARD_ATTACK 102
|
||||
@@ -242,6 +240,7 @@ typedef struct ai_info {
|
||||
flagset<AI::AI_Flags> ai_flags; // Special flags for AI behavior.
|
||||
int shipnum; // Ship using this slot, -1 means none.
|
||||
|
||||
int behavior; // AI behavior; vestigial field from early development of FS1
|
||||
int mode;
|
||||
int previous_mode;
|
||||
int mode_time; // timestamp at which current mode elapses.
|
||||
@@ -278,8 +277,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
|
||||
size_t 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 +294,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
|
||||
@@ -310,7 +308,6 @@ typedef struct ai_info {
|
||||
fix submode_start_time; // time at which we entered the current submode
|
||||
int submode_parm0; // parameter specific to current submode
|
||||
int submode_parm1; // SUSHI: Another optional parameter
|
||||
float submode_float0; // Goober5000: a float parameter
|
||||
fix next_predict_pos_time; // Next time to predict position.
|
||||
|
||||
int next_dynamic_path_check_time; //ETP: Time of next path check in ai_new_maybe_reposition_attack_subsys
|
||||
@@ -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.
|
||||
@@ -376,6 +373,11 @@ typedef struct ai_info {
|
||||
float ai_turret_max_aim_update_delay;
|
||||
flagset<AI::Profile_Flags> ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
|
||||
|
||||
|
||||
union {
|
||||
float stay_near_distance; // Distance to stay within for AIM_STAY_NEAR mode.
|
||||
};
|
||||
|
||||
ship_subsys* targeted_subsys; // Targeted subobject on current target. NULL if none;
|
||||
ship_subsys* last_subsys_target; // last known subsystem target
|
||||
int targeted_subsys_parent; // Parent objnum of subobject, not necessarily targeted
|
||||
@@ -487,7 +489,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 +497,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,21 +528,21 @@ 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);
|
||||
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);
|
||||
extern void ai_turn_towards_vector(vec3d *dest, object *objp, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = nullptr, vec3d* turnrate_mod = nullptr);
|
||||
extern void init_ai_object(int objnum);
|
||||
extern void ai_init(void); // Call this one to parse ai.tbl.
|
||||
extern void ai_level_init(void); // Call before each level to reset AI
|
||||
@@ -561,9 +563,9 @@ 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 void ai_do_stay_near(object *objp, object *other_obj, float dist);
|
||||
extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
|
||||
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
|
||||
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
|
||||
@@ -598,16 +600,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,11 +620,15 @@ 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);
|
||||
|
||||
// added by kazan
|
||||
void ai_start_fly_to_ship(object *objp, int shipnum);
|
||||
void ai_fly_to_ship();
|
||||
|
||||
//Moved declaration here for player ship -WMC
|
||||
void ai_process_subobjects(int objnum);
|
||||
|
||||
@@ -640,6 +643,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
-56
@@ -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,12 @@ 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 +98,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 +122,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 +134,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 +156,6 @@ 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
|
||||
};
|
||||
|
||||
+19
-218
@@ -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);
|
||||
|
||||
@@ -267,7 +258,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Glide Attack Percent:")) {
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
@@ -280,7 +271,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Circle Strafe Percent:")) {
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
@@ -293,7 +284,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Glide Strafe Percent:")) {
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
@@ -306,7 +297,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
@@ -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);
|
||||
|
||||
@@ -574,9 +552,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
profile->flags.set(AI::Profile_Flags::All_nonshielded_ships_can_manage_ets, temp);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
set_flag(profile, "$no directional bias for missile and ship turning:", AI::Profile_Flags::No_turning_directional_bias);
|
||||
set_flag(profile, "$no directional bias for missile and ship turning:", AI::Profile_Flags::No_turning_directional_bias);
|
||||
|
||||
set_flag(profile, "$respect ship axial turnrate differences:", AI::Profile_Flags::Use_axial_turnrate_differences);
|
||||
|
||||
@@ -586,27 +562,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 +582,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 +623,13 @@ 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 +688,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 +703,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 +710,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 +732,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 +766,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;
|
||||
}
|
||||
|
||||
@@ -984,31 +812,4 @@ void ai_profile_t::reset()
|
||||
if (mod_supports_version(23, 2, 0)) {
|
||||
flags.set(AI::Profile_Flags::Ships_playing_dead_dont_manage_ets);
|
||||
}
|
||||
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
@@ -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
|
||||
+134
-172
@@ -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;
|
||||
@@ -548,15 +538,15 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
model_local_to_global_point(&geye, &ep->pnt, pm, 0, &Pl_objp->orient, &Pl_objp->pos);
|
||||
|
||||
// get world pos of subsystem
|
||||
get_subsystem_pos(&gsubpos, target_objp, aip->targeted_subsys);
|
||||
polymodel* tgt_pm = model_get(Ship_info[Ships[target_objp->instance].ship_info_index].model_num);
|
||||
model_local_to_global_point(&gsubpos, &vmd_zero_vector, tgt_pm, aip->targeted_subsys->system_info->subobj_num, &En_objp->orient, &En_objp->pos);
|
||||
|
||||
// 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
|
||||
vec3d* good_pos = nullptr;
|
||||
vec3d world_goal_pos;
|
||||
// For performance reasons we only recheck once a second, otherwise we reuse the last found target.
|
||||
if (timestamp_elapsed(aip->next_dynamic_path_check_time)) {
|
||||
vec3d tgt2pl = Pl_objp->pos - target_objp->pos;
|
||||
@@ -578,6 +568,7 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
vm_rot_point_around_line(&goal_pos, &tgt2pl, angle2goal, &vmd_zero_vector, &cross);
|
||||
|
||||
// then scale in (or out) towards our subsys
|
||||
vec3d world_goal_pos;
|
||||
float new_radius = ((subsys_dist - pl_dist) * (angle2goal / angle2subsys)) + pl_dist;
|
||||
vm_vec_copy_scale(&world_goal_pos, &goal_pos, new_radius / pl_dist);
|
||||
world_goal_pos += target_objp->pos;
|
||||
@@ -716,8 +707,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 +720,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 +864,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 +914,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_DISARM_SHIP))) {
|
||||
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_DISARM_SHIP)) && 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 +1007,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 +1035,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 +1107,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 +1194,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 +1416,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 +1424,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 +1486,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 +1569,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 +1607,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 +1617,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 +1642,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 +1692,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 +1842,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
|
||||
Int3(); // what is going on here? - Get Alan
|
||||
aip->mode = AIM_NONE;
|
||||
return;
|
||||
}
|
||||
@@ -1924,7 +1888,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 +1934,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
@@ -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()
|
||||
|
||||
+594
-1248
File diff suppressed because it is too large.
Load diff
Whitespace-only changes.
+363
-646
File diff suppressed because it is too large.
Load diff
+72
-89
@@ -24,92 +24,79 @@ 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) // 0x03000000
|
||||
#define AI_GOAL_LUA (1<<27) // 0x04000000
|
||||
|
||||
// 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_DISARM_SHIP | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_BOMBER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_STEALTH ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_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 +108,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 +142,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 +166,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, 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, 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, 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, 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 +191,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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
+6
-169
@@ -18,9 +18,9 @@ void ai_lua_add_mode(int sexp_op, const ai_mode_lua& mode) {
|
||||
}
|
||||
|
||||
bool ai_lua_add_order(int sexp_op, player_order_lua order) {
|
||||
Player_orders.emplace_back(order.parseText, order.displayText, -1, sexp_op);
|
||||
Player_orders.emplace_back(vm_strdup(order.parseText.c_str()), vm_strdup(order.displayText.c_str()), -1, sexp_op);
|
||||
Player_orders.back().localize();
|
||||
|
||||
|
||||
Lua_player_orders.emplace(sexp_op, std::move(order));
|
||||
|
||||
return true;
|
||||
@@ -48,140 +48,6 @@ const player_order_lua* ai_lua_find_player_order(int sexp_op) {
|
||||
return &aiLuaOrder->second;
|
||||
}
|
||||
|
||||
int ai_lua_get_num_general_orders() {
|
||||
int count = 0;
|
||||
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
if (order.second.generalOrder) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
SCP_vector<SCP_string> ai_lua_get_general_order_categories(bool enabled_only)
|
||||
{
|
||||
SCP_vector<SCP_string> list;
|
||||
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
const SCP_string &cat = order.second.category;
|
||||
|
||||
// If it's not a general order then move on
|
||||
if (!order.second.generalOrder) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the order is not enabled then move on
|
||||
if (enabled_only && !order.second.cur_enabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Assertion((cat.length() > 0), "Lua general orders category name must be longer than 0 characters!");
|
||||
|
||||
for (size_t i = 0; i <= list.size(); i++) {
|
||||
|
||||
// reached the end of the list, so add it
|
||||
if (i == list.size()) {
|
||||
list.push_back(cat);
|
||||
break;
|
||||
}
|
||||
|
||||
// if it's already in the list then don't add it
|
||||
if (cat == list[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// Provides a list of general orders for mission saving. You can only get one kind
|
||||
// of list at a time. If onlyEnabled and onlyValid are both true, for example, you will get
|
||||
// a list of onlyEnabled orders. If you need a list of enabled orders that are also valid, you'll
|
||||
// need to get both lists separately and compare.
|
||||
SCP_vector<SCP_string> ai_lua_get_general_orders(bool onlyEnabled, bool onlyValid, const SCP_string& category)
|
||||
{
|
||||
SCP_vector<SCP_string> list;
|
||||
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
if (order.second.generalOrder) {
|
||||
bool add = false;
|
||||
|
||||
// All general orders
|
||||
if (!onlyEnabled && !onlyValid && category.empty()) {
|
||||
add = true;
|
||||
} else {
|
||||
|
||||
// Only enabled orders
|
||||
if (onlyEnabled && order.second.cur_enabled) {
|
||||
add = true;
|
||||
|
||||
// Only valid orders
|
||||
} else if (onlyValid && order.second.cur_valid) {
|
||||
add = true;
|
||||
|
||||
// Only orders that match the category requested
|
||||
} else if ((!category.empty()) && (order.second.category == category)) {
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
list.push_back(order.second.parseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int ai_lua_find_general_order_id(const SCP_string& name) {
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
if (order.second.parseText == name) {
|
||||
return order.first;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ai_lua_enable_general_order(int sexp_op, bool enable) {
|
||||
auto aiLuaOrder = Lua_player_orders.find(sexp_op);
|
||||
|
||||
if (aiLuaOrder == Lua_player_orders.end())
|
||||
return;
|
||||
else
|
||||
aiLuaOrder->second.cur_enabled = enable;
|
||||
}
|
||||
|
||||
void ai_lua_validate_general_order(int sexp_op, bool validity)
|
||||
{
|
||||
auto aiLuaOrder = Lua_player_orders.find(sexp_op);
|
||||
|
||||
if (aiLuaOrder == Lua_player_orders.end())
|
||||
return;
|
||||
else
|
||||
aiLuaOrder->second.cur_valid = validity;
|
||||
}
|
||||
|
||||
void ai_lua_reset_general_orders() {
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
ai_lua_enable_general_order(order.first, false);
|
||||
ai_lua_validate_general_order(order.first, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool ai_lua_is_general_order(int sexp_op) {
|
||||
auto aiLuaOrder = Lua_player_orders.find(sexp_op);
|
||||
|
||||
if (aiLuaOrder == Lua_player_orders.end())
|
||||
return false;
|
||||
|
||||
return aiLuaOrder->second.generalOrder;
|
||||
}
|
||||
|
||||
void run_ai_lua_action(const luacpp::LuaFunction& action, const ai_mode_lua& lua_ai, ai_info* aip) {
|
||||
if (!action.isValid()) {
|
||||
Error(LOCATION,
|
||||
@@ -190,11 +56,7 @@ void run_ai_lua_action(const luacpp::LuaFunction& action, const ai_mode_lua& lua
|
||||
}
|
||||
|
||||
luacpp::LuaValueList luaParameters;
|
||||
if (aip->shipnum >= 0){
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_AI_Helper.Set(object_h(&Objects[Ships[aip->shipnum].objnum]))));
|
||||
} else {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_AI_Helper.Set(object_h())));
|
||||
}
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_AI_Helper.Set(object_h(&Objects[Ships[aip->shipnum].objnum]))));
|
||||
if (lua_ai.needsTarget) {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(aip->lua_ai_target.target)));
|
||||
}
|
||||
@@ -205,13 +67,8 @@ void run_ai_lua_action(const luacpp::LuaFunction& action, const ai_mode_lua& lua
|
||||
auto retVals = action.call(Script_system.GetLuaSession(), luaParameters);
|
||||
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::BOOLEAN) {
|
||||
if (retVals[0].getValue<bool>()) {
|
||||
|
||||
// If we don't have a ship then it's a general order and we have nothing else to do
|
||||
if (aip->shipnum >= 0) {
|
||||
ai_mission_goal_complete(aip);
|
||||
}
|
||||
}
|
||||
if (retVals[0].getValue<bool>())
|
||||
ai_mission_goal_complete(aip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,26 +103,6 @@ void ai_lua_start(ai_goal* aigp, object* objp){
|
||||
run_ai_lua_action(action, lua_ai, aip);
|
||||
}
|
||||
|
||||
// For sending general orders that don't run on a ship.
|
||||
// Essentially just runs arbitrary lua script when the command is called
|
||||
void ai_lua_start_general(int lua_sexp_id, int target_objnum)
|
||||
{
|
||||
//Create a dummy aip to pass the target data
|
||||
ai_info aip;
|
||||
aip.shipnum = -1;
|
||||
|
||||
if (target_objnum >= 0 && Objects[target_objnum].type == OBJ_SHIP) {
|
||||
aip.lua_ai_target = {object_ship_wing_point_team(&Ships[Objects[target_objnum].instance]), {}};
|
||||
}
|
||||
|
||||
const auto& lua_ai = ai_lua_find_mode(lua_sexp_id);
|
||||
|
||||
const auto& lua_ai_sexp = lua_ai->sexp;
|
||||
const auto& action = lua_ai_sexp.getActionEnter();
|
||||
|
||||
run_ai_lua_action(action, *lua_ai, &aip);
|
||||
}
|
||||
|
||||
bool ai_lua_is_valid_target_intrinsic(int sexp_op, int target_objnum, ship* self) {
|
||||
ship* target = &Ships[Objects[target_objnum].instance];
|
||||
|
||||
@@ -389,7 +226,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;
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@ struct player_order_lua {
|
||||
int ai_message = MESSAGE_YESSIR;
|
||||
SCP_string parseText = "";
|
||||
SCP_string displayText = "";
|
||||
bool generalOrder = false;
|
||||
SCP_string category = "";
|
||||
bool cur_enabled = false;
|
||||
bool cur_valid = false;
|
||||
enum class target_restrictions : int { TARGET_ALLIES, TARGET_ALL, TARGET_OWN, TARGET_ENEMIES, TARGET_SAME_WING, TARGET_PLAYER_WING, TARGET_ALL_CAPS, TARGET_ALLIED_CAPS, TARGET_ENEMY_CAPS, TARGET_NOT_SELF } targetRestrictions = target_restrictions::TARGET_ALL;
|
||||
enum class ship_restrictions : int { ANY, WING, IN_PLAYER_WING, PLAYER_WING } shipRestrictions = ship_restrictions::ANY;
|
||||
};
|
||||
@@ -33,17 +29,8 @@ bool ai_lua_add_order(int sexp_op, player_order_lua order);
|
||||
bool ai_lua_has_mode(int sexp_op);
|
||||
const ai_mode_lua* ai_lua_find_mode(int sexp_op);
|
||||
const player_order_lua* ai_lua_find_player_order(int sexp_op);
|
||||
SCP_vector<SCP_string> ai_lua_get_general_order_categories(bool enabled_only = true);
|
||||
int ai_lua_get_num_general_orders();
|
||||
SCP_vector<SCP_string> ai_lua_get_general_orders(bool onlyEnabled = false, bool onlyValid = false, const SCP_string& category = "");
|
||||
int ai_lua_find_general_order_id(const SCP_string& name);
|
||||
void ai_lua_enable_general_order(int sexp_op, bool enable);
|
||||
void ai_lua_validate_general_order(int sexp_op, bool validity);
|
||||
void ai_lua_reset_general_orders();
|
||||
bool ai_lua_is_general_order(int sexp_op);
|
||||
void ai_lua(ai_info* aip);
|
||||
void ai_lua_start(ai_goal* aigp, object* objp);
|
||||
void ai_lua_start_general(int lua_sexp_id, int target_objnum);
|
||||
bool ai_lua_is_valid_target(int sexp_op, int target_objnum, ship* self, size_t order);
|
||||
bool ai_lua_is_valid_ship(int sexp_op, bool isWing, ship* self);
|
||||
ai_achievability ai_lua_is_achievable(const ai_goal* aigp, int objnum);
|
||||
+478
-493
File diff suppressed because it is too large.
Load diff
+18
-7
@@ -667,10 +667,12 @@ void anim_read_header(anim *ptr, CFILE *fp)
|
||||
*
|
||||
* @param real_filename Filename of animation
|
||||
* @param cf_dir_type
|
||||
*
|
||||
* @return Pointer to anim that is loaded if success, NULL if failure.
|
||||
* @param file_mapped Whether to use memory-mapped file or not.
|
||||
*
|
||||
* @details Memory-mapped files will page in the animation from disk as it is needed, but performance is not as good.
|
||||
* @return Pointer to anim that is loaded if sucess, NULL if failure.
|
||||
*/
|
||||
anim *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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+13
-21
@@ -22,19 +22,19 @@ anim_instance *init_anim_instance(anim *ptr, int bpp)
|
||||
{
|
||||
anim_instance *inst;
|
||||
|
||||
Assertion(ptr, "Bad pointer in init_anim_instance(), please report to the SCP!");
|
||||
if (!ptr) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( ptr->flags & ANF_STREAMED ) {
|
||||
Assertion(ptr->file_offset > -1, "Bad file offset of %d in init_anim_instance(), please report to the SCP!", ptr->file_offset);
|
||||
if ( ptr->file_offset < 0 ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
Assertion(ptr->data, "Bad data in init_anim_instance(), please report to the SCP!");
|
||||
if ( !ptr->data ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+263
-467
File diff suppressed because it is too large.
Load diff
+25
-52
@@ -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,22 +54,15 @@ 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
|
||||
int damage_type_idx; //Damage type of the asteroid
|
||||
int damage_type_idx_sav; // stored value from table used to reset damage_type_idx
|
||||
float inner_rad; // radius within which maximum area effect damage is applied
|
||||
@@ -80,25 +71,30 @@ 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),
|
||||
: type(ASTEROID_TYPE_DEBRIS), num_detail_levels(0), max_speed(0), damage_type_idx(0),
|
||||
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
|
||||
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
|
||||
fireball_radius_multiplier( -1 ), 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 +103,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 +129,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 +141,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 +163,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 +178,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);
|
||||
|
||||
@@ -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
|
||||
@@ -874,17 +869,17 @@ void EndAutoPilot()
|
||||
Assert( CurrentNav >= 0 );
|
||||
|
||||
int goal = 0;
|
||||
const char *goal_name = NULL;
|
||||
char *goal_name = NULL;
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
-171
@@ -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
|
||||
@@ -438,7 +425,6 @@ DCF(bm_used, "Shows BmpMan Slot Usage") {
|
||||
|
||||
SCP_stringstream text;
|
||||
text << "BmpMan Used Slots\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << none << ", NONE\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << pcx << ", PCX\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << user << ", User\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << tga << ", TGA\n";
|
||||
@@ -611,8 +597,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 recieved for 3D Bitmap creation!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -652,7 +638,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 +900,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 +1022,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 +1058,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 +1151,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 +1184,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 +1364,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 +1393,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 +1485,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 +1944,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 +2041,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 +2167,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 +2217,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 +2281,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 +2328,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 +2373,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 +2418,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 +2477,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 +2770,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 +2815,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 +3400,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
|
||||
}
|
||||
Loaded 100 of 3027 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user