484 lines
19 KiB
C++
484 lines
19 KiB
C++
#include "include/_simconnect.h"
|
|
|
|
SimConnect::SimConnect(
|
|
HWND hWnd,
|
|
std::function<void(const std::string)> toLog,
|
|
std::shared_ptr<germanairlinesva::file::config::Config> configuration)
|
|
: configuration(configuration), toLog(std::move(toLog))
|
|
{
|
|
HRESULT hr = SimConnect_Open(&this->simConnect,
|
|
"GAConnector",
|
|
hWnd,
|
|
SIMCONNECT_MESSAGE,
|
|
NULL,
|
|
NULL);
|
|
if (!SUCCEEDED(hr)) {
|
|
this->toLog("SimConnect_Open: Failed");
|
|
} else {
|
|
this->connectedToSim = true;
|
|
this->toLog("SimConnect_Close: Connection opened");
|
|
|
|
// Setup SimConnect
|
|
SimConnect_SubscribeToSystemEvent(simConnect, EVENTS::E_PAUSE, "Pause");
|
|
SimConnect_SubscribeToSystemEvent(simConnect, EVENTS::E_STATUS, "Sim");
|
|
|
|
SimConnect_MapClientEventToSimEvent(simConnect,
|
|
EVENTS::E_TIMESEC,
|
|
"CLOCK_SECONDS_ZERO");
|
|
SimConnect_AddClientEventToNotificationGroup(simConnect,
|
|
GROUPS::G_TIME,
|
|
EVENTS::E_TIMESEC,
|
|
false);
|
|
SimConnect_SetNotificationGroupPriority(simConnect,
|
|
GROUPS::G_TIME,
|
|
SIMCONNECT_GROUP_PRIORITY_HIGHEST);
|
|
SimConnect_MapClientEventToSimEvent(simConnect,
|
|
EVENTS::E_TIMEMIN,
|
|
"ZULU_MINUTES_SET");
|
|
SimConnect_AddClientEventToNotificationGroup(simConnect,
|
|
GROUPS::G_TIME,
|
|
EVENTS::E_TIMEMIN,
|
|
false);
|
|
SimConnect_SetNotificationGroupPriority(simConnect,
|
|
GROUPS::G_TIME,
|
|
SIMCONNECT_GROUP_PRIORITY_HIGHEST);
|
|
SimConnect_MapClientEventToSimEvent(simConnect,
|
|
EVENTS::E_TIMEHRS,
|
|
"ZULU_HOURS_SET");
|
|
SimConnect_AddClientEventToNotificationGroup(simConnect,
|
|
GROUPS::G_TIME,
|
|
EVENTS::E_TIMEHRS,
|
|
false);
|
|
SimConnect_SetNotificationGroupPriority(simConnect,
|
|
GROUPS::G_TIME,
|
|
SIMCONNECT_GROUP_PRIORITY_HIGHEST);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"BRAKE PARKING INDICATOR",
|
|
"BOOL",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"SIM ON GROUND",
|
|
"BOOL",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"EMPTY WEIGHT",
|
|
"KILOGRAMS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"TOTAL WEIGHT",
|
|
"KILOGRAMS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"FUEL TOTAL QUANTITY WEIGHT",
|
|
"KILOGRAMS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"PLANE HEADING DEGREES TRUE",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"PLANE HEADING DEGREES MAGNETIC",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"GROUND VELOCITY",
|
|
"KNOTS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"AIRSPEED INDICATED",
|
|
"KNOTS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"AIRSPEED BARBER POLE",
|
|
"KNOTS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"VELOCITY WORLD Y",
|
|
"FEET/MINUTE",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"VERTICAL SPEED",
|
|
"FEET/MINUTE",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"PLANE ALTITUDE",
|
|
"FEET",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"PLANE ALT ABOVE GROUND",
|
|
"FEET",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"PLANE LATITUDE",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"PLANE LONGITUDE",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"ABSOLUTE TIME",
|
|
"SECONDS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"ENG FUEL FLOW PPH:1",
|
|
"KILOGRAMS PER SECOND",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"ENG FUEL FLOW PPH:2",
|
|
"KILOGRAMS PER SECOND",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"ENG FUEL FLOW PPH:3",
|
|
"KILOGRAMS PER SECOND",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"ENG FUEL FLOW PPH:4",
|
|
"KILOGRAMS PER SECOND",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"BRAKE INDICATOR",
|
|
"POSITION",
|
|
SIMCONNECT_DATATYPE_INT32,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"BRAKE PARKING POSITION",
|
|
"POSITION",
|
|
SIMCONNECT_DATATYPE_INT32,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"BRAKE LEFT POSITION",
|
|
"POSITION",
|
|
SIMCONNECT_DATATYPE_INT32,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"ZULU TIME",
|
|
"SECONDS",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_DATA,
|
|
"G FORCE",
|
|
"GForce",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_PORT,
|
|
"PLANE HEADING DEGREES TRUE",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_PORT,
|
|
"PLANE LATITUDE",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
SimConnect_AddToDataDefinition(simConnect,
|
|
DEFINITIONS::D_PORT,
|
|
"PLANE LONGITUDE",
|
|
"DEGREES",
|
|
SIMCONNECT_DATATYPE_FLOAT64,
|
|
0,
|
|
SIMCONNECT_UNUSED);
|
|
|
|
SimConnect_RequestDataOnSimObject(simConnect,
|
|
REQUESTS::R_DATA,
|
|
DEFINITIONS::D_DATA,
|
|
SIMCONNECT_OBJECT_ID_USER,
|
|
SIMCONNECT_PERIOD_SIM_FRAME,
|
|
SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT,
|
|
0,
|
|
0,
|
|
0);
|
|
}
|
|
}
|
|
|
|
SimConnect::~SimConnect()
|
|
{
|
|
if (this->connectedToSim) {
|
|
HRESULT hr = SimConnect_Close(this->simConnect);
|
|
if (!SUCCEEDED(hr)) {
|
|
this->toLog("SimConnect_Close: Failed");
|
|
} else {
|
|
this->connectedToSim = true;
|
|
this->toLog("SimConnect_Close: Connection closed");
|
|
}
|
|
}
|
|
}
|
|
|
|
void SimConnect::getStates() const
|
|
{
|
|
SimConnect_RequestSystemState(this->simConnect,
|
|
REQUESTS::R_ACFT,
|
|
"AircraftLoaded");
|
|
SimConnect_RequestSystemState(this->simConnect, REQUESTS::R_DIALOG, "DIALOG");
|
|
}
|
|
|
|
bool SimConnect::isConnected() const { return this->connectedToSim; }
|
|
|
|
char SimConnect::getVersion() const { return this->version; }
|
|
|
|
void SimConnect::getData(
|
|
struct germanairlinesva::gaconnector::websocket::data *data)
|
|
{
|
|
const std::lock_guard<std::mutex> lock(this->mutex);
|
|
memcpy(data, &this->simData, sizeof(this->simData));
|
|
}
|
|
|
|
void SimConnect::handleMessage(std::function<void(int)> callbackOpen,
|
|
std::function<void()> callbackData)
|
|
{
|
|
SIMCONNECT_RECV *pData;
|
|
DWORD cbData;
|
|
|
|
HRESULT hr = SimConnect_GetNextDispatch(this->simConnect, &pData, &cbData);
|
|
if (SUCCEEDED(hr)) {
|
|
switch (pData->dwID) {
|
|
case SIMCONNECT_RECV_ID_OPEN: {
|
|
this->handleOpen((SIMCONNECT_RECV_OPEN *)pData);
|
|
callbackOpen(this->version);
|
|
break;
|
|
}
|
|
case SIMCONNECT_RECV_ID_EVENT: {
|
|
this->handleEvent((SIMCONNECT_RECV_EVENT *)pData);
|
|
break;
|
|
}
|
|
case SIMCONNECT_RECV_ID_SYSTEM_STATE: {
|
|
this->handleSystemEvent((SIMCONNECT_RECV_SYSTEM_STATE *)pData);
|
|
break;
|
|
}
|
|
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA: {
|
|
this->handleData((SIMCONNECT_RECV_SIMOBJECT_DATA *)pData);
|
|
callbackData();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SimConnect::handleOpen(SIMCONNECT_RECV_OPEN *data)
|
|
{
|
|
switch (data->dwSimConnectVersionMajor) {
|
|
case MSFS_VERSION:
|
|
this->version = MSFS_VERSION;
|
|
break;
|
|
default:
|
|
break;
|
|
case FSX_VERSION:
|
|
switch (data->dwSimConnectBuildMajor) {
|
|
case FSXRTM_SUBVERSION:
|
|
case FSSXSP1_SUBVERRSION:
|
|
break;
|
|
case FSXSP2_SUBVERSION:
|
|
case FSXACC_SUBVERSION:
|
|
case FSXGOLD_SUBVERSION:
|
|
this->version = FSX_VERSION;
|
|
break;
|
|
case FSXSE_SUBVERSION:
|
|
if (configuration->getPath(FSXSE_VERSION).length() > 0) {
|
|
this->version = FSXSE_VERSION;
|
|
} else {
|
|
this->version = FSX_VERSION;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case P3D5_VERSION:
|
|
this->version = P3D5_VERSION;
|
|
break;
|
|
case P3D4_VERSION:
|
|
this->version = P3D4_VERSION;
|
|
break;
|
|
case P3D3_VERSION:
|
|
this->version = P3D3_VERSION;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SimConnect::handleSystemEvent(SIMCONNECT_RECV_SYSTEM_STATE *state)
|
|
{
|
|
switch (state->dwRequestID) {
|
|
case REQUESTS::R_ACFT:
|
|
this->aircraftPath = state->szString;
|
|
break;
|
|
case REQUESTS::R_DIALOG:
|
|
this->pausedMenu = state->dwInteger != 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SimConnect::handleEvent(SIMCONNECT_RECV_EVENT *event)
|
|
{
|
|
switch (event->uEventID) {
|
|
case EVENTS::E_PAUSE:
|
|
this->paused = event->dwData != 0;
|
|
break;
|
|
case EVENTS::E_STATUS:
|
|
this->toLog("SimConnect Status " + std::to_string(event->dwData));
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SimConnect::handleData(SIMCONNECT_RECV_SIMOBJECT_DATA *data)
|
|
{
|
|
switch (data->dwRequestID) {
|
|
case REQUESTS::R_DATA: {
|
|
const std::lock_guard<std::mutex> lock(this->mutex);
|
|
|
|
struct data *_data = (struct data *)&data->dwData;
|
|
this->simData.pause = this->paused || this->pausedMenu;
|
|
this->simData.pBrake = _data->parkingBrake != 0 || _data->brakePos;
|
|
this->simData.onGrnd = _data->onGround != 0;
|
|
this->simData.totFuelKg = _data->fuel;
|
|
this->simData.truHdg = _data->headingTrue;
|
|
this->simData.alt = _data->altitude;
|
|
this->simData.gs = _data->groundSpeed;
|
|
this->simData.ias = _data->indicatedAirspeed;
|
|
this->simData.vs =
|
|
abs(_data->verticalVelocity - _data->verticalSpeed) > 200
|
|
? _data->verticalSpeed
|
|
: _data->verticalVelocity;
|
|
this->simData.lat = _data->latitude;
|
|
this->simData.lon = _data->longitude;
|
|
this->simData.ff[0] = _data->fuelFlowEng1;
|
|
this->simData.ff[1] = _data->fuelFlowEng2;
|
|
this->simData.ff[2] = _data->fuelFlowEng3;
|
|
this->simData.ff[3] = _data->fuelFlowEng4;
|
|
this->simData.maxSpd = _data->barberPoleSpeed;
|
|
strcpy(this->simData.path, this->aircraftPath.c_str());
|
|
this->simData.uptime = _data->elapsedTime;
|
|
this->simData.magHeading = _data->headingMagnetic;
|
|
this->simData.payloadKg =
|
|
_data->currentWeight - _data->emptyWeight - _data->fuel;
|
|
this->simData.totalWeightKg = _data->currentWeight;
|
|
}
|
|
}
|
|
}
|
|
|
|
const std::string SimConnect::resolveVersion(char version)
|
|
{
|
|
switch (version) {
|
|
case MSFS_VERSION:
|
|
return "MSFS";
|
|
case FSX_VERSION:
|
|
return "FSX";
|
|
case P3D5_VERSION:
|
|
return "P3D5";
|
|
case P3D4_VERSION:
|
|
return "P3D4";
|
|
break;
|
|
case P3D3_VERSION:
|
|
return "P3D3";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
const std::string SimConnect::resolveScenery(char version)
|
|
{
|
|
switch (version) {
|
|
case FSX_VERSION:
|
|
return FSX_SCENERY;
|
|
case FSXSE_VERSION:
|
|
return FSXSE_SCENERY;
|
|
case P3D5_VERSION:
|
|
return P3D5_SCENREY;
|
|
case P3D4_VERSION:
|
|
return P3D4_SCENREY;
|
|
break;
|
|
case P3D3_VERSION:
|
|
return P3D3_SCENREY;
|
|
default:
|
|
return "/";
|
|
}
|
|
} |