From 0d52c4ca47fe2e234273026c80376531811d8eac Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Wed, 27 May 2020 15:33:04 +0100 Subject: [PATCH] Issue #17 Using xplanemp2 --- src/xswiftbus/main.cpp | 2 - src/xswiftbus/traffic.cpp | 215 ++++++++++-------------------------- src/xswiftbus/traffic.h | 29 +---- src/xswiftbus/utils.cpp | 55 ++++++++- src/xswiftbus/xswiftbus.pro | 17 ++- 5 files changed, 131 insertions(+), 187 deletions(-) diff --git a/src/xswiftbus/main.cpp b/src/xswiftbus/main.cpp index 26243007d..ae51d42a3 100644 --- a/src/xswiftbus/main.cpp +++ b/src/xswiftbus/main.cpp @@ -33,8 +33,6 @@ PLUGIN_API int XPluginStart(char *o_name, char *o_sig, char *o_desc) std::strcpy(o_name, "XSwiftBus"); std::strcpy(o_sig, "org.swift-project.xswiftbus"); std::strcpy(o_desc, "Allows swift to connect to X-Plane via D-Bus IPC"); - - XSwiftBus::CTraffic::initLegacyData(); return 1; } diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index 7da75f41c..f6f741a32 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -15,7 +15,6 @@ #include "traffic.h" #include "utils.h" #include "XPMPMultiplayer.h" -#include "XPMPPlaneRenderer.h" #include #include #include @@ -38,13 +37,16 @@ namespace XSwiftBus CTraffic::Plane::Plane(void *id_, const std::string &callsign_, const std::string &aircraftIcao_, const std::string &airlineIcao_, const std::string &livery_, const std::string &modelName_) : id(id_), callsign(callsign_), aircraftIcao(aircraftIcao_), airlineIcao(airlineIcao_), livery(livery_), modelName(modelName_) { + std::memset(static_cast(&position), 0, sizeof(position)); + position.size = sizeof(position); + std::memset(static_cast(&surveillance), 0, sizeof(surveillance)); + surveillance.size = sizeof(surveillance); std::memset(static_cast(&surfaces), 0, sizeof(surfaces)); + surfaces.size = sizeof(surfaces); surfaces.lights.bcnLights = surfaces.lights.landLights = surfaces.lights.navLights = surfaces.lights.strbLights = 1; - surfaces.size = sizeof(surfaces); - xpdr.size = sizeof(xpdr); - std::strncpy(label, callsign.c_str(), sizeof(label)); + std::srand(static_cast(std::time(nullptr))); surfaces.lights.timeOffset = static_cast(std::rand() % 0xffff); } @@ -59,49 +61,34 @@ namespace XSwiftBus { assert(!s_instance); s_instance = this; - XPLMRegisterDrawCallback(drawCallback, xplm_Phase_Airplanes, 1, this); XPLMRegisterKeySniffer(followAircraftKeySniffer, 1, this); } // *INDENT-ON* CTraffic::~CTraffic() { - XPLMUnregisterDrawCallback(drawCallback, xplm_Phase_Airplanes, 1, this); cleanup(); assert(s_instance == this); s_instance = nullptr; } - static bool s_legacyDataOK = true; - void CTraffic::setPlaneViewMenu(const CMenu &planeViewSubMenu) { m_followPlaneViewSubMenu = planeViewSubMenu; } - void CTraffic::initLegacyData() - { - initXPlanePath(); - auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep; - - std::string csl = dir + "CSL"; - std::string related = dir + "related.txt"; - std::string doc8643 = dir + "Doc8643.txt"; - std::string lights = dir + "lights.png"; - - auto err = XPMPMultiplayerInitLegacyData(csl.c_str(), related.c_str(), lights.c_str(), doc8643.c_str(), - "C172", preferences, preferences); - if (*err) { s_legacyDataOK = false; } - } - bool CTraffic::initialize() { - if (! s_legacyDataOK) { return false; } - if (! m_initialized) { - auto err = XPMPMultiplayerInit(preferences, preferences); - if (*err) { cleanup(); } + initXPlanePath(); + auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep; + std::string related = dir + "related.txt"; + std::string doc8643 = dir + "Doc8643.txt"; + + updateConfiguration(); + auto err = XPMPMultiplayerInit(&m_configuration, related.c_str(), doc8643.c_str()); + if (err && *err) { cleanup(); } else { m_initialized = true; } } @@ -120,7 +107,6 @@ namespace XSwiftBus else { m_enabledMultiplayer = true; - XPMPLoadPlanesIfNecessary(); } } @@ -234,50 +220,18 @@ namespace XSwiftBus // static int g_maxPlanes = 100; // static float g_drawDistance = 50.0f; - int CTraffic::preferences(const char *section, const char *name, int def) + void CTraffic::updateConfiguration() { - if (!s_instance) { return def; } - - if (strcmp(section, "planes") == 0 && strcmp(name, "max_full_count") == 0) - { - return s_instance->getSettings().getMaxPlanes(); // preferences - } - else if (strcmp(section, "debug") == 0 && strcmp(name, "allow_obj8_async_load") == 0) - { - // the setting allow_obj8_async_load (in the debug section) controls - // whether or not async loading is enabled: 1 means enabled, 0 means disabled - return 1; - } - else if (strcmp(section, "debug") == 0 && strcmp(name, "render_phases") == 0) - { - return s_instance->getConfig().getDebugMode() ? 1 : 0; - } - else if (strcmp(section, "debug") == 0 && strcmp(name, "tcas_traffic") == 0) - { - return s_instance->getConfig().getTcasEnabled() ? 1 : 0; - } - return def; - } - - float CTraffic::preferences(const char *section, const char *name, float def) - { - if (!s_instance) { return def; } - - if (strcmp(section, "planes") == 0 && strcmp(name, "full_distance") == 0) - { - return static_cast(s_instance->getSettings().getMaxDrawDistanceNM()); // preferences - } - return def; + m_configuration.maxFullAircraftRenderingDistance = static_cast(s_instance->getSettings().getMaxDrawDistanceNM()); + m_configuration.enableSurfaceClamping = true; + m_configuration.debug.modelMatching = false; } std::string CTraffic::loadPlanesPackage(const std::string &path) { initXPlanePath(); - auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep; - std::string related = dir + "related.txt"; - std::string doc8643 = dir + "Doc8643.txt"; - auto err = XPMPLoadCSLPackage(path.c_str(), related.c_str(), doc8643.c_str()); + auto err = XPMPMultiplayerLoadCSLPackages(path.c_str()); if (*err) { return err; } return {}; } @@ -307,12 +261,11 @@ namespace XSwiftBus XPMPPlaneID id = nullptr; if (modelName.empty()) { - id = XPMPCreatePlane(aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str(), getPlaneData, planeLoaded, static_cast(this)); + id = XPMPCreatePlane(aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str()); } else { - const std::string nt = this->getSettings().getNightTextureMode(); - id = XPMPCreatePlaneWithModelName(modelName.c_str(), aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str(), nt.c_str(), getPlaneData, planeLoaded, static_cast(this)); + id = XPMPCreatePlaneWithModelName(modelName.c_str(), aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str()); } if (!id) @@ -329,6 +282,8 @@ namespace XSwiftBus CMenuItem planeViewMenuItem = m_followPlaneViewSubMenu.item(callsign, [this, callsign] { switchToFollowPlaneView(callsign); }); m_followPlaneViewMenuItems[callsign] = planeViewMenuItem; m_followPlaneViewSequence.push_back(callsign); + + emitPlaneAdded(callsign); } void CTraffic::removePlane(const std::string &callsign) @@ -392,6 +347,8 @@ namespace XSwiftBus plane->position.pitch = static_cast(pitchesDeg.at(i)); plane->position.roll = static_cast(rollsDeg.at(i)); plane->position.heading = static_cast(headingsDeg.at(i)); + plane->position.offsetScale = 1.0f; + plane->position.clampToGround = true; if (setOnGround) { plane->isOnGround = onGrounds.at(i); } } @@ -452,11 +409,10 @@ namespace XSwiftBus Plane *plane = planeIt->second; if (!plane) { continue; } - plane->hasXpdr = true; - plane->xpdr.code = codes.at(i); - if (idents.at(i)) { plane->xpdr.mode = xpmpTransponderMode_ModeC_Ident; } - else if (modeCs.at(i)) { plane->xpdr.mode = xpmpTransponderMode_ModeC; } - else { plane->xpdr.mode = xpmpTransponderMode_Standby; } + plane->surveillance.code = codes.at(i); + if (idents.at(i)) { plane->surveillance.mode = xpmpTransponderMode_ModeC_Ident; } + else if (modeCs.at(i)) { plane->surveillance.mode = xpmpTransponderMode_ModeC; } + else { plane->surveillance.mode = xpmpTransponderMode_Standby; } } } @@ -491,15 +447,13 @@ namespace XSwiftBus groundElevation = plane->terrainProbe.getElevation(latDeg, lonDeg, plane->position.elevation, requestedCallsign, isWater).front(); if (std::isnan(groundElevation)) { groundElevation = 0.0; } } - double fudgeFactor = 3.0; - bool hasOffset = XPMPGetVerticalOffset(plane->id, &fudgeFactor); callsigns.push_back(requestedCallsign); latitudesDeg.push_back(latDeg); longitudesDeg.push_back(lonDeg); elevationsM.push_back(groundElevation); waterFlags.push_back(isWater); - verticalOffsets.push_back(hasOffset ? fudgeFactor : std::numeric_limits::quiet_NaN()); + verticalOffsets.push_back(0); // xpmp2 adjusts the offset for us, so effectively always zero } } @@ -830,6 +784,9 @@ namespace XSwiftBus int CTraffic::process() { invokeQueuedDBusCalls(); + doPlaneUpdates(); + emitSimFrame(); + m_countFrame++; return 1; } @@ -842,73 +799,34 @@ namespace XSwiftBus sizeof(*dst) - sizeof(dst->size)); } - int CTraffic::getPlaneData(void *id, int dataType, void *io_data) + void CTraffic::doPlaneUpdates() { - const auto planeIt = m_planesById.find(id); - // assert(planeIt != m_planesById.end()); - if (planeIt == m_planesById.end()) { return xpmpData_Unavailable; } // less drastic version - Plane *plane = planeIt->second; - if (!plane) { return xpmpData_Unavailable; } - - switch (dataType) + m_updates.clear(); + for (const auto pair : m_planesById) { - case xpmpDataType_Position: - { - const auto io_position = static_cast(io_data); - io_position->lat = plane->position.lat; - io_position->lon = plane->position.lon; - io_position->elevation = plane->position.elevation; - io_position->pitch = plane->position.pitch; - io_position->roll = plane->position.roll; - io_position->heading = plane->position.heading; - std::strncpy(io_position->label, plane->label, sizeof(plane->label)); // fixme don't need to copy on every frame - return xpmpData_NewData; - } - - case xpmpDataType_Surfaces: - if (plane->hasSurfaces) - { - const auto now = std::chrono::system_clock::now(); - - static const float epsilon = std::numeric_limits::epsilon(); - const float f = plane->surfaces.gearPosition - plane->targetGearPosition; - if (std::abs(f) > epsilon) - { - // interpolate gear position - constexpr float gearMoveTimeMs = 5000; - const auto gearPositionDiffRemaining = plane->targetGearPosition - plane->surfaces.gearPosition; - - const auto diffMs = std::chrono::duration_cast(now - plane->prevSurfacesLerpTime); - const auto gearPositionDiffThisFrame = (diffMs.count()) / gearMoveTimeMs; - plane->surfaces.gearPosition += std::copysign(gearPositionDiffThisFrame, gearPositionDiffRemaining); - plane->surfaces.gearPosition = std::max(0.0f, std::min(plane->surfaces.gearPosition, 1.0f)); - } - plane->prevSurfacesLerpTime = now; - const auto io_surfaces = static_cast(io_data); - - if (memcmpPayload(io_surfaces, &plane->surfaces)) - { - std::memcpy(io_surfaces, &plane->surfaces, sizeof(*io_surfaces)); - return xpmpData_NewData; - } - else { return xpmpData_Unchanged; } - } - break; - - case xpmpDataType_Radar: - if (plane->hasXpdr) - { - const auto io_xpdr = static_cast(io_data); - - if (memcmpPayload(io_xpdr, &plane->xpdr)) - { - std::memcpy(io_xpdr, &plane->xpdr, sizeof(*io_xpdr)); - return xpmpData_NewData; - } - else { return xpmpData_Unchanged; } - } + Plane *plane = pair.second; + interpolateGear(plane); + m_updates.push_back({ plane->id, &plane->position, &plane->surfaces, &plane->surveillance }); } - return xpmpData_Unavailable; + XPMPUpdatePlanes(m_updates.data(), sizeof(XPMPUpdate_t), m_updates.size()); + } + + void CTraffic::interpolateGear(Plane* plane) + { + const auto now = std::chrono::system_clock::now(); + static const float epsilon = std::numeric_limits::epsilon(); + const float f = plane->surfaces.gearPosition - plane->targetGearPosition; + if (std::abs(f) > epsilon) + { + constexpr float gearMoveTimeMs = 5000; + const auto gearPositionDiffRemaining = plane->targetGearPosition - plane->surfaces.gearPosition; + + const auto diffMs = std::chrono::duration_cast(now - plane->prevSurfacesLerpTime); + const auto gearPositionDiffThisFrame = (diffMs.count()) / gearMoveTimeMs; + plane->surfaces.gearPosition += std::copysign(gearPositionDiffThisFrame, gearPositionDiffRemaining); + plane->surfaces.gearPosition = std::max(0.0f, std::min(plane->surfaces.gearPosition, 1.0f)); + } + plane->prevSurfacesLerpTime = now; } int CTraffic::orbitPlaneFunc(XPLMCameraPosition_t *cameraPosition, int isLosingControl, void *refcon) @@ -1082,23 +1000,6 @@ namespace XSwiftBus return 1; } - int CTraffic::drawCallback(XPLMDrawingPhase phase, int isBefore, void *refcon) - { - (void)phase; - (void)isBefore; - CTraffic *traffic = static_cast(refcon); - - // The draw callback is called several times per frame. We need this only once. - if (traffic->m_worldRenderType.get() == 0) - { - traffic->emitSimFrame(); - } - - traffic->m_countFrame++; - - return 1; - } - int CTraffic::followAircraftKeySniffer(char character, XPLMKeyFlags flags, char virtualKey, void *refcon) { (void) character; diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index ee81bfc30..afbacff61 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -59,9 +59,6 @@ namespace XSwiftBus //! Set plane view submenu void setPlaneViewMenu(const CMenu &planeViewSubMenu); - //! Called by XPluginStart - static void initLegacyData(); - //! Initialize the multiplayer planes rendering and return true if successful bool initialize(); @@ -155,11 +152,10 @@ namespace XSwiftBus bool containsCallsign(const std::string &callsign) const; static CTraffic *s_instance; - static int preferences(const char *section, const char *name, int def); - static float preferences(const char *section, const char *name, float def); + XPMPConfiguration_t m_configuration = {}; + void updateConfiguration(); static int orbitPlaneFunc(XPLMCameraPosition_t *cameraPosition, int isLosingControl, void *refcon); - static int drawCallback(XPLMDrawingPhase phase, int isBefore, void *refcon); static int followAircraftKeySniffer(char character, XPLMKeyFlags flags, char virtualKey, void *refcon); //! Remote aircraft @@ -173,15 +169,14 @@ namespace XSwiftBus std::string modelName; std::string nightTextureMode; bool hasSurfaces = false; - bool hasXpdr = false; bool isOnGround = false; char label[32] {}; CTerrainProbe terrainProbe; XPMPPlaneSurfaces_t surfaces; float targetGearPosition = 0; std::chrono::system_clock::time_point prevSurfacesLerpTime; - XPMPPlaneRadar_t xpdr; XPMPPlanePosition_t position; + XPMPPlaneSurveillance_t surveillance; Plane(void *id_, const std::string &callsign_, const std::string &aircraftIcao_, const std::string &airlineIcao_, const std::string &livery_, const std::string &modelName_); }; @@ -237,21 +232,9 @@ namespace XSwiftBus bool m_emitSimFrame = true; int m_countFrame = 0; //!< allows to do something every n-th frame - int getPlaneData(void *id, int dataType, void *io_data); - static int getPlaneData(void *id, int dataType, void *io_data, void *self) - { - return static_cast(self)->getPlaneData(id, dataType, io_data); - } - - static void planeLoaded(void *id, bool succeeded, void *self) - { - auto *traffic = static_cast(self); - auto planeIt = traffic->m_planesById.find(id); - if (planeIt == traffic->m_planesById.end()) { return; } - - if (succeeded) { traffic->emitPlaneAdded(planeIt->second->callsign); } - else { traffic->emitPlaneAddingFailed(planeIt->second->callsign); } - } + std::vector m_updates; + void doPlaneUpdates(); + void interpolateGear(Plane *); }; } // ns diff --git a/src/xswiftbus/utils.cpp b/src/xswiftbus/utils.cpp index 79a38fb45..1c544005d 100644 --- a/src/xswiftbus/utils.cpp +++ b/src/xswiftbus/utils.cpp @@ -14,17 +14,25 @@ #include "utils.h" #include -#include #include #include #include #include +#include + +#ifdef APL +#include +#endif namespace XSwiftBus { std::string g_xplanePath; std::string g_sep; +#ifdef APL + int HFS2PosixPath(const char *path, char *result, int resultLen); +#endif + //! Init global xplane path void initXPlanePath() { @@ -52,7 +60,7 @@ namespace XSwiftBus assert(!filePath.empty()); std::ostringstream ss; - ss << XPMPTimestamp() << "xswiftbus: "; + ss << "xswiftbus: "; #if defined(XSWIFTBUS_ENABLE_TRACE_LOG) switch (type) @@ -86,7 +94,7 @@ namespace XSwiftBus ss << line; ss << " : "; -#endif +#endif //XSWIFTBUS_ENABLE_TRACE_LOG ss << message; ss << "\n"; @@ -94,6 +102,47 @@ namespace XSwiftBus const std::string buffer = ss.str(); XPLMDebugString(buffer.c_str()); } + +#ifdef APL + template + struct CFSmartPtr + { + CFSmartPtr(T p) : p_(p) {} + ~CFSmartPtr() { if (p_) CFRelease(p_); } + operator T () { return p_; } + T p_; + }; + + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + #endif + + int HFS2PosixPath(const char *path, char *result, int resultLen) + { + bool is_dir = (path[strlen(path)-1] == ':'); + + CFSmartPtr inStr(CFStringCreateWithCString(kCFAllocatorDefault, path ,kCFStringEncodingMacRoman)); + if (inStr == nullptr) return -1; + + CFSmartPtr url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, inStr, kCFURLHFSPathStyle,0)); + if (url == nullptr) return -1; + + CFSmartPtr outStr(CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle)); + if (outStr == nullptr) return -1; + + if (!CFStringGetCString(outStr, result, resultLen, kCFStringEncodingMacRoman)) + return -1; + + if(is_dir) strcat(result, "/"); + + return 0; + } + + #ifdef __clang__ + #pragma clang diagnostic pop + #endif +#endif //APL } //! \endcond diff --git a/src/xswiftbus/xswiftbus.pro b/src/xswiftbus/xswiftbus.pro index e715b5182..30a1c4ea5 100644 --- a/src/xswiftbus/xswiftbus.pro +++ b/src/xswiftbus/xswiftbus.pro @@ -37,8 +37,16 @@ HEADERS += $$files($$PWD/*.h) # Using the $$files function so we can remove some with -= below SOURCES += $$files(xplanemp2/src/*.cpp) -HEADERS += $$files(xplanemp2/src/*.h) $$files(xplanemp2/include/*.h) -INCLUDEPATH += ./xplanemp2 ./xplanemp2/include ./xplanemp2/src +SOURCES += $$files(xplanemp2/src/*.c) +HEADERS += $$files(xplanemp2/src/*.h) + +SOURCES += $$files(xplanemp2/src/obj8/*.cpp) +HEADERS += $$files(xplanemp2/src/obj8/*.h) + +HEADERS += $$files(xplanemp2/include/*.h) +INCLUDEPATH += ./xplanemp2 ./xplanemp2/include ./xplanemp2/src ./xplanemp2/obj8 + +!macx: SOURCES -= xplanemp2/src/AplFSUtil.cpp unix:!macx { INCLUDEPATH *= /usr/include/dbus-1.0 @@ -64,6 +72,10 @@ else: LIBS += -lpng -lz msvc: DEFINES += _CRT_SECURE_NO_WARNINGS +!swiftConfig(allowNoisyWarnings) { + gcc|llvm:QMAKE_CXXFLAGS_WARN_ON *= -Wno-missing-field-initializers +} + # Required by X-Plane SDK and xplanemp2 win32:DEFINES += IBM=1 linux:DEFINES += LIN=1 @@ -71,6 +83,7 @@ macx:DEFINES += APL=1 DEFINES += XPLM200=1 DEFINES += XPLM210=1 DEFINES += XPLM300=1 +DEFINES += XPLM_DEPRECATED=1 # Name will be used in xplanemp2 log messages DEFINES += XPMP_CLIENT_NAME=\\\"xswiftbus\\\"