Move fsx plugin into plugins/simulator/fsx

refs #211
This commit is contained in:
Roland Winklmeier
2014-04-18 14:33:41 +02:00
parent b6ff89e69f
commit 603f03f092
10 changed files with 60 additions and 60 deletions

View File

@@ -0,0 +1,28 @@
include (../../../../config.pri)
include (../../../../build.pri)
QT += core dbus gui network
TARGET = simulator_fsx
TEMPLATE = lib
CONFIG += plugin shared
CONFIG += blackmisc blackcore blacksim
LIBS += -lSimConnect
DEPENDPATH += . ../../../../src
INCLUDEPATH += . ../../../../src
SOURCES += *.cpp
HEADERS += *.h
win32:!win32-g++*: PRE_TARGETDEPS += ../../../../lib/blackmisc.lib \
../../../../lib/blacksim.lib \
../../../../lib/blackcore.lib
else: PRE_TARGETDEPS += ../../../../lib/libblackmisc.a \
../../../../lib/libblacksim.a \
../../../../lib/libblackcore.a
DESTDIR = ../../../../bin/plugins/simulator
include (../../../../libraries.pri)

View File

@@ -0,0 +1,70 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "simconnect_datadefinition.h"
#include "simconnect/SimConnect.h"
namespace BlackSimPlugin
{
namespace Fsx
{
CSimConnectDataDefinition::CSimConnectDataDefinition()
{
}
HRESULT CSimConnectDataDefinition::initDataDefinitions(const HANDLE hSimConnect)
{
HRESULT hr = S_OK;
hr = initOwnAircraft(hSimConnect);
hr = initAircraftPosition(hSimConnect);
hr = initAircraftConfiguration(hSimConnect);
return hr;
}
HRESULT CSimConnectDataDefinition::initOwnAircraft(const HANDLE hSimConnect)
{
HRESULT hr = S_OK;
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Latitude", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Longitude", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Altitude", "Feet");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Heading Degrees True", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Pitch Degrees", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "Plane Bank Degrees", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "GROUND VELOCITY", "knots");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "SIM ON GROUND", "bool");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "TRANSPONDER CODE:1", NULL);
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM ACTIVE FREQUENCY:1", "MHz");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM ACTIVE FREQUENCY:2", "MHz");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM STANDBY FREQUENCY:1", "MHz");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataOwnAircraft, "COM STANDBY FREQUENCY:2", "MHz");
return hr;
}
HRESULT CSimConnectDataDefinition::initAircraftPosition(const HANDLE hSimConnect)
{
HRESULT hr = S_OK;
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, "Plane Latitude", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, "Plane Longitude", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, "Plane Altitude", "Feet");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, "Plane Heading Degrees True", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, "Plane Pitch Degrees", "Degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, "Plane Bank Degrees", "Degrees");
return hr;
}
HRESULT CSimConnectDataDefinition::initAircraftConfiguration(const HANDLE hSimConnect)
{
HRESULT hr = S_OK;
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, "GEAR CENTER POSITION", "Percent Over 100");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, "GEAR LEFT POSITION", "Percent Over 100");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, "GEAR RIGHT POSITION", "Percent Over 100");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, "GEAR TAIL POSITION", "Percent Over 100");
hr = SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, "GEAR AUX POSITION", "Percent Over 100");
return hr;
}
}
}

View File

@@ -0,0 +1,108 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
#define BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
namespace BlackSimPlugin
{
namespace Fsx
{
//! \brief Data struct of our own aircraft
struct DataDefinitionOwnAircraft
{
double latitude; //!< Latitude
double longitude; //!< Longitude
double altitude; //!< Altitude
double trueHeading; //!< True heading
double pitch; //!< Pitch
double bank; //!< Bank
double velocity; //!< Ground velocity
double simOnGround; //!< Is sim on ground?
double transponderCode; //!< Transponder Code
double com1ActiveMHz; //!< COM1 active frequency
double com2ActiveMHz; //!< COM2 active frequency
double com1StandbyMHz; //!< COM1 standby frequency
double com2StandbyMHz; //!< COM1 standby frequency
};
//! \brief Data struct of aircraft position
struct DataDefinitionAircraftPosition
{
double latitude; //!< Latitude
double longitude; //!< Longitude
double altitude; //!< Altitude
double trueHeading; //!< True heading
double pitch; //!< Pitch
double bank; //!< Bank
};
//! \brief Data struct of aircraft position
struct DataDefinitionAircraftConfiguration
{
double gearCenter; //!< Gear center
double gearLeft; //!< Gear left
double gearRight; //!< Gear right
double gearTail; //!< Gear tail
double gearAux; //!< Gear aux
};
//! \brief Handles SimConnect data definitions
class CSimConnectDataDefinition
{
public:
//! \brief SimConnect definiton ID's
enum DataDefiniton {
DataOwnAircraft,
DataAircraftPosition,
DataAircraftConfiguration
};
//! \brief SimConnect request ID's
enum Requests {
RequestOwnAircraft = 1000
};
//! \brief Constructor
CSimConnectDataDefinition();
/*!
* \brief Initialize all data definitions
* \param hSimConnect
* \return
*/
static HRESULT initDataDefinitions(const HANDLE hSimConnect);
/*!
* \brief Initialize data definition for our own aircraft
* \param hSimConnect
* \return
*/
static HRESULT initOwnAircraft(const HANDLE hSimConnect);
/*!
* \brief Initialize data definition for remote aircrafts
* \param hSimConnect
* \return
*/
static HRESULT initAircraftPosition(const HANDLE hSimConnect);
/*!
* \brief Initialize data definition for remote aircraft configuration
* \param hSimConnect
* \return
*/
static HRESULT initAircraftConfiguration(const HANDLE hSimConnect);
};
}
}
#endif // BLACKSIMPLUGIN_FSX_SIMCONNECT_DATADEFINITION_H

View File

@@ -0,0 +1,106 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "simconnect_exception.h"
#include <QDebug>
namespace BlackSimPlugin
{
namespace Fsx
{
CSimConnectException::CSimConnectException()
{
}
void CSimConnectException::handleException(SIMCONNECT_EXCEPTION exception)
{
switch(exception)
{
case SIMCONNECT_EXCEPTION_ERROR:
break;
case SIMCONNECT_EXCEPTION_SIZE_MISMATCH:
break;
case SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID:
break;
case SIMCONNECT_EXCEPTION_UNOPENED:
break;
case SIMCONNECT_EXCEPTION_VERSION_MISMATCH:
break;
case SIMCONNECT_EXCEPTION_TOO_MANY_GROUPS:
break;
case SIMCONNECT_EXCEPTION_NAME_UNRECOGNIZED:
break;
case SIMCONNECT_EXCEPTION_TOO_MANY_EVENT_NAMES:
break;
case SIMCONNECT_EXCEPTION_EVENT_ID_DUPLICATE:
break;
case SIMCONNECT_EXCEPTION_TOO_MANY_MAPS:
break;
case SIMCONNECT_EXCEPTION_TOO_MANY_OBJECTS:
break;
case SIMCONNECT_EXCEPTION_TOO_MANY_REQUESTS:
break;
case SIMCONNECT_EXCEPTION_WEATHER_INVALID_PORT:
break;
case SIMCONNECT_EXCEPTION_WEATHER_INVALID_METAR:
break;
case SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION:
break;
case SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION:
break;
case SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION:
break;
case SIMCONNECT_EXCEPTION_INVALID_DATA_TYPE:
break;
case SIMCONNECT_EXCEPTION_INVALID_DATA_SIZE:
{
qDebug() << "Invalid data size!";
break;
}
case SIMCONNECT_EXCEPTION_DATA_ERROR:
break;
case SIMCONNECT_EXCEPTION_INVALID_ARRAY:
break;
case SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED:
{
qDebug() << "Failed to create object!";
break;
}
case SIMCONNECT_EXCEPTION_LOAD_FLIGHTPLAN_FAILED:
break;
case SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE:
break;
case SIMCONNECT_EXCEPTION_ILLEGAL_OPERATION:
break;
case SIMCONNECT_EXCEPTION_ALREADY_SUBSCRIBED:
break;
case SIMCONNECT_EXCEPTION_INVALID_ENUM:
break;
case SIMCONNECT_EXCEPTION_DEFINITION_ERROR:
break;
case SIMCONNECT_EXCEPTION_DUPLICATE_ID:
break;
case SIMCONNECT_EXCEPTION_DATUM_ID:
break;
case SIMCONNECT_EXCEPTION_OUT_OF_BOUNDS:
break;
case SIMCONNECT_EXCEPTION_ALREADY_CREATED:
break;
case SIMCONNECT_EXCEPTION_OBJECT_OUTSIDE_REALITY_BUBBLE:
break;
case SIMCONNECT_EXCEPTION_OBJECT_CONTAINER:
break;
case SIMCONNECT_EXCEPTION_OBJECT_AI:
break;
case SIMCONNECT_EXCEPTION_OBJECT_ATC:
break;
case SIMCONNECT_EXCEPTION_OBJECT_SCHEDULE:
break;
default:
break;
}
}
}
}

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BLACKSIMPLUGIN_FSX_SIMCONNECT_EXCEPTION_H
#define BLACKSIMPLUGIN_FSX_SIMCONNECT_EXCEPTION_H
#include "simconnect/SimConnect.h"
namespace BlackSimPlugin
{
namespace Fsx
{
//! \brief Handles SimConnect exceptions
class CSimConnectException
{
public:
CSimConnectException();
/*!
* \brief Handle exception
* \param exception
*/
static void handleException(SIMCONNECT_EXCEPTION exception);
};
}
}
#endif // BLACKSIMPLUGIN_FSX_SIMCONNECT_EXCEPTION_H

View File

@@ -0,0 +1,333 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "blacksim/fsx/fsxsimulatorsetup.h"
#include "simulator_fsx.h"
#include "simconnect_datadefinition.h"
#include "simconnect_exception.h"
#include <QTimer>
using namespace BlackMisc::Aviation;
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Geo;
using namespace BlackSim;
using namespace BlackSim::Fsx;
namespace BlackSimPlugin
{
namespace Fsx
{
BlackCore::ISimulator *CSimulatorFsxFactory::create(QObject *parent)
{
return new Fsx::CSimulatorFsx(parent);
}
CSimulatorFsx::CSimulatorFsx(QObject *parent) :
ISimulator(parent),
m_isConnected(false),
m_simRunning(false),
m_hSimConnect(nullptr),
m_nextObjID(1),
m_simulatorInfo(CSimulatorInfo::FSX())
{
CFsxSimulatorSetup setup;
setup.init(); // this fetches important setting on local side
this->m_simulatorInfo.setSimulatorSetup(setup.getSettings());
QTimer::singleShot(5000, this, SLOT(checkConnection()));
}
bool CSimulatorFsx::isConnected() const
{
return m_isConnected;
}
void CSimulatorFsx::addRemoteAircraft(const CCallsign &callsign, const QString &type, const CAircraftSituation &initialSituation)
{
Q_UNUSED(type);
SIMCONNECT_DATA_INITPOSITION initialPosition;
initialPosition.Latitude = initialSituation.latitude().value();
initialPosition.Longitude = initialSituation.longitude().value();
initialPosition.Altitude = initialSituation.getAltitude().value();
initialPosition.Pitch = initialSituation.getPitch().value();
initialPosition.Bank = initialSituation.getBank().value();
initialPosition.Heading = initialSituation.getHeading().value();
initialPosition.Airspeed = 0;
initialPosition.OnGround = 0;
SimConnectObject simObj;
simObj.m_callsign = callsign;
simObj.m_requestId = m_nextObjID;
simObj.m_objectId = 0;
simObj.m_interpolator.addAircraftSituation(initialSituation);
m_simConnectObjects.insert(callsign, simObj);
++m_nextObjID;
HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, "Boeing 737-800 Paint1", callsign.toQString().left(12).toLatin1().constData(), initialPosition, simObj.m_requestId);
Q_UNUSED(hr);
}
void CSimulatorFsx::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation &situation)
{
if (!m_simConnectObjects.contains(callsign))
{
addRemoteAircraft(callsign, "Boeing 737-800 Paint1", situation);
return;
}
SimConnectObject simObj = m_simConnectObjects.value(callsign);
simObj.m_interpolator.addAircraftSituation(situation);
m_simConnectObjects.insert(callsign, simObj);
}
void CSimulatorFsx::removeRemoteAircraft(const CCallsign &/*callsign*/)
{
// TODO
}
CSimulatorInfo CSimulatorFsx::getSimulatorInfo() const
{
return this->m_simulatorInfo;
}
void CALLBACK CSimulatorFsx::SimConnectProc(SIMCONNECT_RECV *pData, DWORD /* cbData */, void *pContext)
{
CSimulatorFsx *simulatorFsx = static_cast<CSimulatorFsx *>(pContext);
switch (pData->dwID)
{
case SIMCONNECT_RECV_ID_EXCEPTION:
{
SIMCONNECT_RECV_EXCEPTION *event = (SIMCONNECT_RECV_EXCEPTION *)pData;
CSimConnectException::handleException((SIMCONNECT_EXCEPTION)event->dwException);
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 EVENT_SIM_STATUS:
if (event->dwData)
{
simulatorFsx->onSimRunning();
}
else
{
simulatorFsx->onSimStopped();
}
break;
}
break;
}
case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE:
{
SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
if (event->uEventID == EVENT_OBJECT_ADDED)
{
}
else if (event->uEventID == EVENT_OBJECT_REMOVED)
{
}
break;
}
case SIMCONNECT_RECV_ID_EVENT_FRAME:
{
simulatorFsx->onSimFrame();
break;
}
case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
{
SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(pData);
simulatorFsx->setSimconnectObjectID(event->dwRequestID, event->dwObjectID);
}
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
{
SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData;
switch (pObjData->dwRequestID)
{
case CSimConnectDataDefinition::RequestOwnAircraft:
DataDefinitionOwnAircraft *ownAircaft;
ownAircaft = (DataDefinitionOwnAircraft *)&pObjData->dwData;
simulatorFsx->setOwnAircraft(*ownAircaft);
break;
}
break;
}
}
}
void CSimulatorFsx::onSimRunning()
{
m_simRunning = true;
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::RequestOwnAircraft,
CSimConnectDataDefinition::DataOwnAircraft,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME);
}
void CSimulatorFsx::onSimStopped()
{
m_simRunning = false;
}
void CSimulatorFsx::onSimFrame()
{
}
void CSimulatorFsx::onSimExit()
{
}
void CSimulatorFsx::setOwnAircraft(DataDefinitionOwnAircraft aircraft)
{
BlackMisc::Geo::CCoordinateGeodetic position;
position.setLatitude(CLatitude(aircraft.latitude, CAngleUnit::deg()));
position.setLongitude(CLongitude(aircraft.longitude, CAngleUnit::deg()));
BlackMisc::Aviation::CAircraftSituation aircraftSituation;
aircraftSituation.setPosition(position);
aircraftSituation.setPitch(CAngle(aircraft.pitch, CAngleUnit::deg()));
aircraftSituation.setBank(CAngle(aircraft.bank, CAngleUnit::deg()));
aircraftSituation.setHeading(CHeading(aircraft.trueHeading, CHeading::True, CAngleUnit::deg()));
aircraftSituation.setGroundspeed(CSpeed(aircraft.velocity, CSpeedUnit::kts()));
aircraftSituation.setAltitude(CAltitude(aircraft.altitude, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
CComSystem com1;
com1.setFrequencyActive(CFrequency(aircraft.com1ActiveMHz, CFrequencyUnit::MHz()));
com1.setFrequencyStandby(CFrequency(aircraft.com1StandbyMHz, CFrequencyUnit::MHz()));
CComSystem com2;
com2.setFrequencyActive(CFrequency(aircraft.com2ActiveMHz, CFrequencyUnit::MHz()));
com2.setFrequencyStandby(CFrequency(aircraft.com2StandbyMHz, CFrequencyUnit::MHz()));
CTransponder transponder("Transponder", aircraft.transponderCode, CTransponder::ModeS);
m_ownAircraft.setSituation(aircraftSituation);
m_ownAircraft.setCom1System(com1);
m_ownAircraft.setCom2System(com2);
m_ownAircraft.setTransponder(transponder);
}
void CSimulatorFsx::setSimconnectObjectID(DWORD requestID, DWORD objectID)
{
SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID);
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EVENT_FREEZELAT, 1,
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EVENT_FREEZEALT, 1,
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EVENT_FREEZEATT, 1,
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
DataDefinitionAircraftConfiguration configuration;
configuration.gearCenter = 100.0;
configuration.gearLeft = 100.0;
configuration.gearRight = 100.0;
configuration.gearTail = 100.0;
configuration.gearAux = 100.0;
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, objectID, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionAircraftConfiguration), &configuration);
SimConnectObject simObject;
foreach(simObject, m_simConnectObjects)
{
if (simObject.m_requestId == static_cast<int>(requestID))
{
simObject.m_objectId = objectID;
break;
}
}
m_simConnectObjects.insert(simObject.m_callsign, simObject);
}
void CSimulatorFsx::timerEvent(QTimerEvent * /* event */)
{
dispatch();
update();
}
void CSimulatorFsx::checkConnection()
{
if (FAILED(SimConnect_Open(&m_hSimConnect, "BlackBox", nullptr, 0, 0, 0)))
{
// QTimer::singleShot(5000, this, SLOT(checkConnection()));
return;
}
initSystemEvents();
initDataDefinitions();
startTimer(50);
m_isConnected = true;
emit connectionChanged(true);
}
void CSimulatorFsx::dispatch()
{
SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this);
}
HRESULT CSimulatorFsx::initSystemEvents()
{
HRESULT hr = S_OK;
// System events
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, EVENT_SIM_STATUS, "Sim");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, EVENT_OBJECT_ADDED, "ObjectAdded");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, EVENT_OBJECT_REMOVED, "ObjectRemoved");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EVENT_FREEZELAT, "FREEZE_LATITUDE_LONGITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EVENT_FREEZEALT, "FREEZE_ALTITUDE_SET");
hr += SimConnect_MapClientEventToSimEvent(m_hSimConnect, EVENT_FREEZEATT, "FREEZE_ATTITUDE_SET");
return hr;
}
HRESULT CSimulatorFsx::initDataDefinitions()
{
return CSimConnectDataDefinition::initDataDefinitions(m_hSimConnect);
}
void CSimulatorFsx::update()
{
foreach(SimConnectObject simObj, m_simConnectObjects)
{
if (simObj.m_interpolator.hasEnoughAircraftSituations())
{
DataDefinitionAircraftPosition position;
CAircraftSituation situation = simObj.m_interpolator.getCurrentSituation();
position.latitude = situation.latitude().value();
position.longitude = situation.longitude().value();
position.altitude = situation.getAltitude().value(CLengthUnit::ft());
position.pitch = situation.getPitch().value();
position.bank = situation.getBank().value();
position.trueHeading = situation.getHeading().value(CAngleUnit::deg());
DataDefinitionAircraftConfiguration configuration;
configuration.gearCenter = 100.0;
configuration.gearLeft = 100.0;
configuration.gearRight = 100.0;
configuration.gearTail = 100.0;
configuration.gearAux = 100.0;
if (simObj.m_objectId != 0)
{
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataAircraftPosition, simObj.m_objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionAircraftPosition), &position);
// With the following SimConnect call all aircrafts loose their red tag. No idea why though.
SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDataDefinition::DataAircraftConfiguration, simObj.m_objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(DataDefinitionAircraftConfiguration), &configuration);
}
}
}
}
}
}

View File

@@ -0,0 +1,159 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BLACKSIMPLUGIN_SIMULATOR_FSX_H
#define BLACKSIMPLUGIN_SIMULATOR_FSX_H
#include "simconnect_datadefinition.h"
#include "blackcore/simulator.h"
#include "blackcore/interpolator_linear.h"
#include "blackmisc/avaircraft.h"
#include "blacksim/simulatorinfo.h"
#include <simconnect/SimConnect.h>
#include <QObject>
#include <QtPlugin>
#include <QHash>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
namespace BlackSimPlugin
{
namespace Fsx
{
//! \brief Factory implementation to create CSimulatorFsx instances
class Q_DECL_EXPORT CSimulatorFsxFactory : public QObject, public BlackCore::ISimulatorFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "net.vatsim.PilotClient.BlackCore.SimulatorInterface")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
//! \copydoc BlackCore::ISimulatorFactory::create()
virtual BlackCore::ISimulator *create(QObject *parent) override;
};
//! \brief SimConnect Event ID's
enum EVENT_ID
{
EVENT_SIM_STATUS,
EVENT_OBJECT_ADDED,
EVENT_OBJECT_REMOVED,
EVENT_SLEW_ON,
EVENT_FRAME,
EVENT_FREEZELAT,
EVENT_FREEZEALT,
EVENT_FREEZEATT
};
//! \brief FSX Simulator Implementation
class CSimulatorFsx : public BlackCore::ISimulator
{
Q_OBJECT
public:
//! \brief Constructor
CSimulatorFsx(QObject *parent = nullptr);
//! \copydoc ISimulator::isConnected()
virtual bool isConnected() const override;
//! \copydoc ISimulator::getOwnAircraft()
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; }
//! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const QString &type, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override;
//! \copydoc ISimulator::addAircraftSituation()
virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override;
//! \copydoc ISimulator::removeRemoteAircraft()
virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc ISimulator::getSimulatorInfo()
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
/*!
* \brief SimConnect Callback
* \param pData
* \param cbData
* \param pContext
*/
static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
//! \brief Called when sim has started
void onSimRunning();
//! \brief Called when sim has stopped
void onSimStopped();
//! \brief Slot called every visual frame
void onSimFrame();
/*!
* \brief Called when data about our own aircraft is received
* \param aircraft
*/
void setOwnAircraft(DataDefinitionOwnAircraft aircraft);
/*!
* \brief Set ID of a SimConnect object
* \param requestID
* \param objectID
*/
void setSimconnectObjectID(DWORD requestID, DWORD objectID);
//! \private
void onSimExit();
protected:
//! \brief Timer event
virtual void timerEvent(QTimerEvent *event);
private slots:
//! \brief Try to connect
void checkConnection();
//! \brief Dispatch SimConnect messages
void dispatch();
private:
struct SimConnectObject
{
BlackMisc::Aviation::CCallsign m_callsign;
BlackCore::CInterpolatorLinear m_interpolator;
int m_requestId;
int m_objectId;
};
/*!
* \brief Initialize SimConnect system events
* \return
*/
HRESULT initSystemEvents();
/*!
* \brief Initialize SimConnect data definitions
* \return
*/
HRESULT initDataDefinitions();
void update();
bool m_isConnected; //!< Is sim connected
bool m_simRunning; //!< Sim running.
HANDLE m_hSimConnect; //!< Handle to SimConnect object
uint m_nextObjID;
BlackSim::CSimulatorInfo m_simulatorInfo;
BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator
QHash<BlackMisc::Aviation::CCallsign, SimConnectObject> m_simConnectObjects;
};
}
} // namespace BlackCore
#endif // BLACKSIMPLUGIN_SIMULATOR_FSX_H