mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 07:15:35 +08:00
refs #789, FSX errors OPERATION_INVALID and EXCEPTION_UNRECOGNIZED_ID
* only emit aircraft as rendered when object id is received, not before * added CSimualtedAircraft to CSimConnectObject (so it can be used as signal argument) * some utility functions to get callsign/simobject by id
This commit is contained in:
@@ -72,7 +72,7 @@ namespace BlackCore
|
||||
if (!remoteAircraft.isEnabled()) { return false; }
|
||||
|
||||
// if not restriced, directly change
|
||||
if (!isRenderingRestricted()) { return this->physicallyAddRemoteAircraft(remoteAircraft); }
|
||||
if (!isRenderingRestricted()) { this->physicallyAddRemoteAircraft(remoteAircraft); return true; }
|
||||
|
||||
// will be added with next snapshot
|
||||
return false;
|
||||
@@ -81,7 +81,7 @@ namespace BlackCore
|
||||
bool CSimulatorCommon::logicallyRemoveRemoteAircraft(const CCallsign &callsign)
|
||||
{
|
||||
// if not restriced, directly change
|
||||
if (!isRenderingRestricted()) { return this->physicallyRemoveRemoteAircraft(callsign); }
|
||||
if (!isRenderingRestricted()) { this->physicallyRemoveRemoteAircraft(callsign); return true; }
|
||||
|
||||
// will be added with next snapshot
|
||||
return false;
|
||||
@@ -298,7 +298,8 @@ namespace BlackCore
|
||||
int removed = 0;
|
||||
for (const CCallsign &callsign : callsigns)
|
||||
{
|
||||
if (physicallyRemoveRemoteAircraft(callsign)) { removed++; }
|
||||
physicallyRemoveRemoteAircraft(callsign);
|
||||
removed++;
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
@@ -338,8 +339,9 @@ namespace BlackCore
|
||||
for (const CSimulatedAircraft &aircraft : aircraftToBeAdded)
|
||||
{
|
||||
Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO, "Disabled aircraft detected as to be added");
|
||||
bool a = this->physicallyAddRemoteAircraft(aircraft);
|
||||
changed = changed || a;
|
||||
Q_ASSERT_X(aircraft.hasModelString(), Q_FUNC_INFO, "Missing model string");
|
||||
this->physicallyAddRemoteAircraft(aircraft);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,6 @@ namespace BlackSimPlugin
|
||||
client->setPlayerUserId(m_fs9Host->getPlayerUserId());
|
||||
client->start();
|
||||
|
||||
|
||||
m_hashFs9Clients.insert(callsign, client);
|
||||
updateAircraftRendered(callsign, rendered);
|
||||
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
|
||||
|
||||
@@ -15,9 +15,13 @@ namespace BlackSimPlugin
|
||||
{
|
||||
CSimConnectObject::CSimConnectObject() { }
|
||||
|
||||
CSimConnectObject::CSimConnectObject(const BlackMisc::Aviation::CCallsign &callsign, int requestId, int objectId, bool vtol) :
|
||||
m_callsign(callsign), m_requestId(requestId), m_objectId(objectId), m_vtol(vtol)
|
||||
CSimConnectObject::CSimConnectObject(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, int requestId) :
|
||||
m_aircraft(aircraft), m_requestId(requestId)
|
||||
{ }
|
||||
|
||||
bool CSimConnectObject::hasValidRequestAndObjectId() const
|
||||
{
|
||||
return this->m_requestId >= 0 && this->m_objectId >= 0;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#ifndef BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
||||
#define BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
|
||||
|
||||
#include "blackmisc/aviation/callsign.h"
|
||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace BlackMisc { class IInterpolator; }
|
||||
@@ -25,21 +25,20 @@ namespace BlackSimPlugin
|
||||
class CSimConnectObject
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CSimConnectObject();
|
||||
|
||||
//! Constructor
|
||||
CSimConnectObject(const BlackMisc::Aviation::CCallsign &callsign, int requestId, int objectId, bool vtol);
|
||||
CSimConnectObject(const BlackMisc::Simulation::CSimulatedAircraft &aircraft,int requestId);
|
||||
|
||||
//! Destructor
|
||||
~CSimConnectObject() {}
|
||||
|
||||
//! Set callsign
|
||||
void setCallsign(const BlackMisc::Aviation::CCallsign &callsign) { m_callsign = callsign; }
|
||||
|
||||
//! Get Callsign
|
||||
BlackMisc::Aviation::CCallsign getCallsign() const { return m_callsign; }
|
||||
BlackMisc::Aviation::CCallsign getCallsign() const { return m_aircraft.getCallsign(); }
|
||||
|
||||
//! Simulated aircraft (as added)
|
||||
BlackMisc::Simulation::CSimulatedAircraft getAircraft() const { return m_aircraft; }
|
||||
|
||||
//! Set Simconnect request id
|
||||
void setRequestId(int id) { m_requestId = id; }
|
||||
@@ -54,16 +53,15 @@ namespace BlackSimPlugin
|
||||
int getObjectId() const { return m_objectId; }
|
||||
|
||||
//! VTOL?
|
||||
bool isVtol() const { return m_vtol; }
|
||||
bool isVtol() const { return m_aircraft.isVtol(); }
|
||||
|
||||
//! VTOL?
|
||||
void setVtol(bool vtol) { m_vtol = vtol; }
|
||||
//! Was the object really added to SIM
|
||||
bool hasValidRequestAndObjectId() const;
|
||||
|
||||
private:
|
||||
BlackMisc::Aviation::CCallsign m_callsign;
|
||||
BlackMisc::Simulation::CSimulatedAircraft m_aircraft;
|
||||
int m_requestId = -1;
|
||||
int m_objectId = -1;
|
||||
bool m_vtol = false;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -53,7 +53,8 @@ namespace BlackSimPlugin
|
||||
|
||||
m_useFsuipc = true; // Temporarily enabled until Simconnect Weather is implemented.
|
||||
this->m_interpolator = new CInterpolatorLinear(remoteAircraftProvider, this);
|
||||
m_defaultModel = {
|
||||
m_defaultModel =
|
||||
{
|
||||
"Boeing 737-800 Paint1",
|
||||
CAircraftModel::TypeModelMatchingDefaultModel,
|
||||
"B737-800 default model",
|
||||
@@ -128,51 +129,66 @@ namespace BlackSimPlugin
|
||||
|
||||
bool CSimulatorFsx::physicallyAddRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft)
|
||||
{
|
||||
CCallsign callsign(newRemoteAircraft.getCallsign());
|
||||
const CCallsign callsign(newRemoteAircraft.getCallsign());
|
||||
|
||||
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
|
||||
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign");
|
||||
Q_ASSERT_X(newRemoteAircraft.hasModelString(), Q_FUNC_INFO, "missing model string");
|
||||
if (callsign.isEmpty()) { return false; }
|
||||
|
||||
bool aircraftAlreadyExistsInSim = this->m_simConnectObjects.contains(callsign);
|
||||
const bool aircraftAlreadyExistsInSim = this->m_simConnectObjects.contains(callsign);
|
||||
if (aircraftAlreadyExistsInSim)
|
||||
{
|
||||
// remove first
|
||||
this->physicallyRemoveRemoteAircraft(callsign);
|
||||
CLogMessage(this).warning("Have to remove aircraft %1 before I can add it") << callsign;
|
||||
const CSimConnectObject simObj = m_simConnectObjects[callsign];
|
||||
if (simObj.isPendingAdded())
|
||||
{
|
||||
return true; // already pending
|
||||
}
|
||||
else
|
||||
{
|
||||
// same model, nothing will change, otherwise add again when removed
|
||||
if (simObj.getAircraft().getModel() != newRemoteAircraft.getModel())
|
||||
{
|
||||
m_aircraftToAddAgainWhenRemoved.push_back(newRemoteAircraft);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CSimConnectObject simObj(callsign, m_nextObjID, 0, newRemoteAircraft.isVtol());
|
||||
++m_nextObjID;
|
||||
|
||||
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
|
||||
|
||||
// create AI
|
||||
bool adding = false;
|
||||
const CAircraftModel aircraftModel = newRemoteAircraft.getModel();
|
||||
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
|
||||
bool rendered = false;
|
||||
if (isConnected())
|
||||
{
|
||||
// initial position
|
||||
this->setInitialAircraftSituation(remoteAircraftCopy); // set interpolated data/parts if available
|
||||
setInitialAircraftSituation(remoteAircraftCopy); // set interpolated data/parts if available
|
||||
|
||||
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(remoteAircraftCopy.getSituation());
|
||||
QByteArray m = aircraftModel.getModelString().toLocal8Bit();
|
||||
HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, m.constData(), qPrintable(callsign.toQString().left(12)), initialPosition, static_cast<SIMCONNECT_DATA_REQUEST_ID>(simObj.getRequestId()));
|
||||
if (hr != S_OK) { CLogMessage(this).error("SimConnect, can not create AI traffic"); }
|
||||
m_simConnectObjects.insert(callsign, simObj);
|
||||
CLogMessage(this).info("FSX: Added aircraft %1") << callsign.toQString();
|
||||
rendered = true;
|
||||
const QByteArray m = aircraftModel.getModelString().toLocal8Bit();
|
||||
|
||||
const int requestId = m_requestId;
|
||||
++m_requestId;
|
||||
HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, m.constData(), qPrintable(callsign.toQString().left(12)), initialPosition, static_cast<SIMCONNECT_DATA_REQUEST_ID>(requestId));
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(this).error("SimConnect, can not create AI traffic: '%1' '%2'") << callsign.toQString() << aircraftModel.getModelString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we will request a new aircraft by request ID, later we will receive its object id
|
||||
// so far this object id is -1
|
||||
addedAircraft.setRendered(false);
|
||||
const CSimConnectObject simObject(addedAircraft, requestId);
|
||||
m_simConnectObjects.insert(callsign, simObject);
|
||||
adding = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLogMessage(this).warning("FSX: Not connected, not added aircraft %1") << callsign.toQString();
|
||||
CLogMessage(this).warning("FSX: Not connected, not added aircraft '%1' '%2'") << callsign.toQString() << aircraftModel.getModelString();
|
||||
}
|
||||
|
||||
remoteAircraftCopy.setRendered(rendered);
|
||||
this->updateAircraftRendered(callsign, rendered);
|
||||
emit aircraftRenderingChanged(remoteAircraftCopy);
|
||||
|
||||
return rendered;
|
||||
return adding;
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CSimulatedAircraft &ownAircraft, const CIdentifier &originator)
|
||||
@@ -450,7 +466,7 @@ namespace BlackSimPlugin
|
||||
{
|
||||
newMode = sbDataArea.isStandby() ? CTransponder::StateStandby : CTransponder::ModeC;
|
||||
}
|
||||
CSimulatedAircraft myAircraft(this->getOwnAircraft());
|
||||
const CSimulatedAircraft myAircraft(this->getOwnAircraft());
|
||||
bool changed = (myAircraft.getTransponderMode() != newMode);
|
||||
if (!changed) { return; }
|
||||
CTransponder xpdr = myAircraft.getTransponder();
|
||||
@@ -458,22 +474,60 @@ namespace BlackSimPlugin
|
||||
this->updateCockpit(myAircraft.getCom1System(), myAircraft.getCom2System(), xpdr, this->identifier());
|
||||
}
|
||||
|
||||
void CSimulatorFsx::setSimConnectObjectID(DWORD requestID, DWORD objectID)
|
||||
bool CSimulatorFsx::aiAircraftWasAddedInSimulator(DWORD requestID, DWORD objectID)
|
||||
{
|
||||
if (!this->setSimConnectObjectID(requestID, objectID)) { return false; }
|
||||
const CSimConnectObject simObject = this->getSimObjectForObjectId(objectID);
|
||||
|
||||
bool ok = false;
|
||||
if (simObject.hasValidRequestAndObjectId() && !simObject.getCallsign().isEmpty())
|
||||
{
|
||||
|
||||
SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID);
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeLat, 1,
|
||||
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeAlt, 1,
|
||||
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeAtt, 1,
|
||||
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
|
||||
// optimistic approach, as the aircraft is not yet really in the SIM
|
||||
// its generation has been just requested
|
||||
this->updateAircraftRendered(simObject.getCallsign(), true);
|
||||
emit aircraftRenderingChanged(simObject.getAircraft());
|
||||
ok = true;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::setSimConnectObjectID(DWORD requestID, DWORD objectID)
|
||||
{
|
||||
// First check, if this request id belongs to us
|
||||
auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(),
|
||||
[requestID](const CSimConnectObject & obj) { return obj.getRequestId() == static_cast<int>(requestID); });
|
||||
if (it == m_simConnectObjects.end()) { return; }
|
||||
const int requestIntId = static_cast<int>(requestID);
|
||||
auto it = std::find_if(m_simConnectObjects.begin(), m_simConnectObjects.end(), [requestIntId](const CSimConnectObject & obj) { return obj.getRequestId() == requestIntId; });
|
||||
if (it == m_simConnectObjects.end()) { return false; }
|
||||
|
||||
// belongs to us
|
||||
it->setObjectId(static_cast<int>(objectID));
|
||||
SimConnect_AIReleaseControl(m_hSimConnect, objectID, requestID);
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeLat, 1,
|
||||
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeAlt, 1,
|
||||
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
SimConnect_TransmitClientEvent(m_hSimConnect, objectID, EventFreezeAtt, 1,
|
||||
SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
return true;
|
||||
}
|
||||
|
||||
CCallsign CSimulatorFsx::getCallsignForObjectId(DWORD objectID) const
|
||||
{
|
||||
return getSimObjectForObjectId(objectID).getCallsign();
|
||||
}
|
||||
|
||||
CSimConnectObject CSimulatorFsx::getSimObjectForObjectId(DWORD objectID) const
|
||||
{
|
||||
const int objectIntId = static_cast<int>(objectID);
|
||||
for (const CSimConnectObject &simObject : m_simConnectObjects.values())
|
||||
{
|
||||
if (simObject.getObjectId() == objectIntId)
|
||||
{
|
||||
return simObject;
|
||||
}
|
||||
}
|
||||
return CSimConnectObject();
|
||||
}
|
||||
|
||||
void CSimulatorFsx::timerEvent(QTimerEvent *event)
|
||||
@@ -520,7 +574,8 @@ namespace BlackSimPlugin
|
||||
// only remove from sim
|
||||
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "wrong thred");
|
||||
if (!m_simConnectObjects.contains(callsign)) { return false; }
|
||||
return physicallyRemoveRemoteAircraft(m_simConnectObjects.value(callsign));
|
||||
this->physicallyRemoveRemoteAircraft(m_simConnectObjects.value(callsign));
|
||||
return true;
|
||||
}
|
||||
|
||||
int CSimulatorFsx::physicallyRemoveAllRemoteAircraft()
|
||||
@@ -541,7 +596,7 @@ namespace BlackSimPlugin
|
||||
m_simConnectObjects.remove(callsign);
|
||||
SimConnect_AIRemoveObject(m_hSimConnect, static_cast<SIMCONNECT_OBJECT_ID>(simObject.getObjectId()), static_cast<SIMCONNECT_DATA_REQUEST_ID>(simObject.getRequestId()));
|
||||
updateAircraftRendered(callsign, false);
|
||||
CLogMessage(this).info("FSX: Removed aircraft %1") << simObject.getCallsign().toQString();
|
||||
CLogMessage(this).info("FSX: Removed aircraft '%1'") << simObject.getCallsign().toQString();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -587,7 +642,7 @@ namespace BlackSimPlugin
|
||||
}
|
||||
|
||||
// facility
|
||||
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_nextObjID++));
|
||||
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestId++));
|
||||
if (hr != S_OK)
|
||||
{
|
||||
CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToFacilities failed";
|
||||
@@ -686,7 +741,7 @@ namespace BlackSimPlugin
|
||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPosition,
|
||||
static_cast<SIMCONNECT_OBJECT_ID>(simObj.getObjectId()), 0, 0,
|
||||
sizeof(SIMCONNECT_DATA_INITPOSITION), &position);
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set position on SimObject %1 callsign: %2") << simObj.getObjectId() << callsign; }
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set position on SimObject '%1' callsign: '%2'") << simObj.getObjectId() << callsign; }
|
||||
|
||||
} // interpolation data
|
||||
|
||||
@@ -699,9 +754,9 @@ namespace BlackSimPlugin
|
||||
|
||||
} // all callsigns
|
||||
qint64 dt = QDateTime::currentMSecsSinceEpoch() - currentTimestamp;
|
||||
m_statsUpdateAircraftTimeTotal += dt;
|
||||
m_statsUpdateAircraftCount++;
|
||||
m_statsUpdateAircraftTimeAvg = m_statsUpdateAircraftTimeTotal / m_statsUpdateAircraftCount;
|
||||
m_statsUpdateAircraftTimeTotalMs += dt;
|
||||
m_statsUpdateAircraftCountMs++;
|
||||
m_statsUpdateAircraftTimeAvgMs = m_statsUpdateAircraftTimeTotalMs / m_statsUpdateAircraftCountMs;
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::updateRemoteAircraftParts(const CSimConnectObject &simObj, const CAircraftPartsList &parts, IInterpolator::PartsStatus partsStatus, const CAircraftSituation &interpolatedSituation, bool isOnGround) const
|
||||
@@ -781,20 +836,27 @@ namespace BlackSimPlugin
|
||||
static_cast<SIMCONNECT_OBJECT_ID>(simObj.getObjectId()), 0, 0,
|
||||
sizeof(DataDefinitionRemoteAircraftParts), &ddRemoteAircraftParts);
|
||||
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set parts on SimObject %1 callsign: %2") << simObj.getObjectId() << simObj.getCallsign(); }
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set parts on SimObject '%1' callsign: '%2'") << simObj.getObjectId() << simObj.getCallsign(); }
|
||||
return hr == S_OK;
|
||||
}
|
||||
|
||||
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxInitPosition(const CAircraftSituation &situation)
|
||||
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxPosition(const CAircraftSituation &situation, bool guessOnGround)
|
||||
{
|
||||
SIMCONNECT_DATA_INITPOSITION position;
|
||||
position.Latitude = situation.latitude().value(CAngleUnit::deg());
|
||||
position.Longitude = situation.longitude().value(CAngleUnit::deg());
|
||||
position.Altitude = situation.getAltitude().value(CLengthUnit::ft());
|
||||
position.Pitch = situation.getPitch().value(CAngleUnit::deg());
|
||||
position.Bank = situation.getBank().value(CAngleUnit::deg());
|
||||
// MSFS has inverted pitch and bank angles
|
||||
position.Pitch = -situation.getPitch().value(CAngleUnit::deg());
|
||||
position.Bank = -situation.getBank().value(CAngleUnit::deg());
|
||||
position.Heading = situation.getHeading().value(CAngleUnit::deg());
|
||||
position.Airspeed = situation.getGroundSpeed().value(CSpeedUnit::kts());
|
||||
bool onGround = false;
|
||||
if (guessOnGround)
|
||||
{
|
||||
onGround = situation.isOnGroundGuessed();
|
||||
}
|
||||
position.OnGround = onGround ? 1U : 0U;
|
||||
return position;
|
||||
}
|
||||
|
||||
@@ -814,12 +876,12 @@ namespace BlackSimPlugin
|
||||
int offsetSeconds = this->m_syncTimeOffset.valueRounded(CTimeUnit::s(), 0);
|
||||
myDateTime = myDateTime.addSecs(offsetSeconds);
|
||||
}
|
||||
QTime myTime = myDateTime.time();
|
||||
DWORD h = static_cast<DWORD>(myTime.hour());
|
||||
DWORD m = static_cast<DWORD>(myTime.minute());
|
||||
int targetMins = myTime.hour() * 60 + myTime.minute();
|
||||
int simMins = zuluTimeSim.valueRounded(CTimeUnit::min());
|
||||
int diffMins = qAbs(targetMins - simMins);
|
||||
const QTime myTime = myDateTime.time();
|
||||
const DWORD h = static_cast<DWORD>(myTime.hour());
|
||||
const DWORD m = static_cast<DWORD>(myTime.minute());
|
||||
const int targetMins = myTime.hour() * 60 + myTime.minute();
|
||||
const int simMins = zuluTimeSim.valueRounded(CTimeUnit::min());
|
||||
const int diffMins = qAbs(targetMins - simMins);
|
||||
if (diffMins < 2) { return; }
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluHours, h, SIMCONNECT_GROUP_PRIORITY_STANDARD, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
|
||||
@@ -832,7 +894,7 @@ namespace BlackSimPlugin
|
||||
else
|
||||
{
|
||||
m_syncDeferredCounter = 5; // allow some time to sync
|
||||
CLogMessage(this).info("Synchronized time to UTC: %1") << myTime.toString();
|
||||
CLogMessage(this).info("Synchronized time to UTC: '%1'") << myTime.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,8 +108,18 @@ namespace BlackSimPlugin
|
||||
//! Update from SB client area
|
||||
void updateOwnAircraftFromSimulator(DataDefinitionClientAreaSb sbDataArea);
|
||||
|
||||
//! Set ID of a SimConnect object
|
||||
void setSimConnectObjectID(DWORD requestID, DWORD objectID);
|
||||
//! An AI aircraft was added in the simulator
|
||||
//! \remark that AI aircraft was previously request by requestID
|
||||
bool aiAircraftWasAddedInSimulator(DWORD requestID, 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);
|
||||
|
||||
//! Find which callsign belongs to the object id
|
||||
BlackMisc::Aviation::CCallsign getCallsignForObjectId(DWORD objectID) const;
|
||||
|
||||
//! Find which callsign belongs to the object id
|
||||
CSimConnectObject getSimObjectForObjectId(DWORD objectID) const;
|
||||
|
||||
protected:
|
||||
//! \copydoc BlackCore::ISimulator::isConnected()
|
||||
@@ -182,7 +192,7 @@ namespace BlackSimPlugin
|
||||
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_interpolationsSkipped = 0; //!< number of skipped interpolation request
|
||||
int m_nextObjID = 1; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities
|
||||
int m_requestId = 1; //!< request id
|
||||
int m_dispatchErrors = 0; //!< numer of dispatched failed, \sa ps_dispatch
|
||||
HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object
|
||||
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
|
||||
|
||||
@@ -52,10 +52,23 @@ namespace BlackSimPlugin
|
||||
{
|
||||
SIMCONNECT_RECV_EXCEPTION *exception = (SIMCONNECT_RECV_EXCEPTION *)pData;
|
||||
QString ex;
|
||||
ex.sprintf("Exception=%d SendID=%d Index=%d cbData=%d",
|
||||
static_cast<int>(exception->dwException), static_cast<int>(exception->dwSendID),
|
||||
static_cast<int>(exception->dwIndex), static_cast<int>(cbData));
|
||||
CLogMessage(static_cast<CSimulatorFsx *>(nullptr)).error("Caught FSX simConnect exception: %1 %2")
|
||||
const int exceptionId = static_cast<int>(exception->dwException);
|
||||
const int sendId = static_cast<int>(exception->dwSendID);
|
||||
const int index = static_cast<int>(exception->dwIndex);
|
||||
const int data = static_cast<int>(cbData);
|
||||
ex.sprintf("Exception=%d SendID=%d Index=%d cbData=%d", exceptionId, sendId, index, data);
|
||||
if (exceptionId == SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE)
|
||||
{
|
||||
// means we have problems with an AI aircraft
|
||||
//! \todo find out how to obtain the id here so I can get callsign
|
||||
CCallsign cs = simulatorFsx->getCallsignForObjectId(data);
|
||||
if (!cs.isEmpty())
|
||||
{
|
||||
ex += " callsign: ";
|
||||
ex += cs.toQString();
|
||||
}
|
||||
}
|
||||
CLogMessage(simulatorFsx).error("Caught FSX simConnect exception: %1 %2")
|
||||
<< CSimConnectUtilities::simConnectExceptionToString((SIMCONNECT_EXCEPTION)exception->dwException)
|
||||
<< ex;
|
||||
break;
|
||||
@@ -128,7 +141,13 @@ namespace BlackSimPlugin
|
||||
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);
|
||||
DWORD requestID = event->dwRequestID;
|
||||
DWORD objectID = event->dwObjectID;
|
||||
const bool success = simulatorFsx->aiAircraftWasAddedInSimulator(requestID, objectID);
|
||||
if (!success)
|
||||
{
|
||||
CLogMessage(simulatorFsx).warning("Cannot find CSimConnectObject for request %1") << requestID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
||||
@@ -158,12 +177,12 @@ namespace BlackSimPlugin
|
||||
DataDefinitionSimEnvironment *simEnv = (DataDefinitionSimEnvironment *) &pObjData->dwData;
|
||||
if (simulatorFsx->isTimeSynchronized())
|
||||
{
|
||||
int zh = simEnv->zuluTimeSeconds / 3600;
|
||||
int zm = (simEnv->zuluTimeSeconds - (zh * 3600)) / 60;
|
||||
CTime zulu(zh, zm);
|
||||
int lh = simEnv->localTimeSeconds / 3600;
|
||||
int lm = (simEnv->localTimeSeconds - (lh * 3600)) / 60;
|
||||
CTime local(lh, lm);
|
||||
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;
|
||||
@@ -185,9 +204,9 @@ namespace BlackSimPlugin
|
||||
const QString icao(pFacilityAirport->Icao);
|
||||
if (icao.isEmpty()) { continue; } // airfield without ICAO code
|
||||
if (!CAirportIcaoCode::isValidIcaoDesignator(icao)) { continue; } // tiny airfields in SIM
|
||||
CCoordinateGeodetic pos(pFacilityAirport->Latitude, pFacilityAirport->Longitude, pFacilityAirport->Altitude);
|
||||
const CCoordinateGeodetic pos(pFacilityAirport->Latitude, pFacilityAirport->Longitude, pFacilityAirport->Altitude);
|
||||
CAirport airport(CAirportIcaoCode(icao), pos);
|
||||
CLength d = airport.calculcateAndUpdateRelativeDistanceAndBearing(posAircraft);
|
||||
const CLength d = airport.calculcateAndUpdateRelativeDistanceAndBearing(posAircraft);
|
||||
if (d > maxDistance) { continue; }
|
||||
simulatorFsx->m_airportsInRange.replaceOrAddByIcao(airport);
|
||||
}
|
||||
|
||||
@@ -440,9 +440,7 @@ namespace BlackSimPlugin
|
||||
//! \todo XPlane driver check if already exists, how?
|
||||
//! \todo XPlane driver set correct return value
|
||||
|
||||
|
||||
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
|
||||
|
||||
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
|
||||
m_traffic->addPlane(newRemoteAircraft.getCallsign().asString(), aircraftModel.getModelString(),
|
||||
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
|
||||
@@ -457,8 +455,7 @@ namespace BlackSimPlugin
|
||||
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
|
||||
remoteAircraftCopy.setRendered(rendered);
|
||||
emit aircraftRenderingChanged(remoteAircraftCopy);
|
||||
|
||||
return rendered;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSimulatorXPlane::ps_remoteProviderAddAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation)
|
||||
|
||||
Reference in New Issue
Block a user