Load P3D 64 bit SimConnect shared library at runtime

This aligns the behavior and concept with the 32 bit FSX version. SimConnect
is loaded at runtime, depending on the version being selected.
It also adds a featuren to change the P3D SimConnect version at runtime by
unloading the previous and loading a new one.

ref T349
This commit is contained in:
Roland Winklmeier
2018-10-24 14:01:12 +02:00
committed by Klaus Basan
parent 0f140cb155
commit f63008dd3f
10 changed files with 183 additions and 63 deletions

View File

@@ -29,24 +29,14 @@ fsuipc {
simconnect {
DEFINES += SIMCONNECT_H_NOMANIFEST
equals(WORD_SIZE,64) {
P3D_X64_VERSION = "4.2"
INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/P3D-v$${P3D_X64_VERSION}
LIBS *= -L$$EXTERNALS_LIB_DIR/P3D-v$${P3D_X64_VERSION}
LIBS *= -lAdvapi32
LIBS += -ldxguid -lole32
# ole32 only needed for P3D on WIN64 systems, LNK2019: unresolved external symbol __imp_CoTaskMemFree referenced in function
# ldxguid are DirectX guid numbers
CONFIG(debug, debug|release): LIBS *= -lSimConnectDebug
else: LIBS *= -lSimConnect
INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/P3D-v4
DEFINES += P3D_SDK_VERSION=400
}
equals(WORD_SIZE,32) {
INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/FSX-XPack
# LIBS *= -L$$EXTERNALS_LIB_DIR/FSX-XPack
}
RC_FILE = $$SourceRoot/src/plugins/simulator/fsxcommon/simconnect.rc
msvc: QMAKE_LFLAGS *= /ignore:4099
}
blackgui {

View File

@@ -147,9 +147,6 @@ namespace BlackConfig
//! \returns 32, 64 or -1 (in case no info is possible)
static int buildWordSize();
//! P3D 64 bit build version
static const QString &p3dX64BuildVersion(); // defined in buildconfig_gen.cpp.in
private:
//! Major version
static int versionMajor(); // defined in buildconfig_gen.cpp.in

View File

@@ -141,12 +141,6 @@ const QString &BlackConfig::CBuildConfig::gitHeadSha1()
return gitHeadSha1;
}
const QString &BlackConfig::CBuildConfig::p3dX64BuildVersion()
{
static const QString p3dX64BuildVersion(\"$$P3D_X64_VERSION\"); // libraries.pri
return p3dX64BuildVersion;
}
namespace Private
{
const QDateTime lastCommitTimestampImpl()

View File

@@ -8,6 +8,7 @@
*/
#include "simulatorfsx.h"
#include "../fsxcommon/simconnectsymbols.h"
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
@@ -39,5 +40,18 @@ namespace BlackSimPlugin
CAircraftIcaoCode("B738", "L2J")
});
}
bool CSimulatorFsx::connectTo()
{
if (!loadAndResolveFsxSimConnect(true)) { return false; }
return CSimulatorFsxCommon::connectTo();
}
void CSimulatorFsxListener::startImpl()
{
if (!loadAndResolveFsxSimConnect(true)) { return; }
return CSimulatorFsxCommonListener::startImpl();
}
} // ns
} // ns

View File

@@ -31,6 +31,11 @@ namespace BlackSimPlugin
BlackMisc::Weather::IWeatherGridProvider *weatherGridProvider,
BlackMisc::Network::IClientProvider *clientProvider,
QObject *parent = nullptr);
//! \name ISimulator implementations
//! @{
virtual bool connectTo() override;
//! @}
};
//! Listener for FSX
@@ -41,6 +46,9 @@ namespace BlackSimPlugin
public:
//! Constructor
using CSimulatorFsxCommonListener::CSimulatorFsxCommonListener;
protected:
virtual void startImpl() override;
};
} // ns
} // ns

View File

@@ -16,16 +16,12 @@
using namespace BlackMisc;
#ifdef Q_OS_WIN64
bool loadAndResolveSimConnect(bool manifestProbing)
{
Q_UNUSED(manifestProbing);
return true;
}
#else
typedef HRESULT(__stdcall *PfnSimConnect_Open)(HANDLE *, LPCSTR, HWND, DWORD, HANDLE, DWORD);
typedef HRESULT(__stdcall *PfnSimConnect_Close)(HANDLE);
typedef HRESULT(__stdcall *PfnSimConnect_AddToDataDefinition)(HANDLE, SIMCONNECT_DATA_DEFINITION_ID, const char *, const char *, SIMCONNECT_DATATYPE, float, DWORD);
@@ -51,6 +47,12 @@ typedef HRESULT(__stdcall *PfnSimConnect_MapClientDataNameToID)(HANDLE, const ch
typedef HRESULT(__stdcall *PfnSimConnect_CreateClientData)(HANDLE, SIMCONNECT_CLIENT_DATA_ID, DWORD, SIMCONNECT_CREATE_CLIENT_DATA_FLAG);
typedef HRESULT(__stdcall *PfnSimConnect_AddToClientDataDefinition)(HANDLE, SIMCONNECT_CLIENT_DATA_DEFINITION_ID, DWORD, DWORD, float, DWORD);
#ifdef Q_OS_WIN64
typedef HRESULT(__stdcall *PfnSimConnect_RequestGroundInfo)(HANDLE, SIMCONNECT_DATA_REQUEST_ID, double, double, double, double, double, double, DWORD, DWORD, SIMCONNECT_GROUND_INFO_LATLON_FORMAT, SIMCONNECT_GROUND_INFO_ALT_FORMAT, SIMCONNECT_GROUND_INFO_SOURCE_FLAG);
typedef HRESULT(__stdcall *PfnSimConnect_ChangeView)(HANDLE, const char *);
typedef HRESULT(__stdcall *PfnSimConnect_AIReleaseControlEx)(HANDLE, SIMCONNECT_OBJECT_ID, SIMCONNECT_DATA_REQUEST_ID, BOOL);
#endif
//! The SimConnect Symbols
//! \private @{
struct SimConnectSymbols
@@ -79,6 +81,11 @@ struct SimConnectSymbols
PfnSimConnect_MapClientDataNameToID SimConnect_MapClientDataNameToID = nullptr;
PfnSimConnect_CreateClientData SimConnect_CreateClientData = nullptr;
PfnSimConnect_AddToClientDataDefinition SimConnect_AddToClientDataDefinition = nullptr;
#ifdef Q_OS_WIN64
PfnSimConnect_RequestGroundInfo SimConnect_RequestGroundInfo = nullptr;
PfnSimConnect_ChangeView SimConnect_ChangeView = nullptr;
PfnSimConnect_AIReleaseControlEx SimConnect_AIReleaseControlEx = nullptr;
#endif
};
//! @ }
@@ -96,15 +103,81 @@ bool resolveSimConnectSymbol(QLibrary &library, FuncPtr &funcPtr, const char *fu
return true;
}
bool loadAndResolveSimConnect(bool manifestProbing)
bool resolveCommonSimConnectSymbols(QLibrary &simConnectDll)
{
bool resolveSuccess = true;
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_Open, "SimConnect_Open");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_Close, "SimConnect_Close");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AddToDataDefinition, "SimConnect_AddToDataDefinition");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_Text, "SimConnect_Text");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_CallDispatch, "SimConnect_CallDispatch");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_WeatherSetModeCustom, "SimConnect_WeatherSetModeCustom");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_WeatherSetModeGlobal, "SimConnect_WeatherSetModeGlobal");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_WeatherSetObservation, "SimConnect_WeatherSetObservation");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_TransmitClientEvent, "SimConnect_TransmitClientEvent");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SetClientData, "SimConnect_SetClientData");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_RequestDataOnSimObject, "SimConnect_RequestDataOnSimObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_RequestClientData, "SimConnect_RequestClientData");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SubscribeToSystemEvent, "SimConnect_SubscribeToSystemEvent");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_MapClientEventToSimEvent, "SimConnect_MapClientEventToSimEvent");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SubscribeToFacilities, "SimConnect_SubscribeToFacilities");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_GetLastSentPacketID, "SimConnect_GetLastSentPacketID");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AIRemoveObject, "SimConnect_AIRemoveObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SetDataOnSimObject, "SimConnect_SetDataOnSimObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AIReleaseControl, "SimConnect_AIReleaseControl");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AICreateNonATCAircraft, "SimConnect_AICreateNonATCAircraft");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AICreateSimulatedObject, "SimConnect_AICreateSimulatedObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_MapClientDataNameToID, "SimConnect_MapClientDataNameToID");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_CreateClientData, "SimConnect_CreateClientData");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AddToClientDataDefinition, "SimConnect_AddToClientDataDefinition");
return resolveSuccess;
}
#ifdef Q_OS_WIN64
bool resolveP3DSimConnectSymbols(QLibrary &simConnectDll)
{
bool resolveSuccess = true;
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_RequestGroundInfo, "SimConnect_RequestGroundInfo");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_ChangeView, "SimConnect_ChangeView");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AIReleaseControlEx, "SimConnect_AIReleaseControlEx");
return resolveSuccess;
}
bool loadAndResolveP3DSimConnect(P3DSimConnectVersion version)
{
// Check if already loaded
if (gSymbols.SimConnect_Open) { return true; }
QLibrary simConnectDll;
simConnectDll.setFileName("SimConnect.dll");
simConnectDll.setLoadHints(QLibrary::PreventUnloadHint);
QString simConnectFileName(QStringLiteral("SimConnect.P3D-"));
switch (version)
{
case P3DSimConnectv40: simConnectFileName += "v4.0"; break;
case P3DSimConnectv41: simConnectFileName += "v4.1"; break;
case P3DSimConnectv42: simConnectFileName += "v4.2"; break;
case P3DSimConnectv43: simConnectFileName += "v4.3"; break;
}
QLibrary simConnectDll(simConnectFileName);
simConnectDll.setLoadHints(QLibrary::PreventUnloadHint);
if (simConnectDll.load())
{
return resolveCommonSimConnectSymbols(simConnectDll) && resolveP3DSimConnectSymbols(simConnectDll);
}
else
{
CLogMessage(static_cast<SimConnectSymbols*>(nullptr)).error("Failed to load SimConnect.dll: %1") << simConnectDll.errorString();
return false;
}
}
#else
bool loadAndResolveFsxSimConnect(bool manifestProbing)
{
// Check if already loaded
if (gSymbols.SimConnect_Open) { return true; }
QLibrary simConnectDll(QStringLiteral("SimConnect"));
simConnectDll.setLoadHints(QLibrary::PreventUnloadHint);
if (manifestProbing)
{
HMODULE hInst = nullptr;
@@ -153,42 +226,17 @@ bool loadAndResolveSimConnect(bool manifestProbing)
if (simConnectDll.isLoaded())
{
bool resolveSuccess = true;
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_Open, "SimConnect_Open");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_Close, "SimConnect_Close");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AddToDataDefinition, "SimConnect_AddToDataDefinition");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_Text, "SimConnect_Text");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_CallDispatch, "SimConnect_CallDispatch");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_WeatherSetModeCustom, "SimConnect_WeatherSetModeCustom");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_WeatherSetModeGlobal, "SimConnect_WeatherSetModeGlobal");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_WeatherSetObservation, "SimConnect_WeatherSetObservation");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_TransmitClientEvent, "SimConnect_TransmitClientEvent");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SetClientData, "SimConnect_SetClientData");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_RequestDataOnSimObject, "SimConnect_RequestDataOnSimObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_RequestClientData, "SimConnect_RequestClientData");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SubscribeToSystemEvent, "SimConnect_SubscribeToSystemEvent");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_MapClientEventToSimEvent, "SimConnect_MapClientEventToSimEvent");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SubscribeToFacilities, "SimConnect_SubscribeToFacilities");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_GetLastSentPacketID, "SimConnect_GetLastSentPacketID");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AIRemoveObject, "SimConnect_AIRemoveObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_SetDataOnSimObject, "SimConnect_SetDataOnSimObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AIReleaseControl, "SimConnect_AIReleaseControl");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AICreateNonATCAircraft, "SimConnect_AICreateNonATCAircraft");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AICreateSimulatedObject, "SimConnect_AICreateSimulatedObject");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_MapClientDataNameToID, "SimConnect_MapClientDataNameToID");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_CreateClientData, "SimConnect_CreateClientData");
resolveSuccess = resolveSuccess & resolveSimConnectSymbol(simConnectDll, gSymbols.SimConnect_AddToClientDataDefinition, "SimConnect_AddToClientDataDefinition");
return resolveSuccess;
return resolveCommonSimConnectSymbols(simConnectDll);
}
else
{
CLogMessage(static_cast<SimConnectSymbols*>(nullptr)).error("Failed to load SimConnect.dll: %1") << simConnectDll.errorString();
return false;
}
return true;
}
#endif
SIMCONNECTAPI SimConnect_Open(HANDLE *phSimConnect, LPCSTR szName, HWND hWnd, DWORD UserEventWin32, HANDLE hEventHandle, DWORD ConfigIndex)
{
return gSymbols.SimConnect_Open(phSimConnect, szName, hWnd, UserEventWin32, hEventHandle, ConfigIndex);
@@ -309,6 +357,22 @@ SIMCONNECTAPI SimConnect_AddToClientDataDefinition(HANDLE hSimConnect, SIMCONNEC
return gSymbols.SimConnect_AddToClientDataDefinition(hSimConnect, DefineID, dwOffset, dwSizeOrType, fEpsilon, DatumID);
}
#ifdef Q_OS_WIN64
SIMCONNECTAPI SimConnect_RequestGroundInfo(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, double minLat, double minLon, double minAlt, double maxLat, double maxLon, double maxAlt, DWORD dwGridWidth, DWORD dwGridHeight, SIMCONNECT_GROUND_INFO_LATLON_FORMAT eLatLonFormat, SIMCONNECT_GROUND_INFO_ALT_FORMAT eAltFormat, SIMCONNECT_GROUND_INFO_SOURCE_FLAG eSourceFlags)
{
return gSymbols.SimConnect_RequestGroundInfo(hSimConnect, RequestID, minLat, minLon, minAlt, maxLat, maxLon, maxAlt, dwGridWidth, dwGridHeight, eLatLonFormat, eAltFormat, eSourceFlags);
}
SIMCONNECTAPI SimConnect_ChangeView(HANDLE hSimConnect, const char * szName)
{
return gSymbols.SimConnect_ChangeView(hSimConnect, szName);
}
SIMCONNECTAPI SimConnect_AIReleaseControlEx(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_REQUEST_ID RequestID, BOOL destroyAI)
{
return gSymbols.SimConnect_AIReleaseControlEx(hSimConnect, ObjectID, RequestID, destroyAI);
}
#endif

View File

@@ -12,9 +12,30 @@
#ifndef BLACKSIMPLUGIN_FSXCOMMON_SIMCONNECTSYMBOLS_H
#define BLACKSIMPLUGIN_FSXCOMMON_SIMCONNECTSYMBOLS_H
//! Load and resolve SimConnect.
#include <QtGlobal>
#ifdef Q_OS_WIN64
enum P3DSimConnectVersion
{
P3DSimConnectv40,
P3DSimConnectv41,
P3DSimConnectv42,
P3DSimConnectv43
};
//! Load and resolve versioned P3D SimConnect.
//! If a another version was already loaded previously, it won't unload it.
//! You have to call /sa unloadSimConnect() before.
bool loadAndResolveP3DSimConnect(P3DSimConnectVersion version);
#else
//! Load and resolve FSX SimConnect.
//! \param manifestProbing Set to true if you want to try loading from the assembly cache with manifests.
//! Otherwise the library in the bin folder will be loaded.
bool loadAndResolveSimConnect(bool manifestProbing);
bool loadAndResolveFsxSimConnect(bool manifestProbing);
#endif
#endif // guard

View File

@@ -95,8 +95,6 @@ namespace BlackSimPlugin
if (this->isConnected()) { return true; }
this->reset();
if (!loadAndResolveSimConnect(true)) { return false; }
const HRESULT hr = SimConnect_Open(&m_hSimConnect, sApp->swiftVersionChar(), nullptr, 0, nullptr, 0);
if (isFailure(hr))
{
@@ -2462,8 +2460,6 @@ namespace BlackSimPlugin
m_simulatorName.clear();
m_simulatorDetails.clear();
if (!loadAndResolveSimConnect(true)) { return; }
m_timer.start();
}

View File

@@ -8,6 +8,7 @@
*/
#include "simulatorp3d.h"
#include "../fsxcommon/simconnectsymbols.h"
#include "../fscommon/simulatorfscommonfunctions.h"
#include "blackmisc/threadutils.h"
#include "blackmisc/logmessage.h"
@@ -30,6 +31,10 @@ namespace BlackSimPlugin
{
namespace P3D
{
#ifdef Q_OS_WIN64
static P3DSimConnectVersion gP3DSimConnectVersion = P3DSimConnectv42;
#endif
CSimulatorP3D::CSimulatorP3D(const CSimulatorPluginInfo &info,
IOwnAircraftProvider *ownAircraftProvider,
IRemoteAircraftProvider *remoteAircraftProvider,
@@ -49,6 +54,17 @@ namespace BlackSimPlugin
"Constellation in TWA livery", CAircraftIcaoCode("CONI", "L4P")));
}
bool CSimulatorP3D::connectTo()
{
#ifdef Q_OS_WIN64
if (!loadAndResolveP3DSimConnect(gP3DSimConnectVersion)) { return false; }
return CSimulatorFsxCommon::connectTo();
#else
if (!loadAndResolveFsxSimConnect(true)) { return false; }
return CSimulatorFsxCommon::connectTo();
#endif
}
#ifdef Q_OS_WIN64
void CSimulatorP3D::SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext)
{
@@ -277,5 +293,17 @@ namespace BlackSimPlugin
CSimulatorFsxCommon::SimConnectProc(pData, cbData, pContext);
}
#endif
void CSimulatorP3DListener::startImpl()
{
#ifdef Q_OS_WIN64
if (!loadAndResolveP3DSimConnect(gP3DSimConnectVersion)) { return; }
return CSimulatorFsxCommonListener::startImpl();
#else
if (!loadAndResolveFsxSimConnect(true)) { return; }
return CSimulatorFsxCommonListener::startImpl();
#endif
}
} // namespace
} // namespace

View File

@@ -42,6 +42,11 @@ namespace BlackSimPlugin
BlackMisc::Network::IClientProvider *clientProvider,
QObject *parent = nullptr);
//! \name ISimulator implementations
//! @{
virtual bool connectTo() override;
//! @}
#ifdef Q_OS_WIN64
//! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation
virtual bool requestElevation(const BlackMisc::Geo::ICoordinateGeodetic &reference, const BlackMisc::Aviation::CCallsign &callsign) override;
@@ -78,6 +83,9 @@ namespace BlackSimPlugin
public:
//! Constructor
using CSimulatorFsxCommonListener::CSimulatorFsxCommonListener;
protected:
virtual void startImpl() override;
};
} // ns
} // ns