feat: Add MSFS support

Co-Authored-By: Roland Rossgotterer <roland.rossgotterer@gmail.com>
Co-Authored-By: tzobler <tzobler@t-online.de>
This commit is contained in:
Lars Toenning
2024-11-12 17:27:07 +01:00
parent 7b6568f3b9
commit 528b0cc255
50 changed files with 735 additions and 78 deletions

View File

@@ -26,7 +26,7 @@ if(SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN OR SWIFT_BUILD_MSFS_PLUGIN)
add_subdirectory(fsxcommon)
endif()
if(SWIFT_WIN32 AND (SWIFT_BUILD_FS9_PLUGIN OR SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN OR SWIFT_BUILD_MSFS_PLUGIN))
if(SWIFT_WIN32 AND (SWIFT_BUILD_FS9_PLUGIN OR SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN))
add_subdirectory(fsuipc32)
endif()
@@ -45,6 +45,7 @@ endif()
if(SWIFT_BUILD_MSFS_PLUGIN)
add_subdirectory(msfs)
add_subdirectory(msfsconfig)
endif()
if(SWIFT_BUILD_FSX_PLUGIN)

View File

@@ -13,6 +13,7 @@
using namespace swift::misc;
using namespace swift::misc::aviation;
using namespace swift::misc::simulation;
using namespace swift::simplugin::fscommon;
namespace swift::simplugin::fsxcommon
@@ -69,7 +70,7 @@ namespace swift::simplugin::fsxcommon
CSimConnectDefinitions::CSimConnectDefinitions() {}
HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect)
HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect, const CSimulatorInfo &simInfo)
{
HRESULT hr = s_ok();
hr += initOwnAircraft(hSimConnect);
@@ -78,6 +79,10 @@ namespace swift::simplugin::fsxcommon
hr += initRemoteAircraftSimDataSet(hSimConnect);
hr += initSimulatorEnvironment(hSimConnect);
hr += initSbDataArea(hSimConnect);
if (simInfo.isMSFS())
{
hr += initMSFSTransponder(hSimConnect);
}
return hr;
}
@@ -289,6 +294,18 @@ namespace swift::simplugin::fsxcommon
return hr;
}
HRESULT CSimConnectDefinitions::initMSFSTransponder(const HANDLE hSimConnect)
{
HRESULT hr = s_ok();
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS, "TRANSPONDER STATE:1", "Enum");
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS, "TRANSPONDER IDENT:1", "Bool");
if (isFailure(hr))
{
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error(u"SimConnect error: MSFS transponder data definitions %1") << hr;
}
return hr;
}
DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights()
{
this->resetToInvalid();

View File

@@ -9,6 +9,7 @@
#include "plugins/simulator/fsxcommon/fsxcommonexport.h"
#include "plugins/simulator/fsxcommon/simconnectwindows.h"
#include "misc/aviation/aircraftlights.h"
#include "misc/simulation/simulatorinfo.h"
#include <algorithm>
#include <QtGlobal>
@@ -255,6 +256,13 @@ namespace swift::simplugin::fsxcommon
QString toQString() const;
};
//! Data structure for MSFS transponder mode information
struct DataDefinitionMSFSTransponderMode
{
double transponderMode = 1; //!< transponder state simvar
double ident = 0; //!< ident
};
//! Client areas
enum ClientAreaId
{
@@ -277,6 +285,7 @@ namespace swift::simplugin::fsxcommon
DataRemoteAircraftModelData, //!< model data eventually used and reported back from simulator
DataRemoteAircraftSetData, //!< set model data such as airline
DataSimEnvironment,
DataTransponderModeMSFS,
DataClientAreaSb, //!< whole SB area, see http://squawkbox.ca/doc/sdk/fsuipc.php
DataClientAreaSbIdent, //!< SB ident single value 0x7b93/19
DataClientAreaSbStandby, //!< SB standby 0x7b91/17
@@ -291,6 +300,7 @@ namespace swift::simplugin::fsxcommon
RequestOwnAircraftTitle,
RequestSimEnvironment,
RequestSbData, //!< SB client area / XPDR mode
RequestMSFSTransponder, //!< MSFS XPDR mode/ident
RequestFacility,
RequestEndMarker //!< free request ids can start here
};
@@ -318,7 +328,7 @@ namespace swift::simplugin::fsxcommon
CSimConnectDefinitions();
//! Initialize all data definitions
static HRESULT initDataDefinitionsWhenConnected(const HANDLE hSimConnect);
static HRESULT initDataDefinitionsWhenConnected(const HANDLE hSimConnect, const swift::misc::simulation::CSimulatorInfo &simInfo);
private:
//! Initialize data definition for our own aircraft
@@ -338,6 +348,9 @@ namespace swift::simplugin::fsxcommon
//! Initialize the SB data are
static HRESULT initSbDataArea(const HANDLE hSimConnect);
//! Initialize data definition for MSFS transponder
static HRESULT initMSFSTransponder(const HANDLE hSimConnect);
};
} // namespace

View File

@@ -194,6 +194,25 @@ namespace swift::simplugin::fsxcommon
}
changed = true;
}
else if (this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
{
DataDefinitionMSFSTransponderMode t;
t.transponderMode = (newTransponder.isInStandby() ? 1 : 4);
t.ident = newTransponder.isIdentifying();
HRESULT hr = s_ok();
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0,
sizeof(DataDefinitionMSFSTransponderMode), &t);
if (isFailure(hr))
{
CLogMessage(this).warning(u"Setting transponder mode failed (MSFS)");
}
changed = true;
}
}
// avoid changes of cockpit back to old values due to an outdated read back value
@@ -468,32 +487,48 @@ namespace swift::simplugin::fsxcommon
const CFsxP3DSettings settings = m_detailsSettings.getSettings(this->getSimulatorInfo());
m_useAddSimulatedObj = settings.isAddingAsSimulatedObjectEnabled();
m_useSbOffsets = settings.isSbOffsetsEnabled();
if (this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
{
m_useSbOffsets = false; // Always disable SbOffsets for MSFS. Using new transponder mode property directly
}
const HRESULT hr1 = this->logAndTraceSendId(
HRESULT hr = s_ok();
hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft,
CSimConnectDefinitions::DataOwnAircraft, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME),
"Cannot request own aircraft data", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
const HRESULT hr2 = this->logAndTraceSendId(
hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraftTitle,
CSimConnectDefinitions::DataOwnAircraftTitle,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request title", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
const HRESULT hr3 = this->logAndTraceSendId(
hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestSimEnvironment,
CSimConnectDefinitions::DataSimEnvironment,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request sim.env.", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
// Request the data from SB only when its changed and only ONCE so we don't have to run a 1sec event to get/set this info ;)
// there was a bug with SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, see https://www.prepar3d.com/forum/viewtopic.php?t=124789
const HRESULT hr4 = this->logAndTraceSendId(
SimConnect_RequestClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::RequestSbData,
CSimConnectDefinitions::DataClientAreaSb, SIMCONNECT_CLIENT_DATA_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request client data", Q_FUNC_INFO, "SimConnect_RequestClientData");
if (!this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
{
// Request the data from SB only when its changed and only ONCE so we don't have to run a 1sec event to get/set this info ;)
// there was a bug with SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, see https://www.prepar3d.com/forum/viewtopic.php?t=124789
hr += this->logAndTraceSendId(
SimConnect_RequestClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::RequestSbData,
CSimConnectDefinitions::DataClientAreaSb, SIMCONNECT_CLIENT_DATA_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request client data", Q_FUNC_INFO, "SimConnect_RequestClientData");
}
else
{
hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestMSFSTransponder,
CSimConnectDefinitions::DataTransponderModeMSFS,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request MSFS transponder data", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
}
if (isFailure(hr1, hr2, hr3, hr4)) { return; }
if (isFailure(hr)) { return; }
this->emitSimulatorCombinedStatus(); // force sending status
}
@@ -929,6 +964,27 @@ namespace swift::simplugin::fsxcommon
this->updateCockpit(myAircraft.getCom1System(), myAircraft.getCom2System(), xpdr, this->identifier());
}
void CSimulatorFsxCommon::updateTransponderMode(const CTransponder::TransponderMode xpdrMode)
{
if (m_skipCockpitUpdateCycles > 0) { return; }
const CSimulatedAircraft myAircraft(this->getOwnAircraft());
const bool changed = (myAircraft.getTransponderMode() != xpdrMode);
if (!changed) { return; }
CTransponder myXpdr = myAircraft.getTransponder();
myXpdr.setTransponderMode(xpdrMode);
this->updateCockpit(myAircraft.getCom1System(), myAircraft.getCom2System(), myXpdr, this->identifier());
}
void CSimulatorFsxCommon::updateMSFSTransponderMode(const DataDefinitionMSFSTransponderMode transponderMode)
{
auto mode = CTransponder::StateIdent;
if (!transponderMode.ident)
{
qRound(transponderMode.transponderMode) >= 3 ? mode = CTransponder::ModeC : mode = CTransponder::StateStandby;
}
this->updateTransponderMode(mode);
}
bool CSimulatorFsxCommon::simulatorReportedObjectAdded(DWORD objectId)
{
if (this->isShuttingDownOrDisconnected()) { return true; } // pretend everything is fine
@@ -1880,7 +1936,7 @@ namespace swift::simplugin::fsxcommon
HRESULT CSimulatorFsxCommon::initDataDefinitionsWhenConnected()
{
return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect);
return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect, this->getSimulatorPluginInfo().getSimulatorInfo());
}
HRESULT CSimulatorFsxCommon::initWhenConnected()

View File

@@ -478,6 +478,13 @@ namespace swift::simplugin::fsxcommon
//! \threadsafe
void updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea);
//! Update transponder mode
//! \threadsafe
void updateTransponderMode(const misc::aviation::CTransponder::TransponderMode xpdrMode);
//! Update transponder mode from MSFS
void updateMSFSTransponderMode(const DataDefinitionMSFSTransponderMode transponderMode);
//! An AI aircraft was added in the simulator
bool simulatorReportedObjectAdded(DWORD objectId);

View File

@@ -254,6 +254,12 @@ namespace swift::simplugin::fsxcommon
simulatorFsxP3D->synchronizeTime(simEnv);
break;
}
case CSimConnectDefinitions::RequestMSFSTransponder:
{
const DataDefinitionMSFSTransponderMode *transponderMode = reinterpret_cast<const DataDefinitionMSFSTransponderMode *>(&pObjData->dwData);
simulatorFsxP3D->updateMSFSTransponderMode(*transponderMode);
break;
}
default:
{
const DWORD objectId = pObjData->dwObjectID;

View File

@@ -31,19 +31,11 @@ namespace swift::simplugin::msfs
bool CSimulatorMsFs::connectTo()
{
#ifdef Q_OS_WIN64
if (!loadAndResolveMSFSimConnect())
{
return false;
}
return CSimulatorFsxCommon::connectTo();
#else
if (!loadAndResolveFsxSimConnect(true))
{
return false;
}
return CSimulatorFsxCommon::connectTo();
#endif
}
void CSimulatorMsFs::setTrueAltitude(CAircraftSituation &aircraftSituation, const DataDefinitionOwnAircraft &simulatorOwnAircraft)
@@ -54,19 +46,11 @@ namespace swift::simplugin::msfs
void CSimulatorMsFsListener::startImpl()
{
#ifdef Q_OS_WIN64
if (!loadAndResolveMSFSimConnect())
{
return;
}
CSimulatorFsxCommonListener::startImpl();
#else
if (!loadAndResolveFsxSimConnect(true))
{
return;
}
CSimulatorFsxCommonListener::startImpl();
#endif
}
} // ns

View File

@@ -1,6 +1,7 @@
{
"identifier" : "org.swift-project.plugins.simulator.msfs",
"name" : "Flight Simulator 2020",
"simulator" : "fsx",
"description" : "Microsoft Flight Simulator 2020"
"simulator" : "msfs",
"description" : "Microsoft Flight Simulator 2020",
"config" : "org.swift-project.plugins.simulator.msfs.config"
}

View File

@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
add_library(simulatormsfsconfig SHARED
simulatormsfsconfig.cpp
simulatormsfsconfig.h
simulatormsfsconfig.json
)
set_target_properties(simulatormsfsconfig PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/out/bin/plugins/simulator)
set_target_properties(simulatormsfsconfig PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/out/bin/plugins/simulator)
target_include_directories(simulatormsfsconfig PUBLIC ${PROJECT_SOURCE_DIR}/src)
target_link_libraries(simulatormsfsconfig
PUBLIC
gui
misc
Qt::Core
PRIVATE
fsxcommon
)
install(TARGETS simulatormsfsconfig
LIBRARY DESTINATION bin/plugins/simulator
RUNTIME DESTINATION bin/plugins/simulator
)

View File

@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: Copyright (C) 2017 swift Project Community / Contributors
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
#include "simulatormsfsconfig.h"
#include "../fsxcommon/simulatorfsxconfigwindow.h"
namespace swift::simplugin::msfs
{
CSimulatorMsfsConfig::CSimulatorMsfsConfig(QObject *parent) : QObject(parent)
{
// void
}
swift::gui::CPluginConfigWindow *CSimulatorMsfsConfig::createConfigWindow(QWidget *parent)
{
return new fsxcommon::CSimulatorFsxConfigWindow("MSFS", parent);
}
}

View File

@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: Copyright (C) 2017 swift Project Community / Contributors
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
//! \file
#ifndef SWIFT_SIMPLUGIN_MSFS_SIMULATORMSFSCONFIG_H
#define SWIFT_SIMPLUGIN_MSFS_SIMULATORMSFSCONFIG_H
#include "gui/pluginconfig.h"
namespace swift::simplugin::msfs
{
/*!
* Window for setting up the MSFS plugin.
*/
class CSimulatorMsfsConfig : public QObject, public swift::gui::IPluginConfig
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.swift-project.swiftgui.pluginconfiginterface" FILE "simulatormsfsconfig.json")
Q_INTERFACES(swift::gui::IPluginConfig)
public:
//! Ctor
CSimulatorMsfsConfig(QObject *parent = nullptr);
//! Dtor
virtual ~CSimulatorMsfsConfig() {}
//! \copydoc swift::gui::IPluginConfig::createConfigWindow()
swift::gui::CPluginConfigWindow *createConfigWindow(QWidget *parent) override;
};
}
#endif // guard

View File

@@ -0,0 +1,3 @@
{
"identifier" : "org.swift-project.plugins.simulator.msfs.config"
}

View File

@@ -0,0 +1,3 @@
Copyright (C) swift Project Community / Contributors
SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1