Files
XPlaneConnectCSP/xpcPlugin/DataManager.cpp

551 lines
20 KiB
C++

//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
//National Aeronautics and Space Administration. All Rights Reserved.
//
//X-Plane API
//Copyright(c) 2008, Sandy Barbour and Ben Supnik All rights reserved.
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
//associated documentation files(the "Software"), to deal in the Software without restriction,
//including without limitation the rights to use, copy, modify, merge, publish, distribute,
//sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions :
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Neither the names of the authors nor that of X - Plane or Laminar Research
// may be used to endorse or promote products derived from this software
// without specific prior written permission from the authors or
// Laminar Research, respectively.
#include "DataManager.h"
#include "Log.h"
#include "XPLMDataAccess.h"
#include "XPLMGraphics.h"
#include <cmath>
#include <unordered_map>
namespace XPC
{
static std::unordered_map<DREF, XPLMDataRef> drefs;
static std::unordered_map<DREF, XPLMDataRef> mdrefs[20];
static std::unordered_map<std::string, XPLMDataRef> sdrefs;
void DataManager::Initialize()
{
drefs = std::unordered_map<DREF, XPLMDataRef>(
{
{ DREF::None, XPLMFindDataRef("sim/test/test_float") },
{ DREF::Pause, XPLMFindDataRef("sim/operation/override/override_planepath") },
{ DREF::PauseAI, XPLMFindDataRef("sim/operation/override/override_plane_ai_autopilot") },
{ DREF::TotalRuntime, XPLMFindDataRef("sim/time/total_running_time_sec") },
{ DREF::TotalFlighttime, XPLMFindDataRef("sim/time/total_flight_time_sec") },
{ DREF::TimerElapsedtime, XPLMFindDataRef("sim/time/timer_elapsed_time_sec") },
{ DREF::IndicatedAirspeed, XPLMFindDataRef("sim/flightmodel/position/indicated_airspeed") },
{ DREF::TrueAirspeed, XPLMFindDataRef("sim/flightmodel/position/true_airspeed") },
{ DREF::GroundSpeed, XPLMFindDataRef("sim/flightmodel/position/groundspeed") },
{ DREF::MachNumber, XPLMFindDataRef("sim/flightmodel/misc/machno") },
{ DREF::GForceNormal, XPLMFindDataRef("sim/flightmodel2/misc/gforce_normal") },
{ DREF::GForceAxial, XPLMFindDataRef("sim/flightmodel2/misc/gforce_axial") },
{ DREF::GForceSide, XPLMFindDataRef("sim/flightmodel2/misc/gforce_side") },
{ DREF::BarometerSealevelInHg, XPLMFindDataRef("sim/weather/barometer_sealevel_inhg") },
{ DREF::TemperaturSealevelC, XPLMFindDataRef("sim/weather/temperature_sealevel_c") },
{ DREF::WindSpeedKts, XPLMFindDataRef("sim/cockpit2/gauges/indicators/wind_speed_kts") },
{ DREF::YokePitch, XPLMFindDataRef("sim/joystick/yoke_pitch_ratio") },
{ DREF::YokeRoll, XPLMFindDataRef("sim/joystick/yoke_roll_ratio") },
{ DREF::YokeHeading, XPLMFindDataRef("sim/joystick/yoke_heading_ratio") },
{ DREF::Elevator, XPLMFindDataRef("sim/cockpit2/controls/yoke_pitch_ratio") },
{ DREF::Aileron, XPLMFindDataRef("sim/cockpit2/controls/yoke_roll_ratio") },
{ DREF::Rudder, XPLMFindDataRef("sim/cockpit2/controls/yoke_heading_ratio") },
{ DREF::FlapSetting, XPLMFindDataRef("sim/flightmodel/controls/flaprqst") },
{ DREF::FlapActual, XPLMFindDataRef("sim/flightmodel/controls/flaprat") },
{ DREF::GearDeploy, XPLMFindDataRef("sim/aircraft/parts/acf_gear_deploy") },
{ DREF::GearHandle, XPLMFindDataRef("sim/cockpit/switches/gear_handle_status") },
{ DREF::BrakeParking, XPLMFindDataRef("sim/flightmodel/controls/parkbrakel") },
{ DREF::BrakeLeft, XPLMFindDataRef("sim/cockpit2/controls/left_brake_ratio") },
{ DREF::BrakeRight, XPLMFindDataRef("sim/cockpit2/controls/right_brake_ratio") },
{ DREF::M, XPLMFindDataRef("sim/flightmodel/position/M") },
{ DREF::L, XPLMFindDataRef("sim/flightmodel/position/L") },
{ DREF::N, XPLMFindDataRef("sim/flightmodel/position/N") },
{ DREF::QRad, XPLMFindDataRef("sim/flightmodel/position/Qrad") },
{ DREF::PRad, XPLMFindDataRef("sim/flightmodel/position/Prad") },
{ DREF::RRad, XPLMFindDataRef("sim/flightmodel/position/Rrad") },
{ DREF::Q, XPLMFindDataRef("sim/flightmodel/position/Q") },
{ DREF::P, XPLMFindDataRef("sim/flightmodel/position/P") },
{ DREF::R, XPLMFindDataRef("sim/flightmodel/position/R") },
{ DREF::Pitch, XPLMFindDataRef("sim/flightmodel/position/theta") },
{ DREF::Roll, XPLMFindDataRef("sim/flightmodel/position/phi") },
{ DREF::HeadingTrue, XPLMFindDataRef("sim/flightmodel/position/psi") },
{ DREF::HeadingMag, XPLMFindDataRef("sim/flightmodel/position/magpsi") },
{ DREF::Quaternion, XPLMFindDataRef("sim/flightmodel/position/q") },
{ DREF::AngleOfAttack, XPLMFindDataRef("sim/flightmodel/position/alpha") },
{ DREF::Sideslip, XPLMFindDataRef("sim/cockpit2/gauges/indicators/sideslip_degrees") },
{ DREF::HPath, XPLMFindDataRef("sim/flightmodel/position/hpath") },
{ DREF::VPath, XPLMFindDataRef("sim/flightmodel/position/vpath") },
{ DREF::VPath, XPLMFindDataRef("sim/flightmodel/position/magnetic_variation") },
{ DREF::Latitude, XPLMFindDataRef("sim/flightmodel/position/latitude") },
{ DREF::Longitude, XPLMFindDataRef("sim/flightmodel/position/longitude") },
{ DREF::AGL, XPLMFindDataRef("sim/flightmodel/position/y_agl") },
{ DREF::LocalX, XPLMFindDataRef("sim/flightmodel/position/local_x") },
{ DREF::LocalY, XPLMFindDataRef("sim/flightmodel/position/local_y") },
{ DREF::LocalZ, XPLMFindDataRef("sim/flightmodel/position/local_z") },
{ DREF::LocalVX, XPLMFindDataRef("sim/flightmodel/position/local_vx") },
{ DREF::LocalVY, XPLMFindDataRef("sim/flightmodel/position/local_vy") },
{ DREF::LocalVZ, XPLMFindDataRef("sim/flightmodel/position/local_vz") },
{ DREF::ThrottleSet, XPLMFindDataRef("sim/flightmodel/engine/ENGN_thro") },
{ DREF::ThrottleActual, XPLMFindDataRef("sim/flightmodel2/engines/throttle_used_ratio") },
{ DREF::MP1Lat, XPLMFindDataRef("sim/multiplayer/position/plane1_lat") },
{ DREF::MP2Lat, XPLMFindDataRef("sim/multiplayer/position/plane2_lat") },
{ DREF::MP3Lat, XPLMFindDataRef("sim/multiplayer/position/plane3_lat") },
{ DREF::MP4Lat, XPLMFindDataRef("sim/multiplayer/position/plane4_lat") },
{ DREF::MP5Lat, XPLMFindDataRef("sim/multiplayer/position/plane5_lat") },
{ DREF::MP6Lat, XPLMFindDataRef("sim/multiplayer/position/plane6_lat") },
{ DREF::MP7Lat, XPLMFindDataRef("sim/multiplayer/position/plane7_lat") },
{ DREF::MP1Lon, XPLMFindDataRef("sim/multiplayer/position/plane1_lon") },
{ DREF::MP2Lon, XPLMFindDataRef("sim/multiplayer/position/plane2_lon") },
{ DREF::MP3Lon, XPLMFindDataRef("sim/multiplayer/position/plane3_lon") },
{ DREF::MP4Lon, XPLMFindDataRef("sim/multiplayer/position/plane4_lon") },
{ DREF::MP5Lon, XPLMFindDataRef("sim/multiplayer/position/plane5_lon") },
{ DREF::MP6Lon, XPLMFindDataRef("sim/multiplayer/position/plane6_lon") },
{ DREF::MP7Lon, XPLMFindDataRef("sim/multiplayer/position/plane7_lon") },
{ DREF::MP1Alt, XPLMFindDataRef("sim/multiplayer/position/plane1_el") },
{ DREF::MP2Alt, XPLMFindDataRef("sim/multiplayer/position/plane2_el") },
{ DREF::MP3Alt, XPLMFindDataRef("sim/multiplayer/position/plane3_el") },
{ DREF::MP4Alt, XPLMFindDataRef("sim/multiplayer/position/plane4_el") },
{ DREF::MP5Alt, XPLMFindDataRef("sim/multiplayer/position/plane5_el") },
{ DREF::MP6Alt, XPLMFindDataRef("sim/multiplayer/position/plane6_el") },
{ DREF::MP7Alt, XPLMFindDataRef("sim/multiplayer/position/plane7_el") },
});
char multi[256];
for (int i = 1; i < 20; i++)
{
sprintf(multi, "sim/multiplayer/position/plane%i_x", i); // X
mdrefs[i][DREF::LocalX] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_y", i); // Y
mdrefs[i][DREF::LocalY] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_z", i); // Z
mdrefs[i][DREF::LocalZ] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_the", i); // Theta (Pitch)
mdrefs[i][DREF::Pitch] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_phi", i); // Phi (Roll)
mdrefs[i][DREF::Roll] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_psi", i); // Psi (Heading-True)
mdrefs[i][DREF::HeadingTrue] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_gear_deploy", i); // Landing Gear
mdrefs[i][DREF::GearDeploy] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_flap_ratio", i);
mdrefs[i][DREF::FlapSetting] = XPLMFindDataRef(multi); // Can't set the actual flap setting on npc aircraft
mdrefs[i][DREF::FlapActual] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_flap_ratio2", i);
mdrefs[i][DREF::FlapActual2] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_spoiler_ratio", i);
mdrefs[i][DREF::Spoiler] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_speedbrake_ratio", i);
mdrefs[i][DREF::BrakeSpeed] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_slat_ratio", i);
mdrefs[i][DREF::Slats] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_wing_sweep", i);
mdrefs[i][DREF::Sweep] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_throttle", i);
mdrefs[i][DREF::ThrottleActual] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_yolk_pitch", i);
mdrefs[i][DREF::YokePitch] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_yolk_roll", i);
mdrefs[i][DREF::YokeRoll] = XPLMFindDataRef(multi);
sprintf(multi, "sim/multiplayer/position/plane%i_yolk_yaw", i);
mdrefs[i][DREF::YokeHeading] = XPLMFindDataRef(multi);
}
}
int DataManager::Get(std::string dref, float values[], int size)
{
XPLMDataRef& xdref = sdrefs[dref];
if (xdref == nullptr)
{
xdref = XPLMFindDataRef(dref.c_str());
}
if (!xdref)
{
// DREF does not exist
#if LOG_VERBOSITY > 0
Log::WriteLine("[DMAN] ERROR: invalid DREF");
#endif
return 0;
}
XPLMDataTypeID dataType = XPLMGetDataRefTypes(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Get DREF %s (x:%X) type %i", dref.c_str(), xdref, dataType);
#endif
switch (dataType)
{
case 1: // Integer
{
values[0] = (float)XPLMGetDatai(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine(" value was %i", (int)values[0]);
#endif
return 1;
}
case 4: // Double
{
values[0] = (float)XPLMGetDatad(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine(" value was %f", values[0]);
#endif
return 1;
}
case 8: // Float Array
{
int drefSize = XPLMGetDatavf(xdref, NULL, 0, 0);
drefSize = min(drefSize, size);
XPLMGetDatavf(xdref, values, 0, drefSize);
#if LOG_VERBOSITY > 4
Log::FormatLine(" value count was %i", drefSize);
#endif
return drefSize;
}
case 16: // Integer Array
{
int iValues[64];
int drefSize = XPLMGetDatavi(xdref, NULL, 0, 0);
drefSize = min(drefSize, size);
drefSize = min(drefSize, 64);
XPLMGetDatavi(xdref, iValues, 0, drefSize);
for (int i = 0; i < drefSize; ++i)
{
values[i] = (float)iValues[i];
}
#if LOG_VERBOSITY > 4
Log::FormatLine(" value count was %i", drefSize);
#endif
return drefSize;
}
default: // Assume float
{
values[0] = XPLMGetDataf(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine(" value was %f", values[0]);
#endif
return 1;
}
}
}
double DataManager::GetDouble(DREF dref, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
double value = XPLMGetDatad(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Get DREF %i (x:%X) result %f for a/c %i", dref, xdref, value, aircraft);
#endif
return value;
}
float DataManager::GetFloat(DREF dref, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
float value = XPLMGetDataf(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Get DREF %i (x:%X) result %f for a/c %i", dref, xdref, value, aircraft);
#endif
return value;
}
int DataManager::GetInt(DREF dref, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
int value = XPLMGetDatai(xdref);
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Get DREF %i (x:%X) result %i for a/c %i", dref, xdref, value, aircraft);
#endif
return value;
}
int DataManager::GetFloatArray(DREF dref, float values[], int size, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
int resultSize = XPLMGetDatavf(xdref, values, 0, size);
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Get DREF %i (x:%X) result size %i for a/c %i", dref, xdref, resultSize, aircraft);
#endif
return resultSize;
}
int DataManager::GetIntArray(DREF dref, int values[], int size, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
int resultSize = XPLMGetDatavi(xdref, values, 0, size);
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Get DREF %i (x:%X) result size %i for a/c %i", dref, xdref, resultSize, aircraft);
#endif
return resultSize;
}
void DataManager::Set(DREF dref, double value, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Setting DREF %i (x:%X) to %f for a/c %i", dref, xdref, value, aircraft);
#endif
XPLMSetDatad(xdref, value);
}
void DataManager::Set(DREF dref, float value, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Set DREF %i (x:%X) to %f for a/c %i", dref, xdref, value, aircraft);
#endif
XPLMSetDataf(xdref, value);
}
void DataManager::Set(DREF dref, int value, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Set DREF %i (x:%X) to %i for a/c %i", dref, xdref, value, aircraft);
#endif
XPLMSetDatai(xdref, value);
}
void DataManager::Set(DREF dref, float values[], int size, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Set DREF %i (x:%X) (%i values) for a/c %i", dref, xdref, size, aircraft);
#endif
int drefSize = XPLMGetDatavf(xdref, NULL, 0, 0);
drefSize = min(drefSize, size);
XPLMSetDatavf(xdref, values, 0, drefSize);
}
void DataManager::Set(DREF dref, int values[], int size, char aircraft)
{
const XPLMDataRef& xdref = aircraft == 0 ? drefs[dref] : mdrefs[aircraft][dref];
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Setting DREF %i (x:%X) (%i values) for a/c %i", dref, xdref, size, aircraft);
#endif
int drefSize = XPLMGetDatavi(xdref, NULL, 0, 0);
drefSize = min(drefSize, size);
XPLMSetDatavi(xdref, values, 0, drefSize);
}
void DataManager::Set(std::string dref, float values[], int size)
{
XPLMDataRef& xdref = sdrefs[dref];
if (xdref == nullptr)
{
xdref = XPLMFindDataRef(dref.c_str());
}
#if LOG_VERBOSITY > 4
Log::FormatLine("[DMAN] Setting DREF %s (x:%X) (%i values)", dref.c_str(), xdref, size);
#endif
if (!xdref)
{
// DREF does not exist
#if LOG_VERBOSITY > 0
Log::WriteLine("[DMAN] ERROR: invalid DREF");
#endif
return;
}
if (std::isnan(values[0]))
{
#if LOG_VERBOSITY > 0
Log::WriteLine("[DMAN] ERROR: Value must be a number (NaN received)");
#endif
return;
}
XPLMDataTypeID dataType = XPLMGetDataRefTypes(xdref);
switch (dataType)
{
case 1: // Integer
{
XPLMSetDatai(xdref, (int)values[0]);
break;
}
case 4: // Double
{
XPLMSetDatad(xdref, values[0]);
break;
}
case 8: // Float Array
{
int drefSize = XPLMGetDatavf(xdref, NULL, 0, 0);
drefSize = min(drefSize, size);
XPLMSetDatavf(xdref, values, 0, drefSize);
break;
}
case 16: // Integer Array
{
int iValues[64];
int drefSize = XPLMGetDatavi(xdref, NULL, 0, 0);
drefSize = min(drefSize, size);
drefSize = min(drefSize, 64);
for (int i = 0; i < drefSize; ++i)
{
iValues[i] = (int)values[i];
}
XPLMSetDatavi(xdref, iValues, 0, drefSize);
break;
}
default: // Assume float
{
XPLMSetDataf(xdref, values[0]);
break;
}
}
}
void DataManager::SetGear(float gear, bool immediate, char aircraft)
{
#if LOG_VERBOSITY > 3
Log::FormatLine("[DMAN] Setting gear (value:%f, immediate:%i) for aircraft %i", gear, immediate, aircraft);
#endif
float gearArray[10];
if ((gear < -8.5f && gear > 9.5f) || (gear < -997.9f && gear > -999.1f))
{
return;
}
if (std::isnan(gear) || gear < 0 || gear > 1)
{
Log::WriteLine("[GEAR] ERROR: Value must be 0 or 1");
return;
}
for (int i = 0; i < 10; i++)
{
gearArray[i] = gear;
}
if (aircraft == 0) // Own aircraft
{
Set(DREF::GearHandle, (int)gear);
if (immediate)
{
Set(DREF::GearDeploy, gearArray, 10);
}
}
else // Multiplayer aircraft
{
XPLMSetDatavf(mdrefs[aircraft][DREF::GearDeploy], gearArray, 0, 10);
}
}
void DataManager::SetPosition(float pos[3], char aircraft)
{
#if LOG_VERBOSITY > 3
Log::FormatLine("[DMAN] Setting position (%f, %f, %f) for aircraft %i", pos[0], pos[1], pos[2], aircraft);
#endif
if (std::isnan(pos[0] + pos[1] + pos[2]))
{
#if LOG_VERBOSITY > 0
Log::WriteLine("[DMAN] ERROR: Position must be a number (NaN received)");
#endif
return;
}
double local[3] = { 0 };
XPLMWorldToLocal(pos[0], pos[1], pos[2], &local[0], &local[1], &local[2]);
if (aircraft == 0) // Player aircraft
{
// If the sim is paused, setting global position won't update the
// local position, so set them just in case.
Set(DREF::LocalX, local[0]);
Set(DREF::LocalY, local[1]);
Set(DREF::LocalZ, local[2]);
// If the sim is unpaused, this will override the above settings.
Set(DREF::Latitude, (double)pos[0]);
Set(DREF::Longitude, (double)pos[1]);
Set(DREF::AGL, (double)pos[2]);
}
else // Multiplayer
{
XPLMSetDatad(mdrefs[aircraft][DREF::LocalX], local[0]);
XPLMSetDatad(mdrefs[aircraft][DREF::LocalY], local[1]);
XPLMSetDatad(mdrefs[aircraft][DREF::LocalZ], local[2]);
}
}
void DataManager::SetOrientation(float orient[3], char aircraft)
{
#if LOG_VERBOSITY > 3
Log::FormatLine("[DMAN] Setting orientation (%f, %f, %f) for aircraft %i",
orient[0], orient[1], orient[2], aircraft);
#endif
if (std::isnan(orient[0] + orient[1] + orient[2]))
{
#if LOG_VERBOSITY > 0
Log::WriteLine("[DMAN] ERROR: Orientation must be a number (NaN received)");
#endif
return;
}
if (aircraft == 0) // Player aircraft
{
// If the sim is paused, setting the quaternion won't update these values,
// so we set them here just in case.
Set(DREF::Pitch, orient[0]);
Set(DREF::Roll, orient[1]);
Set(DREF::HeadingTrue, orient[2]);
// Convert to Quaternions
// from: http://www.xsquawkbox.net/xpsdk/mediawiki/MovingThePlane
// http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf
float q[4] = { 0 };
float halfRad = 0.00872664625997F;
orient[2] = halfRad * orient[2];
orient[0] = halfRad * orient[0];
orient[1] = halfRad * orient[1];
q[0] = cos(orient[2]) * cos(orient[0]) * cos(orient[1]) + sin(orient[2]) * sin(orient[0]) * sin(orient[1]);
q[1] = cos(orient[2]) * cos(orient[0]) * sin(orient[1]) - sin(orient[2]) * sin(orient[0]) * cos(orient[1]);
q[2] = cos(orient[2]) * sin(orient[0]) * cos(orient[1]) + sin(orient[2]) * cos(orient[0]) * sin(orient[1]);
q[3] = sin(orient[2]) * cos(orient[0]) * cos(orient[1]) - cos(orient[2]) * sin(orient[0]) * sin(orient[1]);
// If the sim is un-paused, this will overwrite the pitch/roll/yaw
// values set above.
Set(DREF::Quaternion, q, 4);
}
else // Multiplayer
{
XPLMSetDataf(mdrefs[aircraft][DREF::Pitch], orient[0]);
XPLMSetDataf(mdrefs[aircraft][DREF::Roll], orient[1]);
XPLMSetDataf(mdrefs[aircraft][DREF::HeadingTrue], orient[2]);
}
}
void DataManager::SetFlaps(float value)
{
if (std::isnan(value))
{
Log::WriteLine("[FLAP] ERROR: Value must be a number (NaN received)");
return;
}
value = max(value, 0);
value = min(value, 1);
Set(DREF::FlapSetting, value);
Set(DREF::FlapActual, value);
}
}