refs #241 Move CFsuipc into simulator_fscommon

This commit is contained in:
Roland Winklmeier
2014-07-26 15:01:16 +02:00
parent 113f161bac
commit e49fa083a7
5 changed files with 19 additions and 6 deletions

View File

@@ -1,227 +0,0 @@
/* 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 NOMINMAX
#define NOMINMAX
#endif
#include "fsuipc.h"
#include <Windows.h>
// bug in FSUIPC_User.h, windows.h not included, so we have to import it first
#include "FSUIPC/FSUIPC_User.h"
#include "blacksim/fscommon/bcdconversions.h"
#include <QDebug>
#include <QLatin1Char>
#include <QDateTime>
using namespace BlackSim::FsCommon;
using namespace BlackMisc::Aviation;
using namespace BlackMisc::Network;
using namespace BlackMisc::Geo;
using namespace BlackMisc::PhysicalQuantities;
namespace BlackSimPlugin
{
namespace Fsx
{
CFsuipc::CFsuipc() : m_connected(false), m_validReadValues(false)
{ }
CFsuipc::~CFsuipc()
{
this->disconnect();
}
bool CFsuipc::connect()
{
DWORD result;
this->m_lastErrorMessage = "";
if (this->m_connected) return this->m_connected; // already connected
this->m_validReadValues = false;
if (FSUIPC_Open(SIM_ANY, &result))
{
this->m_connected = true;
int simIndex = static_cast<int>(FSUIPC_FS_Version);
QString sim(
(simIndex >= 0 && simIndex < CFsuipc::simulators().size()) ?
CFsuipc::simulators().at(simIndex) :
"Unknown FS");
QString ver("%1.%2.%3.%4%5");
ver = ver.arg(QLatin1Char(48 + (0x0f & (FSUIPC_Version >> 28))))
.arg(QLatin1Char(48 + (0x0f & (FSUIPC_Version >> 24))))
.arg(QLatin1Char(48 + (0x0f & (FSUIPC_Version >> 20))))
.arg(QLatin1Char(48 + (0x0f & (FSUIPC_Version >> 16))))
.arg((FSUIPC_Version & 0xffff) ? "a" + (FSUIPC_Version & 0xff) - 1 : "");
this->m_fsuipcVersion = QString("FSUIPC %1 (%2)").arg(ver).arg(sim);
// KB_REMOVE: Remove this later
qDebug() << "FSUIPC connected" << this->m_fsuipcVersion;
}
else
{
this->m_connected = false;
int index = static_cast<int>(result);
this->m_lastErrorMessage = CFsuipc::errorMessages().at(index);
// KB_REMOVE: Remove this later
qDebug() << "FSUIPC" << this->m_lastErrorMessage;
}
return this->m_connected;
}
void CFsuipc::disconnect()
{
FSUIPC_Close(); // Closing when it wasn't open is okay, so this is safe here
this->m_connected = false;
this->m_validReadValues = false;
}
void CFsuipc::process()
{
if (!this->m_connected) return;
this->read();
}
void CFsuipc::read()
{
DWORD dwResult;
char localFsTimeRaw[3];
char modelNameRaw[256];
qint16 com1ActiveRaw;
qint16 com2ActiveRaw;
qint16 com1StandbyRaw;
qint16 com2StandbyRaw;
qint16 transponderCodeRaw;
qint8 xpdrModeSb3Raw;
qint8 xpdrIdentSb3Raw;
qint32 groundspeedRaw;
qint32 pitchRaw;
qint32 bankRaw;
qint32 headingRaw;
qint64 altitudeRaw;
qint32 groundAltitudeRaw;
qint64 latitudeRaw;
qint64 longitudeRaw;
// http://www.projectmagenta.com/all-fsuipc-offsets/
// https://www.ivao.aero/softdev/ivap/fsuipc_sdk.asp
// http://squawkbox.ca/doc/sdk/fsuipc.php
if (FSUIPC_Read(0x0238, 3, localFsTimeRaw, &dwResult) &&
// COM settings
FSUIPC_Read(0x034e, 2, &com1ActiveRaw, &dwResult) &&
FSUIPC_Read(0x3118, 2, &com2ActiveRaw, &dwResult) &&
FSUIPC_Read(0x311a, 2, &com1StandbyRaw, &dwResult) &&
FSUIPC_Read(0x311c, 2, &com2StandbyRaw, &dwResult) &&
FSUIPC_Read(0x0354, 2, &transponderCodeRaw, &dwResult) &&
// COM Settings, transponder, SB3
FSUIPC_Read(0x7b91, 1, &xpdrModeSb3Raw, &dwResult) &&
FSUIPC_Read(0x7b92, 1, &xpdrIdentSb3Raw, &dwResult) &&
// Speeds, situation
FSUIPC_Read(0x02b4, 4, &groundspeedRaw, &dwResult) &&
FSUIPC_Read(0x0578, 4, &pitchRaw, &dwResult) &&
FSUIPC_Read(0x057c, 4, &bankRaw, &dwResult) &&
FSUIPC_Read(0x0580, 4, &headingRaw, &dwResult) &&
FSUIPC_Read(0x0570, 8, &altitudeRaw, &dwResult) &&
// Position
FSUIPC_Read(0x0560, 8, &latitudeRaw, &dwResult) &&
FSUIPC_Read(0x0568, 8, &longitudeRaw, &dwResult) &&
FSUIPC_Read(0x0020, 4, &groundAltitudeRaw, &dwResult) &&
// model name
FSUIPC_Read(0x3d00, 256, &modelNameRaw, &dwResult) &&
// If we wanted other reads/writes at the same time, we could put them here
FSUIPC_Process(&dwResult))
{
this->m_validReadValues = true;
// time, basically as a heartbeat
QString fsTime;
fsTime.sprintf("%02d:%02d:%02d", localFsTimeRaw[0], localFsTimeRaw[1], localFsTimeRaw[2]);
// model
const QString modelName = QString(modelNameRaw); // to be used to distinguish offsets for different models
m_model.setModelString(modelName);
// COMs
CComSystem com1 = this->m_aircraft.getCom1System();
CComSystem com2 = this->m_aircraft.getCom2System();
CTransponder xpdr = this->m_aircraft.getTransponder();
// 2710 => 12710 => / 100.0 => 127.1
com1ActiveRaw = (10000 + CBcdConversions::bcd2Dec(com1ActiveRaw));
com2ActiveRaw = (10000 + CBcdConversions::bcd2Dec(com2ActiveRaw));
com1StandbyRaw = (10000 + CBcdConversions::bcd2Dec(com1StandbyRaw));
com2StandbyRaw = (10000 + CBcdConversions::bcd2Dec(com2StandbyRaw));
com1.setFrequencyActiveMHz(com1ActiveRaw / 100.0);
com2.setFrequencyActiveMHz(com2ActiveRaw / 100.0);
com1.setFrequencyStandbyMHz(com1StandbyRaw / 100.0);
com2.setFrequencyStandbyMHz(com2StandbyRaw / 100.0);
transponderCodeRaw = CBcdConversions::bcd2Dec(transponderCodeRaw);
xpdr.setTransponderCode(transponderCodeRaw);
// Mode by SB3
if (xpdrIdentSb3Raw > 0)
{
// TODO: Reset value
xpdr.setTransponderMode(CTransponder::StateIdent);
}
else
{
xpdr.setTransponderMode(
xpdrModeSb3Raw == 0 ? CTransponder::ModeC : CTransponder::StateStandby
);
}
this->m_aircraft.setCockpit(com1, com2, xpdr);
// position
const double latCorrectionFactor = 90.0 / (10001750.0 * 65536.0 * 65536.0);
const double lonCorrectionFactor = 360.0 / (65536.0 * 65536.0 * 65536.0 * 65536.0);
CAircraftSituation situation = this->m_aircraft.getSituation();
CCoordinateGeodetic position = situation.getPosition();
CLatitude lat(latitudeRaw * latCorrectionFactor, CAngleUnit::deg());
CLongitude lon(longitudeRaw * lonCorrectionFactor, CAngleUnit::deg());
CLength groundAltitude(groundAltitudeRaw / 256.0, CLengthUnit::m());
position.setLatitude(lat);
position.setLongitude(lon);
position.setGeodeticHeight(groundAltitude);
situation.setPosition(position);
// speeds, situation
const double angleCorrectionFactor = 360.0 / 65536.0 / 65536.0; // see FSUIPC docu
CAngle pitch = CAngle(pitchRaw * angleCorrectionFactor, CAngleUnit::deg());
CAngle bank = CAngle(bankRaw * angleCorrectionFactor, CAngleUnit::deg());
CHeading heading = CHeading(headingRaw * angleCorrectionFactor, CHeading::True, CAngleUnit::deg());
CSpeed groundspeed(groundspeedRaw / 65536.0, CSpeedUnit::m_s());
CAltitude altitude(altitudeRaw / (65536.0 * 65536.0), CAltitude::MeanSeaLevel, CLengthUnit::m());
situation.setBank(bank);
situation.setHeading(heading);
situation.setPitch(pitch);
situation.setGroundspeed(groundspeed);
situation.setAltitude(altitude);
this->m_aircraft.setSituation(situation);
// qDebug() << m_aircraft;
}
else
{
this->m_validReadValues = false;
}
}
double CFsuipc::intToFractional(double fractional)
{
double f = fractional / 10.0;
if (f < 1.0) return f;
return intToFractional(f);
}
}
}

View File

@@ -1,98 +0,0 @@
/* 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_FSUIPC_H
#define BLACKSIMPLUGIN_FSUIPC_H
#include "blackmisc/avaircraft.h"
#include "blackmisc/nwaircraftmodel.h"
#include <QStringList>
namespace BlackSimPlugin
{
namespace Fsx
{
//! Class representing a FSUIPC "interface"
class CFsuipc
{
public:
//! Constructor
CFsuipc();
//! Destructor
~CFsuipc();
//! Open conenction with FSUIPC
bool connect();
//! Disconnect
void disconnect();
//! Is connected?
bool isConnected() const { return m_connected; }
//! Valid read values
bool validReadValues() const { return m_validReadValues; }
//! Process reading and writing variables
void process();
//! Error messages
static const QStringList &errorMessages()
{
static const QStringList errors(
{
"Okay",
"Attempt to Open when already Open",
"Cannot link to FSUIPC or WideClient",
"Failed to Register common message with Windows",
"Failed to create Atom for mapping filename",
"Failed to create a file mapping object",
"Failed to open a view to the file map",
"Incorrect version of FSUIPC, or not FSUIPC",
"Sim is not version requested",
"Call cannot execute, link not Open",
"Call cannot execute: no requests accumulated",
"IPC timed out all retries",
"IPC sendmessage failed all retries",
"IPC request contains bad data",
"Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC",
"Read or Write request cannot be added, memory for Process is full",
}
);
return errors;
}
//! Simulators
static const QStringList &simulators()
{
static const QStringList sims(
{
"any", "FS98", "FS2000", "CFS2", "CFS1", "Fly!", "FS2002", "FS2004", "FSX", "ESP", "P3D"
}
);
return sims;
}
private:
bool m_connected;
bool m_validReadValues;
QString m_lastErrorMessage;
QString m_fsuipcVersion;
BlackMisc::Aviation::CAircraft m_aircraft; //!< FSUIPC read aircraft
BlackMisc::Network::CAircraftModel m_model; //!< FSUIPC read model
//! Read data from FSUIPC
void read();
//! Integer representing fractional
static double intToFractional(double fractional);
};
}
}
#endif // guard

View File

@@ -9,7 +9,7 @@ TEMPLATE = lib
CONFIG += plugin shared
CONFIG += blackmisc blackcore blacksim
LIBS += -lSimConnect -lFSUIPC_User
LIBS += -lsimulator_fscommon -lSimConnect -lFSUIPC_User
# required for FSUIPC
win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib
@@ -17,6 +17,8 @@ win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib
DEPENDPATH += . ../../../../src
INCLUDEPATH += . ../../../../src
LIBS += -ldxguid -lole32
SOURCES += *.cpp
HEADERS += *.h

View File

@@ -48,7 +48,7 @@ namespace BlackSimPlugin
m_simulatorInfo(CSimulatorInfo::FSX()),
m_simconnectTimerId(-1),
m_skipCockpitUpdateCycles(0),
m_fsuipc(new CFsuipc())
m_fsuipc(new FsCommon::CFsuipc())
{
CFsxSimulatorSetup setup;
setup.init(); // this fetches important settings on local side

View File

@@ -8,7 +8,7 @@
#include "simconnect_datadefinition.h"
#include "simconnect_object.h"
#include "fsuipc.h"
#include "../fscommon/fsuipc.h"
#include "blackcore/simulator.h"
#include "blackcore/interpolator_linear.h"
#include "blackmisc/avaircraft.h"
@@ -218,7 +218,7 @@ namespace BlackSimPlugin
int m_simconnectTimerId;
int m_skipCockpitUpdateCycles; //!< Skip some update cycles to allow changes in simulator cockpit to be set
QFutureWatcher<bool> m_watcherConnect;
QScopedPointer<CFsuipc> m_fsuipc;
QScopedPointer<FsCommon::CFsuipc> m_fsuipc;
};
}