mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-04 17:30:12 +08:00
refs #891, moved common parts for FSX/P3D to fsxcommon
* driver / listener common parts * config common parts
This commit is contained in:
committed by
Mathew Sutcliffe
parent
347b54171b
commit
70045c046d
25
src/plugins/simulator/fsxcommon/fsxcommon.pro
Normal file
25
src/plugins/simulator/fsxcommon/fsxcommon.pro
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
load(common_pre)
|
||||||
|
|
||||||
|
QT += core dbus concurrent xml network widgets
|
||||||
|
|
||||||
|
TARGET = simulatorfsxcommon
|
||||||
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
CONFIG += staticlib
|
||||||
|
CONFIG += blackmisc blackcore blackgui
|
||||||
|
|
||||||
|
LIBS += -lsimulatorfscommon -lSimConnect -lFSUIPC_User
|
||||||
|
|
||||||
|
# required for FSUIPC
|
||||||
|
win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib
|
||||||
|
|
||||||
|
DEPENDPATH += . $$SourceRoot/src
|
||||||
|
INCLUDEPATH += . $$SourceRoot/src
|
||||||
|
|
||||||
|
SOURCES += *.cpp
|
||||||
|
HEADERS += *.h
|
||||||
|
FORMS += *.ui
|
||||||
|
|
||||||
|
DESTDIR = $$DestRoot/lib
|
||||||
|
|
||||||
|
load(common_post)
|
||||||
223
src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp
Normal file
223
src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/* 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 FsxCommon
|
||||||
|
{
|
||||||
|
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
|
||||||
230
src/plugins/simulator/fsxcommon/simconnectdatadefinition.h
Normal file
230
src/plugins/simulator/fsxcommon/simconnectdatadefinition.h
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/* 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 FsxCommon
|
||||||
|
{
|
||||||
|
//! 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
|
||||||
108
src/plugins/simulator/fsxcommon/simconnectobject.cpp
Normal file
108
src/plugins/simulator/fsxcommon/simconnectobject.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/* 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 FsxCommon
|
||||||
|
{
|
||||||
|
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
|
||||||
161
src/plugins/simulator/fsxcommon/simconnectobject.h
Normal file
161
src/plugins/simulator/fsxcommon/simconnectobject.h
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
/* 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_FSXCOMMON_SIMCONNECTOBJECT_H
|
||||||
|
#define BLACKSIMPLUGIN_FSXCOMMON_SIMCONNECTOBJECT_H
|
||||||
|
|
||||||
|
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||||
|
#include "simconnectdatadefinition.h"
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
class CInterpolatorLinear;
|
||||||
|
class CInterpolationLogger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace FsxCommon
|
||||||
|
{
|
||||||
|
//! 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
|
||||||
175
src/plugins/simulator/fsxcommon/simconnectsettingscomponent.cpp
Normal file
175
src/plugins/simulator/fsxcommon/simconnectsettingscomponent.cpp
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/* Copyright (C) 2015
|
||||||
|
* 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 "simconnectsettingscomponent.h"
|
||||||
|
#include "ui_simconnectsettingscomponent.h"
|
||||||
|
#include "blackgui/guiapplication.h"
|
||||||
|
#include "blackcore/context/contextapplication.h"
|
||||||
|
#include "blackcore/context/contextsimulator.h"
|
||||||
|
#include "blackmisc/network/networkutils.h"
|
||||||
|
#include "blackmisc/logmessage.h"
|
||||||
|
#include "blackmisc/simulation/fsx/simconnectutilities.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
using namespace BlackMisc;
|
||||||
|
using namespace BlackMisc::Simulation::Fsx;
|
||||||
|
using namespace BlackMisc::Network;
|
||||||
|
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace FsxCommon
|
||||||
|
{
|
||||||
|
CSimConnectSettingsComponent::CSimConnectSettingsComponent(QWidget *parent) :
|
||||||
|
QFrame(parent),
|
||||||
|
ui(new Ui::CSimConnectSettingsComponent)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->pb_SettingsFsxOpenSimconnectCfg, &QPushButton::clicked, this, &CSimConnectSettingsComponent::openSimConnectCfgFile);
|
||||||
|
connect(ui->pb_SettingsFsxDeleteSimconnectCfg, &QPushButton::clicked, this, &CSimConnectSettingsComponent::deleteSimConnectCfgFile);
|
||||||
|
connect(ui->pb_SettingsFsxExistsSimconncetCfg, &QPushButton::clicked, this, &CSimConnectSettingsComponent::checkSimConnectCfgFile);
|
||||||
|
connect(ui->pb_SettingsFsxSaveSimconnectCfg, &QPushButton::clicked, this, &CSimConnectSettingsComponent::saveSimConnectCfgFile);
|
||||||
|
connect(ui->pb_SettingsFsxTestConnection, &QPushButton::clicked, this, &CSimConnectSettingsComponent::testSimConnectConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSimConnectSettingsComponent::~CSimConnectSettingsComponent()
|
||||||
|
{
|
||||||
|
// void
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimConnectSettingsComponent::openSimConnectCfgFile()
|
||||||
|
{
|
||||||
|
const QFileInfo info(CSimConnectUtilities::getLocalSimConnectCfgFilename());
|
||||||
|
const QString path = QDir::toNativeSeparators(info.absolutePath());
|
||||||
|
QDesktopServices::openUrl(QUrl(QStringLiteral("file:///") % path));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimConnectSettingsComponent::deleteSimConnectCfgFile()
|
||||||
|
{
|
||||||
|
const QString fileName = CSimConnectUtilities::getLocalSimConnectCfgFilename();
|
||||||
|
const bool result = sGui->getIContextApplication()->removeFile(fileName);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
QMessageBox::information(qApp->activeWindow(), tr("File deleted"),
|
||||||
|
tr("File %1 deleted successfully.").arg(fileName));
|
||||||
|
}
|
||||||
|
checkSimConnectCfgFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimConnectSettingsComponent::checkSimConnectCfgFile()
|
||||||
|
{
|
||||||
|
const QString fileName = CSimConnectUtilities::getLocalSimConnectCfgFilename();
|
||||||
|
if (sGui->getIContextApplication()->existsFile(fileName))
|
||||||
|
{
|
||||||
|
ui->le_SettingsFsxExistsSimconncetCfg->setText(fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->le_SettingsFsxExistsSimconncetCfg->setText("no file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimConnectSettingsComponent::testSimConnectConnection()
|
||||||
|
{
|
||||||
|
const QString address = ui->le_SettingsFsxAddress->text().trimmed();
|
||||||
|
const QString port = ui->le_SettingsFsxPort->text().trimmed();
|
||||||
|
|
||||||
|
if (address.isEmpty() || port.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"),
|
||||||
|
tr("Address and/or port not specified!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!CNetworkUtils::isValidIPv4Address(address))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"),
|
||||||
|
tr("Wrong IPv4 address!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!CNetworkUtils::isValidPort(port))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"),
|
||||||
|
tr("Invalid port!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int p = port.toInt();
|
||||||
|
QString msg;
|
||||||
|
if (!CNetworkUtils::canConnect(address, p, msg))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"), msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMessageBox::information(qApp->activeWindow(), tr("Connection successful"),
|
||||||
|
tr("Connected to %1:%2.").arg(address, port));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSimConnectSettingsComponent::saveSimConnectCfgFile()
|
||||||
|
{
|
||||||
|
QString address = ui->le_SettingsFsxAddress->text().trimmed();
|
||||||
|
QString port = ui->le_SettingsFsxPort->text().trimmed();
|
||||||
|
|
||||||
|
if (address.isEmpty() || port.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"),
|
||||||
|
tr("Address and/or port not specified!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!CNetworkUtils::isValidIPv4Address(address))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"),
|
||||||
|
tr("Wrong IPv4 address!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!CNetworkUtils::isValidPort(port))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Connection invalid"),
|
||||||
|
tr("Invalid port!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int p = port.toInt();
|
||||||
|
QString fileName;
|
||||||
|
|
||||||
|
if (sGui->getIContextSimulator())
|
||||||
|
{
|
||||||
|
const BlackMisc::Simulation::CSimulatorInternals internals(sGui->getIContextSimulator()->getSimulatorInternals());
|
||||||
|
fileName = internals.getStringValue("fsx/simConnectCfgFilename");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
|
fileName = CSimConnectUtilities::getLocalSimConnectCfgFilename();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Failed writing simConnect.cfg"),
|
||||||
|
tr("No file name specified!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sGui->getIContextApplication()->writeToFile(fileName, CSimConnectUtilities::simConnectCfg(address, p)))
|
||||||
|
{
|
||||||
|
QMessageBox::information(qApp->activeWindow(), tr("File saved"),
|
||||||
|
tr("File %1 saved.").arg(fileName));
|
||||||
|
checkSimConnectCfgFile();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::warning(qApp->activeWindow(), tr("Failed writing simConnect.cfg"),
|
||||||
|
tr("Failed writing %1!").arg(fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // ns
|
||||||
|
} // ns
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/* Copyright (C) 2015
|
||||||
|
* 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_FSXCOMMON_SIMCONNECTSETTINGSCOMPONENT_H
|
||||||
|
#define BLACKSIMPLUGIN_FSXCOMMON_SIMCONNECTSETTINGSCOMPONENT_H
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
|
||||||
|
namespace Ui { class CSimConnectSettingsComponent; }
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace FsxCommon
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* A component that gathers all SimConnect related settings.
|
||||||
|
*/
|
||||||
|
class CSimConnectSettingsComponent : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Ctor
|
||||||
|
explicit CSimConnectSettingsComponent(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
//! Dtor
|
||||||
|
virtual ~CSimConnectSettingsComponent();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
//! Open simConnect.cfg using default application
|
||||||
|
void openSimConnectCfgFile();
|
||||||
|
|
||||||
|
//! Delete simConnect.cfg file
|
||||||
|
void deleteSimConnectCfgFile();
|
||||||
|
|
||||||
|
//! Check whether the simConnect.cfg file exists
|
||||||
|
void checkSimConnectCfgFile();
|
||||||
|
|
||||||
|
//! Test the SimConnect connectivity
|
||||||
|
void testSimConnectConnection();
|
||||||
|
|
||||||
|
//! Save a simconnect.cfg file for FSX
|
||||||
|
void saveSimConnectCfgFile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::CSimConnectSettingsComponent> ui;
|
||||||
|
};
|
||||||
|
} // ns
|
||||||
|
} // ns
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
237
src/plugins/simulator/fsxcommon/simconnectsettingscomponent.ui
Normal file
237
src/plugins/simulator/fsxcommon/simconnectsettingscomponent.ui
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CSimConnectSettingsComponent</class>
|
||||||
|
<widget class="QWidget" name="CSimConnectSettingsComponent">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>159</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="vl_SettingsComponent">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="gb_FsxSimConnectConfigFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>FSX/P3D SimConnect config file</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="fl_Settings">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_SettingsFsxAddress">
|
||||||
|
<property name="text">
|
||||||
|
<string>Address</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="le_SettingsFsxAddress">
|
||||||
|
<property name="text">
|
||||||
|
<string>127.0.0.1</string>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>e.g. "127.0.0.1" or "192.128.3.1"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_SettingsFsxPort">
|
||||||
|
<property name="text">
|
||||||
|
<string>Port</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="le_SettingsFsxPort">
|
||||||
|
<property name="text">
|
||||||
|
<string>500</string>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>normally "500"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_SettingsFsxExistsSimconncetCfg">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>is 'SimConnect.cfg' available?</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>.cfg?</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QWidget" name="wi_SettingsFsxExistsSimconncetCfg" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="hl_SettingsFsxExistsSimconncetCfg">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="le_SettingsFsxExistsSimconncetCfg">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>local "SimConnect.cfg" file?</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pb_SettingsFsxExistsSimconncetCfg">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>check</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<layout class="QHBoxLayout" name="hl_SettingsSimconnectCfgButtons">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pb_SettingsFsxOpenSimconnectCfg">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>open</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pb_SettingsFsxDeleteSimconnectCfg">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>del.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pb_SettingsFsxSaveSimconnectCfg">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>save</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pb_SettingsFsxTestConnection">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Test connection</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string extracomment="Test connection">test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
1342
src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp
Normal file
1342
src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp
Normal file
File diff suppressed because it is too large
Load Diff
311
src/plugins/simulator/fsxcommon/simulatorfsxcommon.h
Normal file
311
src/plugins/simulator/fsxcommon/simulatorfsxcommon.h
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
/* 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_FSXCOMMON_SIMULATORFSXCOMMON_H
|
||||||
|
#define BLACKSIMPLUGIN_FSXCOMMON_SIMULATORFSXCOMMON_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>
|
||||||
|
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace FsxCommon
|
||||||
|
{
|
||||||
|
//! 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 CSimulatorFsxCommon : public BlackSimPlugin::FsCommon::CSimulatorFsCommon
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
|
||||||
|
CSimulatorFsxCommon(
|
||||||
|
const BlackMisc::Simulation::CSimulatorPluginInfo &info,
|
||||||
|
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||||
|
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
|
||||||
|
BlackMisc::Weather::IWeatherGridProvider *weatherGridProvider,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
virtual ~CSimulatorFsxCommon();
|
||||||
|
|
||||||
|
//! 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 CSimulatorFsxCommonListener : public BlackCore::ISimulatorListener
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CSimulatorFsxCommonListener(const BlackMisc::Simulation::CSimulatorPluginInfo &info);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//! \copydoc BlackCore::ISimulatorListener::start
|
||||||
|
virtual void start() override;
|
||||||
|
|
||||||
|
//! \copydoc BlackCore::ISimulatorListener::stop
|
||||||
|
virtual void stop() override;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
//! Test if connection can be established
|
||||||
|
void ps_checkConnection();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTimer *m_timer { nullptr };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
34
src/plugins/simulator/fsxcommon/simulatorfsxconfigwindow.cpp
Normal file
34
src/plugins/simulator/fsxcommon/simulatorfsxconfigwindow.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/* Copyright (C) 2015
|
||||||
|
* 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 "simulatorfsxconfigwindow.h"
|
||||||
|
#include "ui_simulatorfsxconfigwindow.h"
|
||||||
|
|
||||||
|
using namespace BlackGui;
|
||||||
|
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace FsxCommon
|
||||||
|
{
|
||||||
|
CSimulatorFsxConfigWindow::CSimulatorFsxConfigWindow(const QString &simulator, QWidget *parent) :
|
||||||
|
CPluginConfigWindow(parent),
|
||||||
|
m_simulator(simulator),
|
||||||
|
ui(new Ui::CSimulatorFsxConfigWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
connect(ui->bb_OkCancel, &QDialogButtonBox::rejected, this, &QWidget::close);
|
||||||
|
this->setWindowTitle(m_simulator + " plugin configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
CSimulatorFsxConfigWindow::~CSimulatorFsxConfigWindow()
|
||||||
|
{
|
||||||
|
// void
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/plugins/simulator/fsxcommon/simulatorfsxconfigwindow.h
Normal file
44
src/plugins/simulator/fsxcommon/simulatorfsxconfigwindow.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* Copyright (C) 2015
|
||||||
|
* 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_FSXCOMMON_SIMULATORFSXCONFIGWINDOW_H
|
||||||
|
#define BLACKSIMPLUGIN_FSXCOMMON_SIMULATORFSXCONFIGWINDOW_H
|
||||||
|
|
||||||
|
#include "blackgui/pluginconfigwindow.h"
|
||||||
|
#include <QScopedPointer>
|
||||||
|
|
||||||
|
namespace Ui { class CSimulatorFsxConfigWindow; }
|
||||||
|
namespace BlackSimPlugin
|
||||||
|
{
|
||||||
|
namespace FsxCommon
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A window that lets user set up the FSX plugin.
|
||||||
|
*/
|
||||||
|
class CSimulatorFsxConfigWindow : public BlackGui::CPluginConfigWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Ctor.
|
||||||
|
CSimulatorFsxConfigWindow(const QString &simulator, QWidget *parent);
|
||||||
|
|
||||||
|
//! Dtor.
|
||||||
|
virtual ~CSimulatorFsxConfigWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_simulator { "FSX" };
|
||||||
|
QScopedPointer<Ui::CSimulatorFsxConfigWindow> ui;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
46
src/plugins/simulator/fsxcommon/simulatorfsxconfigwindow.ui
Normal file
46
src/plugins/simulator/fsxcommon/simulatorfsxconfigwindow.ui
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CSimulatorFsxConfigWindow</class>
|
||||||
|
<widget class="QWidget" name="CSimulatorFsxConfigWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>FSX plugin settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="vl_FsxConfigWindow">
|
||||||
|
<item>
|
||||||
|
<widget class="BlackSimPlugin::FsxCommon::CSimConnectSettingsComponent" name="fr_simConnectSettings">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="bb_OkCancel">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Close</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>BlackSimPlugin::FsxCommon::CSimConnectSettingsComponent</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>simconnectsettingscomponent.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
316
src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp
Normal file
316
src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
/* 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 "simulatorfsxcommon.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 FsxCommon
|
||||||
|
{
|
||||||
|
void CALLBACK CSimulatorFsxCommon::SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext)
|
||||||
|
{
|
||||||
|
CSimulatorFsxCommon *simulatorFsx = static_cast<CSimulatorFsxCommon *>(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<CSimulatorFsxCommon *>(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