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,
171  "GENERAL ENG PCT MAX RPM:1", "percent");
172  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
173  "GENERAL ENG PCT MAX RPM:2", "percent");
174  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
175  "GENERAL ENG PCT MAX RPM:3", "percent");
176  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
177  "GENERAL ENG PCT MAX RPM:4", "percent");
178  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "VELOCITY WORLD X",
179  "Feet per second");
180  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "VELOCITY WORLD Y",
181  "Feet per second");
182  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft, "VELOCITY WORLD Z",
183  "Feet per second");
184  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
185  "ROTATION VELOCITY BODY X", "Radians per second");
186  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
187  "ROTATION VELOCITY BODY Y", "Radians per second");
188  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
189  "ROTATION VELOCITY BODY Z", "Radians per second");
190  // FS2020
191  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraft,
192  "INDICATED ALTITUDE CALIBRATED", "Feet");
193 
194  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE",
195  nullptr, SIMCONNECT_DATATYPE_STRING256);
196  if (isFailure(hr))
197  {
198  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr)).error(u"SimConnect error: initOwnAircraft %1")
199  << hr;
200  }
201  return hr;
202  }
203 
204  HRESULT CSimConnectDefinitions::initRemoteAircraft(const HANDLE hSimConnect)
205  {
206  HRESULT hr = s_ok();
207  // Position
208  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetPosition,
209  "Initial Position", nullptr, SIMCONNECT_DATATYPE_INITPOSITION);
210 
211  // Hint: "Bool" and "Percent .." are units name
212  // default data type is SIMCONNECT_DATATYPE_FLOAT64 -> double
213 
214  // Flaps
215  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
216  "LEADING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
217  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
218  "LEADING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
219  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
220  "TRAILING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
221  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
222  "TRAILING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
223 
224  // Gear & Spoiler
225  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
226  "GEAR HANDLE POSITION", "Bool");
227  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
228  "SPOILERS HANDLE POSITION", "Percent Over 100");
229 
230  // Engines
231  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
232  "GENERAL ENG COMBUSTION:1", "Bool");
233  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
234  "GENERAL ENG COMBUSTION:2", "Bool");
235  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
236  "GENERAL ENG COMBUSTION:3", "Bool");
237  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
238  "GENERAL ENG COMBUSTION:4", "Bool");
239  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
240  "GENERAL ENG THROTTLE LEVER POSITION:1", "percent");
241  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
242  "GENERAL ENG THROTTLE LEVER POSITION:2", "percent");
243  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
244  "GENERAL ENG THROTTLE LEVER POSITION:3", "percent");
245  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPartsWithoutLights,
246  "GENERAL ENG THROTTLE LEVER POSITION:4", "percent");
247 
248  // Lights (other definition)
249  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE",
250  nullptr, SIMCONNECT_DATATYPE_STRING256);
251 
252  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
253  "LIGHT STROBE", "Bool");
254  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
255  "LIGHT LANDING", "Bool");
256  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
257  "LIGHT TAXI", "Bool");
258  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
259  "LIGHT BEACON", "Bool");
260  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT NAV",
261  "Bool");
262  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
263  "LIGHT LOGO", "Bool");
264  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT NAV",
265  "Bool");
266  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
267  "LIGHT RECOGNITION", "Bool");
268  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights,
269  "LIGHT CABIN", "Bool");
270 
271  if (isFailure(hr))
272  {
273  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
274  .error(u"SimConnect error: initRemoteAircraftSituation %1")
275  << hr;
276  }
277  return hr;
278  }
279 
280  HRESULT CSimConnectDefinitions::initRemoteAircraftSimData(const HANDLE hSimConnect)
281  {
282  HRESULT hr = s_ok();
283  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
284  "PLANE LATITUDE", "degrees");
285  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
286  "PLANE LONGITUDE", "degrees");
287  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
288  "PLANE ALTITUDE", "Feet");
289  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
290  "GROUND ALTITUDE", "Feet");
291  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition,
292  "STATIC CG TO GROUND", "Feet");
293  if (isFailure(hr))
294  {
295  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
296  .error(u"SimConnect error: initRemoteAircraftSimData DataRemoteAircraftGetPosition %1")
297  << hr;
298  }
299 
300  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
301  "STATIC CG TO GROUND", "Feet");
302  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
303  "ATC TYPE", nullptr, SIMCONNECT_DATATYPE_STRING32);
304  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
305  "ATC MODEL", nullptr, SIMCONNECT_DATATYPE_STRING32);
306  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC ID",
307  nullptr, SIMCONNECT_DATATYPE_STRING32);
308  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
309  "ATC AIRLINE", nullptr, SIMCONNECT_DATATYPE_STRING64);
310  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData,
311  "ATC FLIGHT NUMBER", nullptr, SIMCONNECT_DATATYPE_STRING8);
312  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "TITLE",
313  nullptr, SIMCONNECT_DATATYPE_STRING256);
314  if (isFailure(hr))
315  {
316  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
317  .error(u"SimConnect error: initRemoteAircraftSimData DataRemoteAircraftModelData %1")
318  << hr;
319  }
320  return hr;
321  }
322 
323  HRESULT CSimConnectDefinitions::initRemoteAircraftSimDataSet(const HANDLE hSimConnect)
324  {
325  HRESULT hr = s_ok();
326 
327  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetData, "ATC ID",
328  nullptr, SIMCONNECT_DATATYPE_STRING32);
329  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetData,
330  "ATC AIRLINE", nullptr, SIMCONNECT_DATATYPE_STRING64);
331  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetData,
332  "ATC FLIGHT NUMBER", nullptr, SIMCONNECT_DATATYPE_STRING8);
333  if (isFailure(hr))
334  {
335  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
336  .error(u"SimConnect error: initRemoteAircraftSimDataSet DataRemoteAircraftModelData %1")
337  << hr;
338  }
339  return hr;
340  }
341 
342  HRESULT CSimConnectDefinitions::initSimulatorEnvironment(const HANDLE hSimConnect)
343  {
344  HRESULT hr = s_ok();
345  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "ZULU TIME", "",
346  SIMCONNECT_DATATYPE_INT32);
347  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment, "ZULU YEAR", "",
348  SIMCONNECT_DATATYPE_INT32);
349  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment,
350  "ZULU MONTH OF YEAR", "", SIMCONNECT_DATATYPE_INT32);
351  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataSimEnvironment,
352  "ZULU DAY OF MONTH", "", SIMCONNECT_DATATYPE_INT32);
353  if (isFailure(hr))
354  {
355  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
356  .error(u"SimConnect error: initSimulatorEnvironment %1")
357  << hr;
358  }
359  return hr;
360  }
361 
362  HRESULT CSimConnectDefinitions::initSbDataArea(const HANDLE hSimConnect)
363  {
364  HRESULT hr = s_ok();
365  const DWORD sbSize = sizeof(DataDefinitionClientAreaSb);
366 
367  // We need to know the client area 'name' and map it to a client ID
368  hr += SimConnect_MapClientDataNameToID(hSimConnect, "SquawkBox Data", ClientAreaSquawkBox);
369  if (isFailure(hr))
370  {
371  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
372  .error(u"SimConnect error: SimConnect_MapClientDataNameToID %1")
373  << hr;
374  return hr;
375  }
376 
377  // Mapping needs to be first
378  hr += SimConnect_CreateClientData(hSimConnect, ClientAreaSquawkBox, sbSize,
379  SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT);
380  if (isFailure(hr))
381  {
382  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
383  .error(u"SimConnect error: SimConnect_CreateClientData %1")
384  << hr;
385  return hr;
386  }
387 
388  // data definitions
389  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSb, 0,
390  sbSize); // whole area
391  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbStandby, 17,
392  1); // standby
393  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbIdent, 19,
394  1); // ident
395  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbConnected, 1,
396  1); // network connected
397  hr += SimConnect_AddToClientDataDefinition(hSimConnect, CSimConnectDefinitions::DataClientAreaSbRunning, 0,
398  1); // SB running
399 
400  if (isFailure(hr))
401  {
402  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
403  .error(u"SimConnect error: SB data area data definitions %1")
404  << hr;
405  return hr;
406  }
407 
408  // write a default client area so we are not suddenly squawking ident or so
409  DataDefinitionClientAreaSb sbArea;
410  byte sbRunning = 1;
411  sbArea.setDefaultValues();
412  hr += SimConnect_SetClientData(hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSb,
413  SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT, 0, sbSize, &sbArea);
414  hr +=
415  SimConnect_SetClientData(hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::DataClientAreaSbRunning,
416  SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT, 0, 1, &sbRunning);
417  if (isFailure(hr))
418  {
419  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
420  .error(u"SimConnect error: SimConnect_SetClientData %1")
421  << hr;
422  }
423  return hr;
424  }
425 
426  HRESULT CSimConnectDefinitions::initMSFSTransponder(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: MSFS transponder data definitions %1")
437  << hr;
438  }
439  return hr;
440  }
441 
442  HRESULT CSimConnectDefinitions::initMSFS2024Transponder(const HANDLE hSimConnect)
443  {
444  HRESULT hr = s_ok();
445  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
446  "TRANSPONDER STATE:1", "Enum");
447  hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
448  "TRANSPONDER IDENT:1", "Bool");
449  if (isFailure(hr))
450  {
451  CLogMessage(static_cast<CSimConnectDefinitions *>(nullptr))
452  .error(u"SimConnect error: MSFS2024 transponder data definitions %1")
453  << hr;
454  }
455  return hr;
456  }
457 
458  DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights()
459  {
460  this->resetToInvalid();
461  }
462 
463  DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights(
464  const CAircraftParts &parts)
465  {
466  this->initFromParts(parts);
467  }
468 
469  bool DataDefinitionRemoteAircraftPartsWithoutLights::operator==(
471  {
472  return std::tie(flapsLeadingEdgeLeftPercent, flapsLeadingEdgeRightPercent, flapsTrailingEdgeLeftPercent,
473  flapsTrailingEdgeRightPercent, gearHandlePosition, spoilersHandlePosition, engine1Combustion,
474  engine2Combustion, engine3Combustion, engine4Combustion) ==
478  rhs.engine4Combustion);
479  }
480 
481  void DataDefinitionRemoteAircraftPartsWithoutLights::setAllEngines(bool on, double engineRpmPct)
482  {
483  engine1Combustion = on ? 1 : 0;
484  engine2Combustion = on ? 1 : 0;
485  engine3Combustion = on ? 1 : 0;
486  engine4Combustion = on ? 1 : 0;
487  engine1RpmPct = engineRpmPct;
488  engine2RpmPct = engineRpmPct;
489  engine3RpmPct = engineRpmPct;
490  engine4RpmPct = engineRpmPct;
491  }
492 
493  void DataDefinitionRemoteAircraftPartsWithoutLights::setEngine(int number1based, bool on, double engineRpmPct)
494  {
495  double v = on ? 1.0 : 0.0;
496  switch (number1based)
497  {
498  case 1:
499  engine1Combustion = v;
500  engine1RpmPct = engineRpmPct;
501  break;
502  case 2:
503  engine2Combustion = v;
504  engine2RpmPct = engineRpmPct;
505  break;
506  case 3:
507  engine3Combustion = v;
508  engine3RpmPct = engineRpmPct;
509  break;
510  case 4:
511  engine4Combustion = v;
512  engine4RpmPct = engineRpmPct;
513  break;
514  default: break;
515  }
516  }
517 
518  void DataDefinitionRemoteAircraftPartsWithoutLights::resetAllFlaps()
519  {
520  flapsLeadingEdgeLeftPercent = 0.0;
521  flapsLeadingEdgeRightPercent = 0.0;
522  flapsTrailingEdgeLeftPercent = 0.0;
523  flapsTrailingEdgeRightPercent = 0.0;
524  }
525 
526  void DataDefinitionRemoteAircraftPartsWithoutLights::resetSpoilers() { spoilersHandlePosition = 0.0; }
527 
528  void DataDefinitionRemoteAircraftPartsWithoutLights::resetToInvalid()
529  {
530  flapsLeadingEdgeLeftPercent = -1;
531  flapsLeadingEdgeRightPercent = -1;
532  flapsTrailingEdgeLeftPercent = -1;
533  flapsTrailingEdgeRightPercent = -1;
534  gearHandlePosition = -1;
535  spoilersHandlePosition = -1;
536  engine1Combustion = -1;
537  engine2Combustion = -1;
538  engine3Combustion = -1;
539  engine4Combustion = -1;
540  engine1RpmPct = -1;
541  engine2RpmPct = -1;
542  engine3RpmPct = -1;
543  engine4RpmPct = -1;
544  }
545 
546  void DataDefinitionRemoteAircraftPartsWithoutLights::initFromParts(const CAircraftParts &parts)
547  {
548  gearHandlePosition = parts.isFixedGearDown() ? 1.0 : 0.0;
549  const double trail = parts.getFlapsPercent() / 100.0;
550  const double lead = trail;
551  flapsTrailingEdgeLeftPercent = trail;
552  flapsTrailingEdgeRightPercent = trail;
553  flapsLeadingEdgeLeftPercent = lead;
554  flapsLeadingEdgeRightPercent = lead;
555  spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
556  this->setAllEngines(false, 0.0); // init
557 
558  int e = 1;
559  for (const CAircraftEngine &engine : parts.getEngines())
560  {
561  this->setEngine(e++, engine.isOn(), engine.getEngineRpmPct());
562  }
563  }
564 
565  CAircraftLights DataDefinitionRemoteAircraftLights::toLights() const
566  {
567  return CAircraftLights(dtb(lightStrobe), dtb(lightLanding), dtb(lightTaxi), dtb(lightBeacon), dtb(lightNav),
568  dtb(lightLogo), dtb(lightRecognition), dtb(lightCabin));
569  }
570 
571  QString DataDefinitionClientAreaSb::toQString() const
572  {
573  return u"0 (running): " % QString::number(data[0]) % u" 1 (connected): " % QString::number(data[1]) %
574  u" 17 (standby): " % QString::number(data[17]) % u" 19 (ident): " % QString::number(data[19]);
575  }
576 
577 } // 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:261
QString number(double n, char format, int precision)
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.