Hello.
I've been developing software that needs to track the plane data from the sim, and I've been having some issues getting the correct values for the SimVars from the sim. My program is in C++ (though I mainly do C-styled coding because it's all I really know. I haven't been able to find time to learn the modern C++ styles) so I've been going through old FSX/P3D examples/samples to try and work out why my program won't work properly, but I'm completely stumped now.
It first started making me frustrated when I tried to access the SimVar BRAKE PARKING INDICATOR, and it not giving me the same type of values as when I had SIM ON GROUND set up the exact same way. So even though they were set up the same way, and the data was exactly the same type, the On Ground bool always works, and the parking brake indicator never does lol. To try and combat this (because I'm trying to write in flight states for the plane, and yes I know that AI Traffic states exist, I just want manual ones set up by conditional statements), I just wrote in some ground velocity things because that WAS working, and now after removing the parking brake indicator, that SimVar doesn't work anymore either.
Here's the cpp file for the simconnect stuff: (the one I'm currently using is the singlePos() function)
And here's the code for the header file:
I'd like to know how to be able to fix this code so that it properly gives me correct data from the sim for all the different SimVar's that I might need (eventually need heading indication and guage info as well if it's possible, as well as payload and fuel info which also need to be settable if that's at all possible in MFS2020). I'm coming here as a last resort, so please give me any advice you can, thanks.
Sidenote: I'm not the greatest at C++ and I'm still learning quite a bit each day, but I should know enough to be able to understand your responses, though if you could make sure to link stuff to sources that explain anything more complicated I'd really appreciate it.
I've been developing software that needs to track the plane data from the sim, and I've been having some issues getting the correct values for the SimVars from the sim. My program is in C++ (though I mainly do C-styled coding because it's all I really know. I haven't been able to find time to learn the modern C++ styles) so I've been going through old FSX/P3D examples/samples to try and work out why my program won't work properly, but I'm completely stumped now.
It first started making me frustrated when I tried to access the SimVar BRAKE PARKING INDICATOR, and it not giving me the same type of values as when I had SIM ON GROUND set up the exact same way. So even though they were set up the same way, and the data was exactly the same type, the On Ground bool always works, and the parking brake indicator never does lol. To try and combat this (because I'm trying to write in flight states for the plane, and yes I know that AI Traffic states exist, I just want manual ones set up by conditional statements), I just wrote in some ground velocity things because that WAS working, and now after removing the parking brake indicator, that SimVar doesn't work anymore either.
Here's the cpp file for the simconnect stuff: (the one I'm currently using is the singlePos() function)
C++:
#include "cSimConnect.h"
void cSimConnect::trackPos()
{
quit = 0;
HRESULT hr;
if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Request Data", nullptr, 0, nullptr, 0)))
{
printf("\nConnected to MFS!");
// Set up the data definition, but do not yet do anything with it
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "title", nullptr, SIMCONNECT_DATATYPE_STRING256);
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Kohlsman setting hg", "inHg");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Altitude", "feet");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Latitude", "degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Longitude", "degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "SIM ON GROUND", nullptr, SIMCONNECT_DATATYPE_INT32);
// Request an event when the simulation starts
hr = SimConnect_SubscribeToSystemEvent(hSimConnect, EVENT_SIM_START, "SimStart");
/*hr = SimConnect_SubscribeToSystemEvent(hSimConnect, KEY_PARKING_BRAKES, "PARKING_BRAKES");*/ // Doesn't work because not a system event apparently
hr = SimConnect_MapClientEventToSimEvent(hSimConnect, KEY_PARKING_BRAKES, "PARKING_BRAKES"); // Sets an event for the parking brakes to be toggled (processed in process).
hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP0, KEY_PARKING_BRAKES);
hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER,
SIMCONNECT_PERIOD_SECOND, 0, 0, 1, 0); // Get the info from the game every second (for now, might want to change it later like having it check once for airport and use this for flight tracking).
// hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER,
// SIMCONNECT_PERIOD_ONCE, 0, 0, 0, 0); // Get plane info once
while (0 == quit)
{
SimConnect_CallDispatch(hSimConnect, DispatchCallback, this);
Sleep(1);
}
hr = SimConnect_Close(hSimConnect);
}
}
void cSimConnect::DispatchCallback(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext)
{
cSimConnect* pThis = reinterpret_cast<cSimConnect*>(pContext);
pThis->Process(pData, cbData);
}
void cSimConnect::Process(SIMCONNECT_RECV* pData, DWORD cbData)
{
HRESULT hr;
printf("\nProcess was called");
/*hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);*/
switch (pData->dwID)
{
case SIMCONNECT_RECV_ID_EVENT: // I can use this case for binding to parking brake for job completion if we want (though the code would have to change).
{
SIMCONNECT_RECV_EVENT* evt = (SIMCONNECT_RECV_EVENT*)pData;
switch (evt->uEventID)
{
case EVENT_SIM_START:
// Now the sim is running, request information on the user aircraft
/*hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);*/
// hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER,
// SIMCONNECT_PERIOD_SECOND, 0, 0, 1, 0);
break;
case KEY_PARKING_BRAKES:
printf("\nThe Parking Brakes were toggled\n");
quit = 1;
break;
}
break;
}
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
{
SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData;
printf("\nObject data received\n");
switch (pObjData->dwRequestID)
{
case REQUEST_1:
{
DWORD ObjectID = pObjData->dwObjectID;
dataStruct* pS = (dataStruct*)&pObjData->dwData;
if (SUCCEEDED(StringCbLengthA(&pS->title[0], sizeof(pS->title), nullptr))) // security check
{
printf("\nObjectID=%d title=\"%s\"\nLat=%f Lon=%f Alt=%f Kohlsman=%.2f\n", ObjectID, pS->title, pS->latitude, pS->longitude, pS->altitude, pS->kohlsmann);
}
break;
}
default:
break;
}
break;
}
case SIMCONNECT_RECV_ID_QUIT:
{
quit = 1;
break;
}
default:
printf("\nReceived:%d", pData->dwID);
break;
}
}
void cSimConnect::singlePos()
{
quit = 0;
HRESULT hr;
if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Request Data", nullptr, 0, nullptr, 0)))
{
/*printf("\nConnected to MFS!");*/
// Set up the data definition, but do not yet do anything with it
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "title", nullptr, SIMCONNECT_DATATYPE_STRING256);
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Kohlsman setting hg", "inHg");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Altitude", "feet");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Latitude", "degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Longitude", "degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "SIM ON GROUND", nullptr, SIMCONNECT_DATATYPE_INT32);
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "GROUND VELOCITY", "Knots");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Ground Altitude", "Feet");
// Request an event when the simulation starts
hr = SimConnect_SubscribeToSystemEvent(hSimConnect, EVENT_SIM_START, "SimStart");
/*hr = SimConnect_SubscribeToSystemEvent(hSimConnect, KEY_PARKING_BRAKES, "PARKING_BRAKES");*/ // Doesn't work because not a system event apparently
// hr = SimConnect_MapClientEventToSimEvent(hSimConnect, KEY_PARKING_BRAKES, "PARKING_BRAKES"); // Sets an event for the parking brakes to be toggled (processed in process).
// hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP0, KEY_PARKING_BRAKES);
// hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
// hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER,
// SIMCONNECT_PERIOD_SECOND, 0, 0, 1, 0); // Get the info from the game every second (for now, might want to change it later like having it check once for airport and use this for flight tracking).
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER,
SIMCONNECT_PERIOD_ONCE); // Get plane info once
while (0 == quit)
{
SimConnect_CallDispatch(hSimConnect, DispatchCallbackSingle, this);
Sleep(1);
}
hr = SimConnect_Close(hSimConnect);
}
}
void cSimConnect::DispatchCallbackSingle(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext)
{
cSimConnect* pThis = reinterpret_cast<cSimConnect*>(pContext);
pThis->ProcessSingle(pData, cbData);
}
void cSimConnect::ProcessSingle(SIMCONNECT_RECV* pData, DWORD cbData)
{
HRESULT hr;
/*printf("\nProcess was called");*/
/*hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);*/
switch (pData->dwID)
{
case SIMCONNECT_RECV_ID_EVENT: // I can use this case for binding to parking brake for job completion if we want (though the code would have to change).
{
SIMCONNECT_RECV_EVENT* evt = (SIMCONNECT_RECV_EVENT*)pData;
switch (evt->uEventID)
{
case EVENT_SIM_START:
// Now the sim is running, request information on the user aircraft
/*hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);*/
// hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_1, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER,
// SIMCONNECT_PERIOD_SECOND, 0, 0, 1, 0);
break;
case KEY_PARKING_BRAKES:
/*printf("\nThe Parking Brakes were toggled\n");*/
quit = 1;
break;
}
break;
}
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
{
SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData;
/*printf("\nObject data received\n");*/
switch (pObjData->dwRequestID)
{
case REQUEST_1:
{
DWORD ObjectID = pObjData->dwObjectID;
dataStruct* pS = (dataStruct*)&pObjData->dwData;
if (SUCCEEDED(StringCbLengthA(&pS->title[0], sizeof(pS->title), nullptr))) // security check
{
/*printf("\nObjectID=%d title=\"%s\"\nLat=%f Lon=%f Alt=%f Kohlsman=%.2f\n", ObjectID, pS->title, pS->latitude, pS->longitude, pS->altitude, pS->kohlsmann);*/
latitude = pS->latitude;
longitude = pS->longitude;
onGround = pS->onGround;
title = pS->title;
altitude = pS->altitude;
groundVelocity = (pS->gvel);
groundAlt = pS->grndalt;
quit = 1;
}
break;
}
default:
break;
}
break;
}
case SIMCONNECT_RECV_ID_QUIT:
{
quit = 1;
break;
}
default:
/*printf("\nReceived:%d", pData->dwID);*/
break;
}
}
And here's the code for the header file:
C++:
#pragma once
#include <Windows.h>
#include <tchar.h>
#include <cstdio>
#include <strsafe.h>
#include <SimConnect.h>
#include <iostream>
#include <string>
static enum GROUP_ID {
GROUP0,
};
static enum EVENT_ID {
EVENT_SIM_START,
KEY_PARKING_BRAKES,
};
static enum DATA_DEFINE_ID {
DEFINITION_1,
};
static enum DATA_REQUEST_ID {
REQUEST_1,
};
struct dataStruct
{
char title[256];
double kohlsmann;
double altitude;
double latitude;
double longitude;
bool onGround;
double gvel;
double grndalt;
};
class cSimConnect
{
public:
std::string title;
double kohlsmann;
double altitude;
double latitude;
double longitude;
bool onGround;
double groundVelocity;
double groundAlt;
HANDLE hSimConnect; // use SimConnect_Open to set this value.
int quit;
void trackPos();
static void DispatchCallback(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext);
void Process(SIMCONNECT_RECV* pData, DWORD cbData);
void singlePos();
static void DispatchCallbackSingle(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext);
void ProcessSingle(SIMCONNECT_RECV* pData, DWORD cbData);
};
I'd like to know how to be able to fix this code so that it properly gives me correct data from the sim for all the different SimVar's that I might need (eventually need heading indication and guage info as well if it's possible, as well as payload and fuel info which also need to be settable if that's at all possible in MFS2020). I'm coming here as a last resort, so please give me any advice you can, thanks.
Sidenote: I'm not the greatest at C++ and I'm still learning quite a bit each day, but I should know enough to be able to understand your responses, though if you could make sure to link stuff to sources that explain anything more complicated I'd really appreciate it.