Avionics
Dropship Simulator
Avionics.cpp
Go to the documentation of this file.
1 #define DIRECTINPUT_VERSION 0x0800
2 
3 
4 //--------------------------------------------------------------------------------------
5 // Includes
6 //--------------------------------------------------------------------------------------
7 #include "Config.h"
8 #include "Virtualization.h"
9 #include "Devices/Printer.h"
10 
11 #include <time.h>
12 
13 //--------------------------------------------------------------------------------------
14 // Global variables
15 //--------------------------------------------------------------------------------------
16 LPDIRECTINPUT8 g_pDI = nullptr;
20 std::vector<Module*> modules;
24 std::vector<Devices::InterfaceKit> ifKits;
25 std::vector<Devices::Analog> analogs;
26 std::vector<Devices::Encoder> encoders;
30 std::vector<Devices::Bass> audioDevices;
32 std::vector<Devices::Joystick> joysticks;
37 
38 
39 //--------------------------------------------------------------------------------------
40 // Forward declarations
41 //--------------------------------------------------------------------------------------
42 void FrameMove(double fTime, float fElapsedTime);
43 void InitApp(HINSTANCE hInstance);
44 void Teardown();
45 
46 
47 //--------------------------------------------------------------------------------------
48 // Entry point to the program. Initializes everything and goes into a message processing
49 // loop. Idle time is used to render the scene.
50 //--------------------------------------------------------------------------------------
51 int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
52 {
53  // Enable run-time memory check for debug builds.
54 #if defined(DEBUG) | defined(_DEBUG)
55  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_CRT_DF);
56  //_CrtSetBreakAlloc(3);
57 #endif
58 
59  ShowCursor(false);
60 
61  // more realistic random number generation
62  srand(static_cast<unsigned int>(time(nullptr)));
63 
64  config.Initialize(&logger, &modules, &bus, &viewport, lpCmdLine);
65 
66  InitApp(hInstance); // joystick.cpp and keyboard.cpp devices need HINSTANCE
67 
68  // Start the timer
69  CDXUTTimer Timer;
70  float fElapsedTime = 0.0f;
71  Timer.Start();
72  double fTime = Timer.GetTime();
73  int frameCount = 0;
74  float frameTime = 0.0f;
75 
76  // Now we're ready to receive and process Windows messages.
77  bool bGotMsg;
78  MSG msg;
79  msg.message = WM_NULL;
80  PeekMessage(&msg, nullptr, 0U, 0U, PM_NOREMOVE);
81 
82  while (WM_QUIT != msg.message)
83  {
84  // Use PeekMessage() so we can use idle time to render the scene.
85  bGotMsg = (PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE) != 0);
86 
87  if (bGotMsg)
88  {
89  // Translate and dispatch the message
90 // if (g_hWndPrimary == NULL ||
91 // 0 == TranslateAccelerator(g_hWndPrimary, NULL, &msg))
92  {
93  TranslateMessage(&msg);
94  DispatchMessage(&msg);
95  }
96  }
97  else
98  {
99  frameCount++;
100  frameTime += fElapsedTime;
101  if (frameTime > 1.0f)
102  {
103  bus.frameRate = static_cast<float>(frameCount) / frameTime;
104  frameTime = 0.0f;
105  frameCount = 0;
106  }
107 
108  FrameMove(fTime, fElapsedTime);
109 
110  // Render a frame during idle time (no messages are waiting)
112  viewport.Render(fElapsedTime);
113  }
114 
115  fTime = Timer.GetTime();
116  fElapsedTime = Timer.GetElapsedTime();
117  }
118 
119  Teardown();
120 
121  return 0;
122 }
123 
124 
125 //--------------------------------------------------------------------------------------
126 // Initialize the app
127 //--------------------------------------------------------------------------------------
128 void InitApp(HINSTANCE hInstance)
129 {
133 
134 #pragma region InterfaceKits
135  ifKits.resize(config.interfaceKitConfigs.size());
137  for (UINT i = 0; i < ifKits.size(); i++)
138  {
139  Devices::InterfaceKit* ifKit = &ifKits.at(i); // otherwise Doxygen doesn't see it!
140  ifKit->Initialize(&logger, &config.interfaceKitConfigs.at(i), &bus);
141  }
142 #pragma endregion
143 
144 #pragma region Encoders
145  encoders.resize(config.encoderConfigs.size());
147  for (UINT i = 0; i < encoders.size(); i++)
148  {
149  Devices::Encoder* encoder = &encoders.at(i); // otherwise Doxygen doesn't see it!
150  encoder->Initialize(&logger, &config.encoderConfigs.at(i), &bus);
151  }
152 #pragma endregion
153 
154 #pragma region Analogs
155  analogs.resize(config.analogConfigs.size());
157  for (UINT i = 0; i < analogs.size(); i++)
158  {
159  Devices::Analog* analog = &analogs.at(i); // otherwise Doxygen doesn't see it!
160  analog->Initialize(&logger, &config.analogConfigs.at(i), &bus);
161  }
162 #pragma endregion
163 
166 
169 
170 #pragma region Bass
171  audioDevices.resize(config.bassConfigs.size());
173  for (UINT i = 0; i < audioDevices.size(); i++)
174  {
175  Devices::Bass* bass = &audioDevices.at(i); // otherwise Doxygen doesn't see it!
176  bass->Initialize(&logger, &config.bassConfigs.at(i), &bus);
177 
179  for (UINT m = 0; m < modules.size(); m++)
180  {
181  if (typeid(*modules.at(m)) == typeid(Vmu))
182  {
183  if (config.bassConfigs.at(i).soundDevice == static_cast<Vmu*>(modules.at(m))->soundDevice)
184  {
185  static_cast<Vmu*>(modules.at(m))->Initialize(bass);
186  }
187  }
188  else if (typeid(*modules.at(m)) == typeid(Fadec))
189  {
190  if (config.bassConfigs.at(i).soundDevice == static_cast<Fadec*>(modules.at(m))->soundDevice)
191  {
192  static_cast<Fadec*>(modules.at(m))->Initialize(nullptr, bass);
193  }
194  }
197  else if (typeid(*modules.at(m)) == typeid(Ase))
198  {
199  if (config.bassConfigs.at(i).soundDevice == static_cast<Ase*>(modules.at(m))->soundDevice)
200  {
201  static_cast<Ase*>(modules.at(m))->Initialize(bass);
202  }
203  }
204  }
205  }
206 #pragma endregion
207 
208 #pragma region DirectInput
209  HRESULT hr;
212  if (FAILED(hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_pDI, NULL)))
213  {
214  logger.Log("InitApp DirectInput8Create failed!", Logger::Error, hr);
215  }
216  else
217  {
219  joysticks.resize(config.joystickConfigs.size());
220  for (UINT i = 0; i < joysticks.size(); i++)
221  {
222  Devices::Joystick* joystick = &joysticks.at(i); // otherwise Doxygen doesn't see it!
223  joystick->Initialize(&logger, &config.joystickConfigs.at(i), &bus, g_pDI);
224 
226  if (config.joystickConfigs.at(i).registerWithFcs)
227  {
228  for (UINT m = 0; m < modules.size(); m++)
229  {
230  if (typeid(*modules.at(m)) == typeid(Fcs))
231  {
232  static_cast<Fcs*>(modules.at(m))->Initialize(joystick);
233  }
234  }
235  }
236  if (config.joystickConfigs.at(i).enable && config.joystickConfigs.at(i).registerWithFadec)
237  {
238  for (UINT m = 0; m < modules.size(); m++)
239  {
240  if (typeid(*modules.at(m)) == typeid(Fadec))
241  {
242  static_cast<Fadec*>(modules.at(m))->Initialize(joystick, nullptr);
243  }
244  }
245  }
246  }
247 
249  }
250 #pragma endregion
251 
253 
255 
257  viewport.Initialize(hInstance);
259 
260  printer.Initialize(&logger, &bus, nullptr);
261 
262 
263 
264  Vehicle platform177;
265  platform177.location.x = -57.0f / 180.0f * 19012.290420994710720528225226931f;
266  platform177.location.y = 7.5f / 90.0f*9506.1452104973553602641126134654f;
267  platform177.location.z = -35.0f;
268  platform177.type = Vehicle::Platform;
269  platform177.VehicleId = "E177";
270  D3DXMatrixRotationX(&platform177.mBaseOrient, D3DX_PI); // now facing north
271  D3DXQuaternionRotationYawPitchRoll(&platform177.orientation, 0, 0, D3DXToRadian(-120.0f)); // left to 240
272  bus.vehicles.push_back(platform177);
273 
274  Vehicle platform419;
275  platform419.location.x = -57.0f / 180.0f * 19012.290420994710720528225226931f - 45.0f;
276  platform419.location.y = 7.5f / 90.0f*9506.1452104973553602641126134654f;
277  platform419.location.z = -35.0f;
278  platform419.type = Vehicle::Platform;
279  platform419.VehicleId = "E419";
280  D3DXMatrixRotationX(&platform419.mBaseOrient, D3DX_PI);
281  D3DXQuaternionRotationYawPitchRoll(&platform419.orientation, 0, 0, -D3DX_PI*0.5f); // left to 270, was north facing
282  bus.vehicles.push_back(platform419);
283 }
284 
285 
287 void Teardown()
288 {
289  viewport.Destroy();
290 
291  for (UINT i = 0; i < ifKits.size(); i++)
292  {
293  Devices::InterfaceKit* ifKit = &ifKits.at(i); // otherwise Doxygen misses it
294  ifKit->Destroy();
295  }
296 
297  for (UINT i = 0; i < encoders.size(); i++)
298  {
299  Devices::Encoder* encoder = &encoders.at(i); // otherwise Doxygen misses it
300  encoder->Destroy();
301  }
302 
303  for (UINT i = 0; i < analogs.size(); i++)
304  {
305  Devices::Analog* analog = &analogs.at(i); // otherwise Doxygen misses it
306  analog->Destroy();
307  }
308 
310  spatial.Destroy();
311 
313  teamSpeak.Destroy();
314 
315  for (UINT i = 0; i < audioDevices.size(); i++)
316  {
317  Devices::Bass* bass = &audioDevices.at(i); // otherwise Doxygen misses it
318  bass->Destroy();
319  }
320 
321 #pragma region Modules
322  for (std::vector<Module*>::iterator it = modules.begin(); it != modules.end(); ++it)
323  {
324  delete *it;
325  }
326 #pragma endregion
327 
328 #pragma region DirectInput
329  for (UINT i = 0; i < joysticks.size(); i++)
330  {
331  Devices::Joystick* joystick = &joysticks.at(i); // otherwise Doxygen misses it
332  joystick->Destroy();
333  }
334 
335  keyboard.Destroy();
336 
337  SAFE_RELEASE(g_pDI);
338 #pragma endregion
339 
340  webcam.Destroy();
341 }
342 
343 
344 //--------------------------------------------------------------------------------------
345 // Handle updates to the scene. This is called regardless of which D3D API is used
346 //--------------------------------------------------------------------------------------
347 void FrameMove(double fTime, float fElapsedTime)
348 {
349  Sleep(20);
350 
352  //static int cycle = 0;
353  //static float cycleLimit = 0.0f;
354  //cycleLimit += fElapsedTime;
355  //if (cycleLimit >= 0.2f)
356  //{
357  // cycleLimit -= 0.2f;
358  // cycle++;
359  // if (cycle > 4)
360  // cycle = 0;
361  //}
362 
363 
364  try
365  {
367  bus.FrameMove(fElapsedTime, fTime);
368 
369 #pragma region Inputs
371  {
372  ups.FrameMove(fElapsedTime);
373  }
374 
376  spatial.FrameMove(fElapsedTime);
377 
379  keyboard.FrameMove(fElapsedTime);
380 
381  for (UINT i = 0; i < joysticks.size(); i++)
382  {
383  Devices::Joystick* joystick = &joysticks.at(i); // otherwise Doxygen misses it
384  joystick->FrameMove(fElapsedTime);
385  }
386 
388  {
389  //if (cycle==2)
390  webcam.FrameMove();
391  }
392 
393  printer.FrameMove();
394 
395 
396 #pragma endregion
397 
398 #pragma region Other I/O
399  for (UINT i = 0; i < ifKits.size(); i++)
400  {
401  Devices::InterfaceKit* ifKit = &ifKits.at(i); // otherwise Doxygen misses it
402  ifKit->FrameMove();
403  }
404 
406  rakNet.FrameMove(fElapsedTime);
407 
410 
412  xplane.FrameMove();
413 
414 #pragma endregion
415 
416 #pragma region Modules (Input and Ouput to Data Bus)
417  for (UINT i = 0; i < modules.size(); i++)
418  {
419  Module* module = modules.at(i); // otherwise Doxygen doesn't see it!
420  module->FrameMove(fElapsedTime);
421  }
422 #pragma endregion
423 
424 #pragma region Outputs
425  for (UINT i = 0; i < analogs.size(); i++)
426  {
427  Devices::Analog* analog = &analogs.at(i); // otherwise Doxygen misses it
428  analog->FrameMove();
429  }
430 
431  for (UINT i = 0; i < audioDevices.size(); i++)
432  {
433  Devices::Bass* bass = &audioDevices.at(i); // otherwise Doxygen misses it
434  bass->FrameMove();
435  }
436 #pragma endregion
437 
438  static float lastErrorTime = 60.0f;
439  lastErrorTime += fElapsedTime;
440  if (logger.lastLevel == Logger::Level::Error || logger.lastLevel == Logger::Level::Fatal)
441  {
442  if (logger.lastError.find("SendEmail") == std::string::npos && lastErrorTime > 60.0f)
443  {
444  rakNet.SendEmail("Logged Error or Fatal", logger.lastError.c_str());
445  lastErrorTime = 0.0f;
446  }
447 
448  if (logger.lastLevel == Logger::Level::Fatal)
449  DXUTShutdown();
450 
452  }
453 
455  for (UINT i = 0; i < 10; i++)
456  virtualization.FrameMove(fTime); // can't send elapsed time unless we hit them all every frame!
457 
458  if (fElapsedTime > 3.0f)
459  {
460  char msg[99];
461  sprintf_s(msg, 99, "Program delay detected (%.3f)!", fElapsedTime);
462  logger.Log(msg, Logger::Warn);
463  }
464  }
465  catch (std::exception& e)
466  {
467  rakNet.SendEmail("OnFrameMove Exception", e.what());
468  logger.Log(e.what(), Logger::Level::Error);
469  Sleep(5000);
470  exit(0);
471  }
472 }
Viewport viewport
Definition: Avionics.cpp:21
Devices::Spatial spatial
Definition: Avionics.cpp:28
void InitApp(HINSTANCE hInstance)
Definition: Avionics.cpp:128
std::vector< HWND > GetWindowHandles() const
Definition: Viewport.cpp:570
void FrameMove() const
Definition: Analog.cpp:154
void SendEmail(std::string subject, std::string body="", int severity=0)
Definition: RakNet.cpp:197
Systems::Virtualization virtualization
Definition: Avionics.cpp:19
Flight Control System.
Definition: Module.h:80
Devices::TeamSpeak teamSpeak
Definition: Avionics.cpp:31
Devices::SpatialConfig spatialConfig
Definition: Config.h:35
void Destroy()
Definition: Webcam.cpp:864
Definition: Logger.h:5
void Initialize(Logger *logger, EncoderConfig *config, Bus *prmBus)
Definition: Encoder.cpp:298
std::vector< Devices::AnalogConfig > analogConfigs
Definition: Config.h:32
void Destroy() const
Definition: Analog.cpp:146
Devices::Xplane xplane
Definition: Avionics.cpp:35
void FrameMove()
Definition: BASS.cpp:69
void Render(float fElapsed)
Definition: Viewport.cpp:65
std::vector< Vehicle > vehicles
for TCAS, GPWS, FMS
Definition: Bus.h:366
LPDIRECTINPUT8 g_pDI
Definition: Avionics.cpp:16
std::string VehicleId
Definition: Vehicle.h:15
Level lastLevel
Definition: Logger.h:23
Bus bus
Definition: Avionics.cpp:18
void Initialize(Logger *prmLogger, TeamSpeakConfig *prmConfig, Bus *prmBus)
Definition: TeamSpeak.cpp:297
void FrameMove()
Definition: Viewport.h:51
Devices::TeamSpeakConfig teamSpeakConfig
Definition: Config.h:39
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
Definition: Avionics.cpp:51
void FrameMove(float fElapsed)
Definition: Spatial.cpp:180
void Initialize(HINSTANCE)
Definition: Viewport.cpp:9
Adaptive Scenario Engine.
Definition: Module.h:260
Config config
Definition: Avionics.cpp:22
void Initialize(Logger *logger, SpatialConfig *config, Bus *prmBus)
Definition: Spatial.cpp:108
void Initialize(Logger *, RakNetConfig *, Bus *)
Definition: RakNet.cpp:12
void Initialize(Logger *logger, AnalogConfig *config, Bus *prmBus)
Definition: Analog.cpp:83
D3DXVECTOR3 location
Definition: Vehicle.h:16
std::string lastError
Definition: Logger.h:22
void Initialize(Logger *logger, ApcupsdConfig *config, Bus *bus)
Definition: apcupsd.cpp:24
D3DXMATRIX mBaseOrient
Definition: Vehicle.h:18
void Destroy()
Definition: Viewport.cpp:532
std::vector< Devices::InterfaceKit > ifKits
Definition: Avionics.cpp:24
void FrameMove(float fElapsed)
Definition: Keyboard.cpp:84
Definition: Bus.h:12
Logger logger
Definition: Avionics.cpp:17
std::vector< Devices::Encoder > encoders
Definition: Avionics.cpp:26
virtual void FrameMove(float fElapsedTime)=0
Definition: Config.h:20
void FrameMove()
Definition: Printer.cpp:14
void Destroy() const
Definition: Encoder.cpp:347
void Destroy() const
Definition: Spatial.cpp:173
C++ monitoring implementation of http://www.apcupsd.org.
Definition: apcupsd.h:32
Devices::RakNet rakNet
Definition: Avionics.cpp:29
Devices::RakNetConfig rakNetConfig
Definition: Config.h:38
Devices::WebcamConfig webcamConfig
Definition: Config.h:42
Full Authority Digital Engine Control.
Definition: Module.h:107
void Initialize(Logger *logger, Bus *prmBus, HWND hWnd)
Definition: Printer.cpp:7
Devices::YouTubeConfig youTubeConfig
Definition: Config.h:41
Devices::ApcupsdConfig apcupsdConfig
Definition: Config.h:36
void Initialize(Logger *logger, std::vector< Module *> *modules, Bus *prmBus, Viewport *viewport, WCHAR *configFile)
Definition: Config.cpp:8
void FrameMove(float fElapsed, double fTime)
Definition: Bus.cpp:3
Abstract base class for modules By definition, instruments don&#39;t do any of the work (they don&#39;t modif...
Definition: Module.h:11
Devices::Printer printer
Definition: Avionics.cpp:36
void Destroy() const
Definition: TeamSpeak.cpp:531
void FrameMove(float fElapsed)
Definition: Joystick.cpp:181
std::vector< Module * > modules
Definition: Avionics.cpp:20
Voice Messaging Unit.
Definition: Module.h:61
void FrameMove(float)
Definition: RakNet.cpp:53
void SetWindowHandles(std::vector< HWND > prmHwnds)
Definition: Keyboard.h:75
void FrameMove() const
Definition: Xplane.cpp:44
Devices::XplaneConfig xplaneConfig
Definition: Config.h:43
void FrameMove(float fElapsed)
Definition: apcupsd.cpp:163
std::vector< Devices::InterfaceKitConfig > interfaceKitConfigs
Definition: Config.h:31
void Log(const char *msg, Level level=Info, int errorCode=0)
These have to be in this order.
Definition: Logger.cpp:16
float frameRate
Definition: Bus.h:35
void Initialize(Logger *logger, JoystickConfig *config, Bus *prmBus, LPDIRECTINPUT8 g_pDI)
Definition: Joystick.cpp:89
std::vector< Devices::Analog > analogs
Definition: Avionics.cpp:25
void Teardown()
clean-up memory (everything in InitApp)
Definition: Avionics.cpp:287
std::vector< Devices::EncoderConfig > encoderConfigs
Definition: Config.h:33
void FrameMove(double fTime)
std::vector< Devices::JoystickConfig > joystickConfigs
Definition: Config.h:40
void Initialize(Logger *, Bus *, YouTubeConfig *)
Definition: YouTube.cpp:16
void Initialize(Logger *logger, InterfaceKitConfig *config, Bus *prmBus)
std::vector< Devices::Bass > audioDevices
Definition: Avionics.cpp:30
void FrameMove(double fTime, float fElapsedTime)
Definition: Avionics.cpp:347
std::vector< Devices::BassConfig > bassConfigs
Definition: Config.h:37
void FrameMove()
Definition: Webcam.cpp:1012
void Initialize(Logger *prmLogger, BassConfig *prmConfig, Bus *prmBus)
Definition: BASS.cpp:19
Devices::KeyboardConfig keyboardConfig
Definition: Config.h:34
void Initialize(Logger *logger, KeyboardConfig *config, Bus *prmBus, LPDIRECTINPUT8 g_pDI)
Definition: Keyboard.cpp:19
Devices::YouTube youTube
Definition: Avionics.cpp:34
void Initialize(Logger *prmLogger, WebcamConfig *prmConfig, Bus *prmBus)
Definition: Webcam.cpp:670
Devices::Webcam webcam
Definition: Avionics.cpp:33
D3DXQUATERNION orientation
Definition: Vehicle.h:17
#define DIRECTINPUT_VERSION
Definition: Avionics.cpp:1
enum Vehicle::Types type
std::vector< Devices::Joystick > joysticks
Definition: Avionics.cpp:32
Devices::Apcupsd ups
Definition: Avionics.cpp:23
Definition: Vehicle.h:6
void Initialize(Logger *logger, XplaneConfig *config, Bus *prmBus)
Definition: Xplane.cpp:5
Devices::Keyboard keyboard
Definition: Avionics.cpp:27
void Destroy() const
Definition: BASS.cpp:110