diff --git a/.github/actions/build-lin/README.md b/.github/actions/build-lin/README.md index ed6a3342..355d9c11 100644 --- a/.github/actions/build-lin/README.md +++ b/.github/actions/build-lin/README.md @@ -1,13 +1,13 @@ # build-lin -This is a custom GitHub action to build an X-Plane plugin on Linux based on a prepared CMake setup. +This is a custom GitHub action to build a library on Linux based on a prepared CMake setup. ## Parameters Parameter|Requied|Default|Description ---------|-------|-------|------------ -`pluginName`|yes||Plugin's name, used both as top-level folder name and as file name as required by X-Plane -`archFolder`|yes|`lin_x64`|Subfolder in which the executable is placed, is based on architecture like 'lin_x64' +`libName`|yes | |Library's name, used as file name +`flags` |no | |Flags to be passed to CMake ## What it does @@ -19,4 +19,4 @@ Parameter|Requied|Default|Description Output|Description ------|----------- -`xpl-file-name`|path to the produced xpl file +`lib-file-name`|path to the produced library diff --git a/.github/actions/build-lin/action.yml b/.github/actions/build-lin/action.yml index 24957ffe..94230501 100644 --- a/.github/actions/build-lin/action.yml +++ b/.github/actions/build-lin/action.yml @@ -1,20 +1,19 @@ name: Build Linux / CMake -description: Build on Linux based on a CMake setup +description: Build library on Linux based on a CMake setup author: TwinFan inputs: - pluginName: - description: "Plugin's name, used both as top-level folder name and as file name as required by X-Plane" + libName: + description: "Library's name, used as file name" required: true - archFolder: - description: "Subfolder in which the executable is placed, is based on architecture like 'lin_x64'" - required: true - default: lin_x64 + flags: + description: "Flags to be passed to CMake" + required: false outputs: - xpl-file-name: - description: Path to the resulting xpl file - value: ${{ steps.return.outputs.xpl-file-name }} + lib-file-name: + description: Path to the resulting lib file + value: ${{ steps.return.outputs.lib-file-name }} runs: using: "composite" @@ -33,25 +32,25 @@ runs: run: | cd build-lin pwd - cmake -G Ninja .. + cmake -G Ninja ${{ inputs.flags }} .. - name: Build shell: bash run: | cd build-lin pwd - ninja XPMP2 XPMP2-Sample XPMP2-Remote + ninja - name: Test for Target shell: bash env: - TARGET_XPL: build-lin/${{ inputs.archFolder }}/${{ inputs.pluginName }}.xpl + TARGET_LIB: build-lin/lib${{ inputs.libName }}.a run: | - if [[ ! -f "$TARGET_XPL" ]]; then - echo Expected target build not found: "$TARGET_XPL" + if [[ ! -f "$TARGET_LIB" ]]; then + echo Expected target build not found: "$TARGET_LIB" exit 1 fi - name: Return Value id: return shell: bash env: - TARGET_XPL: build-lin/${{ inputs.archFolder }}/${{ inputs.pluginName }}.xpl - run: echo "::set-output name=xpl-file-name::$(echo $TARGET_XPL)" + TARGET_LIB: build-lin/lib${{ inputs.libName }}.a + run: echo "lib-file-name=$(echo $TARGET_LIB)" >> $GITHUB_OUTPUT diff --git a/.github/actions/build-mac/README.md b/.github/actions/build-mac/README.md index 0ed2cf8b..4e1e0a11 100644 --- a/.github/actions/build-mac/README.md +++ b/.github/actions/build-mac/README.md @@ -1,22 +1,23 @@ # build-mac -This is a custom GitHub action to build an X-Plane plugin on and for MacOS based on a prepared CMake setup. +This is a custom GitHub action to build a framwork for MacOS based on a prepared CMake setup. ## Inputs Parameter|Requied|Default|Description ---------|-------|-------|------------ -`pluginName`|yes||Plugin's name, used both as top-level folder name and as file name as required by X-Plane -`archFolder`|yes|`mac_x64`|Subfolder in which the executable is placed, is based on architecture like 'mac_x64' +`libName`|yes | |Library's name, used as file name +`flags` |no | |Flags to be passed to CMake ## What it does - Installs Ninja - Creates build folder `build-mac` - There, runs `cmake`, then `ninja` to build +- Zips the framework, including the `-y` parameter to preserve symlinks ## Outputs Output|Description ------|----------- -`xpl-file-name`|path to the produced xpl file +`lib-file-name`|path to the produced zip archive of the framework diff --git a/.github/actions/build-mac/action.yml b/.github/actions/build-mac/action.yml index e34b65e6..36342d90 100644 --- a/.github/actions/build-mac/action.yml +++ b/.github/actions/build-mac/action.yml @@ -3,18 +3,17 @@ description: Build a MacOS plugin based on a CMake setup author: TwinFan inputs: - pluginName: - description: "Plugin's name, used both as top-level folder name and as file name as required by X-Plane" + libName: + description: "Library's name, used both as top-level folder name and as file name as required by X-Plane" required: true - archFolder: - description: "Subfolder in which the executable is placed, is based on architecture like 'mac_x64'" - required: true - default: mac_x64 + flags: + description: "Flags to be passed to CMake" + required: false outputs: - xpl-file-name: - description: Path to the resulting xpl file - value: ${{ steps.return.outputs.xpl-file-name }} + lib-file-name: + description: Path to the resulting lib file + value: ${{ steps.return.outputs.lib-file-name }} runs: using: "composite" @@ -32,25 +31,27 @@ runs: run: | cd build-mac pwd - cmake -G Ninja .. + cmake -G Ninja ${{ inputs.flags }} .. - name: Build shell: bash run: | cd build-mac pwd - ninja XPMP2 XPMP2-Sample XPMP2-Remote - - name: Test for Target + ninja + - name: Test for and Zip Framework shell: bash env: - TARGET_XPL: build-mac/${{ inputs.archFolder }}/${{ inputs.pluginName }}.xpl + TARGET_LIB: build-mac/${{ inputs.libName }}.framework run: | - if [[ ! -f "$TARGET_XPL" ]]; then - echo Expected target build not found: "$TARGET_XPL" + if [[ ! -d "$TARGET_LIB" ]]; then + echo Expected target build not found: "$TARGET_LIB" exit 1 fi + cd build-mac + zip -9ry ${{ inputs.libName }}.framework.zip ${{ inputs.libName }}.framework - name: Return Value id: return shell: bash env: - TARGET_XPL: build-mac/${{ inputs.archFolder }}/${{ inputs.pluginName }}.xpl - run: echo "::set-output name=xpl-file-name::$(echo $TARGET_XPL)" + TARGET_ZIP: build-mac/${{ inputs.libName }}.framework.zip + run: echo "lib-file-name=$(echo $TARGET_ZIP)" >> $GITHUB_OUTPUT diff --git a/.github/actions/build-win/README.md b/.github/actions/build-win/README.md index 0ed2cf8b..09cac992 100644 --- a/.github/actions/build-win/README.md +++ b/.github/actions/build-win/README.md @@ -1,22 +1,22 @@ -# build-mac +# build-win -This is a custom GitHub action to build an X-Plane plugin on and for MacOS based on a prepared CMake setup. +This is a custom GitHub action to build a library on and for Windows based on a prepared CMake setup. ## Inputs Parameter|Requied|Default|Description ---------|-------|-------|------------ -`pluginName`|yes||Plugin's name, used both as top-level folder name and as file name as required by X-Plane -`archFolder`|yes|`mac_x64`|Subfolder in which the executable is placed, is based on architecture like 'mac_x64' +`libName`|yes | |Library's name, used as file name +`flags` |no | |Flags to be passed to CMake ## What it does -- Installs Ninja -- Creates build folder `build-mac` -- There, runs `cmake`, then `ninja` to build +- Runs a separate command file, `build-win.cmd`, which in tun +- Creates build folder `build-win` +- There, runs `CMAKE`, then `NMAKE` to build ## Outputs Output|Description ------|----------- -`xpl-file-name`|path to the produced xpl file +`lib-file-name`|path to the produced lib file diff --git a/.github/actions/build-win/action.yml b/.github/actions/build-win/action.yml index 63129f0d..02ad4289 100644 --- a/.github/actions/build-win/action.yml +++ b/.github/actions/build-win/action.yml @@ -1,45 +1,38 @@ name: Build Windows / MSVC / CMake -description: Build a Windows plugin with MS Visual Studio based on a CMake setup +description: Build a Windows library with MS Visual Studio based on a CMake setup author: TwinFan inputs: - pluginName: - description: "Plugin's name, used both as top-level folder name and as file name as required by X-Plane" + libName: + description: "Library's name, used as file name" required: true - archFolder: - description: "Subfolder in which the executable is placed, is based on architecture like 'win_x64'" - required: true - default: win_x64 + flags: + description: "Flags to be passed to CMake" + required: false outputs: - xpl-file-name: - description: Path to the resulting xpl file - value: ${{ steps.return.outputs.xpl-file-name }} - pdb-file-name: - description: Path to the resulting pdb file (debug symbol info) - value: ${{ steps.return.outputs.pdb-file-name }} + lib-file-name: + description: Path to the resulting lib + value: ${{ steps.return.outputs.lib-file-name }} runs: using: "composite" steps: - name: Build shell: cmd - run: ${{ github.action_path }}\build-win.cmd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise" build-win + run: ${{ github.action_path }}\build-win.cmd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise" build-win "${{ inputs.flags }}" - name: Test for Target shell: bash env: - TARGET_XPL: build-win/${{ inputs.archFolder }}/${{ inputs.pluginName }}.xpl + TARGET_LIB: build-win/${{ inputs.libName }}.lib run: | - if [[ ! -f "$TARGET_XPL" ]]; then - echo Expected target build not found: "$TARGET_XPL" + if [[ ! -f "$TARGET_LIB" ]]; then + echo Expected target build not found: "$TARGET_LIB" exit 1 fi - name: Return Value id: return shell: bash env: - TARGET_XPL: build-win/${{ inputs.archFolder }}/${{ inputs.pluginName }}.xpl - TARGET_PDB: build-win/${{ inputs.archFolder }}/${{ inputs.pluginName }}.pdb - run: | - echo "::set-output name=xpl-file-name::$(echo $TARGET_XPL)" - echo "::set-output name=pdb-file-name::$(echo $TARGET_PDB)" + TARGET_LIB: build-win/${{ inputs.libName }}.lib + run: echo "lib-file-name=$(echo $TARGET_LIB)" >> $GITHUB_OUTPUT diff --git a/.github/actions/build-win/build-win.cmd b/.github/actions/build-win/build-win.cmd index d580408a..4bf36ac8 100644 --- a/.github/actions/build-win/build-win.cmd +++ b/.github/actions/build-win/build-win.cmd @@ -1,6 +1,7 @@ @ECHO OFF REM We expect 2 parameters +REM Additional parameters are passed through to CMake IF "%~1"=="" GOTO :PRINT_HELP IF "%~2"=="" GOTO :PRINT_HELP @@ -20,11 +21,11 @@ PUSHD "%MY_BUILD_DIR%" IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% REM Create Makefile from CMakeLists.txt, using NMake output beacause NMake happens to be available -CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" -DCMAKE_MAKE_PROGRAM="nmake.exe" -DCMAKE_TOOLCHAIN_FILE="..\docker\Toolchain-msvc-x86-64.cmake" .. +CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" -DCMAKE_MAKE_PROGRAM="nmake.exe" -DCMAKE_TOOLCHAIN_FILE="..\docker\Toolchain-msvc-x86-64.cmake" %~3 %~4 %~5 .. IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% REM Perform the actual build -NMAKE /A XPMP2 XPMP2-Sample XPMP2-Remote +NMAKE /A IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% ECHO Windows Build: SUCCESS! diff --git a/.github/actions/sign-notarize/README.md b/.github/actions/sign-notarize/README.md deleted file mode 100644 index 0bf799fc..00000000 --- a/.github/actions/sign-notarize/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# sign-notarize - -This is a custom GitHub action to sign and then notarize a MacOS X-Plane plugin. -It waits for Apple's answer to notarization, which can take a couple of minutes! - -## Inputs - -Parameter|Requied|Default|Description ----------|-------|-------|------------ -`xplFileName`|yes||Path to just built xpl plugin -`certificate`|yes||Base64 encoded .p12 certificate file -`certPwd`|yes||Password of the .p12 certificate file -`notarizeUser`|yes||Apple ID for notarization service (parameter `--apple-id` to `notarytool`) -`notarizeTeam`|yes||Team ID for notarization service (parameter `--team-id` to `notarytool`) -`notarizeAppPwd`|yes||[App-specific password](https://support.apple.com/en-gb/HT204397) for notarization service (parameter `--password` to `notarytool`) - -## What it does - -All actions are performed by script `sign-notarize`, which -- Creates a temporary keychain to store the passed-in certificate -- Signs the file provided in `xplFileName` -- Zips the file and sends it to Apple's notarization service -- Waits for notarization to finish, which can take a few minutes diff --git a/.github/actions/sign-notarize/action.yml b/.github/actions/sign-notarize/action.yml deleted file mode 100644 index e7fd4e63..00000000 --- a/.github/actions/sign-notarize/action.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Sign/Notarize MacOS plugin -description: Signs, then notarizes the plugin -author: TwinFan - -inputs: - xplFileName: - description: "Path to just built xpl plugin" - required: true - certificate: - description: "Base64 encoded .p12 certificate file" - required: true - certPwd: - description: "Password of the .p12 certificate file" - required: true - notarizeUser: - description: "Apple-ID for notarization" - required: true - notarizeTeam: - description: "Team-ID for notarization" - required: true - notarizeAppPwd: - description: "App-specific password for notarization" - required: true - -runs: - using: "composite" - steps: - - name: Sign and Notarize # is actually all in a shell script - shell: bash - run: | - echo ${{ inputs.certificate }} | base64 --decode > certificate.p12 - chmod a+x ${{ github.action_path }}/sign-notarize - ${{ github.action_path }}/sign-notarize "${{ inputs.xplFileName }}" certificate.p12 "${{ inputs.certPwd }}" "${{ inputs.notarizeUser }}" "${{ inputs.notarizeTeam }}" "${{ inputs.notarizeAppPwd }}" diff --git a/.github/actions/sign-notarize/sign-notarize b/.github/actions/sign-notarize/sign-notarize deleted file mode 100755 index 59793698..00000000 --- a/.github/actions/sign-notarize/sign-notarize +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh -# Signs and notarizes a MacOS build -# -# Parameters -# 1. Path to file to sign, then notarize -# 2. Signing ID file like 'certificate.p12' -# 3. Password for above p12 file -# 4. Apple ID for notarization (parameter --apple-id to notarytool) -# 5. Team ID for notarization (parmeter --team-id to notarytool) -# 6. App-specific password for notarization (parameter --password to notarytool) - -set -eu - -# --- Cleanup in case of faulty exit - -function cleanup { - echo ">>> Cleanup <<<" - security delete-keychain build.keychain -} - -# ================================================================== -# Read parameters - -if (( $# < 6 )) -then - echo "$0 requires 6 parameters, check script!" - exit 1 -fi - -PATH_TO_FILE=$1 -SIGN_ID_FILE=$2 -SIGN_ID_PWD=$3 -NOTAR_USER=$4 -NOTAR_TEAM=$5 -NOTAR_PWD=$6 - -# --- Sign - -echo . -echo "--- Sign ---" -echo . - -# Taken from https://localazy.com/blog/how-to-automatically-sign-macos-apps-using-github-actions -# Create a temporary keychain and import the given certificate -security create-keychain -p NotSoSecretAPwd build.keychain -trap cleanup EXIT # Make sure the keychain gets removed in case of failure exit -security default-keychain -s build.keychain -security unlock-keychain -p NotSoSecretAPwd build.keychain -security import "$SIGN_ID_FILE" -P "$SIGN_ID_PWD" -k build.keychain -T /usr/bin/codesign -# Allow some tools to use the keychain -security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k NotSoSecretAPwd build.keychain -# Actually sign -security find-identity -v build.keychain -export MACOS_IDENTITY=`security find-identity -v build.keychain | egrep -o '[0-9A-F]{40}'` -echo MACOS_IDENTITY = $MACOS_IDENTITY -codesign --force --keychain build.keychain -s $MACOS_IDENTITY "$PATH_TO_FILE" -v -codesign --verify --verbose "$PATH_TO_FILE" - -# --- Notarize LiveTraffic and XPMP2-Remote --- - -echo . -echo "--- Notarize ---" -echo . - -# Can only send zip archives to notarization -zip -v "$PATH_TO_FILE.zip" "$PATH_TO_FILE" -xcrun notarytool submit --wait --apple-id "$NOTAR_USER" --password "$NOTAR_PWD" --team-id "$NOTAR_TEAM" "$PATH_TO_FILE.zip" -rm "$PATH_TO_FILE.zip" - -# Note: No stapling possible to .xpl files - -echo . -echo "*** SIGNED and NOTARIZED ***" -exit 0 \ No newline at end of file diff --git a/.github/actions/upload-plugin/README.md b/.github/actions/upload-plugin/README.md deleted file mode 100644 index 009d501d..00000000 --- a/.github/actions/upload-plugin/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# upload-plugin - -This is a custom GitHub action to upload a just built X-Plane plugin to Github's artifacts for later deployment or download. - -## Parameters - -Parameter|Requied|Default|Description ----------|-------|-------|------------ -`pluginName`|yes||Plugin's name, used both as top-level folder name and as file name as required by X-Plane -`archFolder`|yes||Subfolder in which the executable is placed, is based on architecture like 'lin_x64' -`xplFileName`|yes||Path to the just built xpl file - -## What it does - -- Organizes the produced plugin in the correct folder structure for deployment -- and adds it to artifacts. \ No newline at end of file diff --git a/.github/actions/upload-plugin/action.yml b/.github/actions/upload-plugin/action.yml deleted file mode 100644 index 6d74b1e3..00000000 --- a/.github/actions/upload-plugin/action.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Upload Plugin -description: Organizes plugin files in correct structure, then uploads as artifact -author: TwinFan - -inputs: - pluginName: - description: "Plugin's name, used both as top-level folder name and as file name as required by X-Plane" - required: true - archFolder: - description: "Subfolder in which the executable is placed, is based on architecture like 'lin_x64'" - required: true - xplFileName: - description: "Path to just built xpl plugin" - required: true - pdbFileName: - description: "Path to just built pdb file" - required: false - -runs: - using: "composite" - steps: - - name: Prepare Deployment Structure # moves the plugin, like "build-lin/lin_x64/MyPlugin.xpl", to a deployment structure like "deploy-MyPlugin/MyPlugin/lin_x64/MyPlugin.xpl" - shell: bash - run: | - mkdir -p "deploy-${{ inputs.pluginName }}/${{ inputs.pluginName }}/${{ inputs.archFolder }}" - mv "${{ inputs.xplFileName }}" "deploy-${{ inputs.pluginName }}/${{ inputs.pluginName }}/${{ inputs.archFolder }}" - if [[ -n "${{ inputs.pdbFileName }}" ]]; then - mv "${{ inputs.pdbFileName }}" "deploy-${{ inputs.pluginName }}/${{ inputs.pluginName }}/${{ inputs.archFolder }}" - fi - - name: Upload plugin - uses: actions/upload-artifact@v2 - with: - name: ${{ inputs.pluginName }} - path: deploy-${{ inputs.pluginName }}/* # this way the top folder in the artifacts is "MyPlugin" - if-no-files-found: error diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0fe03816..1ee40d6c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,11 +4,17 @@ on: push: pull_request: branches: [ main ] - workflow_dispatch: # Can also be called manually for whatever reason + workflow_dispatch: # Can also be called manually for whatever reason, e.g. if wanting to build with FMOD sound + inputs: + flags: + description: "Flags to be passed to CMake" + required: false + type: string + default: '-DINCLUDE_FMOD_SOUND=1' # Let's set all project specific definitions globally env: - PRJ_NAME: XPMP2-Remote # The plugin's name, expected to be the .xpl file's name and used as the plugin folder name + PRJ_NAME: XPMP2 jobs: ##################################### @@ -17,32 +23,21 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v2 # must checkout before we can use our own actions + uses: actions/checkout@v3 # must checkout before we can use our own actions - name: Build uses: ./.github/actions/build-lin id: build with: - pluginName: ${{ env.PRJ_NAME }} - - name: Upload XPMP2-Remote - uses: ./.github/actions/upload-plugin - with: - pluginName: ${{ env.PRJ_NAME }} - archFolder: lin_x64 - xplFileName: "${{ steps.build.outputs.xpl-file-name }}" - - name: Upload XPMP2-Sample - uses: ./.github/actions/upload-plugin - with: - pluginName: XPMP2-Sample - archFolder: lin_x64 - xplFileName: "./build-lin/lin_x64/XPMP2-Sample.xpl" + libName: ${{ env.PRJ_NAME }} + flags: ${{ inputs.flags }} - name: Prepare XPMP2 lib shell: bash run: | mkdir -p deploy-lib/lib/lin cp -a ./inc deploy-lib - mv ./build-lin/libXPMP2.a deploy-lib/lib/lin + mv ${{ steps.build.outputs.lib-file-name }} deploy-lib/lib/lin - name: Upload XPMP2 lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: XPMP2-lib path: deploy-lib/* # this way we keep the folder structure in the artifact @@ -54,52 +49,20 @@ jobs: runs-on: macos-latest steps: - name: Checkout Code - uses: actions/checkout@v2 # must checkout before we can use our own actions + uses: actions/checkout@v3 # must checkout before we can use our own actions - name: Build uses: ./.github/actions/build-mac id: build with: - pluginName: ${{ env.PRJ_NAME }} - - name: Check if Secrets available - id: checksecrets - env: - MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} - shell: bash - run: | - if [ "$MACOS_CERTIFICATE" == "" ]; then - echo ::set-output name=secretspresent:: - else - echo ::set-output name=secretspresent::true - fi - - name: Codesign and Notarization - if: ${{ steps.checksecrets.outputs.secretspresent }} - uses: ./.github/actions/sign-notarize - with: - xplFileName: ${{ steps.build.outputs.xpl-file-name }} - certificate: ${{ secrets.MACOS_CERTIFICATE }} - certPwd: ${{ secrets.MACOS_CERT_PWD }} - notarizeUser: ${{ secrets.NOTARIZATION_USERNAME }} - notarizeTeam: ${{ secrets.NOTARIZATION_TEAM }} - notarizeAppPwd: ${{ secrets.NOTARIZATION_PASSWORD }} - - name: Upload XPMP2-Remote - uses: ./.github/actions/upload-plugin - with: - pluginName: ${{ env.PRJ_NAME }} - archFolder: mac_x64 - xplFileName: ${{ steps.build.outputs.xpl-file-name }} - - name: Upload XPMP2-Sample - uses: ./.github/actions/upload-plugin - with: - pluginName: XPMP2-Sample - archFolder: mac_x64 - xplFileName: "./build-mac/mac_x64/XPMP2-Sample.xpl" + libName: ${{ env.PRJ_NAME }} + flags: ${{ inputs.flags }} - name: Prepare XPMP2 Framework shell: bash run: | mkdir -p deploy-lib/lib - mv ./build-mac/XPMP2.framework deploy-lib/lib + mv ${{ steps.build.outputs.lib-file-name }} deploy-lib/lib - name: Upload XPMP2 Framework - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: XPMP2-lib path: deploy-lib/* # this way we keep the folder structure in the artifact @@ -111,33 +74,20 @@ jobs: runs-on: windows-2022 steps: - name: Checkout Code - uses: actions/checkout@v2 # must checkout before we can use our own actions + uses: actions/checkout@v3 # must checkout before we can use our own actions - name: Build uses: ./.github/actions/build-win id: build with: - pluginName: ${{ env.PRJ_NAME }} - - name: Upload Artifact - uses: ./.github/actions/upload-plugin - with: - pluginName: ${{ env.PRJ_NAME }} - archFolder: win_x64 - xplFileName: "${{ steps.build.outputs.xpl-file-name }}" - pdbFileName: "${{ steps.build.outputs.pdb-file-name }}" - - name: Upload XPMP2-Sample - uses: ./.github/actions/upload-plugin - with: - pluginName: XPMP2-Sample - archFolder: win_x64 - xplFileName: "./build-win/win_x64/XPMP2-Sample.xpl" - pdbFileName: "./build-win/win_x64/XPMP2-Sample.pdb" + libName: ${{ env.PRJ_NAME }} + flags: ${{ inputs.flags }} - name: Prepare XPMP2 lib shell: bash run: | mkdir -p deploy-lib/lib/win - cp ./build-win/XPMP2.lib deploy-lib/lib/win + cp ${{ steps.build.outputs.lib-file-name }} deploy-lib/lib/win - name: Upload XPMP2 lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: XPMP2-lib path: deploy-lib/* # this way we keep the folder structure in the artifact diff --git a/CMakeLists.txt b/CMakeLists.txt index 277963c7..e834566f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,12 @@ # Targets XPMP2-Remote and XPMP2-Sample are EXCLUDE_FROM_ALL. # If you want to build them you have to explicitely state them on the command line, like # ninja XPMP2-Sample XPMP2-Remote +# +# If you want to build with FMOD sound support, +# 1. Make sure to understand the FMOD license and attribution requirements: +# https://www.fmod.com/licensing +# https://www.fmod.com/attribution +# 2. Define INCLUDE_FMOD_SOUND cache entry, e.g. using `cmake -G Ninja -D INCLUDE_FMOD_SOUND=1 ..` cmake_minimum_required(VERSION 3.16) @@ -23,7 +29,7 @@ else() endif() project(XPMP2 - VERSION 2.50 + VERSION 2.60 DESCRIPTION "Multiplayer library for X-Plane 11 and 12") # Provide compile macros from the above project version definition @@ -33,6 +39,7 @@ add_compile_definitions( XPMP2_VER_MINOR=${PROJECT_VERSION_MINOR} ) +message ("== Building: ${PROJECT_NAME} ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} ==") message ("Compiler Info:") message ("CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}") message ("CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}") @@ -84,7 +91,7 @@ if (MSVC) add_compile_options(/wd4996 /wd4068) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) else() - add_compile_options(-Wall -Wshadow -Wfloat-equal -Wextra -Wno-deprecated-declarations) + add_compile_options(-Wall -Wshadow -Wextra -Wno-deprecated-declarations) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0 AND NOT APPLE) add_compile_options(-Wno-stringop-truncation) endif() @@ -105,7 +112,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug") if (MSVC) add_compile_options(/Zi) else() - add_compile_options(-O0 -g) + add_compile_options(-O0 -g -fPIC) endif() else() add_compile_definitions(NDEBUG=1) @@ -122,10 +129,10 @@ else() endif() endif() -# Mingw Threads -if (MINGW) +# Mingw Threads (if not already defined by an outer target) +if (MINGW AND NOT TARGET mingw_stdthreads) option(MINGW_STDTHREADS_GENERATE_STDHEADERS "" ON) - add_subdirectory(XPMP2-Sample/mingw-std-threads) + add_subdirectory(lib/mingw-std-threads) endif() ################################################################################ @@ -170,17 +177,38 @@ target_include_directories(XPMP2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/SDK/CHeaders/XPLM + ${CMAKE_CURRENT_SOURCE_DIR}/lib/SDK/CHeaders/XPLM ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Some files are known to do float comparison, but are good with that +if (NOT MSVC) + set_source_files_properties( + src/Remote.cpp + src/Sound.cpp + PROPERTIES + COMPILE_FLAGS -Wno-float-equal) +endif() + # Include MingW threads if (MINGW) target_link_libraries(XPMP2 mingw_stdthreads) endif() +# FMOD Library support if requested +# (The actual FMOD lib is not included here, that needs to be done by the plugin target) +if(INCLUDE_FMOD_SOUND) + # Compile options + add_compile_definitions(INCLUDE_FMOD_SOUND) + target_include_directories(XPMP2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/fmod/inc) + target_sources(XPMP2 PRIVATE + src/Sound.h + src/Sound.cpp + ) +endif() + +# make it a framework if(APPLE) - # make it a framework list(APPEND XPMP2_PUB_HEADERS ../inc/XPCAircraft.h ../inc/XPMPAircraft.h @@ -199,191 +227,3 @@ if(APPLE) PUBLIC_HEADER "${XPMP2_PUB_HEADERS}" ) endif() - -# Copy the resulting framework/library also into the 'lib' directory of the sample plugin -if(APPLE) - add_custom_command(TARGET XPMP2 POST_BUILD - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/lib/XPMP2.framework - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/lib/XPMP2.framework - COMMAND cp -a $/../.. ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/lib/XPMP2.framework - ) -elseif(UNIX OR WIN32) - add_custom_command(TARGET XPMP2 POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/lib/$ENV{platform} - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/lib/$ENV{platform} - ) -endif() - -################################################################################ -# XPMP2-Remote plugin -################################################################################ - -# To be able to build here we use header files from the original location. -# And we use the SDK from XPMP2-Sample so that we don't need to keep 2 copies. -add_library(XPMP2-Remote MODULE EXCLUDE_FROM_ALL - # Public XPMP2 header files, usually taken from the XPMP2 framework - inc/XPCAircraft.h - inc/XPMPAircraft.h - inc/XPMPMultiplayer.h - inc/XPMPRemote.h - inc/XPMPPlaneRenderer.h - # X-Plane SDK - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMDataAccess.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMUtilities.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMPlugin.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMGraphics.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMMenus.h - # actual XPMP2-Remote client code - XPMP2-Remote/Client.h - XPMP2-Remote/Client.cpp - XPMP2-Remote/Utilities.h - XPMP2-Remote/Utilities.cpp - XPMP2-Remote/XPMP2-Remote.h - XPMP2-Remote/XPMP2-Remote.cpp -) - -# Header include directories -target_include_directories(XPMP2-Remote PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/inc - ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/SDK/CHeaders/XPLM - ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Remote -) - -# Which depends on XPMP2 -add_dependencies(XPMP2-Remote XPMP2) - -# Link to the just built XPMP2 library -target_link_libraries(XPMP2-Remote XPMP2) - -# Link X-Plane plugin system libraries. They are only provided for OS X and Windows. -if (WIN32 OR APPLE) - # Specify library search location for X-Plane SDK - if (APPLE) - list(APPEND CMAKE_FRAMEWORK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/SDK/Libraries/Mac") - else () - list(APPEND CMAKE_LIBRARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/SDK/Libraries/Win") - endif () - find_library(XPLM_LIBRARY XPLM REQUIRED NAMES XPLM XPLM_64.lib) - target_link_libraries(XPMP2-Remote ${XPLM_LIBRARY}) -endif () - -if (WIN32) - # Link with winsock for network and iphlpap for GetAdaptersAddresses - target_link_libraries(XPMP2-Remote wsock32 ws2_32 iphlpapi) - if (MINGW) - # Include MingW threads - target_link_libraries(XPMP2-Remote mingw_stdthreads) - # When cross-compiling we link the standard libraries statically - target_link_options(XPMP2-Remote PRIVATE -static-libgcc -static-libstdc++) - endif() -elseif (APPLE) - # Link OS X core system libraries. - find_library(IOKIT_LIBRARY IOKit REQUIRED) - find_library(CORE_FOUNDATION_LIBRARY CoreFoundation REQUIRED) - target_link_libraries(XPMP2-Remote ${IOKIT_LIBRARY} ${CORE_FOUNDATION_LIBRARY}) - # Restrict set of symbols exported from the plugin to the ones required by XPLM: - target_link_options(XPMP2-Remote PRIVATE "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/XPMP2-Sample.sym_mac") -elseif (UNIX) - # Link library for dynamic loading of shared objects on UNIX systems. - find_library(DL_LIBRARY dl REQUIRED) - # Threads - set(CMAKE_THREAD_PREFER_PTHREAD TRUE) - set(THREADS_PREFER_PTHREAD_FLAG TRUE) - find_package(Threads REQUIRED) - target_link_libraries(XPMP2-Remote ${DL_LIBRARY} Threads::Threads) - # Specify additional runtime search paths for dynamically-linked libraries. - # Restrict set of symbols exported from the plugin to the ones required by XPLM: - target_link_options(XPMP2-Remote PRIVATE -Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/XPMP2-Sample.sym) -endif () - - -# Target directory and file name -if (WIN32) - set_target_properties(XPMP2-Remote PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/win_x64") -elseif (APPLE) - set_target_properties(XPMP2-Remote PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/mac_x64") -elseif (UNIX) - set_target_properties(XPMP2-Remote PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lin_x64") -endif () - -set_target_properties(XPMP2-Remote PROPERTIES - PREFIX "" - OUTPUT_NAME "XPMP2-Remote" - SUFFIX ".xpl" -) - - -################################################################################ -# XPMP2-Sample plugin -################################################################################ - -# To be able to build here we use header files from the original location. -add_library(XPMP2-Sample MODULE EXCLUDE_FROM_ALL - # Public XPMP2 header files, usually taken from the XPMP2 framework - inc/XPCAircraft.h - inc/XPMPAircraft.h - inc/XPMPMultiplayer.h - inc/XPMPRemote.h - inc/XPMPPlaneRenderer.h - # X-Plane SDK - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMDataAccess.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMUtilities.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMPlugin.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMGraphics.h - XPMP2-Sample/SDK/CHeaders/XPLM/XPLMMenus.h - # actual XPMP2-Sample code - XPMP2-Sample/XPMP2-Sample.cpp -) - -# Header include directories -target_include_directories(XPMP2-Sample PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/inc - ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/SDK/CHeaders/XPLM - ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Remote -) - -# Which depends on XPMP2 -add_dependencies(XPMP2-Sample XPMP2) - -# Link to the just built XPMP2 library -target_link_libraries(XPMP2-Sample XPMP2) - -# Link X-Plane plugin system libraries. They are only provided for OS X and Windows. -if (WIN32 OR APPLE) - target_link_libraries(XPMP2-Sample ${XPLM_LIBRARY}) -endif () - -if (WIN32) - # Link with winsock for network and iphlpapi for GetAdaptersAddresses - target_link_libraries(XPMP2-Sample wsock32 ws2_32 iphlpapi) - if (MINGW) - # Include MingW threads - target_link_libraries(XPMP2-Sample mingw_stdthreads) - # When cross-compiling we link the standard libraries statically - target_link_options(XPMP2-Sample PRIVATE -static-libgcc -static-libstdc++) - endif() -elseif (APPLE) - target_link_libraries(XPMP2-Sample ${IOKIT_LIBRARY} ${CORE_FOUNDATION_LIBRARY}) - # Restrict set of symbols exported from the plugin to the ones required by XPLM: - target_link_options(XPMP2-Sample PRIVATE "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/XPMP2-Sample.sym_mac") -elseif (UNIX) - target_link_libraries(XPMP2-Sample ${DL_LIBRARY} Threads::Threads) - # Restrict set of symbols exported from the plugin to the ones required by XPLM: - target_link_options(XPMP2-Sample PRIVATE -Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample/XPMP2-Sample.sym) -endif () - -# Target directory and file name -if (WIN32) - set_target_properties(XPMP2-Sample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/win_x64") -elseif (APPLE) - set_target_properties(XPMP2-Sample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/mac_x64") -elseif (UNIX) - set_target_properties(XPMP2-Sample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lin_x64") -endif () - -set_target_properties(XPMP2-Sample - PROPERTIES - PREFIX "" - OUTPUT_NAME "XPMP2-Sample" - SUFFIX ".xpl" -) diff --git a/Info.plist b/Info.plist index 4ac0f5c7..39c60c1b 100644 --- a/Info.plist +++ b/Info.plist @@ -19,6 +19,6 @@ CFBundleVersion $(CURRENT_PROJECT_VERSION) NSHumanReadableCopyright - Copyright © 2020 B. Hoppe. All rights reserved. + Copyright © 2022 B. Hoppe. All rights reserved. diff --git a/README.md b/README.md index 479f59eb..6c4e2cc1 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,9 @@ to stay backward compatible. The XPMP2 library has been successfully tested with - X-Plane 11.5x under OpenGL, Vulkan, and Metal, -- X-Plane 12 Alpha and Beta version, -- the enclosed [XPMP2 Remote Client](#XPMP2-Remote-Client-Synchronizing-Planes-across-the-Network), -- the enclosed sample plugin, +- X-Plane 12 Alpha and Beta versions, +- the [XPMP2 Remote Client](#XPMP2-Remote-Client-Synchronizing-Planes-across-the-Network), +- the [`XPMP2-Sample` plugin](https://github.com/TwinFan/XPMP2-Remote), - [LiveTraffic v2.20](https://forums.x-plane.org/index.php?/files/file/49749-livetraffic/) - [X-Pilot 1.3](http://xpilot-project.org/) - X-Plane version of [IVAO Altitude](https://www.ivao.aero/softdev/beta/altitudebeta.asp) @@ -67,6 +67,8 @@ The XPMP2 library has been successfully tested with - XPMP2 implements [instancing](https://developer.x-plane.com/sdk/XPLMInstance/), so it **requires X-Plane 11.10** or later - CSL models in **OBJ8 format** (ie. older OBJ7 models are no longer supported) +- Potentially an FMOD license if built with sound support, see below in + [Sound Support by FMOD](#sound-support-by-fmod) ## Documentation: See [GitHub pages](https://twinfan.github.io/XPMP2/) ## @@ -76,9 +78,10 @@ and more is available in the ### Sample Plugin ### -This package comes with a sample plugin in the `XPMP2-Sample` folder. It is a complete -plugin including build projects and CMake setup. It displays 3 aircraft flying circles -in front of the user's plane. Each of the 3 aircraft is using a different technology: +The separate _Public Template_ repository `XPMP2-Sample` provides a complete +plugin including build projects and CMake setup and can be the basis for your plugin project. +It displays 3 aircraft flying circles in front of the user's plane. +Each of the 3 aircraft is using a different technology: the now recommended way of subclassing `XPMP2::Aircraft`, the legacy way of subclassing `XPCAircraft` (as used by LiveTraffic v1.x), and by calling standard C functions. @@ -134,6 +137,21 @@ precice results. Find [more details here](https://twinfan.github.io/XPMP2/Wake.html). +### Sound Support by FMOD ### + +All displayed aircraft can produce sound in the 3D world for +engine, reversers, taxiing, gear and flap movement. + +XPMP2's Audio Engine is FMOD Core API by Firelight Technologies Pty Ltd. +Understand FMOD [licensing](https://www.fmod.com/licensing) and +[attribution requirements](https://www.fmod.com/attribution) first, +as they will apply to _your_ plugin if using XPMP2 with sound support. + +Because of the licensing requirements, XPMP2 by default is built +**without** sound support. +See the [Sound Support documentation](https://twinfan.github.io/XPMP2/Sound.html) +for details how to enable sound support and how to include it into your plugin. + ### Map Layer ### XPMP2 creates an additional layer in X-Plane's internal map, named after the diff --git a/XPMP2-Remote/Client.cpp b/XPMP2-Remote/Client.cpp deleted file mode 100755 index 4397fdbb..00000000 --- a/XPMP2-Remote/Client.cpp +++ /dev/null @@ -1,636 +0,0 @@ -/// @file Client.cpp -/// @brief Main Client functionality, processing received data -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#include "XPMP2-Remote.h" - -#define INFO_NEW_SENDER_PLUGIN "First data received from %.*s (%u) @ %s" -#define INFO_SENDER_PLUGIN_LOST "Sender %.*s (%u) @ %s fell silent, removed" -#define WARN_LOST_PLANE_CONTACT "Lost contact to plane 0x%06X of %.*s (%u) @ %s" -#define INFO_GOT_AI_CONTROL "Have TCAS / AI control now" -#define INFO_DEACTIVATED "Deactivated, stopped listening to network" - -// -// MARK: Aircraft Administration -// - -/// Contains 'now' at the time the flight loop starts -std::chrono::time_point nowFlightLoop; - -// Constructor for use in network thread: Does _not_ Create the aircraft but only stores the passed information -RemoteAC::RemoteAC (SenderTy& _sender, const XPMP2::RemoteAcDetailTy& _acDetails) : -XPMP2::Aircraft(), // do _not_ create an actual plane! -senderId(_acDetails.modeS_id), -pkgHash(_acDetails.pkgHash), -sShortId(STR_N(_acDetails.sShortId)), -sender(_sender) -{ - // Initialization - histPos[0] = {sizeof(XPLMDrawInfo_t), NAN, NAN, NAN, 0.0f, 0.0f, 0.0f}; - histPos[1] = histPos[0]; - - // store the a/c detail information - Update(_acDetails); -} - -// Destructor -RemoteAC::~RemoteAC() -{} - -// Actually create the aircraft, ultimately calls XPMP2::Aircraft::Create() -void RemoteAC::Create () -{ - // Create the actual plane - Aircraft::Create(acIcaoType, acIcaoAirline, acLivery, senderId, "", - XPMP2::CSLModelByPkgShortId(pkgHash, sShortId)); - bCSLModelChanged = false; -} - -// Update data from a a/c detail structure -void RemoteAC::Update (const XPMP2::RemoteAcDetailTy& _acDetails) -{ - acIcaoType = STR_N(_acDetails.icaoType); - acIcaoAirline = STR_N(_acDetails.icaoOp); - acLivery.clear(); - - // CSL Model: Did it change? (Will be set during UpdatePosition()) - bCSLModelChanged = (pkgHash != _acDetails.pkgHash) || (sShortId != _acDetails.sShortId); - if (bCSLModelChanged) { - pkgHash = _acDetails.pkgHash; - sShortId = _acDetails.sShortId; - } - - label = STR_N(_acDetails.label); - _acDetails.GetLabelCol(colLabel); - // Labels are forced on if our local config says so - bDrawLabel = _acDetails.bDrawLabel || (rcGlob.eDrawLabels == XPMP2RCGlobals::LABELS_ON); - - // We might be in a worker thread...only temporarily store the position - lat = _acDetails.lat; - lon = _acDetails.lon; - alt_ft = double(_acDetails.alt_ft); - diffTime = std::chrono::duration>(_acDetails.dTime); - bWorldCoordUpdated = true; // flag for UpdatePosition() to read fresh data - - drawInfo.pitch = _acDetails.GetPitch(); - drawInfo.heading = _acDetails.GetHeading(); - drawInfo.roll = _acDetails.GetRoll(); - aiPrio = _acDetails.aiPrio; - bOnGrnd = _acDetails.bOnGrnd; - - // Info texts -#if defined(__GNUC__) && (__GNUC__ >= 9) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wclass-memaccess" -#endif - std::memset(&acInfoTexts, 0, sizeof(acInfoTexts)); -#if defined(__GNUC__) && (__GNUC__ >= 9) -#pragma GCC diagnostic pop -#endif -#define memcpy_min(to,from) std::memcpy(to,from,std::min(sizeof(from),sizeof(to))) - memcpy_min(acInfoTexts.tailNum, _acDetails.tailNum); - memcpy_min(acInfoTexts.icaoAcType, _acDetails.icaoType); - memcpy_min(acInfoTexts.manufacturer, _acDetails.manufacturer); - memcpy_min(acInfoTexts.model, _acDetails.model); - memcpy_min(acInfoTexts.icaoAirline, _acDetails.icaoOp); - memcpy_min(acInfoTexts.airline, _acDetails.airline); - memcpy_min(acInfoTexts.flightNum, _acDetails.flightNum); - memcpy_min(acInfoTexts.aptFrom, _acDetails.aptFrom); - memcpy_min(acInfoTexts.aptTo, _acDetails.aptTo); - - // Don't render local planes (the local plugin does already), - // or if explicitely instructed so by the sender - SetRender(sender.bLocal ? false : _acDetails.bRender); - - // Validity and Visibility - SetVisible(_acDetails.bVisible); - if (!_acDetails.bValid) - SetInvalid(); - - // Animation dataRefs - for (size_t i = 0; i < XPMP2::V_COUNT; ++i) - v[i] = XPMP2::REMOTE_DR_DEF[i].unpack(_acDetails.v[i]); -/* - LOG_MSG(logDEBUG, " 0x%06X: %.7f / %.7f, %.1f", - GetModeS_ID(), lat, lon, alt_ft);*/ -} - -// Update data from an a/c position update -void RemoteAC::Update (const XPMP2::RemoteAcPosUpdateTy& _acPosUpd) -{ - // Update position information based on diff values in the position update - lat += XPMP2::REMOTE_DEGREE_RES * double(_acPosUpd.dLat); - lon += XPMP2::REMOTE_DEGREE_RES * double(_acPosUpd.dLon); - alt_ft += XPMP2::REMOTE_ALT_FT_RES * double(_acPosUpd.dAlt_ft); - diffTime = std::chrono::duration>(_acPosUpd.dTime); - bWorldCoordUpdated = true; // flag for UpdatePosition() to read fresh data - - drawInfo.pitch = _acPosUpd.GetPitch(); - drawInfo.heading = _acPosUpd.GetHeading(); - drawInfo.roll = _acPosUpd.GetRoll(); -/* - LOG_MSG(logDEBUG, "0x%06X: %.7f / %.7f, %.1f <-- %+.7f / %+.7f, %+.1f", - GetModeS_ID(), lat, lon, alt_ft, - _acPosUpd.dLat * XPMP2::REMOTE_DEGREE_RES, - _acPosUpd.dLon * XPMP2::REMOTE_DEGREE_RES, - _acPosUpd.dAlt_ft * XPMP2::REMOTE_ALT_FT_RES); */ -} - -// Update data from an a/c animation dataRefs message -void RemoteAC::Update (const XPMP2::RemoteAcAnimTy& _acAnim) -{ - // Loop over all includes values and update the respective dataRef values - for (std::uint8_t idx = 0; idx < _acAnim.numVals; ++idx) { - const XPMP2::RemoteAcAnimTy::DataRefValTy& dr = _acAnim.v[idx]; - v[dr.idx] = XPMP2::REMOTE_DR_DEF[dr.idx].unpack(dr.v); - } -} - -// Called by XPMP2 for position updates, extrapolates from historic positions -void RemoteAC::UpdatePosition (float _elapsed, int) -{ - // Did the CSL model change? - if (bCSLModelChanged) { - bCSLModelChanged = false; - XPMP2::CSLModel *pNewCSLModel = XPMP2::CSLModelByPkgShortId(pkgHash, sShortId); - if (pNewCSLModel && pNewCSLModel != pCSLMdl) - AssignModel("", pNewCSLModel); - } - - // If we have a fresh world position then that's the one that counts - if (bWorldCoordUpdated) { - SetLocation(lat, lon, alt_ft); // Convert to local, stored in drawInfo - bWorldCoordUpdated = false; - - // cycle the historic positions and save the new one - histPos[0] = histPos[1]; - histPos[1] = drawInfo; - // Timestamp: This one [1] is valid _now_ - histTs[1] = nowFlightLoop; - histTs[0] = histTs[1] - diffTime; - - // Special handling for heading as [0] and [1] could be on different sides of 0 / 360 degrees: - // We push things towards positive figures larger than 360 - // as we can then just use fmod(h,360) and don't care about negatives - if (histPos[0].heading >= 360.0f) // if we increased the value last time we need to normalize it before re-calculation - histPos[0].heading -= 360.0f; - const float diffHead = histPos[0].heading - histPos[1].heading; - if (diffHead > 180.0f) - histPos[1].heading += 360.0f; - else if (diffHead < -180.0f) - histPos[0].heading += 360.0f; - } - // extrapolate based on last 2 positions if 2 positions are known with differing timestamps - else if (!std::isnan(histPos[0].x) && histTs[1] > histTs[0]) { - const std::chrono::steady_clock::duration dHist = histTs[1] - histTs[0]; - const std::chrono::steady_clock::duration dNow = nowFlightLoop - histTs[0]; - - // We extrapolate only for a maximum of 1s, after that planes just stop - // (If the sender is, e.g., stuck in an X-Plane dialog then that sender - // will not send position updates, so stopping is fairly close to reality.) - if (dNow - dHist <= std::chrono::seconds(1)) { - try { - const float f = float(dNow.count()) / float(dHist.count()); - drawInfo.x = histPos[0].x + f * (histPos[1].x - histPos[0].x); - drawInfo.y = histPos[0].y + f * (histPos[1].y - histPos[0].y); - drawInfo.z = histPos[0].z + f * (histPos[1].z - histPos[0].z); - drawInfo.pitch = histPos[0].pitch + f * (histPos[1].pitch - histPos[0].pitch); - drawInfo.heading = std::fmod(histPos[0].heading + f * (histPos[1].heading - histPos[0].heading), 360.0f); - drawInfo.roll = histPos[0].roll + f * (histPos[1].roll - histPos[0].roll); - -/* LOG_MSG(logDEBUG, "0x%06X: %.2f / %.2f / %.2f ==> %+8.2f / %+8.2f / %+8.2f [%.4f]", - GetModeS_ID(), drawInfo.x, drawInfo.y, drawInfo.z, - drawInfo.x-prevDraw.x, - drawInfo.y-prevDraw.y, - drawInfo.z-prevDraw.z, f); */ - } - catch (...) { - drawInfo = histPos[1]; - } - } else { - // This plane has no updates...but the sender is updated? - // Then we lost contact to this plane and shall remove it - if (nowFlightLoop - sender.lastMsg < std::chrono::milliseconds(500)) { - LOG_MSG(logWARN, WARN_LOST_PLANE_CONTACT, senderId, - (int)sizeof(sender.settings.name), sender.settings.name, - sender.settings.pluginId, sender.sFrom.c_str()); - SetInvalid(); - } - } - } - - // Special handling for rotational dataRefs: - // These are the only ones we move ourselves as they need to keep going every frame - // for good looks. - // Idea: Turn them based on defined speed - if (GetTireRotRpm() > 1.0f) SetTireRotAngle(std::fmod(GetTireRotAngle() + GetTireRotRpm()/60.0f * _elapsed * 360.0f, 360.0f)); - if (GetEngineRotRpm() > 1.0f) SetEngineRotAngle(std::fmod(GetEngineRotAngle() + GetEngineRotRpm()/60.0f * _elapsed * 360.0f, 360.0f)); - for (size_t i = 1; i <= 4; i++) - if (GetEngineRotRpm(i) > 1.0f) SetEngineRotAngle(i, std::fmod(GetEngineRotAngle(i) + GetEngineRotRpm(i)/60.0f * _elapsed * 360.0f, 360.0f)); - if (GetPropRotRpm() > 1.0f) SetPropRotAngle(std::fmod(GetPropRotAngle() + GetPropRotRpm()/60.0f * _elapsed * 360.0f, 360.0f)); -} - -// -// MARK: Sender Administration -// - -// uses memcmp to compare sender addresses -bool SenderAddrTy::operator< (const SenderAddrTy& o) const -{ - return memcmp(this, &o, sizeof(*this)) < 0; -} - -// Constructor copies values and sets lastMsg to now -SenderTy::SenderTy (const std::string& _from, const XPMP2::RemoteMsgSettingsTy& _s) : -sFrom(_from), bLocal(_s.bLocalSender), -settings(_s), lastMsg(std::chrono::steady_clock::now()) -{ - // Remove port number from IP adress - const size_t posColon = sFrom.rfind(':'); - if (posColon != std::string::npos) - sFrom.erase(posColon); -} - -// Find a sender based on plugin id and IP address -SenderTy* SenderTy::Find (XPLMPluginID _id, const std::uint32_t _from[4]) -{ - SenderAddrTy senderId (_id, _from); - mapSenderTy::iterator itSender = rcGlob.gmapSender.find(senderId); - if (itSender != rcGlob.gmapSender.end()) - return &itSender->second; - return nullptr; -} - -// -// MARK: Process Messages -// - -bool bWaitingForAI = false; ///< have we requested AI access and are now waiting for a callback? -std::mutex gmutexData; ///< the mutex controlling access to all data between network and main thread -/// The lock used by _main thread_ functions to acquire data access -std::unique_lock glockDataMain(gmutexData, std::defer_lock); -/// Indicates if it is needed in the main thread to process updates to settings -std::atomic_flag gbSkipSettingsUpdate = ATOMIC_FLAG_INIT; -/// Indicates if it is needed in the main thread to process new aircraft -std::atomic_flag gbSkipAcMaintenance = ATOMIC_FLAG_INIT; - -void ClientTryGetAI (); - -/// Callback for requesting TCAS: Maybe now we have a chance? -void ClientCBRetryGetAI (void*) -{ - bWaitingForAI = false; - - // If we still want to have TCAS we just try again - if (rcGlob.mergedS.bHaveTCASControl && !XPMPHasControlOfAIAircraft()) - ClientTryGetAI(); -} - -// Try getting TCAS/AI control -void ClientTryGetAI () -{ - // make sure we do this from the main thread only! - assert (rcGlob.IsXPThread()); - - // no need to try (again)? - if (bWaitingForAI || XPMPHasControlOfAIAircraft()) - return; - - // Try getting AI control, pass callback for the case we couldn't get it - const char* cszResult = XPMPMultiplayerEnable(ClientCBRetryGetAI); - if ( cszResult[0] ) { - bWaitingForAI = true; - LOG_MSG(logWARN, "%s", cszResult); - } else if (XPMPHasControlOfAIAircraft()) { - bWaitingForAI = false; - LOG_MSG(logINFO, INFO_GOT_AI_CONTROL); - } -} - -// Stop TCAS/AI control -void ClientReleaseAI () -{ - XPMPMultiplayerDisable(); - bWaitingForAI = false; -} - -/// @brief Handles a received Settings message, which also identifies a sending plugin -/// @details 1. Plugin information is stored in gmapSender. -/// 2. A "merged" version of all sender plugins' settings is created, -/// make a per-field decision for the more significant value. -/// This merged version shall become our local settings. -/// 3. In a last step the changes to current actual settings are determined -/// and necessary action taken. -void ClientProcSettings (const std::uint32_t from[4], - const std::string& sFrom, - const XPMP2::RemoteMsgSettingsTy& _msgSettings) -{ - // Require access - std::lock_guard lk(gmutexData); - - // 1. Store sender information - SenderTy* pSender = SenderTy::Find(_msgSettings.pluginId, from); - if (!pSender) { - // Seeing this plugin the first time! - LOG_MSG(logINFO, INFO_NEW_SENDER_PLUGIN, - (int)sizeof(_msgSettings.name), _msgSettings.name, - _msgSettings.pluginId, - (_msgSettings.bLocalSender ? sFrom + " (local)" : sFrom).c_str()); - rcGlob.gmapSender.emplace(std::piecewise_construct, - std::forward_as_tuple(_msgSettings.pluginId, from), - std::forward_as_tuple(sFrom, _msgSettings)); - - // If this one also happens to be the first plugin at all then it defines - // some settings that cannot be well merged - if (rcGlob.gmapSender.size() == 1) { - // packed config structure does not have zero-termination - std::string defAc = STR_N(_msgSettings.defaultIcao); - std::string defCar = STR_N(_msgSettings.carIcaoType); - XPMPSetDefaultPlaneICAO(defAc.c_str(), defCar.c_str()); - } - } - else - { - // plugin is known, update its settings - pSender->settings = _msgSettings; - pSender->lastMsg = std::chrono::steady_clock::now(); - } - - // 2. Consolidate/merge the settings of all plugins - mapSenderTy::iterator itSender = rcGlob.gmapSender.begin(); - LOG_ASSERT(itSender != rcGlob.gmapSender.end()); - rcGlob.mergedS = itSender->second.settings; - for (++itSender; itSender != rcGlob.gmapSender.end(); ++itSender) - { - const XPMP2::RemoteMsgSettingsTy& otherS = itSender->second.settings; - if (otherS.logLvl < rcGlob.mergedS.logLvl) rcGlob.mergedS.logLvl = otherS.logLvl; - if ( otherS.bLogMdlMatch) rcGlob.mergedS.bLogMdlMatch = true; - if ( otherS.bObjReplDataRefs) rcGlob.mergedS.bLogMdlMatch = true; - if ( otherS.bObjReplTextures) rcGlob.mergedS.bLogMdlMatch = true; - if (!otherS.bLabelCutOffAtVisibility) rcGlob.mergedS.bLabelCutOffAtVisibility = false; - if ( otherS.bMapEnabled) rcGlob.mergedS.bMapEnabled = true; - if ( otherS.bMapLabels) rcGlob.mergedS.bMapLabels = true; - if ( otherS.bHaveTCASControl) rcGlob.mergedS.bHaveTCASControl = true; - } - - // 3. Take action based on whatever settings differ between mergedS and my current settings - XPMPSetAircraftLabelDist(rcGlob.mergedS.maxLabelDist / XPMP2::M_per_NM, - rcGlob.mergedS.bLabelCutOffAtVisibility); - // The next flight loop cycle needs to update some stuff - gbSkipSettingsUpdate.clear(); -} - -// Called at the beginning of each flight loop processing: Get the data lock, create waiting planes -void ClientFlightLoopBegins () -{ - // Any main thread stuff to do due to settings updates? - if (!gbSkipSettingsUpdate.test_and_set()) { - XPMPEnableMap(rcGlob.mergedS.bMapEnabled, - rcGlob.mergedS.bMapLabels); - if (rcGlob.mergedS.bHaveTCASControl) - ClientTryGetAI(); - } - - // Store current time once for all position calculations - nowFlightLoop = std::chrono::steady_clock::now(); - - // Acquire the data access lock once and keep it while the flight loop is running - if (!glockDataMain) - glockDataMain.lock(); - - // Every 10 seconds clean up outdated senders - static float lastSenderCleanup = 0; - if (GetMiscNetwTime() - lastSenderCleanup > 10.0f) { - lastSenderCleanup = GetMiscNetwTime(); - for (mapSenderTy::iterator sIter = rcGlob.gmapSender.begin(); - sIter != rcGlob.gmapSender.end();) - { - const SenderTy& sdr = sIter->second; - if (nowFlightLoop - sdr.lastMsg > std::chrono::seconds(2 * XPMP2::REMOTE_SEND_SETTINGS_INTVL)) { - LOG_MSG(logINFO, INFO_SENDER_PLUGIN_LOST, - (int)sizeof(sdr.settings.name), sdr.settings.name, - sdr.settings.pluginId, sdr.sFrom.c_str()); - sIter = rcGlob.gmapSender.erase(sIter); - } - else - sIter++; - } - } - - // If needed create new or remove deleted aircraft that have been prepared in the meantime - if (gbSkipAcMaintenance.test_and_set()) { - for (auto& s: rcGlob.gmapSender) { // loop all senders - // loop all a/c of that sender - mapRemoteAcTy::iterator acIter = s.second.mapAc.begin(); - while (acIter != s.second.mapAc.end()) { - // a/c to be deleted? - if (acIter->second.IsToBeDeleted()) - acIter = s.second.mapAc.erase(acIter); - // create a/c if not created - else if (acIter->second.GetModeS_ID() == 0) - (acIter++)->second.Create(); - else - acIter++; - } - } - } -} - -// Called at the end of each flight loop processing: Release the data lock -void ClientFlightLoopEnds () noexcept -{ - // Release the data access lock - try { glockDataMain.unlock(); } - catch(...) { /* ignore all errors */ } -} - -/// @brief Handle A/C Details messages, called by XPMP2 via callback -/// @details 1. If the aircraft does not exist create it -/// 2. Else update it's data -void ClientProcAcDetails (const std::uint32_t _from[4], size_t _msgLen, - const XPMP2::RemoteMsgAcDetailTy& _msgAcDetails) -{ - // Find the sender, bail if we don't know it - SenderTy* pSender = SenderTy::Find(_msgAcDetails.pluginId, _from); - if (!pSender) return; - pSender->lastMsg = std::chrono::steady_clock::now(); - - // Loop over all aircraft contained in the message - const size_t numAc = _msgAcDetails.NumElem(_msgLen); - for (size_t i = 0; i < numAc; ++i) { - const XPMP2::RemoteAcDetailTy& acDetails = _msgAcDetails.arr[i]; - // Is the aircraft known? - mapRemoteAcTy::iterator iAc = pSender->mapAc.find(acDetails.modeS_id); - // Now require access (for each plane, because we want to give the main thread's flight loop a better change to grab the lock if needed) - std::unique_lock lk(gmutexData); - // Is the aircraft known? - if (iAc == pSender->mapAc.end()) { - // new aircraft, create an object for it, but not yet the actual plane (as this is the network thread) - pSender->mapAc.emplace(std::piecewise_construct, - std::forward_as_tuple(acDetails.modeS_id), - std::forward_as_tuple(*pSender, acDetails)); - // tell the main thread that it shall process new a/c - gbSkipAcMaintenance.clear(); - } else { - // known aircraft, update its data - iAc->second.Update(acDetails); - } - lk.unlock(); - } -} - -/// Handle A/C Position Update message, called by XPMP2 via callback -void ClientProcAcPosUpdate (const std::uint32_t _from[4], size_t _msgLen, - const XPMP2::RemoteMsgAcPosUpdateTy& _msgAcPosUpdate) -{ - // Find the sender, bail if we don't know it - SenderTy* pSender = SenderTy::Find(_msgAcPosUpdate.pluginId, _from); - if (!pSender) return; - pSender->lastMsg = std::chrono::steady_clock::now(); - - // Loop over all aircraft contained in the message - const size_t numAc = _msgAcPosUpdate.NumElem(_msgLen); - for (size_t i = 0; i < numAc; ++i) { - const XPMP2::RemoteAcPosUpdateTy& acPosUpd = _msgAcPosUpdate.arr[i]; - // Is the aircraft known? - mapRemoteAcTy::iterator iAc = pSender->mapAc.find(XPMPPlaneID(acPosUpd.modeS_id)); - if (iAc != pSender->mapAc.end()) { - // Now require access (for each plane, because we want to give the main thread's flight loop a better change to grab the lock if needed) - std::lock_guard lk(gmutexData); - // known aircraft, update its data - iAc->second.Update(acPosUpd); - } - } - -} - -/// Handle A/C Animation dataRef messages, called by XPMP2 via callback -void ClientProcAcAnim (const std::uint32_t _from[4], size_t _msgLen, - const XPMP2::RemoteMsgAcAnimTy& _msgAcAnim) -{ - // Find the sender, bail if we don't know it - SenderTy* pSender = SenderTy::Find(_msgAcAnim.pluginId, _from); - if (!pSender) return; - pSender->lastMsg = std::chrono::steady_clock::now(); - - // Loop all animation data elements in the message - for (const XPMP2::RemoteAcAnimTy* pAnim = _msgAcAnim.next(_msgLen); - pAnim; - pAnim = _msgAcAnim.next(_msgLen, pAnim)) - { - // Is the aircraft known? - mapRemoteAcTy::iterator iAc = pSender->mapAc.find(XPMPPlaneID(pAnim->modeS_id)); - if (iAc != pSender->mapAc.end()) { - // Now require access (for each plane, because we want to give the main thread's flight loop a better change to grab the lock if needed) - std::lock_guard lk(gmutexData); - // known aircraft, update its data - iAc->second.Update(*pAnim); - } - } -} - -/// Handle A/C Removal message, called by XPMP2 via callback -void ClientProcAcRemove (const std::uint32_t _from[4], size_t _msgLen, - const XPMP2::RemoteMsgAcRemoveTy& _msgAcRemove) -{ - // Find the sender, bail if we don't know it - SenderTy* pSender = SenderTy::Find(_msgAcRemove.pluginId, _from); - if (!pSender) return; - pSender->lastMsg = std::chrono::steady_clock::now(); - - // Loop over all aircraft contained in the message - const size_t numAc = _msgAcRemove.NumElem(_msgLen); - for (size_t i = 0; i < numAc; ++i) { - const XPMP2::RemoteAcRemoveTy& acRemove = _msgAcRemove.arr[i]; - // Is the aircraft known? - mapRemoteAcTy::iterator iAc = pSender->mapAc.find(XPMPPlaneID(acRemove.modeS_id)); - if (iAc != pSender->mapAc.end()) { - // Now require access (for each plane, because we want to give the main thread's flight loop a better change to grab the lock if needed) - std::lock_guard lk(gmutexData); - // mark this a/c for deletion (which must happen in XP's main thread) - iAc->second.MarkForDeletion(); - // tell the main thread that it shall process removed a/c - gbSkipAcMaintenance.clear(); - } - } -} - - - -// -// MARK: Global Functions -// - -// Initializes the module -void ClientInit() -{ - // Initialize the atomic flags to 'set' - gbSkipSettingsUpdate.test_and_set(); - gbSkipAcMaintenance.test_and_set(); -} - -// Shuts down the module gracefully -void ClientCleanup() -{ - // Force off - ClientToggleActive(-1); -} - - -// Toggles the cient's activitiy status, as based on menu command -void ClientToggleActive (int nForce) -{ - // Need to start? - if (nForce > 0 || - XPMP2::RemoteGetStatus() == XPMP2::REMOTE_OFF) - { - // Try already to get TCAS control so we have it before others can snatch it away. - // This is not in accordance with what is laid out in "TCAS Override" - // https://developer.x-plane.com/article/overriding-tcas-and-providing-traffic-information/#Plugin_coordination - // but we serve a good deed here: We can combine several plugins' TCAS needs, - // but only if we are in control: - ClientTryGetAI(); - - // Start the listener to receive message - XPMP2::RemoteCBFctTy rmtCBFcts = { - ClientFlightLoopBegins, // before flight loop processing starts - ClientFlightLoopEnds, // after flight loop processing ends - ClientProcSettings, // Settings - ClientProcAcDetails, // Aircraft Details - ClientProcAcPosUpdate, // Aircraft Position Update - ClientProcAcAnim, // Aircraft Animarion dataRef values - ClientProcAcRemove, // Aircraft Removal - }; - XPMP2::RemoteRecvStart(rmtCBFcts); - } - // Need to stop? - else if (nForce < 0 || - XPMP2::RemoteGetStatus() != XPMP2::REMOTE_OFF) - { - // Release the data access lock, just a safety measure so that we don't hinder shutdown in case we f--- up - try { glockDataMain.unlock(); } - catch (...) { /* ignore all errors */ } - // Stop the listener - XPMP2::RemoteRecvStop(); - // Shut down everything - ClientReleaseAI(); - rcGlob.gmapSender.clear(); // removes aircraft in turn - LOG_MSG(logINFO, INFO_DEACTIVATED); - } -} diff --git a/XPMP2-Remote/Client.h b/XPMP2-Remote/Client.h deleted file mode 100644 index 539c6a44..00000000 --- a/XPMP2-Remote/Client.h +++ /dev/null @@ -1,137 +0,0 @@ -/// @file Client.h -/// @brief Main Client functionality, processing received data -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#pragma once - -// -// MARK: Aircraft Administration -// - -struct SenderTy; - -/// Representation of a remote aircraft -class RemoteAC : public XPMP2::Aircraft { -protected: - // A few defining information taken over from the sender - XPMPPlaneID senderId = 0; ///< sender's plane id (might be different here in case of deduplication) - std::uint16_t pkgHash = 0; ///< hash value of CSL model package - std::string sShortId; ///< CSL model's short id - bool bDeleteMe = false; ///< flag that this a/c needs to removed - - /// @brief We keep 2 historic positions to be able to calculate simple linear extrapolation - /// @details Index 0 is the older one, index 1 the newer one - XPLMDrawInfo_t histPos[2]; - /// Timestamps when these two positions were valid - std::chrono::time_point histTs[2]; - - // World coordinates - double lat = NAN; ///< latitude - double lon = NAN; ///< longitude - double alt_ft = NAN; ///< altitude [ft] - std::chrono::duration> diffTime; ///< time difference to previous historic position as passed in by the sender - bool bWorldCoordUpdated = false; ///< shall freshly set values be used in the next UpdatePosition callback? - - // Did the CSL model change? Will force model-reload during UpdatePosition() - bool bCSLModelChanged = false; - - // The sending plugin this plane came from - SenderTy& sender; - -public: - /// Constructor for use in network thread: Does _not_ Create the aircraft but only stores the passed information - RemoteAC (SenderTy& _sender, const XPMP2::RemoteAcDetailTy& _acDetails); - /// Destructor - virtual ~RemoteAC(); - - /// Actually create the aircraft, ultimately calls XPMP2::Aircraft::Create() - void Create (); - - /// Update data from an a/c detail structure - void Update (const XPMP2::RemoteAcDetailTy& _acDetails); - /// Update data from an a/c position update - void Update (const XPMP2::RemoteAcPosUpdateTy& _acPosUpd); - /// Update data from an a/c animation dataRefs message - void Update (const XPMP2::RemoteAcAnimTy& _acAnim); - - /// Called by XPMP2 for position updates, extrapolates from historic positions - void UpdatePosition (float, int) override; - - /// Mark this aircraft as to-be-deleted in the next flight loop (can't do in worker thread) - void MarkForDeletion () { bDeleteMe = true; } - /// To be deleted? - bool IsToBeDeleted () const { return bDeleteMe; } -}; - -/// Map of remote aircraft; key is the plane id as sent by the sending plugin (while the _modeS_id of the local copy could differ) -typedef std::map mapRemoteAcTy; - -// -// MARK: Sender Administration -// - -/// Uniquely identifies a sending plugin -struct SenderAddrTy { - const XPLMPluginID pluginId; ///< sender's plugin id within X-Plane (first to speed up memcmp as usually this will already differ between plugins) - std::uint32_t from[4]; ///< numerical part of sender's IP address (only differentiating in rare cases of two plugins on different PCs having the same plugin id) - bool operator< (const SenderAddrTy& o) const; ///< uses memcmp to compare this - /// Constructor just fills values - SenderAddrTy (XPLMPluginID _id, const std::uint32_t _from[4]) : - pluginId(_id) { memcpy(from, _from, sizeof(from)); } -}; - -struct SenderTy { - std::string sFrom; ///< string representaton of the sender's IP address - const bool bLocal; ///< is this a local sender on the same computer? - XPMP2::RemoteMsgSettingsTy settings;///< that plugin's settings - std::chrono::time_point lastMsg; - mapRemoteAcTy mapAc; ///< map of aircraft sent by this plugin - - /// Constructor copies values and sets lastMsg to now - SenderTy (const std::string& _from, const XPMP2::RemoteMsgSettingsTy& _s); - - /// Find a sender based on plugin id and IP address - static SenderTy* Find (XPLMPluginID _id, const std::uint32_t _from[4]); -}; - -/// map of sender information -typedef std::map mapSenderTy; - -// -// MARK: Global Functions -// - -/// Initializes the module -void ClientInit(); -/// Shuts down the module gracefully -void ClientCleanup(); - -/// Try getting TCAS/AI control -void ClientTryGetAI (); -/// Stop TCAS/AI control -void ClientReleaseAI (); - -/// @brief Toggles the cient's activitiy status, as based on menu command -/// @param nForce 3-way toggle: `-1? force off, `0` toggle, `+1` force on -void ClientToggleActive (int nForce = 0); - -/// Called at the beginning of each flight loop processing: Get the data lock, create waiting planes -void ClientFlightLoopBegins (); -/// Called at the end of each flight loop processing: Release the data lock -void ClientFlightLoopEnds () noexcept; diff --git a/XPMP2-Remote/README.md b/XPMP2-Remote/README.md deleted file mode 100644 index a59be1e4..00000000 --- a/XPMP2-Remote/README.md +++ /dev/null @@ -1,27 +0,0 @@ -XPMP2 Remote Client -========= - -**Synchronizing Planes across the Network** - -Planes displayed using XPMP2 can by synchronized across the network. -The **XPMP2 Remote Client** needs to run on all remote computers, -receives aircraft data from any number of XPMP2-based plugins anywhere -in the network, and displays the aircraft using the same CSL model, -at the same world location with the same animation dataRefs. - -This supports usage in setups like -- [Networking Multiple Computers for Multiple Displays](https://x-plane.com/manuals/desktop/#networkingmultiplecomputersformultipledisplays), -- [Networked Multiplayer](https://x-plane.com/manuals/desktop/#networkedmultiplayer), -- but also just locally as a **TCAS Concentrator**, which collects plane - information from other local plugins and forwards them combined to TCAS - and classic multiplayer dataRefs for 3rd party add-ons. - -For end user documentation refer to -[LiveTraffic/XPMP2 Remote Client](https://twinfan.gitbook.io/livetraffic/setup/installation/xpmp2-remote-client) -documentation. - -For more background information refer to -[GitHub XPMP2 documentation](https://twinfan.github.io/XPMP2/Remote.html). - -One of many possible setups: -![XPMP2 in a Standard Networked Setup](../docs/pic/XPMP2_Remote_Standard.png) diff --git a/XPMP2-Remote/Utilities.cpp b/XPMP2-Remote/Utilities.cpp deleted file mode 100755 index bb347ee2..00000000 --- a/XPMP2-Remote/Utilities.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/// @file Utilities.cpp -/// @brief Miscellaneous utility functions, including logging -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#include "XPMP2-Remote.h" - -/// The one global variable object -XPMP2RCGlobals rcGlob; - -// -// MARK: Misc -// - -// Get total running time from X-Plane (sim/time/total_running_time_sec) -float GetMiscNetwTime() -{ - // must not use dataRefs from worker threads - if (!rcGlob.IsXPThread()) - return rcGlob.now; - - // In main thread we can fetch a new time - static XPLMDataRef drMiscNetwTime = XPLMFindDataRef("sim/network/misc/network_time_sec"); - return rcGlob.now = XPLMGetDataf(drMiscNetwTime); -} - -// Convenience function to check on something at most every x seconds -bool CheckEverySoOften (float& _lastCheck, float _interval, float _now) -{ - if (_lastCheck < 0.00001f || - _now >= _lastCheck + _interval) { - _lastCheck = _now; - return true; - } - return false; -} - -// Return a plugin's name -std::string GetPluginName (XPLMPluginID who) -{ - char whoName[256]; - XPLMGetPluginInfo(who, whoName, nullptr, nullptr, nullptr); - return whoName; -} - -// -// MARK: String functions -// - -// Copy _at most_ `n` chars from location, or less if zero-terminated. -std::string str_n (const char* s, size_t max) -{ - // find end of string, stopping at max - size_t i = 0; - for (; i < max && *(s+i) != '\0'; ++i); - return std::string(s,i); -} - - -// -//MARK: Log -// - -#if IBM -#define PATH_DELIM_STD '\\' -#else -#define PATH_DELIM_STD '/' -#endif - -const char* LOG_LEVEL[] = { - "DEBUG", "INFO ", "WARN ", "ERROR", "FATAL", "MSG " -}; - -// returns ptr to static buffer filled with log string -const char* LogGetString (const char* szPath, int ln, const char* szFunc, - logLevelTy lvl, const char* szMsg, va_list args ) -{ - static char aszMsg[2048]; - float runS = GetMiscNetwTime(); - const unsigned runH = unsigned(runS / 3600.0f); - runS -= runH * 3600.0f; - const unsigned runM = unsigned(runS / 60.0f); - runS -= runM * 60.0f; - - // prepare timestamp - if ( lvl < logMSG ) // normal messages without, all other with location info - { - const char* szFile = strrchr(szPath, PATH_DELIM_STD); // extract file from path - if ( !szFile ) szFile = szPath; else szFile++; - snprintf(aszMsg, sizeof(aszMsg), "%u:%02u:%06.3f %s %s %s:%d/%s: ", - runH, runM, runS, // Running time stamp - REMOTE_CLIENT_LOG, LOG_LEVEL[lvl], - szFile, ln, szFunc); - } - else - snprintf(aszMsg, sizeof(aszMsg), "%u:%02u:%06.3f %s: ", - runH, runM, runS, // Running time stamp - REMOTE_CLIENT_LOG); - - // append given message - if (args) { - vsnprintf(&aszMsg[strlen(aszMsg)], - sizeof(aszMsg)-strlen(aszMsg)-1, // we save one char for the CR - szMsg, - args); - } - - // ensure there's a trailing CR - size_t l = strlen(aszMsg); - if ( aszMsg[l-1] != '\n' ) - { - aszMsg[l] = '\n'; - aszMsg[l+1] = 0; - } - - // return the static buffer - return aszMsg; -} - -void LogMsg ( const char* szPath, int ln, const char* szFunc, logLevelTy lvl, const char* szMsg, ... ) -{ - va_list args; - - va_start (args, szMsg); - // write to log (flushed immediately -> expensive!) - XPLMDebugString ( LogGetString(szPath, ln, szFunc, lvl, szMsg, args) ); - va_end (args); -} diff --git a/XPMP2-Remote/Utilities.h b/XPMP2-Remote/Utilities.h deleted file mode 100644 index c47fb55f..00000000 --- a/XPMP2-Remote/Utilities.h +++ /dev/null @@ -1,134 +0,0 @@ -/// @file Utilities.h -/// @brief Miscellaneous utility functions, including logging -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#pragma once - -// -// MARK: General texts -// - -#define ERR_ASSERT "ASSERT FAILED: %s" -#define ERR_EXCEPTION "EXCEPTION CAUGHT: %s" - -// -// MARK: Misc -// - -/// Get synched network time from X-Plane (sim/network/misc/network_time_sec) as used in Log.txt -float GetMiscNetwTime (); - -/// @brief Convenience function to check on something at most every x seconds -/// @param _lastCheck Provide a float which holds the time of last check (init with `0.0f`) -/// @param _interval [seconds] How often to perform the check? -/// @param _now Current time, possibly from a call to GetTotalRunningTime() -/// @return `true` if more than `_interval` time has passed since `_lastCheck` -bool CheckEverySoOften (float& _lastCheck, float _interval, float _now); - -/// @brief Convenience function to check on something at most every x seconds -/// @param _lastCheck Provide a float which holds the time of last check (init with `0.0f`) -/// @param _interval [seconds] How often to perform the check? -/// @return `true` if more than `_interval` time has passed since `_lastCheck` -inline bool CheckEverySoOften (float& _lastCheck, float _interval) -{ return CheckEverySoOften(_lastCheck, _interval, GetMiscNetwTime()); } - -/// Return a plugin's name -std::string GetPluginName (XPLMPluginID who); - -// -// MARK: String functions -// - -/// @brief Copy _at most_ `n` chars from location, or less if zero-terminated. -/// @details Unlike std::string(char*, n) this will _not_ copy null chars -std::string str_n (const char* s, size_t max); - -/// Simplify using str_n() with char arrays -#define STR_N(s) str_n(s,sizeof(s)) - -// -// MARK: Logging Support -// - -/// @brief To apply printf-style warnings to our functions. -/// @see Taken from imgui.h's definition of IM_FMTARGS -#if defined(__clang__) || defined(__GNUC__) -#define XPMP2RC_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) -#else -#define XPMP2RC_FMTARGS(FMT) -#endif - -/// Logging level -enum logLevelTy : std::uint8_t { - logDEBUG = 0, ///< Debug, highest level of detail - logINFO, ///< regular info messages - logWARN, ///< warnings, i.e. unexpected, but uncritical events, maybe leading to unwanted display, but still: display of aircraft - logERR, ///< errors mean, aircraft can potentially not be displayed - logFATAL, ///< fatal is shortly before a crash - logMSG ///< will always be output, no matter what has been configured, cannot be suppressed -}; - -/// Returns ptr to static buffer filled with formatted log string -const char* LogGetString ( const char* szFile, int ln, const char* szFunc, logLevelTy lvl, const char* szMsg, va_list args ); - -/// Log Text to log file -void LogMsg ( const char* szFile, int ln, const char* szFunc, logLevelTy lvl, const char* szMsg, ... ) XPMP2RC_FMTARGS(5); - -// -// MARK: Logging macros -// - -/// @brief Log a message if lvl is greater or equal currently defined log level -/// @note First parameter after lvl must be the message text, -/// which can be a format string with its parameters following like in sprintf -#define LOG_MSG(lvl,...) { \ - if (lvl >= rcGlob.mergedS.logLvl) \ - {LogMsg(__FILE__, __LINE__, __func__, lvl, __VA_ARGS__);} \ -} - -/// @brief Throws an exception using XPMP2Error -/// @note First parameter after lvl must be the message text, -/// which can be a format string with its parameters following like in sprintf -#define THROW_ERROR(...) \ -throw XPMP2::XPMP2Error(__FILE__, __LINE__, __func__, __VA_ARGS__); - -/// @brief Throw in an assert-style (logging takes place in XPMP2Error constructor) -/// @note This conditional check _always_ takes place, independend of any build or logging settings! -#define LOG_ASSERT(cond) \ - if (!(cond)) { \ - THROW_ERROR(ERR_ASSERT,#cond); \ - } - -// -// MARK: Compiler differences -// - -// MARK: Thread names -#ifdef DEBUG -// This might not work on older Windows version, which is why we don't publish it in release builds -#if IBM -#define SET_THREAD_NAME(sName) SetThreadDescription(GetCurrentThread(), L##sName) -#elif APL -#define SET_THREAD_NAME(sName) pthread_setname_np(sName) -#elif LIN -#define SET_THREAD_NAME(sName) pthread_setname_np(pthread_self(),sName) -#endif -#else -#define SET_THREAD_NAME(sName) -#endif diff --git a/XPMP2-Remote/XPMP2-Remote.cpp b/XPMP2-Remote/XPMP2-Remote.cpp deleted file mode 100644 index 7e17c162..00000000 --- a/XPMP2-Remote/XPMP2-Remote.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/// @file XPMP2-Remote.cpp -/// @brief XPMP2 Remote Client: Displays aircraft served from other -/// XPMP2-based plugins in the network -/// @details This plugin is intended to be used in a multi-computer simulator -/// setup, usually in the PCs used for external visuals.\n -/// The typical setup would be: -/// - There is a multi-computer setup of one X-Plane Master PC, -/// which also runs one or more XPMP2-based plugins like LiveTraffic, -/// which create additional traffic, let's call them "traffic master". -/// - Other PCs serve to compute additional external visuals. -/// For them to be able to show the very same additional traffic -/// they run XPMP2 Remote Client, which will display a copy -/// of the traffic generated by the XPMP2-based plugin on the master. -/// -/// Technically, this works as follows: -/// - The "traffic masters" will first _listen_ -/// on the network if anyone is interested in their data. -/// - The XPMP2 Remote Client will first send a "beacon of interest" -/// message to the network. -/// - This messages tells the master plugins to start feeding their data. -/// - All communication is UDP multicast on the same multicast -/// group that X-Plane uses, too: 239.255.1.1, but on a different -/// port: 49788 -/// - This generic way allows for many different setups: -/// - While the above might be typical, it is not of interest if the -/// "traffic master" is running on the X-Plane Master or any -/// other X-Plane instance in the network, for example to -/// better balance the load. -/// - It could even be an X-Plane PC not included in the -/// External Visuals setup, like for example in a Networked -/// Multiplayer setup. -/// - Multiple XPMP2-based traffic masters can be active, and -/// they can even run on different PCs. The one XPMP2 Remote Client -/// per PC will still collect all traffic. -/// - If several traffic masters run on different PCs, then _all_ -/// PCs, including the ones running one of the traffic masters, -/// will need to run the XPMP2 Remote Client, so that they -/// pick up the traffic generated on the _other_ traffic masters. -/// -/// @see For multi-computer setup of external visual: -/// https://x-plane.com/manuals/desktop/#networkingmultiplecomputersformultipledisplays -/// @see For Networked Multiplayer: -/// https://x-plane.com/manuals/desktop/#networkedmultiplayer -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -// All headers are collected in one -#include "XPMP2-Remote.h" - -// -// MARK: Utility Functions -// - -/// This is a callback the XPMP2 calls regularly to learn about configuration settings. -/// Only 3 are left, all of them integers. -int CBIntPrefsFunc (const char *, [[maybe_unused]] const char * item, int defaultVal) -{ - // We always want to replace dataRefs and textures upon load to make the most out of the .obj files - if (!strcmp(item, XPMP_CFG_ITM_REPLDATAREFS)) return rcGlob.mergedS.bObjReplDataRefs; // taken from sending plugins - if (!strcmp(item, XPMP_CFG_ITM_REPLTEXTURE)) return rcGlob.mergedS.bObjReplTextures; // taken from sending plugins - if (!strcmp(item, XPMP_CFG_ITM_CLAMPALL)) return 0; // Never needed: The defining coordinates are sent to us, don't interpret them here in any way - if (!strcmp(item, XPMP_CFG_ITM_HANDLE_DUP_ID)) return 1; // must be on: if receiving from different plugins we can easily run in duplicate ids, which shall be handled - if (!strcmp(item, XPMP_CFG_ITM_SUPPORT_REMOTE)) return -1; // We don't want this plugin to ever _send_ traffic! - if (!strcmp(item, XPMP_CFG_ITM_LOGLEVEL)) return (int)rcGlob.mergedS.logLvl; // taken from sending plugins - if (!strcmp(item, XPMP_CFG_ITM_MODELMATCHING)) return rcGlob.mergedS.bLogMdlMatch; // taken from sending plugins - // Otherwise we just accept defaults - return defaultVal; -} - -// -// MARK: Menu / Command functionality -// - -XPLMMenuID hMenu = nullptr; ///< menu id of our plugin's menu -XPLMMenuID hLabels = nullptr; ///< menu id of the Labels submenu -XPLMMenuID hSenders = nullptr; ///< menu id of the Senders submenu -int numSendersInMenu = 0; ///< how many lines to we currently server in the menu? - -// menu indexes -constexpr std::uintptr_t MENU_ACTIVE = 0; -constexpr std::uintptr_t MENU_TCAS = 1; -constexpr std::uintptr_t MENU_LABELS = 2; -constexpr std::uintptr_t MENU_SENDER = 3; - -/// Command definition per menu item -struct CmdMenuDefTy { - const char* cmdName = nullptr; ///< command's name - const char* menuName = nullptr; ///< (initial) menu item's name - const char* description = nullptr; ///< human-readable command description - XPLMCommandRef hCmd = nullptr; ///< command reference assigned by X-Plane -} CMD_MENU_DEF[2] = { - { "XPMP2-Remote/Activate", "Active", "Toggle if Remote Client is active" }, - { "XPMP2-Remote/TCAS", "TCAS Control", "Toggle if Remote Client shall have TCAS control" }, -}; - -/// Sets all menu checkmarks according to current status -void MenuUpdateCheckmarks () -{ - // Menu item "Active" - switch (XPMP2::RemoteGetStatus()) { - case XPMP2::REMOTE_RECV_WAITING: - XPLMSetMenuItemName(hMenu, MENU_ACTIVE, "Active (waiting for data)", 0); - XPLMCheckMenuItem(hMenu, MENU_ACTIVE, xplm_Menu_Checked); - break; - - case XPMP2::REMOTE_RECEIVING: { - char s[50]; - snprintf (s, sizeof(s), "Active (%ld aircraft)", XPMPCountPlanes()); - XPLMSetMenuItemName(hMenu, MENU_ACTIVE, s, 0); - XPLMCheckMenuItem(hMenu, MENU_ACTIVE, xplm_Menu_Checked); - break; - } - - default: - XPLMSetMenuItemName(hMenu, MENU_ACTIVE, "Activate (currently inactive)", 0); - XPLMCheckMenuItem(hMenu, MENU_ACTIVE, xplm_Menu_Unchecked); - break; - } - - // Menu item "TCAS Control" (status display) - XPLMCheckMenuItem(hMenu, MENU_TCAS, XPMPHasControlOfAIAircraft() ? xplm_Menu_Checked : xplm_Menu_Unchecked); - - // Sub menu "Labels" - for (XPMP2RCGlobals::DrawLabelsTy e = XPMP2RCGlobals::LABELS_SYNCH; - e <= XPMP2RCGlobals::LABELS_OFF; e = XPMP2RCGlobals::DrawLabelsTy(e + 1)) - XPLMCheckMenuItem(hLabels, e, rcGlob.eDrawLabels == e ? xplm_Menu_Checked : xplm_Menu_Unchecked); -} - -/// (Re)Create the submenu listing information about connected senders -void MenuUpdateSenders () -{ - // Simple case first: There is no sender - if (rcGlob.gmapSender.empty()) { - // If we show anything we must remove it - if (numSendersInMenu > 0) { - XPLMClearAllMenuItems(hSenders); - XPLMAppendMenuItem(hSenders, "(none)", (void*)MENU_SENDER, 0); - numSendersInMenu = 0; - } - return; - } - - // There are senders, fill in their details - if (numSendersInMenu == 0) // physically there's always one menu item that we can re-use - numSendersInMenu++; - - // Cycle over senders and update textual information - int idx = 0; - for (const mapSenderTy::value_type& p: rcGlob.gmapSender) - { - const SenderTy& snd = p.second; - - // Put together plugin name, IP address, number of aircraft - std::string s (STR_N(snd.settings.name)); - if (!snd.bLocal) { - s += " @ "; - s += snd.sFrom; - } - s += ": "; - s += std::to_string(snd.mapAc.size()); - s += " aircraft"; - - // Do we need a new menu item or can we update an existing one? - if (idx < numSendersInMenu) - XPLMSetMenuItemName(hSenders, idx, s.c_str(), 0); - else { - XPLMAppendMenuItem(hSenders, s.c_str(), (void*)MENU_SENDER, 0); - numSendersInMenu++; - } - idx++; - } - - // Remove left-over menu items - while (idx < numSendersInMenu) - XPLMRemoveMenuItem(hSenders, --numSendersInMenu); -} - - -/// Callback function for menu -int CmdCallback (XPLMCommandRef cmdRef, XPLMCommandPhase inPhase, void*) -{ - // entry point into plugin...catch exceptions latest here - try { - if (inPhase == xplm_CommandBegin) { - if (cmdRef == CMD_MENU_DEF[0].hCmd) { - // Toggle activation of plugin - ClientToggleActive(); - } - else if (cmdRef == CMD_MENU_DEF[1].hCmd) { - // Toggle TCAS/AI status - if (XPMPHasControlOfAIAircraft()) - ClientReleaseAI(); - else - ClientTryGetAI(); - } - - // Update check marks...things might have changed - MenuUpdateCheckmarks(); - } - } - catch (const std::exception& e) { - LOG_MSG(logFATAL, ERR_EXCEPTION, e.what()); - } - return 1; -} - - -/// Callback function for the Labels submenu -void MenuLabelsCB (void* /*inMenuRef*/, void* inItemRef) -{ - // entry point into plugin...catch exceptions latest here - try { - XPMP2RCGlobals::DrawLabelsTy eDrawLabels = - XPMP2RCGlobals::DrawLabelsTy(reinterpret_cast(inItemRef)); - switch (eDrawLabels) { - // Enable label-drawing in principal - case XPMP2RCGlobals::LABELS_SYNCH: - case XPMP2RCGlobals::LABELS_ON: - rcGlob.eDrawLabels = eDrawLabels; - XPMPEnableAircraftLabels(); - break; - - // Disable label drawing completely - case XPMP2RCGlobals::LABELS_OFF: - rcGlob.eDrawLabels = XPMP2RCGlobals::LABELS_OFF; - XPMPDisableAircraftLabels(); - break; - } - // Update check marks...things might have changed - MenuUpdateCheckmarks(); - } - catch (const std::exception& e) { - LOG_MSG(logFATAL, ERR_EXCEPTION, e.what()); - } -} - -// -// MARK: Regular Tasks -// - -/// ID of our flight loop callback for regular tasks -XPLMFlightLoopID flId = nullptr; - -/// Regular tasks, called by flight loop -float FlightLoopCallback(float, float, int, void*) -{ - // entry point into plugin...catch exceptions latest here - try { - GetMiscNetwTime(); // update rcGlob.now, e.g. for logging from worker threads - // if there aren't any planes yet then the XPMP2 library won't call ClientFlightLoopBegins(), instead we do - if (XPMPCountPlanes() == 0) { - try { - // The first plane(s) would be instanciated here, and that could fail, e.g. if there are no CSL models installed - ClientFlightLoopBegins(); - } - catch (const std::exception& e) { - LOG_MSG(logFATAL, ERR_EXCEPTION, e.what()); - } - ClientFlightLoopEnds(); - } - MenuUpdateCheckmarks(); // update menu - MenuUpdateSenders(); - } - catch (const std::exception& e) { - LOG_MSG(logFATAL, ERR_EXCEPTION, e.what()); - } - - // call me every second only - return 1.0f; -} - -// -// MARK: Standard Plugin Callbacks -// - -PLUGIN_API int XPluginStart(char* outName, char* outSig, char* outDesc) -{ -#ifdef DEBUG - rcGlob.mergedS.logLvl = logDEBUG; -#endif - // this is the XP main thread - rcGlob.xpThread = std::this_thread::get_id(); - GetMiscNetwTime(); - - LOG_MSG(logMSG, "%s %.2f starting up...", REMOTE_CLIENT_NAME, REMOTE_CLIENT_VER); - - std::snprintf(outName, 255, "%s %.2f", REMOTE_CLIENT_NAME, REMOTE_CLIENT_VER); - std::strcpy(outSig, XPMP2::REMOTE_SIGNATURE); - std::strcpy(outDesc, "Remote Client displaying traffic generated by XPMP2-based plugins on the network"); - - // use native paths, i.e. Posix style (as opposed to HFS style) - // https://developer.x-plane.com/2014/12/mac-plugin-developers-you-should-be-using-native-paths/ - XPLMEnableFeature("XPLM_USE_NATIVE_PATHS",1); - - // The path separation character, one out of /\: - char pathSep = XPLMGetDirectorySeparator()[0]; - // The plugin's path, results in something like ".../Resources/plugins/XPMP2-Remote/64/XPMP2-Remote.xpl" - char szPath[256]; - rcGlob.mergedS.pluginId = std::uint16_t(XPLMGetMyID()); - XPLMGetPluginInfo(XPLMGetMyID(), nullptr, szPath, nullptr, nullptr); - *(std::strrchr(szPath, pathSep)) = 0; // Cut off the plugin's file name - *(std::strrchr(szPath, pathSep) + 1) = 0; // Cut off the "64" directory name, but leave the dir separation character - // We search in a subdirectory named "Resources" for all we need - std::string resourcePath = szPath; - resourcePath += "Resources"; // should now be something like ".../Resources/plugins/XPMP2-Sample/Resources" - - // Try initializing XPMP2: - const char* res = XPMPMultiplayerInit(REMOTE_CLIENT_NAME, // plugin name, - resourcePath.c_str(), // path to supplemental files - CBIntPrefsFunc, // configuration callback function - "A320", // default ICAO type - REMOTE_CLIENT_LOG2); // plugin short name - if (res[0]) { - LOG_MSG(logFATAL, "Initialization of XPMP2 failed: %s", res); - return 0; - } - - // Load our CSL models - res = XPMPLoadCSLPackage(resourcePath.c_str()); // CSL folder root path - if (res[0]) { - LOG_MSG(logERR, "Error while loading CSL packages: %s", res); - } - - // Create the menu for the plugin - int my_slot = XPLMAppendMenuItem(XPLMFindPluginsMenu(), REMOTE_CLIENT_NAME, NULL, 0); - hMenu = XPLMCreateMenu(REMOTE_CLIENT_NAME, XPLMFindPluginsMenu(), my_slot, NULL, NULL); - - // No CSL models installed? - if (XPMPGetNumberOfInstalledModels() <= 0) { - XPLMAppendMenuItem(hMenu, "Disabled - No CSL models installed!", (void*)MENU_ACTIVE, 0); - XPLMEnableMenuItem(hMenu, 0, false); - LOG_MSG(logFATAL, "There are no CSL models installed, XPMP2 Remote Client CANNOT START!"); - LOG_MSG(logFATAL, "Make sure the same set of CSL models is available under XPMP2-Remote/Resources as is for your sending plugins."); - return 1; - } - - // Define "proper" command and menu items - for (CmdMenuDefTy& cmdDef: CMD_MENU_DEF) { - cmdDef.hCmd = XPLMCreateCommand(cmdDef.cmdName, cmdDef.description); - XPLMRegisterCommandHandler(cmdDef.hCmd, CmdCallback, 1, NULL); - XPLMAppendMenuItemWithCommand(hMenu, cmdDef.menuName, cmdDef.hCmd); - } - - // The Labels submenu has 3 options - XPLMAppendMenuItem(hMenu, "Labels", (void*)MENU_LABELS, 0); - hLabels = XPLMCreateMenu("Labels", hMenu, MENU_LABELS, MenuLabelsCB, NULL); - XPLMAppendMenuItem(hLabels, "Synchronize", (void*)XPMP2RCGlobals::LABELS_SYNCH, 0); - XPLMAppendMenuItem(hLabels, "On", (void*)XPMP2RCGlobals::LABELS_ON, 0); - XPLMAppendMenuItem(hLabels, "Off", (void*)XPMP2RCGlobals::LABELS_OFF, 0); - - // The Senders submenu lists connected plugins with IP address and number of aircraft - XPLMAppendMenuItem(hMenu, "Senders", (void*)MENU_SENDER, 0); - hSenders = XPLMCreateMenu("Senders", hMenu, MENU_SENDER, NULL, NULL); - XPLMAppendMenuItem(hSenders, "(none)", (void*)MENU_SENDER, 0); - - MenuUpdateCheckmarks(); - - return 1; -} - -PLUGIN_API void XPluginStop(void) -{ - // Properly clean up - XPMPMultiplayerCleanup(); - -} - -PLUGIN_API int XPluginEnable(void) -{ - // Initialize the Client module - ClientInit(); - - // No CSL models installed? Then don't try starting - if (XPMPGetNumberOfInstalledModels() <= 0) { - return 1; - } - - // Create a flight loop callback for some regular tasks, called every second - XPLMCreateFlightLoop_t flParams = { - sizeof(flParams), // structSize - xplm_FlightLoop_Phase_BeforeFlightModel, // phase - FlightLoopCallback, // callbackFunc, - nullptr // refcon - }; - flId = XPLMCreateFlightLoop(&flParams); - XPLMScheduleFlightLoop(flId, 1.0f, true); - - // Activate the listener - ClientToggleActive(); - MenuUpdateCheckmarks(); - - // Success - LOG_MSG(logINFO, "Enabled"); - return 1; -} - -PLUGIN_API void XPluginDisable(void) -{ - // Stop our flight loop callback - if (flId) - XPLMDestroyFlightLoop(flId); - flId = nullptr; - - // Cleanup the client, also removes all planes - ClientCleanup(); - - LOG_MSG(logINFO, "Disabled"); -} - -PLUGIN_API void XPluginReceiveMessage(XPLMPluginID who, long inMsg, void*) -{ - // Some other plugin wants TCAS/AI control, but we never release automatically - if (inMsg == XPLM_MSG_RELEASE_PLANES) { - LOG_MSG(logINFO, "%s requested TCAS access, but we don't release automatically", GetPluginName(who).c_str()) - } -} diff --git a/XPMP2-Remote/XPMP2-Remote.h b/XPMP2-Remote/XPMP2-Remote.h deleted file mode 100644 index bfad09b0..00000000 --- a/XPMP2-Remote/XPMP2-Remote.h +++ /dev/null @@ -1,143 +0,0 @@ -/// @file XPMP2-Remote.h -/// @brief XPMP2 Remote Client: Displays aircraft served from other -/// XPMP2-based plugins in the network -/// @details This plugin is intended to be used in a multi-computer simulator -/// setup, usually in the PCs used for external visuals.\n -/// The typical setup would be: -/// - There is a multi-computer setup of one X-Plane Master PC, -/// which also runs one or more XPMP2-based plugins like LiveTraffic, -/// which create additional traffic, let's call them "traffic master". -/// - Other PCs serve to compute additional external visuals. -/// For them to be able to show the very same additional traffic -/// they run XPMP2 Remote Client, which will display a copy -/// of the traffic generated by the XPMP2-based plugin on the master. -/// -/// Technically, this works as follows: -/// - The "traffic masters" will first _listen_ -/// on the network if anyone is interested in their data. -/// - The XPMP2 Remote Client will first send a "beacon of interest" -/// message to the network. -/// - This messages tells the master plugins to start feeding their data. -/// - All communication is UDP multicast on the same multicast -/// group that X-Plane uses, too: 239.255.1.1, but on a different -/// port: 49788 -/// - This generic way allows for many different setups: -/// - While the above might be typical, it is not of interest if the -/// "traffic master" is running on the X-Plane Master or any -/// other X-Plane instance in the network, for example to -/// better balance the load. -/// - It could even be an X-Plane PC not included in the -/// External Visuals setup, like for example in a Networked -/// Multiplayer setup. -/// - Multiple XPMP2-based traffic masters can be active, and -/// they can even run on different PCs. The one XPMP2 Remote Client -/// per PC will still collect all traffic. -/// - If several traffic masters run on different PCs, then _all_ -/// PCs, including the ones running one of the traffic masters, -/// will need to run the XPMP2 Remote Client, so that they -/// pick up the traffic generated on the _other_ traffic masters. -/// -/// @see For multi-computer setup of external visual: -/// https://x-plane.com/manuals/desktop/#networkingmultiplecomputersformultipledisplays -/// @see For Networked Multiplayer: -/// https://x-plane.com/manuals/desktop/#networkedmultiplayer -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#pragma once - -// Standard C headers -#include -#include -#include -#include -#include - -// Standard C++ headers -#include -#include -#include -#include -#include -#include -#include -#include - -// X-Plane SDK -#include "XPLMDataAccess.h" -#include "XPLMUtilities.h" -#include "XPLMPlugin.h" -#include "XPLMMenus.h" -#include "XPLMProcessing.h" - -// Include XPMP2 headers -#include "XPMPAircraft.h" -#include "XPMPMultiplayer.h" -#include "XPMPRemote.h" - -// Include XPMP2-Remote headers -#include "Utilities.h" -#include "Client.h" - -// Windows: I prefer the proper SDK variants of min and max -#ifdef min -#undef min -#endif -#ifdef max -#undef max -#endif - -// -// MARK: Constants -// - -constexpr const char* REMOTE_CLIENT_NAME = "XPMP2 Remote Client"; ///< Plugin name -constexpr const char* REMOTE_CLIENT_LOG = "XPMP2_RC"; ///< ID used in own log entries -constexpr const char* REMOTE_CLIENT_LOG2 = "RC"; ///< Short ID used in XPMP2 log entries -constexpr float REMOTE_CLIENT_VER = 1.20f; ///< Version number for the XPMP2 Remote plugin - -// -// MARK: Globals -// - -/// Holds all global variables -struct XPMP2RCGlobals { - - /// Config values reconciled from sending plugins - XPMP2::RemoteMsgSettingsTy mergedS; - /// Shall aircraft labels be drawn at remote site? - enum DrawLabelsTy { - LABELS_SYNCH = 0, ///< Synchronize drawing of labels with sending client - LABELS_ON, ///< Always draw labels - LABELS_OFF, ///< Don't draw labels - } eDrawLabels = LABELS_SYNCH; ///< Shall aircraft labels be drawn at remote site? - - /// The global map of all sending plugins we've ever heard of - mapSenderTy gmapSender; - - /// Latest timestamp read from network_time_sec - float now = 0.0f; - - ///< id of X-Plane's thread (when it is OK to use XP API calls) - std::thread::id xpThread; - /// Is this thread XP's main thread? - bool IsXPThread() const { return std::this_thread::get_id() == xpThread; } -}; - -/// the one and only instance of XPMP2RCGlobals -extern XPMP2RCGlobals rcGlob; diff --git a/XPMP2-Remote/readme.html b/XPMP2-Remote/readme.html deleted file mode 100755 index 82129565..00000000 --- a/XPMP2-Remote/readme.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - XPMP2 Remote Client Readme - - - -

XPMP2 Remote Client Readme

- -

Documentation

- -

- For full documentation please visit - LiveTraffic/XPMP2 Remote Client on GitBook, - which also includes more details on installation. -

- -

Installation / External Visuals

- -

The typical basic installation is very simple:

- -
    -
  • You run a networked setup, in which one computer is the master. - The master also runs the latest version of XPMP2-based plugins - (like LiveTraffic, xPilot) just as usual - (the senders, because they will send the traffic);
  • -
  • On all other computers on the network install the - XPMP2 Remote Client as follows: -
      -
    • Move the XPMP2-Remote folder under X-Plane's - Resources/plugins folder as with any other plugin.
    • -
    • Install the same set of CSL Models, that your senders use, under the - XPMP2-Remote/Resources folder. - It is not required to rebuild the same folder structure - as CSL models are identified by internal names, - but all models need to be in reach if you want planes - to appear the same way as at your senders.
    • -
    -
  • -
- -

Installation / Local TCAS Concentrator

- -

You have several XPMP2-based plugins (like LiveTraffic, xPilot, - referred to as the senders) running in parallel and want to see - all their traffic on TCAS - (and not only the traffic of the plugin which happens to have TCAS control):

- -

Install XPMP2-Remote on the computer running the senders:

- -
    -
  • Move the XPMP2-Remote folder under X-Plane's - Resources/plugins folder as with any other plugin.
  • -
  • In this setup you don't even need to add all your CSL models - as the Remote Client doesn't actually render planes, - but for technical reasons at least one - model is still required.
  • -
- -

Resulting Directory Structure

- -

...under X-Plane's Resources/plugins folder:

- -

- XPMP2-Remote/
- XPMP2-Remote/lin_x64/XPMP2-Remote.xpl
- XPMP2-Remote/mac_x64/XPMP2-Remote.xpl
- XPMP2-Remote/win_x64/XPMP2-Remote.xpl
- XPMP2-Remote/Resources/CSL/... (here follow the CSL package folders)
- XPMP2-Remote/Resources/Doc8643.txt
- XPMP2-Remote/Resources/MapIcons.png
- XPMP2-Remote/Resources/Obj8DataRefs.txt
- XPMP2-Remote/Resources/related.txt
- XPMP2-Remote/Resources/XPMP2.example.prf
-

- -

Release Notes

- -

v1.x

- -

v1.20

- -

Update: In case of doubt you can always just copy all files from the archive over the files of your existing installation.

- -

At least copy the following files, which have changed compared to v1.10:

-
    -
  • lin|mac|win_x64/XPMP2-Remote.xpl
  • -
  • Resources/Doc8643.txt
  • -
  • Resources/related.txt
  • -
- -

Change log:

- -
    -
  • - ADDED #49 - control of aircraft labels via new sub-menu Labels: -
      -
    • - Synchronized (default) takes over the state of displaying labels - from the senders.
      - Note: Senders will require an update to send this info! - Until then, On is assumed. -
    • -
    • On always displays labels
    • -
    • Off switches off display of labels
    • -
    -
  • -
  • - Universal Mac binary for native support of Apple Silicon with XP12. -
  • -
- -

v1.10

- -

For updating coming from v1.00 -

    -
  • copy lin|mac|win_x64/XPMP2-Remote.xpl. -
-

- -

Change log:

- -
    -
  • ADDED #28 - commands XPMP2-Remote/Activate and - XPMP2-Remote/TCAS for menu items - Activate and TCAS Control - to bind keyboard shortcuts to them or trigger them via CMND network message.
  • -
  • ADDED #26 and - #27 - remote support for the set of - textual shared dataRefs.
  • -
  • ADDED #29 - signature and notarization to the Mac version.
  • -
- -

v1.00

- -

First public version.

- - - diff --git a/XPMP2-Sample/.gitignore b/XPMP2-Sample/.gitignore deleted file mode 100644 index b9ee09a9..00000000 --- a/XPMP2-Sample/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -.DS_Store -.localized -.image* -.vs/ -.vscode/ - -# Build directories -build*/* - -# XCode user specific files -xcuserdata/ -*.xcworkspace/ -*.mode1v3 -*.mode2v3 -*.perspectivev3 -*.pbxuser diff --git a/XPMP2-Sample/CMakeLists.txt b/XPMP2-Sample/CMakeLists.txt deleted file mode 100644 index 0b891f66..00000000 --- a/XPMP2-Sample/CMakeLists.txt +++ /dev/null @@ -1,210 +0,0 @@ -# XPMP2 - Set up to be used in the provided docker environment to build lin and mac -# Set up to be used in a Visual Studio environment to build win (File > Open > Folder, then VS recognized the CMAKE configuration) - -cmake_minimum_required(VERSION 3.16) - -# Mac: Need to tell early on that we want a cross platform build -if(DEFINED ENV{platform}) - message ("-- Platform is $ENV{platform}") - if($ENV{platform} STREQUAL "mac-x86") - message (" Building cross-platform for mac/x86_64") - set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "Archs to build") - elseif($ENV{platform} STREQUAL "mac-arm") - message (" Building cross-platform for mac/arm64") - set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "Archs to build") - endif() -else() - # No 'platform' defined could mean running from command line, assume we build universal image in one go via XCode - set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Archs to build") -endif() - -project(XPMP2-Sample - VERSION 2.50 - DESCRIPTION "XPMP2-Sample X-Plane plugin") - -# Provide compile macros from the above project version definition -add_compile_definitions( - XPMP2_VERSION="${PROJECT_VERSION}" - XPMP2_VER_MAJOR=${PROJECT_VERSION_MAJOR} - XPMP2_VER_MINOR=${PROJECT_VERSION_MINOR} -) - -message ("Compiler Info:") -message ("CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}") -message ("CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}") -message ("CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}") -message ("WIN32 / MSVC / MINGW = ${WIN32} / ${MSVC} / ${MINGW}") -message ("UNIX / APPLE = ${UNIX} / ${APPLE}") -if (APPLE) - message ("OSX_SDK_PATH = $ENV{OSX_SDK_PATH}") - message ("CMAKE_OSX_ARCHITECTURES = ${CMAKE_OSX_ARCHITECTURES}") -endif() - -################################################################################ -# Target Systems -################################################################################ - -# Windows: Target Windows 7.0 and later -if (WIN32) - add_compile_definitions(_WIN32_WINNT=0x0601) - if (NOT DEFINED ENV{platform}) - set(ENV{platform} "win") - endif() -elseif(APPLE) - set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0) - add_compile_options(-mmacosx-version-min=11.0) - add_link_options(-mmacosx-version-min=11.0) -endif() - -################################################################################ -# C++ Standard required -################################################################################ - -set(CMAKE_CXX_STANDARD 17) -set_property(GLOBAL PROPERTY CXX_STANDARD_REQUIRED 17) -set_property(GLOBAL PROPERTY CXX_STANDARD 17) - -################################################################################ -# Compile Options -################################################################################ - -# Enable all X-Plane SDK APIs up to the newest version. -add_compile_definitions(XPLM200=1 XPLM210=1 XPLM300=1 XPLM301=1 XPLM303=1) - -# Define platform macros. -add_compile_definitions(APL=$ IBM=$ LIN=$,$>>) - -# Enable stricter warnings and then disable some we are not interested in. -# For XPMP2 compile, we don't need to be warned about our self-defined depreciations -if (MSVC) - add_compile_options(/wd4996 /wd4068) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) -else() - add_compile_options(-Wall -Wshadow -Wno-float-equal -Wextra -Wno-deprecated-declarations -Wno-unknown-pragmas) - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0 AND NOT APPLE) - add_compile_options(-Wno-stringop-truncation) - endif() - - # Force-enable exception support. This is most likely redundant, although for C - # code the default is the opposite. Since we are mixing C++ and C libraries, - # safer to set it on? - add_compile_options(-fexceptions -fpermissive) - - # Makes symbols non-exported by default. - add_compile_options(-fvisibility=hidden) -endif() - - -# Debug vs Release build -if(CMAKE_BUILD_TYPE MATCHES "Debug") - add_compile_definitions(DEBUG=1) - if (MSVC) - add_compile_options(/Zi) - else() - add_compile_options(-O0 -g) - endif() -else() - add_compile_definitions(NDEBUG=1) - if(MSVC) - # Use highest optimization level in Release builds - add_compile_options(/GL) - elseif(APPLE) - add_compile_options(-O3 -fPIC) - elseif (UNIX OR MINGW) - # Use position-independent code and highest optimization level (FPS!). - add_compile_options(-O3 -fPIC) - # Strip symbols during linking - add_link_options(-s) - endif() -endif() - -################################################################################ -# Source Files -################################################################################ -add_library(XPMP2-Sample MODULE - lib/XPMP2.framework/Versions/${PROJECT_VERSION}/Headers/XPCAircraft.h - lib/XPMP2.framework/Versions/${PROJECT_VERSION}/Headers/XPMPAircraft.h - lib/XPMP2.framework/Versions/${PROJECT_VERSION}/Headers/XPMPMultiplayer.h - SDK/CHeaders/XPLM/XPLMDataAccess.h - SDK/CHeaders/XPLM/XPLMUtilities.h - SDK/CHeaders/XPLM/XPLMPlugin.h - SDK/CHeaders/XPLM/XPLMGraphics.h - SDK/CHeaders/XPLM/XPLMMenus.h - XPMP2-Sample.cpp -) - -# Header include directories -target_include_directories(XPMP2-Sample PRIVATE - ${ADDITIONAL_INCLUDES} - ${CMAKE_CURRENT_SOURCE_DIR}/SDK/CHeaders/XPLM - ${CMAKE_CURRENT_SOURCE_DIR}/lib/XPMP2.framework/Versions/${PROJECT_VERSION}/Headers -) - - -################################################################################ -# Link Libraries -################################################################################ - -# Specify library search locations, especially for X-Plane SDK -# XPMP2 path is hard-coded. Couldn't convince find_library to distinguish libXPMP2.a from XPMP2.lib in Mingw vs MSVC build. -if (APPLE) - list(APPEND CMAKE_FRAMEWORK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib" "${CMAKE_CURRENT_SOURCE_DIR}/SDK/Libraries/Mac") -else () - list(APPEND CMAKE_LIBRARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/SDK/Libraries/Win" "${CMAKE_CURRENT_SOURCE_DIR}/lib/$ENV{platform}") -endif () - -# Link the XPMP2 library -find_library(XPMP2_LIBRARY XPMP2 REQUIRED) -message ("XPMP2_LIBRARY = ${XPMP2_LIBRARY}") -target_link_libraries(XPMP2-Sample ${XPMP2_LIBRARY}) - - -# Link X-Plane plugin system libraries. They are only provided for OS X and Windows. -if (WIN32 OR APPLE) - find_library(XPLM_LIBRARY XPLM REQUIRED NAMES XPLM_64.lib) - message ("XPLM_LIBRARY = ${XPLM_LIBRARY}") - target_link_libraries(XPMP2-Sample ${XPLM_LIBRARY}) -endif () - - -if (WIN32) - # Link with winsock for network and iphlpapi for GetAdaptersAddresses - target_link_libraries(XPMP2-Sample wsock32 ws2_32 iphlpapi) - if (MINGW) - # When cross-compiling we link the standard libraries statically - target_link_options(XPMP2-Sample PRIVATE -static-libgcc -static-libstdc++) - endif() -elseif (APPLE) - # Link OS X core system libraries. - find_library(IOKIT_LIBRARY IOKit REQUIRED) - find_library(CORE_FOUNDATION_LIBRARY CoreFoundation REQUIRED) - target_link_libraries(XPMP2-Sample ${IOKIT_LIBRARY} ${CORE_FOUNDATION_LIBRARY}) - # Restrict set of symbols exported from the plugin to the ones required by XPLM: - target_link_options(XPMP2-Sample PRIVATE "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample.sym_mac") -elseif (UNIX) - # Threads and dynamic loading - find_library(DL_LIBRARY dl REQUIRED) - set(CMAKE_THREAD_PREFER_PTHREAD TRUE) - set(THREADS_PREFER_PTHREAD_FLAG TRUE) - find_package(Threads REQUIRED) - target_link_libraries(XPMP2-Sample ${DL_LIBRARY} Threads::Threads) - # Restrict set of symbols exported from the plugin to the ones required by XPLM: - target_link_options(XPMP2-Sample PRIVATE -Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/XPMP2-Sample.sym) -endif () - - -# Target directory and file name -if (WIN32) - set_target_properties(XPMP2-Sample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/win_x64") -elseif (APPLE) - set_target_properties(XPMP2-Sample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/mac_x64") -elseif (UNIX) - set_target_properties(XPMP2-Sample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lin_x64") -endif () - -set_target_properties(XPMP2-Sample - PROPERTIES - PREFIX "" - OUTPUT_NAME "XPMP2-Sample" - SUFFIX ".xpl" -) diff --git a/XPMP2-Sample/CMakeSettings.json b/XPMP2-Sample/CMakeSettings.json deleted file mode 100644 index ff228eaf..00000000 --- a/XPMP2-Sample/CMakeSettings.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "configurations": [ - { - "name": "x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\build-win\\${name}", - "installRoot": "${projectDir}\\build-win\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "-v", - "ctestCommandArgs": "", - "variables": [ - { - "name": "CMAKE_CXX_FLAGS", - "value": "/DWIN32 /D_WINDOWS /DWIN32_LEAN_AND_MEAN /D_CRT_SECURE_NO_WARNINGS /GS- /Gd /Gy- /Zc:wchar_t /Zc:forScope /Zc:inline /Zc:__cplusplus /W4 /EHsc /fp:precise /diagnostics:column", - "type": "STRING" - }, - { - "name": "CMAKE_CXX_FLAGS_DEBUG", - "value": "/MDd /Od /RTC1 /Zi /DDEBUG", - "type": "STRING" - }, - { - "name": "CMAKE_MODULE_LINKER_FLAGS", - "value": "/machine:x64", - "type": "STRING" - }, - { - "name": "CMAKE_MODULE_LINKER_FLAGS_DEBUG", - "value": "/debug /INCREMENTAL:NO", - "type": "STRING" - } - ] - }, - { - "name": "x64-Release", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "buildRoot": "${projectDir}\\build-win\\${name}", - "installRoot": "${projectDir}\\build-win\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "-v", - "ctestCommandArgs": "", - "inheritEnvironments": [ "msvc_x64_x64" ], - "variables": [ - { - "name": "CMAKE_CXX_FLAGS", - "value": "/DWIN32 /D_WINDOWS /DWIN32_LEAN_AND_MEAN /D_CRT_SECURE_NO_WARNINGS /GS- /Gd /Gy- /Zc:wchar_t /Zc:forScope /Zc:inline /Zc:__cplusplus /W4 /EHsc /fp:precise /diagnostics:column", - "type": "STRING" - }, - { - "name": "CMAKE_CXX_FLAGS_RELWITHDEBINFO", - "value": "/MD /Zi /GL /O2 /DNDEBUG", - "type": "STRING" - }, - { - "name": "CMAKE_MODULE_LINKER_FLAGS", - "value": "/machine:x64", - "type": "STRING" - }, - { - "name": "CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO", - "value": "/LTCG /debug /INCREMENTAL:NO", - "type": "STRING" - } - ] - } - ] -} \ No newline at end of file diff --git a/XPMP2-Sample/README.md b/XPMP2-Sample/README.md deleted file mode 100644 index 7c2f6f91..00000000 --- a/XPMP2-Sample/README.md +++ /dev/null @@ -1,60 +0,0 @@ -XPMP2 Sample Plugin -========= - -This is a fully functional sample implementation that you can use to play with -XPMP2 features and as a starting point for your own implementations. - -I am also using it as a testbed for new features, so the implementation -is regularly built, tested, and sometimes even enhanced to make use of -latest features. - -## Build ## - -There are separate projects available to only build the XPMP2-Sample plugin, -serving as a starting point for your projects. - -Please refer to the -[GitHub Build documentation](https://twinfan.github.io/XPMP2/Building.html) -for details. - -## Features ## - -This plugin creates 3 planes, one with each of the available ways of using the XPMP2 library. -All planes move in a circle around a position 200m in front of the user's plane -(even if the user plane moves). -1. Subclassing `XPMP2::Aircraft` in `class SampleAircraft`, - which is the recommended way for any new plugin. This plane flies - highest, 100m above the user plane. -2. Subclassing the legacy `class XPCAircraft`. This plane flies in the middle, - 50m above the user plane. -3. Using direct C functions. This plane always rolls on the ground, no matter how - high the user plane flies. - -Three menu items are provided: - - 1. "Toggle Planes" creates/removes the planes. - 2. "Toggle Visibility" shows/temporary hides the planes without destroying them. - 3. "Cycle Models" changes the CSL model used per plane. - Also, it flips the visibility of labels in the map view...just for a change. - -## Installation ## - -For the plugin to work properly some CSL models are necessary in some folders -under `Resources` (all folders under `Resources` are scanned for -`xsb_aircraft.txt` file, so the actual structure underneath `Resources` does not matter). - -The directory structure would look as follows: -``` -XPMP2-Sample/ -  lin_x64/ -    XPMP2-Sample.xpl -  mac_x64/ -    XPMP2-Sample.xpl -  win_x64/ -    XPMP2-Sample.xpl -  Resources/ - CSL/ <-- install CSL models here -    Doc8643.txt - MapIcons.png - Obj8DataRefs.txt -    related.txt diff --git a/XPMP2-Sample/XPMP2-Sample.cpp b/XPMP2-Sample/XPMP2-Sample.cpp deleted file mode 100644 index 16ac10ce..00000000 --- a/XPMP2-Sample/XPMP2-Sample.cpp +++ /dev/null @@ -1,1020 +0,0 @@ -/// @file XPMP2-Sample.cpp -/// @brief Example plugin demonstrating XPMP2 techniques -/// @details This plugin creates 3 planes, one with each of the available ways of using the XPMP2 library. -/// All planes move in a circle around a position 200m in front of the user's plane -/// (even if the user plane moves). -/// -/// 1. Subclassing XPMP2::Aircraft, which is the recommended way. This plane flies -/// highest, 100m above the user plane. -/// 2. Subclassing the legacy class XPCAircraft. This plane flies in the middle, 50m above the user plane. -/// 3. Using direct C functions. This plane always rolls on the ground, no matter how -/// high the user plane flies. -/// -/// Three menu items are provided: -/// -/// 1. "Toggle Planes" creates/removes the planes. -/// 2. "Toggle Visibility" shows/temporary hides the planes without destroying them. -/// 3. "Cycle Models" changes the CSL model used per plane. -/// Also, it flips the visibility of labels in the map view...just for a change. -/// -/// For the plugin to work properly some CSL models are necessary in some folders -/// under `Resources` (all folders under `Resources` are scanned for -/// `xsb_aircraft.txt` file, so the actual structure underneath `Resources` does not matter). -/// -/// The directory structure would look as follows:\n -/// `XPMP2-Sample/`\n -/// `  lin_x64/`\n -/// `    XPMP2-Sample.xpl`\n -/// `  mac_x64/`\n -/// `    XPMP2-Sample.xpl`\n -/// `  win_x64/`\n -/// `    XPMP2-Sample.xpl`\n -/// `  Resources/`\n -/// ` CSL/ <-- install CSL models here`\n -/// `    Doc8643.txt`\n -/// ` MapIcons.png`\n -/// ` Obj8DataRefs.txt`\n -/// `    related.txt`\n -/// -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -// Standard C headers -#include -#include -#include -#include - -// X-Plane SDK -#include "XPLMDataAccess.h" -#include "XPLMUtilities.h" -#include "XPLMPlugin.h" -#include "XPLMGraphics.h" -#include "XPLMMenus.h" - -// Include XPMP2 headers -#include "XPCAircraft.h" -#include "XPMPAircraft.h" -#include "XPMPMultiplayer.h" - -#if !XPLM300 - #error This plugin requires version 300 of the SDK -#endif - -/// Initial type / airline / livery to be used to create our 3 planes -/// @see https://www.icao.int/publications/DOC8643/Pages/Search.aspx for ICAO aircraft types - -/// @see https://forums.x-plane.org/index.php?/files/file/37041-bluebell-obj8-csl-packages/ for the Bluebell package, which includes the models named here -std::string PLANE_MODEL[3][3] = { - { "DH8A", "BER", "" }, - { "B06", "TXB", "" }, - { "A321", "", "" }, // Not specifying the airline means: XPMP2 will randomly take any airline's model - with every switch of models -}; - -// -// MARK: Utility Functions -// - -/// Log a message to X-Plane's Log.txt with sprintf-style parameters -void LogMsg (const char* szMsg, ... ) -{ - char buf[512]; - va_list args; - // Write all the variable parameters - va_start (args, szMsg); - std::vsnprintf(buf, sizeof(buf)-2, szMsg, args); - va_end (args); - std::strcat(buf, "\n"); - // write to log (flushed immediately -> expensive!) - XPLMDebugString(buf); -} - -/// This is a callback the XPMP2 calls regularly to learn about configuration settings. -/// Only 3 are left, all of them integers. -int CBIntPrefsFunc (const char *, [[maybe_unused]] const char * item, int defaultVal) -{ - // We always want to replace dataRefs and textures upon load to make the most out of the .obj files - if (!strcmp(item, XPMP_CFG_ITM_REPLDATAREFS)) return 1; - if (!strcmp(item, XPMP_CFG_ITM_REPLTEXTURE)) return 1; // actually...this is ON by default anyway, just to be sure -#if DEBUG - // in debug version of the plugin we provide most complete log output - if (!strcmp(item, XPMP_CFG_ITM_MODELMATCHING)) return 1; - if (!strcmp(item, XPMP_CFG_ITM_LOGLEVEL)) return 0; // DEBUG logging level -#endif - // Otherwise we just accept defaults - return defaultVal; -} - -/// This is the callback for the plane notifier function, which just logs some info to Log.txt -/// @note Plane notifier functions are completely optional and actually rarely used, -/// because you should know already by other means when your plugin creates/modifies/deletes a plane. -/// So this is for pure demonstration (and testing) purposes. -void CBPlaneNotifier(XPMPPlaneID inPlaneID, - XPMPPlaneNotification inNotification, - void * /*inRefcon*/) -{ - XPMP2::Aircraft* pAc = XPMP2::AcFindByID(inPlaneID); - if (pAc) { - LogMsg("XPMP2-Sample: Plane of type %s, airline %s, model %s, label '%s' %s", - pAc->acIcaoType.c_str(), - pAc->acIcaoAirline.c_str(), - pAc->GetModelName().c_str(), - pAc->label.c_str(), - inNotification == xpmp_PlaneNotification_Created ? "created" : - inNotification == xpmp_PlaneNotification_ModelChanged ? "changed" : "destroyed"); - } -} - -// -// MARK: Helper functions for position calculations -// - -/// Distance of our simulated planes to the user's plane's position? [m] -constexpr float PLANE_DIST_M = 200.0f; -/// Radius of the circle the planes do [m] -constexpr float PLANE_RADIUS_M = 100.0f; -/// Altitude difference to stack the 3 planes one above the other [m] -constexpr float PLANE_STACK_ALT_M = 50.0f; -/// Time it shall take to fly/roll a full circle [seconds] -constexpr float PLANE_CIRCLE_TIME_S = 20.0f; -/// Time it shall take to fly/roll a full circle [minutes] -constexpr float PLANE_CIRCLE_TIME_MIN = PLANE_CIRCLE_TIME_S / 60.0f; -/// Assumed circumfence of one plane's tire (rough guess for commercial jet planes) -constexpr float PLANE_TIRE_CIRCUMFENCE_M = 3.2f; -/// Engine / prop rotation assumptions: rotations per minute -constexpr float PLANE_PROP_RPM = 300.0f; - -/// PI -constexpr double PI = 3.1415926535897932384626433832795028841971693993751; - -/// Summarizes the 3 values of a position in the local coordinate system -struct positionTy { - double x = 0.0f; - double y = 0.0f; - double z = 0.0f; -}; - -/// Position of user's plane -static XPLMDataRef dr_x = XPLMFindDataRef("sim/flightmodel/position/local_x"); // double -static XPLMDataRef dr_y = XPLMFindDataRef("sim/flightmodel/position/local_y"); // double -static XPLMDataRef dr_z = XPLMFindDataRef("sim/flightmodel/position/local_z"); // double -static XPLMDataRef dr_heading = XPLMFindDataRef("sim/flightmodel/position/psi"); // float -static XPLMDataRef dr_time = XPLMFindDataRef("sim/time/total_running_time_sec"); // float - -/// Returns a number between 0.0 and 1.0, increasing over the course of 10 seconds, then restarting -inline float GetTimeFragment () -{ - const float t = XPLMGetDataf(dr_time); - return std::fmod(t, PLANE_CIRCLE_TIME_S) / PLANE_CIRCLE_TIME_S; -} - -/// Returns a number between 0.0 and 1.0, going up and down over the course of 10 seconds -inline float GetTimeUpDown () -{ - return std::abs(std::fmod(XPLMGetDataf(dr_time), PLANE_CIRCLE_TIME_S) / (PLANE_CIRCLE_TIME_S/2.0f) - 1.0f); -} - -/// Convert from degree to radians -inline double deg2rad (const double deg) { return (deg * PI / 180.0); } - -/// Save string copy -inline char* strScpy (char* dest, const char* src, size_t size) -{ - strncpy(dest, src, size); - dest[size-1] = 0; // this ensures zero-termination! - return dest; -} - -/// Finds a position 200m in front of the user's plane serving as the center for further operations -positionTy FindCenterPos (float dist) -{ - // Current user's plane's position and heading (relative to Z) - positionTy pos = { - XPLMGetDatad(dr_x), - XPLMGetDatad(dr_y), - XPLMGetDatad(dr_z) - }; - float heading = XPLMGetDataf(dr_heading); - - // Move point 200m away from aircraft, direction of its heading - const double head_rad = deg2rad(heading); - pos.x += sin(head_rad) * dist; // east axis - pos.z -= cos(head_rad) * dist; // south axis - - return pos; -} - -/// Put the position on a circle around itself -void CirclePos (positionTy& pos, - float heading, - float radius) -{ - const double head_rad = deg2rad(heading); - pos.x += radius * sin(head_rad); // east axis - pos.z -= radius * cos(head_rad); // south axis -} - -/// Convert local position to world coordinates -void ConvLocalToWorld (const positionTy& pos, - double& lat, double& lon, double& alt) -{ - XPLMLocalToWorld(pos.x, pos.y, pos.z, - &lat, &lon, &alt); -} - -// -// MARK: Using XPMP2 - New XPMP2::Aircraft class -// This is the new and recommended way of using the library: -// Deriving a class from XPMP2::Aircraft and providing -// a custom implementation for UpdatePosition(), -// which provides all current values in one go directly into -// the member variables, which are later on used for -// controlling the plane objects. This avoids any unnecessary copying -// within the library - -using namespace XPMP2; - -/// Subclassing XPMP2::Aircraft to create our own class -class SampleAircraft : public Aircraft -{ -public: - /// Constructor just passes on all parameters to library - SampleAircraft(const std::string& _icaoType, - const std::string& _icaoAirline, - const std::string& _livery, - XPMPPlaneID _modeS_id = 0, - const std::string& _cslId = "") : - Aircraft(_icaoType, _icaoAirline, _livery, _modeS_id, _cslId) - { - // in our sample implementation, label, radar and info texts - // are not dynamic. In others, they might be, then update them - // in UpdatePosition() - - // Label - label = "XPMP2::Aircraft"; - colLabel[0] = 0.0f; // green - colLabel[1] = 1.0f; - colLabel[2] = 0.0f; - - // Radar - acRadar.code = 7654; - acRadar.mode = xpmpTransponderMode_ModeC; - - // informational texts - strScpy(acInfoTexts.icaoAcType, _icaoType.c_str(), sizeof(acInfoTexts.icaoAcType)); - strScpy(acInfoTexts.icaoAirline, _icaoAirline.c_str(), sizeof(acInfoTexts.icaoAirline)); - strScpy(acInfoTexts.tailNum, "D-EVEL", sizeof(acInfoTexts.tailNum)); - } - - /// Custom implementation for the virtual function providing updates values - virtual void UpdatePosition (float, int) - { - // Calculate the plane's position - const float angle = std::fmod(360.0f * GetTimeFragment(), 360.0f); - positionTy pos = FindCenterPos(PLANE_DIST_M); // relative to user's plane - CirclePos(pos, angle, PLANE_RADIUS_M); // turning around a circle - pos.y += PLANE_STACK_ALT_M * 2; // 100m above user's aircraft - - // Strictly speaking...this is not necessary, we could just write - // directly to drawInfo.x/y/z with above values (for y: + GetVertOfs()), - // but typically in a real-world application you would actually - // have lat/lon/elev...and then the call to SetLocation() is - // what you shall do: - double lat, lon, elev; - // location in lat/lon/feet - XPLMLocalToWorld(pos.x, pos.y, pos.z, &lat, &lon, &elev); - elev /= M_per_FT; // we need elevation in feet - - // So, here we tell the plane its position, which takes care of vertical offset, too - SetLocation(lat, lon, elev, false); - - // further attitude information - SetPitch(0.0f); - SetHeading(std::fmod(90.0f + angle, 360.0f)); - SetRoll(20.0f); - - // Plane configuration info - // This fills a large array of float values: - const float r = GetTimeUpDown(); // a value between 0 and 1 - SetGearRatio(r); - SetNoseWheelAngle(r * 90.0f - 45.0f); // turn nose wheel -45°..+45° - SetFlapRatio(r); - SetSpoilerRatio(r); - SetSpeedbrakeRatio(r); - SetSlatRatio(r); - SetWingSweepRatio(0.0f); - SetThrustRatio(0.5f); - SetYokePitchRatio(r); - SetYokeHeadingRatio(r); - SetYokeRollRatio(r); - - // lights - SetLightsTaxi(false); - SetLightsLanding(false); - SetLightsBeacon(true); - SetLightsStrobe(true); - SetLightsNav(true); - - // tires don't roll in the air - SetTireDeflection(0.0f); - SetTireRotAngle(0.0f); - SetTireRotRpm(0.0f); // also sets the rad/s value! - - // For simplicity, we keep engine and prop rotation identical...probably unrealistic - SetEngineRotRpm(1,PLANE_PROP_RPM); // also sets the rad/s value! - // 2nd engine shall turn 4 times slower... - SetEngineRotRpm(2,PLANE_PROP_RPM/4); // also sets the rad/s value! - - SetPropRotRpm(PLANE_PROP_RPM); // also sets the rad/s value! - - // Current position of engine / prop: keeps turning as per engine/prop speed: - float deg = std::fmod(PLANE_PROP_RPM * PLANE_CIRCLE_TIME_MIN * GetTimeFragment() * 360.0f, - 360.0f); - SetEngineRotAngle(1,deg); - // 2nd engine shall turn 4 times slower... - deg = std::fmod(PLANE_PROP_RPM/4 * PLANE_CIRCLE_TIME_MIN * GetTimeFragment() * 360.0f, - 360.0f); - SetEngineRotAngle(2,deg); - - SetPropRotAngle(deg); - - // no reversers and no moment of touch-down in flight - SetThrustReversRatio(0.0f); - SetReversDeployRatio(0.0f); - SetTouchDown(false); - } - -}; - -/// The one aircraft of this type that we manage -SampleAircraft* pSamplePlane = nullptr; - - -// -// MARK: Using XPMP2 - Legacy XPCAircraft class -// XPCAircraft was a wrapper class offered in the original library -// already. It now is derived from XPMP2's main class, -// XPMP2::Aircraft, to provide the same interface as before. -// Still, it is deprecated and should not be used in new applications. -// Derive directly from XPMP2::Aircraft instead. -// -// This plane will be 50m higher than user's plane, -// circling 200m in front of user's plane. -// - -/// Subclassing XPCAircraft to create our own class -class LegacySampleAircraft : public XPCAircraft -{ -public: - /// Constructor just passes on all parameters to library - LegacySampleAircraft(const char* inICAOCode, - const char* inAirline, - const char* inLivery, - XPMPPlaneID _modeS_id = 0, - const char* inModelName = nullptr) : - XPCAircraft(inICAOCode, inAirline, inLivery, _modeS_id, inModelName) {} - - // My own class overwrites the individual data provision functions - - /// Called before rendering to query plane's current position, overwritten to provide your implementation - virtual XPMPPlaneCallbackResult GetPlanePosition(XPMPPlanePosition_t* outPosition) - { - // Calculate the plane's position - const float angle = std::fmod(120.0f + 360.0f * GetTimeFragment(), 360.0f); - positionTy pos = FindCenterPos(PLANE_DIST_M); // relative to user's plane - CirclePos(pos, angle, PLANE_RADIUS_M); // turning around a circle - pos.y += PLANE_STACK_ALT_M; // 50m above user's aircraft - - // fill the XPMP2 data structure - - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (outPosition->size < (long)sizeof(XPMPPlanePosition_t)) - return xpmpData_Unavailable; - - // location in lat/lon/feet - XPLMLocalToWorld(pos.x, pos.y, pos.z, - &outPosition->lat, - &outPosition->lon, - &outPosition->elevation); // elevation is now given in meter - outPosition->elevation /= M_per_FT; // put it is expected in feet! - - outPosition->pitch = 0.0f; - outPosition->roll =20.0f; // rolled 20° right (tight curve!) - outPosition->heading = std::fmod(90.0f + angle, 360.0f); - strcpy ( outPosition->label, "XPCAircraft subclassed"); - outPosition->offsetScale = 1.0f; // so that full vertical offset is applied and plane sits on its wheels (should probably always be 1.0) - outPosition->clampToGround = false; - outPosition->aiPrio = 1; - outPosition->label_color[0] = 1.0f; // yellow - outPosition->label_color[1] = 1.0f; - outPosition->label_color[2] = 0.0f; - outPosition->label_color[3] = 1.0f; - return xpmpData_NewData; - } - - /// Called before rendering to query plane's current configuration, overwritten to provide your implementation - virtual XPMPPlaneCallbackResult GetPlaneSurfaces(XPMPPlaneSurfaces_t* outSurfaces) - { - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (outSurfaces->size < (long)sizeof(XPMPPlaneSurfaces_t)) - return xpmpData_Unavailable; - - // gear & flight surfaces keep moving for show - outSurfaces->yokePitch = - outSurfaces->yokeHeading = - outSurfaces->yokeRoll = - outSurfaces->gearPosition = - outSurfaces->flapRatio = - outSurfaces->spoilerRatio = - outSurfaces->speedBrakeRatio = - outSurfaces->slatRatio = GetTimeUpDown(); - outSurfaces->thrust = 0.5f; - - // lights: taxi, beacon, and nav lights - outSurfaces->lights.timeOffset = 0; // unused in XPMP2 - outSurfaces->lights.taxiLights = 1; - outSurfaces->lights.landLights = 1; - outSurfaces->lights.bcnLights = 1; - outSurfaces->lights.strbLights = 1; - outSurfaces->lights.navLights = 1; - outSurfaces->lights.flashPattern = xpmp_Lights_Pattern_Default; // unused in XPMP2 - - // tires don't roll in the air - outSurfaces->tireDeflect = 0; - outSurfaces->tireRotDegree = 0; - outSurfaces->tireRotRpm = 0; - - // For simplicity, we keep engine and prop rotation identical...probably unrealistic - constexpr float PROP_REVOLUTIONS = PLANE_PROP_RPM * PLANE_CIRCLE_TIME_MIN; - outSurfaces->engRotRpm = - outSurfaces->propRotRpm = PLANE_PROP_RPM; - outSurfaces->engRotDegree = - outSurfaces->propRotDegree = std::fmod(PROP_REVOLUTIONS * GetTimeFragment() * 360.0f, - 360.0f); - // no reversers in flight - outSurfaces->reversRatio = 0.0f; - - outSurfaces->touchDown = false; - - return xpmpData_NewData; - } - - /// Called before rendering to query plane's current radar visibility, overwritten to provide your implementation - virtual XPMPPlaneCallbackResult GetPlaneRadar(XPMPPlaneRadar_t* outRadar) - { - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (outRadar->size < (long)sizeof(XPMPPlaneRadar_t)) - return xpmpData_Unavailable; - - if (outRadar->code != 4711) { - outRadar->code = 4711; - outRadar->mode = xpmpTransponderMode_ModeC; - return xpmpData_NewData; - } - else - return xpmpData_Unchanged; - } - - /// @brief Called before rendering to query plane's textual information, overwritten to provide your implementation (optional) - /// @details Handling this requests is completely optional. The texts are - /// provided on shared dataRefs and used only by few other plugins, - /// one of it is FSTramp.\n - /// Here in the example we keep it simple and just return some known data. - virtual XPMPPlaneCallbackResult GetInfoTexts(XPMPInfoTexts_t * outInfoTexts) - { - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (outInfoTexts->size < (long)sizeof(XPMPInfoTexts_t)) - return xpmpData_Unavailable; - - if (acIcaoType != outInfoTexts->icaoAcType || - acIcaoAirline != outInfoTexts->icaoAirline) { - strScpy(outInfoTexts->icaoAcType, acIcaoType.c_str(), sizeof(outInfoTexts->icaoAcType)); - strScpy(outInfoTexts->icaoAirline, acIcaoAirline.c_str(), sizeof(outInfoTexts->icaoAirline)); - strScpy(outInfoTexts->flightNum, "LH1234", sizeof(outInfoTexts->flightNum)); - return xpmpData_NewData; - } - else - return xpmpData_Unchanged; - } - -}; - -/// The one aircraft of this type that we manage -LegacySampleAircraft* pLegacyPlane = nullptr; - -// -// MARK: Using XPMP2 - Standard C Functions -// This plane will always be on the ground, ie. its altitude is -// calculated to be on ground level, gear is down. -// The plane's label for display is "Standard C" in red. -// - -/// We handle just one aircraft with standard functions, this one: -XPMPPlaneID hStdPlane = 0; - -/// @brief Handles requests for plane's position data -/// @see LegacySampleAircraft::GetPlanePosition(), which basically is the very same thing. -XPMPPlaneCallbackResult SetPositionData (XPMPPlanePosition_t& data) -{ - // Calculate the plane's position - const float angle = std::fmod(240.0f + 360.0f * GetTimeFragment(), 360.0f); - positionTy pos = FindCenterPos(PLANE_DIST_M); // relative to user's plane - CirclePos(pos, angle, PLANE_RADIUS_M); // turning around a circle - - // fill the XPMP2 data structure - - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (data.size < (long)sizeof(XPMPPlanePosition_t)) - return xpmpData_Unavailable; - - // location in lat/lon/feet - XPLMLocalToWorld(pos.x, pos.y, pos.z, - &data.lat, - &data.lon, - &data.elevation); // elevation is now given in meter - - // We place this plane firmly on the ground using XPMP2's "ground clamping" - data.elevation = -500.0f; // below ground - data.clampToGround = true; // move on ground - - data.pitch = 0.0f; // plane stays level - data.roll = 0.0f; - data.heading = std::fmod(90.0f + angle, 360.0f); - strcpy ( data.label, "Standard C"); - data.offsetScale = 1.0f; // so that full vertical offset is applied and plane sits on its wheels (should probably always be 1.0) - data.aiPrio = 1; - data.label_color[0] = 1.0f; // red - data.label_color[1] = 0.0f; - data.label_color[2] = 0.0f; - data.label_color[3] = 1.0f; - return xpmpData_NewData; -} - -/// @brief Handles requests for plane's surface data -/// @see LegacySampleAircraft::GetPlaneSurfaces(), which basically is the very same thing. -XPMPPlaneCallbackResult SetSurfaceData (XPMPPlaneSurfaces_t& data) -{ - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (data.size < (long)sizeof(XPMPPlaneSurfaces_t)) - return xpmpData_Unavailable; - - // gear & flight surfaces - data.gearPosition = 1.0; // gear is always down - data.yokePitch = // flight surfaces cycle up and down - data.yokeHeading = - data.yokeRoll = - data.flapRatio = - data.spoilerRatio = - data.speedBrakeRatio = - data.slatRatio = GetTimeUpDown(); - data.thrust = 0.2f; - - // lights: taxi, beacon, and nav lights - data.lights.timeOffset = 0; // unused in XPMP2 - data.lights.taxiLights = 1; - data.lights.landLights = 0; - data.lights.bcnLights = 1; - data.lights.strbLights = 0; - data.lights.navLights = 1; - data.lights.flashPattern = xpmp_Lights_Pattern_Default; // unused in XPMP2 - - // tires (assuming a tire circumfence of 3.2m and a circumfence of 628m of the - // circle the plane moves around a center position we try to simulate - // more or less accurate tire rolling, so the tire turns 196 times for - // a full plane's circle, which in turn shall take 10s. - constexpr float ROLL_CIRCUMFENCE = float(2.0 * PI * PLANE_RADIUS_M); - constexpr float TIRE_REVOLUTIONS = ROLL_CIRCUMFENCE / PLANE_TIRE_CIRCUMFENCE_M; - data.tireDeflect = 0; - data.tireRotDegree = std::fmod(TIRE_REVOLUTIONS * GetTimeFragment() * 360.0f, - 360.0f); - data.tireRotRpm = TIRE_REVOLUTIONS / PLANE_CIRCLE_TIME_MIN; - data.tireDeflect = GetTimeUpDown() * 1.5f; // 1.5m up/down of tire deflections - - // For simplicity, we keep engine and prop rotation identical...probably unrealistic - constexpr float PROP_REVOLUTIONS = PLANE_PROP_RPM * PLANE_CIRCLE_TIME_MIN; - data.engRotRpm = - data.propRotRpm = PLANE_PROP_RPM; - data.engRotDegree = - data.propRotDegree = std::fmod(PROP_REVOLUTIONS * GetTimeFragment() * 360.0f, - 360.0f); - // for the show of it we open/close reversers - data.reversRatio = GetTimeUpDown(); - - // Some models produces tire smoke at the moment of touch down, - // so at 0° we tell the model we would touch down right now - data.touchDown = GetTimeFragment() <= 0.05f; - - return xpmpData_NewData; -} - -/// @brief Handles requests for plane's radar data (doesn't actually change over time) -/// @see LegacySampleAircraft::GetPlaneRadar(), which basically is the very same thing. -XPMPPlaneCallbackResult SetRadarData (XPMPPlaneRadar_t& data) -{ - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (data.size < (long)sizeof(XPMPPlaneRadar_t)) - return xpmpData_Unavailable; - - if (data.code != 1234) { - data.code = 1234; - data.mode = xpmpTransponderMode_ModeC; - return xpmpData_NewData; - } else - return xpmpData_Unchanged; -} - -/// @brief Handles requests for plane's informational texts -/// @details Handling this requests is completely optional. The texts are -/// provided on shared dataRefs and used only by few other plugins, -/// one of it is FSTramp.\n -/// Here in the example we keep it simple and just return the ICAO plane type. -/// @see LegacySampleAircraft::GetInfoTexts(), which basically is the very same thing. -XPMPPlaneCallbackResult SetInfoData (XPMPInfoTexts_t& data) -{ - // The size is pre-filled and shall support version differences. - // We make the check simple here and only proceed if the library - // has at least as much storage as we expected for everything: - if (data.size < (long)sizeof(XPMPInfoTexts_t)) - return xpmpData_Unavailable; - - XPMPGetPlaneICAOAndLivery(hStdPlane, // get ICAO type from XPMP2 - data.icaoAcType, - NULL); - strScpy(data.tailNum, "D-ABCD", sizeof(data.tailNum)); - - return xpmpData_NewData; -} - - -/// Callback function handed to XPMP2, will be called in every drawing frame to deliver plane position and configuration -XPMPPlaneCallbackResult CBPlaneData (XPMPPlaneID inPlane, - XPMPPlaneDataType inDataType, - void * ioData, - void * /* inRefcon */) -{ - // sanity check: our plane? - if (inPlane != hStdPlane) return xpmpData_Unavailable; - - // There is 4 requests to deal with - switch (inDataType) { - case xpmpDataType_Position: - return SetPositionData (*(XPMPPlanePosition_t*)ioData); - case xpmpDataType_Surfaces: - return SetSurfaceData(*(XPMPPlaneSurfaces_t*)ioData); - case xpmpDataType_Radar: - return SetRadarData(*(XPMPPlaneRadar_t*)ioData); - case xpmpDataType_InfoTexts: - return SetInfoData(*(XPMPInfoTexts_t*)ioData); - default: - return xpmpData_Unavailable; - } -} - -// -// MARK: Menu functionality -// - -/// menu id of our plugin's menu -XPLMMenuID hMenu = nullptr; - -/// Planes currently visible? -bool gbVisible = true; - -/// Labels currently shown in map view? -bool gbMapLabels = true; - -/// for cycling CSL models: what is the index used for the first plane? -int gModelIdxBase = 0; - -/// Is any plane object created? -inline bool ArePlanesCreated () { return pSamplePlane || pLegacyPlane || hStdPlane; } - -/// Create our 3 planes (if they don't exist already) -void PlanesCreate () -{ - // 1. New interface of XPMP2::Aircraft class - if (!pSamplePlane) try { - pSamplePlane = new SampleAircraft(PLANE_MODEL[gModelIdxBase][0], // type - PLANE_MODEL[gModelIdxBase][1], // airline - PLANE_MODEL[gModelIdxBase][2], // livery - 0xABCDEF); // manually set Mode S id - } - catch (const XPMP2::XPMP2Error& e) { - LogMsg("Could not create object of type SampleAircraft: %s", e.what()); - pSamplePlane = nullptr; - } - - // 2. Subclassing the Legacy XPCAircraft class - // Creating the plane can now (this is new in XPMP2) throw an exception - if (!pLegacyPlane) try { - pLegacyPlane = new LegacySampleAircraft(PLANE_MODEL[(gModelIdxBase+1)%3][0].c_str(), // type - PLANE_MODEL[(gModelIdxBase+1)%3][1].c_str(), // airline - PLANE_MODEL[(gModelIdxBase+1)%3][2].c_str(), // livery - 0x123456); // manually set Mode S id - } - catch (const XPMP2::XPMP2Error& e) { - LogMsg("Could not create object of type LegacySampleAircraft: %s", e.what()); - pLegacyPlane = nullptr; - } - - // 3. Using Standard Legacy C interface - if (!hStdPlane) - hStdPlane = XPMPCreatePlane(PLANE_MODEL[(gModelIdxBase+2)%3][0].c_str(), // type - PLANE_MODEL[(gModelIdxBase+2)%3][1].c_str(), // airline - PLANE_MODEL[(gModelIdxBase+2)%3][2].c_str(), // livery - CBPlaneData, NULL); - - // Put a checkmark in front of menu item if planes are visible - XPLMCheckMenuItem(hMenu, 0, ArePlanesCreated() ? xplm_Menu_Checked : xplm_Menu_Unchecked); - XPLMCheckMenuItem(hMenu, 1, gbVisible ? xplm_Menu_Checked : xplm_Menu_Unchecked); -} - -/// Remove all planes -void PlanesRemove () -{ - if (pSamplePlane) { - delete pSamplePlane; - pSamplePlane = nullptr; - } - - if (pLegacyPlane) { - delete pLegacyPlane; - pLegacyPlane = nullptr; - } - - if (hStdPlane) { - XPMPDestroyPlane(hStdPlane); - hStdPlane = 0; - } - - // Remove the checkmark in front of menu item - XPLMCheckMenuItem(hMenu, 0, xplm_Menu_Unchecked); - XPLMCheckMenuItem(hMenu, 1, xplm_Menu_Unchecked); -} - -/// Show/hide the planes (temporarily, without destroying the plane objects) -void PlanesShowHide () -{ - gbVisible = !gbVisible; // toggle setting - if (pSamplePlane) - pSamplePlane->SetVisible(gbVisible); - if (pLegacyPlane) - pLegacyPlane->SetVisible(gbVisible); - if (hStdPlane) - XPMPSetPlaneVisibility(hStdPlane, gbVisible); - - // Put a checkmark in front of menu item if planes are visible - XPLMCheckMenuItem(hMenu, 1, gbVisible ? xplm_Menu_Checked : xplm_Menu_Unchecked); -} - -/// Cycle the CSL models of the 3 planes -void PlanesCycleModels () -{ - // increase the index into our list of CSL models - // (this is the index used by the first plane, the XPMP2::Aircraft one) - gModelIdxBase = (gModelIdxBase + 1) % 3; - - // Now apply the new model to the 3 planes - if (pSamplePlane) - pSamplePlane->ChangeModel(PLANE_MODEL[gModelIdxBase][0], // type - PLANE_MODEL[gModelIdxBase][1], // airline - PLANE_MODEL[gModelIdxBase][2]); // livery - if (pLegacyPlane) - pLegacyPlane->ChangeModel(PLANE_MODEL[(gModelIdxBase+1)%3][0], // type - PLANE_MODEL[(gModelIdxBase+1)%3][1], // airline - PLANE_MODEL[(gModelIdxBase+1)%3][2]); // livery - if (hStdPlane) - XPMPChangePlaneModel(hStdPlane, - PLANE_MODEL[(gModelIdxBase+2)%3][0].c_str(), // type - PLANE_MODEL[(gModelIdxBase+2)%3][1].c_str(), // airline - PLANE_MODEL[(gModelIdxBase+2)%3][2].c_str()); // livery - - if (pSamplePlane) { - // Demonstrate how to get detailed info of the model in use - XPMP2::CSLModelInfo_t cslInfo = pSamplePlane->GetModelInfo(); - LogMsg("XPMP2-Sample: SamplePlane now using model %s of type %s as defined in line %d of %s", - cslInfo.modelName.c_str(), cslInfo.icaoType.c_str(), - cslInfo.xsbAircraftLn, cslInfo.xsbAircraftPath.c_str()); - for (const XPMP2::CSLModelInfo_t::MatchCrit_t& crit : cslInfo.vecMatchCrit) - LogMsg(" Matches: %s | %s", crit.icaoAirline.c_str(), crit.livery.c_str()); - } - - // Completely unrelated...just for a change and for testing that functionality: - // We also toggle the display of labels in the map: - gbMapLabels = !gbMapLabels; - XPMPEnableMap(true, gbMapLabels); -} - -/// @brief Rematch CSL models based on existing definition -/// @details This will pick a different (partly random) CSL model -/// for those planes, for which no exact match has been found. -/// The A321 is defined without operator code, so each re-match -/// will pick any of the available A321 models. -void PlanesRematch () -{ - if (pSamplePlane) - pSamplePlane->ReMatchModel(); - if (pLegacyPlane) - pLegacyPlane->ReMatchModel(); - if (hStdPlane) { - // There is no standard C function for this task. If really want it - // we need to go the detour of fetching the underlying aircraft object - XPMP2::Aircraft* pStdAc = XPMPGetAircraft(hStdPlane); - if (pStdAc) - pStdAc->ReMatchModel(); - } - -} - -void MenuUpdateCheckmarks () -{ - XPLMCheckMenuItem(hMenu, 0, ArePlanesCreated() ? xplm_Menu_Checked : xplm_Menu_Unchecked); - XPLMCheckMenuItem(hMenu, 1, gbVisible ? xplm_Menu_Checked : xplm_Menu_Unchecked); - XPLMCheckMenuItem(hMenu, 4, XPMPHasControlOfAIAircraft() ? xplm_Menu_Checked : xplm_Menu_Unchecked); -} - -/// Callback function for the case that we might get AI access later -void CPRequestAIAgain (void*) -{ - // Well...we just try again ;-) - XPMPMultiplayerEnable(CPRequestAIAgain); - MenuUpdateCheckmarks(); -} - -/// Callback function for menu -void CBMenu (void* /*inMenuRef*/, void* inItemRef) -{ - // Toggle plane visibility? - if (inItemRef == (void*)1) - { - if (ArePlanesCreated()) - PlanesRemove(); - else - PlanesCreate(); - } - // Show/Hide Planes? - else if (inItemRef == (void*)2) - { - PlanesShowHide(); - } - // Cycle Models? - else if (inItemRef == (void*)3) - { - PlanesCycleModels(); - } - // Rematch Models? - else if (inItemRef == (void*)4) - { - PlanesRematch(); - } - // Toggle AI control? - else if (inItemRef == (void*)5) - { - if (XPMPHasControlOfAIAircraft()) - XPMPMultiplayerDisable(); - else - // When requested by menu we actually wait via callback to get control - XPMPMultiplayerEnable(CPRequestAIAgain); - } - // Update menu items' checkmarks - MenuUpdateCheckmarks(); -} - -// -// MARK: Standard Plugin Callbacks -// - -PLUGIN_API int XPluginStart(char* outName, char* outSig, char* outDesc) -{ - std::strcpy(outName, "XPMP2-Sample"); - std::strcpy(outSig, "TwinFan.plugin.XPMP2-Sample"); - std::strcpy(outDesc, "Sample plugin demonstrating using XPMP2 library"); - - // use native paths, i.e. Posix style (as opposed to HFS style) - // https://developer.x-plane.com/2014/12/mac-plugin-developers-you-should-be-using-native-paths/ - - /* Disable next line only for testing purposes: Does XPMP2 also handle HFS well? */ - XPLMEnableFeature("XPLM_USE_NATIVE_PATHS",1); - - // Create the menu for the plugin - int my_slot = XPLMAppendMenuItem(XPLMFindPluginsMenu(), "XPMP2 Sample", NULL, 0); - hMenu = XPLMCreateMenu("XPMP2 Sample", XPLMFindPluginsMenu(), my_slot, CBMenu, NULL); - XPLMAppendMenuItem(hMenu, "Toggle Planes", (void*)1, 0); - XPLMAppendMenuItem(hMenu, "Toggle Visibility", (void*)2, 0); - XPLMAppendMenuItem(hMenu, "Cycle Models", (void*)3, 0); - XPLMAppendMenuItem(hMenu, "Rematch Models", (void*)4, 0); - XPLMAppendMenuItem(hMenu, "Toggle AI control", (void*)5, 0); - MenuUpdateCheckmarks(); - return 1; -} - -PLUGIN_API void XPluginStop(void) -{ -} - -PLUGIN_API int XPluginEnable(void) -{ - // The path separation character, one out of /\: - char pathSep = XPLMGetDirectorySeparator()[0]; - // The plugin's path, results in something like ".../Resources/plugins/XPMP2-Sample/64/XPMP2-Sample.xpl" - char szPath[256]; - XPLMGetPluginInfo(XPLMGetMyID(), nullptr, szPath, nullptr, nullptr); - *(std::strrchr(szPath, pathSep)) = 0; // Cut off the plugin's file name - *(std::strrchr(szPath, pathSep)+1) = 0; // Cut off the "64" directory name, but leave the dir separation character - // We search in a subdirectory named "Resources" for all we need - std::string resourcePath = szPath; - resourcePath += "Resources"; // should now be something like ".../Resources/plugins/XPMP2-Sample/Resources" - - // Try initializing XPMP2: - const char *res = XPMPMultiplayerInit ("XPMP2-Sample", // plugin name, - resourcePath.c_str(), // path to supplemental files - CBIntPrefsFunc, // configuration callback function - "C172"); // default ICAO type - if (res[0]) { - LogMsg("XPMP2-Sample: Initialization of XPMP2 failed: %s", res); - return 0; - } - - // Load our CSL models - res = XPMPLoadCSLPackage(resourcePath.c_str()); // CSL folder root path - if (res[0]) { - LogMsg("XPMP2-Sample: Error while loading CSL packages: %s", res); - } - - // Now we also try to get control of AI planes. That's optional, though, - // other plugins (like LiveTraffic, XSquawkBox, X-IvAp...) - // could have control already - res = XPMPMultiplayerEnable(CPRequestAIAgain); - if (res[0]) { - LogMsg("XPMP2-Sample: Could not enable AI planes: %s", res); - } - - // Register the plane notifer function - // (this is rarely used in actual applications, but used here for - // demonstration and testing purposes) - XPMPRegisterPlaneNotifierFunc(CBPlaneNotifier, NULL); - - // *** Create the planes *** - PlanesCreate(); - - // Success - MenuUpdateCheckmarks(); - LogMsg("XPMP2-Sample: Enabled"); - return 1; -} - -PLUGIN_API void XPluginDisable(void) -{ - // Remove the planes - PlanesRemove(); - - // Give up AI plane control - XPMPMultiplayerDisable(); - - // Unregister plane notifier (must match function _and_ refcon) - XPMPUnregisterPlaneNotifierFunc(CBPlaneNotifier, NULL); - - // Properly cleanup the XPMP2 library - XPMPMultiplayerCleanup(); - - LogMsg("XPMP2-Sample: Disabled"); -} - -PLUGIN_API void XPluginReceiveMessage(XPLMPluginID, long inMsg, void*) -{ - // Some other plugin wants TCAS/AI control, so we (as an artificial - // traffic plugin) give up - if (inMsg == XPLM_MSG_RELEASE_PLANES) { - XPMPMultiplayerDisable(); - MenuUpdateCheckmarks(); - } -} diff --git a/XPMP2-Sample/XPMP2-Sample.sym b/XPMP2-Sample/XPMP2-Sample.sym deleted file mode 100644 index 3820a9b8..00000000 --- a/XPMP2-Sample/XPMP2-Sample.sym +++ /dev/null @@ -1,8 +0,0 @@ -{ global: -XPluginDisable; -XPluginEnable; -XPluginReceiveMessage; -XPluginStart; -XPluginStop; -local: *; }; - diff --git a/XPMP2-Sample/XPMP2-Sample.sym_mac b/XPMP2-Sample/XPMP2-Sample.sym_mac deleted file mode 100644 index 9339b39e..00000000 --- a/XPMP2-Sample/XPMP2-Sample.sym_mac +++ /dev/null @@ -1,6 +0,0 @@ -_XPluginDisable -_XPluginEnable -_XPluginReceiveMessage -_XPluginStart -_XPluginStop - diff --git a/XPMP2-Sample/XPMP2-Sample.xcodeproj/project.pbxproj b/XPMP2-Sample/XPMP2-Sample.xcodeproj/project.pbxproj deleted file mode 100644 index 116e7f6f..00000000 --- a/XPMP2-Sample/XPMP2-Sample.xcodeproj/project.pbxproj +++ /dev/null @@ -1,437 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 2572C40623D88802006A7726 /* XPMP2-Sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2572C40523D88802006A7726 /* XPMP2-Sample.cpp */; }; - 2575F45123ECC49100747524 /* XPMP2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2575F44C23ECC34F00747524 /* XPMP2.framework */; }; - D6A7BDC116A1DEC000D1426A /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6A7BDC016A1DEC000D1426A /* CoreFoundation.framework */; }; - D6A7BDF116A1DED200D1426A /* XPLM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6A7BDF016A1DED200D1426A /* XPLM.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 2575F44F23ECC35000747524 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - 25A334CA2444FD5E00D4F988 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 2572C40523D88802006A7726 /* XPMP2-Sample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "XPMP2-Sample.cpp"; sourceTree = ""; }; - 2575F44623ECAAF300747524 /* Toolchain-ubuntu-osxcross-10.11.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Toolchain-ubuntu-osxcross-10.11.cmake"; sourceTree = ""; }; - 2575F44C23ECC34F00747524 /* XPMP2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XPMP2.framework; path = lib/XPMP2.framework; sourceTree = ""; }; - 25A0F26D23E8B85E007D6B6E /* Dockerfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dockerfile; sourceTree = ""; }; - 25A0F26E23E8B85E007D6B6E /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - 25A0F26F23E8B85E007D6B6E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - 25A0F27023E8B85F007D6B6E /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = ""; }; - 25A0F27123E8B85F007D6B6E /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; - 25A0F27323E8B906007D6B6E /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; - D607B19909A556E400699BC3 /* XPMP2-Sample.xpl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "XPMP2-Sample.xpl"; sourceTree = BUILT_PRODUCTS_DIR; }; - D6A7BDA916A1DEA200D1426A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; - D6A7BDC016A1DEC000D1426A /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - D6A7BDF016A1DED200D1426A /* XPLM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XPLM.framework; path = SDK/Libraries/Mac/XPLM.framework; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - D607B19709A556E400699BC3 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D6A7BDC116A1DEC000D1426A /* CoreFoundation.framework in Frameworks */, - 2575F45123ECC49100747524 /* XPMP2.framework in Frameworks */, - D6A7BDF116A1DED200D1426A /* XPLM.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 25A0F26B23E8B85E007D6B6E /* docker */ = { - isa = PBXGroup; - children = ( - 2575F44623ECAAF300747524 /* Toolchain-ubuntu-osxcross-10.11.cmake */, - 25A0F26D23E8B85E007D6B6E /* Dockerfile */, - 25A0F26E23E8B85E007D6B6E /* Makefile */, - 25A0F26F23E8B85E007D6B6E /* README.md */, - 25A0F27023E8B85F007D6B6E /* build.sh */, - 25A0F27123E8B85F007D6B6E /* .gitignore */, - ); - path = docker; - sourceTree = ""; - }; - AC4E46B809C2E0B3006B7E1B /* Source */ = { - isa = PBXGroup; - children = ( - 2572C40523D88802006A7726 /* XPMP2-Sample.cpp */, - ); - name = Source; - sourceTree = ""; - }; - D607B15F09A5563000699BC3 = { - isa = PBXGroup; - children = ( - 25A0F27323E8B906007D6B6E /* CMakeLists.txt */, - 25A0F26B23E8B85E007D6B6E /* docker */, - D6A7BDAD16A1DEA700D1426A /* Frameworks */, - AC4E46B809C2E0B3006B7E1B /* Source */, - D607B19A09A556E400699BC3 /* Products */, - ); - sourceTree = ""; - }; - D607B19A09A556E400699BC3 /* Products */ = { - isa = PBXGroup; - children = ( - D607B19909A556E400699BC3 /* XPMP2-Sample.xpl */, - ); - name = Products; - sourceTree = ""; - }; - D6A7BDAD16A1DEA700D1426A /* Frameworks */ = { - isa = PBXGroup; - children = ( - 2575F44C23ECC34F00747524 /* XPMP2.framework */, - D6A7BDC016A1DEC000D1426A /* CoreFoundation.framework */, - D6A7BDA916A1DEA200D1426A /* OpenGL.framework */, - D6A7BDF016A1DED200D1426A /* XPLM.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - D607B19809A556E400699BC3 /* XPMP2-Sample */ = { - isa = PBXNativeTarget; - buildConfigurationList = D607B19B09A556E400699BC3 /* Build configuration list for PBXNativeTarget "XPMP2-Sample" */; - buildPhases = ( - D607B19609A556E400699BC3 /* Sources */, - D607B19709A556E400699BC3 /* Frameworks */, - 2575F44F23ECC35000747524 /* Embed Frameworks */, - 25A334CA2444FD5E00D4F988 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "XPMP2-Sample"; - productName = StarterPlugin; - productReference = D607B19909A556E400699BC3 /* XPMP2-Sample.xpl */; - productType = "com.apple.product-type.library.dynamic"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - D607B16109A5563100699BC3 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1130; - }; - buildConfigurationList = D607B16209A5563100699BC3 /* Build configuration list for PBXProject "XPMP2-Sample" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = D607B15F09A5563000699BC3; - productRefGroup = D607B19A09A556E400699BC3 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D607B19809A556E400699BC3 /* XPMP2-Sample */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - D607B19609A556E400699BC3 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2572C40623D88802006A7726 /* XPMP2-Sample.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - D607B16309A5563100699BC3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_ASSIGN_ENUM = YES; - CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_FLOAT_CONVERSION = YES; - CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.1; - DEBUG_INFORMATION_FORMAT = dwarf; - DSTROOT = "$(XPLANE11_ROOT)/Resources/plugins/$(PROJECT)"; - DYLIB_COMPATIBILITY_VERSION = ""; - DYLIB_CURRENT_VERSION = ""; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - EXECUTABLE_EXTENSION = xpl; - FRAMEWORK_SEARCH_PATHS = ( - lib, - SDK/Libraries/Mac, - ); - GCC_C_LANGUAGE_STANDARD = c11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "APL=1", - "IBM=0", - "LIN=0", - "XPLM200=1", - "XPLM210=1", - "XPLM300=1", - "XPLM301=1", - "XPLM303=1", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - SDK/CHeaders/XPLM, - lib/XPMP2.framework/Headers, - "$(HEADER_SEARCH_PATHS)", - ); - MACH_O_TYPE = mh_bundle; - MACOSX_DEPLOYMENT_TARGET = 10.12; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ( - "$(OTHER_LDFLAGS)", - "-Wl,-exported_symbol", - "-Wl,_XPluginStart", - "-Wl,-exported_symbol", - "-Wl,_XPluginEnable", - "-Wl,-exported_symbol", - "-Wl,_XPluginReceiveMessage", - "-Wl,-exported_symbol", - "-Wl,_XPluginDisable", - "-Wl,-exported_symbol", - "-Wl,_XPluginStop", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.twinfan.XPMP2-Sample"; - PRODUCT_NAME = "${TARGET_NAME}"; - SDKROOT = macosx; - XPLANE11_ROOT = "$(USER_APPS_DIR)/X-Plane/Release"; - }; - name = Debug; - }; - D607B16409A5563100699BC3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_ASSIGN_ENUM = YES; - CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_FLOAT_CONVERSION = YES; - CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DSTROOT = "$(XPLANE11_ROOT)/Resources/plugins/$(PROJECT)"; - DYLIB_COMPATIBILITY_VERSION = ""; - DYLIB_CURRENT_VERSION = ""; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - EXECUTABLE_EXTENSION = xpl; - FRAMEWORK_SEARCH_PATHS = ( - lib, - SDK/Libraries/Mac, - ); - GCC_C_LANGUAGE_STANDARD = c11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "APL=1", - "IBM=0", - "LIN=0", - "XPLM200=1", - "XPLM210=1", - "XPLM300=1", - "XPLM301=1", - "XPLM303=1", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - SDK/CHeaders/XPLM, - lib/XPMP2.framework/Headers, - "$(HEADER_SEARCH_PATHS)", - ); - MACH_O_TYPE = mh_bundle; - MACOSX_DEPLOYMENT_TARGET = 10.12; - OTHER_LDFLAGS = ( - "$(OTHER_LDFLAGS)", - "-Wl,-exported_symbol", - "-Wl,_XPluginStart", - "-Wl,-exported_symbol", - "-Wl,_XPluginEnable", - "-Wl,-exported_symbol", - "-Wl,_XPluginReceiveMessage", - "-Wl,-exported_symbol", - "-Wl,_XPluginDisable", - "-Wl,-exported_symbol", - "-Wl,_XPluginStop", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.twinfan.XPMP2-Sample"; - PRODUCT_NAME = "${TARGET_NAME}"; - SDKROOT = macosx; - XPLANE11_ROOT = "$(USER_APPS_DIR)/X-Plane/Release"; - }; - name = Release; - }; - D607B19C09A556E400699BC3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - DEPLOYMENT_LOCATION = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/lib", - ); - INSTALL_PATH = mac_x64; - VALID_ARCHS = x86_64; - }; - name = Debug; - }; - D607B19D09A556E400699BC3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - DEPLOYMENT_LOCATION = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/lib", - ); - INSTALL_PATH = mac_x64; - VALID_ARCHS = x86_64; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - D607B16209A5563100699BC3 /* Build configuration list for PBXProject "XPMP2-Sample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D607B16309A5563100699BC3 /* Debug */, - D607B16409A5563100699BC3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D607B19B09A556E400699BC3 /* Build configuration list for PBXNativeTarget "XPMP2-Sample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D607B19C09A556E400699BC3 /* Debug */, - D607B19D09A556E400699BC3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = D607B16109A5563100699BC3 /* Project object */; -} diff --git a/XPMP2-Sample/docker/.gitignore b/XPMP2-Sample/docker/.gitignore deleted file mode 100755 index 5f697067..00000000 --- a/XPMP2-Sample/docker/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.image* -MacOSX* \ No newline at end of file diff --git a/XPMP2-Sample/docker/Dockerfile_Bionic b/XPMP2-Sample/docker/Dockerfile_Bionic deleted file mode 100755 index eecb9795..00000000 --- a/XPMP2-Sample/docker/Dockerfile_Bionic +++ /dev/null @@ -1,35 +0,0 @@ -# Linux compile environment, based on Ubuntu Bionic Beaver - -### Ubuntu basics ######################################################## - -FROM ubuntu:18.04 - -# set up package manager with latest mirrors and certificates -RUN sed -i -e 's/http:\/\/archive.ubuntu.com\/ubuntu\//mirror:\/\/mirrors.ubuntu.com\/mirrors.txt/' /etc/apt/sources.list \ - && apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates - - -### Linux ################################################################ - -# Install Linux toolchain (GCC) including CMake -RUN apt-get install -y --no-install-recommends build-essential ninja-build sudo bash coreutils curl libcurl4-openssl-dev \ - && apt-get clean \ - && curl -sSL https://github.com/Kitware/CMake/releases/download/v3.19.2/cmake-3.19.2-Linux-x86_64.tar.gz | tar -xz -C /usr/local/ --strip-components=1 \ - # Install dependency libraries under Linux. - && apt-get install -y --no-install-recommends freeglut3-dev libudev-dev libopenal-dev \ - && apt-get clean - -### User / Entrypoint ####################################################expor - -# Add essential users to the docker image -RUN echo "" | adduser --uid 1000 --disabled-password --gecos "" xpbuild && adduser xpbuild sudo -RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers - -VOLUME /build -USER xpbuild -ADD build.sh /usr/bin/build.sh - -# Entrypoint is the build.sh script, which takes care of actual building -WORKDIR /build -ENTRYPOINT ["build.sh"] diff --git a/XPMP2-Sample/docker/Dockerfile_Focal b/XPMP2-Sample/docker/Dockerfile_Focal deleted file mode 100644 index 438f25c0..00000000 --- a/XPMP2-Sample/docker/Dockerfile_Focal +++ /dev/null @@ -1,294 +0,0 @@ -# Linux, Windows, MacOS cross compile environment, based on Ubuntu Focal Fossa -# NOTE: This script does _not_ download the MacOS SDK from somewhere! -# Instead it is expected to sit in the current folder as MacOSX11.1.sdk.tar.xz -# or its location be passed via Docker ARGs "DARWIN_SDK_VERSION" and/or "DARWIN_SDK_PATH". - -FROM ubuntu:20.04 - -### MingW64 setup taken over from mmozeiko/mingw-w64 ##################### -# but I want Win32 threads, so I need to configure gcc differently - -WORKDIR /mnt - -ENV MINGW=/mingw - -ARG PKG_CONFIG_VERSION=0.29.2 -ARG CMAKE_VERSION=3.19.2 -ARG BINUTILS_VERSION=2.35.1 -ARG MINGW_VERSION=8.0.0 -ARG GCC_VERSION=10.2.0 -ARG NASM_VERSION=2.15.02 -ARG NVCC_VERSION=11.2.0 - -SHELL [ "/bin/bash", "-c" ] - -RUN set -ex \ - \ - && apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get upgrade --no-install-recommends -y \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - ca-certificates \ - gcc-10 \ - g++-10 \ - zlib1g-dev \ - libssl-dev \ - libgmp-dev \ - libmpfr-dev \ - libmpc-dev \ - libisl-dev \ - libssl1.1 \ - libgmp10 \ - libmpfr6 \ - libmpc3 \ - libisl22 \ - xz-utils \ - python \ - python-lxml \ - python-mako \ - ninja-build \ - texinfo \ - meson \ - gnupg \ - bzip2 \ - patch \ - gperf \ - bison \ - file \ - flex \ - make \ - yasm \ - wget \ - zip \ - git \ - \ - && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 1000 --slave /usr/bin/g++ g++ /usr/bin/g++-10 \ - \ - && wget -q https://pkg-config.freedesktop.org/releases/pkg-config-${PKG_CONFIG_VERSION}.tar.gz -O - | tar -xz \ - && wget -q https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz -O - | tar -xz \ - && wget -q https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.xz -O - | tar -xJ \ - && wget -q https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/mingw-w64-v${MINGW_VERSION}.tar.bz2 -O - | tar -xj \ - && wget -q https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz -O - | tar -xJ \ - && wget -q https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/nasm-${NASM_VERSION}.tar.xz -O - | tar -xJ \ - \ - && wget -q https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-gcc/0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch -O - | \ - patch -d gcc-${GCC_VERSION} -p 1 \ - \ - && mkdir -p ${MINGW}/include ${MINGW}/lib/pkgconfig \ - && chmod 0777 -R /mnt ${MINGW} \ - \ - && cd pkg-config-${PKG_CONFIG_VERSION} \ - && ./configure \ - --prefix=/usr/local \ - --with-pc-path=${MINGW}/lib/pkgconfig \ - --with-internal-glib \ - --disable-shared \ - --disable-nls \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && cd cmake-${CMAKE_VERSION} \ - && ./configure \ - --prefix=/usr/local \ - --parallel=`nproc` \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && cd binutils-${BINUTILS_VERSION} \ - && ./configure \ - --prefix=/usr/local \ - --target=x86_64-w64-mingw32 \ - --disable-shared \ - --enable-static \ - --disable-lto \ - --disable-plugins \ - --disable-multilib \ - --disable-nls \ - --disable-werror \ - --with-system-zlib \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && mkdir mingw-w64 \ - && cd mingw-w64 \ - && ../mingw-w64-v${MINGW_VERSION}/mingw-w64-headers/configure \ - --prefix=/usr/local/x86_64-w64-mingw32 \ - --host=x86_64-w64-mingw32 \ - --enable-sdk=all \ - --enable-secure-api \ - && make install \ - && cd .. \ - \ - && mkdir gcc \ - && cd gcc \ - && ../gcc-${GCC_VERSION}/configure \ - --prefix=/usr/local \ - --target=x86_64-w64-mingw32 \ - --enable-languages=c,c++ \ - --disable-shared \ - --enable-static \ - --enable-threads=win32 \ - --with-system-zlib \ - --enable-libgomp \ - --enable-libatomic \ - --enable-graphite \ - --disable-libstdcxx-pch \ - --disable-libstdcxx-debug \ - --disable-multilib \ - --disable-lto \ - --disable-nls \ - --disable-werror \ - && make -j`nproc` all-gcc \ - && make install-gcc \ - && cd .. \ - \ - && cd mingw-w64 \ - && ../mingw-w64-v${MINGW_VERSION}/mingw-w64-crt/configure \ - --prefix=/usr/local/x86_64-w64-mingw32 \ - --host=x86_64-w64-mingw32 \ - --enable-wildcard \ - --disable-lib32 \ - --enable-lib64 \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && cd mingw-w64 \ - && ../mingw-w64-v${MINGW_VERSION}/mingw-w64-libraries/winpthreads/configure \ - --prefix=/usr/local/x86_64-w64-mingw32 \ - --host=x86_64-w64-mingw32 \ - --enable-static \ - --disable-shared \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && cd gcc \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && cd nasm-${NASM_VERSION} \ - && ./configure --prefix=/usr/local \ - && make -j`nproc` \ - && make install \ - && cd .. \ - \ - && rm -r pkg-config-${PKG_CONFIG_VERSION} \ - && rm -r cmake-${CMAKE_VERSION} \ - && rm -r binutils-${BINUTILS_VERSION} \ - && rm -r mingw-w64 mingw-w64-v${MINGW_VERSION} \ - && rm -r gcc gcc-${GCC_VERSION} \ - && rm -r nasm-${NASM_VERSION} \ - \ - && apt-get remove --purge -y file gcc-10 g++-10 zlib1g-dev libssl-dev libgmp-dev libmpfr-dev libmpc-dev libisl-dev python-lxml python-mako \ - \ - && apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub \ - && echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /" > /etc/apt/sources.list.d/cuda.list \ - && apt-get update \ - \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - cuda-nvcc-${NVCC_VERSION:0:2}-${NVCC_VERSION:3:1} \ - \ - && ln -s /usr/local/cuda-${NVCC_VERSION:0:2}.${NVCC_VERSION:3:1} /usr/local/cuda \ - && ln -s /usr/bin/gcc-9 /usr/local/cuda/bin/gcc \ - && ln -s /usr/bin/g++-9 /usr/local/cuda/bin/g++ \ - \ - && apt-get remove --purge -y gnupg \ - && apt-get autoremove --purge -y \ - && apt-get clean - -### -- End of MingW64 setup taken over from mmozeiko/mingw-w64 --- ####### - - -### MacOS ################################################################ - -# Install OS X cross-compiling toolchain (clang). -RUN apt-get install -y --no-install-recommends git sudo clang llvm-dev libxml2-dev uuid-dev libssl-dev bash patch make tar xz-utils bzip2 gzip sed cpio libbz2-dev zlib1g-dev && apt-get clean -#Build arguments -ARG OSXCROSS_REPO="tpoechtrager/osxcross" -ARG DARWIN_SDK_VERSION="11.1" -ARG DARWIN_SDK_PATH="MacOSX${DARWIN_SDK_VERSION}.sdk.tar.xz" -ARG DARWIN_TOOLCHAIN="x86_64-apple-darwin20.2" - -# ENV available in docker image -ENV CROSSBUILD=1 \ - OSX_SDK_PATH="/usr/osxcross/SDK/MacOSX${DARWIN_SDK_VERSION}.sdk" \ - OSX_TOOLCHAIN_PREFIX=${DARWIN_TOOLCHAIN} - -# Clone the OSXCross repo, latest master -RUN git clone 'https://github.com/tpoechtrager/osxcross' /tmp/osxcross - -# Copy the _provided_ MacOS SDK into the image as a tar ball (don't unpack yet! osxcross build.sh will do that later) -COPY ${DARWIN_SDK_PATH} /tmp/osxcross/tarballs/ - -# Build OSXCross -RUN cd /tmp/osxcross \ - && UNATTENDED=1 JOBS=4 SDK_VERSION=${DARWIN_SDK_VERSION} ./build.sh \ - && mv target /usr/osxcross \ - && mv tools /usr/osxcross/ \ - && sudo ldconfig /usr/osxcross/lib \ - && rm -rf "${OSX_SDK_PATH}/usr/share/man" \ - && rm -rf "/tmp/osxcross" \ - && true - - -### Linux ################################################################ - -# Install Linux toolchain (GCC) including CMake -RUN apt-get install -y --no-install-recommends \ - build-essential ninja-build \ - sudo bash coreutils curl \ - libcurl4-openssl-dev freeglut3-dev libudev-dev libopenal-dev \ - && apt-get clean \ -# && curl -sSL https://github.com/Kitware/CMake/releases/download/v3.19.2/cmake-3.19.2-Linux-x86_64.tar.gz | tar -xz -C /usr/local/ --strip-components=1 \ - && true - - -### CURL ################################################################# - -# Download and build libCURL (in a limited version for our purposes: static only for HTTP and FTP) -RUN apt-get install -y --no-install-recommends curl \ - && mkdir /tmp/build-curl \ - && cd /tmp/build-curl \ - && curl -sSL https://curl.se/download/curl-7.74.0.tar.gz | tar -xz -C . --strip-components=1 -ARG MY_CURL_OPT="--enable-static --disable-shared --enable-optimize --without-zlib --enable-http --enable-ipv6 --disable-dict --disable-file --disable-gopher --disable-imap --disable-ldap --disable-mqtt --disable-pop3 --disable-rtsp --disable-smtp --disable-telnet" -ARG WIN_TOOLCHAIN_PREFIX="x86_64-w64-mingw32" - -# --- Mingw64 (Windows) --- -RUN cd /tmp/build-curl \ - && ./configure --host=${WIN_TOOLCHAIN_PREFIX} --prefix=/usr/${WIN_TOOLCHAIN_PREFIX} --exec-prefix=/usr/${WIN_TOOLCHAIN_PREFIX} --disable-pthreads --with-winssl ${MY_CURL_OPT} \ - # install header files - && cd include \ - && make install \ - # make and install libcurl - && cd ../lib \ - && make \ - && make install \ - # remove the temporary build directory - && cd / \ - && rm -Rf /tmp/build-curl \ - && true - -### Add OSXCross and Mingw paths -ENV PATH="${PATH}:/usr/osxcross/bin" \ - MINGW_TOOLCHAIN_PREFIX="x86_64-w64-mingw32" \ - MINGW_PATH="/usr/x86_64-w64-mingw32" -RUN sudo ldconfig /usr/osxcross/lib - -### User / Entrypoint ####################################################expor - -# Add essential users to the docker image -RUN apt-get install -y --no-install-recommends sudo && apt-get clean \ - && echo "" | adduser --uid 1000 --disabled-password --gecos "" xpbuild && adduser xpbuild sudo \ - && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers - -VOLUME /build -USER xpbuild -ADD build.sh /usr/bin/build.sh - -# Entrypoint is the build.sh script, which takes care of actual building -WORKDIR /build -ENTRYPOINT ["build.sh"] diff --git a/XPMP2-Sample/docker/Makefile b/XPMP2-Sample/docker/Makefile deleted file mode 100755 index 87cced53..00000000 --- a/XPMP2-Sample/docker/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -platforms=win mac lin lin-bionic -container_focal=twinfan/focal-win-mac-lin-compile-env:02.00 -container_bionic=twinfan/bionic-lin-compile-env:01.00 - -all: $(platforms) - -.image_bionic: - docker image pull $(container_bionic) - docker inspect -f "{{ .ID}}" $(container_bionic) > .image_bionic - -.image_focal: - docker image pull $(container_focal) - docker inspect -f "{{ .ID}}" $(container_focal) > .image_focal - -bash_bionic: .image_bionic - docker run -it --rm -v "$(realpath ..):/build" --entrypoint bash $(container_bionic) - -bash_focal: .image_focal - docker run -it --rm -v "$(realpath ..):/build" --entrypoint bash $(container_focal) - -lin-bionic: .image_bionic - docker run -i --rm -v "$(realpath ..):/build" --entrypoint docker/build.sh $(container_bionic) $@ - -lin win mac-arm mac-x86: .image_focal - docker run -i --rm -v "$(realpath ..):/build" --entrypoint docker/build.sh $(container_focal) $@ - -mac: mac-arm mac-x86 - mkdir -p ../build-mac/mac_x64 - docker run -i --rm -v "$(realpath ..):/build" --entrypoint bash $(container_focal) -c 'lipo -create -output build-mac/mac_x64/XPMP2-Sample.xpl build-mac-x86/mac_x64/XPMP2-Sample.xpl build-mac-arm/mac_x64/XPMP2-Sample.xpl' - -clean: - rm -rf ../build-lin - rm -rf ../build-lin-bionic - rm -rf ../build-mac - rm -rf ../build-mac-arm - rm -rf ../build-mac-x86 - rm -rf ../build-win - -.PHONY: clean doc $(platforms) bash_bionic bash_focal diff --git a/XPMP2-Sample/docker/README.md b/XPMP2-Sample/docker/README.md deleted file mode 100644 index 8ccb9205..00000000 --- a/XPMP2-Sample/docker/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Docker Build environment - -This directory contains a setup to build all 3 platforms -(Windows, Linux, MacOS) via Docker environments in a -reproducible way. This allows to verify all three environments -compile and link fine. The resulting binaries are supposed -to actually work, though native build environments -(like Visual Studio or XCode) might produce smaller binaries. - -## Just Build - -If you "just want to build" then - -1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop) - and make sure it is running -2. `cd docker` -3. `make` - -During the very first invocaton this can take several minutes -as the two(!) involved Docker images are build for the first ime. -Subsequent builds will run in a matter of seconds. - -Find results in - -- `build-lin` -- `build-mac` -- `build-win` - -## Setup - -### Linux and MacOS based on Ubunto 18.04 - -For Linux and MacOS builds an environment based on Ubuntu 18.04 -is created, defined in `Dockerfile_Bionix` which installs -Linux build and MacOS cross compile tools. - -The resulting image is tagged `bionic-lin-mac-compile-env`. - -### Windows based on Ubuntu 20.04 with Mingw64 - -Windows is cross-compiled on an Ubuntu 20.04-based setup -using Mingw 8.0. Creating this image takes especially long -as several tools including Mingw intself are built from sources. - -`Dockerfile_Mingw` is based on the image -[`mmozeiko/mingw-w64`](https://hub.docker.com/r/mmozeiko/mingw-w64), -the only change is that the Mingw64/gcc compilers are configured -to use Win32 threads instead of pthreads library. - -When finished it is tagged `mingw-compile-env`. diff --git a/XPMP2-Sample/docker/Toolchain-mingw-w64-x86-64.cmake b/XPMP2-Sample/docker/Toolchain-mingw-w64-x86-64.cmake deleted file mode 100755 index cd68f430..00000000 --- a/XPMP2-Sample/docker/Toolchain-mingw-w64-x86-64.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Sample toolchain file for building for Windows from an Ubuntu Linux system. -# -# Expected environment variables and example values: -# MINGW_TOOLCHAIN_PREFIX = "x86_64-w64-mingw32" -# OSX_SDK_PATH = "/usr/x86_64-w64-mingw32" - -set(CMAKE_SYSTEM_NAME Windows) -set(CMAKE_INSTALL_PREFIX $ENV{MINGW_PATH}) -set(CMAKE_FIND_ROOT_PATH $ENV{MINGW_PATH}) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_C_COMPILER $ENV{MINGW_TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER $ENV{MINGW_TOOLCHAIN_PREFIX}-g++) -set(CMAKE_RC_COMPILER $ENV{MINGW_TOOLCHAIN_PREFIX}-windres) diff --git a/XPMP2-Sample/docker/Toolchain-ubuntu-osxcross.cmake b/XPMP2-Sample/docker/Toolchain-ubuntu-osxcross.cmake deleted file mode 100755 index 6e182cfe..00000000 --- a/XPMP2-Sample/docker/Toolchain-ubuntu-osxcross.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Sample toolchain file for building for Mac OS X from an Ubuntu Linux system. -# -# Expected environment variables and example values: -# OSX_TOOLCHAIN_PREFIX = "x86_64-apple-darwin20.2" -# OSX_SDK_PATH = "/usr/osxcross/SDK/MacOSX11.1.sdk" - -set(CMAKE_SYSTEM_NAME Darwin) -set(TOOLCHAIN_PREFIX $ENV{OSX_TOOLCHAIN_PREFIX}) - -# cross compilers to use for C and C++ -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++-libc++) - - -# target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs -set(CMAKE_FIND_ROOT_PATH $ENV{OSX_SDK_PATH}) - -# modify default behavior of FIND_XXX() commands to -# search for headers/libs in the target environment and -# search for programs in the build host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) diff --git a/XPMP2-Sample/docker/build.sh b/XPMP2-Sample/docker/build.sh deleted file mode 100755 index a46b9213..00000000 --- a/XPMP2-Sample/docker/build.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -set -eu - -function build() { - local src_dir="$1" - export platform="$2" - echo "----------------- Building for $platform -----------------" - - local build_dir="$src_dir/build-$platform" - - echo "pwd = $(pwd)" - echo "src_dir = $src_dir" - echo "build_dir = $build_dir" - - local flags=() - local cmake="cmake" - case "$platform" in - win) - flags+=('-DCMAKE_TOOLCHAIN_FILE=../docker/Toolchain-mingw-w64-x86-64.cmake') - ;; - mac*) - flags+=('-DCMAKE_TOOLCHAIN_FILE=../docker/Toolchain-ubuntu-osxcross.cmake') - ;; - esac - - mkdir -p "$build_dir" && cd "$build_dir" - "$cmake" -G Ninja "${flags[@]}" .. - ninja -} - -src_dir="$(pwd)" - -for platform in $@; do - build "$src_dir" "$platform" -done diff --git a/XPMP2-Sample/lib/.gitignore b/XPMP2-Sample/lib/.gitignore deleted file mode 100644 index 5f4af658..00000000 --- a/XPMP2-Sample/lib/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -XPMP2.framework/Headers -XPMP2.framework/Modules -XPMP2.framework/Resources -XPMP2.framework/Current -XPMP2.framework/XPMP2 diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPCAircraft.h b/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPCAircraft.h deleted file mode 100644 index 26ad637a..00000000 --- a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPCAircraft.h +++ /dev/null @@ -1,75 +0,0 @@ -/// @file XPCAircraft.h -/// @brief XPMP2::Aircraft / XPCAircraft represent an aircraft as managed by XPMP2 -/// @deprecated XPCAircraft bases on and is compile-compatible to the XPCAircraft wrapper -/// class provided with the original libxplanemp. -/// In XPMP2, however, this class is not a wrapper but derived from -/// XPMP2::Aircraft, which is the actual means of managing aircraft, -/// Hence, it includes a lot more members.\n -/// New implementations should derive directly from XPMP2::Aircraft. -/// @author Birger Hoppe -/// @copyright The original XPCAircraft.h file in libxplanemp had no copyright note. -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#ifndef _XPCAircraft_h_ -#define _XPCAircraft_h_ - -#include "XPMPAircraft.h" - -/// @brief Legacy wrapper class as provided by original libxplanemp -/// @deprecated Only provided for backwards compile-compatibility. -/// New implementations should subclass XPMP2::Aircraft directly. -class [[deprecated("Subclass XPMP2::Aircraft instead")]] -XPCAircraft : public XPMP2::Aircraft { - -public: - /// Last position data. GetPlanePosition() passes a pointer to this member variable - XPMPPlanePosition_t acPos; - /// Last surface data. GetPlaneSurfaces() passes a pointer to this member variable - XPMPPlaneSurfaces_t acSurfaces; - -public: - - /// @brief Legacy constructor creates a plane and puts it under control of XPlaneMP - /// @exception XPMP2::XPMP2Error Mode S id invalid or duplicate, no model found during model matching - /// @param _icaoType ICAO aircraft type designator, like 'A320', 'B738', 'C172' - /// @param _icaoAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string - /// @param _livery Special livery designator, can be an empty string - /// @param _modeS_id (optional) Unique identification of the plane [0x01..0xFFFFFF], e.g. the 24bit mode S transponder code. XPMP2 assigns an arbitrary unique number of not given - /// @param _modelId (optional) specific model id to be used (no folder/package name, just the id as defined in the `OBJ8_AIRCRAFT` line) - XPCAircraft(const char* _icaoType, - const char* _icaoAirline, - const char* _livery, - XPMPPlaneID _modeS_id = 0, // new parameters are defaulted, so that old code should compile - const char* _modelId = nullptr); - - /// Legacy: Called before rendering to query plane's current position, overwrite to provide your implementation - virtual XPMPPlaneCallbackResult GetPlanePosition(XPMPPlanePosition_t* outPosition) = 0; - /// Legacy: Called before rendering to query plane's current configuration, overwrite to provide your implementation - virtual XPMPPlaneCallbackResult GetPlaneSurfaces(XPMPPlaneSurfaces_t* outSurfaces) = 0; - /// Legacy: Called before rendering to query plane's current radar visibility, overwrite to provide your implementation - virtual XPMPPlaneCallbackResult GetPlaneRadar(XPMPPlaneRadar_t* outRadar) = 0; - /// Legacy: Called before rendering to query plane's textual information, overwrite to provide your implementation (optional) - virtual XPMPPlaneCallbackResult GetInfoTexts(XPMPInfoTexts_t * /*outInfoTexts*/) - { return xpmpData_Unavailable; } - - /// Just calls all 4 previous `Get...` functions and copies the provided values into `drawInfo` and `v` - virtual void UpdatePosition (float _elapsedSinceLastCall, int _flCounter); - -}; - -#endif diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPAircraft.h b/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPAircraft.h deleted file mode 100644 index 8ebccfb5..00000000 --- a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPAircraft.h +++ /dev/null @@ -1,623 +0,0 @@ -/// @file XPMPAircraft.h -/// @brief XPMP2::Aircraft represent an aircraft as managed by XPMP2 -/// @details New implementations should derive directly from XPMP2::Aircraft. -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#ifndef _XPMPAircraft_h_ -#define _XPMPAircraft_h_ - -#include "XPMPMultiplayer.h" -#include "XPLMInstance.h" -#include "XPLMCamera.h" -#include "XPLMMap.h" - -#include -#include -#include -#include -#include -#include - -// -// MARK: XPMP2 New Definitions -// - -namespace XPMP2 { - -class CSLModel; - -/// Convert revolutions-per-minute (RPM) to radians per second (rad/s) by multiplying with PI/30 -constexpr float RPM_to_RADs = 0.10471975511966f; -/// Convert feet to meters, e.g. for altitude calculations -constexpr double M_per_FT = 0.3048; // meter per 1 foot -/// Convert nautical miles to meters -constexpr int M_per_NM = 1852; // meter per one nautical mile -/// @brief standard gravitational acceleration [m/s²] -/// @see https://en.wikipedia.org/wiki/Gravity_of_Earth -constexpr float G_EARTH = 9.80665f; - -/// The dataRefs provided by XPMP2 to the CSL models -enum DR_VALS : std::uint8_t { - V_CONTROLS_GEAR_RATIO = 0, ///< `libxplanemp/controls/gear_ratio` and \n`sim/cockpit2/tcas/targets/position/gear_deploy` - V_CONTROLS_NWS_RATIO, ///< `libxplanemp/controls/nws_ratio`, the nose wheel angle, actually in degrees - V_CONTROLS_FLAP_RATIO, ///< `libxplanemp/controls/flap_ratio` and \n`sim/cockpit2/tcas/targets/position/flap_ratio` and `...flap_ratio2` - V_CONTROLS_SPOILER_RATIO, ///< `libxplanemp/controls/spoiler_ratio` - V_CONTROLS_SPEED_BRAKE_RATIO, ///< `libxplanemp/controls/speed_brake_ratio` and \n`sim/cockpit2/tcas/targets/position/speedbrake_ratio` - V_CONTROLS_SLAT_RATIO, ///< `libxplanemp/controls/slat_ratio` and \n`sim/cockpit2/tcas/targets/position/slat_ratio` - V_CONTROLS_WING_SWEEP_RATIO, ///< `libxplanemp/controls/wing_sweep_ratio` and \n`sim/cockpit2/tcas/targets/position/wing_sweep` - V_CONTROLS_THRUST_RATIO, ///< `libxplanemp/controls/thrust_ratio` and \n`sim/cockpit2/tcas/targets/position/throttle` - V_CONTROLS_YOKE_PITCH_RATIO, ///< `libxplanemp/controls/yoke_pitch_ratio` and \n`sim/cockpit2/tcas/targets/position/yolk_pitch` - V_CONTROLS_YOKE_HEADING_RATIO, ///< `libxplanemp/controls/yoke_heading_ratio` and \n`sim/cockpit2/tcas/targets/position/yolk_yaw` - V_CONTROLS_YOKE_ROLL_RATIO, ///< `libxplanemp/controls/yoke_roll_ratio` and \n`sim/cockpit2/tcas/targets/position/yolk_roll` - V_CONTROLS_THRUST_REVERS, ///< `libxplanemp/controls/thrust_revers` - - V_CONTROLS_TAXI_LITES_ON, ///< `libxplanemp/controls/taxi_lites_on` and \n`sim/cockpit2/tcas/targets/position/lights` - V_CONTROLS_LANDING_LITES_ON, ///< `libxplanemp/controls/landing_lites_on` and \n`sim/cockpit2/tcas/targets/position/lights` - V_CONTROLS_BEACON_LITES_ON, ///< `libxplanemp/controls/beacon_lites_on` and \n`sim/cockpit2/tcas/targets/position/lights` - V_CONTROLS_STROBE_LITES_ON, ///< `libxplanemp/controls/strobe_lites_on` and \n`sim/cockpit2/tcas/targets/position/lights` - V_CONTROLS_NAV_LITES_ON, ///< `libxplanemp/controls/nav_lites_on` and \n`sim/cockpit2/tcas/targets/position/lights` - - V_GEAR_NOSE_GEAR_DEFLECTION_MTR, ///< `libxplanemp/gear/nose_gear_deflection_mtr` - V_GEAR_TIRE_VERTICAL_DEFLECTION_MTR, ///< `libxplanemp/gear/tire_vertical_deflection_mtr` - V_GEAR_TIRE_ROTATION_ANGLE_DEG, ///< `libxplanemp/gear/tire_rotation_angle_deg` - V_GEAR_TIRE_ROTATION_SPEED_RPM, ///< `libxplanemp/gear/tire_rotation_speed_rpm` - V_GEAR_TIRE_ROTATION_SPEED_RAD_SEC, ///< `libxplanemp/gear/tire_rotation_speed_rad_sec` - - V_ENGINES_ENGINE_ROTATION_ANGLE_DEG, ///< `libxplanemp/engines/engine_rotation_angle_deg` - V_ENGINES_ENGINE_ROTATION_SPEED_RPM, ///< `libxplanemp/engines/engine_rotation_speed_rpm` - V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC, ///< `libxplanemp/engines/engine_rotation_speed_rad_sec` - V_ENGINES_PROP_ROTATION_ANGLE_DEG, ///< `libxplanemp/engines/prop_rotation_angle_deg` - V_ENGINES_PROP_ROTATION_SPEED_RPM, ///< `libxplanemp/engines/prop_rotation_speed_rpm` - V_ENGINES_PROP_ROTATION_SPEED_RAD_SEC, ///< `libxplanemp/engines/prop_rotation_speed_rad_sec` - V_ENGINES_THRUST_REVERSER_DEPLOY_RATIO, ///< `libxplanemp/engines/thrust_reverser_deploy_ratio` - - V_ENGINES_ENGINE_ROTATION_ANGLE_DEG1, ///< `libxplanemp/engines/engine_rotation_angle_deg1` - V_ENGINES_ENGINE_ROTATION_ANGLE_DEG2, ///< `libxplanemp/engines/engine_rotation_angle_deg2` - V_ENGINES_ENGINE_ROTATION_ANGLE_DEG3, ///< `libxplanemp/engines/engine_rotation_angle_deg3` - V_ENGINES_ENGINE_ROTATION_ANGLE_DEG4, ///< `libxplanemp/engines/engine_rotation_angle_deg4` - V_ENGINES_ENGINE_ROTATION_SPEED_RPM1, ///< `libxplanemp/engines/engine_rotation_speed_rpm1` - V_ENGINES_ENGINE_ROTATION_SPEED_RPM2, ///< `libxplanemp/engines/engine_rotation_speed_rpm2` - V_ENGINES_ENGINE_ROTATION_SPEED_RPM3, ///< `libxplanemp/engines/engine_rotation_speed_rpm3` - V_ENGINES_ENGINE_ROTATION_SPEED_RPM4, ///< `libxplanemp/engines/engine_rotation_speed_rpm4` - V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC1, ///< `libxplanemp/engines/engine_rotation_speed_rad_sec1` - V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC2, ///< `libxplanemp/engines/engine_rotation_speed_rad_sec2` - V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC3, ///< `libxplanemp/engines/engine_rotation_speed_rad_sec3` - V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC4, ///< `libxplanemp/engines/engine_rotation_speed_rad_sec4` - - - V_MISC_TOUCH_DOWN, ///< `libxplanemp/misc/touch_down` - - V_COUNT ///< always last, number of dataRefs XPMP2 pre-defines -}; - -/// @brief Collates some information on the CSL model -/// @details The XPMP2::CSLModel class definition is private to the XPMP2 library -/// as it contains many technical implementation details. -/// This structure contains some of the CSLModel information in a public -/// definition, returned by XPMP2::Aircraft::GetModelInfo(). -struct CSLModelInfo_t { - /// id, just an arbitrary label read from `xsb_aircraft.txt::OBJ8_AIRCRAFT` - std::string cslId; - /// name, formed by last part of path plus id - std::string modelName; - /// Path to the xsb_aircraft.txt file from where this model is loaded - std::string xsbAircraftPath; - /// Line number in the xsb_aircraft.txt file where the model definition starts - int xsbAircraftLn = 0; - /// ICAO aircraft type this model represents: `xsb_aircraft.txt::ICAO` - std::string icaoType; - /// Doc8643 information: Classification, like L1P, L4J, H1T - std::string doc8643Classification; - /// Doc8643 information: wake turbulence class, like M, L/M, L, H - std::string doc8643WTC; - - /// Any number of airline codes and/or liveries can be assigned to a model for matching purpose - struct MatchCrit_t { - std::string icaoAirline; ///< ICAO airine/operator code - std::string livery; ///< special livery (not often used) - }; - typedef std::vector vecMatchCrit_t; - // List of match criteria defined for the model, can be empty - vecMatchCrit_t vecMatchCrit; - - /// Default constructor does nothing - CSLModelInfo_t() {} - /// Constructor copies from XPMP2::CSLModel - CSLModelInfo_t(const XPMP2::CSLModel& csl); -}; - -/// @brief Actual representation of all aircraft in XPMP2. -/// @note In modern implementations, this class shall be subclassed by your plugin's code. -class Aircraft { - -public: - -protected: - /// @brief A plane is uniquely identified by a 24bit number [0x01..0xFFFFFF] - /// @details This number is directly used as `modeS_id` n the new - /// [TCAS override](https://developer.x-plane.com/article/overriding-tcas-and-providing-traffic-information/) - /// approach. - XPMPPlaneID modeS_id = 0; - -public: - /// @brief ICAO aircraft type designator of this plane - /// @see https://www.icao.int/publications/DOC8643/Pages/Search.aspx - std::string acIcaoType; - std::string acIcaoAirline; ///< ICAO Airline code of this plane - std::string acLivery; ///< Livery code of this plane - - /// @brief Holds position (in local coordinates!) and orientation (pitch, heading roll) of the aircraft. - /// @details This is where the plane will be placed in this drawing cycle.\n - /// @note When filling `y` directly (instead of using SetLocation()) remember to add - /// GetVertOfs() for accurate placement on the ground - XPLMDrawInfo_t drawInfo; - - /// Is the aircraft on the ground? - bool bOnGrnd = false; - - /// @brief actual dataRef values to be provided to the CSL model - /// @details XPMP2 provides a minimum set of dataRefs and also getter/setter - /// member functions, see below. This is the one place where - /// current dataRef values are stored. This array is passed on - /// _directly_ to the XP instance.\n - /// The size of the vector can increase if adding user-defined - /// dataRefs through XPMPAddModelDataRef(). - std::vector v; - - /// aircraft label shown in the 3D world next to the plane - std::string label; - float colLabel[4] = {1.0f,1.0f,0.0f,1.0f}; ///< label base color (RGB) - bool bDrawLabel = true; ///< Shall this aircraft's label be drawn? - - /// How much of the vertical offset shall be applied? (This allows phasing out the vertical offset in higher altitudes.) [0..1] - float vertOfsRatio = 1.0f; - - /// @brief By how much of the gear deflection shall the plane's altitude be reduced? - /// @details This is to keep the wheels on the ground when gear deflection is applied. - /// Unfortunately, the exact factor is model-dependend. `0.5` seems an OK compromise.\n - /// If you know better, then overwrite.\n - /// If you don't want XPMP2 to correct for gear deflection, set `0.0`. - float gearDeflectRatio = 0.5f; - - /// @brief Shall this plane be clamped to ground (ie. never sink below ground)? - /// @note This involves Y-Testing, which is a bit expensive, see [SDK](https://developer.x-plane.com/sdk/XPLMScenery). - /// If you know your plane is not close to the ground, - /// you may want to avoid clamping by setting this to `false`. - /// @see configuration item `XPMP2_CFG_ITM_CLAMPALL` - bool bClampToGround = false; - - /// @brief Priority for display in one of the limited number of TCAS target slots - /// @details The lower the earlier will a plane be considered for TCAS. - /// Increase this value if you want to make a plane less likely - /// to occupy one of the limited TCAS slots. - int aiPrio = 1; - - /// @brief Current radar status - /// @note Only the condition `mode != Standby` is of interest to XPMP2 for considering the aircraft for TCAS display - XPMPPlaneRadar_t acRadar; - - /// @brief Wake dataRef support - /// @see https://developer.x-plane.com/article/plugin-traffic-wake-turbulence/ - /// @details If values aren't set during aircraft creation, ie. remain at `NAN`, then defaults will be applied - /// based on the aircraft's wake turbulence category, - /// looked up from the Doc8643 list via ICAO aircraft type designator. - struct wakeTy { - float wingSpan_m = NAN; ///< wing span of the aircraft creating wake turbulence - float wingArea_m2 = NAN; ///< wing area (total area of both wings combined) of the aircraft creating wake turbulence - float mass_kg = NAN; ///< actual mass of the aircraft creating the wake - - void clear() { *this = wakeTy(); } ///< clear all values to defaults - bool needsDefaults() const; ///< any value left at `NAN`, ie. requires setting from Doc8643 WTC defaults? - /// based on Doc8643 WTC fill with defaults - void applyDefaults(const std::string& _wtc, bool _bOverwriteAllFields = true); - /// Copies values only for non-NAN fields - void fillUpFrom(const wakeTy& o); - } wake; ///< wake-support data - - /// Informational texts passed on via multiplayer shared dataRefs - XPMPInfoTexts_t acInfoTexts; - -protected: - bool bValid = true; ///< is this object valid? (Will be reset in case of exceptions) - bool bVisible = true; ///< Shall this plane be drawn at the moment and be visible to TCAS/interfaces? - bool bRender = true; ///< Shall the CSL model be drawn in 3D world? (if !bRender && bVivile then still visible on TCAS/interfaces, Remote Client uses this for local senders' planes to take over TCAS but not drawing) - - XPMP2::CSLModel* pCSLMdl = nullptr; ///< the CSL model in use - int matchQuality = -1; ///< quality of the match with the CSL model - int acRelGrp = 0; ///< related group, ie. line in `related.txt` in which this a/c appears, if any - - // this is data from about a second ago to calculate cartesian velocities - float prev_x = 0.0f, prev_y = 0.0f, prev_z = 0.0f; - float prev_ts = 0.0f; ///< last update of `prev_x/y/z` in XP's network time - - /// Set by SetOnGrnd() with the timestamp when to reset SetTouchDown() - float tsResetTouchDown = NAN; - - /// X-Plane instance handles for all objects making up the model - std::list listInst; - /// Which `sim/cockpit2/tcas/targets`-index does this plane occupy? [1..63], `-1` if none - int tcasTargetIdx = -1; - - /// Timestamp of last update of camera dist/bearing - float camTimLstUpd = 0.0f; - /// Distance to camera in meters (updated internally regularly) - float camDist = 0.0f; - /// Bearing from camera in degrees (updated internally regularly) - float camBearing = 0.0f; - - /// Y Probe for terrain testing, needed in ground clamping - XPLMProbeRef hProbe = nullptr; - - // Data used for drawing icons in X-Plane's map - int mapIconRow = 0; ///< map icon coordinates, row - int mapIconCol = 0; ///< map icon coordinates, column - float mapX = 0.0f; ///< temporary: map coordinates (NAN = not to be drawn) - float mapY = 0.0f; ///< temporary: map coordinates (NAN = not to be drawn) - std::string mapLabel; ///< label for map drawing - -private: - bool bDestroyInst = false; ///< Instance to be destroyed in next flight loop callback? -public: - /// @brief Constructor creates a new aircraft object, which will be managed and displayed - /// @exception XPMP2::XPMP2Error Mode S id invalid or duplicate, no model found during model matching - /// @param _icaoType ICAO aircraft type designator, like 'A320', 'B738', 'C172' - /// @param _icaoAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string - /// @param _livery Special livery designator, can be an empty string - /// @param _modeS_id (optional) **Unique** identification of the plane [0x01..0xFFFFFF], e.g. the 24bit mode S transponder code. XPMP2 assigns an arbitrary unique number of not given - /// @param _cslId (optional) specific unique model id to be used (package name/short id, as defined in the `OBJ8_AIRCRAFT` line) - Aircraft (const std::string& _icaoType, - const std::string& _icaoAirline, - const std::string& _livery, - XPMPPlaneID _modeS_id = 0, - const std::string& _cslId = ""); - /// Default constructor creates an empty, invalid(!) and invisible shell; call XPMP2::Aircraft::Create() to actually create a plane - Aircraft (); - /// Destructor cleans up all resources acquired - virtual ~Aircraft(); - - /// Aircraft must not be copied as they reference non-copyable resources like XP instances - Aircraft (const Aircraft&) = delete; - /// Aircraft must not be copied as they reference non-copyable resources like XP instances - Aircraft& operator=(const Aircraft&) = delete; - - /// @brief Creates a plane, only a valid operation if object was created using the default constructor - /// @exception Tried on already defined object; XPMP2::XPMP2Error Mode S id invalid or duplicate, no model found during model matching - /// @param _icaoType ICAO aircraft type designator, like 'A320', 'B738', 'C172' - /// @param _icaoAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string - /// @param _livery Special livery designator, can be an empty string - /// @param _modeS_id (optional) **Unique** identification of the plane [0x01..0xFFFFFF], e.g. the 24bit mode S transponder code. XPMP2 assigns an arbitrary unique number of not given - /// @param _cslId (optional) specific unique model id to be used (package name/short id, as defined in the `OBJ8_AIRCRAFT` line) - /// @param _pCSLModel (optional) The actual model to use (no matching or search by `_cslId` if model is given this way) - void Create (const std::string& _icaoType, - const std::string& _icaoAirline, - const std::string& _livery, - XPMPPlaneID _modeS_id = 0, - const std::string& _cslId = "", - CSLModel* _pCSLModel = nullptr); - - /// return the XPMP2 plane id - XPMPPlaneID GetModeS_ID () const { return modeS_id; } - /// Is this object a ground vehicle? - bool IsGroundVehicle() const; - /// @brief Is this object "related" to the given ICAO code? (named in the same line in related.txt) - /// @param _icaoType ICAO aircraft type designator, to which `*this` is compared - /// @details For example, `IsRelatedTo("GLID")` returns if `*this` is a glider - bool IsRelatedTo (const std::string& _icaoType) const; - /// @brief return the current TCAS target index (into `sim/cockpit2/tcas/targets`), 1-based, `-1` if not used - int GetTcasTargetIdx () const { return tcasTargetIdx; } - /// Is this plane currently also being tracked as a TCAS target, ie. will appear on TCAS? - bool IsCurrentlyShownAsTcasTarget () const { return tcasTargetIdx >= 1; } - /// Is this plane currently also being tracked by X-Plane's classic AI/multiplayer? - bool IsCurrentlyShownAsAI () const; - /// Is this plane to be drawn on TCAS? (It will if transponder is not switched off) - bool ShowAsAIPlane () const { return IsVisible() && acRadar.mode != xpmpTransponderMode_Standby; } - /// Reset TCAS target slot index to `-1` - void ResetTcasTargetIdx () { tcasTargetIdx = -1; } - - /// @brief Return a value for dataRef .../tcas/target/flight_id - /// @returns The first non-empty string out of: flight number, registration, departure/arrival airports - virtual std::string GetFlightId() const; - - /// @brief (Potentially) changes the plane's model after doing a new match attempt - /// @param _icaoType ICAO aircraft type designator, like 'A320', 'B738', 'C172' - /// @param _icaoAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string - /// @param _livery Special livery designator, can be an empty string - /// @return match quality, the lower the better - int ChangeModel (const std::string& _icaoType, - const std::string& _icaoAirline, - const std::string& _livery); - - /// @brief Finds a match again, using the existing parameters, eg. after more models have been loaded - /// @return match quality, the lower the better - int ReMatchModel () { return ChangeModel(acIcaoType,acIcaoAirline,acLivery); } - - /// @brief Assigns the given model - /// @param _cslId Search for this id (package/short) - /// @param _pCSLModel (optional) If given use this model and don't search - /// @return Successfuly found and assigned a model? - bool AssignModel (const std::string& _cslId, - CSLModel* _pCSLModel = nullptr); - - /// return a pointer to the CSL model in use (Note: The CSLModel structure is not public.) - XPMP2::CSLModel* GetModel () const { return pCSLMdl; } - /// return the name of the CSL model in use - const std::string& GetModelName () const; - /// return an information structure for the CSL model associated with the aircraft - CSLModelInfo_t GetModelInfo() const { return pCSLMdl ? CSLModelInfo_t(*pCSLMdl) : CSLModelInfo_t(); } - /// quality of the match with the CSL model - int GetMatchQuality () const { return matchQuality; } - /// Vertical offset, ie. the value that needs to be added to `drawInfo.y` to make the aircraft appear on the ground - float GetVertOfs () const; - - /// Is the a/c object valid? - bool IsValid() const { return bValid; } - /// Mark the plane invalid, e.g. after exceptions occured on the data - virtual void SetInvalid(); - - /// Make the plane (in)visible - virtual void SetVisible (bool _bVisible); - /// Is the plane visible? - bool IsVisible () const { return bVisible && bValid; } - - /// Switch rendering of the CSL model on or off - virtual void SetRender (bool _bRender); - /// Is this plane to be rendered? - bool IsRendered () const { return bRender && IsVisible(); } - - /// Are instances created for this aircraft? - bool IsInstanciated () const { return !listInst.empty(); } - - /// Define if this aircraft's label is to be drawn (provided label drawing is enabled globally) - void SetDrawLabel (bool _b) { bDrawLabel = _b; } - /// Shall this aircraft's label be drawn? - bool ShallDrawLabel () const { return bDrawLabel; } - - /// Distance to camera [m] - float GetCameraDist () const { return camDist; } - /// Bearing from camera [°] - float GetCameraBearing () const { return camBearing; } - - /// @brief Called right before updating the aircraft's placement in the world - /// @details Abstract virtual function. Override in derived classes and fill - /// `drawInfo`, the `v` array of dataRefs by calling the `Set`ters, - /// `label`, and `infoTexts` with current values. - /// @see See [XPLMFlightLoop_f](https://developer.x-plane.com/sdk/XPLMProcessing/#XPLMFlightLoop_f) - /// for background on the two passed-on parameters: - /// @param _elapsedSinceLastCall The wall time since last call - /// @param _flCounter A monotonically increasing counter, bumped once per flight loop dispatch from the sim. - virtual void UpdatePosition (float _elapsedSinceLastCall, int _flCounter) = 0; - - /// Is the aircraft on the ground? - bool IsOnGrnd () const { return bOnGrnd; } - /// @brief Set if the aircraft is on the ground - /// @param on_grnd Is the aircraft on the ground? - /// @param setTouchDownTime [opt] If not `NAN` activates SetTouchDown(), and automatically resets it after the given time in seconds - void SetOnGrnd (bool on_grnd, float setTouchDownTime = NAN); - - // --- Getters and Setters for the values in `drawInfo` --- - - /// @brief Converts world coordinates to local coordinates, writes to Aircraft::drawInfo - /// @note Alternatively, the calling plugin can set local coordinates in Aircraft::drawInfo directly - /// @param lat Latitude in degress -90..90 - /// @param lon Longitude in degrees -180..180 - /// @param alt_ft Altitude in feet above MSL - /// @param on_grnd Is the aircraft on the ground? - /// @param setTouchDownTime [opt] If not `NAN` activates SetTouchDown(), and automatically resets it after the given time in seconds - void SetLocation (double lat, double lon, double alt_ft, bool on_grnd, float setTouchDownTime = NAN) { - SetLocation(lat, lon, alt_ft); - SetOnGrnd(on_grnd, setTouchDownTime); - } - - /// Legacy version of above version of SetLocatiion(), here without setting ground flag - void SetLocation (double lat, double lon, double alt_ft); - - /// @brief Converts aircraft's local coordinates to lat/lon values - /// @warning This isn't exactly precice. If you need precise location keep it in your derived class yourself. - void GetLocation (double& lat, double& lon, double& alt_ft) const; - - /// Sets location in local world coordinates - void SetLocalLoc (float _x, float _y, float _z) { drawInfo.x = _x; drawInfo.y = _y; drawInfo.z = _z; } - /// Gets all location info (including local coordinates) - const XPLMDrawInfo_t& GetLocation () const { return drawInfo; } - - float GetPitch () const { return drawInfo.pitch; } ///< pitch [degree] - void SetPitch (float _deg) { drawInfo.pitch = _deg; } ///< pitch [degree] - float GetHeading () const { return drawInfo.heading; } ///< heading [degree] - void SetHeading (float _deg) { drawInfo.heading = _deg; } ///< heading [degree] - float GetRoll () const { return drawInfo.roll; } ///< roll [degree] - void SetRoll (float _deg) { drawInfo.roll = _deg; } ///< roll [degree] - - // --- Getters and Setters for the values in the `v` array --- - float GetGearRatio () const { return v[V_CONTROLS_GEAR_RATIO]; } ///< Gear deploy ratio - void SetGearRatio (float _f) { v[V_CONTROLS_GEAR_RATIO] = _f; } ///< Gear deploy ratio - float GetNoseWheelAngle () const { return v[V_CONTROLS_NWS_RATIO]; } ///< Nose Wheel angle in degrees - void SetNoseWheelAngle (float _f) { v[V_CONTROLS_NWS_RATIO] = _f; } ///< Nose Wheel angle in degrees - float GetFlapRatio () const { return v[V_CONTROLS_FLAP_RATIO]; } ///< Flaps deploy ratio - void SetFlapRatio (float _f) { v[V_CONTROLS_FLAP_RATIO] = _f; } ///< Flaps deploy ratio - float GetSpoilerRatio () const { return v[V_CONTROLS_SPOILER_RATIO]; } ///< Spoilers deploy ratio - void SetSpoilerRatio (float _f) { v[V_CONTROLS_SPOILER_RATIO] = _f; } ///< Spoilers deploy ratio - float GetSpeedbrakeRatio () const { return v[V_CONTROLS_SPEED_BRAKE_RATIO]; } ///< Speedbrakes deploy ratio - void SetSpeedbrakeRatio (float _f) { v[V_CONTROLS_SPEED_BRAKE_RATIO] = _f; } ///< Speedbrakes deploy ratio - float GetSlatRatio () const { return v[V_CONTROLS_SLAT_RATIO]; } ///< Slats deploy ratio - void SetSlatRatio (float _f) { v[V_CONTROLS_SLAT_RATIO] = _f; } ///< Slats deploy ratio - float GetWingSweepRatio () const { return v[V_CONTROLS_WING_SWEEP_RATIO]; } ///< Wing sweep ratio - void SetWingSweepRatio (float _f) { v[V_CONTROLS_WING_SWEEP_RATIO] = _f; } ///< Wing sweep ratio - float GetThrustRatio () const { return v[V_CONTROLS_THRUST_RATIO]; } ///< Thrust ratio - void SetThrustRatio (float _f) { v[V_CONTROLS_THRUST_RATIO] = _f; } ///< Thrust ratio - float GetYokePitchRatio () const { return v[V_CONTROLS_YOKE_PITCH_RATIO]; } ///< Yoke pitch ratio - void SetYokePitchRatio (float _f) { v[V_CONTROLS_YOKE_PITCH_RATIO] = _f; } ///< Yoke pitch ratio - float GetYokeHeadingRatio () const { return v[V_CONTROLS_YOKE_HEADING_RATIO]; } ///< Yoke heading ratio - void SetYokeHeadingRatio (float _f) { v[V_CONTROLS_YOKE_HEADING_RATIO] = _f; } ///< Yoke heading ratio - float GetYokeRollRatio () const { return v[V_CONTROLS_YOKE_ROLL_RATIO]; } ///< Yoke roll ratio - void SetYokeRollRatio (float _f) { v[V_CONTROLS_YOKE_ROLL_RATIO] = _f; } ///< Yoke roll ratio - float GetThrustReversRatio () const { return v[V_CONTROLS_THRUST_REVERS]; } ///< Thrust reversers ratio - void SetThrustReversRatio (float _f){ v[V_CONTROLS_THRUST_REVERS] = _f; } ///< Thrust reversers ratio - - bool GetLightsTaxi () const { return v[V_CONTROLS_TAXI_LITES_ON] > 0.5f; } ///< Taxi lights - void SetLightsTaxi (bool _b) { v[V_CONTROLS_TAXI_LITES_ON] = float(_b); } ///< Taxi lights - bool GetLightsLanding () const { return v[V_CONTROLS_LANDING_LITES_ON] > 0.5f; } ///< Landing lights - void SetLightsLanding (bool _b) { v[V_CONTROLS_LANDING_LITES_ON] = float(_b); } ///< Landing lights - bool GetLightsBeacon () const { return v[V_CONTROLS_BEACON_LITES_ON] > 0.5f; } ///< Beacon lights - void SetLightsBeacon (bool _b) { v[V_CONTROLS_BEACON_LITES_ON] = float(_b); } ///< Beacon lights - bool GetLightsStrobe () const { return v[V_CONTROLS_STROBE_LITES_ON] > 0.5f; } ///< Strobe lights - void SetLightsStrobe (bool _b) { v[V_CONTROLS_STROBE_LITES_ON] = float(_b); } ///< Strobe lights - bool GetLightsNav () const { return v[V_CONTROLS_NAV_LITES_ON] > 0.5f; } ///< Navigation lights - void SetLightsNav (bool _b) { v[V_CONTROLS_NAV_LITES_ON] = float(_b); } ///< Navigation lights - - float GetNoseGearDeflection () const { return v[V_GEAR_NOSE_GEAR_DEFLECTION_MTR]; } ///< Vertical nose gear deflection [meter] - void SetNoseGearDeflection (float _mtr) { v[V_GEAR_NOSE_GEAR_DEFLECTION_MTR] = _mtr; } ///< Vertical nose gear deflection [meter] - float GetTireDeflection () const { return v[V_GEAR_TIRE_VERTICAL_DEFLECTION_MTR]; } ///< Vertical (main) gear deflection [meter] - void SetTireDeflection (float _mtr) { v[V_GEAR_TIRE_VERTICAL_DEFLECTION_MTR] = _mtr; } ///< Vertical (main) gear deflection [meter] - float GetTireRotAngle () const { return v[V_GEAR_TIRE_ROTATION_ANGLE_DEG]; } ///< Tire rotation angle [degree] - void SetTireRotAngle (float _deg) { v[V_GEAR_TIRE_ROTATION_ANGLE_DEG] = _deg; } ///< Tire rotation angle [degree] - float GetTireRotRpm () const { return v[V_GEAR_TIRE_ROTATION_SPEED_RPM]; } ///< Tire rotation speed [rpm] - void SetTireRotRpm (float _rpm) { v[V_GEAR_TIRE_ROTATION_SPEED_RPM] = _rpm; ///< Tire rotation speed [rpm], also sets [rad/s] - v[V_GEAR_TIRE_ROTATION_SPEED_RAD_SEC] = _rpm * RPM_to_RADs; } - float GetTireRotRad () const { return v[V_GEAR_TIRE_ROTATION_SPEED_RAD_SEC]; } ///< Tire rotation speed [rad/s] - void SetTireRotRad (float _rad) { v[V_GEAR_TIRE_ROTATION_SPEED_RAD_SEC] = _rad; ///< Tire rotation speed [rad/s], also sets [rpm] - v[V_GEAR_TIRE_ROTATION_SPEED_RPM] = _rad / RPM_to_RADs; } - - float GetEngineRotAngle () const { return v[V_ENGINES_ENGINE_ROTATION_ANGLE_DEG]; } ///< Engine rotation angle [degree] - void SetEngineRotAngle (float _deg); ///< Engine rotation angle [degree], also sets engines 1..4 - float GetEngineRotRpm () const { return v[V_ENGINES_ENGINE_ROTATION_SPEED_RPM]; } ///< Engine rotation speed [rpm] - void SetEngineRotRpm (float _rpm); ///< Engine rotation speed [rpm], also sets [rad/s] and engines 1..4 - float GetEngineRotRad () const { return v[V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC]; } ///< Engine rotation speed [rad/s] - void SetEngineRotRad (float _rad); ///< Engine rotation speed [rad/s], also sets [rpm] and engines 1..4 - - float GetEngineRotAngle (size_t idx) const ///< Engine rotation angle [degree] for engine `idx` (1..4) - { return 1 <= idx && idx <= 4 ? v[V_ENGINES_ENGINE_ROTATION_ANGLE_DEG1+idx-1] : 0.0f; } - void SetEngineRotAngle (size_t idx, float _deg); ///< Engine rotation angle [degree] for engine `idx` (1..4) - float GetEngineRotRpm (size_t idx) const ///< Engine rotation speed [rpm] for engine `idx` (1..4) - { return 1 <= idx && idx <= 4 ? v[V_ENGINES_ENGINE_ROTATION_SPEED_RPM1+idx-1] : 0.0f; } - void SetEngineRotRpm (size_t idx, float _rpm); ///< Engine rotation speed [rpm] for engine `idx` (1..4), also sets [rad/s] - float GetEngineRotRad (size_t idx) const ///< Engine rotation speed [rad/s] for engine `idx` (1..4) - { return 1 <= idx && idx <= 4 ? v[V_ENGINES_ENGINE_ROTATION_SPEED_RAD_SEC+idx-1] : 0.0f; } - void SetEngineRotRad (size_t idx, float _rad); ///< Engine rotation speed [rad/s] for engine `idx` (1..4), also sets [rpm] - - float GetPropRotAngle () const { return v[V_ENGINES_PROP_ROTATION_ANGLE_DEG]; } ///< Propellor rotation angle [degree] - void SetPropRotAngle (float _deg) { v[V_ENGINES_PROP_ROTATION_ANGLE_DEG] = _deg; } ///< Propellor rotation angle [degree] - float GetPropRotRpm () const { return v[V_ENGINES_PROP_ROTATION_SPEED_RPM]; } ///< Propellor rotation speed [rpm] - void SetPropRotRpm (float _rpm) { v[V_ENGINES_PROP_ROTATION_SPEED_RPM] = _rpm; ///< Propellor rotation speed [rpm], also sets [rad/s] - v[V_ENGINES_PROP_ROTATION_SPEED_RAD_SEC] = _rpm * RPM_to_RADs; } - float GetPropRotRad () const { return v[V_ENGINES_PROP_ROTATION_SPEED_RAD_SEC]; } ///< Propellor rotation speed [rad/s] - void SetPropRotRad (float _rad) { v[V_ENGINES_PROP_ROTATION_SPEED_RAD_SEC] = _rad; ///< Propellor rotation speed [rad/s], also sets [rpm] - v[V_ENGINES_PROP_ROTATION_SPEED_RPM] = _rad / RPM_to_RADs; } - - float GetReversDeployRatio () const { return v[V_ENGINES_THRUST_REVERSER_DEPLOY_RATIO]; } ///< Thrust reversers deploy ratio - void SetReversDeployRatio (float _f){ v[V_ENGINES_THRUST_REVERSER_DEPLOY_RATIO] = _f; } ///< Thrust reversers deploy ratio - - bool GetTouchDown () const { return v[V_MISC_TOUCH_DOWN] > 0.5f; } ///< Moment of touch down - void SetTouchDown (bool _b) { v[V_MISC_TOUCH_DOWN] = float(_b); } ///< Moment of touch down - - // Wake support as per X-Plane 12 - - /// @brief Fill in default wake turbulence support data based on Doc8643 wake turbulence category - /// @param _bOverwriteAllFields If `false` only overwrites `NAN` values in `wakeTy` - void WakeApplyDefaults(bool _bOverwriteAllFields = true); - - float GetWingSpan () const { return wake.wingSpan_m; } ///< Wing span [m] - void SetWingSpan (float _m) { wake.wingSpan_m = _m; } ///< Wing span [m] - - float GetWingArea() const { return wake.wingArea_m2; } ///< Wing area [m²] - void SetWingArea (float _m2) { wake.wingArea_m2 = _m2; } ///< Wing area [m²] - - int GetWakeCat() const; ///< Category between 0=light and 3=Super, derived from WTC - - float GetMass() const { return wake.mass_kg; } ///< Mass [kg] - void SetMass(float _kg) { wake.mass_kg = _kg; } ///< Mass [kg] - - // Overridables: - virtual float GetAoA() const { return GetPitch(); } ///< Angle of Attach, returns pitch (but you can override in your class) - virtual float GetLift() const { return GetMass() * G_EARTH; } ///< Lift produced. You _should_ override to blend in/out for take-off/landing, but XPMP2 has no dynamic info of your plane, not even an on-the-ground flag - - // The following is implemented in Map.cpp: - /// Determine which map icon to use for this aircraft - void MapFindIcon (); - /// Prepare map coordinates - void MapPreparePos (XPLMMapProjectionID projection, - const float boundsLTRB[4]); - /// Actually draw the map icon - void MapDrawIcon (XPLMMapLayerID inLayer, float acSize); - /// Actually draw the map label - void MapDrawLabel (XPLMMapLayerID inLayer, float yOfs); - -protected: - /// Internal: Flight loop callback function controlling update and movement of all planes - static float FlightLoopCB (float, float, int, void*); - /// Internal: This puts the instance into XP's sky and makes it move - void DoMove (); - /// Internal: Update the plane's distance/bearing from the camera location - void UpdateDistBearingCamera (const XPLMCameraPosition_t& posCam); - /// Clamp to ground: Make sure the plane is not below ground, corrects Aircraft::drawInfo if needed. - void ClampToGround (); - /// Create the instances required to represent the plane, return if successful - bool CreateInstances (); - /// Destroy all instances - void DestroyInstances (); - - /// @brief Put together the map label - /// @details Called about once a second. Label depends on tcasTargetIdx - virtual void ComputeMapLabel (); - - // The following functions are implemented in AIMultiplayer.cpp: - /// Define the TCAS target index in use - virtual void SetTcasTargetIdx (int _idx) { tcasTargetIdx = _idx; } - // These functions perform the TCAS target / multiplayer data updates - friend void AIMultiUpdate (); - friend size_t AIUpdateTCASTargets (); - friend size_t AIUpdateMultiplayerDataRefs (); -}; - -/// Find aircraft by its plane ID, can return nullptr -Aircraft* AcFindByID (XPMPPlaneID _id); - -/// (Re)Define default wake turbulence values per WTC -bool AcSetDefaultWakeData(const std::string& _wtc, const Aircraft::wakeTy& _wake); - -// -// MARK: XPMP2 Exception class -// - -/// XPMP2 Exception class, e.g. thrown if there are no CSL models or duplicate modeS_ids when creating an Aircraft -class XPMP2Error : public std::logic_error { -protected: - std::string fileName; ///< filename of the line of code where exception occurred - int ln; ///< line number of the line of code where exception occurred - std::string funcName; ///< function of the line of code where exception occurred - std::string msg; ///< additional text message -public: - /// Constructor puts together a formatted exception text - XPMP2Error (const char* szFile, int ln, const char* szFunc, const char* szMsg, ...); -public: - /// returns msg.c_str() - virtual const char* what() const noexcept; - -public: - // copy/move constructor/assignment as per default - XPMP2Error (const XPMP2Error& o) = default; - XPMP2Error (XPMP2Error&& o) = default; - XPMP2Error& operator = (const XPMP2Error& o) = default; - XPMP2Error& operator = (XPMP2Error&& o) = default; -}; - - - -} // namespace XPMP2 - -#endif diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPMultiplayer.h b/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPMultiplayer.h deleted file mode 100644 index 7beae655..00000000 --- a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPMultiplayer.h +++ /dev/null @@ -1,717 +0,0 @@ -/// @file XPMPMultiplayer.h -/// @brief Initialization and general control functions for XPMP2 -/// -/// @note This file bases on and should be largely compile-compatible to -/// the header provided with the original libxplanemp. -/// @note Some functions are marked deprecated, reason is given with -/// each function. They are only provided for backward -/// compatibility. -/// -/// @details This is one of two main header files for using XPMP2. -/// (The other is `XPMPAircraft.h`). -/// XPMP2 is a library allowing an X-Plane plugin to have -/// planes rendered in X-Plane's 3D world based on OBJ8 -/// CSL models, which need to be installed separately. -/// The plugin shall subclass XPMP2::Aircraft:: and override -/// the abstract virtual function XPMP2::Aircraft::UpdatePosition() -/// to provide updated position and attitude information. -/// XPMP2 takes care of reading and initializaing CSL models, -/// instanciating and updating the aircraft objects in X-Plane, -/// display in a map layer, provisioning information via X-Plane's -/// TCAS targets and AI/multiplayer (and more) dataRefs. -/// -/// @see For more developer's information see -/// https://twinfan.github.io/XPMP2/ -/// -/// @see For TCAS Override approach see -/// https://developer.x-plane.com/article/overriding-tcas-and-providing-traffic-information/ -/// -/// @see For a definition of ICAO aircraft type designators see -/// https://www.icao.int/publications/DOC8643/Pages/Search.aspx -/// -/// @see For a list of ICAO airline/operator codes see -/// https://en.wikipedia.org/wiki/List_of_airline_codes -/// -/// @author Ben Supnik and Chris Serio -/// @copyright Copyright (c) 2004, Ben Supnik and Chris Serio. -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#ifndef _XPLMMultiplayer_h_ -#define _XPLMMultiplayer_h_ - -#include -#include "XPLMDefs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// defined in XPMPAircraft -namespace XPMP2 { class Aircraft; } - -/************************************************************************************ - * MARK: PLANE DATA TYPES - ************************************************************************************/ - -/// XPMPPosition_t -/// -/// @brief This data structure contains the basic position info for an aircraft. -/// @note This structure is only used with deprecated concepts -/// (class XPCAircraft and direct use of callback functions.) -/// @note There is no notion of aircraft velocity or acceleration; you will be queried for -/// your position every rendering frame. Higher level APIs can use velocity and acceleration. -struct XPMPPlanePosition_t { - long size = sizeof(XPMPPlanePosition_t); ///< size of structure - double lat = 0.0; ///< current position of aircraft (latitude) - double lon = 0.0; ///< current position of aircraft (longitude) - double elevation = 0.0; ///< current altitude of aircraft [ft above MSL] - float pitch = 0.0f; ///< pitch [degrees, psitive up] - float roll = 0.0f; ///< roll [degrees, positive right] - float heading = 0.0f; ///< heading [degrees] - char label[32] = ""; ///< label to show with the aircraft - float offsetScale = 1.0f; ///< how much of the surface contact correction offset should be applied [0..1] - bool clampToGround = false; ///< enables ground-clamping for this aircraft (can be expensive, see XPMP2::Aircraft::bClampToGround) - int aiPrio = 1; ///< Priority for AI/TCAS consideration, the lower the earlier - float label_color[4] = {1.0f,1.0f,0.0f,1.0f}; ///< label base color (RGB), defaults to yellow - int multiIdx = 0; ///< OUT: set by XPMP2 to inform application about TCAS target index in use [1..63], with [1..19] also being available via classic multiplayer dataRefs, `< 1` means 'none' -}; - - -/// @brief Light flash patterns -/// @note Unused in XPMP2 -/// @note Not changed to proper enum type as it is used in bitfields in xpmp_LightStatus, -/// which causes misleading, non-suppressable warnings in gcc:\n -/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51242 -enum { - xpmp_Lights_Pattern_Default = 0, ///< Jets: one strobe flash, short beacon (-*---*---*---) - xpmp_Lights_Pattern_EADS = 1, ///< Airbus+EADS: strobe flashes twice (-*-*-----*-*--), short beacon - xpmp_Lights_Pattern_GA = 2 ///< GA: one strobe flash, long beacon (-*--------*---) -}; -typedef unsigned int XPMPLightsPattern; ///< Light flash pattern (unused in XPMP2) - - -#if __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" // because we don't want to change the anonymous structure following here as that would require code change in legacy plugins -#elif _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4202 4201) -#endif -/// @brief Defines, which lights of the aircraft are on -/// @note This structure is only used with deprecated concepts -/// (class XPCAircraft and direct use of callback functions.) -union xpmp_LightStatus { - unsigned int lightFlags = 0x150000; ///< this defaults to taxi | beacon | nav lights on - struct { - unsigned int timeOffset : 16; ///< time offset to avoid lights across planes blink in sync (unused in XPMP2) - - unsigned int taxiLights : 1; ///< taxi lights on? - unsigned int landLights : 1; ///< landing lights on? - unsigned int bcnLights : 1; ///< beacon on? - unsigned int strbLights : 1; ///< strobe lights on? - unsigned int navLights : 1; ///< navigation lights on? - - /// light pattern (unused in XPMP2) - XPMPLightsPattern flashPattern : 4; - }; -}; -#if __GNUC__ -#pragma GCC diagnostic pop -#elif _MSC_VER -#pragma warning(pop) -#endif - - -/// @brief External physical configuration of the plane -/// @note This structure is only used with deprecated concepts -/// (class XPCAircraft and direct use of callback functions.) -/// @details This data structure will contain information about the external physical configuration of the plane, -/// things you would notice if you are seeing it from outside. This includes flap position, gear position, -/// etc. -struct XPMPPlaneSurfaces_t { - long size = sizeof(XPMPPlaneSurfaces_t); ///< structure size - float gearPosition = 0.0f; ///< gear position [0..1] - float flapRatio = 0.0f; ///< flap extension ratio [0..1] - float spoilerRatio = 0.0f; ///< spoiler extension ratio [0..1] - float speedBrakeRatio = 0.0f; ///< speed brake extension ratio [0..1] - float slatRatio = 0.0f; ///< slats extension ratio [0..1] - float wingSweep = 0.0f; ///< wing sweep ratio [0..1] - float thrust = 0.0f; ///< thrust ratio [0..1] - float yokePitch = 0.0f; ///< yoke pitch ratio [0..1] - float yokeHeading = 0.0f; ///< yoke heading ratio [0..1] - float yokeRoll = 0.0f; ///< yoke roll ratio [0..1] - - xpmp_LightStatus lights; ///< status of lights - - float tireDeflect = 0.0f; ///< tire deflection (meters) - float tireRotDegree = 0.0f; ///< tire rotation angle (degrees 0..360) - float tireRotRpm = 0.0f; ///< tire rotation speed (rpm) - - float engRotDegree = 0.0f; ///< engine rotation angle (degrees 0..360) - float engRotRpm = 0.0f; ///< engine rotation speed (rpm) - float propRotDegree = 0.0f; ///< prop rotation angle (degrees 0..360) - float propRotRpm = 0.0f; ///< prop rotation speed (rpm) - float reversRatio = 0.0f; ///< thrust reversers ratio - - bool touchDown = false; ///< just now is moment of touch down? -}; - - -/// @brief These enumerations define the way the transponder of a given plane is operating. -/// @note Only information used by XPMP2 is `"mode != xpmpTransponderMode_Standby"`, -/// in which case the plane is considered for TCAS display. -enum XPMPTransponderMode { - xpmpTransponderMode_Standby, ///< transponder is in standby, not currently sending -> aircraft not visible on TCAS - xpmpTransponderMode_Mode3A, ///< transponder is on - xpmpTransponderMode_ModeC, ///< transponder is on - xpmpTransponderMode_ModeC_Low, ///< transponder is on - xpmpTransponderMode_ModeC_Ident ///< transponder is on -}; - - -/// @brief defines information about an aircraft visible to radar. -struct XPMPPlaneRadar_t { - long size = sizeof(XPMPPlaneRadar_t); ///< structure size - long code = 0; ///< current radar code, published via dataRef `sim/cockpit2/tcas/targets/modeC_code` - XPMPTransponderMode mode = xpmpTransponderMode_ModeC; ///< current radar mode, if _not_ `xpmpTransponderMode_Standby` then is plane considered for TCAS display -}; - - -/// @brief Textual information of planes to be passed on -/// via shared dataRefs to other plugins. -/// @details The texts are not used within XPMP2 in any way, just passed on to dataRefs -struct XPMPInfoTexts_t { - long size = sizeof(XPMPInfoTexts_t);///< structure size - char tailNum[10] = {0}; ///< registration, tail number - char icaoAcType[5] = {0}; ///< ICAO aircraft type designator, 3-4 chars - char manufacturer[40] = {0}; ///< a/c manufacturer, human readable - char model[40] = {0}; ///< a/c model, human readable - char icaoAirline[4] = {0}; ///< ICAO airline code - char airline[40] = {0}; ///< airline, human readable - char flightNum [10] = {0}; ///< flight number - char aptFrom [5] = {0}; ///< Origin airport (ICAO) - char aptTo [5] = {0}; ///< Destination airport (ICAO) -}; - - -/// @brief This enum defines the different categories of aircraft information we can query about. -/// @note While these enums are defined in a way that they could be combined together, -/// there is no place, which makes use of this possibility. Each value will be used -/// individually only. Because of this, the definition has been changed in XPMP2 -/// to an actual enum type for clarity. -/// @note This enum is only used with deprecated concepts -/// (class XPCAircraft and direct use of callback functions.) -enum XPMPPlaneDataType { - xpmpDataType_Position = 1L << 1, ///< position data in XPMPPlanePosition_t - xpmpDataType_Surfaces = 1L << 2, ///< physical appearance in XPMPPlaneSurfaces_t - xpmpDataType_Radar = 1L << 3, ///< radar information in XPMPPlaneRadar_t - xpmpDataType_InfoTexts = 1L << 4, ///< informational texts in XPMPInfoTexts_t -}; - - -/// @brief Definfes the different responses to asking for information. -/// @note This enum is only used with deprecated concepts -/// (class XPCAircraft and direct use of callback functions.) -enum XPMPPlaneCallbackResult { - xpmpData_Unavailable = 0, /* The information has never been specified. */ - xpmpData_Unchanged = 1, /* The information from the last time the plug-in was asked. */ - xpmpData_NewData = 2 /* The information has changed this sim cycle. */ -}; - - -/// @brief Unique ID for an aircraft created by a plugin. -/// @note In XPMP2 this value is no longer a pointer to an internal memory address, -/// but will directly be used as `modeS_id` in the new -/// [TCAS override](https://developer.x-plane.com/article/overriding-tcas-and-providing-traffic-information/) -/// approach. -typedef unsigned XPMPPlaneID; - -/// Minimum allowed XPMPPlaneID / mode S id -constexpr XPMPPlaneID MIN_MODE_S_ID = 0x00000001; -/// Maximum allowed XPMPPlaneID / mode S id -constexpr XPMPPlaneID MAX_MODE_S_ID = 0x00FFFFFF; - - -/************************************************************************************ -* MARK: INITIALIZATION -************************************************************************************/ - -// Config section is defined for legacy reasons only -#define XPMP_CFG_SEC_MODELS "models" ///< Config section "models" -#define XPMP_CFG_SEC_PLANES "planes" ///< Config section "planes" -#define XPMP_CFG_SEC_DEBUG "debug" ///< Config section "debug" - -// Config key definitions -#define XPMP_CFG_ITM_REPLDATAREFS "replace_datarefs" ///< Config key: Replace dataRefs in OBJ8 files upon load, creating new OBJ8 files for XPMP2 (defaults to OFF!) -#define XPMP_CFG_ITM_REPLTEXTURE "replace_texture" ///< Config key: Replace textures in OBJ8 files upon load if needed (specified on the OBJ8 line in xsb_aircraft.txt), creating new OBJ8 files -#define XPMP_CFG_ITM_CLAMPALL "clamp_all_to_ground" ///< Config key: Ensure no plane sinks below ground, no matter of XPMP2::Aircraft::bClampToGround -#define XPMP_CFG_ITM_HANDLE_DUP_ID "handle_dup_id" ///< Config key: Boolean: If XPMP2::Aircraft::modeS_id already exists then assign a new unique one, overwrites XPMP2::Aircraft::modeS_id -#define XPMP_CFG_ITM_SUPPORT_REMOTE "support_remote" ///< Config key: Support remote connections? `<0` force off, `0` default: on if in a networked or multiplayer setup, `>0` force on -#define XPMP_CFG_ITM_LOGLEVEL "log_level" ///< Config key: General level of logging into `Log.txt` (0 = Debug, 1 = Info, 2 = Warning, 3 = Error, 4 = Fatal) -#define XPMP_CFG_ITM_MODELMATCHING "model_matching" ///< Config key: Write information on model matching into `Log.txt` - -/// @brief Definition for the type of configuration callback function -/// @details The plugin using XPMP2 can provide such a callback function via XPMPMultiplayerInit(). -/// It will be called max. every 2s to fetch each of the following configuration values:\n -/// \n -/// `section | key                 | type | default | description`\n -/// `------- | ------------------- | ---- | ------- | -------------------------------------------------------------------------`\n -/// `models  | replace_datarefs    | int  |    0    | Replace dataRefs in OBJ8 files upon load, creating new OBJ8 files for XPMP2 (defaults to OFF!)`\n -/// `models  | replace_texture     | int  |    1    | Replace textures in OBJ8 files upon load if needed (specified on the OBJ8 line in xsb_aircraft.txt), creating new OBJ8 files`\n -/// `planes  | clamp_all_to_ground | int  |    1    | Ensure no plane sinks below ground, no matter of XPMP2::Aircraft::bClampToGround`\n -/// `planes  | handle_dup_id       | int  |    0    | Boolean: If XPMP2::Aircraft::modeS_id already exists then assign a new unique one, overwrites XPMP2::Aircraft::modeS_id`\n -/// `planes  | support_remote      | int  |    0    | 3-state integer: Support remote connections? <0 force off, 0 default: on if in a networked or multiplayer setup, >0 force on`\n -/// `debug   | log_level           | int  |    2    | General level of logging into Log.txt (0 = Debug, 1 = Info, 2 = Warning, 3 = Error, 4 = Fatal)`\n -/// `debug   | model_matching      | int  |    0    | Write information on model matching into Log.txt`\n -/// @note There is no immediate requirement to check the value of `_section` in your implementation. -/// `_key` by itself is unique. Compare it with any of the `XPMP_CFG_ITM_*` values and return your value. -/// @param _section Configuration section, ie. group of values, any of the `XPMP_CFG_SEC_...` values -/// @param _key Any of the `XPMP_CFG_ITM_*` values to indicate which config value is to be returned. -/// @param _default A default provided by XPMP2. Have your callback return `_default` if you don't want to explicitely set a value or don't know the `_key`. -/// @return Your callback shall return your config value for config item `_key` -typedef int (*XPMPIntPrefsFuncTy)(const char* _section, const char* _key, int _default); - -/// @brief Deprecated legacy initialization of XPMP2. -/// @note Parameters changed compared to libxplanemp! -/// @details Effectively calls, in this order, -/// XPMPMultiplayerInit() and XPMPLoadCSLPackage(). -/// @see XPMPMultiplayerInit() and XPMPLoadCSLPackage() for details on the parameters. -[[deprecated("Use XPMPMultiplayerInit and XPMPLoadCSLPackages")]] -const char * XPMPMultiplayerInitLegacyData(const char* inCSLFolder, - const char* inPluginName, - const char* resourceDir, - XPMPIntPrefsFuncTy inIntPrefsFunc = nullptr, - const char* inDefaultICAO = nullptr, - const char* inPluginLogAcronym = nullptr); - -/// @brief Initializes the XPMP2 library. This shall be your first call to the library. -/// @note Parameters changed compared to libxplanemp! -/// @param inPluginName Your plugin's name, mainly used as map layer name and for logging -/// @param resourceDir The directory where XPMP2 finds all required supplemental files (`Doc8643.txt`, `MapIcons.png`, `related.txt`, optionally `Obj8DataRefs.txt`) -/// @param inIntPrefsFunc (optional) A pointer to a callback function providing integer config values. See ::XPMPIntPrefsFuncTy for details. -/// @param inDefaultICAO (optional) A fallback aircraft type if no type can be deduced otherwise for an aircraft. -/// @param inPluginLogAcronym (optional) A short text to be used in log output. If not given then `inPluginName` is used also for this purpose. -/// @return Empty string in case of success, otherwise a human-readable error message. -const char * XPMPMultiplayerInit(const char* inPluginName, - const char* resourceDir, - XPMPIntPrefsFuncTy inIntPrefsFunc = nullptr, - const char* inDefaultICAO = nullptr, - const char* inPluginLogAcronym = nullptr); - -/// @brief Overrides the plugin's name to be used in Log output -/// @details The same as providing a plugin name with XPMPMultiplayerInit(). -/// If no name is provided, it defaults to the plugin's name as set in XPluginStart(). -/// @note Replaces the compile-time macro `XPMP_CLIENT_LONGNAME` needed in `libxplanemp`. -/// @param inPluginName Your plugin's name, used as map layer name, and as folder name under `Aircraft` -/// @param inPluginLogAcronym (optional) A short text to be used in log output. If not given then `inPluginName` is used also for this purpse. -void XPMPSetPluginName (const char* inPluginName, - const char* inPluginLogAcronym = nullptr); - - -/// @brief Clean up the multiplayer library -/// @details This shall be your last call to XPMP2. -/// Call this latest from XPluginStop for proper and controlled -/// cleanup of resources used by XPMP2. -void XPMPMultiplayerCleanup(); - - -/// @brief Used to set the light textures for old OBJ7 models. -/// @note Unsupported with XPMP2, will always return "OBJ7 format is no longer supported" -[[deprecated("Unsupported feature, will alsways return 'OBJ7 format is no longer supported'")]] -const char * XPMPMultiplayerOBJ7SupportEnable(const char * inTexturePath); - - -/************************************************************************************ -* MARK: AI / Multiplayer plane control -************************************************************************************/ - - -/// @brief Tries to grab control of TCAS targets (formerly known as AI/multiplayer) from X-Plane -/// @details Only one plugin can have TCAS targets control at any one time. -/// So be prepared to properly handle an non-empty response -/// that indicates that you did not get control now. -/// The returned message includes the name of the plugin -/// currently having control.\n -/// If successful, XPMP2's aircraft will appear on TCAS and are -/// available to 3rd-party plugins relying on TCAS tagrtes or multiplayer dataRefs.\n -/// Typically, a plugin calls this function -/// just before the first aircraft are created. But it could also -/// be bound to a menu item, for example. -/// @param _callback (optional) You can provide a callback function, -/// which is called directly by X-Plane when control of -/// TCAS targets is not successful now but becomes available later. -/// @param _refCon (optional) A value just passed through to the callback. -/// @see X-Plane SDK documentation on -/// [XPLMAcquirePlanes](https://developer.x-plane.com/sdk/XPLMPlanes/#XPLMPlanesAvailable_f) -/// for more details about the callback. -/// @return Empty string on success, human-readable error message otherwise, -/// includes name of plugin currently having TCAS tagrets control -const char * XPMPMultiplayerEnable(void (*_callback)(void*) = nullptr, - void* _refCon = nullptr); - - -/// @brief Release TCAS targets control. -/// @details Afterwards, XPMP2's aircraft will no longer appear on TCAS or -/// on 3rd-party plugins relying on TCAS targets dataRefs.\n -/// Is called during XPMPMultiplayerCleanup() automatically. -void XPMPMultiplayerDisable(); - - -/// @brief Has XPMP2 control of TCAS targets? -/// @see XPMPMultiplayerEnable() -bool XPMPHasControlOfAIAircraft(); - -/************************************************************************************ -* MARK: CSL Package Handling -************************************************************************************/ - -/// @brief Loads CSL packages from the given folder, searching up to 5 folder levels deep. -/// @details This function mainly searches the given folder for packages. -/// It traverses all folders in search for `xsb_aircraft.txt` files. -/// It will find all `xsb_aircraft.txt` files situated at or below -/// the given root path, up to 5 levels deep.\n -/// As soon as such a file is found it is read and processed. -/// Depth search then ends. (But searching parallel folders may -/// still continue.)\n -/// The `xsb_aircraft.txt` is loaded and processed. Duplicate models -/// (by package _and_ CSL model name, -/// tags `EXPORT_NAME` _and_ `OBJ8_AIRCRAFT`) are ignored. -/// For others the existence of the `.obj` file is validated, -/// but not the existence of files in turn needed by the `.obj` -/// file, like textures. If validated successfully the model is added to an -/// internal catalogue.\n -/// Actual loading of objects is done later and asynchronously only -/// when needed during aircraft creation. -/// @param inCSLFolder Root folder to start the search. -const char * XPMPLoadCSLPackage(const char * inCSLFolder); - - -/// @brief Legacy function only provided for backwards compatibility. Does not actually do anything. -[[deprecated("No longer needed, does not do anything.")]] -void XPMPLoadPlanesIfNecessary(); - - -/// @brief Returns the number of loaded CSL models -int XPMPGetNumberOfInstalledModels(); - - -/// @brief Fetch information about a CSL model identified by an index -/// @note Index numbers may change if more models are loaded, don't rely on them. -/// Model name is unique. -/// @deprecated Instead, use XPMPGetModelInfo2().\n -/// This legacy function is defined with pointers to text arrays as -/// return type. This is rather unsafe. XPMP2's internal maps and buffers -/// may change if more models are loaded, hence pointers may become invalid. -/// Don't rely on these pointers staying valid over an extended period of time. -/// @param inIndex Number between `0` and `XPMPGetNumberOfInstalledModels()-1 -/// @param[out] outModelName Receives pointer to model name (id). Optional, can be nullptr. -/// @param[out] outIcao Receives pointer to ICAO aircraft type designator. Optional, can be `nullptr`. -/// @param[out] outAirline Receives pointer to ICAO airline code. Optional, can be `nullptr`. -/// @param[out] outLivery Receives pointer to special livery string. Optional, can be `nullptr`. -[[deprecated("Unsafe, use XPMPGetModelInfo2() instead.")]] -void XPMPGetModelInfo(int inIndex, const char **outModelName, const char **outIcao, const char **outAirline, const char **outLivery); - -/// @brief Fetch information about a CSL model identified by an index -/// @note Index numbers may change if more models are loaded, don't rely on them. -/// Model name is unique. -/// @param inIndex Number between `0` and `XPMPGetNumberOfInstalledModels()-1 -/// @param[out] outModelName Receives model name (id) -/// @param[out] outIcao Receives ICAO aircraft designator -/// @param[out] outAirline Receives ICAO airline code -/// @param[out] outLivery Receives special livery string -void XPMPGetModelInfo2(int inIndex, std::string& outModelName, std::string& outIcao, std::string& outAirline, std::string& outLivery); - - -/// @brief Tests model match quality based on the given parameters. -/// @param inICAO ICAO aircraft type designator, optional, can be `nullptr` -/// @param inAirline ICAO airline code, optional, can be `nullptr` -/// @param inLivery Special livery text, optional, can be `nullptr` -/// @return Match quality, the lower the better -int XPMPModelMatchQuality(const char * inICAO, - const char * inAirline, - const char * inLivery); - - -/// @brief Is `inICAO` a valid ICAO aircraft type designator? -bool XPMPIsICAOValid(const char * inICAO); - -/// @brief Add a user-defined dataRef to the list of dataRefs supported by every plane. -/// @details All planes created by XPMP2 define the same set of dataRefs. -/// See XPMP2::DR_VALS for the definitions that come pre-defined with -/// XPMP2. Here you can add more dataRefs that you want to set -/// in your XPMP2::Aircraft::UpdatePosition() implementation. -/// @return The functions returns the array index you need to use in the -/// XPMP2::Aircraft::v array to provide the actual value. -/// Or `0` when an error occured. -/// @note There is a duplication check: Adding an already existing dataRef, -/// no matter if XPMP2-predefined or by the plugin will return the -/// already existing index. -/// @note Can only be called while no plane exists as it influence the size -/// of important data arrays. Returns `0` if called while planes exist. -/// @note Can only be called from XP's main thread as XPLM SDK functions are called. -/// Returns `0` if called from a worker thread. -/// @note User-defined dataRefs are _not_ transfered to the XPMP2 Remote Client -/// for display on network-connected X-Plane instances. -size_t XPMPAddModelDataRef (const std::string& dataRef); - -/************************************************************************************ - * MARK: PLANE CREATION API - ************************************************************************************/ - - -/// @brief Callback function your plugin provides to return updated plane data -/// @note This type is only used with deprecated concepts -/// (direct use of callback functions.) -/// @details This functions is called by XPMP2 once per cycle per plane per data type. -/// Your implementation returns the requested data, -/// so that XPMP2 can move and update the associated aircraft instance. -/// @param inPlane ID of the plane, for which data is requested -/// @param inDataType The type of data that is requested, see ::XPMPPlaneDataType -/// @param[out] ioData A pointer to a structure XPMP2 provides, for you to fill the data into. -/// For its type see ::XPMPPlaneDataType. -/// @param inRefcon The refcon value you provided when creating the plane -typedef XPMPPlaneCallbackResult (* XPMPPlaneData_f)(XPMPPlaneID inPlane, - XPMPPlaneDataType inDataType, - void * ioData, - void * inRefcon); - - -/// @brief Creates a new plane -/// @deprecated Subclass XPMP2::Aircraft instead -/// @details Effectively calls XPMPCreatePlaneWithModelName() with -/// `inModelName = nullptr` -/// @param inICAOCode ICAO aircraft type designator, like 'A320', 'B738', 'C172' -/// @param inAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string -/// @param inLivery Special livery designator, can be an empty string -/// @param inDataFunc Callback function called by XPMP2 to fetch updated data -/// @param inRefcon A refcon value passed back to you in all calls to the `inDataFunc` -/// @param inModeS_id (optional) Unique identification of the plane [0x01..0xFFFFFF], e.g. the 24bit mode S transponder code. XPMP2 assigns an arbitrary unique number of not given -[[deprecated("Subclass XPMP2::Aircraft instead")]] -XPMPPlaneID XPMPCreatePlane(const char * inICAOCode, - const char * inAirline, - const char * inLivery, - XPMPPlaneData_f inDataFunc, - void * inRefcon, - XPMPPlaneID inModeS_id = 0); - -/// @brief Creates a new plane, providing a specific CSL model name -/// @deprecated Subclass XPMP2::Aircraft instead -/// @param inModelName CSL Model name (id) to use, or `nullptr` if normal matching using the next 3 parameters shall be applied -/// @param inICAOCode ICAO aircraft type designator, like 'A320', 'B738', 'C172' -/// @param inAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string -/// @param inLivery Special livery designator, can be an empty string -/// @param inDataFunc Callback function called by XPMP2 to fetch updated data -/// @param inRefcon A refcon value passed back to you in all calls to the `inDataFunc` -/// @param inModeS_id (optional) Unique identification of the plane [0x01..0xFFFFFF], e.g. the 24bit mode S transponder code. XPMP2 assigns an arbitrary unique number of not given -[[deprecated("Subclass XPMP2::Aircraft instead")]] -XPMPPlaneID XPMPCreatePlaneWithModelName(const char * inModelName, - const char * inICAOCode, - const char * inAirline, - const char * inLivery, - XPMPPlaneData_f inDataFunc, - void * inRefcon, - XPMPPlaneID inModeS_id = 0); - -/// @brief [Deprecated] Removes a plane previously created with XPMPCreatePlane() -/// @deprecated Delete subclassed XPMP2::Aircraft object instead. -[[deprecated("Delete subclassed XPMP2::Aircraft object instead")]] -void XPMPDestroyPlane(XPMPPlaneID _id); - - -/// @brief Show/Hide the aircraft temporarily without destroying the object -void XPMPSetPlaneVisibility(XPMPPlaneID _id, bool _bVisible); - - -/// @brief Perform model matching again and change the CSL model to the resulting match -/// @note Effectively calls XPMP2::Aircraft::ChangeModel(), -/// so if you have the aircraft object, prefer calling that function directly. -/// @param inPlaneID Which plane to change? -/// @param inICAOCode ICAO aircraft type designator, like 'A320', 'B738', 'C172' -/// @param inAirline ICAO airline code, like 'BAW', 'DLH', can be an empty string -/// @param inLivery Special livery designator, can be an empty string -/// @return Match quality, the lower the better / -1 if `inPlaneID` is invalid -int XPMPChangePlaneModel(XPMPPlaneID inPlaneID, - const char * inICAOCode, - const char * inAirline, - const char * inLivery); - - -/// @brief Return the name of the model, with which the given plane is rendered -/// @note Effectively calls XPMP2::Aircraft::GetModelName(), -/// so if you have the aircraft object, prefer calling that function directly. -/// @param inPlaneID Identifies the plane -/// @param[out] outTxtBuf (optional) Points to a character array to hold the model name. -/// The returned C string is guaranteed to be zero-terminated. -/// Pass in NULL to just receive the string's length -/// @param outTxtBufSize Size of that buffer -/// @return Length of the model name to return -/// (not counting the terminating zero, independend of the passed-in buffer). -/// -1 if `inPlaneID` is invalid -int XPMPGetPlaneModelName(XPMPPlaneID inPlaneID, - char * outTxtBuf, - int outTxtBufSize); - - -/// @brief Returns ICAO aircraft type designator and livery of the given plane -/// @deprecated This legacy function is defined in a rather unsafe way. -/// Instead, use XPMPGetAircraft() and access -/// PMP2::Aircraft::acIcaoType and -/// XPMP2::Aircraft::acLivery directly. -[[deprecated("Unsafe pointer operations")]] -void XPMPGetPlaneICAOAndLivery(XPMPPlaneID inPlane, - char * outICAOCode, // Can be NULL - char * outLivery); // Can be NULL - - -/// @brief Unsupported, don't use. -/// @deprecated Not supported in XPMP2! -/// In the legacy library this is actually more like an internal function, -/// calling all callback functions for querying aircraft data -/// (much like XPCAircraft::UpdatePosition() is now in XPMP2). -/// I doubt that it was intended to be called from the outside in the first place. -/// @return Always `xpmpData_Unavailable` -[[deprecated("Unsupported")]] -XPMPPlaneCallbackResult XPMPGetPlaneData(XPMPPlaneID inPlane, - XPMPPlaneDataType inDataType, - void * outData); - - -/// Returns the match quality of the currently used model, or `-1` if `inPlane` is invalid -int XPMPGetPlaneModelQuality(XPMPPlaneID inPlane); - - -/// Returns the number of planes in existence. -long XPMPCountPlanes(void); - - -/// Returns the plane ID of the Nth plane. -XPMPPlaneID XPMPGetNthPlane(long index); - - -/// Returns the underlying aircraft object, or `nullptr` if `_id` is invalid -XPMP2::Aircraft* XPMPGetAircraft (XPMPPlaneID _id); - - -/// @brief Define default aircraft and ground vehicle ICAO types -/// @param _acIcaoType Default ICAO aircraft type designator, used when matching returns nothing -/// @param _carIcaoType Type used to identify ground vehicels (internally defaults to "ZZZC") -void XPMPSetDefaultPlaneICAO(const char* _acIcaoType, - const char* _carIcaoType = nullptr); - -/************************************************************************************ - * MARK: PLANE OBSERVATION API - ************************************************************************************/ - - -/// Events that trigger a notification callback -enum XPMPPlaneNotification { - xpmp_PlaneNotification_Created = 1, ///< a plane was just created - xpmp_PlaneNotification_ModelChanged = 2, ///< a plane's model changed - xpmp_PlaneNotification_Destroyed = 3, ///< a plane is about to be destroyed -}; - - -/// @brief Type of the callback function you provide, called when one of the -/// events defined in ::XPMPPlaneNotification happens -/// @param inPlaneID Identifies the affected plane -/// @param inNotification The event that took place -/// @param inRefcon A refcon that you provided in XPMPRegisterPlaneNotifierFunc() -typedef void (*XPMPPlaneNotifier_f)(XPMPPlaneID inPlaneID, - XPMPPlaneNotification inNotification, - void * inRefcon); - - -/// @brief Registers a callback, which is called when one of the -/// events defined in ::XPMPPlaneNotification happens -/// @param inFunc Pointer to your callback function -/// @param inRefcon A refcon passed through to your callback -void XPMPRegisterPlaneNotifierFunc(XPMPPlaneNotifier_f inFunc, - void * inRefcon); - - -/// @brief Unregisters a notification callback. Both function pointer and refcon -/// must match what was registered. -/// @param inFunc Pointer to your callback function -/// @param inRefcon A refcon passed through to your callback -void XPMPUnregisterPlaneNotifierFunc(XPMPPlaneNotifier_f inFunc, - void * inRefcon); - -/************************************************************************************ - * MARK: PLANE RENDERING API (unsued in XPMP2) - ************************************************************************************/ - -/// @brief The original libxplanemp allowed to override rendering; no longer supported -/// @deprecated Unsupported in XPMP2. The type definition is available to stay -/// compile-time compatible, but the callback will not be called. -[[deprecated("Unsupported, will not be called")]] -typedef void (* XPMPRenderPlanes_f)( - int inIsBlend, - void * inRef); - - -/// @brief The original libxplanemp allowed to override rendering; no longer supported -/// @deprecated Unsupported in XPMP2. The function is available to stay compile-time compatible, -/// but it does nothing. -[[deprecated("Unsupported, doesn't do anything")]] -void XPMPSetPlaneRenderer(XPMPRenderPlanes_f inRenderer, - void * inRef); - - -/// @brief Legacy debug-support function, no longer supported -/// @deprecated No longer supported as rendering is done by X-Plane's instancing -[[deprecated("Unsupported, doesn't do anything")]] -void XPMPDumpOneCycle(void); - - -/// Enable or disable drawing of labels with the aircraft -void XPMPEnableAircraftLabels (bool _enable = true); - - -/// @brief Disable drawing of labels with the aircraft -/// @details Effectively calls XPMPEnableAircraftLabels() -void XPMPDisableAircraftLabels(); - - -/// Returns if labels are currently configured to be drawn -bool XPMPDrawingAircraftLabels(); - - -/// Configure maximum label distance and if labels shall be cut off at reported visibility -/// @param _dist_nm Maximum label distance in nm, default is 3, minimum is 1 -/// @param _bCutOffAtVisibility Shall labels not be drawn further away than XP's reported visibility? -void XPMPSetAircraftLabelDist (float _dist_nm, bool _bCutOffAtVisibility = true); - -// -// MARK: MAP -// Enable or disable the drawing of icons on maps -// - -/// @brief Enable or disable the drawing of aircraft icons on X-Plane's map -/// @param _bEnable Enable or disable entire map functionality -/// @param _bLabels If map is enabled, shall also labels be drawn? -/// @details XPMP2 creates a separate Map Layer named after the plugin for this purposes. -/// By default, the map functionality is enabled including label writing. -void XPMPEnableMap (bool _bEnable, bool _bLabels = true); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPRemote.h b/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPRemote.h deleted file mode 100644 index 8b49fa0e..00000000 --- a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Headers/XPMPRemote.h +++ /dev/null @@ -1,455 +0,0 @@ -/// @file XPMPRemote.h -/// @brief Semi-public remote network functionality for master/client operations -/// @details Technically, this is public functionality from a library -/// point of view. But it is intended for the "XPMP Remote Client" only, -/// not for a standard plugin.\n -/// Network messages are packed for space efficiency, but also to avoid -/// layout differences between compilers/platforms. -/// However, manual layout tries to do reasonable alignment of numeric values -/// and 8-byte-alignment of each structure, so that arrays of structures -/// also align well. -/// @author Birger Hoppe -/// @copyright (c) 2020 Birger Hoppe -/// @copyright Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions:\n -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software.\n -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/// THE SOFTWARE. - -#ifndef _XPMPRemote_h_ -#define _XPMPRemote_h_ - -#include -#include -#include -#include -#include -#include - -namespace XPMP2 { - -/// The signature of the XPMP2 Remote Client -constexpr const char* REMOTE_SIGNATURE = "TwinFan.plugin.XPMP2.Remote"; - -// -// MARK: Global Helpers -// - -/// @brief Produces a reproducible(!) hash value for strings -/// @details Result is the same if the same string is provided, across platform -/// and across executions, unlike what std::hash requires.\n -/// It is implemented as a 16-bit version of the PJW hash: -/// @see https://en.wikipedia.org/wiki/PJW_hash_function -std::uint16_t PJWHash16 (const char *s); - -/// @brief Find a model by package name hash and short id -/// @details This approach is used by the remote client to safe network bandwith. -/// If an exact match with `pkgHash` _and_ `shortID` is not found, -/// then a model matching the short id alone is returned if available. -CSLModel* CSLModelByPkgShortId (std::uint16_t _pkgHash, - const std::string& _shortId); - -/// @brief Clamps `v` between `lo` and `hi`: `lo` if `v` < `lo`, `hi` if `hi` < `v`, otherwise `v` -/// @see C++17, https://en.cppreference.com/w/cpp/algorithm/clamp -/// @note Reimplemented here because Docker clang environment doesn't include it -template -constexpr const T& clamp( const T& v, const T& lo, const T& hi ) -{ - assert( !(hi < lo) ); - return (v < lo) ? lo : (hi < v) ? hi : v; -} - -// -// MARK: Network Data Definitions -// - -/// Message type -enum RemoteMsgTy : std::uint8_t { - RMT_MSG_INTEREST_BEACON = 0, ///< beacon sent by a remote client to signal interest in data - RMT_MSG_SEND, ///< internal indicator telling to send out all pending messages - RMT_MSG_SETTINGS, ///< a sender's id and its settings - RMT_MSG_AC_DETAILED, ///< aircraft full details, needed to create new a/c objects and to re-synch all remote data - RMT_MSG_AC_POS_UPDATE, ///< aircraft differences only - RMT_MSG_AC_ANIM, ///< aircraft animation values (dataRef values) only - RMT_MSG_AC_REMOVE, ///< aircraft is removed -}; - -/// Definition for how to map dataRef values to (u)int8, ie. to an integer range of 8 bits -struct RemoteDataRefPackTy { - float minV = 0.0f; ///< minimum transferred value - float range = 0.0f; ///< range of transferred value = maxV - minV - - /// Constructor sets minimum value and range - RemoteDataRefPackTy (float _min, float _max) : minV(_min), range(_max - _min) { assert(range != 0.0f); } - - /// pack afloat value to integer - std::uint8_t pack (float f) const { return std::uint8_t(clamp(f-minV,0.0f,range) * UINT8_MAX / range); } - /// unpack an integer value to float - float unpack (std::uint8_t i) const { return minV + range*float(i)/255.0f; } -}; - -/// An array holding all dataRef packing definitions -extern const std::array REMOTE_DR_DEF; - -// -// MARK: Message Header (Base) -// - -// To ensure best network capacity usage as well as identical alignment across platform we enforce tightly packed structures. -// The approach is very different between Visual C++ and clang / gcc, though: -#ifdef _MSC_VER // Visual C++ -#pragma pack(push,1) // set packing once (ie. not per struct) -#define PACKED -#elif defined(__clang__) || defined(__GNUC__) // Clang (Mac XCode etc) or GNU (Linux) -#define PACKED __attribute__ ((__packed__)) -#else -#error Unhandled Compiler! -#endif - -/// Message header, identical for all message types -struct RemoteMsgBaseTy { - RemoteMsgTy msgTy : 4; ///< message type - std::uint8_t msgVer : 4; ///< message version - bool bLocalSender : 1; ///< is the sender "local", ie. on same machine? - std::uint8_t filler1 : 7; ///< yet unsed - std::uint16_t pluginId = 0; ///< lower 16 bit of the sending plugin's id - std::uint32_t filler2 = 0; ///< yet unused, fills up to size 8 - /// Constructor just sets the values - RemoteMsgBaseTy (RemoteMsgTy _ty, std::uint8_t _ver); -} PACKED; - -// -// MARK: Beacon of Interest -// - -/// Interest Beacon message version number -constexpr std::uint8_t RMT_VER_BEACON = 0; -/// "Beacon of Interest", ie. some message on the multicast just to wake up sender -struct RemoteMsgBeaconTy : public RemoteMsgBaseTy { - // don't need additional data fields - /// Constructor sets appropriate message type - RemoteMsgBeaconTy(); -} PACKED; - -// -// MARK: Settings -// - -/// How often to send settings? [s] -constexpr int REMOTE_SEND_SETTINGS_INTVL = 20; - -/// Setttings message version number -constexpr std::uint8_t RMT_VER_SETTINGS = 0; -/// Settings message, identifying a sending plugin, regularly providing its settings -struct RemoteMsgSettingsTy : public RemoteMsgBaseTy { - char name[16]; ///< plugin's name, not necessarily zero-terminated if using full 12 chars - float maxLabelDist; ///< Maximum distance for drawing labels? [m] - char defaultIcao[4]; ///< Default ICAO aircraft type designator if no match can be found - char carIcaoType[4]; ///< Ground vehicle type identifier - std::uint8_t logLvl :3; ///< logging level - bool bLogMdlMatch :1; ///< Debug model matching? - bool bObjReplDataRefs :1; ///< Replace dataRefs in `.obj` files on load? - bool bObjReplTextures :1; ///< Replace textures in `.obj` files on load if needed? - bool bLabelCutOffAtVisibility :1; ///< Cut off labels at XP's reported visibility mit? - bool bMapEnabled :1; ///< Do we feed X-Plane's maps with our aircraft positions? - bool bMapLabels :1; ///< Do we show labels with the aircraft icons? - bool bHaveTCASControl :1; ///< Do we have AI/TCAS control? - std::uint16_t filler; ///< yet unused, fills size up for a multiple of 8 - - /// Constructor sets most values to zero - RemoteMsgSettingsTy (); - -} PACKED; - -// -// MARK: A/C Details -// - -/// A/C detail message version number -constexpr std::uint8_t RMT_VER_AC_DETAIL = 2; -constexpr std::uint8_t RMT_VER_AC_DETAIL_1 = 1; -constexpr std::uint8_t RMT_VER_AC_DETAIL_0 = 0; -/// A/C details, packed into an array message -struct RemoteAcDetailTy { - std::uint32_t modeS_id; ///< plane's unique id at the sender side (might differ remotely in case of duplicates) - char icaoType[4]; ///< icao a/c type - char icaoOp[4]; ///< icao airline code - char sShortId[20]; ///< CSL model's short id - std::uint16_t pkgHash; ///< hash value of package name - char label[23]; ///< label - std::uint8_t labelCol[3]; ///< label color (RGB) - float alt_ft; ///< [ft] current altitude - // ^ the above has 64 bytes, so that these doubles start on an 8-byte bounday: - double lat; ///< latitude - double lon; ///< longitude - std::int16_t pitch; ///< [0.01°] pitch/100 - std::uint16_t heading; ///< [0.01°] heading/100 - std::int16_t roll; ///< [0.01°] roll/100 - - std::int16_t aiPrio; ///< priority for display in limited TCAS target slots, `-1` indicates "no TCAS display" - std::uint16_t dTime; ///< [0.0001s] time difference to previous position in 1/10000s - bool bValid : 1; ///< is this object valid? (Will be reset in case of exceptions) - bool bVisible : 1; ///< Shall this plane be drawn at the moment? - bool bRender : 1; ///< Shall the CSL model be drawn in 3D world? - bool bDrawLabel : 1; ///< Draw the label of the aircraft? (new with v2) - bool bOnGrnd : 1; ///< Is the aircraft on the ground? - - // selectively taken from XPMPInfoTexts_t and packed: - char tailNum[10]; ///< registration, tail number - char manufacturer[40]; ///< a/c manufacturer, human readable - char model[40]; ///< a/c model, human readable - char airline[40]; ///< airline, human readable - char flightNum [10]; ///< flight number - char aptFrom [5]; ///< Origin airport (ICAO) - char aptTo [5]; ///< Destination airport (ICAO) - - std::uint8_t filler[5]; ///< yet unused - - ///< Array of _packed_ dataRef values for CSL model animation - std::uint8_t v[XPMP2::V_COUNT]; // 42 - - /// Default Constructor sets all to zero - RemoteAcDetailTy (); - /// A/c copy constructor fills from passed-in XPMP2::Aircraft object - RemoteAcDetailTy (const Aircraft& _ac, double _lat, double _lon, float _alt_ft, std::uint16_t _dTime); - /// Copies values from passed-in XPMP2::Aircraft object - void CopyFrom (const Aircraft& _ac, double _lat, double _lon, float _alt_ft, std::uint16_t _dTime); - - void SetLabelCol (const float _col[4]); ///< set the label color from a float array (4th number, alpha, is always considered 1.0) - void GetLabelCol (float _col[4]) const; ///< writes color out into a float array - - void SetPitch (float _p) { pitch = std::int16_t(_p*100.0f); } ///< sets pitch from float - float GetPitch () const { return float(pitch) / 100.0f; } ///< returns float pitch - - /// @brief Sets heading from float - /// @note Only works well for `0 <= _h < 360` - void SetHeading (float _h); - float GetHeading () const { return float(heading) / 100.0f; } ///< returns float heading - - void SetRoll (float _r) { roll = std::int16_t(std::lround(_r*100.0f)); } ///< sets pitch from float - float GetRoll () const { return float(roll) / 100.0f; } ///< returns float pitch - - static constexpr size_t msgSize () { return sizeof(RemoteAcDetailTy); } ///< message size -} PACKED; - -/// A/C detail message, has an inherited header plus an array of XPMP2::RemoteAcDetailTy elements -struct RemoteMsgAcDetailTy : public RemoteMsgBaseTy { - RemoteAcDetailTy arr[1]; ///< basis for the array of actual details - - /// Constructor sets expected message type and version - RemoteMsgAcDetailTy () : RemoteMsgBaseTy(RMT_MSG_AC_DETAILED, RMT_VER_AC_DETAIL) {} - /// Convert msg len to number of arr elements - static constexpr size_t NumElem (size_t _msgLen) { return (_msgLen - sizeof(RemoteMsgBaseTy)) / sizeof(RemoteAcDetailTy); } -} PACKED; - -// -// MARK: A/C Position Update -// - -/// A/C Position update message version number -constexpr std::uint8_t RMT_VER_AC_POS_UPDATE = 0; - -/// What is the maximum difference a RemoteAcPosUpdateTy can hold? -constexpr double REMOTE_DEGREE_RES = 0.00000001; ///< resolution of degree updates -constexpr double REMOTE_MAX_DIFF_DEGREE = REMOTE_DEGREE_RES * INT16_MAX;///< maximum degree difference that can be represented in a pos update msg -constexpr double REMOTE_ALT_FT_RES = 0.01; ///< resolution of altitude[ft] updates -constexpr double REMOTE_MAX_DIFF_ALT_FT = REMOTE_ALT_FT_RES * INT16_MAX;///< maximum altitude[ft] difference that can be represented in a pos update msg -constexpr float REMOTE_TIME_RES = 0.0001f; ///< resolution of time difference -constexpr float REMOTE_MAX_DIFF_TIME = REMOTE_TIME_RES * UINT16_MAX; ///< maximum time difference thatn can be represented in a pos update msg - -/// @brief A/C Position updates based on global coordinates -/// @details for space efficiency only deltas to last msg are given in -/// 0.0000001 degree lat/lon (roughly 1 centimeter resolution) and -/// 0.01 ft altitude -struct RemoteAcPosUpdateTy { - std::uint32_t modeS_id; ///< plane's unique id at the sender side (might differ remotely in case of duplicates) - std::int16_t dLat; ///< [0.0000001 degrees] latitude position difference - std::int16_t dLon; ///< [0.0000001 degrees] longitude position difference - std::int16_t dAlt_ft; ///< [0.01 ft] altitude difference - std::uint16_t dTime; ///< [0.0001s] time difference to previous position in 1/10000s - std::int16_t pitch; ///< [0.01 degree] pitch/100 - std::uint16_t heading; ///< [0.01 degree] heading/100 - std::int16_t roll; ///< [0.01 degree] roll/100 - std::uint16_t filler1; ///< not yet used (for 4-byte alignment) - - /// Default Constructor sets all 0 - RemoteAcPosUpdateTy () { std::memset(this,0,sizeof(*this)); } - /// Constructor sets all values - RemoteAcPosUpdateTy (XPMPPlaneID _modeS_id, - std::int16_t _dLat, std::int16_t _dLon, - std::int16_t _dAlt_ft, std::uint16_t _dTime, - float _pitch, float _heading, float _roll); - - void SetPitch (float _p) { pitch = std::int16_t(_p*100.0f); } ///< sets pitch from float - float GetPitch () const { return float(pitch) / 100.0f; } ///< returns float pitch - - /// @brief Sets heading from float - /// @note Only works well for `0 <= _h < 360` - void SetHeading (float _h); - float GetHeading () const { return float(heading) / 100.0f; } ///< returns float heading - - void SetRoll (float _r) { roll = std::int16_t(std::lround(_r*100.0f)); }///< sets pitch from float - float GetRoll () const { return float(roll) / 100.0f; } ///< returns float pitch - - static constexpr size_t msgSize () { return sizeof(RemoteAcPosUpdateTy); } ///< message size -} PACKED; - -/// A/C detail message, has an inherited header plus an array of XPMP2::RemoteAcDetailTy elements -struct RemoteMsgAcPosUpdateTy : public RemoteMsgBaseTy { - RemoteAcPosUpdateTy arr[1]; ///< basis for the array of actual position updates - - /// Constructor sets expected message type and version - RemoteMsgAcPosUpdateTy () : RemoteMsgBaseTy(RMT_MSG_AC_POS_UPDATE, RMT_VER_AC_POS_UPDATE) {} - /// Convert msg len to number of arr elements - static constexpr size_t NumElem (size_t _msgLen) { return (_msgLen - sizeof(RemoteMsgBaseTy)) / sizeof(RemoteAcPosUpdateTy); } -} PACKED; - -// -// MARK: A/C animation dataRefs -// - -/// A/C Position update message version number -constexpr std::uint8_t RMT_VER_AC_ANIM = 0; - -/// @brief A/C animation dataRef changes -/// @details This structure has variable length depending on the number of -/// actual dataRef values to carry. And several of these variable -/// length structures are added into one variable length network message. -/// @note Structure must stay aligned with XPMP2::RmtDataAcAnimTy -struct RemoteAcAnimTy { - std::uint32_t modeS_id = 0; ///< plane's unique id at the sender side (might differ remotely in case of duplicates) - std::uint8_t numVals = 0; ///< number of dataRef values in the following array - std::uint8_t filler = 0; ///< not yet used - - /// dataRef animation types and value - struct DataRefValTy { - DR_VALS idx; ///< index into XPMP2::Aircraft::v - std::uint8_t v; ///< dataRef animation value - } v[1]; ///< array of dataRef animation types and value - - /// Constructor - RemoteAcAnimTy (XPMPPlaneID _id) : modeS_id(_id) { v[0].idx = DR_VALS(0); v[0].v = 0; } - - /// message size assuming `num` array elements - static constexpr size_t msgSize (std::uint8_t num) - { return sizeof(RemoteAcAnimTy) + (num-1) * sizeof(DataRefValTy); } - /// current message size - size_t msgSize() const { return msgSize(numVals); } -} PACKED; - -/// A/C animation dataRef message, has an inherited header plus an array of _variable sized_ XPMP2::RemoteAcAnimTy elements -struct RemoteMsgAcAnimTy : public RemoteMsgBaseTy { - RemoteAcAnimTy animData; ///< message data starts here but extend beyond this point! - - /// Constructor sets expected message type and version - RemoteMsgAcAnimTy () : RemoteMsgBaseTy(RMT_MSG_AC_ANIM, RMT_VER_AC_ANIM), animData(0) {} - - /// Returns a pointer to the first/next animation data element in the message - const RemoteAcAnimTy* next (size_t _msgLen, const RemoteAcAnimTy* pCurr = nullptr) const; -} PACKED; - - -// -// MARK: A/C Removal -// - - -/// A/C removal message version number -constexpr std::uint8_t RMT_VER_AC_REMOVE = 0; - -/// A/C Removal only includes the plane id, structure required for msgSize() function -struct RemoteAcRemoveTy { - std::uint32_t modeS_id; ///< plane's unique id at the sender side (might differ remotely in case of duplicates) - - /// Constructor sets plane id - RemoteAcRemoveTy (XPMPPlaneID _id = 0) : modeS_id(_id) {} - - static constexpr size_t msgSize () { return sizeof(RemoteAcRemoveTy); } ///< message size -} PACKED; - -/// A/C removal message, an array of plane ids -struct RemoteMsgAcRemoveTy : public RemoteMsgBaseTy { - RemoteAcRemoveTy arr[1]; ///< plane's unique id at the sender side (might differ remotely in case of duplicates) - - /// Constructor sets expected message type and version - RemoteMsgAcRemoveTy () : RemoteMsgBaseTy(RMT_MSG_AC_REMOVE, RMT_VER_AC_REMOVE) {} - /// Convert msg len to number of arr elements - static constexpr size_t NumElem (size_t _msgLen) { return (_msgLen - sizeof(RemoteMsgBaseTy)) / sizeof(arr[0]); } -} PACKED; - -#ifdef _MSC_VER // Visual C++ -#pragma pack(pop) // reseting packing -#endif - -// A few static validations just to make sure that no compiler fiddles with my network message layout. -static_assert(sizeof(RemoteMsgBaseTy) == 8, "RemoteMsgBaseTy doesn't have expected size"); -static_assert(sizeof(RemoteMsgSettingsTy) == 40, "RemoteMsgSettingsTy doesn't have expected size"); -static_assert(sizeof(RemoteAcDetailTy) == 246+42, "RemoteAcDetailTy doesn't have expected size"); -static_assert(sizeof(RemoteMsgAcDetailTy) == 254+42, "RemoteMsgAcDetailTy doesn't have expected size"); -static_assert(sizeof(RemoteAcPosUpdateTy) == 20, "RemoteAcPosUpdateTy doesn't have expected size"); -static_assert(sizeof(RemoteMsgAcPosUpdateTy)== 28, "RemoteMsgAcPosUpdateTy doesn't have expected size"); -static_assert(sizeof(RemoteAcAnimTy) == 8, "RemoteAcAnimTy doesn't have expected size"); -static_assert(RemoteAcAnimTy::msgSize(V_COUNT) == 90, "RemoteAcAnimTy for V_COUNT dataRefs doesn't have expected size"); -static_assert(sizeof(RemoteMsgAcAnimTy) == 16, "RemoteMsgAcAnimTy doesn't have expected size"); -static_assert(sizeof(RemoteMsgAcRemoveTy) == 12, "RemoteMsgAcRemoveTy doesn't have expected size"); - -// -// MARK: Miscellaneous -// - -/// Function prototypes for callback functions to handle the received messages -struct RemoteCBFctTy { - /// Called in flight loop before processing first aircraft - void (*pfBeforeFirstAc)() = nullptr; - /// Called in flight loop after processing last aircraft - void (*pfAfterLastAc)() = nullptr; - /// Callback for processing Settings messages - void (*pfMsgSettings) (const std::uint32_t from[4], - const std::string& sFrom, - const RemoteMsgSettingsTy&) = nullptr; - /// Callback for processing A/C Details messages - void (*pfMsgACDetails) (const std::uint32_t from[4], size_t msgLen, - const RemoteMsgAcDetailTy&) = nullptr; - /// Callback for processing A/C Details messages - void (*pfMsgACPosUpdate) (const std::uint32_t from[4], size_t msgLen, - const RemoteMsgAcPosUpdateTy&) = nullptr; - /// Callback for processing A/C Animation dataRef messages - void (*pfMsgACAnim) (const std::uint32_t from[4], size_t msgLen, - const RemoteMsgAcAnimTy&) = nullptr; - /// Callback for processing A/C Removal messages - void (*pfMsgACRemove) (const std::uint32_t from[4], size_t msgLen, - const RemoteMsgAcRemoveTy&) = nullptr; -}; - -/// State of remote communcations -enum RemoteStatusTy : unsigned { - REMOTE_OFF = 0, ///< no remote connectivtiy, not listening, not sending - REMOTE_SEND_WAITING, ///< listening for a request to send data, but not actively sending data - REMOTE_SENDING, ///< actively sending aircraft data out to the network - REMOTE_RECV_WAITING, ///< waiting to receive data, periodically sending a token of interest - REMOTE_RECEIVING, ///< actively receiving data -}; - -/// Returns the current Remote status -RemoteStatusTy RemoteGetStatus(); - -/// Starts the listener, will call provided callback functions with received messages -void RemoteRecvStart (const RemoteCBFctTy& _rmtCBFcts); - -/// Stops the receiver -void RemoteRecvStop (); - -} - - -#endif diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Resources/Info.plist b/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Resources/Info.plist deleted file mode 100644 index 4ac0f5c7..00000000 --- a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/Resources/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2020 B. Hoppe. All rights reserved. - - diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/XPMP2 b/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/XPMP2 deleted file mode 100644 index 703f6fdc..00000000 Binary files a/XPMP2-Sample/lib/XPMP2.framework/Versions/2.50/XPMP2 and /dev/null differ diff --git a/XPMP2-Sample/lib/XPMP2.framework/Versions/Current b/XPMP2-Sample/lib/XPMP2.framework/Versions/Current deleted file mode 120000 index 348c6a7e..00000000 --- a/XPMP2-Sample/lib/XPMP2.framework/Versions/Current +++ /dev/null @@ -1 +0,0 @@ -2.50 \ No newline at end of file diff --git a/XPMP2-Sample/lib/lin-bionic/libXPMP2.a b/XPMP2-Sample/lib/lin-bionic/libXPMP2.a deleted file mode 100644 index f3dab2d9..00000000 Binary files a/XPMP2-Sample/lib/lin-bionic/libXPMP2.a and /dev/null differ diff --git a/XPMP2-Sample/lib/lin/libXPMP2.a b/XPMP2-Sample/lib/lin/libXPMP2.a deleted file mode 100644 index 59e615a7..00000000 Binary files a/XPMP2-Sample/lib/lin/libXPMP2.a and /dev/null differ diff --git a/XPMP2-Sample/lib/win/XPMP2.lib b/XPMP2-Sample/lib/win/XPMP2.lib deleted file mode 100644 index b431585a..00000000 Binary files a/XPMP2-Sample/lib/win/XPMP2.lib and /dev/null differ diff --git a/XPMP2-Sample/lib/win/libXPMP2.a b/XPMP2-Sample/lib/win/libXPMP2.a deleted file mode 100644 index 01d97d9e..00000000 Binary files a/XPMP2-Sample/lib/win/libXPMP2.a and /dev/null differ diff --git a/XPMP2.xcodeproj/project.pbxproj b/XPMP2.xcodeproj/project.pbxproj index 7b7fb67e..1fd46198 100644 --- a/XPMP2.xcodeproj/project.pbxproj +++ b/XPMP2.xcodeproj/project.pbxproj @@ -9,36 +9,27 @@ /* Begin PBXBuildFile section */ 252C01F423E62040007C231F /* AIMultiplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 252C01F223E62040007C231F /* AIMultiplayer.cpp */; }; 252C01F523E62040007C231F /* AIMultiplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 252C01F323E62040007C231F /* AIMultiplayer.h */; }; - 252FD04E25421C2B00286AE6 /* Client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 252FD04C25421C2A00286AE6 /* Client.cpp */; }; 25338211253A39060090E0B3 /* Network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2533820F253A39060090E0B3 /* Network.cpp */; }; 25338212253A39060090E0B3 /* Network.h in Headers */ = {isa = PBXBuildFile; fileRef = 25338210253A39060090E0B3 /* Network.h */; }; 253485AA23C289E5002BA65A /* XPMPAircraft.h in Headers */ = {isa = PBXBuildFile; fileRef = 253485A923C289E4002BA65A /* XPMPAircraft.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2541FA46253C902200AEA532 /* XPMPRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = 2541FA45253C902200AEA532 /* XPMPRemote.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2541FA4D253CDD6700AEA532 /* Remote.h in Headers */ = {isa = PBXBuildFile; fileRef = 2541FA4B253CDD6700AEA532 /* Remote.h */; }; 2541FA4E253CDD6700AEA532 /* Remote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2541FA4C253CDD6700AEA532 /* Remote.cpp */; }; + 255EC99228E3871100F99F93 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 255EC99028E3871100F99F93 /* Sound.cpp */; }; + 255EC99328E3871100F99F93 /* Sound.h in Headers */ = {isa = PBXBuildFile; fileRef = 255EC99128E3871100F99F93 /* Sound.h */; }; 256DC2F724F3141500C1595C /* CSLCopy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256DC2F624F3141500C1595C /* CSLCopy.cpp */; }; - 256EE0002540D7EF0007D517 /* XPMP2-Remote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256EDFFF2540D7EF0007D517 /* XPMP2-Remote.cpp */; }; - 256EE0102540E39D0007D517 /* Utilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256EE00F2540E39D0007D517 /* Utilities.cpp */; }; 2575F45423EDFC5E00747524 /* Map.h in Headers */ = {isa = PBXBuildFile; fileRef = 2575F45223EDFC5E00747524 /* Map.h */; }; 2575F45523EDFC5E00747524 /* Map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2575F45323EDFC5E00747524 /* Map.cpp */; }; 2589B84A23CB4D6F005B76B8 /* RelatedDoc8643.h in Headers */ = {isa = PBXBuildFile; fileRef = 2589B84823CB4D6F005B76B8 /* RelatedDoc8643.h */; }; 2589B84B23CB4D6F005B76B8 /* RelatedDoc8643.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2589B84923CB4D6F005B76B8 /* RelatedDoc8643.cpp */; }; 2599B91923BF636E00F92BB5 /* Aircraft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2599B91823BF636E00F92BB5 /* Aircraft.cpp */; }; 2599B92223BF63F600F92BB5 /* XPMP2.h in Headers */ = {isa = PBXBuildFile; fileRef = 2599B92123BF63F600F92BB5 /* XPMP2.h */; }; - 259FFDFB25A132D400B6D553 /* XPMP2.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2502C17A23BE8A1600578919 /* XPMP2.framework */; }; 25AE8CB523E376E2000BE21E /* 2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25AE8CB323E376E1000BE21E /* 2D.cpp */; }; 25AE8CB623E376E2000BE21E /* 2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 25AE8CB423E376E2000BE21E /* 2D.h */; }; - 25B071F12540D6C400CCDA1D /* XPMP2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2502C17A23BE8A1600578919 /* XPMP2.framework */; }; - 25B071F22540D6C400CCDA1D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D86CC7253E285E00424494 /* CoreFoundation.framework */; }; - 25B071F32540D6C400CCDA1D /* XPLM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D86CC9253E288900424494 /* XPLM.framework */; }; 25D680B923BE95FB00C83CC5 /* XPCAircraft.h in Headers */ = {isa = PBXBuildFile; fileRef = 25D680B623BE95FB00C83CC5 /* XPCAircraft.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25D680BA23BE95FB00C83CC5 /* XPMPMultiplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25D680B723BE95FB00C83CC5 /* XPMPMultiplayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25D680BB23BE95FB00C83CC5 /* XPMPPlaneRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25D680B823BE95FB00C83CC5 /* XPMPPlaneRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25D680C523BE9DBD00C83CC5 /* XPMPMultiplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25D680C423BE9DBD00C83CC5 /* XPMPMultiplayer.cpp */; }; - 25D86CC8253E285F00424494 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D86CC7253E285E00424494 /* CoreFoundation.framework */; }; - 25D86CCA253E288900424494 /* XPLM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D86CC9253E288900424494 /* XPLM.framework */; }; - 25D86CCD253E289100424494 /* XPMP2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2502C17A23BE8A1600578919 /* XPMP2.framework */; }; - 25D86D7A253E2F3E00424494 /* XPMP2-Sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25D86D06253E2E5900424494 /* XPMP2-Sample.cpp */; }; 25EC1C4023BF6DF1000940BB /* CSLModels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1C3F23BF6DF1000940BB /* CSLModels.cpp */; }; 25EC1C4223BF6DFA000940BB /* CSLModels.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1C4123BF6DFA000940BB /* CSLModels.h */; }; 25EC1C4723BF7569000940BB /* Utilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1C4523BF7569000940BB /* Utilities.cpp */; }; @@ -46,36 +37,6 @@ 25FF33FE23BFF250001B0AB4 /* Aircraft.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FF33FD23BFF250001B0AB4 /* Aircraft.h */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 25B071ED2540D6C400CCDA1D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 2502C16023BE3CFC00578919 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2502C17923BE8A1600578919; - remoteInfo = XPMP2; - }; - 25D86CCF253E289100424494 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 2502C16023BE3CFC00578919 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2502C17923BE8A1600578919; - remoteInfo = XPMP2; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 259FFDFA25A1327F00B6D553 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "${PROJECT_DIR}/XPMP2-Sample/lib"; - dstSubfolderSpec = 0; - files = ( - 259FFDFB25A132D400B6D553 /* XPMP2.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 25019BC624919A1500355472 /* HowTo.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = HowTo.md; sourceTree = ""; }; 25019BC724919A1500355472 /* CSLdataRefs.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CSLdataRefs.md; sourceTree = ""; }; @@ -91,22 +52,17 @@ 252C01F923E6D64F007C231F /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 252C01FA23E6D64F007C231F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 252C01FB23E6D64F007C231F /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = ""; }; - 252FD04C25421C2A00286AE6 /* Client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Client.cpp; sourceTree = ""; }; - 252FD04D25421C2B00286AE6 /* Client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Client.h; sourceTree = ""; }; 2533820F253A39060090E0B3 /* Network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Network.cpp; sourceTree = ""; }; 25338210253A39060090E0B3 /* Network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Network.h; sourceTree = ""; }; 253485A923C289E4002BA65A /* XPMPAircraft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPMPAircraft.h; sourceTree = ""; }; 2541FA45253C902200AEA532 /* XPMPRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPMPRemote.h; sourceTree = ""; }; 2541FA4B253CDD6700AEA532 /* Remote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Remote.h; sourceTree = ""; }; 2541FA4C253CDD6700AEA532 /* Remote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Remote.cpp; sourceTree = ""; }; - 2561DA2D2571AE4800E3DE3D /* readme.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = readme.html; sourceTree = ""; }; + 255EC99028E3871100F99F93 /* Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sound.cpp; sourceTree = ""; }; + 255EC99128E3871100F99F93 /* Sound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sound.h; sourceTree = ""; }; 256C287925B4E6270033007D /* Toolchain-ubuntu-osxcross.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Toolchain-ubuntu-osxcross.cmake"; sourceTree = ""; }; 256DC2F524F3090B00C1595C /* Obj8DataRefs.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Obj8DataRefs.txt; sourceTree = ""; }; 256DC2F624F3141500C1595C /* CSLCopy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSLCopy.cpp; sourceTree = ""; }; - 256EDFFF2540D7EF0007D517 /* XPMP2-Remote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "XPMP2-Remote.cpp"; sourceTree = ""; }; - 256EE0042540DDE10007D517 /* XPMP2-Remote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XPMP2-Remote.h"; sourceTree = ""; }; - 256EE00E2540E39D0007D517 /* Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utilities.h; sourceTree = ""; }; - 256EE00F2540E39D0007D517 /* Utilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utilities.cpp; sourceTree = ""; }; 256F4687255C9A6A00FBE18A /* XPMP2.example.prf */ = {isa = PBXFileReference; lastKnownFileType = text; path = XPMP2.example.prf; sourceTree = ""; }; 2571D63525B2591B0055AA1E /* Toolchain-mingw-w64-x86-64.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Toolchain-mingw-w64-x86-64.cmake"; sourceTree = ""; }; 2571D63825B3196D0055AA1E /* Dockerfile_Bionic */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dockerfile_Bionic; sourceTree = ""; }; @@ -125,7 +81,6 @@ 2599B92123BF63F600F92BB5 /* XPMP2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPMP2.h; sourceTree = ""; }; 25AE8CB323E376E1000BE21E /* 2D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 2D.cpp; sourceTree = ""; }; 25AE8CB423E376E2000BE21E /* 2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 2D.h; sourceTree = ""; }; - 25B071F72540D6C400CCDA1D /* XPMP2-Remote.xpl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "XPMP2-Remote.xpl"; sourceTree = BUILT_PRODUCTS_DIR; }; 25D1D25523C9285300D20D58 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 25D680B123BE936B00C83CC5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25D680B623BE95FB00C83CC5 /* XPCAircraft.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = XPCAircraft.h; sourceTree = ""; }; @@ -135,11 +90,7 @@ 25D680BF23BE9BB900C83CC5 /* MainPage.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = MainPage.md; sourceTree = ""; }; 25D680C023BE9D3200C83CC5 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 25D680C423BE9DBD00C83CC5 /* XPMPMultiplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XPMPMultiplayer.cpp; sourceTree = ""; }; - 25D86CC0253E281800424494 /* XPMP2-Sample.xpl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "XPMP2-Sample.xpl"; sourceTree = BUILT_PRODUCTS_DIR; }; 25D86CC7253E285E00424494 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 25D86CC9253E288900424494 /* XPLM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XPLM.framework; path = "XPMP2-Sample/SDK/Libraries/Mac/XPLM.framework"; sourceTree = ""; }; - 25D86D06253E2E5900424494 /* XPMP2-Sample.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "XPMP2-Sample.cpp"; sourceTree = ""; }; - 25D86D98253F94F200424494 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; 25EC1C3F23BF6DF1000940BB /* CSLModels.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSLModels.cpp; sourceTree = ""; }; 25EC1C4123BF6DFA000940BB /* CSLModels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSLModels.h; sourceTree = ""; }; 25EC1C4523BF7569000940BB /* Utilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utilities.cpp; sourceTree = ""; }; @@ -148,23 +99,10 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 25B071F02540D6C400CCDA1D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 25B071F12540D6C400CCDA1D /* XPMP2.framework in Frameworks */, - 25B071F22540D6C400CCDA1D /* CoreFoundation.framework in Frameworks */, - 25B071F32540D6C400CCDA1D /* XPLM.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 25D86CBE253E281800424494 /* Frameworks */ = { + 255EC98D28E381EF00F99F93 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 25D86CCD253E289100424494 /* XPMP2.framework in Frameworks */, - 25D86CC8253E285F00424494 /* CoreFoundation.framework in Frameworks */, - 25D86CCA253E288900424494 /* XPLM.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -183,8 +121,6 @@ 25D680B523BE95FB00C83CC5 /* inc */, 2596FD462447226700C6A41E /* Resources */, 25D680BC23BE9B5700C83CC5 /* src */, - 25D86CD7253E2E5900424494 /* XPMP2-Sample */, - 256EDFF32540D7730007D517 /* XPMP2-Remote */, 25D86CC6253E285E00424494 /* Frameworks */, 2502C16923BE3CFC00578919 /* Products */, ); @@ -194,8 +130,6 @@ isa = PBXGroup; children = ( 2502C17A23BE8A1600578919 /* XPMP2.framework */, - 25D86CC0253E281800424494 /* XPMP2-Sample.xpl */, - 25B071F72540D6C400CCDA1D /* XPMP2-Remote.xpl */, ); name = Products; sourceTree = ""; @@ -214,20 +148,6 @@ path = docker; sourceTree = ""; }; - 256EDFF32540D7730007D517 /* XPMP2-Remote */ = { - isa = PBXGroup; - children = ( - 2561DA2D2571AE4800E3DE3D /* readme.html */, - 252FD04C25421C2A00286AE6 /* Client.cpp */, - 252FD04D25421C2B00286AE6 /* Client.h */, - 256EE00F2540E39D0007D517 /* Utilities.cpp */, - 256EE00E2540E39D0007D517 /* Utilities.h */, - 256EE0042540DDE10007D517 /* XPMP2-Remote.h */, - 256EDFFF2540D7EF0007D517 /* XPMP2-Remote.cpp */, - ); - path = "XPMP2-Remote"; - sourceTree = ""; - }; 2596FD462447226700C6A41E /* Resources */ = { isa = PBXGroup; children = ( @@ -272,9 +192,11 @@ 2589B84823CB4D6F005B76B8 /* RelatedDoc8643.h */, 2541FA4C253CDD6700AEA532 /* Remote.cpp */, 2541FA4B253CDD6700AEA532 /* Remote.h */, + 255EC99028E3871100F99F93 /* Sound.cpp */, + 255EC99128E3871100F99F93 /* Sound.h */, 25EC1C4523BF7569000940BB /* Utilities.cpp */, - 2599B92123BF63F600F92BB5 /* XPMP2.h */, 25EC1C4623BF7569000940BB /* Utilities.h */, + 2599B92123BF63F600F92BB5 /* XPMP2.h */, 25D680C423BE9DBD00C83CC5 /* XPMPMultiplayer.cpp */, ); path = src; @@ -302,21 +224,11 @@ 25D86CC6253E285E00424494 /* Frameworks */ = { isa = PBXGroup; children = ( - 25D86CC9253E288900424494 /* XPLM.framework */, 25D86CC7253E285E00424494 /* CoreFoundation.framework */, ); name = Frameworks; sourceTree = ""; }; - 25D86CD7253E2E5900424494 /* XPMP2-Sample */ = { - isa = PBXGroup; - children = ( - 25D86D98253F94F200424494 /* CMakeLists.txt */, - 25D86D06253E2E5900424494 /* XPMP2-Sample.cpp */, - ); - path = "XPMP2-Sample"; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -332,6 +244,7 @@ 253485AA23C289E5002BA65A /* XPMPAircraft.h in Headers */, 25D680BA23BE95FB00C83CC5 /* XPMPMultiplayer.h in Headers */, 25D680B923BE95FB00C83CC5 /* XPCAircraft.h in Headers */, + 255EC99328E3871100F99F93 /* Sound.h in Headers */, 252C01F523E62040007C231F /* AIMultiplayer.h in Headers */, 25338212253A39060090E0B3 /* Network.h in Headers */, 2541FA4D253CDD6700AEA532 /* Remote.h in Headers */, @@ -350,10 +263,9 @@ buildConfigurationList = 2502C17F23BE8A1700578919 /* Build configuration list for PBXNativeTarget "XPMP2" */; buildPhases = ( 2502C17623BE8A1600578919 /* Sources */, + 255EC98D28E381EF00F99F93 /* Frameworks */, 2502C17523BE8A1600578919 /* Headers */, - 259FFDFA25A1327F00B6D553 /* CopyFiles */, 255C338A2544E1FF002C166F /* ShellScript */, - 259FFDFC25A132EC00B6D553 /* ShellScript */, ); buildRules = ( ); @@ -364,56 +276,18 @@ productReference = 2502C17A23BE8A1600578919 /* XPMP2.framework */; productType = "com.apple.product-type.framework"; }; - 25B071EB2540D6C400CCDA1D /* XPMP2-Remote */ = { - isa = PBXNativeTarget; - buildConfigurationList = 25B071F42540D6C400CCDA1D /* Build configuration list for PBXNativeTarget "XPMP2-Remote" */; - buildPhases = ( - 25B071EE2540D6C400CCDA1D /* Sources */, - 25B071F02540D6C400CCDA1D /* Frameworks */, - 255C33772544C9D9002C166F /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - 25B071EC2540D6C400CCDA1D /* PBXTargetDependency */, - ); - name = "XPMP2-Remote"; - productName = "XPMP2-Sample"; - productReference = 25B071F72540D6C400CCDA1D /* XPMP2-Remote.xpl */; - productType = "com.apple.product-type.library.dynamic"; - }; - 25D86CBF253E281800424494 /* XPMP2-Sample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 25D86CC3253E281800424494 /* Build configuration list for PBXNativeTarget "XPMP2-Sample" */; - buildPhases = ( - 25D86CBD253E281800424494 /* Sources */, - 25D86CBE253E281800424494 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 25D86CD0253E289100424494 /* PBXTargetDependency */, - ); - name = "XPMP2-Sample"; - productName = "XPMP2-Sample"; - productReference = 25D86CC0253E281800424494 /* XPMP2-Sample.xpl */; - productType = "com.apple.product-type.library.dynamic"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 2502C16023BE3CFC00578919 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1340; + LastUpgradeCheck = 1400; ORGANIZATIONNAME = TwinFan; TargetAttributes = { 2502C17923BE8A1600578919 = { CreatedOnToolsVersion = 11.3; }; - 25D86CBF253E281800424494 = { - CreatedOnToolsVersion = 12.0.1; - }; }; }; buildConfigurationList = 2502C16323BE3CFC00578919 /* Build configuration list for PBXProject "XPMP2" */; @@ -430,32 +304,11 @@ projectRoot = ""; targets = ( 2502C17923BE8A1600578919 /* XPMP2 */, - 25D86CBF253E281800424494 /* XPMP2-Sample */, - 25B071EB2540D6C400CCDA1D /* XPMP2-Remote */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ - 255C33772544C9D9002C166F /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Skip this in a Travis CI build\n[[ ! -z \"${TRAVIS_BUILD_DIR}\" ]] && exit 0\nTAGS=\"TODO:|FIXME:\"\necho \"Searching ${SRCROOT} for ${TAGS}\"\nfind \"${SRCROOT}/XPMP2-Remote\" \\( -name \"*.cpp\" -or -name \"*.h\" \\) -print0 | xargs -0 egrep --with-filename --line-number --only-matching \"($TAGS).*\\$\" | perl -p -e \"s/($TAGS)/ warning: \\$1/\"\n"; - showEnvVarsInLog = 0; - }; 255C338A2544E1FF002C166F /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -475,27 +328,6 @@ shellScript = "# Skip this in a Travis CI build\n[[ ! -z \"${TRAVIS_BUILD_DIR}\" ]] && exit 0\nTAGS=\"TODO:|FIXME:\"\necho \"Searching ${SRCROOT} for ${TAGS}\"\nfind {\"${SRCROOT}/inc\",\"${SRCROOT}/src\"} \\( -name \"*.cpp\" -or -name \"*.h\" \\) -print0 | xargs -0 egrep --with-filename --line-number --only-matching \"($TAGS).*\\$\" | perl -p -e \"s/($TAGS)/ warning: \\$1/\"\n"; showEnvVarsInLog = 0; }; - 259FFDFC25A132EC00B6D553 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}", - ); - outputFileListPaths = ( - ); - outputPaths = ( - "${LT_LIB_DIR}/${WRAPPER_NAME}", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Copy to LiveTraffic build dir if that exists (but don't fail)\nLT_LIB_DIR=\"${PROJECT_DIR}/../LiveTraffic/Lib/XPMP2\"\n[[ ! -d \"${LT_LIB_DIR}\" ]] && exit 0\nrm -Rf ${LT_LIB_DIR}/${WRAPPER_NAME}\ncp -af ${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME} ${LT_LIB_DIR}\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -514,42 +346,12 @@ 2575F45523EDFC5E00747524 /* Map.cpp in Sources */, 25338211253A39060090E0B3 /* Network.cpp in Sources */, 2599B91923BF636E00F92BB5 /* Aircraft.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 25B071EE2540D6C400CCDA1D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 256EE0002540D7EF0007D517 /* XPMP2-Remote.cpp in Sources */, - 256EE0102540E39D0007D517 /* Utilities.cpp in Sources */, - 252FD04E25421C2B00286AE6 /* Client.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 25D86CBD253E281800424494 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 25D86D7A253E2F3E00424494 /* XPMP2-Sample.cpp in Sources */, + 255EC99228E3871100F99F93 /* Sound.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 25B071EC2540D6C400CCDA1D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 2502C17923BE8A1600578919 /* XPMP2 */; - targetProxy = 25B071ED2540D6C400CCDA1D /* PBXContainerItemProxy */; - }; - 25D86CD0253E289100424494 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 2502C17923BE8A1600578919 /* XPMP2 */; - targetProxy = 25D86CCF253E289100424494 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin XCBuildConfiguration section */ 2502C16A23BE3CFC00578919 /* Debug */ = { isa = XCBuildConfiguration; @@ -559,7 +361,6 @@ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++17"; - CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; @@ -593,10 +394,10 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = "${XPMP2_VER_MAJOR}.${XPMP2_VER_MINOR}"; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = W5UR4ZV2BP; - DSTROOT = "$(XPLANE11_ROOT)/Resources/plugins/$(TARGET_NAME)"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; FRAMEWORK_VERSION = "${CURRENT_PROJECT_VERSION}"; @@ -607,6 +408,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", + "INCLUDE_FMOD_SOUND=1", "APL=1", "IBM=0", "LIN=0", @@ -637,19 +439,19 @@ GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = inc; INFOPLIST_FILE = Info.plist; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.twinfan.XPMP2; PRODUCT_NAME = XPMP2; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx; - USER_HEADER_SEARCH_PATHS = "$(XPSDK_ROOT)/CHeaders/XPLM"; - XPLANE11_ROOT = "$(USER_APPS_DIR)/X-Plane/Release"; + USER_HEADER_SEARCH_PATHS = ( + "$(XPSDK_ROOT)/CHeaders/XPLM", + lib/fmod/inc, + ); XPMP2_VER_MAJOR = 2; - XPMP2_VER_MINOR = 50; - XPSDK_ROOT = "XPMP2-Sample/SDK"; + XPMP2_VER_MINOR = 60; + XPSDK_ROOT = lib/SDK; }; name = Debug; }; @@ -661,7 +463,6 @@ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++17"; - CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; @@ -695,10 +496,10 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = "${XPMP2_VER_MAJOR}.${XPMP2_VER_MINOR}"; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = W5UR4ZV2BP; - DSTROOT = "$(XPLANE11_ROOT)/Resources/plugins/$(TARGET_NAME)"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_VERSION = "${CURRENT_PROJECT_VERSION}"; @@ -707,6 +508,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "NDEBUG=1", + "INCLUDE_FMOD_SOUND=1", "APL=1", "IBM=0", "LIN=0", @@ -737,18 +539,18 @@ GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = inc; INFOPLIST_FILE = Info.plist; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; PRODUCT_BUNDLE_IDENTIFIER = com.twinfan.XPMP2; PRODUCT_NAME = XPMP2; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx; - USER_HEADER_SEARCH_PATHS = "$(XPSDK_ROOT)/CHeaders/XPLM"; - XPLANE11_ROOT = "$(USER_APPS_DIR)/X-Plane/Release"; + USER_HEADER_SEARCH_PATHS = ( + "$(XPSDK_ROOT)/CHeaders/XPLM", + lib/fmod/inc, + ); XPMP2_VER_MAJOR = 2; - XPMP2_VER_MINOR = 50; - XPSDK_ROOT = "XPMP2-Sample/SDK"; + XPMP2_VER_MINOR = 60; + XPSDK_ROOT = lib/SDK; }; name = Release; }; @@ -757,9 +559,17 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; - DSTROOT = "$(PROJECT_DIR)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/XPMP2-Sample/lib/SDK/Libraries/Mac", + ); GCC_PREFIX_HEADER = src/XPMP2.h; + HEADER_SEARCH_PATHS = ( + inc, + "XPMP2-Sample/lib/fmod/inc", + ); INSTALL_PATH = "XPMP2-Sample/lib"; LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(PRODUCT_MODULE_NAME)"; LD_RUNPATH_SEARCH_PATHS = ( @@ -767,6 +577,10 @@ "@executable_path/../Frameworks", "@loader_path/Frameworks", ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/XPMP2-Sample/lib/fmod", + ); MACH_O_TYPE = staticlib; PRODUCT_BUNDLE_IDENTIFIER = com.twinfan.XPMP2; PRODUCT_NAME = XPMP2; @@ -778,9 +592,17 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; - DSTROOT = "$(PROJECT_DIR)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/XPMP2-Sample/lib/SDK/Libraries/Mac", + ); GCC_PREFIX_HEADER = src/XPMP2.h; + HEADER_SEARCH_PATHS = ( + inc, + "XPMP2-Sample/lib/fmod/inc", + ); INSTALL_PATH = "XPMP2-Sample/lib"; LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(PRODUCT_MODULE_NAME)"; LD_RUNPATH_SEARCH_PATHS = ( @@ -788,178 +610,16 @@ "@executable_path/../Frameworks", "@loader_path/Frameworks", ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/XPMP2-Sample/lib/fmod", + ); MACH_O_TYPE = staticlib; PRODUCT_BUNDLE_IDENTIFIER = com.twinfan.XPMP2; PRODUCT_NAME = XPMP2; }; name = Release; }; - 25B071F52540D6C400CCDA1D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = NO; - CLANG_ENABLE_OBJC_ARC = NO; - CODE_SIGN_IDENTITY = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; - DEFINES_MODULE = NO; - DEPLOYMENT_LOCATION = YES; - DYLIB_COMPATIBILITY_VERSION = ""; - DYLIB_CURRENT_VERSION = ""; - ENABLE_HARDENED_RUNTIME = YES; - EXECUTABLE_EXTENSION = xpl; - EXECUTABLE_PREFIX = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/XPMP2-Sample/SDK/Libraries/Mac", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "XPMP2-Remote/XPMP2-Remote.h"; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = ""; - INFOPLIST_FILE = ""; - INSTALL_PATH = mac_x64; - MACH_O_TYPE = mh_bundle; - OTHER_CODE_SIGN_FLAGS = "--timestamp"; - OTHER_LDFLAGS = ( - "$(OTHER_LDFLAGS)", - "-Wl,-exported_symbol", - "-Wl,_XPluginStart", - "-Wl,-exported_symbol", - "-Wl,_XPluginEnable", - "-Wl,-exported_symbol", - "-Wl,_XPluginReceiveMessage", - "-Wl,-exported_symbol", - "-Wl,_XPluginDisable", - "-Wl,-exported_symbol", - "-Wl,_XPluginStop", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - }; - name = Debug; - }; - 25B071F62540D6C400CCDA1D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = NO; - CLANG_ENABLE_OBJC_ARC = NO; - CODE_SIGN_IDENTITY = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; - DEFINES_MODULE = NO; - DEPLOYMENT_LOCATION = YES; - DYLIB_COMPATIBILITY_VERSION = ""; - DYLIB_CURRENT_VERSION = ""; - ENABLE_HARDENED_RUNTIME = YES; - EXECUTABLE_EXTENSION = xpl; - EXECUTABLE_PREFIX = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/XPMP2-Sample/SDK/Libraries/Mac", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "XPMP2-Remote/XPMP2-Remote.h"; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = ""; - INFOPLIST_FILE = ""; - INSTALL_PATH = mac_x64; - MACH_O_TYPE = mh_bundle; - OTHER_CODE_SIGN_FLAGS = "--timestamp"; - OTHER_LDFLAGS = ( - "$(OTHER_LDFLAGS)", - "-Wl,-exported_symbol", - "-Wl,_XPluginStart", - "-Wl,-exported_symbol", - "-Wl,_XPluginEnable", - "-Wl,-exported_symbol", - "-Wl,_XPluginReceiveMessage", - "-Wl,-exported_symbol", - "-Wl,_XPluginDisable", - "-Wl,-exported_symbol", - "-Wl,_XPluginStop", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - }; - name = Release; - }; - 25D86CC1253E281800424494 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = NO; - CLANG_ENABLE_OBJC_ARC = NO; - DEFINES_MODULE = NO; - DEPLOYMENT_LOCATION = YES; - DYLIB_COMPATIBILITY_VERSION = ""; - DYLIB_CURRENT_VERSION = ""; - EXECUTABLE_EXTENSION = xpl; - EXECUTABLE_PREFIX = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/XPMP2-Sample/SDK/Libraries/Mac", - ); - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = ""; - INFOPLIST_FILE = ""; - INSTALL_PATH = mac_x64; - MACH_O_TYPE = mh_bundle; - OTHER_LDFLAGS = ( - "$(OTHER_LDFLAGS)", - "-Wl,-exported_symbol", - "-Wl,_XPluginStart", - "-Wl,-exported_symbol", - "-Wl,_XPluginEnable", - "-Wl,-exported_symbol", - "-Wl,_XPluginReceiveMessage", - "-Wl,-exported_symbol", - "-Wl,_XPluginDisable", - "-Wl,-exported_symbol", - "-Wl,_XPluginStop", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - }; - name = Debug; - }; - 25D86CC2253E281800424494 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = NO; - CLANG_ENABLE_OBJC_ARC = NO; - DEFINES_MODULE = NO; - DEPLOYMENT_LOCATION = YES; - DYLIB_COMPATIBILITY_VERSION = ""; - DYLIB_CURRENT_VERSION = ""; - EXECUTABLE_EXTENSION = xpl; - EXECUTABLE_PREFIX = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/XPMP2-Sample/SDK/Libraries/Mac", - ); - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = ""; - INFOPLIST_FILE = ""; - INSTALL_PATH = mac_x64; - MACH_O_TYPE = mh_bundle; - OTHER_LDFLAGS = ( - "$(OTHER_LDFLAGS)", - "-Wl,-exported_symbol", - "-Wl,_XPluginStart", - "-Wl,-exported_symbol", - "-Wl,_XPluginEnable", - "-Wl,-exported_symbol", - "-Wl,_XPluginReceiveMessage", - "-Wl,-exported_symbol", - "-Wl,_XPluginDisable", - "-Wl,-exported_symbol", - "-Wl,_XPluginStop", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -981,24 +641,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 25B071F42540D6C400CCDA1D /* Build configuration list for PBXNativeTarget "XPMP2-Remote" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 25B071F52540D6C400CCDA1D /* Debug */, - 25B071F62540D6C400CCDA1D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 25D86CC3253E281800424494 /* Build configuration list for PBXNativeTarget "XPMP2-Sample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 25D86CC1253E281800424494 /* Debug */, - 25D86CC2253E281800424494 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 2502C16023BE3CFC00578919 /* Project object */; diff --git a/XPMP2.xcodeproj/xcshareddata/xcschemes/XPMP2.xcscheme b/XPMP2.xcodeproj/xcshareddata/xcschemes/XPMP2.xcscheme index 5f412a3c..b8d996ae 100644 --- a/XPMP2.xcodeproj/xcshareddata/xcschemes/XPMP2.xcscheme +++ b/XPMP2.xcodeproj/xcshareddata/xcschemes/XPMP2.xcscheme @@ -1,6 +1,6 @@ Open > Folder", [see here for VS's "Open Folder" functionality](https://docs.microsoft.com/en-us/cpp/build/open-folder-projects-cpp?view=vs-2019)) -- In both cases will VS use the CMake setup to configure building the binaries. +- Open the root folder of the repo using "File > Open > Folder", + [see here for VS's "Open Folder" functionality](https://docs.microsoft.com/en-us/cpp/build/open-folder-projects-cpp?view=vs-2019)) +- VS use the CMake setup to configure building the binaries. - Build from within Visual Studio. -Results are in `build/x64`. - -The `XPMP2.lib` library is also copied into `XPMP2-Sample/lib` to be available in a subsequent build -of the sample plugin. +Results are in `build-win`. ### MacOS My development environment is Mac OS, so expect the XCode environment to be -maintained best. Open `XPMP2.xcodeproj` resp. -`XPMP2-Sample/XPMP2-Sample.xcodeproj` in XCode. +maintained best. Open `XPMP2.xcodeproj` resp. `XPMP2-Sample.xcodeproj` in XCode. -In the XCode Build Settings you may want to change the definition +In the `XPMP2-Sample` XCode Build Settings you may want to change the definition of the User-Defined build macro `XPLANE11_ROOT`: Put in the path to your X-Plane 11 installation's root path, then the XPMP2 binaries will be installed right there in the appropriate `Resources/plugins` sub-folder @@ -62,11 +56,9 @@ which can build all 3 platforms, Linux even in two flavors. - Install [Docker Desktop](https://www.docker.com/products/docker-desktop) and start it. - `cd` to the project's `docker` folder, and enter `make` for all - XPMP2 library targets on all platforms, or -- `cd` to `XPMP2-Sample/docker`, and enter `make` for the sample plugin only - on all platforms. + XPMP2 library targets on all platforms. -9 individual `make` targets are available: +The following `make` targets are available: - `lin` builds Linux on Ubuntu 20.04 - `lin-bionic` builds Linux on Ubuntu 18.04 @@ -76,19 +68,18 @@ which can build all 3 platforms, Linux even in two flavors. - `win` builds Windows using a Mingw64 cross compiler setup - `bash_focal` starts a bash prompt in the Ubuntu 20.04 docker container - `bash_bionic` starts a bash prompt in the Ubuntu 18.04 docker container -- `doc` builds the documentation based on Doxygen, will probably only work on a Mac with Doxygen provided in `Applications/Doxygen.app`. +- `doc` builds the documentation based on Doxygen, will probably only work on a Mac with Doxygen provided in `Applications/Doxygen.app` +- `clean` removes all `build-` folders Find results in the respective `build-` folder, the `XPMP2` library right there, -the Sample and Remote plugins in their proper `_x64` subfolder. - -The resulting library/framework are also copied into `XPMP2-Sample/lib/` so it is accessible if building the Sample plugin from the Sample project only. +the Sample plugins in their proper `_x64` subfolder. For more details and background information on the provided Docker environments see the `docker/README.md`. ## Using CMake -Given a proper local setup with a suitable compile, CMake, and Ninja installed, +Given a proper local setup with a suitable compiler, CMake, and Ninja installed, you can just locally build the sources from the `CMakeList.txt` file, e.g. like this: @@ -110,7 +101,10 @@ each coming with its own `README.md`. The workflow builds Linux, MacOS, and Windows plugin binaries and provides them as artifacts, so you can download the result from the _Actions_ tab on GitHub. -For **MacOS**, the plugin can be **signed and notarized**, provided that the required _Repository Secrets_ are defined in the repository's settings +### Apple: Sign and Notiarize + +The Apple build of the `XPMP2-Sample` plugin can be signed and notarized, +provided that the following _Repository Secrets_ are defined in the repository's settings (Settings > Secrets > Actions): - `MACOS_CERTIFICATE`: Base64-encoded .p12 certificate as [explained here](https://localazy.com/blog/how-to-automatically-sign-macos-apps-using-github-actions#lets-get-started) @@ -118,3 +112,32 @@ For **MacOS**, the plugin can be **signed and notarized**, provided that the req - `NOTARIZATION_USERNAME`: Apple ID for notarization service (parameter `--apple-id` to `notarytool`) - `NOTARIZATION_TEAM`: Team ID for notarization service (parameter `--team-id` to `notarytool`) - `NOTARIZATION_PASSWORD`: [App-specific password](https://support.apple.com/en-gb/HT204397) for notarization service (parameter `--password` to `notarytool`) + +## Including XPMP2 directly in GitHub project and CMake builds + +You can avoid separate builds and instead include `XPMP2` directly into your project. +Recommended steps are: + +1. Include XPMP2 as a Github Submodule into your Github project, using something like + ``` + git submodule add --name XPMP2 'https://github.com/TwinFan/XPMP2' lib/XPMP2 + ``` + To update your local version with changes from the XPMP2 repository run something like + ``` + git submodule update --remote + ``` +2. In your `CMakeLists.txt` file include XPMP2 using something like the following in appropriate places: + 1. If needing FMOD sound support first define + ``` + set (INCLUDE_FMOD_SOUND 1) + add_compile_definitions(INCLUDE_FMOD_SOUND=1) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib/XPMP2/lib/fmod/logo") + target_sources(${CMAKE_PROJECT_NAME} lib/XPMP2/lib/fmod/logo/FMOD_Logo.cpp) + ``` + 2. Including building XPMP2 as follows: + ``` + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib/XPMP2/inc") + add_subdirectory(lib/XPMP2) + add_dependencies(${CMAKE_PROJECT_NAME} XPMP2) + target_link_libraries(${CMAKE_PROJECT_NAME} XPMP2) + ``` diff --git a/docs/Calc3DCoord.xlsx b/docs/Calc3DCoord.xlsx new file mode 100644 index 00000000..cc3e09a3 Binary files /dev/null and b/docs/Calc3DCoord.xlsx differ diff --git a/docs/Deploying.md b/docs/Deploying.md index 7a9a77a1..cf7cfab3 100644 --- a/docs/Deploying.md +++ b/docs/Deploying.md @@ -1,13 +1,28 @@ Deploying XPMP2-based Plugins == -XPMP2 needs a couple additional files to work. In your calls to -`XPMPMultiplayerInit` and `XPMPLoadCSLPackage` you provide the locations -to the folders holding these files. +FMOD Sound Support (XP11/Windows) +-- +If you built XPMP2 and your plugin with [FMOD Sound Support](Sound.html), +and you want to allow running your plugin with X-Plane 11 under Windows, +then you should ship the `fmod.dll`, too, as +``` +win_x64/fmod.dll +``` +next to your plugin's Windows version. Find `api/core/lib/x64/fmod.dll` in the Windows version +of the FMOD Core API that you had [downloaded from FMOD](https://www.fmod.com/download#fmodengine). + +The reason is that X-Plane updated the FMOD versions included in X-Plane between XP11 and XP12. +While XPMP2 is built in a way that it can run with either version, +XP11 ships a DLL by the name of `fmod64.dll` while XPMP2 expects it by the name `fmod.dll` as XP12 provides it. Resources -- +XPMP2 needs a couple additional files to work. In your calls to +`XPMPMultiplayerInit` and `XPMPLoadCSLPackage` you provide the locations +to the folders holding these files. + You should ship all the files provided in the `Resources` folder: - `Doc8643.txt` is a list of ICAO aircraft type designators taken from diff --git a/docs/MainPage.md b/docs/MainPage.md index e81c5921..52ab0beb 100644 --- a/docs/MainPage.md +++ b/docs/MainPage.md @@ -30,6 +30,18 @@ The following header file is for use by the "XPMP2 Remote Client": - XPMPRemote.h - Defines network functionality and data structure for synchronizing planes between networked computers. +### Sound Support by FMOD + +XPMP2's Audio Engine is FMOD Core API by Firelight Technologies Pty Ltd. +Understand FMOD [licensing](https://www.fmod.com/licensing) and +[attribution requirements](https://www.fmod.com/attribution) first, +as they will apply to _your_ plugin if using XPMP2 with sound support. + +Because of the licensing requirements, XPMP2 by default is built +**without** sound support. +See the [Sound Support documentation](https://twinfan.github.io/XPMP2/Sound.html) +for details how to enable sound support and how to include it into your plugin. + Quick Links to Detailed Documentation: -- diff --git a/docs/Sound.md b/docs/Sound.md new file mode 100644 index 00000000..ca316d4d --- /dev/null +++ b/docs/Sound.md @@ -0,0 +1,219 @@ +## Sound Support by FMOD + +XPMP2's Audio Engine is FMOD Core API by Firelight Technologies Pty Ltd. + +While X-Plane supports and uses FMOD, too, for aircraft-specific sounds, +XPMP2 cannot make use of any X-Plane functionality to produce the sounds +as X-Plane at the moment does not allow to dynamically add sounds +to instanced objects. + +Instead, XPMP2 creates its own fully indepent instance of the FMOD system. +This also means that XPMP2 has to provide FMOD with all spacial information +for each aircraft's sound to create a proper 3D sound illusion +relative to the user's current camera position. Which opens a totally new +space for potential bugs... + +### Register with FMOD and Download + +Understand FMOD [licensing](https://www.fmod.com/licensing) and +[attribution requirements](https://www.fmod.com/attribution) first, +as they will apply to _your_ plugin if using XPMP2 with sound support. + +You will need to [register a user with FMOD](https://www.fmod.com/profile/register), +then sign in and [download the latest FMOD Core API](https://www.fmod.com/download#fmodengine) +at least for Windows and Mac (if you ship on those platforms). + +### Building XPMP2 with FMOD Sound Support + +Due to above licencing requirements, +sound support is only included if XPMP2 is consciously built with +CMake cache entry `INCLUDE_FMOD_SOUND`, which in turn defines a +compile-time macro by the same name, e.g. by doing +``` +cmake -G Ninja -DINCLUDE_FMOD_SOUND=1 .. +``` +The Docker `Makefile` allows passing CMake parameters via the `FLAGS` macro: +``` +make FLAGS=-DINCLUDE_FMOD_SOUND=1 {...platform(s)...} +``` +The GitHub Actions triggered by default are building without FMOD support, too. +Running "Build all Platforms" manually, though, allows to specify `FLAGS`. + +### Including FMOD Sound Support in Your Plugin + +In your plugin, you also need to define `INCLUDE_FMOD_SOUND` _before_ including the XPMP2 headers: +``` +#define INCLUDE_FMOD_SOUND 1 // Include FMOD sound support +#include "XPMPMultiplayer.h" +#include "XPMPAircraft.h" +``` +Then link to +- an FMOD-sound-enabled version of `XPMP2`, +- FMOD libraries from the downloaded FMOD Core API, namely + - `api/core/lib/libfmod.dylib` (Mac) and + - `api/core/lib/x64/fmod_vc.ib` (Windows). + +#### CMake + +When building with `CMake` you'll need something like this in your `CMakeLists.txt`: +``` +# Need FMOD Sound Support (from XPMP2) +set (INCLUDE_FMOD_SOUND 1) # tells XPMP2 to build with FMOD +add_compile_definitions(INCLUDE_FMOD_SOUND=1) # tells LiveTraffic compile to include FMOD from XPMP2 headers +[...] +# Incude building XPMP2 +add_subdirectory(Lib/XPMP2) +add_dependencies( XPMP2) +target_link_libraries( XPMP2) +[...] +# Link to FMOD +if (WIN32 OR APPLE) + # Where you put the downloaded FMOD Core API libraries: + list(APPEND CMAKE_LIBRARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/fmod") + find_library(FMOD_LIBRARY NAMES fmod_vc.lib libfmod.dylib REQUIRED) + target_link_libraries( ${FMOD_LIBRARY}) +endif () +``` +This defines both the `CMake` cache entry as well as the preprocessor macro +to build with FMOD sound support. It then, after having set `INCLUDE_FMOD_SOUND`, +includes `XPMP2` into your build tree. Finally, it links your plugin to the FMOD library, +but only for Windows and Apple builds. A Linux build is not specifically linked with FMOD +(the same way it is also not linked to `XPML` or `OpenGL` libraries), because X-Plane itself +will always load some version of the library on its startup before any plugin. +Linux' dynamic loader will then find that already loaded library and use it also for +your plugin. + +#### Avoid Crash + +If the XPMP2 you linked is compiled with `INCLUDE_FMOD_SOUND` +but your actual plugin without, +then the plugin will crash in `XPMP2::Aircraft::FlightLoopCB()` +at the point when it tries to call `XPMP2::Aircraft::UpdateSound()`, +because the `XPMP2::Aircraft` object created by your plugin +is created with too short a `vtable` as it did not consider the +virtual member functions for sound support. + +You can tell if your XPMP2 library includes FMOD support +latest from the init message in +`Log.txt`, when it says: + +``` +...XPMPMultiplayerInit: XPMP2 2.60 with FMOD support initializing...` +``` + +Solution: Either link to an XPMP2 build without FMOD support. Or make sure to +`#define INCLUDE_FMOD_SOUND 1` in your plugin before including the XPMP2 headers. + +#### FMOD Logo + +Not built into XPMP2 (to avoid a link-time dependency on OpenGL) but provided separately are functions to create the FMOD logo as per [attribution requirements](https://www.fmod.com/attribution). Include `FMOD_Logo.cpp` and `FMOD_Logo.h` from `XPMP2/lib/fmod/logo` into your project. Showing the FMOD logo in a Dear ImGui window is then as simple as +``` +#include "FMOD_Logo.h" +... +int logoId = 0; +if (FMODLogo::GetTexture(logoId)) { + ImGui::Image((void*)(intptr_t)logoId, ImVec2(FMODLogo::IMG_WIDTH, FMODLogo::IMG_HEIGHT)); +} +``` + +### Ship `fmod.dll` + +If your plugin supports X-Plane 11 under Windows, then from the downloaded FMOD Core API +you need to ship `api/core/lib/x64/fmod.dll` in the plugin's `win_x64` folder. +See [Deploying](Deploying.html) for details. + +### Default Sounds + +Your are **not required** to provide any sound-specific coding in your plugin. +As a matter of fact, the XPMP2-Sample plugin has no single line of code +that controls sound (there is only some sample code to enumerate the loaded +sounds into `Log.txt`, purely for my personal testing purposes). +And even the way more complex LiveTraffic only adds a Master Volume control +and the required FMOD logo display, but no line of sound control to its aircraft class. + +Once built with sound support, XPMP2 provides a lot of sounds by default. +XPMP2 distinguishes 5 sound types, see `XPMP2::Aircraft::SoundEventsTy`, +and plays sounds that are included in any X-Plane installation's +`Resources/sounds` folders based on the level of certain dataRefs: + +Event | dataRef | Sound +-------|------|----------- +Engine | Thrust Ratio | Depends on aircraft type, volume changes with Thrust +Reverse | Thrust Reverse Ratio | `XP_SOUND_REVERSE_THRUST`, volume changes with Thrust Reverse +Tire | Tire Rotation RPM | `XP_SOUND_ROLL_RUNWAY`, volume changes with RPM +Gear | Gear Ratio | `XP_SOUND_GEAR` upon a change to the Gear Ratio +Flaps | Flap Ratio | `XP_SOUND_FLAP` once upon a change to the Flap Ratio + +The engine sounds depend on the aircraft type, more specifically on the +[ICAO aircraft type designators](https://www.icao.int/publications/doc8643/pages/search.aspx) +as provided in `Resources/Doc8643.txt`: + +Type Designator | means | Sound +----------------|-------------------|--------------- +`ZZZC` | Ground vehicle | `XP_SOUND_ELECTRIC` +`H??` or `G??` | Heli, Gyrocopter | `XP_SOUND_PROP_HELI` +`E??` | Electric | `XP_SOUND_ELECTRIC` +`J1?` | Jet, single | `XP_SOUND_HIBYPASSJET` +`J??` | Jet, multi | `XP_SOUND_LOBYPASSJET` +`P??` | Piston | `XP_SOUND_PROP_AIRPLANE` +`T??` | Turboprop | `XP_SOUND_TURBOPROP` + +The sounds' volume additionally depends on the number of engines, +which while obvious for the engine sounds is generally an ok indicator +for the plane's size and hence volume. + +### Controlling Sound + +Here are your options to influence sound. + +#### Enable/Disable + +Beside using `XPMPSoundEnable()` directly, you can also provides values +for configuration items `XPMP_CFG_ITM_ACTIVATE_SOUND` and +`XPMP_CFG_ITM_MUTE_ON_PAUSE` in your configuration callback. + +#### General Volume + +`XPMPSoundSetMasterVolume()` and `XPMPSoundMute()` allow controlling +the volume of XPMP2's sounds generally across all aircraft. + +#### Add your own Sounds + +`XPMPSoundAdd()` allows you to add your own sounds. +Sounds can be looping (like engine sounds, which play continuously) +or one-time sounds. + +The function optionally also allows to define **sound cone** parameters. +A sound cone basically is a cone-shaped area, in which the sound +is heared with full volume, while outside of it the sound is reduced +(attenuated) to a lower volume. The default sounds use that for the +jet eingine sounds, which are louder _behind_ the aircraft. +`coneDir` and `conePitch` are defined relative to the aircraft's heading. +XPMP2 takes care of orientating the actual sound cone dynamically with +the actual aircraft orientation. The other three cone-specific +parameters are passed through to FMOD +(see [set3DConeSettings](https://www.fmod.com/docs/api/core-api-sound.html#sound_set3dconesettings)). + +#### Override virtual `Aircraft` member functions + +For more control over the sounds your aircraft emit you can override +`Aircraft`'s virtual member functions: + +- `Aircraft::SoundSetup()` + is called after aircraft creation once the CSL model to use is determined; + called again after CSL model changes. Use to define/override some defaults. + Is a good place to set `aSndCh[SoundEventsTy].bAuto = false` in case + you want to have full control over any of the pre-defined sound types. +- `Aircraft::SoundUpdate()` + is called in every flight loop cycle and decides, + which sounds to start/stop at which volume. You can make calls to + functions like `Aircraft::SoundPlay/SoundStop/SoundVolume()`. +- `Aircraft::SoundGetName()` is called by XPMP2's standard implementation of + `SoundUpdate()`. Override if you just want to have control over which sounds + at which volume to play for the standard event types, but otherwise + want to leave sound handling to XPMP2. You can return any sound name, + ie. also additional names you have registered previously with `XPMPSoundAdd()`. +- `Aircraft::SoundRemoveAll()` is called during object destruction to cleanup + all sound objects. If you have started playing any sounds yourself + you should clean them up here before calling the standard function + to give XPMP2 a chance for cleanup, too. \ No newline at end of file diff --git a/docs/XPMP2.doxygen b/docs/XPMP2.doxygen index a48b633b..7a42a39b 100644 --- a/docs/XPMP2.doxygen +++ b/docs/XPMP2.doxygen @@ -827,7 +827,8 @@ INPUT = inc \ src \ docs \ XPMP2-Remote \ - XPMP2-Sample + XPMP2-Sample \ + XPMP2-Sample/lib/fmod/logo # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -2133,7 +2134,7 @@ MACRO_EXPANSION = NO # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. @@ -2165,7 +2166,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = INCLUDE_FMOD_SOUND=1 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/docs/html/2D_8cpp.html b/docs/html/2D_8cpp.html index 2476c19e..06182aaf 100644 --- a/docs/html/2D_8cpp.html +++ b/docs/html/2D_8cpp.html @@ -59,6 +59,7 @@

Namespaces

 XPMP2 + Defined by FMOD.
  +

diff --git a/docs/html/2D_8h.html b/docs/html/2D_8h.html index eef2774f..ac772811 100644 --- a/docs/html/2D_8h.html +++ b/docs/html/2D_8h.html @@ -59,6 +59,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/2D_8h_source.html b/docs/html/2D_8h_source.html index 8ff34709..7a1a201b 100644 --- a/docs/html/2D_8h_source.html +++ b/docs/html/2D_8h_source.html @@ -63,10 +63,10 @@
36 }
37 
38 #endif
-
Definition: XPMPAircraft.h:41
-
void TwoDInit()
Initialize the module.
Definition: 2D.cpp:227
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
+
void TwoDInit()
Initialize the module.
Definition: 2D.cpp:226
void TwoDDrawLabels()
Write the labels of all aircraft.
Definition: 2D.cpp:118
-
void TwoDCleanup()
Grace cleanup.
Definition: 2D.cpp:245
+
void TwoDCleanup()
Grace cleanup.
Definition: 2D.cpp:244

Namespaces

 XPMP2
 Defined by FMOD.
 
- +

@@ -161,7 +162,7 @@

 Release TCAS targets control. More...
 
bool XPMPHasControlOfAIAircraft ()
 Has XPMP2 control of TCAS targets? More...
 Has XPMP2 control of TCAS targets? More...
 
+

@@ -193,7 +194,7 @@

Detailed Description

Implementation of serving TCAS target dataRef updates.

Updates the up to 63 slots of X-Plane's defined TCAS targets, which are in turn synced with the 19 "legacy" multiplayer slots, which in turn many other plugins (like TCAS implementations or map tools) read to learn about any multiplayer aircraft.
- Also serves shared dataRefs for publishing text information, which is not X-Plane standard but originally suggested by FSTramp. However, the post and file, in which he suggested this addition, is no longer available on forums.x-plane.org. Still, XPMP2 fullfills the earlier definition.

See also
X-Plane 11.50 Beta 8 introduced a new way of informing X-Plane of TCAS targets, see here a blog entry for details: https://developer.x-plane.com/article/overriding-tcas-and-providing-traffic-information/
+ Also serves shared dataRefs for publishing text information, which is not X-Plane standard but originally suggested by FSTramp. However, the post and file, in which he suggested this addition, is no longer available on forums.x-plane.org. Still, XPMP2 fullfills the earlier definition.

See also
X-Plane 11.50 Beta 8 introduced a new way of informing X-Plane of TCAS targets, see here a blog entry for details: https://developer.x-plane.com/article/overriding-tcas-and-providing-traffic-information/
Author
Birger Hoppe
@@ -557,7 +558,7 @@

Release TCAS targets control.

-

Afterwards, XPMP2's aircraft will no longer appear on TCAS or on 3rd-party plugins relying on TCAS targets dataRefs.
+

Afterwards, XPMP2's aircraft will no longer appear on TCAS or on 3rd-party plugins relying on TCAS targets dataRefs.
Is called during XPMPMultiplayerCleanup() automatically.

@@ -590,7 +591,7 @@

XPMP2's aircraft will appear on TCAS and are available to 3rd-party plugins relying on TCAS tagrtes or multiplayer dataRefs.
+ If successful, XPMP2's aircraft will appear on TCAS and are available to 3rd-party plugins relying on TCAS tagrtes or multiplayer dataRefs.
Typically, a plugin calls this function just before the first aircraft are created. But it could also be bound to a menu item, for example.

Parameters
diff --git a/docs/html/AIMultiplayer_8h.html b/docs/html/AIMultiplayer_8h.html index 2a639705..ec986305 100644 --- a/docs/html/AIMultiplayer_8h.html +++ b/docs/html/AIMultiplayer_8h.html @@ -59,6 +59,7 @@ +
_callback(optional) You can provide a callback function, which is called directly by X-Plane when control of TCAS targets is not successful now but becomes available later.

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/AIMultiplayer_8h_source.html b/docs/html/AIMultiplayer_8h_source.html index 06d678d0..136e6bb0 100644 --- a/docs/html/AIMultiplayer_8h_source.html +++ b/docs/html/AIMultiplayer_8h_source.html @@ -64,11 +64,11 @@
38 } // namespace XPMP2
39 
40 #endif
-
Definition: XPMPAircraft.h:41
-
void AIMultiInformDREs()
Inform DRE and DRT of our shared dataRefs.
Definition: AIMultiplayer.cpp:828
-
void AIMultiInit()
Initialize the module.
Definition: AIMultiplayer.cpp:851
-
void AIMultiCleanup()
Grace cleanup.
Definition: AIMultiplayer.cpp:1026
-
void AIMultiUpdate()
Updates all TCAS target dataRefs, both standard X-Plane, as well as additional shared dataRefs for te...
Definition: AIMultiplayer.cpp:606
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
+
void AIMultiInformDREs()
Inform DRE and DRT of our shared dataRefs.
Definition: AIMultiplayer.cpp:830
+
void AIMultiInit()
Initialize the module.
Definition: AIMultiplayer.cpp:853
+
void AIMultiCleanup()
Grace cleanup.
Definition: AIMultiplayer.cpp:1028
+
void AIMultiUpdate()
Updates all TCAS target dataRefs, both standard X-Plane, as well as additional shared dataRefs for te...
Definition: AIMultiplayer.cpp:608

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/Aircraft_8h_source.html b/docs/html/Aircraft_8h_source.html index fe869fb6..b9dd698f 100644 --- a/docs/html/Aircraft_8h_source.html +++ b/docs/html/Aircraft_8h_source.html @@ -86,19 +86,19 @@
69 } // namespace XPMP2
70 
71 #endif
-
XPMPPlaneCallbackResult(* XPMPPlaneData_f)(XPMPPlaneID inPlane, XPMPPlaneDataType inDataType, void *ioData, void *inRefcon)
Callback function your plugin provides to return updated plane data.
Definition: XPMPMultiplayer.h:489
-
XPMPPlaneCallbackResult
Definfes the different responses to asking for information.
Definition: XPMPMultiplayer.h:231
-
unsigned XPMPPlaneID
Unique ID for an aircraft created by a plugin.
Definition: XPMPMultiplayer.h:243
-
Textual information of planes to be passed on via shared dataRefs to other plugins.
Definition: XPMPMultiplayer.h:199
-
This data structure contains the basic position info for an aircraft.
Definition: XPMPMultiplayer.h:79
-
defines information about an aircraft visible to radar.
Definition: XPMPMultiplayer.h:189
-
External physical configuration of the plane.
Definition: XPMPMultiplayer.h:147
+
XPMPPlaneCallbackResult(* XPMPPlaneData_f)(XPMPPlaneID inPlane, XPMPPlaneDataType inDataType, void *ioData, void *inRefcon)
Callback function your plugin provides to return updated plane data.
Definition: XPMPMultiplayer.h:601
+
XPMPPlaneCallbackResult
Definfes the different responses to asking for information.
Definition: XPMPMultiplayer.h:240
+
unsigned XPMPPlaneID
Unique ID for an aircraft created by a plugin.
Definition: XPMPMultiplayer.h:252
+
Textual information of planes to be passed on via shared dataRefs to other plugins.
Definition: XPMPMultiplayer.h:208
+
This data structure contains the basic position info for an aircraft.
Definition: XPMPMultiplayer.h:88
+
defines information about an aircraft visible to radar.
Definition: XPMPMultiplayer.h:198
+
External physical configuration of the plane.
Definition: XPMPMultiplayer.h:156
Legacy wrapper class as provided by original libxplanemp.
Definition: XPCAircraft.h:37
This class helps creating aircraft via the legacy global functions. It provides standard implementati...
Definition: Aircraft.h:28
-
Definition: XPMPAircraft.h:41
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
std::map< XPMPPlaneID, Aircraft * > mapAcTy
Map of all aircraft, key is tthe plane id.
Definition: Aircraft.h:57
-
void AcCleanup()
Grace cleanup, esp. remove all aircraft.
Definition: Aircraft.cpp:1038
-
void AcInit()
Initialize the module.
Definition: Aircraft.cpp:1008
+
void AcCleanup()
Grace cleanup, esp. remove all aircraft.
Definition: Aircraft.cpp:1068
+
void AcInit()
Initialize the module.
Definition: Aircraft.cpp:1038

Namespaces

 XPMP2
 Defined by FMOD.
 
+

@@ -79,11 +80,11 @@

Copy .obj file just before loading, to replace dataRefs and texture.

These routines make a copy of an .obj file just before it gets loaded by X-Plane. This way we can replace dataRefs and textures.

  1. xsb_aircraft.txt formats vary by now out in the wild. For example, X-CSL/X-IvAp used to defined texture on the OBJ8 line. X-Plane, especially for instancing, cannot replace textures on the fly. The solution is to copy the .obj file, replacing the up to two lines defining the texture to use, and then only have it loaded by X-Plane.
  2. -
  3. CSL-Models might not use correct dataRefs as supported by XPMP2. For example are the widely used Bluebell models known to have translated only a limited set of dataRefs from their World Traffic origin into the libxplanemp world. XPMP2 now supports a lot more dataRefs. Replacing dataRef names in those models unlocks a number of feature like rotating props/rotors, turning wheels, or reversers.
  4. +
  5. CSL-Models might not use correct dataRefs as supported by XPMP2. For example are the widely used Bluebell models known to have translated only a limited set of dataRefs from their World Traffic origin into the libxplanemp world. XPMP2 now supports a lot more dataRefs. Replacing dataRef names in those models unlocks a number of feature like rotating props/rotors, turning wheels, or reversers.
-
See also
https://twinfan.github.io/XPMP2/XSBAircraftFormat.html for the xsb_aircraft.txt format definition as supported by XPMP2.
+
See also
https://twinfan.github.io/XPMP2/XSBAircraftFormat.html for the xsb_aircraft.txt format definition as supported by XPMP2.
-https://twinfan.github.io/XPMP2/CSLdataRefs.html for a list of animation dataRefs supported by XPMP2. And beyond that you can add even more using the XPMPAddModelDataRef() function.
+https://twinfan.github.io/XPMP2/CSLdataRefs.html for a list of animation dataRefs supported by XPMP2. And beyond that you can add even more using the XPMPAddModelDataRef() function.
Author
Birger Hoppe

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/CSLModels_8h.html b/docs/html/CSLModels_8h.html index 7a8b2fe6..1db4cddd 100644 --- a/docs/html/CSLModels_8h.html +++ b/docs/html/CSLModels_8h.html @@ -74,6 +74,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
- + - + - + - + @@ -377,7 +377,7 @@

-

Handle A/C Animation dataRef messages, called by XPMP2 via callback.

+

Handle A/C Animation dataRef messages, called by XPMP2 via callback.

@@ -413,7 +413,7 @@

-

Handle A/C Details messages, called by XPMP2 via callback.

+

Handle A/C Details messages, called by XPMP2 via callback.

  1. If the aircraft does not exist create it
    1. Else update it's data
    2. @@ -455,7 +455,7 @@

      -

      Handle A/C Position Update message, called by XPMP2 via callback.

      +

      Handle A/C Position Update message, called by XPMP2 via callback.

      @@ -491,7 +491,7 @@

      -

      Handle A/C Removal message, called by XPMP2 via callback.

      +

      Handle A/C Removal message, called by XPMP2 via callback.

      diff --git a/docs/html/Client_8h_source.html b/docs/html/Client_8h_source.html index f10bf8aa..14e20ce0 100644 --- a/docs/html/Client_8h_source.html +++ b/docs/html/Client_8h_source.html @@ -147,7 +147,7 @@
      void ClientTryGetAI()
      Try getting TCAS/AI control.
      Definition: Client.cpp:306
      void ClientInit()
      Initializes the module.
      Definition: Client.cpp:581
      std::map< XPMPPlaneID, RemoteAC > mapRemoteAcTy
      Map of remote aircraft; key is the plane id as sent by the sending plugin (while the _modeS_id of the...
      Definition: Client.h:83
      -
      unsigned XPMPPlaneID
      Unique ID for an aircraft created by a plugin.
      Definition: XPMPMultiplayer.h:243
      +
      unsigned XPMPPlaneID
      Unique ID for an aircraft created by a plugin.
      Definition: XPMPMultiplayer.h:252
      Representation of a remote aircraft.
      Definition: Client.h:30
      double lon
      longitude
      Definition: Client.h:46
      std::chrono::duration< int, std::ratio< 1, 10000 > > diffTime
      time difference to previous historic position as passed in by the sender
      Definition: Client.h:48
      @@ -169,7 +169,7 @@
      std::chrono::time_point< std::chrono::steady_clock > histTs[2]
      Timestamps when these two positions were valid.
      Definition: Client.h:42
      std::string sShortId
      CSL model's short id.
      Definition: Client.h:35
      double alt_ft
      altitude [ft]
      Definition: Client.h:47
      -
      Actual representation of all aircraft in XPMP2.
      Definition: XPMPAircraft.h:147
      +
      Actual representation of all aircraft in XPMP2.
      Definition: XPMPAircraft.h:181
      Uniquely identifies a sending plugin.
      Definition: Client.h:90
      SenderAddrTy(XPLMPluginID _id, const std::uint32_t _from[4])
      Constructor just fills values.
      Definition: Client.h:95
      std::uint32_t from[4]
      numerical part of sender's IP address (only differentiating in rare cases of two plugins on different...
      Definition: Client.h:92
      diff --git a/docs/html/FMOD__Logo_8cpp.html b/docs/html/FMOD__Logo_8cpp.html new file mode 100644 index 00000000..51d82976 --- /dev/null +++ b/docs/html/FMOD__Logo_8cpp.html @@ -0,0 +1,112 @@ + + + + + + + +XPMP2: XPMP2-Sample/lib/fmod/logo/FMOD_Logo.cpp File Reference + + + + + + +
      +
      +

diff --git a/docs/html/CSLModels_8h_source.html b/docs/html/CSLModels_8h_source.html index c2f64ab2..29da3952 100644 --- a/docs/html/CSLModels_8h_source.html +++ b/docs/html/CSLModels_8h_source.html @@ -172,67 +172,69 @@
200  const char* GetWTC () const { return doc8643->wtc; }
201  char GetClassType () const { return doc8643->GetClassType(); }
202  char GetClassNumEng () const { return doc8643->GetClassNumEng(); }
-
203  char GetClassEngType () const { return doc8643->GetClassEngType(); }
-
204  bool HasRotor () const { return doc8643->HasRotor(); }
-
205 
-
207  float GetVertOfs () const { return vertOfs; }
-
208 
-
210  ObjLoadStateTy GetObjState () const;
-
212  bool IsObjInvalid () const { return GetObjState() == OLS_INVALID; }
-
213 
-
216  std::list<XPLMObjectRef> GetAllObjRefs ();
-
217 
-
219  void IncRefCnt () { ++refCnt; }
-
221  void DecRefCnt ();
-
223  unsigned GetRefCnt () const { return refCnt; }
-
224 
-
226  static float GarbageCollection (float inElapsedSinceLastCall,
-
227  float inElapsedTimeSinceLastFlightLoop,
-
228  int inCounter,
-
229  void * inRefcon);
-
230 
-
231 protected:
-
233  void Unload ();
-
235  float FetchVertOfsFromObjFile () const;
-
236 };
-
237 
-
239 typedef std::map<std::string,CSLModel> mapCSLModelTy;
-
240 
-
242 typedef std::multimap<unsigned long,std::pair<CSLModel*,const CSLModel::MatchCritTy*> > mmapCSLModelPTy;
-
243 
-
244 //
-
245 // MARK: Global Functions
-
246 //
-
247 
-
249 void CSLModelsInit ();
-
250 
-
252 void CSLModelsCleanup ();
-
253 
-
258 const char* CSLModelsLoad (const std::string& _path,
-
259  int _maxDepth = 5);
-
260 
-
264 CSLModel* CSLModelById (const std::string& _cslId,
-
265  mapCSLModelTy::iterator* _pOutIter = nullptr);
-
266 
-
270 CSLModel* CSLModelByKey(const std::string& _cslKey,
-
271  mapCSLModelTy::iterator* _pOutIter = nullptr);
-
272 
-
280 int CSLModelMatching (const std::string& _type,
-
281  const std::string& _airline,
-
282  const std::string& _livery,
-
283  CSLModel* &pModel);
-
284 
-
285 } // namespace XPMP2
-
286 
-
287 #endif
+
203  int GetNumEngines() const { return doc8643->GetNumEngines(); }
+
204  char GetClassEngType () const { return doc8643->GetClassEngType(); }
+
205  bool HasRotor () const { return doc8643->HasRotor(); }
+
206 
+
208  float GetVertOfs () const { return vertOfs; }
+
209 
+
211  ObjLoadStateTy GetObjState () const;
+
213  bool IsObjInvalid () const { return GetObjState() == OLS_INVALID; }
+
214 
+
217  std::list<XPLMObjectRef> GetAllObjRefs ();
+
218 
+
220  void IncRefCnt () { ++refCnt; }
+
222  void DecRefCnt ();
+
224  unsigned GetRefCnt () const { return refCnt; }
+
225 
+
227  static float GarbageCollection (float inElapsedSinceLastCall,
+
228  float inElapsedTimeSinceLastFlightLoop,
+
229  int inCounter,
+
230  void * inRefcon);
+
231 
+
232 protected:
+
234  void Unload ();
+
236  float FetchVertOfsFromObjFile () const;
+
237 };
+
238 
+
240 typedef std::map<std::string,CSLModel> mapCSLModelTy;
+
241 
+
243 typedef std::multimap<unsigned long,std::pair<CSLModel*,const CSLModel::MatchCritTy*> > mmapCSLModelPTy;
+
244 
+
245 //
+
246 // MARK: Global Functions
+
247 //
+
248 
+
250 void CSLModelsInit ();
+
251 
+
253 void CSLModelsCleanup ();
+
254 
+
259 const char* CSLModelsLoad (const std::string& _path,
+
260  int _maxDepth = 5);
+
261 
+
265 CSLModel* CSLModelById (const std::string& _cslId,
+
266  mapCSLModelTy::iterator* _pOutIter = nullptr);
+
267 
+
271 CSLModel* CSLModelByKey(const std::string& _cslKey,
+
272  mapCSLModelTy::iterator* _pOutIter = nullptr);
+
273 
+
281 int CSLModelMatching (const std::string& _type,
+
282  const std::string& _airline,
+
283  const std::string& _livery,
+
284  CSLModel* &pModel);
+
285 
+
286 } // namespace XPMP2
+
287 
+
288 #endif
Represetns a CSL model as it is saved on disk.
Definition: CSLModels.h:113
-
bool IsObjInvalid() const
(Minimum) )State of the X-Plane object: Is it invalid?
Definition: CSLModels.h:212
+
bool IsObjInvalid() const
(Minimum) )State of the X-Plane object: Is it invalid?
Definition: CSLModels.h:213
std::string cslId
full id: package name / shortId, expected to be unique
Definition: CSLModels.h:132
const Doc8643 * doc8643
Proper Doc8643 entry for this model.
Definition: CSLModels.h:155
listCSLObjTy listObj
list of objects representing this model
Definition: CSLModels.h:140
+
int GetNumEngines() const
Definition: CSLModels.h:203
int xsbAircraftLn
Line number in the xsb_aircraft.txt file where the model definition starts.
Definition: CSLModels.h:149
unsigned refCnt
Reference counter: Number of Aircraft actively using this model.
Definition: CSLModels.h:159
-
char GetClassEngType() const
Definition: CSLModels.h:203
+
char GetClassEngType() const
Definition: CSLModels.h:204
char GetClassNumEng() const
Definition: CSLModels.h:202
std::string shortId
short id, just an arbitrary label read from xsb_aircraft.txt::OBJ8_AIRCRAFT
Definition: CSLModels.h:130
const std::string & GetId() const
full id: package name / shortId, expected to be unique
Definition: CSLModels.h:190
@@ -244,12 +246,12 @@
std::future< float > futVertOfs
future for asynchronously reading vertOfs
Definition: CSLModels.h:163
MatchCritVecTy vecMatchCrit
further match-relevant fields like airline and livery can be a list
Definition: CSLModels.h:138
std::string icaoType
ICAO aircraft type this model represents: xsb_aircraft.txt::ICAO
Definition: CSLModels.h:153
-
float FetchVertOfsFromObjFile() const
Read the obj files to fill CSLModel::vertOfs.
Definition: CSLModels.cpp:524
+
float FetchVertOfsFromObjFile() const
Read the obj files to fill CSLModel::vertOfs.
Definition: CSLModels.cpp:523
const std::string & GetLivery() const
Livery code this model represents: xsb_aircraft.txt::LIVERY
Definition: CSLModels.h:194
ObjLoadStateTy GetObjState() const
(Minimum) )State of the X-Plane objects: Is it being loaded or available?
Definition: CSLModels.cpp:435
const std::string & GetIcaoType() const
ICAO aircraft type this model represents: xsb_aircraft.txt::ICAO
Definition: CSLModels.h:192
bool IsValid() const
Minimum requirement for using this object is: id, type, path.
Definition: CSLModels.h:187
-
bool HasRotor() const
Definition: CSLModels.h:204
+
bool HasRotor() const
Definition: CSLModels.h:205
char GetClassType() const
Definition: CSLModels.h:201
std::string modelName
name, formed by last part of path plus id
Definition: CSLModels.h:134
void CompModelName()
Puts together the model name string from a path component and shortId
Definition: CSLModels.cpp:418
@@ -258,19 +260,19 @@
const std::string & GetShortId() const
short id, just an arbitrary label read from xsb_aircraft.txt::OBJ8_AIRCRAFT
Definition: CSLModels.h:189
int GetRelatedGrp() const
"related" group for this model (a group of alike plane models), or 0
Definition: CSLModels.h:195
int related
"related" group for this model (a group of alike plane models), or 0
Definition: CSLModels.h:157
-
float GetVertOfs() const
Vertical Offset to be applied to aircraft model.
Definition: CSLModels.h:207
-
void Unload()
Unload all objects.
Definition: CSLModels.cpp:516
+
float GetVertOfs() const
Vertical Offset to be applied to aircraft model.
Definition: CSLModels.h:208
+
void Unload()
Unload all objects.
Definition: CSLModels.cpp:515
const char * GetWTC() const
Wake turbulence category.
Definition: CSLModels.h:200
std::vector< MatchCritTy > MatchCritVecTy
Vector of match-relevant fields.
Definition: CSLModels.h:127
std::string GetKeyString() const
compiles the string used as key in the CSL model map
Definition: CSLModels.cpp:429
float vertOfs
Vertical offset to be applied [m].
Definition: CSLModels.h:142
-
void IncRefCnt()
Increase the reference counter for Aircraft usage.
Definition: CSLModels.h:219
+
void IncRefCnt()
Increase the reference counter for Aircraft usage.
Definition: CSLModels.h:220
CSLModel & operator=(CSLModel &&o)=default
bool bVertOfsReadFromFile
Shall we try reading vertOfs from the OBJ8 file if we need this a/c?
Definition: CSLModels.h:144
void DecRefCnt()
Decrease the reference counter for Aircraft usage.
Definition: CSLModels.cpp:484
float refZeroTs
Time point when refCnt reached 0 (used in garbage collection, in terms of XP's total running time)
Definition: CSLModels.h:161
CSLModel(CSLModel &&o)=default
Generate standard move constructor.
-
unsigned GetRefCnt() const
Current reference counter.
Definition: CSLModels.h:223
+
unsigned GetRefCnt() const
Current reference counter.
Definition: CSLModels.h:224
std::string xsbAircraftPath
Path to the xsb_aircraft.txt file from where this model is loaded.
Definition: CSLModels.h:147
const std::string & GetModelName() const
name, formed by last part of path plus id (human readable, but not guaranteed to be unique)
Definition: CSLModels.h:191
void AddMatchCriteria(const std::string &_type, const MatchCritTy &_matchCrit, int lnNr)
Set the a/c type model and add other match criteria.
Definition: CSLModels.cpp:387
@@ -300,15 +302,15 @@
void DetermineWhichObjToLoad()
Determine which file to load and if we need a copied .obj file.
Definition: CSLModels.cpp:112
bool CopyAndReplace()
Perform the copy-on-load functionality, replacing dataRefs and textures, expected to be called via st...
Definition: CSLCopy.cpp:73
std::string texture
texture file if defined, to be used in the TEXTURE line of the .obj file
Definition: CSLModels.h:45
-
Definition: XPMPAircraft.h:41
-
int CSLModelMatching(const std::string &_type, const std::string &_airline, const std::string &_livery, CSLModel *&pModel)
Find a matching model.
Definition: CSLModels.cpp:1359
-
void CSLModelsCleanup()
Grace cleanup.
Definition: CSLModels.cpp:1062
-
std::multimap< unsigned long, std::pair< CSLModel *, const CSLModel::MatchCritTy * > > mmapCSLModelPTy
Multimap of references to CSLModels and match criteria for matching purposes.
Definition: CSLModels.h:242
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
+
int CSLModelMatching(const std::string &_type, const std::string &_airline, const std::string &_livery, CSLModel *&pModel)
Find a matching model.
Definition: CSLModels.cpp:1358
+
void CSLModelsCleanup()
Grace cleanup.
Definition: CSLModels.cpp:1061
+
std::multimap< unsigned long, std::pair< CSLModel *, const CSLModel::MatchCritTy * > > mmapCSLModelPTy
Multimap of references to CSLModels and match criteria for matching purposes.
Definition: CSLModels.h:243
std::pair< std::string, std::string > pairOfStrTy
Definition: CSLModels.h:109
-
CSLModel * CSLModelById(const std::string &_cslId, mapCSLModelTy::iterator *_pOutIter)
Find a model by unique id.
Definition: CSLModels.cpp:1107
+
CSLModel * CSLModelById(const std::string &_cslId, mapCSLModelTy::iterator *_pOutIter)
Find a model by unique id.
Definition: CSLModels.cpp:1106
std::list< CSLObj > listCSLObjTy
List of objects.
Definition: CSLModels.h:107
-
std::map< std::string, CSLModel > mapCSLModelTy
Map of CSLModels (owning the object), ordered by related group / type.
Definition: CSLModels.h:239
-
void CSLModelsInit()
Initialization.
Definition: CSLModels.cpp:1043
+
std::map< std::string, CSLModel > mapCSLModelTy
Map of CSLModels (owning the object), ordered by related group / type.
Definition: CSLModels.h:240
+
void CSLModelsInit()
Initialization.
Definition: CSLModels.cpp:1042
ObjLoadStateTy
State of the X-Plane object: Is it being loaded or available?
Definition: CSLModels.h:30
@ OLS_COPYING
creating a new .obj file copy, replacing dataRefs and textures
Definition: CSLModels.h:33
@ OLS_UNAVAIL
Not yet tried loading the CSL object.
Definition: CSLModels.h:32
@@ -316,17 +318,18 @@
@ OLS_LOADING
async load underway
Definition: CSLModels.h:34
@ OLS_AVAILABLE
X-Plane object available in xpObj
Definition: CSLModels.h:35
std::map< std::string, std::string > mapCSLPackageTy
Map of CSLPackages: Maps an id to the base path (path ends on forward slash)
Definition: CSLModels.h:27
-
CSLModel * CSLModelByKey(const std::string &_cslKey, mapCSLModelTy::iterator *_pOutIter)
Find a model by (even more) unique key.
Definition: CSLModels.cpp:1131
-
const char * CSLModelsLoad(const std::string &_path, int _maxDepth)
Read the CSL Models found in the given path and below.
Definition: CSLModels.cpp:1078
+
CSLModel * CSLModelByKey(const std::string &_cslKey, mapCSLModelTy::iterator *_pOutIter)
Find a model by (even more) unique key.
Definition: CSLModels.cpp:1130
+
const char * CSLModelsLoad(const std::string &_path, int _maxDepth)
Read the CSL Models found in the given path and below.
Definition: CSLModels.cpp:1077
Combines match-relevant fields (beside ICAO a/c type)
Definition: CSLModels.h:116
std::string livery
Livery code this model represents: xsb_aircraft.txt::LIVERY
Definition: CSLModels.h:120
bool merge(const MatchCritTy &o)
Decide which criteria is better and keep that.
Definition: CSLModels.cpp:321
std::string icaoAirline
ICAO Airline code this model represents: xsb_aircraft.txt::AIRLINE
Definition: CSLModels.h:118
Represents a line in the Doc8643.txt file, of which we use only classification and WTC.
Definition: RelatedDoc8643.h:62
-
bool HasRotor() const
Definition: RelatedDoc8643.h:77
+
bool HasRotor() const
Definition: RelatedDoc8643.h:78
+
int GetNumEngines() const
Definition: RelatedDoc8643.h:76
char wtc[4]
Definition: RelatedDoc8643.h:65
char GetClassNumEng() const
Definition: RelatedDoc8643.h:75
-
char GetClassEngType() const
Definition: RelatedDoc8643.h:76
+
char GetClassEngType() const
Definition: RelatedDoc8643.h:77
char GetClassType() const
Definition: RelatedDoc8643.h:74
diff --git a/docs/html/Client_8cpp.html b/docs/html/Client_8cpp.html index 037906ad..c4c2f925 100644 --- a/docs/html/Client_8cpp.html +++ b/docs/html/Client_8cpp.html @@ -95,16 +95,16 @@

 Called at the end of each flight loop processing: Release the data lock. More...
 
void ClientProcAcDetails (const std::uint32_t _from[4], size_t _msgLen, const XPMP2::RemoteMsgAcDetailTy &_msgAcDetails)
 Handle A/C Details messages, called by XPMP2 via callback. More...
 Handle A/C Details messages, called by XPMP2 via callback. More...
 
void ClientProcAcPosUpdate (const std::uint32_t _from[4], size_t _msgLen, const XPMP2::RemoteMsgAcPosUpdateTy &_msgAcPosUpdate)
 Handle A/C Position Update message, called by XPMP2 via callback. More...
 Handle A/C Position Update message, called by XPMP2 via callback. More...
 
void ClientProcAcAnim (const std::uint32_t _from[4], size_t _msgLen, const XPMP2::RemoteMsgAcAnimTy &_msgAcAnim)
 Handle A/C Animation dataRef messages, called by XPMP2 via callback. More...
 Handle A/C Animation dataRef messages, called by XPMP2 via callback. More...
 
void ClientProcAcRemove (const std::uint32_t _from[4], size_t _msgLen, const XPMP2::RemoteMsgAcRemoveTy &_msgAcRemove)
 Handle A/C Removal message, called by XPMP2 via callback. More...
 Handle A/C Removal message, called by XPMP2 via callback. More...
 
void ClientInit ()
 Initializes the module. More...
+ + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+ + + + + + + + + +
+ +
+
FMOD_Logo.cpp File Reference
+
+
+ +

Compressed version of the FMOD logo with code to create a texture ID in X-Plane for display with Dear ImGui. +More...

+
#include "FMOD_Logo.h"
+#include <cassert>
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include "XPLMGraphics.h"
+
+ + + +

+Namespaces

 
+ + + + + + + +

+Functions

uint8_t * FMODLogo::LoadRGBA (bool bBlack=true)
 Load the data of the FMOD logo, expanded into RGBA data. More...
 
bool FMODLogo::GetTexture (int &texId, bool bBlack=true)
 The one "public" function to return a texture id for the logo. More...
 
+ + + + + + + +

+Variables

constexpr size_t FMODLogo::RLE_SIZE = 5527
 number of array entries in the RLE array More...
 
const uint16_t FMODLogo::ALPHA_RLE [RLE_SIZE]
 Run-length encoded data of the Alpha value of each pixel in the FMOD logo. More...
 
+

Detailed Description

+

Compressed version of the FMOD logo with code to create a texture ID in X-Plane for display with Dear ImGui.

+
See also
FMOD attribution requirements
+
+FMOD Logo download
+

The FMOD logo is essential a single-color image, either black (RGB 0x06 0x08 0x0b) or white (0xff 0xff 0xff), with only the alpha value varying across the image. The below array ALPHA_RLE is a run-length encoded dump of these alpha values. The provided functions recreate the full RGBA data, so that it can be used with OpenGL functionality to be turned into a texture.

+

Usage
+

        #include "FMOD_Logo.inc"
+        ...
+        int logoId = 0;
+        if (FMODLogo::GetTexture(logoId)) {
+            ImGui::Image((void*)(intptr_t)logoId, ImVec2(FMODLogo::IMG_WIDTH, FMODLogo::IMG_HEIGHT));
+        }
+
+
Author
of the code: Birger Hoppe
+ +
+ + + + diff --git a/docs/html/FMOD__Logo_8h.html b/docs/html/FMOD__Logo_8h.html new file mode 100644 index 00000000..8bfe60ab --- /dev/null +++ b/docs/html/FMOD__Logo_8h.html @@ -0,0 +1,113 @@ + + + + + + + +XPMP2: XPMP2-Sample/lib/fmod/logo/FMOD_Logo.h File Reference + + + + + + +
+
+ + + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+
+ + + + + + + +
+
+ +
+
FMOD_Logo.h File Reference
+
+
+ +

Compressed version of the FMOD logo with code to create a texture ID in X-Plane for display with Dear ImGui. +More...

+
#include <cstdint>
+
+

Go to the source code of this file.

+ + + + +

+Namespaces

 
+ + + + + + + +

+Functions

bool FMODLogo::GetTexture (int &texId, bool bBlack=true)
 The one "public" function to return a texture id for the logo. More...
 
uint8_t * FMODLogo::LoadRGBA (bool bBlack=true)
 Load the data of the FMOD logo, expanded into RGBA data. More...
 
+ + + + + + + + + + +

+Variables

constexpr int FMODLogo::IMG_WIDTH = 728
 Logo image width. More...
 
constexpr int FMODLogo::IMG_HEIGHT = 192
 Logo image height. More...
 
constexpr int FMODLogo::IMG_SIZE = IMG_WIDTH * IMG_HEIGHT
 Logo image size in number of pixels. More...
 
+

Detailed Description

+

Compressed version of the FMOD logo with code to create a texture ID in X-Plane for display with Dear ImGui.

+
See also
FMOD attribution requirements
+
+FMOD Logo download
+

The FMOD logo is essential a single-color image, either black (RGB 0x06 0x08 0x0b) or white (0xff 0xff 0xff), with only the alpha value varying across the image. The below array ALPHA_RLE is a run-length encoded dump of these alpha values. The provided functions recreate the full RGBA data, so that it can be used with OpenGL functionality to be turned into a texture.

+

Usage
+

        #include "FMOD_Logo.h"
+        ...
+        int logoId = 0;
+        if (FMODLogo::GetTexture(logoId)) {
+            ImGui::Image((void*)(intptr_t)logoId, ImVec2(FMODLogo::IMG_WIDTH, FMODLogo::IMG_HEIGHT));
+        }
+
+
Author
of the code: Birger Hoppe
+ +
+ + + + diff --git a/docs/html/FMOD__Logo_8h_source.html b/docs/html/FMOD__Logo_8h_source.html new file mode 100644 index 00000000..0df2ac9f --- /dev/null +++ b/docs/html/FMOD__Logo_8h_source.html @@ -0,0 +1,79 @@ + + + + + + + +XPMP2: XPMP2-Sample/lib/fmod/logo/FMOD_Logo.h Source File + + + + + + +
+
+ + + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+
+ + + + + + + +
+
+
+
FMOD_Logo.h
+
+
+Go to the documentation of this file.
1 
+
43 #pragma once
+
44 
+
45 #include <cstdint>
+
46 
+
47 namespace FMODLogo {
+
48 
+
49 // Dimensions of the FMOD logo
+
50 constexpr int IMG_WIDTH = 728;
+
51 constexpr int IMG_HEIGHT = 192;
+
52 constexpr int IMG_SIZE = IMG_WIDTH * IMG_HEIGHT;
+
53 
+
60 bool GetTexture (int& texId, bool bBlack = true);
+
61 
+
70 uint8_t* LoadRGBA (bool bBlack = true);
+
71 
+
72 }; // namespace FMODLogo
+
Definition: FMOD_Logo.cpp:63
+
constexpr int IMG_WIDTH
Logo image width.
Definition: FMOD_Logo.h:50
+
constexpr int IMG_HEIGHT
Logo image height.
Definition: FMOD_Logo.h:51
+
constexpr int IMG_SIZE
Logo image size in number of pixels.
Definition: FMOD_Logo.h:52
+
uint8_t * LoadRGBA(bool bBlack)
Load the data of the FMOD logo, expanded into RGBA data.
Definition: FMOD_Logo.cpp:419
+
bool GetTexture(int &id, bool bBlack)
The one "public" function to return a texture id for the logo.
Definition: FMOD_Logo.cpp:459
+
+ + + + diff --git a/docs/html/Map_8cpp.html b/docs/html/Map_8cpp.html index 2b5d5ddf..d5cf6072 100644 --- a/docs/html/Map_8cpp.html +++ b/docs/html/Map_8cpp.html @@ -60,6 +60,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

@@ -231,7 +232,7 @@

XPMP2 creates a separate Map Layer named after the plugin for this purposes. By default, the map functionality is enabled including label writing.

+

XPMP2 creates a separate Map Layer named after the plugin for this purposes. By default, the map functionality is enabled including label writing.

diff --git a/docs/html/Map_8h.html b/docs/html/Map_8h.html index 54ecd2f1..6662941f 100644 --- a/docs/html/Map_8h.html +++ b/docs/html/Map_8h.html @@ -60,6 +60,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/Map_8h_source.html b/docs/html/Map_8h_source.html index b5c90ab7..2f4488b8 100644 --- a/docs/html/Map_8h_source.html +++ b/docs/html/Map_8h_source.html @@ -63,7 +63,7 @@
36 }
37 
38 #endif
-
Definition: XPMPAircraft.h:41
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
void MapInit()
Initialize the module.
Definition: Map.cpp:371
void MapCleanup()
Grace cleanup.
Definition: Map.cpp:382
std::map< std::string, XPLMMapLayerID > mapMapLayerIDTy
A map holding our layer identifier, indexed by the map's name.
Definition: Map.h:27
diff --git a/docs/html/Network_8cpp.html b/docs/html/Network_8cpp.html index 578e3ea4..17ab2e92 100644 --- a/docs/html/Network_8cpp.html +++ b/docs/html/Network_8cpp.html @@ -62,6 +62,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/Network_8h.html b/docs/html/Network_8h.html index 53656aee..b3fcd125 100644 --- a/docs/html/Network_8h.html +++ b/docs/html/Network_8h.html @@ -88,6 +88,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/Network_8h_source.html b/docs/html/Network_8h_source.html index 27625cbf..e166a197 100644 --- a/docs/html/Network_8h_source.html +++ b/docs/html/Network_8h_source.html @@ -274,7 +274,7 @@
virtual void GetAddrHints(struct addrinfo &hints)
Sets flags to AI_PASSIVE, AF_INET, SOCK_DGRAM, IPPROTO_UDP.
Definition: Network.cpp:456
UDPReceiver(const std::string &_addr, int _port, size_t _bufSize=512, unsigned _timeOut_ms=0)
Constructor creates a socket and binds it to the given address.
Definition: Network.h:132
UDPReceiver()
Default constructor is not doing anything.
Definition: Network.h:130
-
Definition: XPMPAircraft.h:41
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
const std::vector< InetAddrTy > & NetwGetLocalAddresses()
Return all local addresses (also cached locally)
Definition: Network.cpp:820
bool NetwIsLocalAddr(const InetAddrTy &addr)
Is given address a local one?
Definition: Network.cpp:899
constexpr SOCKET INVALID_SOCKET
Definition: Network.h:46
diff --git a/docs/html/RelatedDoc8643_8cpp.html b/docs/html/RelatedDoc8643_8cpp.html index 0c4e07e2..51ed6f9d 100644 --- a/docs/html/RelatedDoc8643_8cpp.html +++ b/docs/html/RelatedDoc8643_8cpp.html @@ -60,6 +60,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/RelatedDoc8643_8h.html b/docs/html/RelatedDoc8643_8h.html index f7cdd1c2..66906ff3 100644 --- a/docs/html/RelatedDoc8643_8h.html +++ b/docs/html/RelatedDoc8643_8h.html @@ -70,6 +70,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 
+

@@ -109,7 +110,7 @@

Handling the related.txt file for creating groups of similar looking aircraft types, and Doc8643, the official list of ICAO aircraft type codes.

A related group is declared simply by a line of ICAO a/c type codes read from the file. Internally, the group is just identified by its line number in related.txt. So the group "44" might be "A306 A30B A310", the Airbus A300 series.

Doc8643 is a list of information maintained by the ICAO to list all registered aircraft types. Each type designator can appear multiple times in the dataset for slightly differing models, but the classification und the WTC will be the same in all those listing.
- XPMP2 is only interested in type designator, classification, and WTC.

Author
Birger Hoppe
+ XPMP2 is only interested in type designator, classification, and WTC.

Author
Birger Hoppe

Namespaces

 XPMP2
 Defined by FMOD.
 
+

diff --git a/docs/html/Remote_8h.html b/docs/html/Remote_8h.html index 46b64826..ef145d5c 100644 --- a/docs/html/Remote_8h.html +++ b/docs/html/Remote_8h.html @@ -82,6 +82,7 @@

Namespaces

 XPMP2
 Defined by FMOD.
 

diff --git a/docs/html/Remote_8h_source.html b/docs/html/Remote_8h_source.html index 978add51..be1e0947 100644 --- a/docs/html/Remote_8h_source.html +++ b/docs/html/Remote_8h_source.html @@ -168,8 +168,8 @@
185 
186 }
187 #endif
-
unsigned XPMPPlaneID
Unique ID for an aircraft created by a plugin.
Definition: XPMPMultiplayer.h:243
-
Actual representation of all aircraft in XPMP2.
Definition: XPMPAircraft.h:147
+
unsigned XPMPPlaneID
Unique ID for an aircraft created by a plugin.
Definition: XPMPMultiplayer.h:252
+
Actual representation of all aircraft in XPMP2.
Definition: XPMPAircraft.h:181
Represetns a CSL model as it is saved on disk.
Definition: CSLModels.h:113
Animation dataRef requires a special queue data type as each msg element is already of variable lengt...
Definition: Remote.h:106
RmtDataAcAnimTy(XPMPPlaneID _id)
Default constructor only sets message type and id, makes sure data is initialized.
Definition: Remote.h:116
@@ -195,7 +195,7 @@
void send(UDPMulticast &_mc)
send the message (if there is any), then reset the buffer
Definition: Remote.cpp:465
void * pMsg
points to the actual message buffer of size glob.remoteBufSize
Definition: Remote.h:132
UDP Multicast, always binding to INADDR_ANY.
Definition: Network.h:145
-
Definition: XPMPAircraft.h:41
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
std::map< XPMPPlaneID, RmtAcCacheTy > mapRmtAcCacheTy
Defines a map with the plane id as key and the aboce cache structure as payload.
Definition: Remote.h:63
void RemoteAcClearAll()
Informs us that there are no more aircraft, clear our caches!
Definition: Remote.cpp:1312
void RemoteAcEnqueueDone()
Informs us that all a/c have been processed: All pending messages to be sent now.
Definition: Remote.cpp:1251
@@ -216,8 +216,8 @@
std::unique_ptr< RmtDataAcAnimTy > ptrRmtDataAcAnimTy
Smart pointer to XPMP2::RmtDataAcAnimTy.
Definition: Remote.h:122
void RemoteInit()
Initialize the module.
Definition: Remote.cpp:1058
RmtDataEnqeueTy< RemoteAcPosUpdateTy, RMT_MSG_AC_POS_UPDATE > RmtDataAcPosUpdateTy
A/C Position Update queue type.
Definition: Remote.h:99
-
DR_VALS
The dataRefs provided by XPMP2 to the CSL models.
Definition: XPMPAircraft.h:56
-
@ V_COUNT
always last, number of dataRefs XPMP2 pre-defines
Definition: XPMPAircraft.h:106
+
DR_VALS
The dataRefs provided by XPMP2 to the CSL models.
Definition: XPMPAircraft.h:90
+
@ V_COUNT
always last, number of dataRefs XPMP2 pre-defines
Definition: XPMPAircraft.h:140
RmtDataEnqeueTy< RemoteAcDetailTy, RMT_MSG_AC_DETAILED > RmtDataAcDetailTy
A/C Detail queue type.
Definition: Remote.h:98
A/C animation dataRef changes.
Definition: XPMPRemote.h:329
size_t msgSize() const
current message size
Definition: XPMPRemote.h:347
diff --git a/docs/html/Sound_8cpp.html b/docs/html/Sound_8cpp.html new file mode 100644 index 00000000..43d52bb4 --- /dev/null +++ b/docs/html/Sound_8cpp.html @@ -0,0 +1,755 @@ + + + + + + + +XPMP2: src/Sound.cpp File Reference + + + + + + +
+
+ + + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+
+ + + + + + + +
+
+ +
+
Sound.cpp File Reference
+
+
+ +

Sound for aircraft, based on the FMOD library. +More...

+
#include "XPMP2.h"
+#include "fmod_errors.h"
+
+ + + + + + + + + + + + + +

+Classes

struct  XPMP2::FMOD_10830_ADVANCEDSETTINGS
 FMOD 1.08.30 version of FMOD_ADVANCEDSETTINGS. More...
 
struct  XPMP2::SoundDefTy
 Definition of how sound is handled based on dataRef values (type) More...
 
class  XPMP2::FmodError
 Exception class to pass on error information. More...
 
class  XPMP2::SoundFile
 Represents a sound file. More...
 
+ + + + +

+Namespaces

 XPMP2
 Defined by FMOD.
 
+ + + + + + + + + + + + + + +

+Macros

#define FMOD_TEST(fmodCall)
 Log an error if fmodRes is not FMOD_OK More...
 
#define FMOD_CATCH   catch (const FmodError& e) { e.LogErr(); }
 Standard catch clause to handle FmodError exceptions by just logging them. More...
 
#define FMOD_LOG(fmodCall)
 Just log an error without raising an exception. More...
 
#define ADD_SND(s, f, l)   if (!XPMPSoundAdd(s,f,l)[0]) ++n;
 
#define ADD_CONE(s, f, l, cd, cp, cia, coa, cov)   if (!XPMPSoundAdd(s,f,l,cd,cp,cia,coa,cov)[0]) ++n;
 
+ + + + +

+Typedefs

typedef std::map< std::string, SoundFile > XPMP2::mapSoundTy
 Map of all sounds, indexed by a sound name (type) More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

FMOD_VECTOR XPMP2::HeadPitch2Vec (const float head, const float pitch)
 Convert heading/pitch to normalized x/y/z vector. More...
 
bool XPMP2::UseOldFmod ()
 Use pre-v2 FMOD version structures? More...
 
FMOD_RESULT F_CALLBACK XPMP2::SoundLogCB (FMOD_DEBUG_FLAGS flags, const char *file, int line, const char *func, const char *message)
 Callback function called by FMOD for logging purposes. More...
 
void XPMP2::SoundLogEnable (bool bEnable=true)
 Enables/disables FMOD logging. More...
 
FMOD_CHANNELGROUP * XPMP2::SoundGetMasterChn ()
 Get the FMOD system's master channel group, or nullptr More...
 
SoundFile * XPMP2::SoundGetSoundFile (FMOD_CHANNEL *pChn)
 Get pointer to Sound File that created the channel. More...
 
bool XPMP2::SoundIsChnValid (FMOD_CHANNEL *pChn)
 Is the channel still payling / is it valid? More...
 
template<class T_ADVSET >
void XPMP2::SoundSetFmodSettings (T_ADVSET &advSet)
 Helper functon to set FMOD settings. More...
 
const char * XPMP2::SoundEventTxt (Aircraft::SoundEventsTy e)
 Return a text for the values of Aircraft::SoundEventsTy. More...
 
bool XPMP2::SoundInit ()
 Initialize the sound module and load the sounds. More...
 
void XPMP2::SoundUpdatesDone ()
 Tell FMOD that all updates are done. More...
 
void XPMP2::SoundCleanup ()
 Graceful shoutdown. More...
 
bool XPMPSoundEnable (bool bEnable)
 Enable/Disable Sound. More...
 
bool XPMPSoundIsEnabled ()
 Is Sound enabled? More...
 
void XPMPSoundSetMasterVolume (float fVol)
 Set Master Volume. More...
 
void XPMPSoundMute (bool bMute)
 Mute all sounds (temporarily) More...
 
const char * XPMPSoundAdd (const char *sName, const char *filePath, bool bLoop, float coneDir, float conePitch, float coneInAngle, float coneOutAngle, float coneOutVol)
 Add a sound that can later be referenced from an XPMP2::Aircraft. More...
 
const char * XPMPSoundEnumerate (const char *prevName, const char **ppFilePath)
 Enumerate all sounds, including the internal ones. More...
 
+ + + + + + + + + + + + + +

+Variables

constexpr int XPMP2::EXP_COMP_SKIP_CYCLES = 10
 In how many cycles to skip expensive computations? More...
 
constexpr int XPMP2::FMOD_NUM_VIRT_CHANNELS = 1000
 Number of virtual channels during initialization. More...
 
constexpr float XPMP2::FMOD_3D_MAX_DIST = 10000.0f
 Value used for 3D max distance, which doesn't have much of a function for the inverse roll-off model used here. More...
 
constexpr float XPMP2::FMOD_LOW_PASS_GAIN = 0.2f
 Gain used when activating Low Pass filter. More...
 
+

Detailed Description

+

Sound for aircraft, based on the FMOD library.

+
Note
Audio Engine is FMOD Core API by Firelight Technologies Pty Ltd. Understand FMOD licensing and attribution requirements first!
+ Sound support is only included if built with CMake cache entry INCLUDE_FMOD_SOUND.
+
+
See also
FMOD Core API Guide https://fmod.com/docs/2.02/api/core-guide.html
+

FMOD's C interface is used exclusively (and not the C++ ABI). This is to ease handling of dynamic libaries between versions (XP11 is using FMOD 1.x while XP12 has upgraded to 2.x) and allows compiling with MingW.

+

Some functionality looks like immitating FMOD's SoundGroup, but 3D positioning was unstable when used via SoundGroup, and the cone functionality did not work at all, so this file handles all sound channels individually.

Note
If linking to the logging version of the FMOD API library (the one ending in L) and specifying a config item log_level of 0 = Debug (see XPMPIntPrefsFuncTy) while initializing sound, ie. typically during the first call to XPMPMultiplayerInit(), then FMOD logging output is added to X-Plane's Log.txt.
+
Author
Birger Hoppe
+ +

Class Documentation

+ +

◆ XPMP2::FMOD_10830_ADVANCEDSETTINGS

+ +
+
+ + + + +
struct XPMP2::FMOD_10830_ADVANCEDSETTINGS
+
+

FMOD 1.08.30 version of FMOD_ADVANCEDSETTINGS.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Class Members
+char ** +ASIOChannelList +
+int +ASIONumChannels +
+FMOD_SPEAKER * +ASIOSpeakerList +
+int +cbSize +
+unsigned int +commandQueueSize +
+unsigned int +defaultDecodeBufferSize +
+float +distanceFilterCenterFreq +
+int +DSPBufferPoolSize +
+unsigned int +geometryMaxFadeTime +
+float +HRTFFreq +
+float +HRTFMaxAngle +
+float +HRTFMinAngle +
+int +maxADPCMCodecs +
+int +maxAT9Codecs +
+int +maxFADPCMCodecs +
+int +maxMPEGCodecs +
+int +maxPCMCodecs +
+int +maxVorbisCodecs +
+int +maxXMACodecs +
+unsigned short +profilePort +
+unsigned int +randomSeed +
+FMOD_DSP_RESAMPLER +resamplerMethod +
+int +reverb3Dinstance +
+unsigned int +stackSizeMixer +
+unsigned int +stackSizeNonBlocking +
+unsigned int +stackSizeStream +
+float +vol0virtualvol +
+ +
+
+

Macro Definition Documentation

+ +

◆ ADD_CONE

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#define ADD_CONE( s,
 f,
 l,
 cd,
 cp,
 cia,
 coa,
 cov 
)   if (!XPMPSoundAdd(s,f,l,cd,cp,cia,coa,cov)[0]) ++n;
+
+ +
+
+ +

◆ ADD_SND

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
#define ADD_SND( s,
 f,
 
)   if (!XPMPSoundAdd(s,f,l)[0]) ++n;
+
+ +
+
+ +

◆ FMOD_CATCH

+ +
+
+ + + + +
#define FMOD_CATCH   catch (const FmodError& e) { e.LogErr(); }
+
+ +

Standard catch clause to handle FmodError exceptions by just logging them.

+ +
+
+ +

◆ FMOD_LOG

+ +
+
+ + + + + + + + +
#define FMOD_LOG( fmodCall)
+
+Value:
{ \
+
if ((XPMP2::gFmodRes = (fmodCall)) != FMOD_OK) \
+
XPMP2::FmodError(#fmodCall, XPMP2::gFmodRes, __LINE__, __func__).LogErr(); \
+
}
+
+

Just log an error without raising an exception.

+ +
+
+ +

◆ FMOD_TEST

+ +
+
+ + + + + + + + +
#define FMOD_TEST( fmodCall)
+
+Value:
{ \
+
if ((gFmodRes = (fmodCall)) != FMOD_OK) \
+
throw FmodError(#fmodCall, gFmodRes, __LINE__, __func__); \
+
}
+
+

Log an error if fmodRes is not FMOD_OK

+ +
+
+

Function Documentation

+ +

◆ XPMPSoundAdd()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
const char* XPMPSoundAdd (const char * sName,
const char * filePath,
bool bLoop,
float coneDir = NAN,
float conePitch = NAN,
float coneInAngle = NAN,
float coneOutAngle = NAN,
float coneOutVol = NAN 
)
+
+ +

Add a sound that can later be referenced from an XPMP2::Aircraft.

+

XPMP2 loads a number of default sounds from what X-Plane ships. This function allows to add your own. It will try to load the sound immediately.

Parameters
+ + + + + + + + + +
sNameA descriptive name, used as a key to refer to this sound later
filePathPath to the sound file; a relative path is relative to resourceDir as set by XPMPMultiplayerInit()
bLoopIs this sound to be played in a loop?
coneDir[opt] Which direction relative to plane's heading does the cone point to? (180 would be typical for jet engines)
conePitch[opt] Which pitch does the cone point to (up/down)? (0 would be typical, ie. level with the plane)
coneInAngle[opt] Inside cone angle. This is the angle spread within which the sound is unattenuated.
coneOutAngle[opt] Outside cone angle. This is the angle spread outside of which the sound is attenuated to its coneOutVol.
coneOutVol[opt] Cone outside volume.
+
+
+
Returns
Empty string in case of success, otherwise a human-readable error message.
+ +
+
+ +

◆ XPMPSoundEnable()

+ +
+
+ + + + + + + + +
bool XPMPSoundEnable (bool bEnable = true)
+
+ +

Enable/Disable Sound.

+

Enable or disable sound support. The default on startup is controlled by the configuration item sound / activate_sound, which in turn defaults to 1.

Returns
Is sound now available? (Could still be false even in case of activation if there was a problem during sound initialization)
+ +
+
+ +

◆ XPMPSoundEnumerate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const char* XPMPSoundEnumerate (const char * prevName,
const char ** ppFilePath = nullptr 
)
+
+ +

Enumerate all sounds, including the internal ones.

+
Parameters
+ + + +
prevNamenullptr or empty string to start from beginning, last returned name to continue with next sound
[out]ppFilePath(optional) Receives pointer to file path
+
+
+
Returns
Next sound's name.
+
Note
String pointers can change any frame. If you want to use the strings longer than immediately, make yourself a string copy.
+ +
+
+ +

◆ XPMPSoundIsEnabled()

+ +
+
+ + + + + + + +
bool XPMPSoundIsEnabled ()
+
+ +

Is Sound enabled?

+ +
+
+ +

◆ XPMPSoundMute()

+ +
+
+ + + + + + + + +
void XPMPSoundMute (bool bMute)
+
+ +

Mute all sounds (temporarily)

+
Parameters
+ + +
bMuteMute (true) or unmute (false)?
+
+
+ +
+
+ +

◆ XPMPSoundSetMasterVolume()

+ +
+
+ + + + + + + + +
void XPMPSoundSetMasterVolume (float fVol = 1.0f)
+
+ +

Set Master Volume.

+
Parameters
+ + +
fVolVolume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.
+
+
+ +
+
+
+ + + + diff --git a/docs/html/Sound_8h.html b/docs/html/Sound_8h.html new file mode 100644 index 00000000..8e12962b --- /dev/null +++ b/docs/html/Sound_8h.html @@ -0,0 +1,94 @@ + + + + + + + +XPMP2: src/Sound.h File Reference + + + + + + +
+
+ + + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+
+ + + + + + + +
+
+ +
+
Sound.h File Reference
+
+
+ +

Sound for aircraft, based on the FMOD library. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Namespaces

 XPMP2
 Defined by FMOD.
 
+ + + + + + + + + + +

+Functions

bool XPMP2::SoundInit ()
 Initialize the sound module and load the sounds. More...
 
void XPMP2::SoundUpdatesDone ()
 Tell FMOD that all updates are done. More...
 
void XPMP2::SoundCleanup ()
 Graceful shoutdown. More...
 
+

Detailed Description

+

Sound for aircraft, based on the FMOD library.

+
Note
Audio Engine is FMOD Core API by Firelight Technologies Pty Ltd. Understand FMOD licensing and attribution requirements first!
+ Sound support is only included if built with CMake cache entry INCLUDE_FMOD_SOUND.
+
+
Author
Birger Hoppe
+ +
+ + + + diff --git a/docs/html/Sound_8h_source.html b/docs/html/Sound_8h_source.html new file mode 100644 index 00000000..16e4b78e --- /dev/null +++ b/docs/html/Sound_8h_source.html @@ -0,0 +1,82 @@ + + + + + + + +XPMP2: src/Sound.h Source File + + + + + + +
+
+ + + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+
+ + + + + + + +
+
+
+
Sound.h
+
+
+Go to the documentation of this file.
1 
+
27 #pragma once
+
28 
+
29 // Only included if specified. Understand FMOD licensing and attribution first!
+
30 #ifdef INCLUDE_FMOD_SOUND
+
31 
+
32 namespace XPMP2 {
+
33 
+
34 
+
35 //
+
36 // MARK: Global Functions
+
37 //
+
38 
+
40 bool SoundInit ();
+
41 
+
43 void SoundUpdatesDone ();
+
44 
+
46 void SoundCleanup ();
+
47 
+
48 }
+
49 
+
50 #endif // INCLUDE_FMOD_SOUND
+
Defined by FMOD.
Definition: XPMPAircraft.h:73
+
bool SoundInit()
Initialize the sound module and load the sounds.
Definition: Sound.cpp:739
+
void SoundUpdatesDone()
Tell FMOD that all updates are done.
Definition: Sound.cpp:790
+
void SoundCleanup()
Graceful shoutdown.
Definition: Sound.cpp:832
+
+ + + + diff --git a/docs/html/Sound_8md.html b/docs/html/Sound_8md.html new file mode 100644 index 00000000..1c3a7937 --- /dev/null +++ b/docs/html/Sound_8md.html @@ -0,0 +1,52 @@ + + + + + + + +XPMP2: docs/Sound.md File Reference + + + + + + +
+
+ + + + + + +
+
XPMP2 +
+
X-Plane multiplayer library 2 - using instancing
+
+
+ + + + + + +
+
+
+
docs/Sound.md File Reference
+
+
+
+ + + + diff --git a/docs/html/Utilities_8cpp.html b/docs/html/Utilities_8cpp.html deleted file mode 100644 index a0fa93ab..00000000 --- a/docs/html/Utilities_8cpp.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - -XPMP2: src/Utilities.cpp File Reference - - - - - - -
-
- - - - - - -
-
XPMP2 -
-
X-Plane multiplayer library 2 - using instancing
-
-
- - - - - - - -
-
- -
-
Utilities.cpp File Reference
-
-
- -

Miscellaneous utility functions, including logging. -More...

-
#include "XPMP2.h"
-
- - - -

-Namespaces

 XPMP2
 
- - - -

-Macros

#define S_ISDIR(m)   (((m) & _S_IFMT) == _S_IFDIR)
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-Functions

int XPMP2::PrefsFuncIntDefault (const char *, const char *, int _default)
 Default config function just always returns the provided default value. More...
 
bool XPMP2::ExistsFile (const std::string &filename)
 Does a file path exist? More...
 
bool XPMP2::IsDir (const std::string &path)
 Is path a directory? More...
 
bool XPMP2::CreateDir (const std::string &path)
 Create directory if it does not exist. More...
 
bool XPMP2::CopyFileIfNewer (const std::string &source, const std::string &destDir)
 Copy file if source is newer or destination missing. More...
 
std::list< std::string > XPMP2::GetDirContents (const std::string &path)
 List of files in a directory (wrapper around XPLMGetDirectoryContents) More...
 
std::istream & XPMP2::safeGetline (std::istream &is, std::string &t)
 Read a line from a text file, no matter if ending on CRLF or LF. More...
 
std::string XPMP2::StripXPSysDir (const std::string &path)
 If a path starts with X-Plane's system directory it is stripped. More...
 
void XPMP2::RemoveExtension (std::string &path)
 Removes everything after the last dot, the dot including. More...
 
std::string & XPMP2::str_tolower (std::string &s)
 change a std::string to uppercase More...
 
std::vector< std::string > XPMP2::str_tokenize (const std::string s, const std::string tokens, bool bSkipEmpty=true)
 separates string into tokens More...
 
std::uint16_t XPMP2::PJWHash16 (const char *s)
 Produces a reproducible(!) hash value for strings. More...
 
float XPMP2::headDiff (float head1, float head2)
 (Shortest) difference between 2 angles: How much to turn to go from h1 to h2? More...
 
float XPMP2::GetMiscNetwTime ()
 Get synched network time from X-Plane (sim/network/misc/network_time_sec) as used in Log.txt. More...
 
const char * XPMP2::GetGraphicsDriverTxt ()
 Text string for current graphics driver in use. More...
 
bool XPMP2::CheckEverySoOften (float &_lastCheck, float _interval, float _now)
 Convenience function to check on something at most every x seconds. More...
 
const char * XPMP2::LogGetString (const char *szFile, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg, va_list args)
 Returns ptr to static buffer filled with formatted log string. More...
 
void XPMP2::LogMsg (const char *szFile, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg,...) XPMP2_FMTARGS(5)
 Log Text to log file. More...
 
- - - - - - -

-Variables

GlobVars XPMP2::glob
 The one and only global variable structure. More...
 
const char * XPMP2::LOG_LEVEL []
 
-

Detailed Description

-

Miscellaneous utility functions, including logging.

-
Author
Birger Hoppe
- -

Macro Definition Documentation

- -

◆ S_ISDIR

- -
-
- - - - - - - - -
#define S_ISDIR( m)   (((m) & _S_IFMT) == _S_IFDIR)
-
- -
-
-
- - - - diff --git a/docs/html/Utilities_8h.html b/docs/html/Utilities_8h.html deleted file mode 100644 index 6f281694..00000000 --- a/docs/html/Utilities_8h.html +++ /dev/null @@ -1,554 +0,0 @@ - - - - - - - -XPMP2: src/Utilities.h File Reference - - - - - - -
-
- - - - - - -
-
XPMP2 -
-
X-Plane multiplayer library 2 - using instancing
-
-
- - - - - - - -
-
- -
-
Utilities.h File Reference
-
-
- -

Miscellaneous utility functions, including logging. -More...

- -

Go to the source code of this file.

- - - - -

-Namespaces

 XPMP2
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-Macros

#define ERR_ASSERT   "ASSERT FAILED: %s"
 
#define ERR_EXCEPTION   "EXCEPTION CAUGHT: %s"
 
#define PATH_DELIM_STD   '/'
 
#define WHITESPACE   " \t\f\v\r\n"
 
#define XPMP2_FMTARGS(FMT)
 To apply printf-style warnings to our functions. More...
 
#define LOG_MSG(lvl, ...)
 Log a message if lvl is greater or equal currently defined log level. More...
 
#define LOG_MATCHING(lvl, ...)
 Log a message about matching if logging of model matching is enabled. More...
 
#define THROW_ERROR(...)   throw XPMP2Error(__FILE__, __LINE__, __func__, __VA_ARGS__);
 Throws an exception using XPMP2Error. More...
 
#define LOG_ASSERT(cond)
 Throw in an assert-style (logging takes place in XPMP2Error constructor) More...
 
#define CATCH_AC(ac)
 Standard catch clauses for dealing with aircraft: logs message, sets aircraft invalid. More...
 
#define STRCPY_S(dest, src)   strncpy_s(dest,sizeof(dest),src,sizeof(dest)-1)
 Simpler access to strncpy_s if dest is a char array (not a pointer!) More...
 
#define STRCPY_ATMOST(dest, src)   strncpy_s(dest,sizeof(dest),strAtMost(src,sizeof(dest)-1).c_str(),sizeof(dest)-1)
 
#define SET_THREAD_NAME(sName)
 
- - - - -

-Enumerations

enum  XPMP2::logLevelTy {
-  XPMP2::logDEBUG = 0, -XPMP2::logINFO, -XPMP2::logWARN, -XPMP2::logERR, -
-  XPMP2::logFATAL, -XPMP2::logMSG -
- }
 Logging level. More...
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-Functions

int XPMP2::PrefsFuncIntDefault (const char *, const char *, int _default)
 Default config function just always returns the provided default value. More...
 
float XPMP2::PrefsFuncFloatDefault (const char *, const char *, float _default)
 
bool XPMP2::ExistsFile (const std::string &filename)
 Does a file path exist? More...
 
bool XPMP2::IsDir (const std::string &path)
 Is path a directory? More...
 
bool XPMP2::CreateDir (const std::string &path)
 Create directory if it does not exist. More...
 
bool XPMP2::CopyFileIfNewer (const std::string &source, const std::string &destDir)
 Copy file if source is newer or destination missing. More...
 
std::list< std::string > XPMP2::GetDirContents (const std::string &path)
 List of files in a directory (wrapper around XPLMGetDirectoryContents) More...
 
std::istream & XPMP2::safeGetline (std::istream &is, std::string &t)
 Read a line from a text file, no matter if ending on CRLF or LF. More...
 
std::string XPMP2::StripXPSysDir (const std::string &path)
 If a path starts with X-Plane's system directory it is stripped. More...
 
void XPMP2::RemoveExtension (std::string &path)
 Removes everything after the last dot, the dot including. More...
 
std::string & XPMP2::str_tolower (std::string &s)
 change a std::string to uppercase More...
 
std::string & XPMP2::rtrim (std::string &s, const char *t=WHITESPACE)
 trimming of string (from right) More...
 
std::string & XPMP2::ltrim (std::string &s, const char *t=WHITESPACE)
 trimming of string (from left) More...
 
std::string & XPMP2::trim (std::string &s, const char *t=WHITESPACE)
 trimming of string (from both ends) More...
 
std::vector< std::string > XPMP2::str_tokenize (const std::string s, const std::string tokens, bool bSkipEmpty=true)
 separates string into tokens More...
 
template<class T >
XPMP2::rad2deg (const T _rad)
 Convert radians to degrees, normalized to [0..360) More...
 
template<class T >
XPMP2::deg2rad (const T _deg)
 Convert degree to radians. More...
 
template<class T >
XPMP2::sqr (const T a)
 Square. More...
 
template<class T >
XPMP2::dist (const T x1, const T y1, const T z1, const T x2, const T y2, const T z2)
 Pythagorean distance between two points in a 3-D world. More...
 
float XPMP2::atan2deg (float x, float y)
 atan2 converted to degrees: the angle between (0|0) and the given point More...
 
float XPMP2::angleLocCoord (float x1, float z1, float x2, float z2)
 Angle of line from point (x1|z1) to point (x2|z2) More...
 
float XPMP2::headDiff (float head1, float head2)
 (Shortest) difference between 2 angles: How much to turn to go from h1 to h2? More...
 
template<class numT >
numT XPMP2::headNormalize (numT _head)
 Normalize a heading value to [0..360), works for both float and double values. More...
 
float XPMP2::GetMiscNetwTime ()
 Get synched network time from X-Plane (sim/network/misc/network_time_sec) as used in Log.txt. More...
 
const char * XPMP2::GetGraphicsDriverTxt ()
 Text string for current graphics driver in use. More...
 
bool XPMP2::CheckEverySoOften (float &_lastCheck, float _interval, float _now)
 Convenience function to check on something at most every x seconds. More...
 
bool XPMP2::CheckEverySoOften (float &_lastCheck, float _interval)
 Convenience function to check on something at most every x seconds. More...
 
const char * XPMP2::LogGetString (const char *szFile, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg, va_list args)
 Returns ptr to static buffer filled with formatted log string. More...
 
void XPMP2::LogMsg (const char *szFile, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg,...) XPMP2_FMTARGS(5)
 Log Text to log file. More...
 
int XPMP2::strerror_s (char *buf, size_t bufsz, int errnum)
 
std::string XPMP2::TOPOSIX (const std::string &p)
 On Lin/Win there is no need for a conversion, but we do treat p now as std::string More...
 
std::string XPMP2::FROMPOSIX (const std::string &p)
 On Lin/Win there is no need for a conversion, but we do treat p now as std::string More...
 
- - - - - - - - - - - - -

-Variables

constexpr const char * XPMP2::RSRC_RELATED = "related.txt"
 
constexpr const char * XPMP2::RSRC_DOC8643 = "Doc8643.txt"
 
constexpr const char * XPMP2::RSRC_MAP_ICONS = "MapIcons.png"
 
constexpr const char * XPMP2::RSRC_OBJ8DATAREFS = "Obj8DataRefs.txt"
 
constexpr double XPMP2::PI = 3.1415926535897932384626433832795028841971693993751
 Pi. More...
 
-

Detailed Description

-

Miscellaneous utility functions, including logging.

-
Author
Birger Hoppe
- -

Macro Definition Documentation

- -

◆ CATCH_AC

- -
-
- - - - - - - - -
#define CATCH_AC( ac)
-
-Value:
catch (const std::exception& e) { \
-
LOG_MSG(logFATAL, ERR_EXCEPTION, e.what()); \
-
(ac).SetInvalid(); \
-
} \
-
catch (...) { \
-
LOG_MSG(logFATAL, ERR_EXCEPTION, "<unknown>"); \
-
(ac).SetInvalid(); \
-
}
-
-

Standard catch clauses for dealing with aircraft: logs message, sets aircraft invalid.

- -
-
- -

◆ ERR_ASSERT

- -
-
- - - - -
#define ERR_ASSERT   "ASSERT FAILED: %s"
-
- -
-
- -

◆ ERR_EXCEPTION

- -
-
- - - - -
#define ERR_EXCEPTION   "EXCEPTION CAUGHT: %s"
-
- -
-
- -

◆ LOG_ASSERT

- -
-
- - - - - - - - -
#define LOG_ASSERT( cond)
-
-Value:
if (!(cond)) { \
-
THROW_ERROR(ERR_ASSERT,#cond); \
-
}
-
-

Throw in an assert-style (logging takes place in XPMP2Error constructor)

-
Note
This conditional check always takes place, independend of any build or logging settings!
- -
-
- -

◆ LOG_MATCHING

- -
-
- - - - - - - - - - - - - - - - - - -
#define LOG_MATCHING( lvl,
 ... 
)
-
-Value:
{ \
-
if (glob.bLogMdlMatch && lvl >= glob.logLvl) \
-
{LogMsg(__FILE__, __LINE__, __func__, lvl, __VA_ARGS__);} \
-
}
-
-

Log a message about matching if logging of model matching is enabled.

-
Note
First parameter after lvl must be the message text, which can be a format string with its parameters following like in sprintf
- -
-
- -

◆ LOG_MSG

- -
-
- - - - - - - - - - - - - - - - - - -
#define LOG_MSG( lvl,
 ... 
)
-
-Value:
{ \
-
if (lvl >= glob.logLvl) \
-
{LogMsg(__FILE__, __LINE__, __func__, lvl, __VA_ARGS__);} \
-
}
-
-

Log a message if lvl is greater or equal currently defined log level.

-
Note
First parameter after lvl must be the message text, which can be a format string with its parameters following like in sprintf
- -
-
- -

◆ PATH_DELIM_STD

- -
-
- - - - -
#define PATH_DELIM_STD   '/'
-
- -
-
- -

◆ SET_THREAD_NAME

- -
-
- - - - - - - - -
#define SET_THREAD_NAME( sName)
-
- -
-
- -

◆ STRCPY_ATMOST

- -
-
- - - - - - - - - - - - - - - - - - -
#define STRCPY_ATMOST( dest,
 src 
)   strncpy_s(dest,sizeof(dest),strAtMost(src,sizeof(dest)-1).c_str(),sizeof(dest)-1)
-
- -
-
- -

◆ STRCPY_S

- -
-
- - - - - - - - - - - - - - - - - - -
#define STRCPY_S( dest,
 src 
)   strncpy_s(dest,sizeof(dest),src,sizeof(dest)-1)
-
- -

Simpler access to strncpy_s if dest is a char array (not a pointer!)

- -
-
- -

◆ THROW_ERROR

- -
-
- - - - - - - - -
#define THROW_ERROR( ...)   throw XPMP2Error(__FILE__, __LINE__, __func__, __VA_ARGS__);
-
- -

Throws an exception using XPMP2Error.

-
Note
First parameter after lvl must be the message text, which can be a format string with its parameters following like in sprintf
- -
-
- -

◆ WHITESPACE

- -
-
- - - - -
#define WHITESPACE   " \t\f\v\r\n"
-
- -
-
- -

◆ XPMP2_FMTARGS

- -
-
- - - - - - - - -
#define XPMP2_FMTARGS( FMT)
-
- -

To apply printf-style warnings to our functions.

-
See also
Taken from imgui.h's definition of IM_FMTARGS
- -
-
-
-
logLevelTy logLvl
Logging level.
Definition: XPMP2.h:115
-
bool bLogMdlMatch
Debug model matching?
Definition: XPMP2.h:117
-
void LogMsg(const char *szMsg,...)
Log a message to X-Plane's Log.txt with sprintf-style parameters.
Definition: XPMP2-Sample.cpp:92
-
@ logFATAL
fatal is shortly before a crash
Definition: Utilities.h:218
-
#define ERR_EXCEPTION
Definition: Utilities.h:31
-
GlobVars glob
The one and only global variable structure.
Definition: Utilities.cpp:29
-
#define ERR_ASSERT
Definition: Utilities.h:30
- - - - diff --git a/docs/html/Utilities_8h_source.html b/docs/html/Utilities_8h_source.html deleted file mode 100644 index 958b2631..00000000 --- a/docs/html/Utilities_8h_source.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - - - -XPMP2: src/Utilities.h Source File - - - - - - -
-
- - - - - - -
-
XPMP2 -
-
X-Plane multiplayer library 2 - using instancing
-
-
- - - - - - - -
-
-
-
Utilities.h
-
-
-Go to the documentation of this file.
1 
-
21 #ifndef _Utilities_h_
-
22 #define _Utilities_h_
-
23 
-
24 namespace XPMP2 {
-
25 
-
26 //
-
27 // MARK: General texts
-
28 //
-
29 
-
30 #define ERR_ASSERT "ASSERT FAILED: %s"
-
31 #define ERR_EXCEPTION "EXCEPTION CAUGHT: %s"
-
32 
-
33 // Required supplemental files
-
34 constexpr const char* RSRC_RELATED = "related.txt";
-
35 constexpr const char* RSRC_DOC8643 = "Doc8643.txt";
-
36 constexpr const char* RSRC_MAP_ICONS = "MapIcons.png";
-
37 constexpr const char* RSRC_OBJ8DATAREFS = "Obj8DataRefs.txt";
-
38 
-
39 //
-
40 // MARK: Default configuration callbacks
-
41 //
-
42 
-
43 int PrefsFuncIntDefault (const char *, const char *, int _default);
-
44 float PrefsFuncFloatDefault (const char *, const char *, float _default);
-
45 
-
46 //
-
47 // MARK: File access helpers
-
48 //
-
49 
-
50 #if IBM
-
51 #define PATH_DELIM_STD '\\'
-
52 #else
-
53 #define PATH_DELIM_STD '/'
-
54 #endif
-
55 
-
57 bool ExistsFile (const std::string& filename);
-
58 
-
60 bool IsDir (const std::string& path);
-
61 
-
64 bool CreateDir(const std::string& path);
-
65 
-
68 bool CopyFileIfNewer(const std::string& source, const std::string& destDir);
-
69 
-
71 std::list<std::string> GetDirContents (const std::string& path);
-
72 
-
74 std::istream& safeGetline(std::istream& is, std::string& t);
-
75 
-
77 std::string StripXPSysDir (const std::string& path);
-
78 
-
80 void RemoveExtension (std::string& path);
-
81 
-
82 //
-
83 // MARK: String helpers
-
84 //
-
85 
-
86 #define WHITESPACE " \t\f\v\r\n"
-
87 
-
89 std::string& str_tolower(std::string& s);
-
90 
-
93 inline std::string& rtrim(std::string& s, const char* t = WHITESPACE)
-
94 {
-
95  s.erase(s.find_last_not_of(t) + 1);
-
96  return s;
-
97 }
-
98 
-
101 inline std::string& ltrim(std::string& s, const char* t = WHITESPACE)
-
102 {
-
103  s.erase(0, s.find_first_not_of(t));
-
104  return s;
-
105 }
-
106 
-
109 inline std::string& trim(std::string& s, const char* t = WHITESPACE)
-
110 {
-
111  return ltrim(rtrim(s, t), t);
-
112 }
-
113 
-
115 std::vector<std::string> str_tokenize (const std::string s,
-
116  const std::string tokens,
-
117  bool bSkipEmpty = true);
-
118 
-
119 //
-
120 // MARK: Math helpers
-
121 //
-
122 
-
124 constexpr double PI = 3.1415926535897932384626433832795028841971693993751;
-
125 
-
127 template <class T>
-
128 inline T rad2deg (const T _rad)
-
129 { return (_rad < T(0) ? T(360) : T(0)) + _rad * T(180) / T(PI); }
-
130 
-
132 template <class T>
-
133 inline T deg2rad (const T _deg)
-
134 { return _deg * T(PI) / T(180); }
-
135 
-
137 template <class T>
-
138 inline T sqr (const T a) { return a*a; }
-
139 
-
141 template <class T>
-
142 inline T dist (const T x1, const T y1, const T z1,
-
143  const T x2, const T y2, const T z2)
-
144 {
-
145  return std::sqrt(sqr(x1-x2) + sqr(y1-y2) + sqr(z1-z2));
-
146 }
-
147 
-
149 inline float atan2deg (float x, float y)
-
150 { return rad2deg(atan2(x,y)); }
-
151 
-
159 inline float angleLocCoord (float x1, float z1, float x2, float z2)
-
160 { return rad2deg(atan2(z2-z1,x2-x1) + float(PI/2.0)); }
-
161 
-
163 float headDiff (float head1, float head2);
-
164 
-
166 template <class numT>
-
167 numT headNormalize (numT _head)
-
168 {
-
169  if (_head < numT(0))
-
170  _head += std::ceil(_head/-numT(360)) * numT(360);
-
171  else if (_head >= numT(360))
-
172  _head -= std::floor(_head/numT(360)) * numT(360);
-
173  return _head;
-
174 }
-
175 
-
176 //
-
177 // MARK: Misc
-
178 //
-
179 
-
181 float GetMiscNetwTime ();
-
182 
-
184 const char* GetGraphicsDriverTxt ();
-
185 
-
191 bool CheckEverySoOften (float& _lastCheck, float _interval, float _now);
-
192 
-
197 inline bool CheckEverySoOften (float& _lastCheck, float _interval)
-
198 { return CheckEverySoOften(_lastCheck, _interval, GetMiscNetwTime()); }
-
199 
-
200 //
-
201 // MARK: Logging Support
-
202 //
-
203 
-
206 #if defined(__clang__) || defined(__GNUC__)
-
207 #define XPMP2_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1)))
-
208 #else
-
209 #define XPMP2_FMTARGS(FMT)
-
210 #endif
-
211 
- -
214  logDEBUG = 0,
- - - - -
219  logMSG
-
220 };
-
221 
-
223 const char* LogGetString ( const char* szFile, int ln, const char* szFunc, logLevelTy lvl, const char* szMsg, va_list args );
-
224 
-
226 void LogMsg ( const char* szFile, int ln, const char* szFunc, logLevelTy lvl, const char* szMsg, ... ) XPMP2_FMTARGS(5);
-
227 
-
228 //
-
229 // MARK: Logging macros
-
230 //
-
231 
-
235 #define LOG_MSG(lvl,...) { \
-
236  if (lvl >= glob.logLvl) \
-
237  {LogMsg(__FILE__, __LINE__, __func__, lvl, __VA_ARGS__);} \
-
238 }
-
239 
-
243 #define LOG_MATCHING(lvl,...) { \
-
244  if (glob.bLogMdlMatch && lvl >= glob.logLvl) \
-
245  {LogMsg(__FILE__, __LINE__, __func__, lvl, __VA_ARGS__);} \
-
246 }
-
247 
-
251 #define THROW_ERROR(...) \
-
252 throw XPMP2Error(__FILE__, __LINE__, __func__, __VA_ARGS__);
-
253 
-
256 #define LOG_ASSERT(cond) \
-
257  if (!(cond)) { \
-
258  THROW_ERROR(ERR_ASSERT,#cond); \
-
259  }
-
260 
-
262 #define CATCH_AC(ac) \
-
263  catch (const std::exception& e) { \
-
264  LOG_MSG(logFATAL, ERR_EXCEPTION, e.what()); \
-
265  (ac).SetInvalid(); \
-
266  } \
-
267  catch (...) { \
-
268  LOG_MSG(logFATAL, ERR_EXCEPTION, "<unknown>"); \
-
269  (ac).SetInvalid(); \
-
270  }
-
271 
-
272 
-
273 //
-
274 // MARK: Compiler differences
-
275 //
-
276 
-
277 #if APL == 1 || LIN == 1
-
278 // not quite the same but close enough for our purposes
-
279 inline void strncpy_s(char * dest, size_t destsz, const char * src, size_t count)
-
280 {
-
281  strncpy(dest, src, std::min(destsz,count)); dest[destsz - 1] = 0;
-
282 }
-
283 
-
284 // these simulate the VC++ version, not the C standard versions!
-
285 inline struct tm *gmtime_s(struct tm * result, const time_t * time)
-
286 { return gmtime_r(time, result); }
-
287 inline struct tm *localtime_s(struct tm * result, const time_t * time)
-
288 { return localtime_r(time, result); }
-
289 
-
290 #endif
-
291 
-
293 #define STRCPY_S(dest,src) strncpy_s(dest,sizeof(dest),src,sizeof(dest)-1)
-
294 #define STRCPY_ATMOST(dest,src) strncpy_s(dest,sizeof(dest),strAtMost(src,sizeof(dest)-1).c_str(),sizeof(dest)-1)
-
295 
-
296 #if IBM != 1
-
297 // XCode/Linux don't provide the _s functions, not even with __STDC_WANT_LIB_EXT1__ 1
-
298 inline int strerror_s( char *buf, size_t bufsz, int errnum )
-
299 { return strerror_r(errnum, buf, bufsz); }
-
300 #endif
-
301 
-
302 // In case of Mac we need to prepare for HFS-to-Posix path conversion
-
303 #if APL
-
304 std::string TOPOSIX (const std::string& p);
-
307 std::string FROMPOSIX (const std::string& p);
-
308 #else
-
309 inline std::string TOPOSIX (const std::string& p) { return p; }
-
312 inline std::string FROMPOSIX (const std::string& p) { return p; }
-
313 #endif
-
314 
-
315 // MARK: Thread names
-
316 #ifdef DEBUG
-
317 // This might not work on older Windows version, which is why we don't publish it in release builds
-
318 #if IBM
-
319 #define SET_THREAD_NAME(sName) SetThreadDescription(GetCurrentThread(), L##sName)
-
320 #elif APL
-
321 #define SET_THREAD_NAME(sName) pthread_setname_np(sName)
-
322 #elif LIN
-
323 #define SET_THREAD_NAME(sName) pthread_setname_np(pthread_self(),sName)
-
324 #endif
-
325 #else
-
326 #define SET_THREAD_NAME(sName)
-
327 #endif
-
328 
-
329 } // namespace XPMP2
-
330 
-
331 #endif
-
-
T rad2deg(const T _rad)
Convert radians to degrees, normalized to [0..360)
Definition: Utilities.h:128
-
virtual const char * what() const noexcept
returns msg.c_str()
Definition: Utilities.cpp:527
-
@ logWARN
warnings, i.e. unexpected, but uncritical events, maybe leading to unwanted display,...
Definition: Utilities.h:216
-
#define LOG_MSG(lvl,...)
Log a message if lvl is greater or equal currently defined log level.
Definition: Utilities.h:235
-
#define THROW_ERROR(...)
Throws an exception using XPMP2Error.
Definition: Utilities.h:251
-
std::string logAcronym
Plugin acronym used in log output.
Definition: XPMP2.h:135
-
std::string TOPOSIX(const std::string &p)
On Lin/Win there is no need for a conversion, but we do treat p now as std::string
Definition: Utilities.h:310
-
const char * LogGetString(const char *szPath, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg, va_list args)
Returns ptr to static buffer filled with formatted log string.
Definition: Utilities.cpp:541
-
std::string & str_tolower(std::string &s)
change a std::string to uppercase
Definition: Utilities.cpp:397
-
logLevelTy logLvl
Logging level.
Definition: XPMP2.h:115
-
#define XPMP_CFG_ITM_REPLDATAREFS
Config key: Replace dataRefs in OBJ8 files upon load, creating new OBJ8 files for XPMP2 (defaults to ...
Definition: XPMPMultiplayer.h:261
-
RemoteCfgTy remoteCfg
Configuration: Are we to support remote connections?
Definition: XPMP2.h:195
-
T dist(const T x1, const T y1, const T z1, const T x2, const T y2, const T z2)
Pythagorean distance between two points in a 3-D world.
Definition: Utilities.h:142
-
#define XPMP_CFG_ITM_CLAMPALL
Config key: Ensure no plane sinks below ground, no matter of XPMP2::Aircraft::bClampToGround.
Definition: XPMPMultiplayer.h:263
-
void RemoveExtension(std::string &path)
Removes everything after the last dot, the dot including.
Definition: Utilities.cpp:286
-
bool bLogMdlMatch
Debug model matching?
Definition: XPMP2.h:117
-
#define XPMP_CFG_ITM_REPLTEXTURE
Config key: Replace textures in OBJ8 files upon load if needed (specified on the OBJ8 line in xsb_air...
Definition: XPMPMultiplayer.h:262
-
T deg2rad(const T _deg)
Convert degree to radians.
Definition: Utilities.h:133
-
bool bHandleDupId
Handle duplicate XPMP2::Aircraft::modeS_id by overwriting with unique id.
Definition: XPMP2.h:121
-
@ REMOTE_CFG_CONDITIONALLY
config: on if in a netwoked/multiplayer setup
Definition: Remote.h:34
-
constexpr double PI
Pi.
Definition: Utilities.h:124
-
@ logINFO
regular info messages
Definition: Utilities.h:215
-
std::istream & safeGetline(std::istream &is, std::string &t)
Read a line from a text file, no matter if ending on CRLF or LF.
Definition: Utilities.cpp:255
-
bool ExistsFile(const std::string &filename)
Does a file path exist?
Definition: Utilities.cpp:138
-
std::string msg
additional text message
Definition: XPMPAircraft.h:515
-
void RemoteSenderUpdateStatus()
Compares current vs. expected status and takes appropriate action.
Definition: Remote.cpp:770
-
constexpr const char * RSRC_MAP_ICONS
Definition: Utilities.h:36
-
bool bClampAll
Clamp all planes to the ground? Default is false as clamping is kinda expensive due to Y-Testing.
Definition: XPMP2.h:119
-
float PrefsFuncFloatDefault(const char *, const char *, float _default)
-
void ReadVersions()
Read version numbers into verXplane/verXPLM.
Definition: Utilities.cpp:114
-
XPMPPlaneID planeId
Current plane ID counter.
Definition: XPMP2.h:226
-
std::string & rtrim(std::string &s, const char *t=WHITESPACE)
trimming of string (from right)
Definition: Utilities.h:93
-
bool UsingModernGraphicsDriver() const
Using a modern graphics driver, ie. Vulkan/Metal?
Definition: XPMP2.h:240
-
const char * LOG_LEVEL[]
Definition: Utilities.cpp:536
-
@ logERR
errors mean, aircraft can potentially not be displayed
Definition: Utilities.h:217
-
bool CheckEverySoOften(float &_lastCheck, float _interval, float _now)
Convenience function to check on something at most every x seconds.
Definition: Utilities.cpp:497
-
XPMPPlaneID NextPlaneId()
Get the next unique artifical plane id.
Definition: Utilities.cpp:37
-
std::string FROMPOSIX(const std::string &p)
On Lin/Win there is no need for a conversion, but we do treat p now as std::string
Definition: Utilities.h:312
-
std::string & trim(std::string &s, const char *t=WHITESPACE)
trimming of string (from both ends)
Definition: Utilities.h:109
-
void UpdateCfgVals()
Update all settings, e.g. for logging level, by calling prefsFuncInt.
Definition: Utilities.cpp:61
-
std::vector< std::string > str_tokenize(const std::string s, const std::string tokens, bool bSkipEmpty)
separates string into tokens
Definition: Utilities.cpp:404
-
#define S_ISDIR(m)
Definition: Utilities.cpp:133
-
int PrefsFuncIntDefault(const char *, const char *, int _default)
Default config function just always returns the provided default value.
Definition: Utilities.cpp:55
-
int verXPLM
XPLM's SDK version number (XPLMGetVersions)
Definition: XPMP2.h:206
-
#define WHITESPACE
Definition: Utilities.h:86
-
#define XPMP_CFG_SEC_DEBUG
Config section "debug".
Definition: XPMPMultiplayer.h:258
-
#define XPMP_CFG_ITM_SUPPORT_REMOTE
Config key: Support remote connections? <0 force off, 0 default: on if in a networked or multiplayer ...
Definition: XPMPMultiplayer.h:265
-
#define XPMP_CFG_SEC_MODELS
Config section "models".
Definition: XPMPMultiplayer.h:256
-
#define XPMP_CFG_ITM_HANDLE_DUP_ID
Config key: Boolean: If XPMP2::Aircraft::modeS_id already exists then assign a new unique one,...
Definition: XPMPMultiplayer.h:264
-
float headDiff(float head1, float head2)
(Shortest) difference between 2 angles: How much to turn to go from h1 to h2?
Definition: Utilities.cpp:451
-
int verXPlane
X-Plane's version number (XPLMGetVersions)
Definition: XPMP2.h:204
-
bool IsDir(const std::string &path)
Is path a directory?
Definition: Utilities.cpp:145
-
bool CreateDir(const std::string &path)
Create directory if it does not exist.
Definition: Utilities.cpp:154
-
bool bXPUsingModernGraphicsDriver
Using a modern graphics driver, ie. Vulkan/Metal?
Definition: XPMP2.h:208
-
float atan2deg(float x, float y)
atan2 converted to degrees: the angle between (0|0) and the given point
Definition: Utilities.h:149
-
constexpr XPMPPlaneID MIN_MODE_S_ID
Minimum allowed XPMPPlaneID / mode S id.
Definition: XPMPMultiplayer.h:246
-
#define XPMP_CFG_ITM_MODELMATCHING
Config key: Write information on model matching into Log.txt
Definition: XPMPMultiplayer.h:267
-
int(* prefsFuncInt)(const char *, const char *, int)
Configuration callback for integer values.
Definition: XPMP2.h:138
-
@ REMOTE_CFG_ON
config: force on
Definition: Remote.h:35
-
constexpr XPMPPlaneID MAX_MODE_S_ID
Maximum allowed XPMPPlaneID / mode S id.
Definition: XPMPMultiplayer.h:248
-
float angleLocCoord(float x1, float z1, float x2, float z2)
Angle of line from point (x1|z1) to point (x2|z2)
Definition: Utilities.h:159
-
std::uint16_t PJWHash16(const char *s)
Produces a reproducible(!) hash value for strings.
Definition: Utilities.cpp:430
-
@ logDEBUG
Debug, highest level of detail.
Definition: Utilities.h:214
-
bool bXPNetworkedSetup
Is X-Plane configured for networked multi-computer or multiplayer setup?
Definition: XPMP2.h:210
-
@ REMOTE_CFG_OFF
config: force off
Definition: Remote.h:33
-
#define XPMP2_FMTARGS(FMT)
To apply printf-style warnings to our functions.
Definition: Utilities.h:209
-
Header file covering all includes required for compiling XPMP2, basis for pre-compiled headers.
-
void LogMsg(const char *szPath, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg,...)
Log Text to log file.
Definition: Utilities.cpp:586
-
bool bObjReplDataRefs
Replace dataRefs in .obj files on load? (defaults to OFF!)
Definition: XPMP2.h:124
-
@ logFATAL
fatal is shortly before a crash
Definition: Utilities.h:218
-
T sqr(const T a)
Square.
Definition: Utilities.h:138
-
unsigned XPMPPlaneID
Unique ID for an aircraft created by a plugin.
Definition: XPMPMultiplayer.h:243
-
std::list< std::string > GetDirContents(const std::string &path)
List of files in a directory (wrapper around XPLMGetDirectoryContents)
Definition: Utilities.cpp:222
-
#define XPMP_CFG_ITM_LOGLEVEL
Config key: General level of logging into Log.txt (0 = Debug, 1 = Info, 2 = Warning,...
Definition: XPMPMultiplayer.h:266
-
GlobVars glob
The one and only global variable structure.
Definition: Utilities.cpp:29
-
#define PATH_DELIM_STD
Definition: Utilities.h:53
-
std::string StripXPSysDir(const std::string &path)
If a path starts with X-Plane's system directory it is stripped.
Definition: Utilities.cpp:268
-
logLevelTy
Logging level.
Definition: Utilities.h:213
-
bool CopyFileIfNewer(const std::string &source, const std::string &destDir)
Copy file if source is newer or destination missing.
Definition: Utilities.cpp:169
-
constexpr const char * RSRC_OBJ8DATAREFS
Definition: Utilities.h:37
-
bool bObjReplTextures
Replace textures in .obj files on load if needed?
Definition: XPMP2.h:126
-
constexpr const char * RSRC_DOC8643
Definition: Utilities.h:35
-
#define XPMP_CFG_SEC_PLANES
Config section "planes".
Definition: XPMPMultiplayer.h:257
-
@ logMSG
will always be output, no matter what has been configured, cannot be suppressed
Definition: Utilities.h:219
-
Definition: XPMPAircraft.h:39
-
int strerror_s(char *buf, size_t bufsz, int errnum)
Definition: Utilities.h:298
-
std::string & ltrim(std::string &s, const char *t=WHITESPACE)
trimming of string (from left)
Definition: Utilities.h:101
-
const char * GetGraphicsDriverTxt()
Text string for current graphics driver in use.
Definition: Utilities.cpp:483
-
constexpr const char * RSRC_RELATED
Definition: Utilities.h:34
-
float GetMiscNetwTime()
Get synched network time from X-Plane (sim/network/misc/network_time_sec) as used in Log....
Definition: Utilities.cpp:474
-
#define LOG_ASSERT(cond)
Throw in an assert-style (logging takes place in XPMP2Error constructor)
Definition: Utilities.h:256
-
mapAcTy mapAc
Global map of all created planes.
Definition: XPMP2.h:163
-
numT headNormalize(numT _head)
Normalize a heading value to [0..360), works for both float and double values.
Definition: Utilities.h:167
-
XPMP2Error(const char *szFile, int ln, const char *szFunc, const char *szMsg,...)
Constructor puts together a formatted exception text.
Definition: Utilities.cpp:512
- - - - diff --git a/docs/html/XPCAircraft_8h.html b/docs/html/XPCAircraft_8h.html index fbfa6b3b..50d2bf7f 100644 --- a/docs/html/XPCAircraft_8h.html +++ b/docs/html/XPCAircraft_8h.html @@ -50,7 +50,7 @@
-

XPMP2::Aircraft / XPCAircraft represent an aircraft as managed by XPMP2. +

XPMP2::Aircraft / XPCAircraft represent an aircraft as managed by XPMP2. More...

#include "XPMPAircraft.h"
@@ -63,8 +63,8 @@

 

Detailed Description

-

XPMP2::Aircraft / XPCAircraft represent an aircraft as managed by XPMP2.

-
Deprecated:
XPCAircraft bases on and is compile-compatible to the XPCAircraft wrapper class provided with the original libxplanemp. In XPMP2, however, this class is not a wrapper but derived from XPMP2::Aircraft, which is the actual means of managing aircraft, Hence, it includes a lot more members.
+

XPMP2::Aircraft / XPCAircraft represent an aircraft as managed by XPMP2.

+
Deprecated:
XPCAircraft bases on and is compile-compatible to the XPCAircraft wrapper class provided with the original libxplanemp. In XPMP2, however, this class is not a wrapper but derived from XPMP2::Aircraft, which is the actual means of managing aircraft, Hence, it includes a lot more members.
New implementations should derive directly from XPMP2::Aircraft.
Author
Birger Hoppe