mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 15:25:35 +08:00
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:
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
27
src/plugins/simulator/msfsconfig/CMakeLists.txt
Normal file
27
src/plugins/simulator/msfsconfig/CMakeLists.txt
Normal 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
|
||||
)
|
||||
18
src/plugins/simulator/msfsconfig/simulatormsfsconfig.cpp
Normal file
18
src/plugins/simulator/msfsconfig/simulatormsfsconfig.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
34
src/plugins/simulator/msfsconfig/simulatormsfsconfig.h
Normal file
34
src/plugins/simulator/msfsconfig/simulatormsfsconfig.h
Normal 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
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"identifier" : "org.swift-project.plugins.simulator.msfs.config"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Copyright (C) swift Project Community / Contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||
Reference in New Issue
Block a user