mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-11 23:05:34 +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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user