swift
simconnectdatadefinition.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <tuple>
7 
8 #include <QStringBuilder>
9 
10 #include "../fscommon/simulatorfscommonfunctions.h"
11 #include "simconnectsymbols.h"
12 
15 #include "misc/logmessage.h"
16 
17 using namespace swift::misc;
18 using namespace swift::misc::aviation;
19 using namespace swift::misc::simulation;
20 using namespace swift::simplugin::fscommon;
21 
22 namespace swift::simplugin::fsxcommon
23 {
24  const QString &CSimConnectDefinitions::requestToString(Request request)
25  {
26  static const QString ownAircraft("RequestOwnAircraft");
27  static const QString title("RequestOwnAircraftTitle");
28  static const QString sbData("RequestSbData");
29  static const QString facility("RequestFacility");
30  static const QString end("<end>");
31  static const QString unknown("unknown");
32 
33  switch (request)
34  {
35  case RequestOwnAircraft: return ownAircraft;
36  case RequestOwnAircraftTitle: return title;
37  case RequestSbData: return sbData;
38  case RequestFacility: return facility;
39  case RequestEndMarker: return end;
40  default: break;
41  }
42  return unknown;
43  }
44 
45  const QString &CSimConnectDefinitions::simObjectRequestToString(SimObjectRequest simObjectRequest)
46  {
47  static const QString baseId("base id");
48  static const QString add("add");
49  static const QString remove("remove");
50  static const QString lights("lights");
51  static const QString pos("position");
52  static const QString model("model");
53  static const QString misc("misc");
54  static const QString end("<end>");
55  static const QString unknown("unknown");
56 
57  switch (simObjectRequest)
58  {
59  case SimObjectBaseId: return baseId;
60  case SimObjectAdd: return add;
61  case SimObjectRemove: return remove;
62  case SimObjectLights: return lights;
63  case SimObjectPositionData: return pos;
64  case SimObjectModel: return model;
65  case SimObjectMisc: return misc;
66  case SimObjectEndMarker: return end;
67  default: break;
68  }
69  return unknown;
70  }
71 
72  CSimConnectDefinitions::CSimConnectDefinitions() {}
73 
74  HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect,
75  const CSimulatorInfo &simInfo)
76  {
77  HRESULT hr = s_ok();
78  hr += initOwnAircraft(hSimConnect);
79  hr += initRemoteAircraft(hSimConnect);
80  hr += initRemoteAircraftSimData(hSimConnect);
81  hr += initRemoteAircraftSimDataSet(hSimConnect);
82  hr += initSimulatorEnvironment(hSimConnect);
83  hr += initSbDataArea(hSimConnect);
84  if (simInfo.isMSFS()) { hr += initMSFSTransponder(hSimConnect); }
85  if (simInfo.isMSFS2024()) { hr += initMSFS2024Transponder(hSimConnect); }
86  return hr;
87  }
88 
89  HRESULT CSimConnectDefinitions::initOwnAircraft(const HANDLE hSimConnect)
90  {
91  // FSX vars: https://docs.microsoft.com/en-us/previous-versions/microsoft-esp/cc526981(v%3dmsdn.10)
92  // all the VARS here should be FSX/P3D
93  HRESULT hr = s_ok();
94  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE LATITUDE",
95  "Degrees");
96  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE LONGITUDE",
97  "Degrees");
98  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE ALTITUDE",
99  "Feet");
100  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
101  "PLANE ALT ABOVE GROUND", "Feet");
102  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PRESSURE ALTITUDE",
103  "Meters");
104  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
105  "STATIC CG TO GROUND", "Feet");
106  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
107  "PLANE HEADING DEGREES TRUE", "Degrees");
108  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
109  "PLANE PITCH DEGREES", "Degrees");
110  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "PLANE BANK DEGREES",
111  "Degrees");
112  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND VELOCITY",
113  "Knots");
114  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "GROUND ALTITUDE",
115  "Feet");
116  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "SIM ON GROUND",
117  "Bool");
118  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT STROBE",
119  "Bool");
120  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT LANDING",
121  "Bool");
122  hr +=
123  SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT TAXI", "Bool");
124  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT BEACON",
125  "Bool");
126  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT NAV", "Bool");
127  hr +=
128  SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "LIGHT LOGO", "Bool");
129  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "TRANSPONDER CODE:1",
130  nullptr);
131  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
132  "COM ACTIVE FREQUENCY:1", "MHz");
133  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
134  "COM ACTIVE FREQUENCY:2", "MHz");
135  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
136  "COM STANDBY FREQUENCY:1", "MHz");
137  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
138  "COM STANDBY FREQUENCY:2", "MHz");
139  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM TRANSMIT:1",
140  "Bool");
141  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM TRANSMIT:2",
142  "Bool");
143  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM RECEIVE ALL",
144  "Bool");
145  hr +=
146  SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM TEST:1", "Bool");
147  hr +=
148  SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM TEST:2", "Bool");
149  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM STATUS:1",
150  "Enum");
151  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "COM STATUS:2",
152  "Enum");
153  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
154  "FLAPS HANDLE PERCENT", "Percent Over 100");
155  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
156  "SPOILERS HANDLE POSITION", "Percent Over 100");
157  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
158  "GEAR HANDLE POSITION", "Bool");
159  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "NUMBER OF ENGINES",
160  "Number");
161  // Simconnect supports index 1 - 4
162  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
163  "GENERAL ENG COMBUSTION:1", "Bool");
164  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
165  "GENERAL ENG COMBUSTION:2", "Bool");
166  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
167  "GENERAL ENG COMBUSTION:3", "Bool");
168  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
169  "GENERAL ENG COMBUSTION:4", "Bool");
170  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "VELOCITY WORLD X",
171  "Feet per second");
172  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "VELOCITY WORLD Y",
173  "Feet per second");
174  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "VELOCITY WORLD Z",
175  "Feet per second");
176  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
177  "ROTATION VELOCITY BODY X", "Radians per second");
178  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
179  "ROTATION VELOCITY BODY Y", "Radians per second");
180  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
181  "ROTATION VELOCITY BODY Z", "Radians per second");
182  // FS2020
183  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
184  "INDICATED ALTITUDE CALIBRATED", "Feet");
185 
186  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE",
187  nullptr, SIMCONNECT_DATATYPE_STRING256);
188  if (isFailure(hr))
189  {
190  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error(u"SimConnect error: initOwnAircraft %1")
191  << hr;
192  }
193  return hr;
194  }
195 
196  HRESULT CSimConnectDefinitions::initRemoteAircraft(const HANDLE hSimConnect)
197  {
198  HRESULT hr = s_ok();
199  // Position
200  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetPosition,
201  "Initial Position", nullptr, SIMCONNECT_DATATYPE_INITPOSITION);
202 
203  // Hint: "Bool" and "Percent .." are units name
204  // default data type is SIMCONNECT_DATATYPE_FLOAT64 -> double
205 
206  // Flaps
207  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
208  "LEADING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
209  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
210  "LEADING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
211  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
212  "TRAILING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
213  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
214  "TRAILING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
215 
216  // Gear & Spoiler
217  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
218  "GEAR HANDLE POSITION", "Bool");
219  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
220  "SPOILERS HANDLE POSITION", "Percent Over 100");
221 
222  // Engines
223  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
224  "GENERAL ENG COMBUSTION:1", "Bool");
225  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
226  "GENERAL ENG COMBUSTION:2", "Bool");
227  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
228  "GENERAL ENG COMBUSTION:3", "Bool");
229  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
230  "GENERAL ENG COMBUSTION:4", "Bool");
231 
232  // Lights (other definition)
233  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE",
234  nullptr, SIMCONNECT_DATATYPE_STRING256);
235 
236  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
237  "LIGHT STROBE", "Bool");
238  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
239  "LIGHT LANDING", "Bool");
240  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
241  "LIGHT TAXI", "Bool");
242  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
243  "LIGHT BEACON", "Bool");
244  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT NAV",
245  "Bool");
246  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
247  "LIGHT LOGO", "Bool");
248  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT NAV",
249  "Bool");
250  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
251  "LIGHT RECOGNITION", "Bool");
252  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
253  "LIGHT CABIN", "Bool");
254 
255  if (isFailure(hr))
256  {
257  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
258  .error(u"SimConnect error: initRemoteAircraftSituation %1")
259  << hr;
260  }
261  return hr;
262  }
263 
264  HRESULT CSimConnectDefinitions::initRemoteAircraftSimData(const HANDLE hSimConnect)
265  {
266  HRESULT hr = s_ok();
267  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
268  "PLANE LATITUDE", "degrees");
269  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
270  "PLANE LONGITUDE", "degrees");
271  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
272  "PLANE ALTITUDE", "Feet");
273  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
274  "GROUND ALTITUDE", "Feet");
275  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
276  "STATIC CG TO GROUND", "Feet");
277  if (isFailure(hr))
278  {
279  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
280  .error(u"SimConnect error: initRemoteAircraftSimData DataRemoteAircraftGetPosition %1")
281  << hr;
282  }
283 
284  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
285  "STATIC CG TO GROUND", "Feet");
286  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
287  "ATC TYPE", nullptr, SIMCONNECT_DATATYPE_STRING32);
288  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
289  "ATC MODEL", nullptr, SIMCONNECT_DATATYPE_STRING32);
290  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC ID",
291  nullptr, SIMCONNECT_DATATYPE_STRING32);
292  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
293  "ATC AIRLINE", nullptr, SIMCONNECT_DATATYPE_STRING64);
294  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
295  "ATC FLIGHT NUMBER", nullptr, SIMCONNECT_DATATYPE_STRING8);
296  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "TITLE",
297  nullptr, SIMCONNECT_DATATYPE_STRING256);
298  if (isFailure(hr))
299  {
300  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
301  .error(u"SimConnect error: initRemoteAircraftSimData DataRemoteAircraftModelData %1")
302  << hr;
303  }
304  return hr;
305  }
306 
307  HRESULT CSimConnectDefinitions::initRemoteAircraftSimDataSet(const HANDLE hSimConnect)
308  {
309  HRESULT hr = s_ok();
310 
311  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetData, "ATC ID",
312  nullptr, SIMCONNECT_DATATYPE_STRING32);
313  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetData,
314  "ATC AIRLINE", nullptr, SIMCONNECT_DATATYPE_STRING64);
315  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetData,
316  "ATC FLIGHT NUMBER", nullptr, SIMCONNECT_DATATYPE_STRING8);
317  if (isFailure(hr))
318  {
319  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
320  .error(u"SimConnect error: initRemoteAircraftSimDataSet DataRemoteAircraftModelData %1")
321  << hr;
322  }
323  return hr;
324  }
325 
326  HRESULT CSimConnectDefinitions::initSimulatorEnvironment(const HANDLE hSimConnect)
327  {
328  HRESULT hr = s_ok();
329  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "ZULU TIME", "",
330  SIMCONNECT_DATATYPE_INT32);
331  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "ZULU YEAR", "",
332  SIMCONNECT_DATATYPE_INT32);
333  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment,
334  "ZULU MONTH OF YEAR", "", SIMCONNECT_DATATYPE_INT32);
335  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment,
336  "ZULU DAY OF MONTH", "", SIMCONNECT_DATATYPE_INT32);
337  if (isFailure(hr))
338  {
339  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
340  .error(u"SimConnect error: initSimulatorEnvironment %1")
341  << hr;
342  }
343  return hr;
344  }
345 
346  HRESULT CSimConnectDefinitions::initSbDataArea(const HANDLE hSimConnect)
347  {
348  HRESULT hr = s_ok();
349  const DWORD sbSize = sizeof(DataDefinitionClientAreaSb);
350 
351  // We need to know the client area 'name' and map it to a client ID
352  hr += SimConnect_MapClientDataNameToID(hSimConnect, "SquawkBox Data", ClientAreaSquawkBox);
353  if (isFailure(hr))
354  {
355  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
356  .error(u"SimConnect error: SimConnect_MapClientDataNameToID %1")
357  << hr;
358  return hr;
359  }
360 
361  // Mapping needs to be first
362  hr += SimConnect_CreateClientData(hSimConnect, ClientAreaSquawkBox, sbSize,
363  SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT);
364  if (isFailure(hr))
365  {
366  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
367  .error(u"SimConnect error: SimConnect_CreateClientData %1")
368  << hr;
369  return hr;
370  }
371 
372  // data definitions
373  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSb, 0,
374  sbSize); // whole area
375  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbStandby, 17,
376  1); // standby
377  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbIdent, 19,
378  1); // ident
379  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbConnected, 1,
380  1); // network connected
381  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbRunning, 0,
382  1); // SB running
383 
384  if (isFailure(hr))
385  {
386  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
387  .error(u"SimConnect error: SB data area data definitions %1")
388  << hr;
389  return hr;
390  }
391 
392  // write a default client area so we are not suddenly squawking ident or so
393  DataDefinitionClientAreaSb sbArea;
394  byte sbRunning = 1;
395  sbArea.setDefaultValues();
396  hr += SimConnect_SetClientData(hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSb,
397  SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT, 0, sbSize, &sbArea);
398  hr +=
399  SimConnect_SetClientData(hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbRunning,
400  SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT, 0, 1, &sbRunning);
401  if (isFailure(hr))
402  {
403  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
404  .error(u"SimConnect error: SimConnect_SetClientData %1")
405  << hr;
406  }
407  return hr;
408  }
409 
410  HRESULT CSimConnectDefinitions::initMSFSTransponder(const HANDLE hSimConnect)
411  {
412  HRESULT hr = s_ok();
413  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
414  "TRANSPONDER STATE:1", "Enum");
415  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
416  "TRANSPONDER IDENT:1", "Bool");
417  if (isFailure(hr))
418  {
419  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
420  .error(u"SimConnect error: MSFS transponder data definitions %1")
421  << hr;
422  }
423  return hr;
424  }
425 
426  HRESULT CSimConnectDefinitions::initMSFS2024Transponder(const HANDLE hSimConnect)
427  {
428  HRESULT hr = s_ok();
429  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
430  "TRANSPONDER STATE:1", "Enum");
431  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
432  "TRANSPONDER IDENT:1", "Bool");
433  if (isFailure(hr))
434  {
435  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
436  .error(u"SimConnect error: MSFS2024 transponder data definitions %1")
437  << hr;
438  }
439  return hr;
440  }
441 
442  DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights()
443  {
444  this->resetToInvalid();
445  }
446 
447  DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights(
448  const CAircraftParts &parts)
449  {
450  this->initFromParts(parts);
451  }
452 
453  bool DataDefinitionRemoteAircraftPartsWithoutLights::operator==(
455  {
456  return std::tie(flapsLeadingEdgeLeftPercent, flapsLeadingEdgeRightPercent, flapsTrailingEdgeLeftPercent,
457  flapsTrailingEdgeRightPercent, gearHandlePosition, spoilersHandlePosition, engine1Combustion,
458  engine2Combustion, engine3Combustion, engine4Combustion) ==
462  rhs.engine4Combustion);
463  }
464 
465  void DataDefinitionRemoteAircraftPartsWithoutLights::setAllEngines(bool on)
466  {
467  engine1Combustion = on ? 1 : 0;
468  engine2Combustion = on ? 1 : 0;
469  engine3Combustion = on ? 1 : 0;
470  engine4Combustion = on ? 1 : 0;
471  }
472 
473  void DataDefinitionRemoteAircraftPartsWithoutLights::setEngine(int number1based, bool on)
474  {
475  double v = on ? 1.0 : 0.0;
476  switch (number1based)
477  {
478  case 1: engine1Combustion = v; break;
479  case 2: engine2Combustion = v; break;
480  case 3: engine3Combustion = v; break;
481  case 4: engine4Combustion = v; break;
482  default: break;
483  }
484  }
485 
486  void DataDefinitionRemoteAircraftPartsWithoutLights::resetAllFlaps()
487  {
488  flapsLeadingEdgeLeftPercent = 0.0;
489  flapsLeadingEdgeRightPercent = 0.0;
490  flapsTrailingEdgeLeftPercent = 0.0;
491  flapsTrailingEdgeRightPercent = 0.0;
492  }
493 
494  void DataDefinitionRemoteAircraftPartsWithoutLights::resetSpoilers() { spoilersHandlePosition = 0.0; }
495 
496  void DataDefinitionRemoteAircraftPartsWithoutLights::resetToInvalid()
497  {
498  flapsLeadingEdgeLeftPercent = -1;
499  flapsLeadingEdgeRightPercent = -1;
500  flapsTrailingEdgeLeftPercent = -1;
501  flapsTrailingEdgeRightPercent = -1;
502  gearHandlePosition = -1;
503  spoilersHandlePosition = -1;
504  engine1Combustion = -1;
505  engine2Combustion = -1;
506  engine3Combustion = -1;
507  engine4Combustion = -1;
508  }
509 
510  void DataDefinitionRemoteAircraftPartsWithoutLights::initFromParts(const CAircraftParts &parts)
511  {
512  gearHandlePosition = parts.isFixedGearDown() ? 1.0 : 0.0;
513  const double trail = parts.getFlapsPercent() / 100.0;
514  const double lead = trail;
515  flapsTrailingEdgeLeftPercent = trail;
516  flapsTrailingEdgeRightPercent = trail;
517  flapsLeadingEdgeLeftPercent = lead;
518  flapsLeadingEdgeRightPercent = lead;
519  spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
520  this->setAllEngines(false); // init
521 
522  int e = 1;
523  for (const CAircraftEngine &engine : parts.getEngines()) { this->setEngine(e++, engine.isOn()); }
524  }
525 
526  CAircraftLights DataDefinitionRemoteAircraftLights::toLights() const
527  {
528  return CAircraftLights(dtb(lightStrobe), dtb(lightLanding), dtb(lightTaxi), dtb(lightBeacon), dtb(lightNav),
529  dtb(lightLogo), dtb(lightRecognition), dtb(lightCabin));
530  }
531 
532  QString DataDefinitionClientAreaSb::toQString() const
533  {
534  return u"0 (running): " % QString::number(data[0]) % u" 1 (connected): " % QString::number(data[1]) %
535  u" 17 (standby): " % QString::number(data[17]) % u" 19 (ident): " % QString::number(data[19]);
536  }
537 
538 } // namespace swift::simplugin::fsxcommon
Class for emitting a log message.
Definition: logmessage.h:27
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Value object encapsulating information about aircraft's engines.
Value object encapsulating information about aircraft's lights.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
bool isSpoilersOut() const
Are spoilers out?
bool isFixedGearDown() const
Is fixed gear down?
int getFlapsPercent() const
Get flaps position in percent.
CAircraftEngineList getEngines() const
Get engines.
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
SimObjectRequest
SimObject requests used for AI aircraft and probes.
Free functions in swift::misc.
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:338
unsigned long DWORD
Fake Windows DWORD.
HRESULT s_ok()
Correctly casted values/checks.
bool isFailure(HRESULT result)
Correctly casted values/checks.
bool dtb(double doubleBool)
Correctly casted values/checks.