mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-02 06:35:52 +08:00
refs #891, FSX using common base class
This commit is contained in:
committed by
Mathew Sutcliffe
parent
70045c046d
commit
5d8ed66931
@@ -10,7 +10,7 @@ TEMPLATE = lib
|
||||
CONFIG += plugin shared
|
||||
CONFIG += blackmisc blackcore
|
||||
|
||||
LIBS += -lsimulatorfscommon -lSimConnect -lFSUIPC_User
|
||||
LIBS += -lsimulatorfscommon -lsimulatorfsxcommon -lSimConnect -lFSUIPC_User
|
||||
|
||||
# required for FSUIPC
|
||||
win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift Project Community / Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "simconnectdatadefinition.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include <tuple>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
CSimConnectDefinitions::CSimConnectDefinitions() { }
|
||||
|
||||
HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
hr += initOwnAircraft(hSimConnect);
|
||||
hr += initRemoteAircraft(hSimConnect);
|
||||
hr += initRemoteAircraftSimData(hSimConnect);
|
||||
hr += initSimulatorEnvironment(hSimConnect);
|
||||
hr += initSbDataArea(hSimConnect);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CSimConnectDefinitions::initOwnAircraft(const HANDLE hSimConnect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE LATITUDE", "Degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE LONGITUDE", "Degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE ALTITUDE", "Feet");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE ALT ABOVE GROUND", "Feet");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "STATIC CG TO GROUND", "Feet");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE HEADING DEGREES TRUE", "Degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE PITCH DEGREES", "Degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE BANK DEGREES", "Degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND VELOCITY", "Knots");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND ALTITUDE", "Feet");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "SIM ON GROUND", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT STROBE", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT LANDING", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT TAXI", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT BEACON", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT NAV", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT LOGO", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "TRANSPONDER CODE:1", NULL);
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM ACTIVE FREQUENCY:1", "MHz");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM ACTIVE FREQUENCY:2", "MHz");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM STANDBY FREQUENCY:1", "MHz");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM STANDBY FREQUENCY:2", "MHz");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "FLAPS HANDLE PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "SPOILERS HANDLE POSITION", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GEAR HANDLE POSITION", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "NUMBER OF ENGINES", "Number");
|
||||
// Simconnect supports index 1 - 4
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GENERAL ENG COMBUSTION:1", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GENERAL ENG COMBUSTION:2", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GENERAL ENG COMBUSTION:3", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GENERAL ENG COMBUSTION:4", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE", NULL, SIMCONNECT_DATATYPE_STRING256);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initOwnAircraft %1") << hr;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CSimConnectDefinitions::initRemoteAircraft(const HANDLE hSimConnect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
// Position
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPosition, "Initial Position", NULL, SIMCONNECT_DATATYPE_INITPOSITION);
|
||||
|
||||
// Hint: "Bool" and "Percent .." are units name
|
||||
// default data type is SIMCONNECT_DATATYPE_FLOAT64 -> double
|
||||
|
||||
// Flaps
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LEADING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LEADING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "TRAILING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "TRAILING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
|
||||
|
||||
// Gear & Spoiler
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GEAR HANDLE POSITION", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "SPOILERS HANDLE POSITION", "Percent Over 100");
|
||||
|
||||
// Engines
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:1", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:2", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:3", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:4", "Bool");
|
||||
|
||||
// Lights (other definition)
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT STROBE", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT LANDING", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT TAXI", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT BEACON", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT NAV", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT LOGO", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT NAV", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT RECOGNITION", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT CABIN", "Bool");
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSituation %1") << hr;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CSimConnectDefinitions::initRemoteAircraftSimData(const HANDLE hSimConnect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "PLANE LATITUDE", "degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "PLANE LONGITUDE", "degrees");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "PLANE ALTITUDE", "Feet");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "GROUND ALTITUDE", "Feet");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSimData, "STATIC CG TO GROUND", "Feet");
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSimData %1") << hr;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CSimConnectDefinitions::initSimulatorEnvironment(const HANDLE hSimConnect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "ZULU TIME", "", SIMCONNECT_DATATYPE_INT32);
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "LOCAL TIME", "", SIMCONNECT_DATATYPE_INT32);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initSimulatorEnvironment %1") << 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, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT, 0, sbSize, &sbArea);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: SimConnect_SetClientData %1") << hr;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool DataDefinitionRemoteAircraftParts::operator==(const DataDefinitionRemoteAircraftParts &rhs) const
|
||||
{
|
||||
return std::tie(flapsLeadingEdgeLeftPercent, flapsLeadingEdgeRightPercent, flapsTrailingEdgeLeftPercent, flapsTrailingEdgeRightPercent,
|
||||
gearHandlePosition, spoilersHandlePosition,
|
||||
engine1Combustion, engine2Combustion, engine3Combustion, engine4Combustion) ==
|
||||
std::tie(rhs.flapsLeadingEdgeLeftPercent, rhs.flapsLeadingEdgeRightPercent, rhs.flapsTrailingEdgeLeftPercent, rhs.flapsTrailingEdgeRightPercent,
|
||||
rhs.gearHandlePosition, rhs.spoilersHandlePosition,
|
||||
rhs.engine1Combustion, rhs.engine2Combustion, rhs.engine3Combustion, rhs.engine4Combustion);
|
||||
}
|
||||
|
||||
void DataDefinitionRemoteAircraftParts::setAllEngines(bool on)
|
||||
{
|
||||
engine1Combustion = on ? 1 : 0;
|
||||
engine2Combustion = on ? 1 : 0;
|
||||
engine3Combustion = on ? 1 : 0;
|
||||
engine4Combustion = on ? 1 : 0;
|
||||
}
|
||||
|
||||
void DataDefinitionRemoteAircraftParts::resetAllFlaps()
|
||||
{
|
||||
flapsLeadingEdgeLeftPercent = 0;
|
||||
flapsLeadingEdgeRightPercent = 0;
|
||||
flapsTrailingEdgeLeftPercent = 0;
|
||||
flapsTrailingEdgeRightPercent = 0;
|
||||
}
|
||||
|
||||
void DataDefinitionRemoteAircraftParts::resetSpoilers()
|
||||
{
|
||||
spoilersHandlePosition = 0;
|
||||
}
|
||||
|
||||
CAircraftLights DataDefinitionRemoteAircraftLights::toLights() const
|
||||
{
|
||||
return CAircraftLights(lightStrobe, lightLanding, lightTaxi, lightBeacon, lightNav, lightLogo, lightRecognition, lightCabin);
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
@@ -1,230 +0,0 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* 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
|
||||
#define BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include "blackmisc/aviation/aircraftlights.h"
|
||||
#include <simconnect/SimConnect.h>
|
||||
#include <windows.h>
|
||||
#include <algorithm>
|
||||
#include <QString>
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
//! Data struct of our own aircraft
|
||||
//! \sa SimConnect variables http://msdn.microsoft.com/en-us/library/cc526981.aspx
|
||||
//! \sa SimConnect events http://msdn.microsoft.com/en-us/library/cc526980.aspx
|
||||
struct DataDefinitionOwnAircraft
|
||||
{
|
||||
double latitude; //!< Latitude (deg)
|
||||
double longitude; //!< Longitude (deg)
|
||||
double altitude; //!< Altitude (ft)
|
||||
double altitudeAGL; //!< Altitude above ground (ft)
|
||||
double cgToGround; //!< Static CG to ground (ft)
|
||||
double trueHeading; //!< True heading (deg)
|
||||
double pitch; //!< Pitch (deg)
|
||||
double bank; //!< Bank (deg)
|
||||
double velocity; //!< Ground velocity
|
||||
double elevation; //!< Elevation (ft)
|
||||
double simOnGround; //!< Is aircraft on ground?
|
||||
|
||||
double lightStrobe; //!< Is strobe light on?
|
||||
double lightLanding; //!< Is landing light on?
|
||||
double lightTaxi; //!< Is taxi light on?
|
||||
double lightBeacon; //!< Is beacon light on?
|
||||
double lightNav; //!< Is nav light on?
|
||||
double lightLogo; //!< Is logo light on?
|
||||
|
||||
double transponderCode; //!< Transponder Code
|
||||
double com1ActiveMHz; //!< COM1 active frequency
|
||||
double com2ActiveMHz; //!< COM2 active frequency
|
||||
double com1StandbyMHz; //!< COM1 standby frequency
|
||||
double com2StandbyMHz; //!< COM1 standby frequency
|
||||
|
||||
double flapsHandlePosition; //!< Flaps handle position in percent
|
||||
double spoilersHandlePosition; //!< Spoilers out?
|
||||
double gearHandlePosition; //!< Gear handle position
|
||||
|
||||
double numberOfEngines; //!< Number of engines
|
||||
double engine1Combustion; //!< Engine 1 combustion flag
|
||||
double engine2Combustion; //!< Engine 2 combustion flag
|
||||
double engine3Combustion; //!< Engine 3 combustion flag
|
||||
double engine4Combustion; //!< Engine 4 combustion flag
|
||||
};
|
||||
|
||||
//! Data struct of aircraft position
|
||||
struct DataDefinitionOwnAircraftModel
|
||||
{
|
||||
char title[256]; //!< Aircraft model string
|
||||
};
|
||||
|
||||
//! Data struct of remote aircraft parts
|
||||
struct DataDefinitionRemoteAircraftParts
|
||||
{
|
||||
double flapsLeadingEdgeLeftPercent; //!< Leading edge left in percent
|
||||
double flapsLeadingEdgeRightPercent; //!< Leading edge right in percent
|
||||
double flapsTrailingEdgeLeftPercent; //!< Trailing edge left in percent
|
||||
double flapsTrailingEdgeRightPercent; //!< Trailing edge right in percent
|
||||
double gearHandlePosition; //!< Gear handle position
|
||||
double spoilersHandlePosition; //!< Spoilers out?
|
||||
double engine1Combustion; //!< Engine 1 combustion flag
|
||||
double engine2Combustion; //!< Engine 2 combustion flag
|
||||
double engine3Combustion; //!< Engine 3 combustion flag
|
||||
double engine4Combustion; //!< Engine 4 combustion flag
|
||||
|
||||
//! Equal to other parts
|
||||
bool operator==(const DataDefinitionRemoteAircraftParts &rhs) const;
|
||||
|
||||
//! All engines on/off
|
||||
void setAllEngines(bool on);
|
||||
|
||||
//! Reset all flaps
|
||||
void resetAllFlaps();
|
||||
|
||||
//! Reset spoilers
|
||||
void resetSpoilers();
|
||||
};
|
||||
|
||||
//! Data for aircraft lighs
|
||||
struct DataDefinitionRemoteAircraftLights
|
||||
{
|
||||
double lightStrobe; //!< Is strobe light on?
|
||||
double lightLanding; //!< Is landing light on?
|
||||
double lightTaxi; //!< Is taxi light on?
|
||||
double lightBeacon; //!< Is beacon light on?
|
||||
double lightNav; //!< Is nav light on?
|
||||
double lightLogo; //!< Is logo light on?
|
||||
double lightRecognition; //!< Is recognition light on
|
||||
double lightCabin; //!< Is cabin light on
|
||||
|
||||
//! Convert to lights
|
||||
BlackMisc::Aviation::CAircraftLights toLights() const;
|
||||
};
|
||||
|
||||
//! Data for AI object sent back from simulator
|
||||
struct DataDefinitionRemoteAircraftSimData
|
||||
{
|
||||
double latitude; //!< Latitude (deg)
|
||||
double longitude; //!< Longitude (deg)
|
||||
double altitude; //!< Altitude (ft)
|
||||
double elevation; //!< Elevation (ft)
|
||||
double cgToGround; //!< Static CG to ground (ft)
|
||||
|
||||
//! Above ground ft
|
||||
double aboveGround() const { return altitude - elevation; }
|
||||
};
|
||||
|
||||
//! Data struct simulator environment
|
||||
struct DataDefinitionSimEnvironment
|
||||
{
|
||||
qint32 zuluTimeSeconds; //!< Simulator zulu (GMT) ime 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, static_cast<byte>(0));
|
||||
data[17] = 1; // standby
|
||||
data[19] = 0; // no ident
|
||||
}
|
||||
};
|
||||
|
||||
//! Client areas
|
||||
enum ClientAreaId
|
||||
{
|
||||
ClientAreaSquawkBox
|
||||
};
|
||||
|
||||
//! Handles SimConnect data definitions
|
||||
class CSimConnectDefinitions
|
||||
{
|
||||
public:
|
||||
//! SimConnect definiton IDs
|
||||
enum DataDefiniton
|
||||
{
|
||||
DataOwnAircraft,
|
||||
DataOwnAircraftTitle,
|
||||
DataRemoteAircraftLights,
|
||||
DataRemoteAircraftParts,
|
||||
DataRemoteAircraftPosition,
|
||||
DataRemoteAircraftSimData,
|
||||
DataSimEnvironment,
|
||||
DataClientAreaSb, //!< whole SB area
|
||||
DataClientAreaSbIdent, //!< ident single value
|
||||
DataClientAreaSbStandby //!< standby
|
||||
};
|
||||
|
||||
//! SimConnect request IDs
|
||||
enum Request
|
||||
{
|
||||
RequestOwnAircraft,
|
||||
RequestRemoveAircraft,
|
||||
RequestOwnAircraftTitle,
|
||||
RequestSimEnvironment,
|
||||
RequestSbData, //!< SB client area / XPDR mode
|
||||
RequestEndMarker //!< free request ids can start here
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
CSimConnectDefinitions();
|
||||
|
||||
//! Initialize all data definitions
|
||||
static HRESULT initDataDefinitionsWhenConnected(const HANDLE hSimConnect);
|
||||
|
||||
//! Log message category
|
||||
static QString getLogCategory() { return "swift.fsx.simconnect"; }
|
||||
|
||||
private:
|
||||
//! Initialize data definition for our own aircraft
|
||||
static HRESULT initOwnAircraft(const HANDLE hSimConnect);
|
||||
|
||||
//! Initialize data definition for remote aircraft
|
||||
static HRESULT initRemoteAircraft(const HANDLE hSimConnect);
|
||||
|
||||
//! Initialize data for remote aircraft queried from simulator
|
||||
static HRESULT initRemoteAircraftSimData(const HANDLE hSimConnect);
|
||||
|
||||
//! Initialize data definition for Simulator environment
|
||||
static HRESULT initSimulatorEnvironment(const HANDLE hSimConnect);
|
||||
|
||||
//! Initialize the SB data are
|
||||
static HRESULT initSbDataArea(const HANDLE hSimConnect);
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
@@ -1,108 +0,0 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift Project Community / Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "simconnectobject.h"
|
||||
#include "blackmisc/simulation/interpolatorlinear.h"
|
||||
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Simulation;
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
CSimConnectObject::CSimConnectObject()
|
||||
{ }
|
||||
|
||||
CSimConnectObject::CSimConnectObject(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, DWORD requestId,
|
||||
BlackMisc::Simulation::CInterpolationLogger *logger) :
|
||||
m_aircraft(aircraft), m_requestId(requestId), m_validRequestId(true),
|
||||
m_interpolator(QSharedPointer<BlackMisc::Simulation::CInterpolatorLinear>::create(aircraft.getCallsign()))
|
||||
{
|
||||
m_interpolator->attachLogger(logger);
|
||||
}
|
||||
|
||||
bool CSimConnectObject::isPendingAdded() const
|
||||
{
|
||||
return !this->hasValidRequestAndObjectId() || !this->m_confirmedAdded;
|
||||
}
|
||||
|
||||
bool CSimConnectObject::isConfirmedAdded() const
|
||||
{
|
||||
Q_ASSERT_X(!m_confirmedAdded || this->hasValidRequestAndObjectId(), Q_FUNC_INFO, "confirmed but invalid ids");
|
||||
return m_confirmedAdded;
|
||||
}
|
||||
|
||||
void CSimConnectObject::setConfirmedAdded(bool confirm)
|
||||
{
|
||||
m_confirmedAdded = confirm;
|
||||
m_aircraft.setRendered(true);
|
||||
}
|
||||
|
||||
void CSimConnectObject::setPendingRemoved(bool pending)
|
||||
{
|
||||
m_pendingRemoved = pending;
|
||||
m_aircraft.setRendered(false);
|
||||
}
|
||||
|
||||
bool CSimConnectObject::hasValidRequestAndObjectId() const
|
||||
{
|
||||
return this->hasValidRequestId() && this->hasValidObjectId();
|
||||
}
|
||||
|
||||
bool CSimConnectObjects::setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId)
|
||||
{
|
||||
// First check, if this request id belongs to us
|
||||
auto it = std::find_if(this->begin(), this->end(), [requestId](const CSimConnectObject & obj) { return obj.getRequestId() == requestId; });
|
||||
if (it == this->end()) { return false; }
|
||||
|
||||
// belongs to us
|
||||
it->setObjectId(objectId);
|
||||
return true;
|
||||
}
|
||||
|
||||
CCallsign CSimConnectObjects::getCallsignForObjectId(DWORD objectId) const
|
||||
{
|
||||
return getSimObjectForObjectId(objectId).getCallsign();
|
||||
}
|
||||
|
||||
CSimConnectObject CSimConnectObjects::getSimObjectForObjectId(DWORD objectId) const
|
||||
{
|
||||
for (const CSimConnectObject &simObject : this->values())
|
||||
{
|
||||
if (simObject.getObjectId() == objectId) { return simObject; }
|
||||
}
|
||||
return CSimConnectObject();
|
||||
}
|
||||
|
||||
CSimConnectObject CSimConnectObjects::getSimObjectForRequestId(DWORD requestId) const
|
||||
{
|
||||
for (const CSimConnectObject &simObject : this->values())
|
||||
{
|
||||
if (simObject.getRequestId() == requestId) { return simObject; }
|
||||
}
|
||||
return CSimConnectObject();
|
||||
}
|
||||
|
||||
bool CSimConnectObjects::isKnownSimObjectId(DWORD objectId) const
|
||||
{
|
||||
const CSimConnectObject simObject(getSimObjectForObjectId(objectId));
|
||||
return simObject.hasValidRequestAndObjectId() && objectId == simObject.getObjectId();
|
||||
}
|
||||
|
||||
bool CSimConnectObjects::containsPendingAdd() const
|
||||
{
|
||||
for (const CSimConnectObject &simObject : this->values())
|
||||
{
|
||||
if (simObject.isPendingAdded()) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
@@ -1,161 +0,0 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* 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
|
||||
#define BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
||||
|
||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||
#include "simconnectdatadefinition.h"
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
class CInterpolatorLinear;
|
||||
class CInterpolationLogger;
|
||||
}
|
||||
}
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
//! Class representing a SimConnect object
|
||||
class CSimConnectObject
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
CSimConnectObject();
|
||||
|
||||
//! Constructor
|
||||
CSimConnectObject(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, DWORD requestId,
|
||||
BlackMisc::Simulation::CInterpolationLogger *logger);
|
||||
|
||||
//! Destructor
|
||||
~CSimConnectObject() {}
|
||||
|
||||
//! Get Callsign
|
||||
const BlackMisc::Aviation::CCallsign &getCallsign() const { return m_aircraft.getCallsign(); }
|
||||
|
||||
//! Simulated aircraft (as added)
|
||||
const BlackMisc::Simulation::CSimulatedAircraft &getAircraft() const { return m_aircraft; }
|
||||
|
||||
//! Simulated aircraft model string
|
||||
const QString &getAircraftModelString() const { return m_aircraft.getModelString(); }
|
||||
|
||||
//! Interpolator
|
||||
BlackMisc::Simulation::CInterpolatorLinear *getInterpolator() const { return m_interpolator.data(); }
|
||||
|
||||
//! Get current lights (requested from simulator)
|
||||
const BlackMisc::Aviation::CAircraftLights &getCurrentLightsInSimulator() const { return m_currentLightsInSim; }
|
||||
|
||||
//! Set current lights when received from simulator
|
||||
void setCurrentLightsInSimulator(const BlackMisc::Aviation::CAircraftLights &lights) { m_currentLightsInSim = lights; }
|
||||
|
||||
//! Parts as sent to simulator
|
||||
const DataDefinitionRemoteAircraftParts &getPartsAsSent() const { return m_partsAsSent; }
|
||||
|
||||
//! Parts as sent to simulator
|
||||
void setPartsAsSent(const DataDefinitionRemoteAircraftParts &parts) { m_partsAsSent = parts; }
|
||||
|
||||
//! Lights as sent to simulator
|
||||
const BlackMisc::Aviation::CAircraftLights &getLightsAsSent() const { return m_lightsAsSent; }
|
||||
|
||||
//! Lights as sent to simulator
|
||||
void setLightsAsSent(const BlackMisc::Aviation::CAircraftLights &lights) { m_lightsAsSent = lights; }
|
||||
|
||||
//! How often do we request data from simulator for this remote aircraft
|
||||
SIMCONNECT_PERIOD getSimDataPeriod() const { return m_requestSimDataPeriod; }
|
||||
|
||||
//! How often do we request data from simulator for this remote aircraft
|
||||
void setSimDataPeriod(SIMCONNECT_PERIOD period) { m_requestSimDataPeriod = period; }
|
||||
|
||||
//! Set Simconnect request id
|
||||
void setRequestId(DWORD id) { m_requestId = id; m_validRequestId = true; }
|
||||
|
||||
//! Get Simconnect request id
|
||||
DWORD getRequestId() const { return m_requestId; }
|
||||
|
||||
//! Set Simconnect object id
|
||||
void setObjectId(DWORD id) { m_objectId = id; m_validObjectId = true; }
|
||||
|
||||
//! Set Simconnect object id
|
||||
DWORD getObjectId() const { return m_objectId; }
|
||||
|
||||
//! Valid request id?
|
||||
bool hasValidRequestId() const { return this->m_validRequestId; }
|
||||
|
||||
//! Valid object id?
|
||||
bool hasValidObjectId() const { return this->m_validObjectId; }
|
||||
|
||||
//! Object is requested, not yet added
|
||||
bool isPendingAdded() const;
|
||||
|
||||
//! Adding is confirmed
|
||||
bool isConfirmedAdded() const;
|
||||
|
||||
//! Marked as confirmed
|
||||
void setConfirmedAdded(bool confirm);
|
||||
|
||||
//! Removing is pending
|
||||
bool isPendingRemoved() const { return m_pendingRemoved; }
|
||||
|
||||
//! Marked as confirmed
|
||||
void setPendingRemoved(bool pending);
|
||||
|
||||
//! VTOL?
|
||||
bool isVtol() const { return m_aircraft.isVtol(); }
|
||||
|
||||
//! Was the object really added to SIM
|
||||
bool hasValidRequestAndObjectId() const;
|
||||
|
||||
private:
|
||||
BlackMisc::Simulation::CSimulatedAircraft m_aircraft; //!< corresponding aircraft
|
||||
DWORD m_requestId = 0;
|
||||
DWORD m_objectId = 0;
|
||||
bool m_validRequestId = false;
|
||||
bool m_validObjectId = false;
|
||||
bool m_confirmedAdded = false;
|
||||
bool m_pendingRemoved = false;
|
||||
int m_lightsRequestedAt = -1;
|
||||
DataDefinitionRemoteAircraftParts m_partsAsSent {}; //!< parts as sent
|
||||
BlackMisc::Aviation::CAircraftLights m_currentLightsInSim { nullptr }; //!< current lights to know state for toggling
|
||||
BlackMisc::Aviation::CAircraftLights m_lightsAsSent { nullptr }; //!< lights as sent to simulator
|
||||
SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation
|
||||
QSharedPointer<BlackMisc::Simulation::CInterpolatorLinear> m_interpolator; //!< shared pointer because CSimConnectObject can be copied
|
||||
};
|
||||
|
||||
//! Simulator objects (aka AI aircraft)
|
||||
class CSimConnectObjects : public QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject>
|
||||
{
|
||||
public:
|
||||
//! Set ID of a SimConnect object, so far we only have an request id in the object
|
||||
bool setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId);
|
||||
|
||||
//! Find which callsign belongs to the object id
|
||||
BlackMisc::Aviation::CCallsign getCallsignForObjectId(DWORD objectId) const;
|
||||
|
||||
//! Get object per object id
|
||||
CSimConnectObject getSimObjectForObjectId(DWORD objectId) const;
|
||||
|
||||
//! Get object per request id
|
||||
CSimConnectObject getSimObjectForRequestId(DWORD requestId) const;
|
||||
|
||||
//! Is the object id one of our AI objects?
|
||||
bool isKnownSimObjectId(DWORD objectId) const;
|
||||
|
||||
//! Pending add condition
|
||||
bool containsPendingAdd() const;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,85 +9,17 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKSIMPLUGIN_SIMULATOR_FSX_H
|
||||
#define BLACKSIMPLUGIN_SIMULATOR_FSX_H
|
||||
#ifndef BLACKSIMPLUGIN_FSX_SIMULATORFSX_H
|
||||
#define BLACKSIMPLUGIN_FSX_SIMULATORFSX_H
|
||||
|
||||
#include "simconnectdatadefinition.h"
|
||||
#include "simconnectobject.h"
|
||||
#include "../fscommon/simulatorfscommon.h"
|
||||
#include "blackcore/simulator.h"
|
||||
#include "blackmisc/simulation/interpolatorlinear.h"
|
||||
#include "blackmisc/simulation/simulatorplugininfo.h"
|
||||
#include "blackmisc/simulation/simulatorsettings.h"
|
||||
#include "blackmisc/simulation/aircraftmodel.h"
|
||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||
#include "blackmisc/aviation/airportlist.h"
|
||||
#include "blackmisc/statusmessage.h"
|
||||
#include "blackmisc/network/client.h"
|
||||
#include "blackmisc/pixmap.h"
|
||||
|
||||
#include <simconnect/SimConnect.h>
|
||||
#include <QObject>
|
||||
#include <QtPlugin>
|
||||
#include <QHash>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include "../fsxcommon/simulatorfsxcommon.h"
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
//! SimConnect Event IDs
|
||||
enum EventIds
|
||||
{
|
||||
SystemEventSimStatus,
|
||||
SystemEventObjectAdded,
|
||||
SystemEventObjectRemoved,
|
||||
SystemEventSlewToggle,
|
||||
SystemEventFrame,
|
||||
SystemEventPause,
|
||||
SystemEventFlightLoaded,
|
||||
EventPauseToggle,
|
||||
EventFreezeLat,
|
||||
EventFreezeAlt,
|
||||
EventFreezeAtt,
|
||||
EventSetCom1Active,
|
||||
EventSetCom2Active,
|
||||
EventSetCom1Standby,
|
||||
EventSetCom2Standby,
|
||||
EventSetTransponderCode,
|
||||
EventTextMessage,
|
||||
EventSetTimeZuluYear,
|
||||
EventSetTimeZuluDay,
|
||||
EventSetTimeZuluHours,
|
||||
EventSetTimeZuluMinutes,
|
||||
// ------------ lights -------------
|
||||
EventLandingLightsOff,
|
||||
EventLandinglightsOn,
|
||||
EventLandingLightsSet,
|
||||
EventLandingLightsToggle,
|
||||
EventPanelLightsOff,
|
||||
EventPanelLightsOn,
|
||||
EventPanelLightsSet,
|
||||
EventStrobesOff,
|
||||
EventStrobesOn,
|
||||
EventStrobesSet,
|
||||
EventStrobesToggle,
|
||||
EventToggleBeaconLights,
|
||||
EventToggleCabinLights,
|
||||
EventToggleLogoLights,
|
||||
EventToggleNavLights,
|
||||
EventToggleRecognitionLights,
|
||||
EventToggleTaxiLights,
|
||||
EventToggleWingLights
|
||||
};
|
||||
|
||||
//! FSX Simulator Implementation
|
||||
class CSimulatorFsx : public BlackSimPlugin::FsCommon::CSimulatorFsCommon
|
||||
class CSimulatorFsx : public BlackSimPlugin::FsxCommon::CSimulatorFsxCommon
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -99,213 +31,18 @@ namespace BlackSimPlugin
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
BlackMisc::Weather::IWeatherGridProvider *weatherGridProvider,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CSimulatorFsx();
|
||||
|
||||
//! SimConnect Callback
|
||||
static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
|
||||
|
||||
//! \name ISimulator implementations
|
||||
//! @{
|
||||
virtual bool connectTo() override;
|
||||
virtual bool disconnectFrom() override;
|
||||
virtual bool physicallyAddRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &newRemoteAircraft) override;
|
||||
virtual bool physicallyRemoveRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
virtual int physicallyRemoveAllRemoteAircraft() override;
|
||||
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Simulation::CSimulatedAircraft &ownAircraft, const BlackMisc::CIdentifier &originator) override;
|
||||
virtual void displayStatusMessage(const BlackMisc::CStatusMessage &message) const override;
|
||||
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
|
||||
virtual bool isPhysicallyRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||
virtual BlackMisc::Aviation::CCallsignSet physicallyRenderedAircraft() const override;
|
||||
//! @}
|
||||
|
||||
protected:
|
||||
//! \name Interface implementations
|
||||
//! @{
|
||||
virtual bool isConnected() const override;
|
||||
virtual bool isSimulating() const override;
|
||||
//! @}
|
||||
|
||||
//! \name Base class overrides
|
||||
//! @{
|
||||
virtual void reset() override;
|
||||
virtual void clearAllAircraft() override;
|
||||
virtual void initSimulatorInternals() override;
|
||||
virtual void injectWeatherGrid(const BlackMisc::Weather::CWeatherGrid &weatherGrid) override;
|
||||
virtual void ps_remoteProviderAddAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) override;
|
||||
virtual void ps_remoteProviderAddAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftParts &parts) override;
|
||||
//! @}
|
||||
|
||||
//! Timer event (our SimConnect event loop), runs ps_dispatch
|
||||
//! \sa m_simconnectTimerId
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private slots:
|
||||
//! Dispatch SimConnect messages
|
||||
void ps_dispatch();
|
||||
|
||||
//! Remove aircraft not in provider anymore
|
||||
//! \remark kind of cleanup function, in an ideal this should never need to cleanup something
|
||||
BlackMisc::Aviation::CCallsignSet ps_physicallyRemoveAircraftNotInProvider();
|
||||
|
||||
//! Handle that an object has been added in simulator
|
||||
//! \remark checks if the object was really added after an add request and not directly removed again
|
||||
bool ps_deferredSimulatorReportedObjectAdded(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
//! Try to add the aircraft currently out of bubble
|
||||
void ps_addAircraftCurrentlyOutOfBubble();
|
||||
|
||||
private:
|
||||
//! Call this method to declare the simulator connected
|
||||
void setSimConnected();
|
||||
|
||||
//! Called when sim has started
|
||||
void onSimRunning();
|
||||
|
||||
//! Slot called every visual frame
|
||||
void onSimFrame();
|
||||
|
||||
//! Called when simulator has stopped, e.g. by selecting the "select aircraft screen"
|
||||
void onSimStopped();
|
||||
|
||||
//! Simulator is going down
|
||||
void onSimExit();
|
||||
|
||||
//! Get new request id, overflow safe
|
||||
DWORD obtainRequestIdSimData();
|
||||
|
||||
//! Init when connected
|
||||
HRESULT initWhenConnected();
|
||||
|
||||
//! Initialize SimConnect system events
|
||||
HRESULT initEvents();
|
||||
|
||||
//! Initialize SimConnect data definitions
|
||||
HRESULT initDataDefinitionsWhenConnected();
|
||||
|
||||
//! Update remote aircraft
|
||||
void updateRemoteAircraft();
|
||||
|
||||
//! Update remote aircraft parts (send to FSX)
|
||||
bool updateRemoteAircraftParts(const CSimConnectObject &simObj,
|
||||
const BlackMisc::Aviation::CAircraftParts &parts, const BlackMisc::Simulation::CPartsStatus &partsStatus);
|
||||
|
||||
//! Update remote aircraft parts by guessing (send to FSX)
|
||||
bool guessAndUpdateRemoteAircraftParts(const CSimConnectObject &simObj,
|
||||
const BlackMisc::Aviation::CAircraftSituation &interpolatedSituation, const BlackMisc::Simulation::CInterpolationStatus &interpolationStatus);
|
||||
|
||||
//! Send parts to simulator
|
||||
bool sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts, const BlackMisc::Aviation::CAircraftLights &lights);
|
||||
|
||||
//! Send lights to simulator (those which have to be toggled)
|
||||
//! \remark challenge here is that I can only sent those value if I have already obtained the current light state from simulator
|
||||
void sendToggledLightsToSimulator(const CSimConnectObject &simObj, const BlackMisc::Aviation::CAircraftLights &lightsWanted, bool force = false);
|
||||
|
||||
//! Called when data about our own aircraft are received
|
||||
void updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft);
|
||||
|
||||
//! Remote aircraft data sent from simulator
|
||||
void updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData);
|
||||
|
||||
//! Update from SB client area
|
||||
void updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea);
|
||||
|
||||
//! An AI aircraft was added in the simulator
|
||||
bool simulatorReportedObjectAdded(DWORD objectID);
|
||||
|
||||
//! Simulator reported that AI aircraft was removed
|
||||
bool simulatorReportedObjectRemoved(DWORD objectID);
|
||||
|
||||
//! Set ID of a SimConnect object, so far we only have an request id in the object
|
||||
bool setSimConnectObjectId(DWORD requestID, DWORD objectID);
|
||||
|
||||
//! Remember current lights
|
||||
bool setCurrentLights(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftLights &lights);
|
||||
|
||||
//! Remember lights sent
|
||||
bool setLightsAsSent(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftLights &lights);
|
||||
|
||||
//! Display receive exceptions?
|
||||
bool stillDisplayReceiveExceptions();
|
||||
|
||||
//! The simconnect related objects
|
||||
const CSimConnectObjects &getSimConnectObjects() const { return m_simConnectObjects; }
|
||||
|
||||
//! Format conversion
|
||||
SIMCONNECT_DATA_INITPOSITION aircraftSituationToFsxPosition(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||
|
||||
//! Sync time with user's computer
|
||||
void synchronizeTime(const BlackMisc::PhysicalQuantities::CTime &zuluTimeSim, const BlackMisc::PhysicalQuantities::CTime &localTimeSim);
|
||||
|
||||
//! Request data for a simObject (aka remote aircraft)
|
||||
bool requestDataForSimObject(const CSimConnectObject &simObject, SIMCONNECT_PERIOD period = SIMCONNECT_PERIOD_SECOND);
|
||||
|
||||
//! Request lights for a simObject
|
||||
bool requestLightsForSimObject(const CSimConnectObject &simObject);
|
||||
|
||||
//! FSX position as string
|
||||
static QString fsxPositionToString(const SIMCONNECT_DATA_INITPOSITION &position);
|
||||
|
||||
//! Get the callsigns which are no longer in the provider, but still in m_simConnectObjects
|
||||
BlackMisc::Aviation::CCallsignSet getCallsignsMissingInProvider() const;
|
||||
|
||||
//! Request for sim data?
|
||||
static bool isRequestForSimData(DWORD requestId) { return requestId >= (RequestSimDataStart + RequestSimDataOffset) && requestId < (RequestSimDataStart + RequestSimDataOffset + SimObjectNumber); }
|
||||
|
||||
//! Request for sim data?
|
||||
static bool isRequestForLights(DWORD requestId) { return requestId >= (RequestSimDataStart + RequestLightsOffset) && requestId < (RequestSimDataStart + RequestLightsOffset + SimObjectNumber); }
|
||||
|
||||
static constexpr int GuessRemoteAircraftPartsCycle = 20; //!< guess every n-th cycle
|
||||
static constexpr int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again
|
||||
static constexpr int IgnoreReceiveExceptions = 10; //!< skip exceptions when displayed more than x times
|
||||
static constexpr int SimObjectNumber = 10000; //!< max. SimObjects at the same time
|
||||
static constexpr int RequestSimDataStart = static_cast<int>(CSimConnectDefinitions::RequestEndMarker);
|
||||
static constexpr int RequestSimDataEnd = RequestSimDataStart + SimObjectNumber - 1;
|
||||
static constexpr int RequestSimDataOffset = 0 * SimObjectNumber;
|
||||
static constexpr int RequestLightsOffset = 1 * SimObjectNumber;
|
||||
|
||||
QString m_simConnectVersion; //!< SimConnect version
|
||||
bool m_simConnected = false; //!< Is simulator connected?
|
||||
bool m_simSimulating = false; //!< Simulator running?
|
||||
bool m_useSbOffsets = true; //!< with SB offsets
|
||||
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
||||
int m_simConnectTimerId = -1; //!< Timer identifier
|
||||
int m_skipCockpitUpdateCycles = 0; //!< skip some update cycles to allow changes in simulator cockpit to be set
|
||||
int m_interpolationRequest = 0; //!< current interpolation request
|
||||
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa ps_dispatch
|
||||
int m_receiveExceptionCount = 0; //!< exceptions
|
||||
HANDLE m_hSimConnect = nullptr; //!< handle to SimConnect object
|
||||
CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
|
||||
QTimer m_realityBubbleTimer { this }; //!< updating of aircraft out of reality bubble
|
||||
DWORD m_requestIdSimData = RequestSimDataStart; //!< request id, use obtainRequestId() to get id
|
||||
BlackMisc::Simulation::CSimulatedAircraftList m_outOfRealityBubble; //!< aircraft removed by FSX because they are out of reality bubble
|
||||
};
|
||||
|
||||
//! Listener for FSX
|
||||
class CSimulatorFsxListener : public BlackCore::ISimulatorListener
|
||||
class CSimulatorFsxListener : public BlackSimPlugin::FsxCommon::CSimulatorFsxCommonListener
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CSimulatorFsxListener(const BlackMisc::Simulation::CSimulatorPluginInfo &info);
|
||||
|
||||
public slots:
|
||||
//! \copydoc BlackCore::ISimulatorListener::start
|
||||
virtual void start() override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulatorListener::stop
|
||||
virtual void stop() override;
|
||||
|
||||
private slots:
|
||||
//! Test if connection can be established
|
||||
void ps_checkConnection();
|
||||
|
||||
private:
|
||||
QTimer *m_timer { nullptr };
|
||||
using CSimulatorFsxCommonListener::CSimulatorFsxCommonListener;
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -1,316 +0,0 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift Project Community / Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "simulatorfsx.h"
|
||||
#include "blackcore/application.h"
|
||||
#include "simconnectdatadefinition.h"
|
||||
#include "blackmisc/simulation/fscommon/bcdconversions.h"
|
||||
#include "blackmisc/simulation/fsx/simconnectutilities.h"
|
||||
#include "blackmisc/simulation/simulatorplugininfo.h"
|
||||
#include "blackmisc/aviation/airportlist.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
|
||||
using namespace BlackCore;
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Simulation;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Geo;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc::Simulation;
|
||||
using namespace BlackMisc::Simulation::FsCommon;
|
||||
using namespace BlackMisc::Simulation::Fsx;
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
void CALLBACK CSimulatorFsx::SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext)
|
||||
{
|
||||
CSimulatorFsx *simulatorFsx = static_cast<CSimulatorFsx *>(pContext);
|
||||
switch (pData->dwID)
|
||||
{
|
||||
case SIMCONNECT_RECV_ID_OPEN:
|
||||
{
|
||||
SIMCONNECT_RECV_OPEN *event = (SIMCONNECT_RECV_OPEN *)pData;
|
||||
simulatorFsx->m_simulatorVersion = QString("%1.%2.%3.%4").arg(event->dwApplicationVersionMajor).arg(event->dwApplicationVersionMinor).arg(event->dwApplicationBuildMajor).arg(event->dwApplicationBuildMinor);
|
||||
simulatorFsx->m_simConnectVersion = QString("%1.%2.%3.%4").arg(event->dwSimConnectVersionMajor).arg(event->dwSimConnectVersionMinor).arg(event->dwSimConnectBuildMajor).arg(event->dwSimConnectBuildMinor);
|
||||
simulatorFsx->m_simulatorName = QString(event->szApplicationName);
|
||||
simulatorFsx->m_simulatorDetails = QString("Open: AppName=\"%1\" AppVersion=%2 SimConnectVersion=%3").arg(simulatorFsx->m_simulatorName, simulatorFsx->m_simulatorVersion, simulatorFsx->m_simConnectVersion);
|
||||
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).info("Connect to FSX: %1") << sApp->swiftVersionString();
|
||||
simulatorFsx->setSimConnected();
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_EXCEPTION:
|
||||
{
|
||||
if (!simulatorFsx->stillDisplayReceiveExceptions()) { break; }
|
||||
SIMCONNECT_RECV_EXCEPTION *exception = (SIMCONNECT_RECV_EXCEPTION *)pData;
|
||||
const DWORD exceptionId = exception->dwException;
|
||||
const DWORD sendId = exception->dwSendID;
|
||||
const DWORD index = exception->dwIndex;
|
||||
const DWORD data = cbData;
|
||||
const QString exStr(CSimConnectUtilities::simConnectExceptionToString((SIMCONNECT_EXCEPTION)exception->dwException));
|
||||
QString ex;
|
||||
ex.sprintf("Exception=%lu | SendID=%lu | Index=%lu | cbData=%lu", exceptionId, sendId, index, data);
|
||||
switch (exceptionId)
|
||||
{
|
||||
case SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE:
|
||||
break;
|
||||
case SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CLogMessage(simulatorFsx).warning("Caught FSX simConnect exception: %1 %2") << exStr << ex;
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_QUIT:
|
||||
{
|
||||
simulatorFsx->onSimExit();
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_EVENT:
|
||||
{
|
||||
SIMCONNECT_RECV_EVENT *event = static_cast<SIMCONNECT_RECV_EVENT *>(pData);
|
||||
switch (event->uEventID)
|
||||
{
|
||||
case SystemEventSimStatus:
|
||||
{
|
||||
const bool running = event->dwData ? true : false;
|
||||
if (running)
|
||||
{
|
||||
simulatorFsx->onSimRunning();
|
||||
}
|
||||
else
|
||||
{
|
||||
simulatorFsx->onSimStopped();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SystemEventPause:
|
||||
{
|
||||
const bool p = event->dwData ? true : false;
|
||||
if (simulatorFsx->m_simPaused != p)
|
||||
{
|
||||
simulatorFsx->m_simPaused = p;
|
||||
simulatorFsx->emitSimulatorCombinedStatus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE:
|
||||
{
|
||||
const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
|
||||
const DWORD objectID = event->dwData;
|
||||
const SIMCONNECT_SIMOBJECT_TYPE objectType = event->eObjType;
|
||||
if (objectType != SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT && objectType != SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// such an object is not necessarily one of ours
|
||||
// for instance, I always see object 5 when I start the simulator
|
||||
if (!simulatorFsx->getSimConnectObjects().isKnownSimObjectId(objectID)) break;
|
||||
switch (event->uEventID)
|
||||
{
|
||||
case SystemEventObjectAdded:
|
||||
// added in SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID
|
||||
break;
|
||||
case SystemEventObjectRemoved:
|
||||
simulatorFsx->simulatorReportedObjectRemoved(objectID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_EVENT_FRAME:
|
||||
{
|
||||
SIMCONNECT_RECV_EVENT_FRAME *event = (SIMCONNECT_RECV_EVENT_FRAME *) pData;
|
||||
switch (event->uEventID)
|
||||
{
|
||||
case SystemEventFrame:
|
||||
// doing interpolation
|
||||
simulatorFsx->onSimFrame();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
|
||||
{
|
||||
SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(pData);
|
||||
const DWORD requestId = event->dwRequestID;
|
||||
const DWORD objectId = event->dwObjectID;
|
||||
bool success = simulatorFsx->setSimConnectObjectId(requestId, objectId);
|
||||
if (!success) { break; } // not an request ID of ours
|
||||
|
||||
success = simulatorFsx->simulatorReportedObjectAdded(objectId);
|
||||
if (success)
|
||||
{
|
||||
const CSimConnectObject simObject = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId);
|
||||
HRESULT result = S_OK;
|
||||
result += simulatorFsx->requestDataForSimObject(simObject);
|
||||
result += simulatorFsx->requestLightsForSimObject(simObject);
|
||||
Q_UNUSED(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
const CSimulatedAircraft remoteAircraft(simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId).getAircraft());
|
||||
const CStatusMessage msgAdd = CStatusMessage(simulatorFsx).error("Cannot add object %1") << objectId;
|
||||
CLogMessage::preformatted(msgAdd);
|
||||
emit simulatorFsx->physicallyAddingRemoteModelFailed(remoteAircraft, msgAdd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE:
|
||||
{
|
||||
// SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE *)pData;
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
||||
{
|
||||
SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData;
|
||||
const DWORD requestId = pObjData->dwRequestID;
|
||||
switch (requestId)
|
||||
{
|
||||
case CSimConnectDefinitions::RequestOwnAircraft:
|
||||
{
|
||||
static_assert(sizeof(DataDefinitionOwnAircraft) == 30 * sizeof(double), "DataDefinitionOwnAircraft has an incorrect size.");
|
||||
const DataDefinitionOwnAircraft *ownAircaft = (DataDefinitionOwnAircraft *)&pObjData->dwData;
|
||||
simulatorFsx->updateOwnAircraftFromSimulator(*ownAircaft);
|
||||
break;
|
||||
}
|
||||
case CSimConnectDefinitions::RequestOwnAircraftTitle:
|
||||
{
|
||||
const DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData;
|
||||
CAircraftModel model;
|
||||
model.setModelString(dataDefinitionModel->title);
|
||||
model.setModelType(CAircraftModel::TypeOwnSimulatorModel);
|
||||
simulatorFsx->reverseLookupAndUpdateOwnAircraftModel(model);
|
||||
break;
|
||||
}
|
||||
case CSimConnectDefinitions::RequestSimEnvironment:
|
||||
{
|
||||
const DataDefinitionSimEnvironment *simEnv = (DataDefinitionSimEnvironment *) &pObjData->dwData;
|
||||
if (simulatorFsx->isTimeSynchronized())
|
||||
{
|
||||
const int zh = simEnv->zuluTimeSeconds / 3600;
|
||||
const int zm = (simEnv->zuluTimeSeconds - (zh * 3600)) / 60;
|
||||
const CTime zulu(zh, zm);
|
||||
const int lh = simEnv->localTimeSeconds / 3600;
|
||||
const int lm = (simEnv->localTimeSeconds - (lh * 3600)) / 60;
|
||||
const CTime local(lh, lm);
|
||||
simulatorFsx->synchronizeTime(zulu, local);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const DWORD objectId = pObjData->dwObjectID;
|
||||
if (isRequestForSimData(requestId))
|
||||
{
|
||||
static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size.");
|
||||
const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId);
|
||||
if (!simObj.hasValidRequestAndObjectId()) break;
|
||||
const DataDefinitionRemoteAircraftSimData *remoteAircraftSimData = (DataDefinitionRemoteAircraftSimData *)&pObjData->dwData;
|
||||
// extra check, but ids should be the same
|
||||
if (objectId == simObj.getObjectId())
|
||||
{
|
||||
simulatorFsx->updateRemoteAircraftFromSimulator(simObj, *remoteAircraftSimData);
|
||||
}
|
||||
}
|
||||
else if (isRequestForLights(requestId))
|
||||
{
|
||||
static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 8 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size.");
|
||||
const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId);
|
||||
if (!simObj.hasValidRequestAndObjectId()) break;
|
||||
const DataDefinitionRemoteAircraftLights *remoteAircraftLights = (DataDefinitionRemoteAircraftLights *)&pObjData->dwData;
|
||||
// extra check, but ids should be the same
|
||||
if (objectId == simObj.getObjectId())
|
||||
{
|
||||
const CCallsign callsign(simObj.getCallsign());
|
||||
const CAircraftLights lights = remoteAircraftLights->toLights(); // as in simulator
|
||||
simulatorFsx->setCurrentLights(callsign, lights);
|
||||
if (simObj.getLightsAsSent().isNull())
|
||||
{
|
||||
// allows to compare for toggle
|
||||
simulatorFsx->setLightsAsSent(callsign, lights);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_AIRPORT_LIST:
|
||||
{
|
||||
static const CLength maxDistance(200.0, CLengthUnit::NM());
|
||||
const CCoordinateGeodetic posAircraft(simulatorFsx->getOwnAircraftPosition());
|
||||
SIMCONNECT_RECV_AIRPORT_LIST *pAirportList = (SIMCONNECT_RECV_AIRPORT_LIST *) pData;
|
||||
for (unsigned i = 0; i < pAirportList->dwArraySize; ++i)
|
||||
{
|
||||
SIMCONNECT_DATA_FACILITY_AIRPORT *pFacilityAirport = pAirportList->rgData + i;
|
||||
if (!pFacilityAirport) { break; }
|
||||
const QString icao(pFacilityAirport->Icao);
|
||||
if (icao.isEmpty()) { continue; } // airfield without ICAO code
|
||||
if (!CAirportIcaoCode::isValidIcaoDesignator(icao)) { continue; } // tiny airfields/strips in simulator
|
||||
if (CAirportIcaoCode::containsNumbers(icao)) { continue; } // tiny airfields/strips in simulator
|
||||
const CCoordinateGeodetic pos(pFacilityAirport->Latitude, pFacilityAirport->Longitude, pFacilityAirport->Altitude);
|
||||
CAirport airport(CAirportIcaoCode(icao), pos);
|
||||
const CLength d = airport.calculcateAndUpdateRelativeDistanceAndBearing(posAircraft);
|
||||
if (d > maxDistance) { continue; }
|
||||
airport.updateMissingParts(simulatorFsx->getWebServiceAirport(icao));
|
||||
simulatorFsx->m_airportsInRangeFromSimulator.replaceOrAddByIcao(airport);
|
||||
}
|
||||
|
||||
if (simulatorFsx->m_airportsInRangeFromSimulator.size() > simulatorFsx->maxAirportsInRange())
|
||||
{
|
||||
simulatorFsx->m_airportsInRangeFromSimulator.sortByDistanceToOwnAircraft();
|
||||
simulatorFsx->m_airportsInRangeFromSimulator.truncate(simulatorFsx->maxAirportsInRange());
|
||||
}
|
||||
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)
|
||||
{
|
||||
//! \fixme FSUIPC vs SimConnect 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. Whoever knows, add comment or fix if wrong
|
||||
DataDefinitionClientAreaSb *sbData = (DataDefinitionClientAreaSb *) &clientData->dwData;
|
||||
simulatorFsx->updateOwnAircraftFromSimulator(*sbData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_EVENT_FILENAME:
|
||||
{
|
||||
SIMCONNECT_RECV_EVENT_FILENAME *event = static_cast<SIMCONNECT_RECV_EVENT_FILENAME *>(pData);
|
||||
switch (event->uEventID)
|
||||
{
|
||||
case SystemEventFlightLoaded:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // main switch
|
||||
} // method
|
||||
} // namespace
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user