diff --git a/src/plugins/simulator/fsx/simconnectobject.h b/src/plugins/simulator/fsx/simconnectobject.h index f66affc33..4554818fc 100644 --- a/src/plugins/simulator/fsx/simconnectobject.h +++ b/src/plugins/simulator/fsx/simconnectobject.h @@ -13,7 +13,7 @@ #define BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H #include "blackmisc/simulation/simulatedaircraft.h" -#include "simconnect/SimConnect.h" +#include "simconnectdatadefinition.h" #include namespace BlackMisc { namespace Simulation { class IInterpolator; } } @@ -43,6 +43,24 @@ namespace BlackSimPlugin //! Simulated aircraft model string const QString &getAircraftModelString() const { return m_aircraft.getModelString(); } + //! 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; } @@ -89,14 +107,18 @@ namespace BlackSimPlugin bool hasValidRequestAndObjectId() const; private: - BlackMisc::Simulation::CSimulatedAircraft m_aircraft; + BlackMisc::Simulation::CSimulatedAircraft m_aircraft; //!< corresponding aircraft DWORD m_requestId = 0; DWORD m_objectId = 0; - SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation 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 }; //! Simulator objects (aka AI aircraft) diff --git a/src/plugins/simulator/fsx/simulatorfsx.cpp b/src/plugins/simulator/fsx/simulatorfsx.cpp index caa77388e..2fff79ade 100644 --- a/src/plugins/simulator/fsx/simulatorfsx.cpp +++ b/src/plugins/simulator/fsx/simulatorfsx.cpp @@ -156,7 +156,7 @@ namespace BlackSimPlugin // initial position if interpolator has data, otherwise do nothing setInitialAircraftSituation(addedAircraft); // set interpolated data/parts if available - const DWORD requestId = obtainRequestId(); + const DWORD requestId = obtainRequestIdSimData(); SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxPosition(addedAircraft.getSituation()); const QString modelString(addedAircraft.getModelString()); @@ -373,15 +373,10 @@ namespace BlackSimPlugin disconnectFrom(); } - DWORD CSimulatorFsx::obtainRequestId() + DWORD CSimulatorFsx::obtainRequestIdSimData() { - DWORD id = m_requestId++; - if (id < FirstRequestId) - { - // overflow, restart - id = FirstRequestId; - m_requestId = FirstRequestId + 1; - } + const DWORD id = m_requestIdSimData++; + if (id > RequestSimDataEnd) { m_requestIdSimData = RequestSimDataStart; } return id; } @@ -562,7 +557,7 @@ namespace BlackSimPlugin } // P3D also has SimConnect_AIReleaseControlEx; - const DWORD requestId = obtainRequestId(); + const DWORD requestId = obtainRequestIdSimData(); HRESULT hr = SimConnect_AIReleaseControl(m_hSimConnect, objectId, static_cast(requestId)); if (hr == S_OK) { @@ -670,6 +665,20 @@ namespace BlackSimPlugin return this->m_simConnectObjects.setSimConnectObjectIdForRequestId(requestID, objectID); } + bool CSimulatorFsx::setCurrentLights(const CCallsign &callsign, const CAircraftLights &lights) + { + if (!m_simConnectObjects.contains(callsign)) { return false; } + m_simConnectObjects[callsign].setCurrentLightsInSimulator(lights); + return true; + } + + bool CSimulatorFsx::setLightsAsSent(const CCallsign &callsign, const CAircraftLights &lights) + { + if (!m_simConnectObjects.contains(callsign)) { return false; } + m_simConnectObjects[callsign].setLightsAsSent(lights); + return true; + } + void CSimulatorFsx::timerEvent(QTimerEvent *event) { Q_UNUSED(event); @@ -733,9 +742,8 @@ namespace BlackSimPlugin } // call in SIM - SimConnect_AIRemoveObject(m_hSimConnect, static_cast(simObject.getObjectId()), static_cast(m_requestId++)); + SimConnect_AIRemoveObject(m_hSimConnect, static_cast(simObject.getObjectId()), static_cast(m_requestIdSimData++)); m_hints.remove(simObject.getCallsign()); - m_lastPartsSendToSim.remove(simObject.getObjectId()); // mark in provider bool updated = updateAircraftRendered(callsign, false); @@ -825,7 +833,7 @@ namespace BlackSimPlugin } // facility - hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, static_cast(m_requestId++)); + hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, static_cast(m_requestIdSimData++)); if (hr != S_OK) { CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToFacilities failed"; @@ -863,7 +871,7 @@ namespace BlackSimPlugin void CSimulatorFsx::updateRemoteAircraft() { - static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size."); + static_assert(sizeof(DataDefinitionRemoteAircraftParts) == sizeof(double) * 10, "DataDefinitionRemoteAircraftParts has an incorrect size."); Q_ASSERT_X(this->m_interpolator, Q_FUNC_INFO, "missing interpolator"); Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread"); @@ -905,7 +913,6 @@ namespace BlackSimPlugin CInterpolationHints hints(m_hints[simObj.getCallsign()]); hints.setAircraftParts(useAircraftParts ? parts : CAircraftParts(), useAircraftParts); hints.setLoggingInterpolation(logInterpolationAndParts); - const CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, hints, interpolatorStatus); if (interpolatorStatus.allTrue()) @@ -930,7 +937,7 @@ namespace BlackSimPlugin else { // guess on position, but not every frame - if (m_interpolationRequest % 20 == 0) + if (m_interpolationRequest % GuessRemoteAircraftPartsCycle == 0) { this->guessAndUpdateRemoteAircraftParts(simObj, interpolatedSituation, interpolatorStatus); } @@ -950,44 +957,45 @@ namespace BlackSimPlugin DataDefinitionRemoteAircraftParts ddRemoteAircraftParts = {}; // init members const bool isOnGround = interpolatedSituation.isOnGround() == CAircraftSituation::OnGround; ddRemoteAircraftParts.gearHandlePosition = isOnGround ? 1 : 0; + CAircraftLights lights; // when first detected moving, lights on if (isOnGround) { - // ddRemoteAircraftParts.lightTaxi = 1; - ddRemoteAircraftParts.lightBeacon = 1; - ddRemoteAircraftParts.lightNav = 1; + lights.setTaxiOn(true); + lights.setBeaconOn(true); + lights.setNavOn(true); double gskmh = interpolatedSituation.getGroundSpeed().value(CSpeedUnit::km_h()); if (gskmh > 7.5) { // mode taxi - // ddRemoteAircraftParts.lightTaxi = 1; - ddRemoteAircraftParts.lightLanding = 0; + lights.setTaxiOn(true); + lights.setLandingOn(false); } - else if (gskmh > 25) + else if (gskmh > 40) { // mode accelaration for takeoff - // ddRemoteAircraftParts.lightTaxi = 0; - ddRemoteAircraftParts.lightLanding = 1; + lights.setTaxiOn(false); + lights.setLandingOn(true); } else { // slow movements or parking - // ddRemoteAircraftParts.lightTaxi = 0; - ddRemoteAircraftParts.lightLanding = 0; + lights.setTaxiOn(false); + lights.setLandingOn(false); } } else { - // ddRemoteAircraftParts.lightTaxi = 0; - ddRemoteAircraftParts.lightBeacon = 1; - ddRemoteAircraftParts.lightNav = 1; + lights.setTaxiOn(false); + lights.setBeaconOn(true); + lights.setNavOn(true); // landing lights for < 10000ft (normally MSL, here ignored) - ddRemoteAircraftParts.lightLanding = (interpolatedSituation.getAltitude().value(CLengthUnit::ft()) < 10000) ? 1 : 0; + lights.setLandingOn(interpolatedSituation.getAltitude().value(CLengthUnit::ft()) < 10000); } - return this->sendRemoteAircraftPartsToSim(simObj, ddRemoteAircraftParts); + return this->sendRemoteAircraftPartsToSimulator(simObj, ddRemoteAircraftParts, lights); } bool CSimulatorFsx::updateRemoteAircraftParts(const CSimConnectObject &simObj, const CAircraftParts &parts, const IInterpolator::PartsStatus &partsStatus) @@ -996,48 +1004,72 @@ namespace BlackSimPlugin if (!partsStatus.isSupportingParts()) { return false; } DataDefinitionRemoteAircraftParts ddRemoteAircraftParts; // no init, all values will be set - - ddRemoteAircraftParts.lightStrobe = parts.getLights().isStrobeOn() ? 1 : 0; - ddRemoteAircraftParts.lightLanding = parts.getLights().isLandingOn() ? 1 : 0; - // ddRemoteAircraftParts.lightTaxi = parts.getLights().isTaxiOn() ? 1 : 0; - ddRemoteAircraftParts.lightBeacon = parts.getLights().isBeaconOn() ? 1 : 0; - ddRemoteAircraftParts.lightNav = parts.getLights().isNavOn() ? 1 : 0; - ddRemoteAircraftParts.lightLogo = parts.getLights().isLogoOn() ? 1 : 0; ddRemoteAircraftParts.flapsLeadingEdgeLeftPercent = parts.getFlapsPercent() / 100.0; ddRemoteAircraftParts.flapsLeadingEdgeRightPercent = parts.getFlapsPercent() / 100.0; ddRemoteAircraftParts.flapsTrailingEdgeLeftPercent = parts.getFlapsPercent() / 100.0; ddRemoteAircraftParts.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0; ddRemoteAircraftParts.spoilersHandlePosition = parts.isSpoilersOut() ? 1 : 0; - ddRemoteAircraftParts.gearHandlePosition = parts.isGearDown() ? 1 : 0; // on ground we always show gear + ddRemoteAircraftParts.gearHandlePosition = parts.isGearDown() ? 1 : 0; ddRemoteAircraftParts.engine1Combustion = parts.isEngineOn(1) ? 1 : 0; ddRemoteAircraftParts.engine2Combustion = parts.isEngineOn(2) ? 1 : 0; ddRemoteAircraftParts.engine3Combustion = parts.isEngineOn(3) ? 1 : 0; ddRemoteAircraftParts.engine4Combustion = parts.isEngineOn(4) ? 1 : 0; - return this->sendRemoteAircraftPartsToSim(simObj, ddRemoteAircraftParts); + return this->sendRemoteAircraftPartsToSimulator(simObj, ddRemoteAircraftParts, parts.getLights()); } - bool CSimulatorFsx::sendRemoteAircraftPartsToSim(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts) + bool CSimulatorFsx::sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts, const CAircraftLights &lights) { Q_ASSERT(m_hSimConnect); const DWORD objectId = simObj.getObjectId(); - if (m_lastPartsSendToSim.contains(objectId)) - { - // no need to send same parts - if (m_lastPartsSendToSim[objectId] == ddRemoteAircraftParts) { return true; } - } + // same as in simulator or same as already send to simulator + const CAircraftLights sentLights(simObj.getLightsAsSent()); + if (simObj.getPartsAsSent() == ddRemoteAircraftParts && + (simObj.getCurrentLightsInSimulator() == lights || sentLights == lights)) { return true; } - m_lastPartsSendToSim[objectId] = ddRemoteAircraftParts; - HRESULT hr = SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, - objectId, 0, 0, - sizeof(DataDefinitionRemoteAircraftParts), &ddRemoteAircraftParts); + // in case we sent we sent everything + const HRESULT hr = SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, + objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, + sizeof(DataDefinitionRemoteAircraftParts), &ddRemoteAircraftParts); if (hr != S_OK) { CLogMessage(this).warning("Failed so set parts on SimObject '%1' callsign: '%2'") << simObj.getObjectId() << simObj.getCallsign(); } + + // lights we can set directly + SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventLandingLightsSet, lights.isLandingOn() ? 1.0 : 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventStrobesSet, lights.isStrobeOn() ? 1.0 : 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + + // lights we need to toggle (risk with quickly changing values that we accidentally toggle back) + // I sent 0/1 here, but the value is supposed to be irrelevant since "toggling" + if (!sentLights.isNull()) + { + if (sentLights.isTaxiOn() == lights.isTaxiOn()) + { + SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleTaxiLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + } + if (sentLights.isNavOn() == lights.isNavOn()) + { + SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleNavLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + } + if (sentLights.isBeaconOn() == lights.isBeaconOn()) + { + SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleBeaconLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + } + if (sentLights.isLogoOn() == lights.isLogoOn()) + { + SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleLogoLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); + } + } + + // Update data + CSimConnectObject &objUdpate = m_simConnectObjects[simObj.getCallsign()]; + objUdpate.setPartsAsSent(ddRemoteAircraftParts); + objUdpate.setLightsAsSent(lights); // pretend lights are set + + // done return hr == S_OK; } - SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxPosition(const CAircraftSituation &situation) { SIMCONNECT_DATA_INITPOSITION position; @@ -1114,7 +1146,7 @@ namespace BlackSimPlugin if (!simObject.hasValidRequestAndObjectId()) { return false; } if (simObject.getSimDataPeriod() == period) { return true; } // already queried like this - const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId(), CSimConnectDefinitions::DataRemoteAircraftSimData, simObject.getObjectId(), period, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED); + const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId() + RequestSimDataOffset, CSimConnectDefinitions::DataRemoteAircraftSimData, simObject.getObjectId(), period, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED); if (result == S_OK) { m_simConnectObjects[simObject.getCallsign()].setSimDataPeriod(period); @@ -1124,6 +1156,15 @@ namespace BlackSimPlugin return false; } + bool CSimulatorFsx::requestLightsForSimObject(const CSimConnectObject &simObject) + { + if (!simObject.hasValidRequestAndObjectId()) { return false; } + const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId() + RequestLightsOffset, CSimConnectDefinitions::DataRemoteAircraftLights, simObject.getObjectId(), SIMCONNECT_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED); + if (result == S_OK) { return true; } + CLogMessage(this).error("Cannot request data on object '%1'") << simObject.getObjectId(); + return false; + } + void CSimulatorFsx::initSimulatorInternals() { CSimulatorFsCommon::initSimulatorInternals(); @@ -1145,7 +1186,7 @@ namespace BlackSimPlugin m_syncDeferredCounter = 0; m_skipCockpitUpdateCycles = 0; m_interpolationRequest = 0; - m_requestId = FirstRequestId; + m_requestIdSimData = RequestSimDataStart; m_dispatchErrors = 0; m_receiveExceptionCount = 0; CSimulatorFsCommon::reset(); @@ -1155,7 +1196,6 @@ namespace BlackSimPlugin { m_simConnectObjects.clear(); m_outOfRealityBubble.clear(); - m_lastPartsSendToSim.clear(); CSimulatorFsCommon::clearAllAircraft(); } @@ -1191,7 +1231,7 @@ namespace BlackSimPlugin { constexpr int QueryInterval = 5 * 1000; // 5 seconds m_timer->setInterval(QueryInterval); - this->m_timer->setObjectName(this->objectName().append(":m_timer")); + m_timer->setObjectName(this->objectName().append(":m_timer")); connect(m_timer, &QTimer::timeout, this, &CSimulatorFsxListener::ps_checkConnection); } diff --git a/src/plugins/simulator/fsx/simulatorfsx.h b/src/plugins/simulator/fsx/simulatorfsx.h index 5c10f3125..66c416506 100644 --- a/src/plugins/simulator/fsx/simulatorfsx.h +++ b/src/plugins/simulator/fsx/simulatorfsx.h @@ -171,7 +171,7 @@ namespace BlackSimPlugin void onSimExit(); //! Get new request id, overflow safe - DWORD obtainRequestId(); + DWORD obtainRequestIdSimData(); //! Init when connected HRESULT initWhenConnected(); @@ -194,7 +194,7 @@ namespace BlackSimPlugin const BlackMisc::Aviation::CAircraftSituation &interpolatedSituation, const BlackMisc::Simulation::IInterpolator::InterpolationStatus &interpolationStatus); //! Send parts to sim - bool sendRemoteAircraftPartsToSim(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts); + bool sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts, const BlackMisc::Aviation::CAircraftLights &lights); //! Called when data about our own aircraft are received void updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft); @@ -214,6 +214,12 @@ namespace BlackSimPlugin //! 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(); @@ -229,32 +235,45 @@ namespace BlackSimPlugin //! 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; - 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 FirstRequestId = static_cast(CSimConnectDefinitions::RequestEndMarker); + //! 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(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_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_interpolationRequest = 0; //!< current interpolation request int m_dispatchErrors = 0; //!< number of dispatched failed, \sa ps_dispatch int m_receiveExceptionCount = 0; //!< exceptions - DWORD m_requestId = FirstRequestId; //!< request id, use obtainRequestId() to get id 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 - BlackMisc::Simulation::CSimulatedAircraftList m_outOfRealityBubble; //!< aircraft removed by FSX because they are out of reality bubble - QHash m_lastPartsSendToSim; //!< Last parts send to simulator, avoid always sending same parts + 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 diff --git a/src/plugins/simulator/fsx/simulatorfsxsimconnectproc.cpp b/src/plugins/simulator/fsx/simulatorfsxsimconnectproc.cpp index 1a0e572f3..d7d035a71 100644 --- a/src/plugins/simulator/fsx/simulatorfsxsimconnectproc.cpp +++ b/src/plugins/simulator/fsx/simulatorfsxsimconnectproc.cpp @@ -160,7 +160,9 @@ namespace BlackSimPlugin if (success) { const CSimConnectObject simObject = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId); - HRESULT result = simulatorFsx->requestDataForSimObject(simObject); + HRESULT result = S_OK; + result += simulatorFsx->requestDataForSimObject(simObject); + result += simulatorFsx->requestLightsForSimObject(simObject); Q_UNUSED(result); } else @@ -216,11 +218,12 @@ namespace BlackSimPlugin } default: { - static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size."); - const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().getSimObjectForRequestId(requestId); - if (simObj.hasValidRequestAndObjectId()) + const DWORD objectId = pObjData->dwObjectID; + if (isRequestForSimData(requestId)) { - const DWORD objectId = pObjData->dwObjectID; + 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()) @@ -228,6 +231,25 @@ namespace BlackSimPlugin simulatorFsx->updateRemoteAircraftFromSimulator(simObj, *remoteAircraftSimData); } } + else if (isRequestForLights(requestId)) + { + static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 6 * 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; @@ -287,7 +309,6 @@ namespace BlackSimPlugin } default: break; - } // main switch } // method } // namespace