756 lines
38 KiB
C++

#include "load-manager.h"
#include "pax.h"
// Data
UserData_t* UserData;
GSXData_t* GSXData;
paxPayloadData_t* livePaxPayloadData;
paxPayloadData_t* targetPaxPayloadData;
fPayloadData_t* liveFPayloadData;
fPayloadData_t* targetFPayloadData;
FuelData_t* liveFuelData;
// Operational
bool commBusCallbackRegistered;
HANDLE simConnect;
FILE* logFile;
char sendTimer = 0;
// Init
extern "C" MSFS_CALLBACK void module_init(void) {
log(stdout, MODULE_NAME"Starting init.\n");
logFile = fopen("\\work\\log.txt", "w");
if (logFile == NULL)
{
log(stderr, MODULE_NAME"Error creating logfile.\n");
}
UserData = new UserData_t();
GSXData = new GSXData_t();
livePaxPayloadData = new paxPayloadData_t();
targetPaxPayloadData = new paxPayloadData_t();
liveFPayloadData = new fPayloadData_t();
targetFPayloadData = new fPayloadData_t();
liveFuelData = new FuelData_t();
#pragma region SimConnect
// SimConnect open
HRESULT hr;
hr = SimConnect_Open(&simConnect, "KHOFMANN TFDi MD-11 Load Manager", nullptr, 0, 0, 0);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not open SimConnect connection, terminating.\n");
return;
}
// SimConnect Empty Weight data definition
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_EMPTY_WEIGHT, "EMPTY WEIGHT", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add EMPTY WEIGHT to data definition, terminating.\n");
return;
}
// SimConnect Pax/F Weight data definition
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:1", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:1 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:1", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:1 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:2", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:2 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:2", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:2 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:3", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:3 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:3", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:3 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:4", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:4 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:4", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:4 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:5", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:5 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:5", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:5 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:6", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:6 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:6", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:6 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:7", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:7 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:7", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:7 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:8", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:8 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:8", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:8 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:9", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:9 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:9", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:9 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:10", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:10 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:10", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:10 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:11", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:11 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:11", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:11 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:12", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:12 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:12", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:12 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:13", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:13 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:13", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:13 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:14", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:14 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:14", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:14 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:15", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:15 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_F, "PAYLOAD STATION WEIGHT:15", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:15 to F data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:16", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:16 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:17", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:17 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:18", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:18 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:19", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:19 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:20", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:20 to PAX data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_PAYLOAD_PAX, "PAYLOAD STATION WEIGHT:21", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add PAYLOAD STATION WEIGHT:21 to PAX data definition, terminating.\n");
return;
}
// SimConnect Fuel data definition
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL WEIGHT PER GALLON", "pounds", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL WEIGHT PER GALLON to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK LEFT MAIN QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK LEFT MAIN QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK RIGHT MAIN QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK RIGHT MAIN QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK CENTER QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK CENTER QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK CENTER2 QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK CENTER2 QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK CENTER3 QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK CENTER3 QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK LEFT TIP QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK LEFT TIP QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK RIGHT TIP QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK RIGHT TIP QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK EXTERNAL1 QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK EXTERNAL1 QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK LEFT AUX QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK LEFT AUX QUANTITY to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_FUEL, "FUEL TANK RIGHT AUX QUANTITY", "gallons", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add FUEL TANK RIGHT AUX QUANTITY to data definition, terminating.\n");
return;
}
// GSX LVars
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_BOARDING_STATE", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_BOARDING_STATE to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_DEBOARDING_STATE", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_DEBOARDING_STATE to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_NUMPASSENGERS_BOARDING_TOTAL", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_NUMPASSENGERS_BOARDING_TOTAL to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_NUMPASSENGERS_DEBOARDING_TOTAL", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_NUMPASSENGERS_DEBOARDING_TOTAL to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_BOARDING_CARGO_PERCENT", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_BOARDING_CARGO_PERCENT to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_DEBOARDING_CARGO_PERCENT", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:FSDT_GSX_DEBOARDING_CARGO_PERCENT to data definition, terminating.\n");
return;
}
// User LVars
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_EFB_IS_CARGO", "bool", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:MD11_EFB_IS_CARGO to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_OPT_ER", "bool", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:MD11_OPT_ER to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_EFB_OPTIONS_GENERAL", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not add L:MD11_EFB_OPTIONS_GENERAL to data definition, terminating.\n");
return;
}
log(stdout, MODULE_NAME"Data definitions created\n");
// SimConnect Requests
hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_EMPTY_WEIGHT, DATA_DEFINITION_EMPTY_WEIGHT, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not request empty weight, terminating.\n");
return;
}
hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_PAX, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not request payload pax, terminating.\n");
return;
}
hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_F, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not request payload f, terminating.\n");
return;
}
hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_FUEL, DATA_DEFINITION_FUEL, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not request fuel, terminating.\n");
return;
}
hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_GSX, DATA_DEFINITION_GSX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not request GSX, terminating.\n");
return;
}
hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_USER_DATA, DATA_DEFINITION_USER_DATA, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not request user data, terminating.\n");
return;
}
log(stdout, MODULE_NAME"Requests created.\n");
hr = SimConnect_CallDispatch(simConnect, MyDispatchProc, nullptr);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Could not set dispatch proc, terminating.\n");
return;
}
log(stdout, MODULE_NAME"Callback created.\n");
#pragma endregion
// CommBus
if (!fsCommBusRegister(COMM_BUS_UPDATE_TARGET_EVENT, commBusUpdateTargetCallback)) {
log(stderr, MODULE_NAME"Could not register CommBus, terminating.\n");
return;
}
else {
log(stdout, MODULE_NAME"CommBus registered.\n");
}
log(stdout, MODULE_NAME"Initialized.\n");
}
// Deinit
extern "C" MSFS_CALLBACK void module_deinit(void) {
HRESULT hr;
hr = SimConnect_Close(simConnect);
if (hr != S_OK) {
log(stderr, MODULE_NAME"Failed to close SimConnect.\n");
}
delete UserData;
delete GSXData;
delete livePaxPayloadData;
delete targetPaxPayloadData;
delete liveFPayloadData;
delete targetFPayloadData;
delete liveFuelData;
fsCommBusUnregister(COMM_BUS_UPDATE_TARGET_EVENT, commBusUpdateTargetCallback);
}
// Main loop
extern "C" MSFS_CALLBACK bool Load_Manager_gauge_callback(FsContext ctx, int service_id, void* pData) {
/*
switch (service_id) {
case PANEL_SERVICE_PRE_UPDATE: {
}
default:
break;
}
*/
return true;
}
// CommBus
void commBusUpdateTargetCallback(const char* args, unsigned int size, void* ctx) {
printf("Target payload update request: %d", receiveData(args));
}
// JSON receive
int receiveData(const char* buf) {
if (liveFPayloadData == nullptr || livePaxPayloadData == nullptr || targetFPayloadData == nullptr || targetPaxPayloadData == nullptr ||
liveFuelData == nullptr || UserData == nullptr) return 0;
rapidjson::Document document;
document.Parse(buf);
if (document.HasParseError()) return document.GetParseError();
// Shared part 1
targetFPayloadData->empty = targetPaxPayloadData->empty = FROM_POUNDS(UserData->isImperial, liveFPayloadData->empty);
targetFPayloadData->pilot = targetPaxPayloadData->pilot = PILOT_WEIGHT(UserData->isImperial);
targetFPayloadData->firstOfficer = targetPaxPayloadData->firstOfficer = PILOT_WEIGHT(UserData->isImperial);
targetFPayloadData->engineer = targetPaxPayloadData->engineer = PILOT_WEIGHT(UserData->isImperial);
// Shared part 2
targetFPayloadData->leftAux = targetPaxPayloadData->leftAux = UserData->isER ? AUX_WEIGHT(UserData->isImperial) : 0;
targetFPayloadData->rightAux = targetPaxPayloadData->rightAux = UserData->isER ? AUX_WEIGHT(UserData->isImperial) : 0;
// Pax only fixed weights
if (!UserData->isCargo) {
targetPaxPayloadData->cabinCrewFront = FRONT_CREW_WEIGHT(UserData->isImperial);
targetPaxPayloadData->cabinCrewRear = REAR_CREW_WEIGHT(UserData->isImperial);
}
if (document.HasMember("mode")) {
int mode = document["mode"].GetUint();
switch(mode) {
// SB Entry
case 0: {
if (!document.HasMember("cargo") || !document.HasMember("CGTarget")) return -1;
unsigned int cargo = document["cargo"].GetInt();
double CGTarget = document["CGTarget"].GetDouble();
if (UserData->isCargo) {
}
else {
if (!document.HasMember("numPax")) return -1;
unsigned short numPax = document["numPax"].GetInt();
distribute(targetPaxPayloadData, liveFuelData, numPax, cargo, CGTarget, UserData->isImperial);
}
break;
}
// ZFW Entry
case 1: {
if (!document.HasMember("ZFWTarget") || !document.HasMember("CGTarget")) return -1;
double ZFWTarget = document["ZFWTarget"].GetDouble();
double CGTarget = document["CGTarget"].GetDouble();
if (UserData->isCargo) {
}
else {
distribute(targetPaxPayloadData, liveFuelData, ZFWTarget, CGTarget, UserData->isImperial);
}
break;
}
// Station Entry
case 2: {
if (UserData->isCargo) {
}
else {
if (!document.HasMember("business1") || !document.HasMember("business2") ||
!document.HasMember("economy1") || !document.HasMember("economy2") ||
!document.HasMember("forwardCargo") || !document.HasMember("rearCargo")) return -1;
targetPaxPayloadData->paxCount.business1 = document["business1"].GetInt();
targetPaxPayloadData->paxCount.business2 = document["business2"].GetInt();
targetPaxPayloadData->paxCount.economy1 = document["economy1"].GetInt();
targetPaxPayloadData->paxCount.economy2 = document["economy2"].GetInt();
targetPaxPayloadData->forwardCargo = document["forwardCargo"].GetDouble();
targetPaxPayloadData->rearCargo = document["rearCargo"].GetDouble();
generatePayload(targetPaxPayloadData, UserData->isImperial);
normalisePayload(targetPaxPayloadData, UserData->isImperial);
}
break;
}
default:
break;
}
}
else return -1;
return 0;
}
// JSON send
void sendData () {
if (liveFPayloadData == nullptr || livePaxPayloadData == nullptr || targetFPayloadData == nullptr || targetPaxPayloadData == nullptr ||
liveFuelData == nullptr || UserData == nullptr || GSXData == nullptr) return;
rapidjson::Document document;
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
document.SetObject();
rapidjson::Value livePayload;
livePayload.SetObject();
rapidjson::Value targetPayload;
targetPayload.SetObject();
rapidjson::Value GSX;
GSX.SetObject();
rapidjson::StringBuffer strbuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
#pragma region Live Payload
// OEW (empty + aux tank wgts)
livePayload.AddMember("empty",
FROM_POUNDS(UserData->isImperial, UserData->isCargo ? liveFPayloadData->empty : livePaxPayloadData->empty) +
FROM_POUNDS(UserData->isImperial, UserData->isCargo ? liveFPayloadData->leftAux : livePaxPayloadData->leftAux) +
FROM_POUNDS(UserData->isImperial, UserData->isCargo ? liveFPayloadData->rightAux : livePaxPayloadData->rightAux),
allocator);
// Cargo only
if (UserData->isCargo) {
livePayload.AddMember("crew",
FROM_POUNDS(UserData->isImperial, liveFPayloadData->pilot) +
FROM_POUNDS(UserData->isImperial, liveFPayloadData->firstOfficer) +
FROM_POUNDS(UserData->isImperial, liveFPayloadData->engineer),
allocator);
livePayload.AddMember("upper1", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper1Left + liveFPayloadData->upper1Right), allocator);
livePayload.AddMember("upper2", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper2Left + liveFPayloadData->upper2Right), allocator);
livePayload.AddMember("upper3", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper3Left + liveFPayloadData->upper3Right), allocator);
livePayload.AddMember("upper4", FROM_POUNDS(UserData->isImperial, liveFPayloadData->upper4Left + liveFPayloadData->upper4Right), allocator);
livePayload.AddMember("lowerForward", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerForward), allocator);
livePayload.AddMember("lowerRear", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerRear), allocator);
}
// Pax only (converted to passengers)
else {
livePayload.AddMember("crew",
FROM_POUNDS(UserData->isImperial, livePaxPayloadData->pilot) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->firstOfficer) +
FROM_POUNDS(UserData->isImperial, livePaxPayloadData->engineer) + FROM_POUNDS(UserData->isImperial, livePaxPayloadData->cabinCrewFront) +
FROM_POUNDS(UserData->isImperial, livePaxPayloadData->cabinCrewRear),
allocator);
livePayload.AddMember("businnes1",
(short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->business1Left + livePaxPayloadData->business1Center +
livePaxPayloadData->business1Right) / PAX_WEIGHT(UserData->isImperial)),
allocator);
livePayload.AddMember("business2",
(short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->business2Left + livePaxPayloadData->business2Center +
livePaxPayloadData->business2Right) / PAX_WEIGHT(UserData->isImperial)),
allocator);
livePayload.AddMember("economy1",
(short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->economy1Left + livePaxPayloadData->economy1Center +
livePaxPayloadData->economy1Right) / PAX_WEIGHT(UserData->isImperial)),
allocator);
livePayload.AddMember("economy2",
(short)(FROM_POUNDS(UserData->isImperial, livePaxPayloadData->economy2Left + livePaxPayloadData->economy2Center +
livePaxPayloadData->economy2Right) / PAX_WEIGHT(UserData->isImperial)),
allocator);
livePayload.AddMember("forwardCargo", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->forwardCargo), allocator);
livePayload.AddMember("rearCargo", FROM_POUNDS(UserData->isImperial, livePaxPayloadData->rearCargo), allocator);
}
// CGs
calculateCGs(livePaxPayloadData, liveFuelData, &livePaxPayloadData->ZFWCG, &livePaxPayloadData->TOCG, true);
livePayload.AddMember("ZFWCG", UserData->isCargo ? liveFPayloadData->ZFWCG : livePaxPayloadData->ZFWCG, allocator);
livePayload.AddMember("TOCG", UserData->isCargo ? liveFPayloadData->ZFWCG : livePaxPayloadData->TOCG, allocator);
// Fuel
livePayload.AddMember("fuel", FROM_POUNDS(UserData->isImperial, liveFuelData->total), allocator);
#pragma endregion
#pragma region Target Payload
// OEW (empty + aux tank wgts)
targetPayload.AddMember("empty",
(UserData->isCargo ? targetFPayloadData->empty : targetPaxPayloadData->empty)+
(UserData->isCargo ? targetFPayloadData->leftAux : targetPaxPayloadData->leftAux) +
(UserData->isCargo ? targetFPayloadData->rightAux : targetPaxPayloadData->rightAux),
allocator);
// Cargo only
if (UserData->isCargo) {
targetPayload.AddMember("crew", targetFPayloadData->pilot + targetFPayloadData->firstOfficer + targetFPayloadData->engineer, allocator);
targetPayload.AddMember("upper1", targetFPayloadData->upper1Left + targetFPayloadData->upper1Right, allocator);
targetPayload.AddMember("upper2", targetFPayloadData->upper2Left + targetFPayloadData->upper2Right, allocator);
targetPayload.AddMember("upper3", targetFPayloadData->upper3Left + targetFPayloadData->upper3Right, allocator);
targetPayload.AddMember("upper4", targetFPayloadData->upper4Left + targetFPayloadData->upper4Right, allocator);
targetPayload.AddMember("lowerForward", targetFPayloadData->lowerForward, allocator);
targetPayload.AddMember("lowerRear", targetFPayloadData->lowerRear, allocator);
}
// Pax only (converted to passengers)
else {
targetPayload.AddMember("crew",
targetPaxPayloadData->pilot + targetPaxPayloadData->firstOfficer + targetPaxPayloadData->engineer +
targetPaxPayloadData->cabinCrewFront + targetPaxPayloadData->cabinCrewRear,
allocator);
targetPayload.AddMember("businnes1", targetPaxPayloadData->paxCount.business1, allocator);
targetPayload.AddMember("business2", targetPaxPayloadData->paxCount.business2, allocator);
targetPayload.AddMember("economy1", targetPaxPayloadData->paxCount.economy1, allocator);
targetPayload.AddMember("economy2", targetPaxPayloadData->paxCount.economy2, allocator);
targetPayload.AddMember("forwardCargo", targetPaxPayloadData->forwardCargo, allocator);
targetPayload.AddMember("rearCargo", targetPaxPayloadData->rearCargo, allocator);
}
// CGs
targetPayload.AddMember("ZFWCG", UserData->isCargo ? targetFPayloadData->ZFWCG : targetPaxPayloadData->ZFWCG, allocator);
targetPayload.AddMember("TOCG", UserData->isCargo ? targetFPayloadData->TOCG : targetPaxPayloadData->TOCG, allocator);
#pragma endregion
//TODO: Evaluate necessity of sending GSX data
// GSX
GSX.AddMember("boardingState", GSXData->boardingState, allocator);
GSX.AddMember("deboardingState", GSXData->deboardingState, allocator);
GSX.AddMember("passengersBoarded", GSXData->passengersBoarded, allocator);
GSX.AddMember("passengersDeboarded", GSXData->passengersDeboarded, allocator);
GSX.AddMember("cargoBoarded", GSXData->cargoBoarded, allocator);
GSX.AddMember("cargoDeboarded", GSXData->cargoDeboarded, allocator);
// Construct document
document.AddMember("livePayload", livePayload.Move(), allocator);
document.AddMember("targetPayload", targetPayload.Move(), allocator);
document.AddMember("GSX", GSX.Move(), allocator);
// Write to CommBus
document.Accept(writer);
fsCommBusCall(COMM_BUS_LIVE_DATA_EVENT, strbuf.GetString(), strbuf.GetSize(), FsCommBusBroadcast_JS);
}
// Logfile
void log(FILE* file, const char* format, void* optionalElement)
{
if (logFile != NULL)
{
fprintf(logFile, format, optionalElement);
fflush(logFile);
}
fprintf(file, format, optionalElement);
}
// SimConnect
void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) {
switch (pData->dwID) {
case SIMCONNECT_RECV_ID_SIMOBJECT_DATA: {
SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData;
switch (pObjData->dwRequestID) {
case DATA_REQUEST_EMPTY_WEIGHT: {
liveFPayloadData->empty = livePaxPayloadData->empty = *((double*)&pObjData->dwData);
sendTimer++;
break;
}
case DATA_REQUEST_PAYLOAD_F: {
fPayloadData_t* data = (fPayloadData_t*)&pObjData->dwData;
data->empty = liveFPayloadData->empty;
memcpy(liveFPayloadData, data, sizeof(fPayloadData_t));
sendTimer++;
break;
}
case DATA_REQUEST_PAYLOAD_PAX: {
paxPayloadData_t* data = (paxPayloadData_t*)&pObjData->dwData;
data->empty = livePaxPayloadData->empty;
memcpy(livePaxPayloadData, data, sizeof(paxPayloadData_t));
sendTimer++;
break;
}
case DATA_REQUEST_FUEL: {
FuelData_t* data = (FuelData_t*)&pObjData->dwData;
liveFuelData->main1 = data->main1 * data->poundsPerGallon;
liveFuelData->main3 = data->main3 * data->poundsPerGallon;
liveFuelData->main2 = data->main2 * data->poundsPerGallon;
liveFuelData->upperAux = data->upperAux * data->poundsPerGallon;
liveFuelData->lowerAux = data->lowerAux * data->poundsPerGallon;
liveFuelData->main1Tip = data->main1Tip * data->poundsPerGallon;
liveFuelData->main3Tip = data->main3Tip * data->poundsPerGallon;
liveFuelData->tail = data->tail * data->poundsPerGallon;
liveFuelData->forwardAux1 = data->forwardAux1 * data->poundsPerGallon;
liveFuelData->forwardAux2 = data->forwardAux2 * data->poundsPerGallon;
liveFuelData->total = liveFuelData->main1 + liveFuelData->main3 + liveFuelData->main2 + liveFuelData->upperAux +
liveFuelData->lowerAux + liveFuelData->main1Tip + liveFuelData->main3Tip + liveFuelData->tail +
liveFuelData->forwardAux1 + liveFuelData->forwardAux2;
sendTimer++;
break;
}
case DATA_REQUEST_GSX: {
GSXData_t* data = (GSXData_t*)&pObjData->dwData;
memcpy(GSXData, data, sizeof(GSXData_t));
sendTimer++;
break;
}
case DATA_REQUEST_USER_DATA: {
UserData_t* data = (UserData_t*)&pObjData->dwData;
data->isImperial = ((long)data->isImperial) & 1;
memcpy(UserData, data, sizeof(UserData_t));
sendTimer++;
break;
}
default: {
break;
}
}
// Send once every request "frame"
if (sendTimer == 6) {
sendData();
sendTimer = 0;
}
break;
}
case SIMCONNECT_RECV_ID_EXCEPTION:
{
SIMCONNECT_RECV_EXCEPTION* pEx = (SIMCONNECT_RECV_EXCEPTION*)pData;
log(stderr, MODULE_NAME"SimConnect Exception: %i\n", &pEx->dwException);
break;
}
default: {
break;
}
}
}