mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-27 19:25:49 +08:00
refs #349, added SB client area (for ident, transponder mode) to driver
* added SB client area support * renamed member functions to better reflect meaning * added all structures required for SB client area * changed to new logging
This commit is contained in:
@@ -8,76 +8,126 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "simconnect_datadefinition.h"
|
#include "simconnect_datadefinition.h"
|
||||||
|
#include "blackmisc/logmessage.h"
|
||||||
|
|
||||||
|
using namespace BlackMisc;
|
||||||
|
|
||||||
namespace BlackSimPlugin
|
namespace BlackSimPlugin
|
||||||
{
|
{
|
||||||
namespace Fsx
|
namespace Fsx
|
||||||
{
|
{
|
||||||
|
|
||||||
CSimConnectDataDefinition::CSimConnectDataDefinition() { }
|
CSimConnectDefinitions::CSimConnectDefinitions() { }
|
||||||
|
|
||||||
HRESULT CSimConnectDataDefinition::initDataDefinitions(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += initOwnAircraft(hSimConnect);
|
hr += initOwnAircraft(hSimConnect);
|
||||||
hr += initRemoteAircraftSituation(hSimConnect);
|
hr += initRemoteAircraftSituation(hSimConnect);
|
||||||
hr += initGearHandlePosition(hSimConnect);
|
hr += initGearHandlePosition(hSimConnect);
|
||||||
hr += initSimulatorEnvironment(hSimConnect);
|
hr += initSimulatorEnvironment(hSimConnect);
|
||||||
|
hr += initSbDataArea(hSimConnect);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CSimConnectDataDefinition::initOwnAircraft(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initOwnAircraft(const HANDLE hSimConnect)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Latitude", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Latitude", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Longitude", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Longitude", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Altitude", "Feet");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Altitude", "Feet");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Heading Degrees True", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Heading Degrees True", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Pitch Degrees", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Pitch Degrees", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Bank Degrees", "Degrees");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "Plane Bank Degrees", "Degrees");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "GROUND VELOCITY", "knots");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND VELOCITY", "knots");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "SIM ON GROUND", "bool");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "SIM ON GROUND", "bool");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "TRANSPONDER CODE:1", NULL);
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "TRANSPONDER CODE:1", NULL);
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM ACTIVE FREQUENCY:1", "MHz");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM ACTIVE FREQUENCY:1", "MHz");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM ACTIVE FREQUENCY:2", "MHz");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM ACTIVE FREQUENCY:2", "MHz");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM STANDBY FREQUENCY:1", "MHz");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM STANDBY FREQUENCY:1", "MHz");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM STANDBY FREQUENCY:2", "MHz");
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM STANDBY FREQUENCY:2", "MHz");
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraftTitle, "TITLE", NULL, SIMCONNECT_DATATYPE_STRING256);
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE", NULL, SIMCONNECT_DATATYPE_STRING256);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK)
|
||||||
qFatal("initOwnAircraft");
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initOwnAircraft %1") << hr;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CSimConnectDataDefinition::initRemoteAircraftSituation(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initRemoteAircraftSituation(const HANDLE hSimConnect)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataRemoteAircraftSituation, "Initial Position", "", SIMCONNECT_DATATYPE_INITPOSITION);
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSituation, "Initial Position", "", SIMCONNECT_DATATYPE_INITPOSITION);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK)
|
||||||
qFatal("initRemoteAircraftSituation");
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSituation %1") << hr;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CSimConnectDataDefinition::initGearHandlePosition(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initGearHandlePosition(const HANDLE hSimConnect)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataGearHandlePosition, "GEAR HANDLE POSITION", "BOOL", SIMCONNECT_DATATYPE_INT32);
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataGearHandlePosition, "GEAR HANDLE POSITION", "BOOL", SIMCONNECT_DATATYPE_INT32);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK)
|
||||||
qFatal("initGearHandlePosition");
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initGearHandlePosition %1") << hr;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CSimConnectDataDefinition::initSimulatorEnvironment(const HANDLE hSimConnect)
|
HRESULT CSimConnectDefinitions::initSimulatorEnvironment(const HANDLE hSimConnect)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataSimEnvironment, "ZULU TIME", "", SIMCONNECT_DATATYPE_INT32);
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "ZULU TIME", "", SIMCONNECT_DATATYPE_INT32);
|
||||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataSimEnvironment, "LOCAL TIME", "", SIMCONNECT_DATATYPE_INT32);
|
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "LOCAL TIME", "", SIMCONNECT_DATATYPE_INT32);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK)
|
||||||
qFatal("initSimulatorEnvironment");
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initSimulatorEnvironment %1") << hr;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
HRESULT CSimConnectDefinitions::initSbDataArea(const HANDLE hSimConnect)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD sbSize = sizeof(DataDefinitionClientAreaSb);
|
||||||
|
|
||||||
|
// We need to know the client area 'name' and map it to a client ID
|
||||||
|
hr += SimConnect_MapClientDataNameToID(hSimConnect, "SquawkBox Data", ClientAreaSquawkBox);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: SimConnect_MapClientDataNameToID %1") << hr;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mapping needs to be first
|
||||||
|
hr += SimConnect_CreateClientData(hSimConnect, ClientAreaSquawkBox, sbSize, SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: SimConnect_CreateClientData %1") << hr;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSb, 0, sbSize);
|
||||||
|
hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbStandby, 17, 1);
|
||||||
|
hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbIdent, 19, 1);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: SB data area data definitions %1") << hr;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write a default client area so we are not suddenly squawking ident or so
|
||||||
|
DataDefinitionClientAreaSb sbArea;
|
||||||
|
sbArea.setDefaultValues();
|
||||||
|
hr += SimConnect_SetClientData(hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSb, NULL, 0, sbSize, &sbArea);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: SimConnect_SetClientData %1") << hr;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
/* Copyright (C) 2013 VATSIM Community / contributors
|
/* Copyright (C) 2013
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* swift project Community / Contributors
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
*
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||||
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||||
|
* contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
#ifndef BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
|
#ifndef BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
|
||||||
#define BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
|
#define BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
|
||||||
@@ -13,6 +19,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <simconnect/SimConnect.h>
|
#include <simconnect/SimConnect.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
namespace BlackSimPlugin
|
namespace BlackSimPlugin
|
||||||
{
|
{
|
||||||
@@ -57,13 +65,46 @@ namespace BlackSimPlugin
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Data struct simulator environment
|
//! Data struct simulator environment
|
||||||
struct DataDefinitionSimEnvironment {
|
struct DataDefinitionSimEnvironment
|
||||||
|
{
|
||||||
qint32 zuluTimeSeconds; //!< Simulator zulu (GMT) ime in secs.
|
qint32 zuluTimeSeconds; //!< Simulator zulu (GMT) ime in secs.
|
||||||
qint32 localTimeSeconds; //!< Simulator local time in secs.
|
qint32 localTimeSeconds; //!< Simulator local time in secs.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! The whole SB data area
|
||||||
|
struct DataDefinitionClientAreaSb
|
||||||
|
{
|
||||||
|
byte data[128] {}; //!< 128 bytes of data, offsets http://www.squawkbox.ca/doc/sdk/fsuipc.php
|
||||||
|
|
||||||
|
//! Standby = 1, else 0
|
||||||
|
byte getTransponderMode() const { return data[17]; }
|
||||||
|
|
||||||
|
//! Ident = 1, else 0
|
||||||
|
byte getIdent() const { return data[19]; }
|
||||||
|
|
||||||
|
//! Ident?
|
||||||
|
bool isIdent() const { return getIdent() != 0; }
|
||||||
|
|
||||||
|
//! Standby
|
||||||
|
bool isStandby() const { return getTransponderMode() != 0; }
|
||||||
|
|
||||||
|
//! Set default values
|
||||||
|
void setDefaultValues()
|
||||||
|
{
|
||||||
|
std::fill(data, data + 128, 0);
|
||||||
|
data[17] = 1; // standby
|
||||||
|
data[19] = 0; // no ident
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Client areas
|
||||||
|
enum ClientAreaId
|
||||||
|
{
|
||||||
|
ClientAreaSquawkBox
|
||||||
|
};
|
||||||
|
|
||||||
//! Handles SimConnect data definitions
|
//! Handles SimConnect data definitions
|
||||||
class CSimConnectDataDefinition
|
class CSimConnectDefinitions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -74,23 +115,30 @@ namespace BlackSimPlugin
|
|||||||
DataOwnAircraftTitle,
|
DataOwnAircraftTitle,
|
||||||
DataRemoteAircraftSituation,
|
DataRemoteAircraftSituation,
|
||||||
DataGearHandlePosition,
|
DataGearHandlePosition,
|
||||||
DataSimEnvironment
|
DataSimEnvironment,
|
||||||
|
DataClientAreaSb, //!< whole SB area
|
||||||
|
DataClientAreaSbIdent, //!< ident single value
|
||||||
|
DataClientAreaSbStandby //!< standby
|
||||||
};
|
};
|
||||||
|
|
||||||
//! SimConnect request IDs
|
//! SimConnect request IDs
|
||||||
enum Requests
|
enum Request
|
||||||
{
|
{
|
||||||
RequestOwnAircraft,
|
RequestOwnAircraft,
|
||||||
RequestRemoveAircraft,
|
RequestRemoveAircraft,
|
||||||
RequestOwnAircraftTitle,
|
RequestOwnAircraftTitle,
|
||||||
RequestSimEnvironment
|
RequestSimEnvironment,
|
||||||
|
RequestSbData, // SB client area / XPDR mode ..
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CSimConnectDataDefinition();
|
CSimConnectDefinitions();
|
||||||
|
|
||||||
//! Initialize all data definitions
|
//! Initialize all data definitions
|
||||||
static HRESULT initDataDefinitions(const HANDLE hSimConnect);
|
static HRESULT initDataDefinitionsWhenConnected(const HANDLE hSimConnect);
|
||||||
|
|
||||||
|
//! Log message category
|
||||||
|
static QString getMessageCategory() { return "swift.fsx.simconnect"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -105,8 +153,11 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
//! Initialize data definition for Simulator environment
|
//! Initialize data definition for Simulator environment
|
||||||
static HRESULT initSimulatorEnvironment(const HANDLE hSimConnect);
|
static HRESULT initSimulatorEnvironment(const HANDLE hSimConnect);
|
||||||
|
|
||||||
|
//! Initialize the SB data are
|
||||||
|
static HRESULT initSbDataArea(const HANDLE hSimConnect);
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|||||||
@@ -17,10 +17,7 @@ namespace BlackSimPlugin
|
|||||||
namespace Fsx
|
namespace Fsx
|
||||||
{
|
{
|
||||||
CSimConnectObject::CSimConnectObject() :
|
CSimConnectObject::CSimConnectObject() :
|
||||||
m_interpolator(new CInterpolatorLinear()),
|
m_interpolator(new CInterpolatorLinear())
|
||||||
m_requestId(-1),
|
{ }
|
||||||
m_objectId(-1)
|
} // namespace
|
||||||
{
|
} // namespace
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
/* Copyright (C) 2013 VATSIM Community / contributors
|
/* Copyright (C) 2013
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* swift project Community / Contributors
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
*
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||||
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||||
|
* contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
#ifndef BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
#ifndef BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
||||||
#define BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
#define BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
||||||
@@ -50,10 +56,10 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
BlackMisc::Aviation::CCallsign m_callsign;
|
BlackMisc::Aviation::CCallsign m_callsign;
|
||||||
QSharedPointer<BlackCore::IInterpolator> m_interpolator;
|
QSharedPointer<BlackCore::IInterpolator> m_interpolator;
|
||||||
int m_requestId;
|
int m_requestId = -1;
|
||||||
int m_objectId;
|
int m_objectId = -1;
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|||||||
@@ -45,14 +45,7 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
CSimulatorFsx::CSimulatorFsx(QObject *parent) :
|
CSimulatorFsx::CSimulatorFsx(QObject *parent) :
|
||||||
ISimulator(parent),
|
ISimulator(parent),
|
||||||
m_simConnected(false),
|
|
||||||
m_simRunning(false),
|
|
||||||
m_simTimeSynced(false),
|
|
||||||
m_hSimConnect(nullptr),
|
|
||||||
m_nextObjID(1),
|
|
||||||
m_simulatorInfo(CSimulatorInfo::FSX()),
|
m_simulatorInfo(CSimulatorInfo::FSX()),
|
||||||
m_simconnectTimerId(-1),
|
|
||||||
m_skipCockpitUpdateCycles(0),
|
|
||||||
m_fsuipc(new FsCommon::CFsuipc())
|
m_fsuipc(new FsCommon::CFsuipc())
|
||||||
{
|
{
|
||||||
CFsxSimulatorSetup setup;
|
CFsxSimulatorSetup setup;
|
||||||
@@ -77,26 +70,27 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
bool CSimulatorFsx::isFsuipcConnected() const
|
bool CSimulatorFsx::isFsuipcConnected() const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(m_fsuipc);
|
||||||
return m_fsuipc->isConnected();
|
return m_fsuipc->isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSimulatorFsx::connectTo()
|
bool CSimulatorFsx::connectTo()
|
||||||
{
|
{
|
||||||
if (m_simConnected) return true;
|
if (m_simConnected) { return true; }
|
||||||
|
|
||||||
if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0)))
|
if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0)))
|
||||||
{
|
{
|
||||||
emit connectionStatusChanged(ConnectionFailed);
|
emit connectionStatusChanged(ConnectionFailed);
|
||||||
emitSimulatorCombinedStatus();
|
emitSimulatorCombinedStatus(); // all status values at once
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(m_fsuipc);
|
||||||
this->m_fsuipc->connect(); // connect FSUIPC too
|
this->m_fsuipc->connect(); // connect FSUIPC too
|
||||||
}
|
}
|
||||||
|
|
||||||
initEvents();
|
initWhenConnected();
|
||||||
initDataDefinitions();
|
|
||||||
m_simconnectTimerId = startTimer(10);
|
m_simconnectTimerId = startTimer(10);
|
||||||
m_simConnected = true;
|
m_simConnected = true;
|
||||||
|
|
||||||
@@ -112,7 +106,7 @@ namespace BlackSimPlugin
|
|||||||
// simplified connect, timers and signals not in different thread
|
// simplified connect, timers and signals not in different thread
|
||||||
auto asyncConnectFunc = [&]() -> bool
|
auto asyncConnectFunc = [&]() -> bool
|
||||||
{
|
{
|
||||||
if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) return false;
|
if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) { return false; }
|
||||||
this->m_fsuipc->connect(); // FSUIPC too
|
this->m_fsuipc->connect(); // FSUIPC too
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -225,12 +219,17 @@ namespace BlackSimPlugin
|
|||||||
if (newCom1 != this->m_ownAircraft.getCom1System())
|
if (newCom1 != this->m_ownAircraft.getCom1System())
|
||||||
{
|
{
|
||||||
if (newCom1.getFrequencyActive() != this->m_ownAircraft.getCom1System().getFrequencyActive())
|
if (newCom1.getFrequencyActive() != this->m_ownAircraft.getCom1System().getFrequencyActive())
|
||||||
|
{
|
||||||
|
CFrequency newFreq = newCom1.getFrequencyActive();
|
||||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Active,
|
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Active,
|
||||||
CBcdConversions::comFrequencyToBcdHz(newCom1.getFrequencyActive()), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
|
}
|
||||||
if (newCom1.getFrequencyStandby() != this->m_ownAircraft.getCom1System().getFrequencyStandby())
|
if (newCom1.getFrequencyStandby() != this->m_ownAircraft.getCom1System().getFrequencyStandby())
|
||||||
|
{
|
||||||
|
CFrequency newFreq = newCom1.getFrequencyStandby();
|
||||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Standby,
|
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom1Standby,
|
||||||
CBcdConversions::comFrequencyToBcdHz(newCom1.getFrequencyStandby()), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
|
}
|
||||||
this->m_ownAircraft.setCom1System(newCom1);
|
this->m_ownAircraft.setCom1System(newCom1);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
@@ -238,29 +237,54 @@ namespace BlackSimPlugin
|
|||||||
if (newCom2 != this->m_ownAircraft.getCom2System())
|
if (newCom2 != this->m_ownAircraft.getCom2System())
|
||||||
{
|
{
|
||||||
if (newCom2.getFrequencyActive() != this->m_ownAircraft.getCom2System().getFrequencyActive())
|
if (newCom2.getFrequencyActive() != this->m_ownAircraft.getCom2System().getFrequencyActive())
|
||||||
|
{
|
||||||
|
CFrequency newFreq = newCom2.getFrequencyActive();
|
||||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Active,
|
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Active,
|
||||||
CBcdConversions::comFrequencyToBcdHz(newCom2.getFrequencyActive()), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
|
}
|
||||||
if (newCom2.getFrequencyStandby() != this->m_ownAircraft.getCom2System().getFrequencyStandby())
|
if (newCom2.getFrequencyStandby() != this->m_ownAircraft.getCom2System().getFrequencyStandby())
|
||||||
|
{
|
||||||
|
CFrequency newFreq = newCom2.getFrequencyStandby();
|
||||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Standby,
|
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetCom2Standby,
|
||||||
CBcdConversions::comFrequencyToBcdHz(newCom2.getFrequencyStandby()), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
CBcdConversions::comFrequencyToBcdHz(newFreq), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
|
}
|
||||||
this->m_ownAircraft.setCom2System(newCom2);
|
this->m_ownAircraft.setCom2System(newCom2);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newTransponder != this->m_ownAircraft.getTransponder())
|
CTransponder xpdr = this->m_ownAircraft.getTransponder();
|
||||||
|
if (newTransponder != xpdr)
|
||||||
{
|
{
|
||||||
if (newTransponder.getTransponderCode() != this->m_ownAircraft.getTransponder().getTransponderCode())
|
if (newTransponder.getTransponderCode() != xpdr.getTransponderCode())
|
||||||
{
|
{
|
||||||
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTransponderCode,
|
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTransponderCode,
|
||||||
CBcdConversions::transponderCodeToBcd(newTransponder), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
CBcdConversions::transponderCodeToBcd(newTransponder), SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
this->m_ownAircraft.setTransponder(newTransponder);
|
|
||||||
|
if (newTransponder.getTransponderMode() != xpdr.getTransponderMode())
|
||||||
|
{
|
||||||
|
if (m_useSbOffsets)
|
||||||
|
{
|
||||||
|
byte ident = newTransponder.isIdentifying() ? 1 : 0; // 1 is ident
|
||||||
|
byte standby = newTransponder.isInStandby() ? 1 : 0; // 1 is standby
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
hr += SimConnect_SetClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbIdent, NULL, 0, 1, &ident);
|
||||||
|
hr += SimConnect_SetClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbStandby, NULL, 0, 1, &standby);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(this).warning("Setting transponder mode failed (SB offsets)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) { this->m_ownAircraft.setTransponder(newTransponder); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// avoid changes of cockpit back to old values due to an outdated read back value
|
// avoid changes of cockpit back to old values due to an outdated read back value
|
||||||
if (changed) m_skipCockpitUpdateCycles = SkipUpdateCyclesForCockpit;
|
if (changed) { m_skipCockpitUpdateCycles = SkipUpdateCyclesForCockpit; }
|
||||||
|
|
||||||
// bye
|
// bye
|
||||||
return changed;
|
return changed;
|
||||||
@@ -311,21 +335,38 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
void CSimulatorFsx::onSimRunning()
|
void CSimulatorFsx::onSimRunning()
|
||||||
{
|
{
|
||||||
if (m_simRunning) return;
|
if (m_simRunning) { return; }
|
||||||
m_simRunning = true;
|
m_simRunning = true;
|
||||||
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::RequestOwnAircraft,
|
HRESULT hr;
|
||||||
CSimConnectDataDefinition::DataOwnAircraft,
|
hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft,
|
||||||
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME);
|
CSimConnectDefinitions::DataOwnAircraft,
|
||||||
|
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME);
|
||||||
|
|
||||||
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::RequestOwnAircraftTitle,
|
hr += SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraftTitle,
|
||||||
CSimConnectDataDefinition::DataOwnAircraftTitle,
|
CSimConnectDefinitions::DataOwnAircraftTitle,
|
||||||
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND,
|
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND,
|
||||||
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
|
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
|
||||||
|
|
||||||
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::RequestSimEnvironment,
|
hr += SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestSimEnvironment,
|
||||||
CSimConnectDataDefinition::DataSimEnvironment,
|
CSimConnectDefinitions::DataSimEnvironment,
|
||||||
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND,
|
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND,
|
||||||
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
|
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
|
||||||
|
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("FSX plugin: SimConnect_RequestDataOnSimObject failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 ;)
|
||||||
|
hr += SimConnect_RequestClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::RequestSbData,
|
||||||
|
CSimConnectDefinitions::DataClientAreaSb, SIMCONNECT_CLIENT_DATA_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED);
|
||||||
|
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("FSX plugin: SimConnect_RequestClientData failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
emit simulatorStarted();
|
emit simulatorStarted();
|
||||||
emitSimulatorCombinedStatus();
|
emitSimulatorCombinedStatus();
|
||||||
@@ -366,9 +407,8 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
CComSystem com1 = m_ownAircraft.getCom1System(); // set defaults
|
CComSystem com1 = m_ownAircraft.getCom1System(); // set defaults
|
||||||
CComSystem com2 = m_ownAircraft.getCom2System();
|
CComSystem com2 = m_ownAircraft.getCom2System();
|
||||||
CTransponder transponder = m_ownAircraft.getTransponder();
|
|
||||||
|
|
||||||
// When I change cockpit values in the sim (from GUI to simulator, not originating from simulator)
|
// When I change cockpit values in the SIM (from GUI to simulator, not originating from simulator)
|
||||||
// it takes a little while before these values are set in the simulator.
|
// it takes a little while before these values are set in the simulator.
|
||||||
// To avoid jitters, I wait some update cylces to stabilize the values
|
// To avoid jitters, I wait some update cylces to stabilize the values
|
||||||
if (m_skipCockpitUpdateCycles < 1)
|
if (m_skipCockpitUpdateCycles < 1)
|
||||||
@@ -381,22 +421,35 @@ namespace BlackSimPlugin
|
|||||||
com2.setFrequencyStandby(CFrequency(simulatorOwnAircraft.com2StandbyMHz, CFrequencyUnit::MHz()));
|
com2.setFrequencyStandby(CFrequency(simulatorOwnAircraft.com2StandbyMHz, CFrequencyUnit::MHz()));
|
||||||
m_ownAircraft.setCom2System(com2);
|
m_ownAircraft.setCom2System(com2);
|
||||||
|
|
||||||
transponder.setTransponderCode(simulatorOwnAircraft.transponderCode);
|
m_ownAircraft.setTransponderCode(simulatorOwnAircraft.transponderCode);
|
||||||
m_ownAircraft.setTransponder(transponder);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
--m_skipCockpitUpdateCycles;
|
--m_skipCockpitUpdateCycles;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::setSimconnectObjectID(DWORD requestID, DWORD objectID)
|
void CSimulatorFsx::updateOwnAircraftFromSim(DataDefinitionClientAreaSb sbDataArea)
|
||||||
|
{
|
||||||
|
if (sbDataArea.isIdent())
|
||||||
|
{
|
||||||
|
this->m_ownAircraft.setTransponderMode(CTransponder::StateIdent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->m_ownAircraft.setTransponderMode(sbDataArea.isStandby() ? CTransponder::StateStandby : CTransponder::ModeC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimulatorFsx::setSimConnectObjectID(DWORD requestID, DWORD objectID)
|
||||||
{
|
{
|
||||||
// First check, if this request id belongs to us
|
// First check, if this request id belongs to us
|
||||||
auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(),
|
auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(),
|
||||||
[requestID](const CSimConnectObject & obj) { return obj.getRequestId() == static_cast<int>(requestID); });
|
[requestID](const CSimConnectObject & obj) { return obj.getRequestId() == static_cast<int>(requestID); });
|
||||||
|
if (it == m_simConnectObjects.end()) { return; }
|
||||||
|
|
||||||
if (it == m_simConnectObjects.end())
|
// belongs to use
|
||||||
return;
|
|
||||||
|
|
||||||
it->setObjectId(objectID);
|
it->setObjectId(objectID);
|
||||||
SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID);
|
SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID);
|
||||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeLat, 1,
|
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeLat, 1,
|
||||||
@@ -409,26 +462,26 @@ namespace BlackSimPlugin
|
|||||||
DataDefinitionGearHandlePosition gearHandle;
|
DataDefinitionGearHandlePosition gearHandle;
|
||||||
gearHandle.gearHandlePosition = 1;
|
gearHandle.gearHandlePosition = 1;
|
||||||
|
|
||||||
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataGearHandlePosition, objectID, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(gearHandle), &gearHandle);
|
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataGearHandlePosition, objectID, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(gearHandle), &gearHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::timerEvent(QTimerEvent * /* event */)
|
void CSimulatorFsx::timerEvent(QTimerEvent *event)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
ps_dispatch();
|
ps_dispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::ps_dispatch()
|
void CSimulatorFsx::ps_dispatch()
|
||||||
{
|
{
|
||||||
SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this);
|
SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this);
|
||||||
if (this->m_fsuipc) this->m_fsuipc->process();
|
this->m_fsuipc->process();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::ps_connectToFinished()
|
void CSimulatorFsx::ps_connectToFinished()
|
||||||
{
|
{
|
||||||
if (m_watcherConnect.result())
|
if (m_watcherConnect.result())
|
||||||
{
|
{
|
||||||
initEvents();
|
initWhenConnected();
|
||||||
initDataDefinitions();
|
|
||||||
m_simconnectTimerId = startTimer(50);
|
m_simconnectTimerId = startTimer(50);
|
||||||
m_simConnected = true;
|
m_simConnected = true;
|
||||||
|
|
||||||
@@ -449,6 +502,28 @@ namespace BlackSimPlugin
|
|||||||
m_simConnectObjects.remove(simObject.getCallsign());
|
m_simConnectObjects.remove(simObject.getCallsign());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CSimulatorFsx::initWhenConnected()
|
||||||
|
{
|
||||||
|
// called when connected
|
||||||
|
|
||||||
|
HRESULT hr = initEvents();
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("FSX plugin: initEvents failed");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// inti data definitions and SB data area
|
||||||
|
hr += initDataDefinitionsWhenConnected();
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("FSX plugin: initDataDefinitionsWhenConnected failed");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CSimulatorFsx::initEvents()
|
HRESULT CSimulatorFsx::initEvents()
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
@@ -460,7 +535,8 @@ namespace BlackSimPlugin
|
|||||||
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause");
|
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause");
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
qFatal("SimConnect_SubscribeToSystemEvent failed");
|
CLogMessage(this).error("FSX plugin: SimConnect_SubscribeToSystemEvent failed");
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapped events, see event ids here: http://msdn.microsoft.com/en-us/library/cc526980.aspx
|
// Mapped events, see event ids here: http://msdn.microsoft.com/en-us/library/cc526980.aspx
|
||||||
@@ -481,21 +557,23 @@ namespace BlackSimPlugin
|
|||||||
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluMinutes, "ZULU_MINUTES_SET");
|
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EventSetTimeZuluMinutes, "ZULU_MINUTES_SET");
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
qFatal("SimConnect_MapClientEventToSimEvent failed");
|
CLogMessage(this).error("FSX plugin: SimConnect_MapClientEventToSimEvent failed");
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// facility
|
// facility
|
||||||
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, m_nextObjID++);
|
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, m_nextObjID++);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
qFatal("SimConnect_SubscribeToFacilities failed");
|
CLogMessage(this).error("FSX plugin: SimConnect_SubscribeToFacilities failed");
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CSimulatorFsx::initDataDefinitions()
|
HRESULT CSimulatorFsx::initDataDefinitionsWhenConnected()
|
||||||
{
|
{
|
||||||
return CSimConnectDataDefinition::initDataDefinitions(m_hSimConnect);
|
return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSimulatorFsx::updateOtherAircrafts()
|
void CSimulatorFsx::updateOtherAircrafts()
|
||||||
@@ -526,10 +604,10 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
if (simObj.getObjectId() != 0)
|
if (simObj.getObjectId() != 0)
|
||||||
{
|
{
|
||||||
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataRemoteAircraftSituation, simObj.getObjectId(), SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(ddAircraftSituation), &ddAircraftSituation);
|
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSituation, simObj.getObjectId(), SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(ddAircraftSituation), &ddAircraftSituation);
|
||||||
|
|
||||||
// With the following SimConnect call all aircrafts loose their red tag. No idea why though.
|
// With the following SimConnect call all aircrafts loose their red tag. No idea why though.
|
||||||
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataGearHandlePosition, simObj.getObjectId(), SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionGearHandlePosition), &gearHandle);
|
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataGearHandlePosition, simObj.getObjectId(), SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionGearHandlePosition), &gearHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,10 +636,10 @@ namespace BlackSimPlugin
|
|||||||
int simMins = zuluTimeSim.valueRounded(CTimeUnit::min());
|
int simMins = zuluTimeSim.valueRounded(CTimeUnit::min());
|
||||||
int diffMins = qAbs(targetMins - simMins);
|
int diffMins = qAbs(targetMins - simMins);
|
||||||
if (diffMins < 2) return;
|
if (diffMins < 2) return;
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluHours, h, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluHours, h, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluMinutes, m, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluMinutes, m, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||||
|
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
CLogMessage(this).warning("Sending time sync failed!");
|
CLogMessage(this).warning("Sending time sync failed!");
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
//! Simulator info
|
//! Simulator info
|
||||||
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
|
||||||
|
|
||||||
|
//! Log message category
|
||||||
|
static QString getMessageCategory() { return "swift.fsx.plugin"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! SimConnect Event IDs
|
//! SimConnect Event IDs
|
||||||
@@ -76,13 +80,14 @@ namespace BlackSimPlugin
|
|||||||
EventSetTimeZuluYear,
|
EventSetTimeZuluYear,
|
||||||
EventSetTimeZuluDay,
|
EventSetTimeZuluDay,
|
||||||
EventSetTimeZuluHours,
|
EventSetTimeZuluHours,
|
||||||
EventSetTimeZuluMinutes
|
EventSetTimeZuluMinutes,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! FSX Simulator Implementation
|
//! FSX Simulator Implementation
|
||||||
class CSimulatorFsx : public BlackCore::ISimulator
|
class CSimulatorFsx : public BlackCore::ISimulator
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CSimulatorFsx(QObject *parent = nullptr);
|
CSimulatorFsx(QObject *parent = nullptr);
|
||||||
@@ -104,6 +109,9 @@ namespace BlackSimPlugin
|
|||||||
//! SimConnect Callback
|
//! SimConnect Callback
|
||||||
static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
|
static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
|
||||||
|
|
||||||
|
//! Log message category
|
||||||
|
static QString getMessageCategory() { return "swift.fsx.plugin"; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
//! \copydoc ISimulator::connectTo()
|
//! \copydoc ISimulator::connectTo()
|
||||||
@@ -173,12 +181,15 @@ namespace BlackSimPlugin
|
|||||||
//! Called when data about our own aircraft are received
|
//! Called when data about our own aircraft are received
|
||||||
void updateOwnAircraftFromSim(DataDefinitionOwnAircraft simulatorOwnAircraft);
|
void updateOwnAircraftFromSim(DataDefinitionOwnAircraft simulatorOwnAircraft);
|
||||||
|
|
||||||
|
//! Called when data about SB area received
|
||||||
|
void updateOwnAircraftFromSim(DataDefinitionClientAreaSb sbDataArea);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Set ID of a SimConnect object
|
* Set ID of a SimConnect object
|
||||||
* \param requestID
|
* \param requestID
|
||||||
* \param objectID
|
* \param objectID
|
||||||
*/
|
*/
|
||||||
void setSimconnectObjectID(DWORD requestID, DWORD objectID);
|
void setSimConnectObjectID(DWORD requestID, DWORD objectID);
|
||||||
|
|
||||||
//! \private
|
//! \private
|
||||||
void onSimExit();
|
void onSimExit();
|
||||||
@@ -195,7 +206,7 @@ namespace BlackSimPlugin
|
|||||||
//! Dispatch SimConnect messages
|
//! Dispatch SimConnect messages
|
||||||
void ps_dispatch();
|
void ps_dispatch();
|
||||||
|
|
||||||
//! Called when asynchronous connection to Simconnect has finished
|
//! Called when asynchronous connection to SimConnect has finished
|
||||||
void ps_connectToFinished();
|
void ps_connectToFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -203,11 +214,14 @@ namespace BlackSimPlugin
|
|||||||
//! Remove a remote aircraft
|
//! Remove a remote aircraft
|
||||||
void removeRemoteAircraft(const CSimConnectObject &simObject);
|
void removeRemoteAircraft(const CSimConnectObject &simObject);
|
||||||
|
|
||||||
|
//! Init SimConnect
|
||||||
|
HRESULT initWhenConnected();
|
||||||
|
|
||||||
//! Initialize SimConnect system events
|
//! Initialize SimConnect system events
|
||||||
HRESULT initEvents();
|
HRESULT initEvents();
|
||||||
|
|
||||||
//! Initialize SimConnect data definitions
|
//! Initialize SimConnect data definitions
|
||||||
HRESULT initDataDefinitions();
|
HRESULT initDataDefinitionsWhenConnected();
|
||||||
|
|
||||||
//! Update other aircrafts
|
//! Update other aircrafts
|
||||||
void updateOtherAircrafts();
|
void updateOtherAircrafts();
|
||||||
@@ -216,14 +230,15 @@ namespace BlackSimPlugin
|
|||||||
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
|
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
|
||||||
|
|
||||||
static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again
|
static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again
|
||||||
bool m_simConnected = false; //!< Is simulator connected?
|
bool m_simConnected = false; //!< Is simulator connected?
|
||||||
bool m_simRunning = false; //!< Simulator running?
|
bool m_simRunning = false; //!< Simulator running?
|
||||||
bool m_simPaused = false; //!< Simulator paused?
|
bool m_simPaused = false; //!< Simulator paused?
|
||||||
bool m_simTimeSynced = false; //!< Time synchronized?
|
bool m_simTimeSynced = false; //!< Time synchronized?
|
||||||
|
bool m_useSbOffsets = true; //!< SB offsets
|
||||||
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
||||||
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset;
|
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset;
|
||||||
HANDLE m_hSimConnect; //!< Handle to SimConnect object
|
HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object
|
||||||
uint m_nextObjID; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities
|
uint m_nextObjID = 1; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities
|
||||||
QString simulatorDetails;
|
QString simulatorDetails;
|
||||||
BlackSim::CSimulatorInfo m_simulatorInfo;
|
BlackSim::CSimulatorInfo m_simulatorInfo;
|
||||||
BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
|
BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
|
||||||
@@ -231,13 +246,12 @@ namespace BlackSimPlugin
|
|||||||
BlackMisc::Network::CAircraftModel m_aircraftModel;
|
BlackMisc::Network::CAircraftModel m_aircraftModel;
|
||||||
BlackMisc::Aviation::CAirportList m_airportsInRange;
|
BlackMisc::Aviation::CAirportList m_airportsInRange;
|
||||||
|
|
||||||
int m_simconnectTimerId;
|
int m_simconnectTimerId = -1;
|
||||||
int m_skipCockpitUpdateCycles; //!< Skip some update cycles to allow changes in simulator cockpit to be set
|
int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set
|
||||||
QFutureWatcher<bool> m_watcherConnect;
|
QFutureWatcher<bool> m_watcherConnect;
|
||||||
QScopedPointer<FsCommon::CFsuipc> m_fsuipc;
|
QScopedPointer<FsCommon::CFsuipc> m_fsuipc;
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
} // namespace
|
||||||
} // namespace BlackCore
|
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace BlackSimPlugin
|
|||||||
.arg(event->szApplicationName)
|
.arg(event->szApplicationName)
|
||||||
.arg(event->dwApplicationVersionMajor).arg(event->dwApplicationVersionMinor).arg(event->dwApplicationBuildMajor).arg(event->dwApplicationBuildMinor)
|
.arg(event->dwApplicationVersionMajor).arg(event->dwApplicationVersionMinor).arg(event->dwApplicationBuildMajor).arg(event->dwApplicationBuildMinor)
|
||||||
.arg(event->dwSimConnectVersionMajor).arg(event->dwSimConnectVersionMinor).arg(event->dwSimConnectBuildMajor).arg(event->dwSimConnectBuildMinor);
|
.arg(event->dwSimConnectVersionMajor).arg(event->dwSimConnectVersionMinor).arg(event->dwSimConnectBuildMajor).arg(event->dwSimConnectBuildMinor);
|
||||||
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).info(CProject::systemNameAndVersion());
|
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).info("Connect to FSX: %1") << CProject::systemNameAndVersion();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIMCONNECT_RECV_ID_EXCEPTION:
|
case SIMCONNECT_RECV_ID_EXCEPTION:
|
||||||
@@ -52,7 +52,7 @@ namespace BlackSimPlugin
|
|||||||
ex.sprintf("Exception=%d SendID=%d Index=%d cbData=%d",
|
ex.sprintf("Exception=%d SendID=%d Index=%d cbData=%d",
|
||||||
static_cast<int>(exception->dwException), static_cast<int>(exception->dwSendID),
|
static_cast<int>(exception->dwException), static_cast<int>(exception->dwSendID),
|
||||||
static_cast<int>(exception->dwIndex), static_cast<int>(cbData));
|
static_cast<int>(exception->dwIndex), static_cast<int>(cbData));
|
||||||
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).error("Caught simConnect exception: %1 %2")
|
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).error("Caught FSX simConnect exception: %1 %2")
|
||||||
<< CSimConnectUtilities::simConnectExceptionToString((SIMCONNECT_EXCEPTION)exception->dwException)
|
<< CSimConnectUtilities::simConnectExceptionToString((SIMCONNECT_EXCEPTION)exception->dwException)
|
||||||
<< ex;
|
<< ex;
|
||||||
break;
|
break;
|
||||||
@@ -93,9 +93,11 @@ namespace BlackSimPlugin
|
|||||||
SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
|
SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
|
||||||
if (event->uEventID == SystemEventObjectAdded)
|
if (event->uEventID == SystemEventObjectAdded)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
}
|
}
|
||||||
else if (event->uEventID == SystemEventObjectRemoved)
|
else if (event->uEventID == SystemEventObjectRemoved)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -115,7 +117,7 @@ namespace BlackSimPlugin
|
|||||||
case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
|
case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
|
||||||
{
|
{
|
||||||
SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(pData);
|
SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(pData);
|
||||||
simulatorFsx->setSimconnectObjectID(event->dwRequestID, event->dwObjectID);
|
simulatorFsx->setSimConnectObjectID(event->dwRequestID, event->dwObjectID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
||||||
@@ -123,14 +125,14 @@ namespace BlackSimPlugin
|
|||||||
SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData;
|
SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData;
|
||||||
switch (pObjData->dwRequestID)
|
switch (pObjData->dwRequestID)
|
||||||
{
|
{
|
||||||
case CSimConnectDataDefinition::RequestOwnAircraft:
|
case CSimConnectDefinitions::RequestOwnAircraft:
|
||||||
{
|
{
|
||||||
DataDefinitionOwnAircraft *ownAircaft;
|
DataDefinitionOwnAircraft *ownAircaft;
|
||||||
ownAircaft = (DataDefinitionOwnAircraft *)&pObjData->dwData;
|
ownAircaft = (DataDefinitionOwnAircraft *)&pObjData->dwData;
|
||||||
simulatorFsx->updateOwnAircraftFromSim(*ownAircaft);
|
simulatorFsx->updateOwnAircraftFromSim(*ownAircaft);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CSimConnectDataDefinition::RequestOwnAircraftTitle:
|
case CSimConnectDefinitions::RequestOwnAircraftTitle:
|
||||||
{
|
{
|
||||||
DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData;
|
DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData;
|
||||||
CAircraftModel model;
|
CAircraftModel model;
|
||||||
@@ -138,7 +140,7 @@ namespace BlackSimPlugin
|
|||||||
simulatorFsx->setAircraftModel(model);
|
simulatorFsx->setAircraftModel(model);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CSimConnectDataDefinition::RequestSimEnvironment:
|
case CSimConnectDefinitions::RequestSimEnvironment:
|
||||||
{
|
{
|
||||||
DataDefinitionSimEnvironment *simEnv = (DataDefinitionSimEnvironment *) &pObjData->dwData;
|
DataDefinitionSimEnvironment *simEnv = (DataDefinitionSimEnvironment *) &pObjData->dwData;
|
||||||
qint32 zh = simEnv->zuluTimeSeconds / 3600;
|
qint32 zh = simEnv->zuluTimeSeconds / 3600;
|
||||||
@@ -179,12 +181,24 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SIMCONNECT_RECV_ID_CLIENT_DATA:
|
||||||
|
{
|
||||||
|
if (!simulatorFsx->m_useSbOffsets) { break; }
|
||||||
|
SIMCONNECT_RECV_CLIENT_DATA *clientData = (SIMCONNECT_RECV_CLIENT_DATA *)pData;
|
||||||
|
if (simulatorFsx->m_useSbOffsets && clientData->dwRequestID == CSimConnectDefinitions::RequestSbData)
|
||||||
|
{
|
||||||
|
//! \todo why is offset 19 ident 2/0 ?
|
||||||
|
//! In FSUIPC it is 0/1, according to documentation it is 0/1 but I receive 2/0 here
|
||||||
|
DataDefinitionClientAreaSb *sbData = (DataDefinitionClientAreaSb *) &clientData->dwData;
|
||||||
|
simulatorFsx->updateOwnAircraftFromSim(*sbData);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} // main switch
|
} // main switch
|
||||||
} // method
|
} // method
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user