Rise
The Vieneo Province
GameClass.cpp
Go to the documentation of this file.
1 #include "GameClass.h"
2 
3 #include <Dbt.h>
4 #include <ctime>
5 #include <VersionHelpers.h>
6 
7 #include "SDKmisc.h" // For DXUTDisplaySwitchingToREFWarning
8 
11 
12 #define GUID_DEVINTERFACE_USB_DEVICE {0x4d1e55b2, 0xf16f, 0x11cf,{ 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}}
13 /* A5DCBF10-6530-11D2-901F-00C04FB951ED */
14 
16 {
17  logger = new Logger();
18  logger->AddToCallStack("GameClass::ctor");
19 
20  config = Config();
21  SecureZeroMemory(vphelp, vphelpC);
22 
23  networking = new Networking(this);
25 
26  sound = new Sound(this);
27 
28  GUI = new HMI(this, networking, sound);
29  GUI->LoadLanguage();
30 
31  graphics = new Graphics(GUI);
32  bus = new Bus(logger);
33  viewscreen = new Viewscreen(this);
34  displays = new Displays(logger, bus, GUI);
36 
37  // Back in the Dropship days these were sourced from XML configuration
38  modules.emplace_back(new Cas(bus, logger, sound));
39  modules.emplace_back(new IceDetector(bus, logger));
40  modules.emplace_back(new Gpws(bus, logger));
41  modules.emplace_back(new Vmu(bus, logger, sound));
43  modules.emplace_back(new TCAS(bus, logger, &viewscreen->matrixView));
44 
46 }
47 
49 {
50  logger->AddToCallStack("GameClass::dtor");
51 
52  // make sure we have no unlreased resources
53 
54  SAFE_DELETE(discord);
55  // displays has untracked resources that he manages... this is what got us in trouble with OnLostDevice failing to Reset
56  SAFE_DELETE(displays);
57  SAFE_DELETE(bus);
58  SAFE_DELETE(viewscreen);
59  SAFE_DELETE(graphics);
60  SAFE_DELETE(GUI);
61  SAFE_DELETE(sound);
62  SAFE_DELETE(networking);
63  SAFE_DELETE(logger);
64 
65  for (size_t i = 0; i < modules.size(); i++)
66  SAFE_DELETE(modules.at(i));
67  modules.clear();
68 }
69 
70 // ReSharper disable once CppMemberFunctionMayBeConst
71 // Can not be const because of the debug mode
73 {
74  logger->AddToCallStack("GameClass::Close");
75 
76  if (!UnregisterDeviceNotification(dev_notify))
77  logger->Log("UnregisterDeviceNotification failed!", Logger::Error);
78 
79 #ifdef _DEBUG
80  vpfmTimer->Report("Frame Move (Viewscreen)");
81  SAFE_DELETE(vpfmTimer);
82  viewscreen->cockpitFrameMoveTimer->Report(" Frame Move (Viewscreen->Cockpit)");
83  SAFE_DELETE(viewscreen->cockpitFrameMoveTimer);
84  viewscreen->instrumentsFrameMoveTimer->Report(" Frame Move (Viewscreen->Instruments)");
85  SAFE_DELETE(viewscreen->instrumentsFrameMoveTimer);
86  viewscreen->weatherFrameMoveTimer->Report(" Frame Move (Viewscreen->Weather)");
87  SAFE_DELETE(viewscreen->weatherFrameMoveTimer);
88  viewscreen->modulesFrameMoveTimer->Report(" Frame Move (Viewscreen->Modules)");
89  SAFE_DELETE(viewscreen->modulesFrameMoveTimer);
90  viewscreen->displaysFrameMoveTimer->Report(" Frame Move (Viewscreen->Displays)");
91  SAFE_DELETE(viewscreen->displaysFrameMoveTimer);
92  viewscreen->inputFrameMoveTimer->Report(" Frame Move (Viewscreen->Input)");
93  SAFE_DELETE(viewscreen->inputFrameMoveTimer);
94  viewscreen->weaponsFrameMoveTimer->Report(" Frame Move (Viewscreen->Weapons)");
95  SAFE_DELETE(viewscreen->weaponsFrameMoveTimer);
96  viewscreen->propulsionFrameMoveTimer->Report(" Frame Move (Viewscreen->Propulsion)");
97  SAFE_DELETE(viewscreen->propulsionFrameMoveTimer);
98  viewscreen->otherFrameMoveTimer->Report(" Frame Move (Viewscreen->Other)");
99  SAFE_DELETE(viewscreen->otherFrameMoveTimer);
100  uifmTimer->Report("Frame Move (GUI)");
101  SAFE_DELETE(uifmTimer);
102  otfmTimer->Report("Frame Move (Other)");
103  SAFE_DELETE(otfmTimer);
104  vpfrTimer->Report("Frame Render (Viewscreen)");
105  SAFE_DELETE(vpfrTimer);
106  viewscreen->cityTimer->Report(" Frame Render (Viewscreen->City)");
107  SAFE_DELETE(viewscreen->cityTimer);
108  viewscreen->shipTimer->Report(" Frame Render (Viewscreen->Ship)");
109  SAFE_DELETE(viewscreen->shipTimer);
110  viewscreen->liteTimer->Report(" Frame Render (Viewscreen->Lite)");
111  SAFE_DELETE(viewscreen->liteTimer);
112  uifrTimer->Report("Frame Render (GUI)");
113  SAFE_DELETE(uifrTimer);
114  otfrTimer->Report("Frame Render (Other)");
115  SAFE_DELETE(otfrTimer);
116 #endif
117 
118  if (displaystage == GameState::STATUS_GAME) // keep from saving before initialized, does its own logging
120 
121  networking->Close();
122  sound->Close();
123 }
124 
126 {
127  bus->Scanner.Reset();
128  for (int i = 0; i < MAX_SCAN; i++)
129  playerships[i].align = 1;
130 }
131 
133 {
134  SClientPacket outpacket; // NOLINT
135  outpacket.type = 36; // new scanner
136  outpacket.f_x = 1.0f; // request all data
137  outpacket.f_y = 0.0f; // NULL
138  outpacket.f_z = 0.0f; // NULL
139  outpacket.f_w = 0.0f; // vehicle ID unused for request all data
140  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
141 }
142 
143 void GameClass::TouchFile(const WCHAR* str)
144 {
145 #if defined(_DEBUG) && defined(_TOUCHFILES)
146  // touch file so we know what the hell is real!
147  HANDLE handle;
148  handle = CreateFile(str, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
149  if (handle == INVALID_HANDLE_VALUE)
150  {
151  logger->Log("Bailing out in LoadSound trying to CreateFile: INVALID_HANDLE_VALUE @1", Logger::Level::Error);
152  }
153  SYSTEMTIME st;
154  GetSystemTime(&st);
155  FILETIME ft;
156  if (!SystemTimeToFileTime(&st, &ft))
157  {
158  logger->Log("Bailing out in LoadSound trying to CreateFile @1", Logger::Level::Error);
159  }
160  if (!SetFileTime(handle, nullptr, nullptr, &ft))
161  {
162  logger->Log("Bailing out in LoadSound trying to SetFileTime @1", Logger::Level::Error);
163  }
164  CloseHandle(handle);
165 #endif
166 }
167 
169 {
170  if (ourcockpit.vdat.clengine > -1)
171  ourcockpit.vdat.clengine = 127;
172  if (ourcockpit.vdat.elevator > -1)
173  ourcockpit.vdat.elevator = 127;
174  if (ourcockpit.vdat.hulllight > -1)
175  ourcockpit.vdat.hulllight = 127;
176  // ourcockpit.vdat.inertialdamp=0;
177  if (ourcockpit.vdat.landing[0] > -1)
178  ourcockpit.vdat.landing[0] = 127;
179  if (ourcockpit.vdat.landing[1] > -1)
180  ourcockpit.vdat.landing[1] = 127;
181  if (ourcockpit.vdat.leftaileron > -1)
182  ourcockpit.vdat.leftaileron = 127;
183  if (ourcockpit.vdat.leftengine > -1)
184  ourcockpit.vdat.leftengine = 127;
185  if (ourcockpit.vdat.leftwing > -1)
186  ourcockpit.vdat.leftwing = 127;
187  // ourcockpit.vdat.logotype=0;
188  if (ourcockpit.vdat.monitor[0] > -1)
189  ourcockpit.vdat.monitor[0] = 127;
190  if (ourcockpit.vdat.monitor[1] > -1)
191  ourcockpit.vdat.monitor[1] = 127;
192  if (ourcockpit.vdat.monitor[2] > -1)
193  ourcockpit.vdat.monitor[2] = 127;
194  if (ourcockpit.vdat.monitor[3] > -1)
195  ourcockpit.vdat.monitor[3] = 127;
196  if (ourcockpit.vdat.monitor[4] > -1)
197  ourcockpit.vdat.monitor[4] = 127;
198  if (ourcockpit.vdat.monitor[5] > -1)
199  ourcockpit.vdat.monitor[5] = 127;
200  if (ourcockpit.vdat.monitor[6] > -1)
201  ourcockpit.vdat.monitor[6] = 127;
202  if (ourcockpit.vdat.overhead > -1)
203  ourcockpit.vdat.overhead = 127;
204  // ourcockpit.vdat.paintr=255;
205  // ourcockpit.vdat.paintg=255;
206  // ourcockpit.vdat.paintb=255;
207  if (ourcockpit.vdat.rcs > -1)
208  ourcockpit.vdat.rcs = 127;
209  if (ourcockpit.vdat.rightaileron > -1)
210  ourcockpit.vdat.rightaileron = 127;
211  if (ourcockpit.vdat.rightengine > -1)
212  ourcockpit.vdat.rightengine = 127;
213  if (ourcockpit.vdat.rightwing > -1)
214  ourcockpit.vdat.rightwing = 127;
215  if (ourcockpit.vdat.rudder > -1)
216  ourcockpit.vdat.rudder = 127;
217  // if (ourcockpit.vdat.scanners>-1)
218  // ourcockpit.vdat.scanners=127;
219  if (ourcockpit.vdat.struts[0] > -1)
220  ourcockpit.vdat.struts[0] = 127;
221  if (ourcockpit.vdat.vtail > -1)
222  ourcockpit.vdat.vtail = 127;
223  if (ourcockpit.vdat.htail > -1)
224  ourcockpit.vdat.htail = 127;
225  // ourcockpit.vdat.tgd
226  if (ourcockpit.vdat.thrustaug > -1)
227  ourcockpit.vdat.thrustaug = 127;
228  // ourcockpit.vdat.weapontype
229  if (ourcockpit.vdat.windshield > -1)
230  ourcockpit.vdat.windshield = 127;
231  if (ourcockpit.vdat.yawdamper > -1)
232  ourcockpit.vdat.yawdamper = 127;
233 
234  if (ourcockpit.vdat.baydoor > -1)
235  ourcockpit.vdat.baydoor = 127;
236  if (ourcockpit.vdat.flapsLE > -1)
237  ourcockpit.vdat.flapsLE = 127;
238  if (ourcockpit.vdat.flapsTE > -1)
239  ourcockpit.vdat.flapsTE = 127;
240  if (ourcockpit.vdat.parkingBrake > -1)
241  ourcockpit.vdat.parkingBrake = 127;
242  if (ourcockpit.vdat.leftBrake > -1)
243  ourcockpit.vdat.leftBrake = 127;
244  if (ourcockpit.vdat.rightBrake > -1)
245  ourcockpit.vdat.rightBrake = 127;
246  if (ourcockpit.vdat.antiIce > -1)
247  ourcockpit.vdat.antiIce = 127;
248  if (ourcockpit.vdat.biolock > -1)
249  ourcockpit.vdat.biolock = 127;
250  if (ourcockpit.vdat.steering > -1)
251  ourcockpit.vdat.steering = 127;
252  if (ourcockpit.vdat.vpt > -1)
253  ourcockpit.vdat.vpt = 127;
254 
255  ourcockpit.vdatChanged = true;
256 
257  bus->ComponentRcsRollFail = false;
258  bus->ComponentFcsRollFail = false;
259 }
260 
262 {
263  if (GUI->player[ourcockpit.ourplyrC].frame == REF_INANOTHER && ourcockpit.power == 1.0f && displaystage == GameState::STATUS_GAME && !dead)
265  else
266  PostQuitMessage(0);
267 }
268 
269 void GameClass::ToggleFullScreen(bool goFullScreen)
270 {
271  // want full screen (true) is windowed (true)
272  // want windowed (false) is windowed (true)
273  // want windowed (false) is full-screen (false)
274  if (goFullScreen && DXUTIsWindowed())
275  {
276  logger->Log("DXUTToggleFullScreen(true)");
277  DXUTToggleFullScreen();
278  maximized = false;
279  }
280  else if (!goFullScreen && !DXUTIsWindowed())
281  {
282  logger->Log("DXUTToggleFullScreen(false)");
283  DXUTToggleFullScreen();
284  }
285  if (GUI)
286  {
287  SetCursor(LoadCursor(nullptr, GUI->currentCursor));
288  SetCursor(LoadCursor(DXUTGetHINSTANCE(), GUI->currentCursor));
289  }
290  ShowCursor(true);
291 }
292 
294 {
295  logger->AddToCallStack("GameClass::InitializeGame");
296 
297  // Set starting gamestate
298  loadstage = 0;
300 
301  // Set the randomization seed based on time so it is always different
302  time_t ltime;
303  time(&ltime);
304  srand(static_cast<unsigned int>(ltime));
305 
306 #ifdef _DEBUG
307  vpfrTimer = new CStopWatch(logger);
308  vpfmTimer = new CStopWatch(logger);
309  uifrTimer = new CStopWatch(logger);
310  uifmTimer = new CStopWatch(logger);
311  otfrTimer = new CStopWatch(logger);
312  otfmTimer = new CStopWatch(logger);
313 #endif
314 
316 }
317 
318 HRESULT GameClass::InitDirectInput(HWND hDlg) const
319 {
320  logger->AddToCallStack("GameClass::InitDirectInput");
321  HRESULT hr;
322 
323  logger->Log("InitDirectInput() called...");
324 
325  try
326  {
327 #pragma region DirectInput
328  logger->Log("Calling DirectInput8Create...");
329  if (!viewscreen->g_pDI && FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
330  IID_IDirectInput8, reinterpret_cast<void**>(&viewscreen->g_pDI), NULL)))
331  {
332  logger->Log("DirectInput8Create() failed!", Logger::Level::Warn);
333  return hr;
334  }
335  logger->Log("Done with DirectInput8Create!");
336 #pragma endregion
337 
338 #pragma region Keyboard
339  logger->Log("Calling ptrKeyboard->Initialize...");
340  if (FAILED(hr = viewscreen->ptrKeyboard->Initialize(hDlg)))
341  return hr;
342  logger->Log("Done with ptrKeyboard->Initialize!");
343 #pragma endregion
344 
345 #pragma region Joystick
346  logger->Log("Calling ptrJoystick->Initialize...");
347  viewscreen->ptrJoystick->Initialize(DXUTGetHWND());
348  logger->Log("Done with ptrJoystick->Initialize!");
349 #pragma endregion
350  }
351  catch (const std::exception& e)
352  {
353  logger->Log(const_cast<char*>(e.what()), Logger::Level::Error);
354  }
355 
356  logger->Log("InitDirectInput() exited successfully!");
357 
358  return S_OK;
359 }
360 
361 void GameClass::SendScreenShot(HBITMAP hBitmap) const
362 {
363  const DWORD dwPaletteSize = 0;
364  HANDLE hOldPal2 = nullptr;
365  HDC hDC = CreateDC(TEXT("DISPLAY"), nullptr, nullptr, nullptr);
366  const int iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
367  WORD wBitCount;
368  DeleteDC(hDC);
369  if (iBits <= 1)
370  wBitCount = 1;
371  else if (iBits <= 4)
372  wBitCount = 4;
373  else if (iBits <= 8)
374  wBitCount = 8;
375  else
376  wBitCount = 24;
377 
378  BITMAP Bitmap0;
379  GetObject(hBitmap, sizeof(Bitmap0), reinterpret_cast<LPSTR>(&Bitmap0));
380 
381  BITMAPINFOHEADER bi;
382  bi.biSize = sizeof(BITMAPINFOHEADER);
383  bi.biWidth = Bitmap0.bmWidth;
384  bi.biHeight = -Bitmap0.bmHeight;
385  bi.biPlanes = 1;
386  bi.biBitCount = wBitCount;
387  bi.biCompression = BI_RGB;
388  bi.biSizeImage = 0;
389  bi.biXPelsPerMeter = 0;
390  bi.biYPelsPerMeter = 0;
391  bi.biClrImportant = 0;
392  bi.biClrUsed = 256;
393 
394  const DWORD dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount + 31) & ~31) / 8 * Bitmap0.bmHeight;
395  const HANDLE hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof BITMAPINFOHEADER);
396  const LPBITMAPINFOHEADER lpbi = static_cast<LPBITMAPINFOHEADER>(GlobalLock(hDib));
397  *lpbi = bi;
398 
399  const HANDLE hPal = GetStockObject(DEFAULT_PALETTE);
400  if (hPal)
401  {
402  hDC = GetDC(nullptr);
403  hOldPal2 = SelectPalette(hDC, static_cast<HPALETTE>(hPal), FALSE);
404  RealizePalette(hDC);
405  }
406 
407  GetDIBits(hDC, hBitmap, 0, static_cast<UINT>(Bitmap0.bmHeight), reinterpret_cast<LPSTR>(lpbi) + sizeof BITMAPINFOHEADER
408  + dwPaletteSize, reinterpret_cast<BITMAPINFO*>(lpbi), DIB_RGB_COLORS);
409 
410  if (hOldPal2)
411  {
412  SelectPalette(hDC, static_cast<HPALETTE>(hOldPal2), TRUE);
413  RealizePalette(hDC);
414  ReleaseDC(nullptr, hDC);
415  }
416 
417  BITMAPFILEHEADER bmfHdr;
418  bmfHdr.bfType = 0x4D42; // "BM"
419  const DWORD dwDIBSize = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER + dwPaletteSize + dwBmBitsSize;
420  bmfHdr.bfSize = dwDIBSize;
421  bmfHdr.bfReserved1 = 0;
422  bmfHdr.bfReserved2 = 0;
423  bmfHdr.bfOffBits = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER + dwPaletteSize;
424 
425  char* buffer = new char[sizeof BITMAPFILEHEADER + dwDIBSize + 1];
426  buffer[0] = ID_USER_PACKET_SCREENSHOT;
427  memcpy(&buffer[1], &bmfHdr, sizeof BITMAPFILEHEADER);
428  memcpy(&buffer[1 + sizeof BITMAPFILEHEADER], lpbi, dwDIBSize);
429  networking->SendScreenShot(buffer, sizeof BITMAPFILEHEADER + dwDIBSize + 1);
430  SAFE_DELETE(buffer);
431 
432  GlobalUnlock(hDib);
433  GlobalFree(hDib);
434 }
435 
437 {
438  const HDC hdc = GetDC(nullptr); // get the desktop device context
439  const HDC hDest = CreateCompatibleDC(hdc); // create a device context to use yourself
440 
441  // get the height and width of the screen
442  const int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
443  const int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
444 
445  // create a bitmap
446  const HBITMAP hbDesktop = CreateCompatibleBitmap(hdc, width, height);
447 
448  // use the previously created device context with the bitmap
449  SelectObject(hDest, hbDesktop);
450 
451  // copy from the desktop device context to the bitmap device context
452  // call this once per 'frame'
453  BitBlt(hDest, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
454 
455  // after the recording is done, release the desktop context you got..
456  ReleaseDC(nullptr, hdc);
457 
458  SendScreenShot(hbDesktop);
459 
460  // ..delete the bitmap you were using to capture frames..
461  DeleteObject(hbDesktop);
462 
463  // ..and delete the context you created
464  DeleteDC(hDest);
465 }
466 
467 //--------------------------------------------------------------------------------------
468 // Returns true if a particular depth-stencil format can be created and used with
469 // an adapter format and backbuffer format combination.
470 BOOL GameClass::IsDepthFormatOk(D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat) const
471 {
472  logger->AddToCallStack("GameClass::IsDepthFormatOk");
473  // Verify that the depth format exists
474  HRESULT hr = DXUTGetD3D9Object()->CheckDeviceFormat(D3DADAPTER_DEFAULT,
475  D3DDEVTYPE_HAL,
476  AdapterFormat,
477  D3DUSAGE_DEPTHSTENCIL,
478  D3DRTYPE_SURFACE,
479  DepthFormat);
480  if (FAILED(hr)) return FALSE;
481 
482  // Verify that the backbuffer format is valid
483  hr = DXUTGetD3D9Object()->CheckDeviceFormat(D3DADAPTER_DEFAULT,
484  D3DDEVTYPE_HAL,
485  AdapterFormat,
486  D3DUSAGE_RENDERTARGET,
487  D3DRTYPE_SURFACE,
488  BackBufferFormat);
489  if (FAILED(hr)) return FALSE;
490 
491  // Verify that the depth format is compatible
492  hr = DXUTGetD3D9Object()->CheckDepthStencilMatch(D3DADAPTER_DEFAULT,
493  D3DDEVTYPE_HAL,
494  AdapterFormat,
495  BackBufferFormat,
496  DepthFormat);
497 
498  return SUCCEEDED(hr);
499 }
500 
505 bool CALLBACK GameClass::IsDeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext)
506 {
507  GameClass* game = static_cast<GameClass*>(pUserContext);
508  game->logger->AddToCallStack("GameClass::IsDeviceAcceptable");
509 
510  return game->IsDepthFormatOk(D3DFMT_D24S8, AdapterFormat, BackBufferFormat) ||
511  game->IsDepthFormatOk(D3DFMT_D24X8, AdapterFormat, BackBufferFormat) ||
512  game->IsDepthFormatOk(D3DFMT_D24X4S4, AdapterFormat, BackBufferFormat) ||
513  game->IsDepthFormatOk(D3DFMT_D24FS8, AdapterFormat, BackBufferFormat);
514 }
515 
516 bool CALLBACK GameClass::ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext)
517 {
518  GameClass* game = static_cast<GameClass*>(pUserContext);
519  game->logger->AddToCallStack("GameClass::ModifyDeviceSettings");
520  game->logger->Log("Calling ModifyDeviceSettings()...");
521 
522  // ReSharper disable once CppJoinDeclarationAndAssignment
523  // ReSharper disable once CppEntityAssignedButNoRead
524  HRESULT hr;
525  D3DCAPS9 pCaps;
526  // ReSharper disable once CppJoinDeclarationAndAssignment
527  V(DXUTGetD3D9Object()->GetDeviceCaps(pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &pCaps));
528 
529  // vsync
530  pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
531 
532  // full-scene anti-aliasing
533  if (SUCCEEDED(DXUTGetD3D9Object()->CheckDeviceMultiSampleType(pCaps.AdapterOrdinal,
534  pCaps.DeviceType, pDeviceSettings->d3d9.pp.BackBufferFormat,
535  FALSE, D3DMULTISAMPLE_4_SAMPLES, NULL)))
536  pDeviceSettings->d3d9.pp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
537 
538  // Make sure device supports HW T&L and vertex version 3.0 or later
539  if ((pCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
540  pCaps.VertexShaderVersion < D3DVS_VERSION(3, 0))
541  {
542  pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
543  game->logger->Log("Insufficient vertex shader version!", Logger::Level::Fatal);
544  }
545  else
546  {
547  pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
548  game->logger->Log("Hardware vertex processing detected!");
549  }
550 
551  // Debugging vertex shaders requires either REF or software vertex processing
552  // and debugging pixel shaders requires REF.
553 #ifdef DEBUG_VS
554  if (pDeviceSettings->DeviceType != D3DDEVTYPE_REF)
555  {
556  pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
557  pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
558  pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
559  }
560 #endif
561 #ifdef DEBUG_PS
562  pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
563 #endif
564 
565  // This sample requires a stencil buffer.
566  if (game->IsDepthFormatOk(D3DFMT_D24S8,
567  pDeviceSettings->d3d9.AdapterFormat,
568  pDeviceSettings->d3d9.pp.BackBufferFormat))
569  pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24S8;
570  else
571  if (game->IsDepthFormatOk(D3DFMT_D24X8,
572  pDeviceSettings->d3d9.AdapterFormat,
573  pDeviceSettings->d3d9.pp.BackBufferFormat))
574  pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24X8;
575  else
576  if (game->IsDepthFormatOk(D3DFMT_D24X4S4,
577  pDeviceSettings->d3d9.AdapterFormat,
578  pDeviceSettings->d3d9.pp.BackBufferFormat))
579  pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24X4S4;
580  else
581  if (game->IsDepthFormatOk(D3DFMT_D24FS8,
582  pDeviceSettings->d3d9.AdapterFormat,
583  pDeviceSettings->d3d9.pp.BackBufferFormat))
584  pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24FS8;
585  else
586  game->logger->Log("Could not find a suitable depth stencil format!", Logger::Level::Fatal);
587 
588  // For the first device created if its a REF device, optionally display a warning dialog box
589  if (pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF)
590  {
591  DXUTDisplaySwitchingToREFWarning(DXUT_D3D9_DEVICE);
592  game->logger->Log("Switching to reference device warning!", Logger::Level::Debug);
593  }
594 
595  if (pCaps.NumSimultaneousRTs < 3)
596  {
597  game->logger->Log("Insufficient number of available render targets!", Logger::Fatal);
598  }
599 
600  return true;
601 }
602 
610 HRESULT CALLBACK GameClass::OnCreateDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext)
611 {
612  GameClass* game = static_cast<GameClass*>(pUserContext);
613  game->logger->AddToCallStack("GameClass::OnCreateDevice");
614  game->logger->Log("Calling OnCreateDevice()...");
615 
616  HRESULT hr;
617 
618  V_RETURN(game->GUI->OnCreateDevice(pd3dDevice)); // 6 references (4 we track)
619 
620  V_RETURN(game->graphics->LoadShaderFile());
621  V_RETURN(game->graphics->g_pEffect->SetTechnique("TShader")); // now have 37 (5 we track) so apparently 21 for the different samplers, etc?
622 
623  V_RETURN(game->viewscreen->OnCreateDevice(pd3dDevice)); // now have 78 ... added 41 (48 we track, added 43)
624 
625 
626  // @todo so this block was intended to reload the game if they moved it to a different monitor? but it is causing issues for some players
627  // where onresetdevice(STATUS_GAME) doesn't get called because we hijack the displaystage here...
629  {
630  game->logger->Log("OnCreateDevice called in STATUS_GAME so we are headed back to STATUS_LOADING!", Logger::Level::Debug);
631 
632  game->GUI->furtherdelay = 0.5f;
633  game->GUI->fade = 0.0f;
634  game->GUI->cloudmotion = 0.0f; // for zoom
635  game->GUI->eyemotion = 0.0f;
636 
637  game->loadstage = game->stage = game->instage = 0;
639  game->logger->Log("Advanced to STATUS_LOADING");
640  game->discord->UpdatePresence("Loading Screen", "Loading game assets...", "loading");
641  }
642 
643  game->logger->Log("OnCreateDevice() done!");
644  return S_OK;
645 }
646 
647 //--------------------------------------------------------------------------------------
648 // This callback function will be called immediately after the Direct3D device has been
649 // reset, which will happen after a lost device scenario. This is the best location to
650 // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever
651 // the device is lost. Resources created here should be released in the OnLostDevice
652 // callback.
653 //--------------------------------------------------------------------------------------
654 HRESULT CALLBACK GameClass::OnResetDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext)
655 {
656  GameClass* game = static_cast<GameClass*>(pUserContext);
657  game->logger->AddToCallStack("GameClass::OnResetDevice");
658 
659  HRESULT hr;
660  //hr = game->graphics->g_pEffect->OnResetDevice();
661  //if (!SUCCEEDED(hr))
662  // game->logger->Log("game->graphics->g_pEffect->OnResetDevice()", Logger::Level::Fatal, hr);
663  //game->UpdateTrackedResource("g_pEffect", 2);
664 
665  char msg[99];
666  sprintf_s(msg, 99, "GameClass::OnResetDevice() DS %i", game->displaystage);
667  game->logger->Log(msg);
668 
669  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
670  switch (game->displaystage)
671  {
672  case GameState::STATUS_SPLASH: // used B4
673  case GameState::STATUS_LOGIN: // used B4
674  case GameState::STATUS_CREATE: // used B4
675 
676  V(game->graphics->OnResetDevice()); // g_pEffect only
677 
678  game->GUI->OnResetDevice(); // g_pSprite and dialogmanager only
679  break;
680 
681  case GameState::STATUS_LOADING: // used B4
682  V(game->graphics->OnResetDevice()); // g_pEffect only
683 
684  game->GUI->OnResetDevice(); // g_pSprite and dialogmanager only
685 
686  V(game->viewscreen->OnResetDevice(pd3dDevice, pBackBufferSurfaceDesc));
687 
688  break;
689 
690  case GameState::STATUS_GAME: // STATUS_GAME
691  V(game->graphics->OnResetDevice()); // g_pEffect only
692  V(game->viewscreen->OnResetDevice(pd3dDevice, pBackBufferSurfaceDesc));
693 
694  game->GUI->OnResetDevice();
695 
696  game->logger->Log("game->GUI->g_HUD Initializing...");
697  game->logger->AddToCallStack("game->GUI->g_HUD Initializing...");
698  game->GUI->g_HUD.Init(&game->GUI->g_DialogResourceManager);
699  game->GUI->g_HUD.RemoveAllControls();
700  game->GUI->g_HUD.SetCallback(HMI::OnGUIEvent, game->GUI);
701  V(game->GUI->g_HUD.SetFont(0, L"DejaVu Sans Mono", static_cast<LONG>(12.0f * game->displayscale), FW_NORMAL));
702 
703  // this is a Windows font that should be present on all systems
704  V(game->GUI->g_HUD.SetFont(1, L"Comic Sans MS", static_cast<LONG>(24.0f * game->displayscale), FW_NORMAL));
705  game->GUI->g_HUD.SetLocation(0, 0);
706 
707  // @todo so this should be pretty easy ... OnResetDevice is not getting called on DS 4
708  V(game->GUI->g_HUD.AddStatic(IDC_REJOINTEXT, L"", static_cast<int>((designedWidthC * 0.5f - 200.0f) * game->displayscale), static_cast<int>((designedHeightC * 0.5f - 135.0f) * game->displayscale), static_cast<int>(400.0f * game->displayscale), static_cast<int>(235.0f * game->displayscale)));
709  game->GUI->g_HUD.GetStatic(IDC_REJOINTEXT)->SetTextColor(0xFFFFFFFF);
710  game->GUI->g_HUD.GetControl(IDC_REJOINTEXT)->GetElement(0)->iFont = 1;
711  V(game->GUI->g_HUD.AddButton(IDC_REJOINBTN, game->GUI->strings[L_DEAD_BUTTON].c_str(), static_cast<int>((designedWidthC * 0.5f - 40.0f) * game->displayscale), static_cast<int>((designedHeightC * 0.5f + 25.0f) * game->displayscale), static_cast<int>(80.0f * game->displayscale), static_cast<int>(35.0f * game->displayscale), 0, true));
712  game->GUI->g_HUD.GetButton(IDC_REJOINBTN)->SetEnabled(false);
713 
714  // this is after we moved it to a new window
716  game->viewscreen->LoadVehicleProfile(0, true);
717 
718  game->displays->OnResetDevice();
719 
720  break;
721  }
722 
723  game->logger->Log("OnResetDevice() done!");
724  game->logger->AddToCallStack("GameClass::OnResetDevice DONE");
725 
726  return S_OK;
727 }
728 
729 void GameClass::UseOrDisuseInventoryItemType(int itemtype, int itemId, int vehicleId) const
730 {
731  logger->AddToCallStack("GameClass::UseOrDisuseInventoryItemType");
732 
733  // disuse or switching
734  if (itemtype == ourcockpit.inventoryItemInUseType)
735  itemtype = 0; // removed
736 
737  if (ourcockpit.inventoryItemInUseType == KitType::Binoculars)
738  {
739  g_fFOV = D3DXToRadian(115.0f);
741  }
742  else if (ourcockpit.inventoryItemInUseType == KitType::NightVision)
743  {
744  //D3DCOLORVALUE h;
745  //h.r = 0.0f; h.g = 0.0f; h.b = 0.0f; h.a = 0.0f; // Based on middle brightness wall.bmp
746  }
747 
748  // using an item or new item
749  if (itemtype == KitType::Binoculars)
750  {
751  g_fFOV = D3DXToRadian(12.0f);
753  }
754  else if (itemtype == KitType::NightVision)
755  {
756  //D3DCOLORVALUE h;
757  //h.r = 0.0f; h.g = 0.5f; h.b = 0.0f; h.a = 0.0f; // Based on middle brightness wall.bmp
758  }
759 
760  ourcockpit.inventoryItemInUseType = itemtype; // 0 is none
762  ourcockpit.intentoryItemInUseVehicleId = vehicleId; // 0 is personal inventory
763 }
764 
765 //--------------------------------------------------------------------------------------
766 // This callback function will be called once at the beginning of every frame. This is the
767 // best location for your application to handle updates to the scene, but is not
768 // intended to contain actual rendering calls, which should instead be placed in the
769 // OnFrameRender callback.
770 //--------------------------------------------------------------------------------------
771 void CALLBACK GameClass::OnFrameMove(double fTime, float fElapsedTime, void* pUserContext)
772 {
773  GameClass* game = static_cast<GameClass*>(pUserContext);
774 
775  char msg[99];
776  sprintf_s(msg, 99, "GameClass::OnFrameMove %i", game->displaystage);
777  game->logger->AddToCallStack(msg);
778 
779  game->FrameElapsedTime = fElapsedTime;
780 
781  if (game->lastDeviceChange < 2.0f)
782  {
783  game->lastDeviceChange += fElapsedTime;
784  if (game->lastDeviceChange >= 2.0f)
785  {
786  if (game->lastDeviceChangedSound)
787  {
788  game->sound->Reset();
789  game->lastDeviceChangedSound = false;
790  }
791 
792  if (game->lastDeviceChangedInput)
793  {
795  game->viewscreen->ptrJoystick->Initialize(DXUTGetHWND());
796  game->lastDeviceChangedInput = false;
797  }
798 
799  // update after everything is done because new BASS_Init system will have new device enumeration
802  }
803  }
804 
805 
806 
807 
808  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
809  switch (game->displaystage)
810  {
812  {
813  if (game->loadstage < SOUND_APALTITUDE)
814  {
815  game->sound->LoadSounds(game->loadstage);
817  game->loadstage++;
818  }
819  else
820  {
821  game->GUI->FadeIn(0.6f, fElapsedTime);
822  }
823 
825  game->sound->loopintro = false;
826 
828  (game->sound->musicstage == GameState::STATUS_LOGIN || (!game->sound->loopintro && !game->sound->g_pSoundIntro)))
829  game->logger->Log("Oops, this is where we were skipping ahead in STATUS_SPLASH before all resources were loaded!", Logger::Level::Debug);
830 
832  (game->sound->musicstage == GameState::STATUS_LOGIN || (!game->sound->loopintro && !game->sound->g_pSoundIntro)))
833  {
834  game->GUI->furtherdelay += fElapsedTime;
835  if (game->GUI->furtherdelay > 0.5f) // wait until the part of the song
836  {
837  if (!game->GUI->m_pddsGUIParts)
838  {
839  game->logger->Log("Somehow we are advancing to STATUS_LOGIN with a null MOTD GLASS!", Logger::Level::Error);
840  game->LoadTexture(&game->GUI->m_pddsGUIParts, "m_pddsGUIParts", L"Textures\\Glass.png");
841  }
842 
843  if (!game->GUI->m_pddsGUIScroll)
844  {
845  sprintf_s(msg, sizeof msg, "Somehow we are advancing to STATUS_LOGIN with a null m_pddsGUIScroll %i!", game->loadstage);
846  game->logger->Log(msg, Logger::Level::Error);
847  game->LoadTexture(&game->GUI->m_pddsGUIScroll, "m_pddsGUIScroll", L"Textures\\Logo.png");
848  }
849 
850  game->GUI->furtherdelay = 0.5f;
851  game->GUI->fade = 0.0f;
852 
853  game->loadstage = 0;
855  game->discord->UpdatePresence("Login Screen", "Waiting for credentials...", "login");
856 
857  if (game->GUI->tm_time.tm_mon == 11 && game->GUI->tm_time.tm_mday >= 11 && game->GUI->tm_time.tm_mday <= 25) // Dec 11-25
858  game->sound->Play(SOUND_HOLIDAYBELLS);
859  else if (game->GUI->tm_time.tm_mon == 9 && game->GUI->tm_time.tm_mday >= 17) // Oct 17-31
860  game->sound->Play(SOUND_HOLIDAYHOWL);
861 
862  game->logger->Log("Advanced to STATUS_LOGIN");
863 
864  game->GUI->CreateDialogs();
865  game->GUI->InitApp();
866  game->GUI->LoadConfiguration(); // user-defined
867  }
868  }
869 
870  game->GUI->LightningCalculations(fElapsedTime);
871 
872  game->networking->FrameMove(game->displaystage);
873  }
874  break;
875 
877  {
878  if (game->loadstage < SOUND_ENUMERATION)
879  {
880  //game->GUI->fade = game->GUI->furtherdelay = 0.0f;
882  if (game->loadstage >= SOUND_APALTITUDE)
883  game->sound->LoadSounds(game->loadstage);
884  game->loadstage++;
885  }
886 
887  game->GUI->FadeIn(0.4f, fElapsedTime);
888 
890  {
891  game->GUI->furtherdelay += fElapsedTime;
892  if (game->GUI->furtherdelay > 0.5f) // wait until the part of the song
893  {
894  if (!game->GUI->m_pddsGUIScroll)
895  {
896  sprintf_s(msg, sizeof msg, "Somehow we are advancing to STATUS_LOADING with a null m_pddsGUIScroll %i!", game->loadstage);
897  game->logger->Log(msg, Logger::Level::Error);
898  game->LoadTexture(&game->GUI->m_pddsGUIScroll, "m_pddsGUIScroll", L"Textures\\Logo.png");
899  }
900 
901  // don't keep these
902  SAFE_RELEASE(game->graphics->m_pddsCloudBaseMapAndNetwork);
903  game->UpdateTrackedResource("m_pddsCloudBaseMapAndNetwork", 3);
904  SAFE_RELEASE(game->graphics->m_pddsLightningAndBackground[0]);
905  game->UpdateTrackedResource("m_pddsLightningAndBackground[0]", 3);
906  SAFE_RELEASE(game->graphics->m_pddsLightningAndBackground[1]);
907  game->UpdateTrackedResource("m_pddsLightningAndBackground[1]", 3);
908  SAFE_RELEASE(game->graphics->m_pddsLightningAndBackground[2]);
909  game->UpdateTrackedResource("m_pddsLightningAndBackground[2]", 3);
910 
911  game->GUI->furtherdelay = 0.5f;
912  game->GUI->fade = 0.0f;
913 
914  game->loadstage = game->stage = game->instage = 0;
916  game->logger->Log("Advanced to STATUS_LOADING");
917  game->discord->UpdatePresence("Loading Screen", "Loading game assets...", "loading");
918  }
919  }
920 
921  game->networking->FrameMove(game->displaystage);
922 
923  game->GUI->LightningCalculations(fElapsedTime);
924  }
925  break;
926 
928  {
929  static float rxhold = 0.0f, txhold = 0.0f;
930  if (game->GUI->rxbuffer > 0)
931  {
932  rxhold += fElapsedTime;
933  if (rxhold > 0.05f)
934  {
935  game->GUI->rxlight = !game->GUI->rxlight;
936  game->GUI->rxbuffer -= 3;
937  rxhold = 0.0f;
938  }
939  }
940  else
941  game->GUI->rxlight = false;
942  if (game->GUI->txbuffer > 0)
943  {
944  txhold += fElapsedTime;
945  if (txhold > 0.05f)
946  {
947  game->GUI->txlight = !game->GUI->txlight;
948  game->GUI->txbuffer -= 3;
949  txhold = 0.0f;
950  }
951  }
952  else
953  game->GUI->txlight = false;
954 
955  if (game->loadstage < 4)
956  {
958  //game->sound->LoadSounds(GameState::STATUS_CREATE, game->loadstage);
959  game->loadstage++;
960  game->GUI->furtherdelay = 0.0f;
961  }
962 
963  if (game->loadstage >= 4 && (game->sound->musicstage == GameState::STATUS_LOADING || (!game->sound->loopintro && !game->sound->g_pSoundIntro && game->GUI->immigrationPassed)))
964  {
965  game->GUI->furtherdelay += fElapsedTime;
966  if (game->GUI->furtherdelay > 0.5f) // wait until the part of the song
967  {
968  game->GUI->furtherdelay = 0.5f;
969  game->GUI->fade = 0.0f;
970 
971  game->loadstage = game->stage = game->instage = 0;
973  game->logger->Log("Advanced to STATUS_LOADING");
974  game->discord->UpdatePresence("Loading Screen", "Loading game assets...", "loading");
975 
976  // this fixes the window size after we leave immigration
977  RECT rect;
978  if (!GetWindowRect(DXUTGetHWND(), &rect))
979  {
980  sprintf_s(msg, sizeof msg, "Error in GetWindowRect: %d", GetLastError());
981  game->logger->Log(msg, Logger::Fatal);
982  return;
983  }
984 
985  // All these use Y because we lock the aspect ratio
986  if (!MoveWindow(DXUTGetHWND(), rect.left, static_cast<int>(rect.top + 102.5f * game->displayscale), static_cast<int>(700.0f * game->displayscale), static_cast<int>(500.0f * game->displayscale), true))
987  {
988  sprintf_s(msg, sizeof msg, "Error in MoveWindow: %d", GetLastError());
989  game->logger->Log(msg, Logger::Fatal);
990  return;
991  }
992  DXUTReset3DEnvironment();
993 
994  game->GUI->g_HUD.RemoveAllControls();
995  return;
996  }
997  }
998 
999  game->networking->FrameMove(game->displaystage);
1000 
1001  game->GUI->OnFrameMove(fElapsedTime);
1002 
1003  if (game->screenShotStatus == 2)
1004  {
1005  game->screenShotStatus = 3;
1006  }
1007  else if (game->screenShotStatus == 4)
1008  {
1009  game->screenShotStatus = 5; // stop
1010  game->ScreenCapture();
1011  }
1012  }
1013  break;
1014 
1016  {
1017  game->GUI->eyemotion += fElapsedTime / 78.0f;
1018  if (game->GUI->eyemotion > 1.0f)
1019  {
1020  game->GUI->eyemotion = 1.0f;
1021  game->sound->loopintro = false;
1022  }
1023 
1024  if (game->loadstage == 0)
1025  game->GUI->furtherdelay = 0.0f;
1026 
1027  // good idea but wrong implementation, results in confirmation packets sent like 10 times
1028  // and isn't actually throttling the texture loading because it is done in framerender because of the
1029  // output text
1030  if (game->loadstage < 78)// && game->loadstage < (short)(game->GUI->eyemotion*78.0f)) // one per second
1031  {
1032  game->GUI->LoadTextures(GameState::STATUS_LOADING, game->loadstage); // 1 get eyezoom, 8 gets new msgs
1033  }
1034 
1035  if (game->loadstage == 78)
1036  {
1037 #pragma region Eventually we can delete this
1038  game->logger->Log("Transmitting the contents of their old PODS system to the server!");
1039  rename("pods.dat", "Save\\pods.dat");
1040 
1041  // load data
1042  int pods;
1043  _sopen_s(&pods, "Save\\pods.dat", _O_RDONLY | O_BINARY, _SH_DENYNO, _S_IWRITE);
1044  if (pods != -1)
1045  {
1046  _lseek(pods, 0, SEEK_SET);
1047  int PODStot;
1048  _read(pods, &PODStot, 4);
1049 
1050  for (int t = 1; t <= PODStot; t++)
1051  {
1052  struct SPODSData // for file
1053  {
1054  unsigned short serial; // 2
1055  unsigned char type; // 1
1056  char loadtype; // 1
1057  unsigned char unused; // 1
1058  char reference; // 1
1059  char handle[13]; // 13
1060  char dest; // positive is docks, negative is cities // 1
1061  float latitude, longitude; // 8
1062  char IVR[10], PODS[6]; // what ship it is in // 16
1063  D3DXVECTOR3 location; // new system to replace latitude and longitude
1064  unsigned short quantity; // 2
1065  float weight; // 4
1066  // total 62 of 100
1067  } temppods = {};
1068  _lseek(pods, t * 100, SEEK_SET);
1069  _read(pods, &temppods, sizeof(SPODSData));
1070  if (temppods.serial)
1071  {
1072  SPacketBig bigPacket = SPacketBig();
1073  bigPacket.type = 13; // legacy scan data upstream
1074  sprintf_s(bigPacket.msg, 78, "%i,%i,%i,%i,%s,%i,%s,%s,%.3f,%.3f,%.3f,%i,%.0f",
1075  temppods.serial, temppods.type, temppods.loadtype, temppods.reference, temppods.handle, temppods.dest, &temppods.IVR[4], temppods.PODS, temppods.location.x, temppods.location.y, temppods.location.z, temppods.quantity, temppods.weight);
1076  game->networking->SendToServer(&bigPacket, sizeof SPacketBig, true);
1077  }
1078  }
1079  _close(pods);
1080 
1081  remove("Save\\pods.dat");
1082  }
1083 #pragma endregion
1084  }
1085  if (game->loadstage == 79)
1086  {
1087 #pragma region Eventually we can delete this
1088  game->logger->Log("Transmitting the contents of their old VPT system to the server!");
1089  remove("Save\\msgbodies.dat");
1090  remove("Save\\msgheader.dat");
1091 
1092  rename("vpt.dat", "Save\\vpt.dat");
1093 
1094  // load data
1095  int vpt;
1096  _sopen_s(&vpt, "Save\\vpt.dat", _O_RDONLY | O_BINARY, _SH_DENYNO, _S_IWRITE);
1097  if (vpt != -1)
1098  {
1099  for (int t = 1; t <= MAX_SHIPINMEMORY && _eof(vpt) != 1; t++)
1100  {
1101  struct SVPT
1102  {
1103  char IVR[6]; //6
1104  char owner[13]; // 19
1105  unsigned char type; //20
1106  char hullname[20]; //51
1107  char reference;//52
1108  D3DXVECTOR3 location; //64
1109  unsigned short serial;
1110  char damage;
1111  bool armed;
1112  unsigned short pilot;
1113  } tempvpt = {};
1114  _lseek(vpt, t * 100, SEEK_SET);
1115  _read(vpt, &tempvpt, sizeof(SVPT));
1116  if (tempvpt.serial)
1117  {
1118  SPacketBig bigPacket = SPacketBig();
1119  bigPacket.type = 13; // legacy scan data upstream
1120  sprintf_s(bigPacket.msg, 78, "%i,%i,%i,%i,%s,%i,%s,%s,%.3f,%.3f,%.3f,%i,%.0f",
1121  tempvpt.serial, tempvpt.type, 0, tempvpt.reference, tempvpt.owner, 0, "", tempvpt.IVR, tempvpt.location.x, tempvpt.location.y, tempvpt.location.z, 0, 0.0f);
1122  game->networking->SendToServer(&bigPacket, sizeof SPacketBig, true);
1123  }
1124  }
1125  _close(vpt);
1126 
1127  remove("Save\\vpt.dat");
1128  }
1129 #pragma endregion
1130  }
1131  if (game->loadstage == 80)
1132  {
1133  // need to get WPtargetC from server
1134  // need to get touchdown zone stuff on the server as a public waypoint
1135 
1136  // need to keep this part
1137  game->bus->waypoint.clear();
1138  Swaypoint tempwaypoint = Swaypoint();
1139  ZeroMemory(&tempwaypoint, sizeof Swaypoint);
1140  game->bus->waypoint.emplace_back(tempwaypoint);
1141 
1142  // Now instead of looking at the local file system we request all the stuffs from the server!
1144  }
1145  if (game->loadstage == 81)
1146  {
1147 #pragma region Eventually we can delete this
1148  game->logger->Log("Transmitting the contents of their old help system to the server!");
1149  if (game->config.configver == 32)
1150  {
1151  for (int i = 1; i < 81; i++) // don't include 0... it is MOTD... don't include higher than 80
1152  {
1153  if (game->config.oldvphelp[i]) // "true" means "seen"
1154  {
1155  SClientPacket outpacket = SClientPacket();
1156  // 41=HelpVerbiageControl, x=helpId, y=(0=remindme,1=understood,2=reset,3=disable,4=import), z=, w=
1157  outpacket.type = 41;
1158  outpacket.f_x = static_cast<float>(i);
1159  outpacket.f_y = 4.0f;
1160  outpacket.f_z = 0.0f;
1161  outpacket.f_w = 0.0f;
1162  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1163  game->vphelp[i] = game->config.oldvphelp[i];
1164  }
1165  }
1166 
1167  game->config.configver = 33;
1168  game->config.Save();
1169  }
1170 #pragma endregion
1171  }
1172 
1173  game->networking->FrameMove(GameState::STATUS_LOADING); // 5 send confirmation packet, raknetmsghandler process too though
1174 
1175  game->GUI->fade += fElapsedTime / 5.8f; // fade in over six seconds (with music)
1176  if (game->GUI->fade > 1.0f)
1177  game->GUI->fade = 1.0f;
1178 
1179  if (game->loadstage < 81)
1180  game->loadstage++;
1181 
1182  if (game->loadstage >= 81 && (game->sound->musicstage == GameState::STATUS_GAME || (!game->sound->loopintro && !game->sound->g_pSoundIntro)) && game->stage > 32)
1183  {
1184  game->GUI->furtherdelay += fElapsedTime;
1185  if (game->GUI->furtherdelay > 0.5f) // wait until the part of the song
1186  {
1187  game->GUI->furtherdelay = 0.5f;
1188 
1189  SAFE_RELEASE(game->GUI->m_pddsGUIRanks);
1190  game->UpdateTrackedResource("m_pddsGUIRanks", 3);
1191  SAFE_RELEASE(game->GUI->m_pddsGUIParts); // because we are going to load Textures\\GUI\\gui.png in place of Textures\\Glass.png
1192  game->UpdateTrackedResource("m_pddsGUIParts", 3);
1193  SAFE_RELEASE(game->GUI->m_pddsGUIInterlace);
1194  game->UpdateTrackedResource("m_pddsGUIInterlace", 3);
1195  SAFE_RELEASE(game->GUI->m_pddsGUIScroll);
1196  game->UpdateTrackedResource("m_pddsGUIScroll", 3);
1197  SAFE_RELEASE(game->GUI->m_pddsGUIScrollButton);
1198  game->UpdateTrackedResource("m_pddsGUIScrollButton", 3);
1199  SAFE_RELEASE(game->GUI->m_pddsGUIActions);
1200  game->UpdateTrackedResource("m_pddsGUIActions", 3);
1201 
1202  game->GUI->OnFrameMove(fElapsedTime); // just calling once
1203 
1204  game->loadstage = 0;
1206  game->logger->Log("Advanced to STATUS_GAME");
1207  game->discord->UpdateTelemetry();
1208 
1209  game->viewscreen->OnFrameMove(fTime, fElapsedTime);
1210 
1211  // Add the standard frame!
1212  SetWindowLong(DXUTGetHWND(), GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE);
1213 
1214  if (game->config.g_bStartFullscreen)
1215  {
1216  game->logger->Log("DXUTToggleFullScreen()");
1217  DXUTToggleFullScreen();
1218  game->maximized = false;
1219  SetCursor(LoadCursor(nullptr, game->GUI->currentCursor));
1220  }
1221  else
1222  {
1223  game->maximized = true;
1224  ShowWindow(DXUTGetHWND(), SW_MAXIMIZE);
1225  }
1226 
1227  SetFocus(DXUTGetHWND()); // fixes the focus problem where kb was beeping at me
1228 
1229 // const D3DSURFACE_DESC* pp = DXUTGetD3D9BackBufferSurfaceDesc();
1230 // game->viewscreen->OnResetDevice(DXUTGetD3D9Device(), pp, game->viewscreen);
1231 
1232  // this only gets called once... only needs to be called once
1233  game->GUI->LoadTextures(STATUS_GAME, 0);
1234 
1235  break; // so we don't execute FrameMove below on the new displaystage
1236  }
1237  }
1238  }
1239  break;
1240 
1242  {
1243 #if !defined(DIALOGHARNESS) | !defined(_DEBUG)
1244 
1245 #ifdef _DEBUG
1246  game->otfmTimer->startTimer();
1247 #endif
1249  game->sound->FrameMove(fElapsedTime);
1250 #ifdef _DEBUG
1251  game->otfmTimer->stopTimer();
1252 #endif
1253 
1254 #ifdef _DEBUG
1255  game->vpfmTimer->startTimer();
1256 #endif
1257  game->viewscreen->OnFrameMove(fTime, fElapsedTime);
1258 #ifdef _DEBUG
1259  game->vpfmTimer->stopTimer();
1260 #endif
1261 
1262 #endif
1263 #ifdef _DEBUG
1264  game->uifmTimer->startTimer();
1265 #endif
1266  game->GUI->OnFrameMove(fElapsedTime);
1267 #ifdef _DEBUG
1268  game->uifmTimer->stopTimer();
1269 #endif
1270 
1271  game->bus->FrameMove(fElapsedTime);
1272 
1273  for (UINT i = 0; i < game->bus->commandStream.size(); i++)
1274  {
1275  const Command command = game->bus->commandStream.at(i);
1276 
1277  if (command.name == "UseInventoryItem")
1278  {
1279  if (!playerships[0].simulator)
1280  {
1281  const int itemIndex = command.ivalues[0];
1282  int itemType, vehicleId;
1283  if (command.bValue)
1284  {
1285  itemType = ourcockpit.personalInventory.at(itemIndex);
1286  vehicleId = 0;
1287  }
1288  else
1289  {
1290  itemType = ourcockpit.vehicleInventory.at(itemIndex);
1291  vehicleId = playerships[0].vehicleId;
1292  }
1293 
1294  switch (itemType)
1295  {
1296  case KitType::LockPick:
1297  if (game->bus->targetC >= 0)
1298  {
1299  SClientPacket outpacket = SClientPacket();
1300  // 21=useinventory x=itemtype, y=(0==use 1==xfer 2==swap 4==install), z=(0==personal 1==vehicle), w=serverarray
1301  outpacket.type = 21; // use inventory on target
1302  outpacket.f_x = static_cast<float>(itemType); // item type
1303  outpacket.f_y = 0.0f; // use
1304  outpacket.f_z = 0.0f; // personal, doesn't matter from where
1305  // @todo this may not even be needed now since we send the targetVehicleId when we change targets
1306  outpacket.f_w = static_cast<float>(playerships[game->viewscreen->scanslot[game->bus->targetC]].vehicleId);
1307  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1308  }
1309  else
1310  {
1312  }
1313  break;
1314  case KitType::Binoculars:
1315  case KitType::NightVision:
1316  case KitType::Sunglasses:
1317  game->UseOrDisuseInventoryItemType(itemType, itemIndex, vehicleId);
1318  break;
1319  case KitType::ATM:
1320  case KitType::TemporaryRunwayLighting:
1321  case KitType::UpLink:
1322  {
1323  SClientPacket outpacket = SClientPacket();
1324  // 21=useinventory x=itemtype, y=(0==use 1==xfer 4==install), z=(0==personal 1==vehicle), w=serverarray
1325  outpacket.type = 21; // use inventory on target
1326  outpacket.f_x = static_cast<float>(itemType); // item type
1327  outpacket.f_y = 4.0f; // install
1328  outpacket.f_z = 1.0f; // always from vehicle
1329  outpacket.f_w = 0.0f; // n/a for surface target
1330  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1331  break;
1332  }
1333  case KitType::Firework:
1334  {
1335  SClientPacket outpacket = SClientPacket();
1336  // 21=useinventory x=itemtype, y=(0==use 1==xfer 2==swap 4==install), z=(0==personal 1==vehicle), w=serverarray
1337  outpacket.type = 21; // use inventory on target
1338  outpacket.f_x = static_cast<float>(itemType); // item type
1339  outpacket.f_y = 0.0f; // use
1340  outpacket.f_z = 0.0f; // personal, doesn't matter from where
1341  outpacket.f_w = 0.0f; // our vessel
1342  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1343  break;
1344  }
1345  default:
1346  game->logger->Log("Received request to UseInventoryItem but unhandled type!", Logger::Level::Error);
1347  break;
1348  }
1349  }
1350  else
1351  {
1353  }
1354  game->bus->commandStream.erase(game->bus->commandStream.begin() + i);
1355  }
1356  else if (command.name == "TransferInventoryItem")
1357  {
1358  if (!playerships[0].simulator)
1359  {
1360  if (game->bus->targetC >= 0)
1361  {
1362  const int itemIndex = command.ivalues[0];
1363  int itemType;
1364  if (command.bValue)
1365  itemType = ourcockpit.personalInventory.at(itemIndex);
1366  else
1367  itemType = ourcockpit.vehicleInventory.at(itemIndex);
1368 
1370  game->UseOrDisuseInventoryItemType(0, 0, 0);
1371 
1372  SClientPacket outpacket = SClientPacket();
1373  // 21=useinventory x=itemtype, y=(0==use 1==xfer 2==swapToVehicle, 3==swapToPersonal 4==install), z=(0==personal 1==vehicle), w=serverarray
1374  outpacket.type = 21; // transfer inventory to target
1375  outpacket.f_x = static_cast<float>(itemType); // item type
1376  outpacket.f_y = 1.0f; // xfer
1377  outpacket.f_z = static_cast<float>(command.ivalues[1]); // 0 is personal, 1 is vehicle
1378  // @todo this may not even be needed now since we send the targetVehicleId when we change targets
1379  outpacket.f_w = static_cast<float>(playerships[game->viewscreen->scanslot[game->bus->targetC]].vehicleId);
1380  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1381  }
1382  else
1383  {
1385  }
1386  }
1387  else
1388  {
1390  }
1391  game->bus->commandStream.erase(game->bus->commandStream.begin() + i);
1392  }
1393  else if (command.name == "SwapInventoryItem")
1394  {
1395  if (!playerships[0].simulator)
1396  {
1397  const int itemIndex = command.ivalues[0];
1398  int itemType, vehicleId;
1399  if (command.bValue) // WAS on person is true
1400  {
1401  itemType = ourcockpit.personalInventory.at(itemIndex);
1402  vehicleId = playerships[0].vehicleId; // was on person, now in vehicle
1403  }
1404  else
1405  {
1406  itemType = ourcockpit.vehicleInventory.at(itemIndex);
1407  vehicleId = 0; // was in vehicle (cabin), now on person (baggage)
1408  }
1409 
1410  if (ourcockpit.inventoryItemInUseId == itemIndex && ourcockpit.inventoryItemInUseType == itemType)
1411  ourcockpit.intentoryItemInUseVehicleId = vehicleId; // update vehicleId
1412 
1413  SClientPacket outpacket = SClientPacket();
1414  // 21=useinventory x=itemtype, y=(0==use on 1==xfer to 2==swap 3==unused 4==install), z=(0==from personal 1==from vehicle), w=serverarray
1415  outpacket.type = 21; // swap inventory
1416  outpacket.f_x = static_cast<float>(itemType); // item type
1417  outpacket.f_y = 2.0f; // swap
1418  outpacket.f_z = static_cast<float>(command.ivalues[1]); // 0 is personal2vehicle, 1 is vehicle2personal
1419  outpacket.f_w = 0.0f; // no vehicle needed
1420  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1421  }
1422  else
1423  {
1425  }
1426  game->bus->commandStream.erase(game->bus->commandStream.begin() + i);
1427  }
1428  else if (command.name == "TransferWeapon")
1429  {
1430  if (!playerships[0].simulator)
1431  {
1432  SClientPacket outpacket = SClientPacket();
1433  outpacket.type = 19; // cash/fuel/weapon transfer
1434  outpacket.f_x = 0.0f; // cash
1435  outpacket.f_y = 0.0f; // fuel
1436  outpacket.f_z = 1.0f; // weapon
1437  outpacket.f_w = static_cast<float>(command.ivalues[0]);
1438  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1439  }
1440  else
1441  {
1443  }
1444  game->bus->commandStream.erase(game->bus->commandStream.begin() + i);
1445  }
1446  else if (command.name == "ToggleAvionics")
1447  {
1448  if (command.ivalues[0] == 3)
1449  {
1452  if (game->sound->g_pSoundIntro)
1453  BASS_ChannelStop(game->sound->g_pSoundIntro);
1455  }
1456  else if (command.ivalues[0] == 4)
1457  {
1460  ZeroMemory(&game->bus->assayGrid.gridarray, sizeof SAssayGrid);
1461  }
1462  else if (command.ivalues[0] == 5)
1463  {
1466  }
1467  game->bus->commandStream.erase(game->bus->commandStream.begin() + i);
1468  }
1469  }
1470 
1472  {
1473  SClientPacket outpacket; // NOLINT
1474  outpacket.type = 11; // Menu type
1475  outpacket.f_x = static_cast<float>(interactive.outboundMenuSelect); // selection
1476  outpacket.f_y = 0.0f; // NULL
1477  outpacket.f_z = 0.0f; // NULL
1478  outpacket.f_w = 0.0f; // NULL
1479  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1481  }
1482  }
1483  break;
1484  }
1485 
1486  game->logger->AddToCallStack("GameClass::OnFrameMove END");
1487 }
1488 
1489 //--------------------------------------------------------------------------------------
1490 // This callback function will be called at the end of every frame to perform all the
1491 // rendering calls for the scene, and it will also be called if the window needs to be
1492 // repainted. After this function has returned, DXUT will call
1493 // IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
1494 //--------------------------------------------------------------------------------------
1495 void CALLBACK GameClass::OnFrameRender(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext)
1496 {
1497  GameClass* game = static_cast<GameClass*>(pUserContext);
1498 
1499  char msg[99];
1500  sprintf_s(msg, 99, "GameClass::OnFrameRender (%i)", game->displaystage);
1501  game->logger->AddToCallStack(msg);
1502 
1503  // ReSharper disable once CppEntityAssignedButNoRead
1504  HRESULT hr;
1505 
1506  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1507  switch (game->displaystage)
1508  {
1511  if (SUCCEEDED(pd3dDevice->BeginScene()))
1512  {
1513  V(pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0L, 1.0f, 0));
1514 
1515  pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
1516  pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1517  pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1518  pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1519  pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1520 
1521  game->GUI->OnRender(fElapsedTime, pd3dDevice);
1522 
1523  //If succeeded beginscene, and we get here, end it
1524  V(pd3dDevice->EndScene());
1525  }
1526  break;
1527 
1528  case GameState::STATUS_CREATE: // he used his own OnFrameRenderCreate
1529  if (SUCCEEDED(pd3dDevice->BeginScene()))
1530  {
1531  V(pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0L, 1.0f, 0));
1532 
1533  pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
1534  pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1535  pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1536  pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1537  pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1538 
1539  game->graphics->DrawImmigration(pd3dDevice, fElapsedTime);
1540 
1541  //If succeeded beginscene, and we get here, end it
1542  V(pd3dDevice->EndScene());
1543 
1544  if (game->screenShotStatus == 1 || game->screenShotStatus == 3)
1545  game->screenShotStatus++; // got a render, now next framemove we get the screen grab
1546  }
1547  break;
1548 
1550  if (SUCCEEDED(pd3dDevice->BeginScene()))
1551  {
1552  V(pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, game->GUI->fade == 1.0f ? D3DCOLOR_XRGB(static_cast<short>(255.0f * game->GUI->furtherdelay / 0.5f), static_cast<short>(255.0f * game->GUI->furtherdelay / 0.5f), static_cast<short>(255.0f * game->GUI->furtherdelay / 0.5f)) : 0L, 1.0f, 0));
1553 
1554  pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
1555  pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1556  pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1557  pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1558  pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1559 
1560  game->GUI->OnRender(fElapsedTime, pd3dDevice);
1561 
1562  if (game->stage == 0)
1563  {
1564  game->logger->Log("#include TEXTURES called!");
1565  game->instage = -1;
1566  }
1567 
1568  game->viewscreen->ptrRenderer->LoadTextures(pd3dDevice, &game->stage, &game->instage);
1569 
1570  if (game->stage == 31)
1571  {
1572  game->logger->Log("#include TEXTURES exited successfully!");
1573  game->instage = -1;
1574  }
1575 
1576  // load remaining sounds
1577  if (game->stage == 32)
1578  {
1579  game->instage = -1;
1580  deathinhibit = 5.0f; // proceeding to game, don't hiccup and die right away
1581  }
1582 
1583  if (game->instage == -1)
1584  {
1585  game->stage++;
1586  game->instage = 0;
1587  }
1588 
1589  //If succeeded beginscene, and we get here, end it
1590  V(pd3dDevice->EndScene());
1591  }
1592  break;
1593 
1595  {
1596  // Outside view (may include dynamic texture for simulator screen)
1597 
1598 #ifdef _DEBUG
1599  game->vpfrTimer->startTimer();
1600 #endif
1601 
1602  // He leaves a BeginScene() unclosed for us
1603  game->viewscreen->OnFrameRender(pd3dDevice, fTime);
1604 
1605 #ifdef _DEBUG
1606  game->vpfrTimer->stopTimer();
1607 #endif
1608 
1609  V(pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS));
1610 
1611  V(pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true));
1612  V(pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA));
1613  V(pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA));
1614 
1615 #ifdef _DEBUG
1616  game->uifrTimer->startTimer();
1617 #endif
1618 
1619  game->GUI->OnRender(fElapsedTime, pd3dDevice);
1620 
1621  game->logger->AddToCallStack("GameClass g_HUD.OnRender");
1622  V(game->GUI->g_HUD.OnRender(fElapsedTime));
1623 
1624 #ifdef _DEBUG
1625  game->uifrTimer->stopTimer();
1626 #endif
1627 
1628  // Need to close this finally now that everything is drawn
1629  // We will have switched to the device endscene even if we were in a simulator by this point
1630  if (game->beginScene == 1)
1631  {
1632  V(pd3dDevice->EndScene());
1633  game->beginScene = 0;
1634  }
1635  else
1636  {
1637  sprintf_s(msg, sizeof msg, "Found a %i when trying to EndScene", game->beginScene);
1638  game->logger->Log(msg, Logger::Level::Fatal);
1639  }
1640 
1641  V(pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false));
1642  V(pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS));
1643 
1644  // Dynamic textures for license plates and instrumentation
1645  // He has his own BeginScene() and EndScene() so it is not left open
1646 #ifdef _DEBUG
1647  game->otfrTimer->startTimer();
1648 #endif
1649  game->viewscreen->OnFrameRender2(pd3dDevice, fElapsedTime);
1650 #ifdef _DEBUG
1651  game->otfrTimer->stopTimer();
1652 #endif
1653  }
1654  break;
1655  }
1656 
1657  game->logger->AddToCallStack("GameClass::OnFrameRender DONE");
1658 }
1659 
1661 {
1662  if (!ourcockpit.gndvehicle) // can't turn on FD without AFCS
1663  {
1664  // ReSharper disable once CppExpressionWithoutSideEffects
1665  TurnOffDOR();
1666  // ReSharper disable once CppExpressionWithoutSideEffects
1667  TurnOffTVM();
1668 
1669  if (!bus->AFCS.CurrentLateralMode)
1670  {
1671  bus->AFCS.CurrentLateralMode = Bus::Afcs::LateralModes::Roll;
1672  if (fabsf(bus->RollAttitudeRadians) < 0.087266462599716478846184538424431f) // 5°
1673  bus->AFCS.DesiredRollRadians = 0.0f;
1674  else if (fabsf(bus->RollAttitudeRadians) >= D3DX_PI)
1675  bus->AFCS.DesiredRollRadians = 0.0f;
1676  else
1678  }
1680  {
1681  bus->AFCS.CurrentVerticalMode = Bus::Afcs::VerticalModes::Pitch;
1683  }
1684 
1686  }
1687 }
1688 
1689 //--------------------------------------------------------------------------------------
1690 // Before handling window messages, DXUT passes incoming windows
1691 // messages to the application through this callback function. If the application sets
1692 // *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
1693 //--------------------------------------------------------------------------------------
1694 LRESULT CALLBACK GameClass::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext)
1695 {
1696  GameClass* game = static_cast<GameClass*>(pUserContext);
1697  game->logger->AddToCallStack("GameClass::MsgProc");
1698 
1699  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1700  switch (uMsg)
1701  {
1702  case WM_SYSCOMMAND:
1703  if (wParam == SC_RESTORE)
1704  return 0;
1705  break;
1706 
1707 
1708  case WM_CREATE:
1709  {
1710  game->logger->Log("GameClass::MsgProc WM_CREATE");
1711 
1712  DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
1713  ZeroMemory(&NotificationFilter, sizeof DEV_BROADCAST_DEVICEINTERFACE);
1714  NotificationFilter.dbcc_size = sizeof DEV_BROADCAST_DEVICEINTERFACE;
1715  NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
1716  NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
1717  game->dev_notify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
1718  if (game->dev_notify == nullptr)
1719  {
1720  game->logger->Log("Could not register for device notifications!", Logger::Fatal);
1721  }
1722  }
1723  break;
1724 
1725  case WM_CLOSE:
1726  {
1727  game->RequestClose();
1728  *pbNoFurtherProcessing = true;
1729  return 0;
1730  }
1731 
1732  case WM_DEVICECHANGE:
1733  {
1734  game->logger->Log("GameClass::MsgProc WM_DEVICECHANGE");
1735 
1736  if (lParam)
1737  {
1738  const auto lpdb = PDEV_BROADCAST_HDR(lParam);
1739  if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
1740  {
1741  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1742  switch (wParam)
1743  {
1744  case DBT_DEVICEARRIVAL:
1745  case DBT_DEVICEREMOVECOMPLETE:
1746  {
1747  const size_t oldDeviceCount = game->viewscreen->ptrJoystick->deviceList.size();
1749  if (oldDeviceCount != game->viewscreen->ptrJoystick->deviceList.size())
1750  {
1751  game->lastDeviceChangedInput = true;
1752  game->lastDeviceChange = 0.0f;
1753  }
1754  }
1755  break;
1756  }
1757  }
1758  }
1759 
1760  const size_t oldDeviceCount = game->sound->deviceGuids.size();
1761  game->sound->EnumDevices();
1762  if (oldDeviceCount != game->sound->deviceGuids.size())
1763  {
1764  game->lastDeviceChangedSound = true;
1765  game->lastDeviceChange = 0.0f;
1766  }
1767  }
1768  break;
1769 
1770  case WM_ACTIVATE:
1771  game->logger->Log("GameClass::MsgProc WM_ACTIVATE");
1772  break;
1773  case WM_NULL:
1774  game->logger->Log("GameClass::MsgProc WM_NULL");
1775  break;
1776  case WM_DESTROY:
1777  game->logger->Log("GameClass::MsgProc WM_DESTROY");
1778  break;
1779  case WM_ENABLE:
1780  game->logger->Log("GameClass::MsgProc WM_ENABLE");
1781  break;
1782  case WM_SETFOCUS:
1783  game->logger->Log("GameClass::MsgProc WM_SETFOCUS");
1784  break;
1785  case WM_KILLFOCUS:
1786  game->logger->Log("GameClass::MsgProc WM_KILLFOCUS");
1787  break;
1788  case WM_QUIT:
1789  game->logger->Log("GameClass::MsgProc WM_QUIT");
1790  break;
1791  case WM_SHOWWINDOW:
1792  game->logger->Log("GameClass::MsgProc WM_SHOWWINDOW");
1793  break;
1794 
1795  case WM_MOVE:
1796  game->logger->Log("GameClass::MsgProc WM_MOVE");
1797  break;
1798 
1799  case WM_SIZE:
1800  {
1801  game->logger->Log("GameClass::MsgProc WM_SIZE");
1802  if (game->displaystage == GameState::STATUS_GAME && !IsIconic(hWnd))
1803  {
1804  if (DXUTIsWindowed())
1805  {
1806  /*if (wParam == SIZE_RESTORED)
1807  {
1808  if (game->maximized)
1809  game->logger->Log("SIZE_RESTORED, calling ShowWindow SW_MINIMIZE");
1810  else
1811  game->logger->Log("SIZE_RESTORED, calling ShowWindow SW_MAXIMIZE");
1812  ShowWindow(hWnd, game->maximized ? SW_SHOWMINNOACTIVE : SW_MAXIMIZE);
1813  game->maximized = !game->maximized;
1814  }*/
1815 
1816  RECT client;
1817  if (GetClientRect(hWnd, &client)) // && game->maximized)
1818  {
1819  char msg[999];
1820  sprintf_s(msg, 999, "old window resolution width%.0f height%.0f", game->displayWidth, game->displayHeight);
1821  game->logger->Log(msg);
1822  game->displayWidth = static_cast<float>(client.right - client.left);
1823  game->displayHeight = static_cast<float>(client.bottom - client.top);
1824  game->displayscale = game->config.scale;
1825  sprintf_s(msg, 999, "new window resolution width%.0f height%.0f", game->displayWidth, game->displayHeight);
1826  game->logger->Log(msg);
1827  }
1828  }
1829  else
1830  {
1831  char msg[999];
1832  sprintf_s(msg, 999, "old exclusive resolution width%.0f height%.0f", game->displayWidth, game->displayHeight);
1833  game->logger->Log(msg);
1834  game->displayWidth = static_cast<float>(DXUTGetD3D9PresentParameters().BackBufferWidth);
1835  game->displayHeight = static_cast<float>(DXUTGetD3D9PresentParameters().BackBufferHeight);
1836  game->displayscale = game->config.scale;
1837  sprintf_s(msg, 999, "new exclusive resolution width%.0f height%.0f", game->displayWidth, game->displayHeight);
1838  game->logger->Log(msg);
1839  }
1840  }
1841  }
1842  break;
1843  }
1844 
1845 
1846  game->logger->AddToCallStack("GameClass::MsgProc (Before g_HUD.MsgProc)");
1847 
1848  game->GUI->Edited = false;
1849  if (g_bTextInput == 0)
1850  {
1851  // Give the dialogs a chance to handle the message first
1852  *pbNoFurtherProcessing = game->GUI->MsgProc(hWnd, uMsg, wParam, lParam);
1853  if (*pbNoFurtherProcessing)
1854  {
1855  game->GUI->Edited = true;
1856  return 0;
1857  }
1858 
1859  game->logger->AddToCallStack("CDXUTDialog::MsgProc");
1860  *pbNoFurtherProcessing = game->GUI->g_HUD.MsgProc(hWnd, uMsg, wParam, lParam);
1861  if (*pbNoFurtherProcessing)
1862  {
1863  game->GUI->Edited = true;
1864  return 0;
1865  }
1866  }
1867 
1868  game->logger->AddToCallStack("GameClass::MsgProc (After g_HUD.MsgProc)");
1869 
1870  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1871  switch (uMsg)
1872  {
1873  case WM_RBUTTONDOWN:
1874  game->logger->Log("GameClass::MsgProc WM_RBUTTONDOWN");
1875  game->logger->AddToCallStack("GameClass::MsgProc WM_RBUTTONDOWN");
1876  // reset timeout
1877  game->GUI->g_bRightDown = true;
1878  break;
1879 
1880  case WM_RBUTTONUP:
1881  game->logger->Log("GameClass::MsgProc WM_RBUTTONUP");
1882  game->logger->AddToCallStack("GameClass::MsgProc WM_RBUTTONUP");
1883  // reset timeout
1884  game->GUI->g_bRightDown = false;
1885  break;
1886 
1887  case WM_RBUTTONDBLCLK:
1888  game->logger->Log("GameClass::MsgProc WM_RBUTTONDBLCLK");
1889  game->logger->AddToCallStack("GameClass::MsgProc WM_RBUTTONDBLCLK");
1890  // reset timeout
1891  if (ourcockpit.texturelib != VehicleType::Apartment &&
1892  ourcockpit.texturelib != VehicleType::SimBay &&
1893  ourcockpit.texturelib != VehicleType::ControlTower)
1894  {
1895  game->viewscreen->targetLeftright = 0.0f;
1896  game->viewscreen->targetUpdown = -D3DXToRadian(10.0f);
1897  game->viewscreen->rolltilt = 0.0f;
1898  }
1899  else
1900  {
1901  game->viewscreen->targetLeftright = game->viewscreen->targetUpdown = game->viewscreen->rolltilt = 0.0f;
1902  }
1903  if (game->GUI->informationDialog) // unavailable until STATUS_GAME
1905  break;
1906 
1907  case WM_CHAR:
1908  game->logger->Log("GameClass::MsgProc WM_CHAR");
1909  game->logger->AddToCallStack("GameClass::MsgProc WM_CHAR");
1910  if (g_bTextInput)
1911  {
1912  if (LOWORD(wParam) > 13) // valid ascii
1913  {
1914  if (strlen(outgoing) < 77)
1915  sprintf_s(outgoing, sizeof(outgoing), "%s%c", outgoing, LOWORD(wParam));
1916  }
1917  else if (LOWORD(wParam) == 13) // enter
1918  {
1919  if (g_bTextInput == 2) // server menu line input
1920  {
1921  // Send it
1922  SPacketBig outpacket = SPacketBig();
1923  strcpy_s(outpacket.msg, sizeof outpacket.msg, outgoing);
1924  outpacket.type = 6; // Requested line input
1925  outpacket.array = 0;
1926  game->networking->SendToServer(&outpacket, sizeof(SPacketBig), true);
1927  g_bTextInput = 0;
1928 
1929  if (!interactive.avail)
1930  game->displays->RestorePage("MFD");
1931  }
1932  else if (g_bTextInput == 5) // cash transfer
1933  {
1934  int amount;
1935  if (sscanf_s(outgoing, "%d", &amount) == 1 && amount > 0.0f)
1936  {
1937  if (!playerships[0].simulator)
1938  {
1939  SClientPacket outpacket; // NOLINT
1940  outpacket.type = 19; // cash/fuel/weapon transfer
1941  outpacket.f_x = static_cast<float>(amount); // cash
1942  outpacket.f_y = 0.0f; // fuel
1943  outpacket.f_z = 0.0f; // weapon
1944  outpacket.f_w = static_cast<float>(temptarget);
1945  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1946  }
1947  }
1948  else
1949  {
1951  }
1952  g_bTextInput = 0;
1953  }
1954  else if (g_bTextInput == 6) // fuel transfer
1955  {
1956  int amount;
1957  if (sscanf_s(outgoing, "%d", &amount) == 1)
1958  {
1959  if (!playerships[0].simulator)
1960  {
1961  SClientPacket outpacket; // NOLINT
1962  outpacket.type = 19; // cash/fuel/weapon transfer
1963  outpacket.f_x = 0.0f; // cash
1964  outpacket.f_y = static_cast<float>(amount); // fuel
1965  outpacket.f_z = 0.0f; // weapon
1966  outpacket.f_w = static_cast<float>(temptarget);
1967  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1968  }
1969  }
1970  else
1971  {
1973  }
1974  g_bTextInput = 0;
1975  }
1976  else if (g_bTextInput == 8) // fuel jettison
1977  {
1978  int amount;
1979  if (sscanf_s(outgoing, "%d", &amount) == 1 && amount < 0)
1980  {
1981  if (-amount > fuel / Kg2Lbs)
1982  {
1984  }
1985  else
1986  {
1987  fuel += amount * Kg2Lbs;
1988 
1989  SClientPacket outpacket; // NOLINT
1990  outpacket.type = 4; // jettison fuel
1991  outpacket.f_x = -static_cast<float>(amount); // fuel lbs
1992  outpacket.f_y = 0.0f; // unused
1993  outpacket.f_z = 0.0f; // unused
1994  outpacket.f_w = 0.0f; // unused
1995  game->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1996  }
1997  }
1998  else
1999  {
2001  }
2002  g_bTextInput = 0;
2003  }
2004 
2005  }
2006  else if (LOWORD(wParam) == 8) // backspace
2007  {
2008  if (strlen(outgoing) > 0)
2009  outgoing[strlen(outgoing) - 1] = 0;
2010  }
2011  }
2012  break;
2013  }
2014 
2015  game->logger->AddToCallStack("GameClass::MsgProc END");
2016 
2017  return 0;
2018 }
2019 
2020 void GameClass::LoadTexture(LPDIRECT3DTEXTURE9* resource, const std::string& pointerName, const WCHAR* file, D3DFORMAT format)
2021 {
2022  logger->AddToCallStack("GameClass::LoadTexture");
2023 
2024  // release
2025  if (*resource)
2026  {
2027  SAFE_RELEASE(*resource);
2028  UpdateTrackedResource(pointerName.c_str(), 3);
2029  char msg[199];
2030  sprintf_s(msg, 199, "Resource was not previously released: %s", pointerName.c_str());
2031  logger->Log(msg, Logger::Level::Error);
2032  }
2033 
2034  if (!file[0])
2035  {
2036  char msg[199];
2037  sprintf_s(msg, 199, "Filename was blank for: %s", pointerName.c_str());
2038  logger->Log(msg, Logger::Level::Debug);
2039  return;
2040  }
2041 
2042  HRESULT hr;
2043  if (FAILED(hr = D3DXCreateTextureFromFileExW(DXUTGetD3D9Device(), file, D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, format,
2044  D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, nullptr, nullptr, resource)))
2045  {
2046  char msg[199];
2047  if (hr == D3DERR_INVALIDCALL)
2048  sprintf_s(msg, 199, "Cannot load texture: %S (D3DERR_INVALIDCALL)", file);
2049  else if (hr == D3DERR_NOTAVAILABLE)
2050  sprintf_s(msg, 199, "Cannot load texture: %S (D3DERR_NOTAVAILABLE)", file);
2051  else if (hr == D3DERR_OUTOFVIDEOMEMORY)
2052  sprintf_s(msg, 199, "Cannot load texture: %S (D3DERR_OUTOFVIDEOMEMORY)", file);
2053  else if (hr == D3DXERR_INVALIDDATA)
2054  sprintf_s(msg, 199, "Cannot load texture: %S (D3DXERR_INVALIDDATA)", file);
2055  else if (hr == E_OUTOFMEMORY)
2056  sprintf_s(msg, 199, "Cannot load texture: %S (E_OUTOFMEMORY)", file);
2057  else
2058  sprintf_s(msg, 199, "Cannot load texture: %S (0x%x)", file, hr);
2059  logger->Log(msg, Logger::Fatal);
2060  return;
2061  }
2062 
2063  AddTrackedResource(pointerName.c_str()); // managed
2064 
2065  TouchFile(file);
2066 
2067  logger->AddToCallStack("GameClass::LoadTexture DONE");
2068 }
2069 
2071 {
2072  logger->AddToCallStack("GameClass::GearUpShift");
2073  if (ourcockpit.power < 0.5f) return;
2074 
2075  const char oldgear = ourcockpit.gearshift;
2079  else
2080  {
2081  const float tach = viewscreen->ptrPropulsion->GetTach();
2083  if (ourcockpit.gearshift == -1) // reverse
2084  {
2085  if (ourcockpit.texturelib == T27 || ourcockpit.texturelib == T120 || ourcockpit.texturelib == T121)
2086  {
2087  SClientPacket outpacket; // NOLINT
2088  outpacket.type = 23; // Universe sound
2089  outpacket.f_x = 0.0f; // car noise
2090  outpacket.f_y = 2.0f; // brakes off
2091  outpacket.f_z = 0.0f; // NULL
2092  outpacket.f_w = 0.0f; // NULL
2093  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2095 
2096  outpacket.type = 23; // Universe sound
2097  outpacket.f_x = 0.0f; // car noise
2098  outpacket.f_y = 3.0f; // reverse on
2099  outpacket.f_z = 0.0f; // NULL
2100  outpacket.f_w = 0.0f; // NULL
2101  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2103  }
2104  if (tach > 0.5f)
2105  sound->PlayEx(SOUND_GEARGRIND, false, sound->GetAttenuation(true));
2106  }
2107  else if (oldgear == -1) // reverse
2108  {
2109  if (ourcockpit.texturelib == T27 || ourcockpit.texturelib == T120 || ourcockpit.texturelib == T121)
2110  {
2111  SClientPacket outpacket; // NOLINT
2112  outpacket.type = 23; // Universe sound
2113  outpacket.f_x = 0.0f; // car noise
2114  outpacket.f_y = 4.0f; // reverse off
2115  outpacket.f_z = 0.0f; // NULL
2116  outpacket.f_w = 0.0f; // NULL
2117  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2119  }
2120  }
2121  if (ourcockpit.gearshift == 1) // 1
2122  {
2123  if (locvelcomp.z >= 0.002f || tach > 0.5f)
2124  sound->PlayEx(SOUND_GEARGRIND, false, sound->GetAttenuation(true));
2126  }
2128  }
2129 
2131 }
2132 
2134 {
2135  logger->AddToCallStack("GameClass::GearDownShift");
2136  if (ourcockpit.power < 0.5f) return;
2137 
2138  const float tach = viewscreen->ptrPropulsion->GetTach();
2141  if (ourcockpit.gearshift < -2)
2142  ourcockpit.gearshift = -2;
2143  else
2144  {
2145  if (ourcockpit.gearshift == -2) // park
2146  {
2147  if (locvelcomp.z >= 0.002f)
2148  sound->PlayEx(SOUND_GEARGRIND, false, sound->GetAttenuation(true));
2149  if (ourcockpit.texturelib == T27 || ourcockpit.texturelib == T120 || ourcockpit.texturelib == T121)
2150  {
2151  SClientPacket outpacket; // NOLINT
2152  outpacket.type = 23; // Universe sound
2153  outpacket.f_x = 0.0f; // car noise
2154  outpacket.f_y = 1.0f; // brakes on
2155  outpacket.f_z = 0.0f; // NULL
2156  outpacket.f_w = 0.0f; // NULL
2157  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2159 
2160  outpacket.type = 23; // Universe sound
2161  outpacket.f_x = 0.0f; // car noise
2162  outpacket.f_y = 4.0f; // reverse off
2163  outpacket.f_z = 0.0f; // NULL
2164  outpacket.f_w = 0.0f; // NULL
2165  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2167  }
2168  }
2169  else if (ourcockpit.gearshift == -1) // reverse
2170  {
2171  if (-locvelcomp.z >= 0.002f || tach > 0.5f)
2172  sound->PlayEx(SOUND_GEARGRIND, false, sound->GetAttenuation(true));
2173  if (ourcockpit.texturelib == T27 || ourcockpit.texturelib == T120 || ourcockpit.texturelib == T121)
2174  {
2175  SClientPacket outpacket; // NOLINT
2176  outpacket.type = 23; // Universe sound
2177  outpacket.f_x = 0.0f; // car noise
2178  outpacket.f_y = 3.0f; // reverse on
2179  outpacket.f_z = 0.0f; // NULL
2180  outpacket.f_w = 0.0f; // NULL
2181  networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2183  }
2184  }
2186  }
2187 
2189 }
2190 
2191 void GameClass::LostScannerTarget(const char* msg) const
2192 {
2193  logger->AddToCallStack("GameClass::LostScannerTarget");
2194 
2195  if (bus->targetC == -1)
2196  {
2197  char bug[199];
2198  sprintf_s(bug, 199, "That's weird, tried to lose scanner target but already -1: %s", msg);
2199  logger->Log(bug, Logger::Level::Debug);
2200  return;
2201  }
2202 
2203  bus->targetC = -1;
2205 
2206  if (ourcockpit.gndvehicle)
2207  {
2209  return;
2210  }
2211 
2212  if (bus->AFCS.CurrentLateralMode >= Bus::Afcs::LateralModes::Navigation)
2213  {
2215  bus->AFCS.CurrentLateralMode = Bus::Afcs::LateralModes::Roll;
2216  }
2217 
2218  // ReSharper disable once CppExpressionWithoutSideEffects
2219  TurnOffTVM();
2220 }
2221 
2223 {
2224  logger->AddToCallStack("GameClass::LostVerticalTarget");
2225 
2226  if (bus->AFCS.CurrentVerticalMode >= Bus::Afcs::VerticalModes::AltitudeAgl)
2227  {
2229  bus->AFCS.CurrentVerticalMode = Bus::Afcs::VerticalModes::Pitch;
2230  }
2231 }
2232 
2234 {
2235  logger->AddToCallStack("GameClass::AutopilotDisconnect");
2236  if (!bus->AFCS.AutopilotEngaged) return;
2237 
2238  bus->AFCS.AutopilotEngaged = false;
2239  if (!ourcockpit.gndvehicle && ourcockpit.power > 0.5f)
2241 }
2242 
2244 {
2245  logger->AddToCallStack("GameClass::TurnOffTVM");
2246 
2247  if (bus->AFCS.TvmOn)
2248  {
2249  bus->AFCS.TvmOn = false;
2251  bus->AFCS.DesiredClosingSpeed = 0.0f; // reset
2252  for (int i = 0; i < MAX_ENGINES; i++)
2253  {
2254  bus->EngineThrustLever[i] = 0.0f;
2255  bus->ThrustReverserCommand[i] = false;
2256  }
2257  return true; // NOLINT(readability-simplify-boolean-expr)
2258  }
2259  return false;
2260 }
2261 
2263 {
2264  logger->AddToCallStack("GameClass::TurnOffDOR");
2265 
2266  if (bus->AFCS.DorOn)
2267  {
2268  bus->AFCS.DorOn = false;
2270  bus->AFCS.DesiredClosingSpeed = 0.0f; // reset
2271  for (int i = 0; i < MAX_ENGINES; i++)
2272  {
2273  bus->EngineThrustLever[i] = 0.0f;
2274  bus->ThrustReverserCommand[i] = false;
2275  }
2276  return true; // NOLINT(readability-simplify-boolean-expr)
2277  }
2278  return false;
2279 }
2280 
2281 //--------------------------------------------------------------------------------------
2282 // As a convenience, DXUT inspects the incoming windows messages for
2283 // keystroke messages and decodes the message parameters to pass relevant keyboard
2284 // messages to the application. The framework does not remove the underlying keystroke
2285 // messages, which are still passed to the application's MsgProc callback.
2286 //--------------------------------------------------------------------------------------
2287 void CALLBACK GameClass::KeyboardProc(UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext)
2288 {
2289  GameClass* game = static_cast<GameClass*>(pUserContext);
2290 
2291  char msg[99];
2292  sprintf_s(msg, 99, "KeyboardProc START %i %i %i", game->displaystage, nChar, bKeyDown ? 1 : 0);
2293  game->logger->AddToCallStack(msg);
2294 
2295  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2296  switch (game->displaystage)
2297  {
2299  if (bKeyDown)
2300  {
2301  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2302  switch (nChar)
2303  {
2304 #ifdef _DEBUG
2305  case VK_SPACE:
2306  game->sound->loopintro = false;
2307  Sound::AdvanceStage(NULL, NULL, NULL, game->sound);
2308  break;
2309 #endif
2310 
2311  case VK_ESCAPE:
2312  PostQuitMessage(0);
2313  break;
2314  }
2315 }
2316  break;
2317 
2319  if (bKeyDown)
2320  {
2321  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2322  switch (nChar)
2323  {
2324  case VK_RETURN:
2325  if (game->GUI->g_HUD.GetEditBox(IDC_CALLSIGN) && game->GUI->g_HUD.GetEditBox(IDC_PASSWORD))
2326  {
2327  if (game->GUI->g_HUD.GetEditBox(IDC_CALLSIGN)->m_bHasFocus)
2328  {
2329  CDXUTDialog::ClearFocus();
2330  game->GUI->g_HUD.RequestFocus(game->GUI->g_HUD.GetEditBox(IDC_PASSWORD));
2331  }
2332  else if (game->GUI->g_HUD.GetEditBox(IDC_PASSWORD)->m_bHasFocus)
2333  {
2334  CDXUTDialog::ClearFocus();
2335  HMI::OnGUIEvent(0, IDC_LOGIN, nullptr, game->GUI);
2336  }
2337  }
2338  break;
2339 
2340  case VK_ESCAPE:
2341  PostQuitMessage(0);
2342  break;
2343  }
2344  }
2345  break;
2346 
2348  if (bKeyDown)
2349  {
2350  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2351  switch (nChar)
2352  {
2353  case VK_ESCAPE:
2354  PostQuitMessage(0);
2355  break;
2356 
2357 #ifdef _DEBUG
2358  case VK_F5:
2359  game->LoadTexture(&game->GUI->m_pddsGUIInterlace, "m_pddsGUIInterlace", L"Textures\\Immigration.png");
2360  game->LoadTexture(&game->graphics->m_pddsCloudBaseMapAndNetwork, "m_pddsCloudBaseMapAndNetwork", L"Textures\\Network.png");
2361  break;
2362 #endif
2363  }
2364  }
2365  break;
2366 
2368  if (bKeyDown)
2369  {
2370  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2371  switch (nChar)
2372  {
2373  case VK_SPACE:
2374  game->sound->loopintro = false;
2375  Sound::AdvanceStage(NULL, NULL, NULL, game->sound);
2376  break;
2377 
2378  case VK_ESCAPE:
2379  PostQuitMessage(0);
2380  break;
2381 
2382 #ifdef _DEBUG
2383  case VK_F5:
2384  game->LoadTexture(&game->GUI->m_pddsGUIActions, "m_pddsGUIActions", L"Textures\\eyezoomtest.png", D3DFMT_R8G8B8);
2385  break;
2386 #endif
2387  }
2388  }
2389  break;
2390 
2392  if (bKeyDown)
2393  {
2394  sprintf_s(msg, 99, "KeyboardProc key %x", nChar);
2395  game->logger->AddToCallStack(msg);
2396 
2397  //Switching on the values passed to KeyboardProc, see http://www.tweakvb.com/cheat2000.pdf
2398  //things that require the key to be held down CAN'T go in this section
2399  //only things that can take a single key or key repeats can go here (that we want to slow down)
2400  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2401  switch (nChar)
2402  {
2403  case VK_ESCAPE:
2404  {
2405  for (int i = 0; i < D_ENUMERATION; i++)
2406  DialogBase::dialogs[i]->ClearEdit();
2407  }
2408  break;
2409 
2410  case VK_RETURN:
2411  {
2412  if (bAltDown)
2413  {
2414  game->config.g_bStartFullscreen = DXUTIsWindowed();
2417  }
2418  }
2419  break;
2420 
2421  case VK_F4:
2422  {
2423  if (!g_bShift)
2424  {
2425  game->displays->ChangeCockpit();
2426 
2427  D3DXSaveTextureToFile(L"texture.bmp", D3DXIFF_BMP, game->viewscreen->m_pddsDynamicTexture, nullptr);
2428 
2429  if (playerships[0].simulator)
2430  D3DXSaveTextureToFile(L"projection.bmp", D3DXIFF_BMP, game->viewscreen->m_pddsProjectionTexture, nullptr);
2431  }
2432  else if (game->GUI->IsAdmin)
2433  {
2434  game->viewscreen->LoadVehicleProfile(0, true);
2435  }
2436  }
2437  break;
2438 
2439  case VK_F2:
2440  {
2441  if (game->GUI->IsAdmin)
2442  {
2443  if (!g_bShift)
2444  {
2445  game->config.language = 1;
2446  game->networking->RequestVerbiage(35);
2447  }
2448  else
2449  {
2450 
2451  DWORD dwShaderFlags = D3DXSHADER_OPTIMIZATION_LEVEL3;
2452 #ifdef DEBUG_VS
2453  dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
2454 #endif
2455 #ifdef DEBUG_PS
2456  dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
2457 #endif
2458  SAFE_RELEASE(game->graphics->g_pEffect);
2459  game->UpdateTrackedResource("g_pEffect", 3);
2460  HRESULT hr = D3DXCreateEffectFromFile(DXUTGetD3D9Device(), L"CustomUI.fx", nullptr, nullptr, dwShaderFlags, nullptr, &game->graphics->g_pEffect, nullptr);
2461  if (!SUCCEEDED(hr))
2462  game->logger->Log("Graphics::LoadShaderFile D3DXCreateEffectFromFile", Logger::Level::Fatal, hr);
2463  game->AddTrackedResource("g_pEffect", D3DPOOL_FORCE_DWORD);
2464  V(game->graphics->g_pEffect->SetTechnique("TShader"));
2465  }
2466  }
2467  }
2468  break;
2469  }
2470 
2472  if (g_bTextInput || game->GUI->Editing || game->GUI->Edited)
2473  return;
2474 
2475  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2476  switch (nChar)
2477  {
2478  case VK_DIVIDE:
2479  case VK_OEM_2:
2480  case 0xC1: // @bug 0001702: @timelord plays Rise on a laptop so some of his keybidings are wrong
2481  {
2482  if (ourcockpit.gndvehicle)
2483  {
2484  game->GearDownShift();
2485  }
2486  else
2487  {
2488  if (!game->bus->AFCS.TvmOn && !game->bus->AFCS.DorOn)
2489  {
2490  for (int i = 0; i < MAX_ENGINES; i++)
2491  {
2492  game->bus->EngineThrustLever[i] = 0.0f;
2493  }
2494  }
2495  else
2496  {
2497  game->bus->AFCS.DesiredClosingSpeed -= 1.0f;
2498  }
2499  }
2500  }
2501  break;
2502  case VK_MULTIPLY:
2503  case 56: // 8
2504  {
2506  if (nChar == 56 && !g_bShift)
2507  break;
2508 
2509  if (ourcockpit.gndvehicle)
2510  {
2511  game->GearUpShift();
2512  }
2513  else
2514  {
2515  if (!game->bus->AFCS.TvmOn && !game->bus->AFCS.DorOn)
2516  {
2517  for (int i = 0; i < MAX_ENGINES; i++)
2518  {
2519  game->bus->EngineThrustLever[i] = 1.0f;
2520  }
2521  }
2522  else
2523  {
2524  game->bus->AFCS.DesiredClosingSpeed += 1.0f;
2525  }
2526  }
2527  }
2528  break;
2529  }
2530  }
2531  break;
2532  }
2533 
2534  game->logger->AddToCallStack("GameClass::KeyboardProc END");
2535 }
2536 
2537 //--------------------------------------------------------------------------------------
2538 // This callback function will be called immediately after the Direct3D device has
2539 // entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
2540 // in the OnResetDevice callback should be released here, which generally includes all
2541 // D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for
2542 // information about lost devices.
2543 //--------------------------------------------------------------------------------------
2544 void CALLBACK GameClass::OnLostDevice(void* pUserContext)
2545 {
2546  GameClass* game = static_cast<GameClass*>(pUserContext);
2547 
2548  game->logger->AddToCallStack("GameClass::OnLostDevice");
2549  game->logger->Log("Calling OnLostDevice()...");
2550 
2551  // ReSharper disable once CppEntityAssignedButNoRead
2552  HRESULT hr;
2553 
2554  V(game->graphics->g_pEffect->OnLostDevice());
2555  game->UpdateTrackedResource("g_pEffect", 1);
2556 
2557  game->GUI->g_DialogResourceManager.OnD3D9LostDevice();
2558  game->UpdateTrackedResource("g_DialogResourceManager", 1);
2559 
2560  if (game->GUI->g_pFont)
2561  {
2562  V(game->GUI->g_pFont->OnLostDevice());
2563  game->UpdateTrackedResource("g_pFont", 1);
2564  }
2565  if (game->GUI->g_pChatFont)
2566  {
2567  V(game->GUI->g_pChatFont->OnLostDevice());
2568  game->UpdateTrackedResource("g_pChatFont", 1);
2569  }
2570 
2571  if (game->GUI->g_pTextSprite)
2572  {
2573  V(game->GUI->g_pTextSprite->OnLostDevice());
2574  game->UpdateTrackedResource("g_pTextSprite", 1);
2575  }
2576 
2577  if (game->displaystage >= GameState::STATUS_LOGIN) // was LOADING but missed a bunch of stuff in lost device
2578  game->viewscreen->OnLostDevice();
2579 
2580  if (game->displaystage == GameState::STATUS_GAME)
2581  game->displays->OnLostDevice();
2582 
2583  game->logger->Log("OnLostDevice() done!");
2584 
2585  for (size_t t = 0; t < game->trackedResources.size(); t++)
2586  {
2587  if (game->trackedResources.at(t).pool != D3DPOOL_MANAGED &&
2588  game->trackedResources.at(t).status != 1 && game->trackedResources.at(t).status != 3)
2589  {
2590  char msg[199];
2591  sprintf_s(msg, 199, "Resource not set to lost: %s", game->trackedResources.at(t).name);
2592  game->logger->Log(msg, Logger::Level::Error);
2593  }
2594  }
2595 }
2596 
2597 //--------------------------------------------------------------------------------------
2598 // This callback function will be called immediately after the Direct3D device has
2599 // been destroyed, which generally happens as a result of application termination or
2600 // windowed/full screen toggles. Resources created in the OnCreateDevice callback
2601 // should be released here, which generally includes all D3DPOOL_MANAGED resources.
2602 //--------------------------------------------------------------------------------------
2603 void CALLBACK GameClass::OnDestroyDevice(void* pUserContext)
2604 {
2605  GameClass* game = static_cast<GameClass*>(pUserContext);
2606  game->logger->AddToCallStack("GameClass::OnDestroyDevice");
2607  game->logger->Log("Calling OnDestroyDevice()...");
2608 
2609  game->GUI->OnDestroyDevice();
2610  game->graphics->OnDestroyDevice();
2611 
2612  //if (game->displaystage >= GameState::STATUS_LOADING)
2613  game->viewscreen->OnDestroyDevice();
2614 
2615  if (game->displaystage == GameState::STATUS_GAME)
2616  game->displays->OnDestroyDevice();
2617 
2618  game->logger->AddToCallStack("TrackedResourcesCheck");
2619 
2620  bool found = false;
2621  char msg[199];
2622  for (UINT i = 0; i < game->trackedResources.size(); i++)
2623  {
2624  if (game->trackedResources.at(i).status != 3) // not released
2625  {
2626  if (!found)
2627  {
2628  game->logger->Log("Resources that haven't been freed:", Logger::Level::Warn);
2629  found = true;
2630  }
2631  sprintf_s(msg, 199, " --> %s", game->trackedResources.at(i).name);
2632  game->logger->Log(msg, Logger::Level::Warn);
2633  }
2634  }
2635  if (!found)
2636  game->logger->Log("All tracked resources have been freed!");
2637 
2638  // no idea why but I get 1 reference left even with all of my state management
2639  DXUTGetD3D9Device()->Release();
2640 
2641  game->logger->Log("OnDestroyDevice() done!");
2642 }
2643 
2644 void GameClass::GetProgramVersion(int& major, int& minor, int& build, int& revision) const
2645 {
2646  WCHAR filename[MAX_PATH];
2647  GetModuleFileName(nullptr, filename, MAX_PATH);
2648 
2649  char msg[MAX_PATH];
2650  sprintf_s(msg, MAX_PATH, "Executable: %S", filename);
2651  logger->Log(msg);
2652 
2653  const DWORD dwSize = GetFileVersionInfoSize(filename, nullptr);
2654  if (dwSize == 0)
2655  {
2656  sprintf_s(msg, MAX_PATH, "Error in GetFileVersionInfoSize: %d", GetLastError());
2657  logger->Log(msg, Logger::Fatal);
2658  return;
2659  }
2660 
2661  BYTE* pbVersionInfo = new BYTE[dwSize];
2662 
2663  if (!GetFileVersionInfo(filename, 0, dwSize, pbVersionInfo))
2664  {
2665  sprintf_s(msg, MAX_PATH, "Error in GetFileVersionInfo: %d", GetLastError());
2666  logger->Log(msg, Logger::Fatal);
2667  SAFE_DELETE_ARRAY(pbVersionInfo);
2668  return;
2669  }
2670 
2671  LPBYTE p = nullptr;
2672  UINT querySize;
2673  if (!VerQueryValue(pbVersionInfo, TEXT("\\"), reinterpret_cast<VOID FAR * FAR*>(&p), &querySize))
2674  {
2675  sprintf_s(msg, MAX_PATH, "Error in VerQueryValue: %d", GetLastError());
2676  logger->Log(msg, Logger::Fatal);
2677  SAFE_DELETE_ARRAY(pbVersionInfo);
2678  return;
2679  }
2680 
2681  // pFileInfo->dwFileVersionMS is usually zero. However, you should check
2682  // this if your version numbers seem to be wrong
2683  VS_FIXEDFILEINFO* verInfo = reinterpret_cast<VS_FIXEDFILEINFO*>(p);
2684  major = HIWORD(verInfo->dwFileVersionMS);
2685  minor = LOWORD(verInfo->dwFileVersionMS);
2686  build = HIWORD(verInfo->dwFileVersionLS);
2687  revision = LOWORD(verInfo->dwFileVersionLS);
2688 
2689  SAFE_DELETE_ARRAY(pbVersionInfo);
2690 }
2691 
2693 {
2694  const DWORD64 start = __rdtsc();
2695  Sleep(1000);
2696  const DWORD64 end = __rdtsc();
2697  const DWORD64 hz = end - start;
2698  const DWORD64 mhz = hz / 1000000;
2699  return static_cast<float>(mhz);
2700 }
2701 
2702 void GameClass::AddTrackedResource(const char* name, _D3DPOOL pool)
2703 {
2704  assert(strlen(name) < 32);
2705  for (UINT i = 0; i < trackedResources.size(); i++)
2706  {
2707  if (_strcmpi(trackedResources.at(i).name, name) == 0)
2708  {
2709  if (trackedResources.at(i).status != 1 && trackedResources.at(i).status != 3)
2710  {
2711  char msg[199];
2712  sprintf_s(msg, 199, "GameClass::AddTrackedResource Already Tracking: %s (%i)", name, trackedResources.at(i).status);
2713  logger->Log(msg, Logger::Level::Warn);
2714  }
2715  else
2716  {
2717  trackedResources.at(i).status = 0;
2718  }
2719  return;
2720  }
2721  }
2722  trackedResources.emplace_back(Resource(name, pool));
2723 }
2724 
2725 void GameClass::UpdateTrackedResource(const char* name, int status)
2726 {
2727  assert(status != 0);
2728  assert(strlen(name) < 32);
2729  for (UINT i = 0; i < trackedResources.size(); i++)
2730  {
2731  if (_strcmpi(trackedResources.at(i).name, name) == 0)
2732  {
2733  if (status == trackedResources.at(i).status)
2734  {
2735  char msg[199];
2736  sprintf_s(msg, 199, "GameClass::UpdateTrackedResource %s already status %i", name, status);
2737  logger->Log(msg, Logger::Level::Warn);
2738  }
2739  else if (status == 2 && trackedResources.at(i).status == 3) // can't go to "reset" from anything but "lost" or "created"
2740  {
2741  char msg[199];
2742  sprintf_s(msg, 199, "GameClass::UpdateTrackedResource %s status transition %i", name, status);
2743  logger->Log(msg, Logger::Level::Warn);
2744  }
2745  else
2746  {
2747  trackedResources.at(i).status = status;
2748  }
2749  return;
2750  }
2751  }
2752 #ifdef _DEBUG
2753  char msg[199];
2754  sprintf_s(msg, 199, "GameClass::UpdateTrackedResource Wasn't Tracking: %s", name);
2755  logger->Log(msg, Logger::Level::Warn);
2756 #endif
2757 }
float rolltilt
Definition: Viewscreen.h:313
HRESULT EnumDevices()
Definition: joystick.cpp:350
void Initialize(HWND prmHWND)
Definition: joystick.cpp:325
LPDIRECT3DTEXTURE9 m_pddsGUIInterlace
Definition: gui.h:733
bool DismissHelp(int helpId, int nControlID=GUI_UNDERSTOOD)
Scockpit ourcockpit
Definition: globals.cpp:176
Definition: gui.h:399
int inventoryItemInUseType
Definition: globals.h:687
static void CALLBACK OnLostDevice(void *pUserContext)
Definition: GameClass.cpp:2544
#define designedHeightC
Definition: GameClass.h:23
bool TurnOffTVM() const
Definition: GameClass.cpp:2243
void SendScreenShot(const char *fileContents, int length) const
Definition: Networking.cpp:140
#define MAX_ENGINES
Definition: Bus.h:14
bool Edited
Definition: gui.h:778
ID3DXEffect * g_pEffect
Definition: Graphics.h:30
int intentoryItemInUseVehicleId
Definition: globals.h:688
void OnResetDevice()
Definition: gui.cpp:1000
int screenShotStatus
Definition: GameClass.h:105
static void CALLBACK KeyboardProc(UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext)
Definition: GameClass.cpp:2287
std::vector< DIDEVICEINSTANCE > deviceList
Definition: joystick.h:27
std::vector< Resource > trackedResources
Definition: GameClass.h:50
float power
Definition: globals.h:608
virtual void UpdateMenu(short tab)
bool bValue
Definition: Command.h:22
void InitApp()
Definition: gui.cpp:1675
static void CALLBACK OnDestroyDevice(void *pUserContext)
Definition: GameClass.cpp:2603
float fuel
Definition: globals.cpp:143
struct Bus::Afcs AFCS
float targetLeftright
Definition: Viewscreen.h:311
Definition: Sound.h:276
bool oldvphelp[128]
Definition: config.h:18
void DrawImmigration(IDirect3DDevice9 *pd3dDevice, float fElapsedTime)
Definition: Graphics.cpp:170
Config config
Definition: GameClass.h:102
LPDIRECT3DTEXTURE9 m_pddsGUIRanks
Definition: gui.h:740
int ivalues[2]
Definition: Command.h:21
void Close()
Definition: Networking.cpp:48
void SetNetworkingPointer(Networking *prmNetworking)
Definition: Logger.cpp:105
unsigned char language
Definition: config.h:12
BOOL IsDepthFormatOk(D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat) const
Definition: GameClass.cpp:470
std::vector< Command > commandStream
Definition: Bus.h:342
GameState displaystage
Definition: GameClass.h:121
unsigned char beginScene
Definition: GameClass.h:126
bool radioPower
Definition: globals.h:606
Definition: Logger.h:9
void RequestWaypointData() const
Definition: waypoints.cpp:14
HRESULT OnCreateDevice(IDirect3DDevice9 *pd3dDevice)
Definition: Viewscreen.cpp:418
enum Bus::Afcs::LateralModes CurrentLateralMode
void SendToServer(void *pData, DWORD dwSize, bool bGuaranteed, PacketOrdering order=ORDERING_NONE) const
Definition: Networking.cpp:59
#define designedWidthC
Definition: GameClass.h:22
void EnumDevices()
Definition: Sound.cpp:218
LPDIRECT3DTEXTURE9 m_pddsLightningAndBackground[3]
Definition: Graphics.h:32
bool g_bStartFullscreen
Definition: config.h:23
bool MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: gui.cpp:1046
LPDIRECT3DTEXTURE9 m_pddsGUIActions
Definition: gui.h:739
ID3DXFont * g_pFont
Definition: gui.h:727
Definition: Module.h:443
renderer * ptrRenderer
Definition: Viewscreen.h:286
bool weatherRadarPower
Definition: globals.h:606
scanDb Scanner
Definition: Bus.h:379
Sinteractive interactive
Definition: globals.cpp:183
static LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing, void *pUserContext)
Definition: GameClass.cpp:1694
HRESULT OnResetDevice(void) const
Definition: Graphics.cpp:127
float GetTach() const
InformationDialog * informationDialog
Definition: gui.h:789
short instage
Definition: GameClass.h:124
void AutopilotDisconnect() const
Definition: GameClass.cpp:2233
std::vector< GUID > deviceGuids
Definition: Sound.h:337
HSTREAM g_pSoundIntro
Definition: Sound.h:329
Definition: Module.h:149
HRESULT LoadShaderFile(void)
Definition: Graphics.cpp:354
unsigned short vehicleId
Definition: globals.h:570
s_network_objects playerships[MAX_SCAN]
Definition: globals.cpp:174
waypoints * ptrWaypoints
Definition: Viewscreen.h:290
short texturelib
Definition: globals.h:612
static HRESULT CALLBACK OnResetDevice(IDirect3DDevice9 *pd3dDevice, const D3DSURFACE_DESC *pBackBufferSurfaceDesc, void *pUserContext)
Definition: GameClass.cpp:654
bool DorOn
Definition: Bus.h:130
void OnDestroyDevice()
Definition: Displays.cpp:587
float displayHeight
Definition: GameClass.h:129
bool ComponentRcsRollFail
Definition: Bus.h:382
float RollAttitudeRadians
Definition: Bus.h:37
LPWSTR currentCursor
Definition: gui.h:779
float g_fFOV
Definition: globals.cpp:129
bool g_bGotConclusion
Definition: globals.cpp:150
std::vector< unsigned char > personalInventory
Definition: globals.h:675
void OnFrameRender(IDirect3DDevice9 *pd3dDevice, double fTime) const
Definition: render.cpp:8
static void CALLBACK OnFrameRender(IDirect3DDevice9 *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext)
Definition: GameClass.cpp:1495
void GearUpShift() const
Definition: GameClass.cpp:2070
static float GetCpuSpeedMhz()
Definition: GameClass.cpp:2692
void InitializeGame()
Definition: GameClass.cpp:293
std::vector< Module * > modules
Definition: GameClass.h:117
void ToggleFullScreen(bool goFullScreen)
Definition: GameClass.cpp:269
short scanslot[MAX_SCAN]
Definition: Viewscreen.h:276
short stage
Definition: GameClass.h:124
s_mesh_component * componentarray
Definition: globals.h:678
float cloudmotion
Definition: gui.h:760
void SendEvent(EventType eventType, float extent=0.0f) const
Definition: Networking.cpp:111
float displayWidth
Definition: GameClass.h:129
float DesiredRollRadians
Definition: Bus.h:116
bool ComponentFcsRollFail
Definition: Bus.h:383
static HRESULT CALLBACK OnCreateDevice(IDirect3DDevice9 *pd3dDevice, const D3DSURFACE_DESC *pBackBufferSurfaceDesc, void *pUserContext)
Definition: GameClass.cpp:610
char g_bTextInput
Definition: globals.cpp:108
void Save()
Definition: config.cpp:363
Logger * logger
Definition: GameClass.h:113
bool rxlight
Definition: gui.h:770
joystick * ptrJoystick
Definition: Viewscreen.h:283
void OnDestroyDevice()
void FrameMove(GameState displaystage)
Definition: Networking.cpp:191
float fade
Definition: gui.h:758
D3DXVECTOR3 locvelcomp
Definition: globals.cpp:99
#define vphelpC
Definition: globals.h:64
CDXUTDialogResourceManager g_DialogResourceManager
Definition: gui.h:752
DiscordRPC * discord
Definition: GameClass.h:115
void OnResetDevice()
Definition: Displays.cpp:482
Definition: Bus.h:16
void Close()
Definition: Sound.cpp:375
std::string name
Definition: Command.h:11
bool vphelp[vphelpC]
Definition: GameClass.h:103
float DesiredClosingSpeed
Definition: Bus.h:127
bool ThrustReverserCommand[MAX_ENGINES]
Definition: Bus.h:61
#define Kg2Lbs
Definition: globals.h:31
Definition: config.h:8
static DialogBase * dialogs[D_ENUMERATION]
Definition: DialogBase.h:39
CDXUTDialog g_HUD
Definition: gui.h:710
char fwdgears
Definition: globals.h:652
LPDIRECT3DTEXTURE9 m_pddsGUIParts
Definition: gui.h:731
static bool CALLBACK IsDeviceAcceptable(D3DCAPS9 *pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void *pUserContext)
Definition: GameClass.cpp:505
void OnDestroyDevice()
Definition: gui.cpp:3324
unsigned char configver
Definition: config.h:14
void LostScannerTarget(const char *msg) const
Definition: GameClass.cpp:2191
float targetUpdown
Definition: Viewscreen.h:312
propulsion * ptrPropulsion
Definition: Viewscreen.h:285
GridProperties gridProperties
Definition: grid.h:36
void Initialize()
Definition: Viewscreen.cpp:314
bool TurnOffDOR() const
Definition: GameClass.cpp:2262
#define DIRECTINPUT_VERSION
Definition: keyboard.h:10
float DesiredPitchRadians
Definition: Bus.h:117
bool loopintro
Definition: Sound.h:332
void RequestScannerData() const
Definition: GameClass.cpp:132
void OnLostDevice()
void RequestClose() const
Definition: GameClass.cpp:261
bool IsAdmin
Definition: gui.h:777
void GetProgramVersion(int &major, int &minor, int &build, int &revision) const
Definition: GameClass.cpp:2644
void UseOrDisuseInventoryItemType(int itemtype, int itemId, int vehicleId) const
Definition: GameClass.cpp:729
bool txlight
Definition: gui.h:770
Viewscreen * viewscreen
Definition: GameClass.h:111
void Close()
Definition: GameClass.cpp:72
int inventoryItemInUseId
Definition: globals.h:689
Networking * networking
Definition: GameClass.h:107
keyboard * ptrKeyboard
Definition: Viewscreen.h:282
bool PopUpHelp(short helpId, bool allowDismiss=true, bool isLearnMore=false)
Definition: Module.h:36
static void CALLBACK OnGUIEvent(UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext)
Definition: gui.cpp:2771
SPlayerData player[MAX_ONLINEPLAYERS]
Definition: gui.h:765
void ChangeCockpit()
Definition: Displays.cpp:318
LPDIRECT3DTEXTURE9 m_pddsCloudBaseMapAndNetwork
Definition: Graphics.h:31
char outgoing[80]
Definition: globals.cpp:107
void RepairVehicle() const
Definition: GameClass.cpp:168
void FadeIn(float f, float fElapsedTime)
Definition: gui.cpp:4478
void OnLostDevice()
Definition: Displays.cpp:473
bool vdatChanged
Definition: globals.h:670
unsigned short temptarget
Definition: globals.cpp:119
void LoadLanguage()
Definition: gui.cpp:1480
bool Editing
Definition: gui.h:778
void LoadConfiguration() const
Definition: gui.cpp:1701
bool g_bRightDown
Definition: gui.h:720
void CreateDialogs()
Definition: gui.cpp:2532
void Reset()
Definition: Sound.cpp:583
float lastDeviceChange
Definition: GameClass.h:52
void OnFrameMove(double fTime, float fElapsedTime)
Definition: framemove.cpp:283
void OnFrameRender2(IDirect3DDevice9 *pd3dDevice, float fElapsedTime)
Definition: render.cpp:2445
short txbuffer
Definition: gui.h:772
void KillScannerData() const
Definition: GameClass.cpp:125
float verticaltime
Definition: Viewscreen.h:243
static void CALLBACK AdvanceStage(HSYNC handle, DWORD channel, DWORD data, void *user)
Definition: Sound.cpp:797
short outboundMenuSelect
Definition: globals.h:762
HRESULT InitDirectInput(HWND hDlg) const
Definition: GameClass.cpp:318
void LoadTexture(LPDIRECT3DTEXTURE9 *resource, const std::string &pointerName, const WCHAR *file, D3DFORMAT format=D3DFMT_A8R8G8B8)
Definition: GameClass.cpp:2020
Definition: Module.h:66
Definition: Command.h:5
short targetC
Definition: Bus.h:378
void ScreenCapture() const
Definition: GameClass.cpp:436
void LightningCalculations(float fElapsedTime)
Definition: gui.cpp:4490
HRESULT Initialize(HWND hDlg)
Definition: keyboard.cpp:18
float clutchtime
Definition: globals.h:651
void OnDestroyDevice(void)
Definition: Graphics.cpp:138
enum Bus::Afcs::VerticalModes CurrentVerticalMode
bool lastDeviceChangedInput
Definition: GameClass.h:54
Graphics * graphics
Definition: GameClass.h:109
float eyemotion
Definition: gui.h:756
LPDIRECT3DTEXTURE9 m_pddsDynamicTexture
Definition: Viewscreen.h:201
void FlightDirectorOn() const
Definition: GameClass.cpp:1660
float furtherdelay
Definition: gui.h:757
bool remoteAssayPower
Definition: globals.h:606
Sound * sound
Definition: GameClass.h:108
void SendScreenShot(HBITMAP hbitmap) const
Definition: GameClass.cpp:361
void OnRender(float fElapsedTime, IDirect3DDevice9 *pd3dDevice)
Definition: gui.cpp:1946
void FrameMove(float elapsedTime)
Definition: Sound.cpp:1053
float GetAttenuation(bool applyDensity) const
Definition: Sound.cpp:1062
void LoadVehicleProfile(short t, bool forceCockpitTextures=false)
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
grid * ptrGrid
Definition: Viewscreen.h:279
LPDIRECTINPUT8 g_pDI
Definition: Viewscreen.h:96
bool immigrationPassed
Definition: gui.h:776
void FrameMove(float fElapsed)
Definition: Bus.cpp:15
short rxbuffer
Definition: gui.h:772
Definition: gui.h:696
bool avail
Definition: globals.h:760
bool TvmOn
Definition: Bus.h:126
float deathinhibit
Definition: globals.cpp:51
HRESULT OnCreateDevice(IDirect3DDevice9 *pd3dDevice)
Definition: gui.cpp:1144
float Play(int soundEnum)
Definition: Sound.cpp:577
static void CALLBACK OnFrameMove(double fTime, float fElapsedTime, void *pUserContext)
Definition: GameClass.cpp:771
void UpdatePresence(const char *prmDetails, const char *prmState, const char *prmLargeImageKey)
Definition: DiscordRPC.cpp:44
ID3DXSprite * g_pTextSprite
Definition: gui.h:726
D3DXMATRIX matrixView
Definition: Viewscreen.h:220
void SetProjectionMatrices()
LPDIRECT3DTEXTURE9 m_pddsGUIScrollButton
Definition: gui.h:738
void RestorePage(std::string screenName)
Definition: Displays.cpp:602
void OnFrameMove(float fElapsedTime)
Definition: gui.cpp:212
bool lastDeviceChangedSound
Definition: GameClass.h:53
float scale
Definition: config.h:24
short loadstage
Definition: GameClass.h:122
ID3DXFont * g_pChatFont
Definition: gui.h:728
HMI * GUI
Definition: GameClass.h:110
short ourplyrC
Definition: globals.h:659
tm tm_time
Definition: gui.h:708
void LoadTextures(GameState displaystage, short loadstage)
Definition: gui.cpp:3222
char dead
Definition: globals.cpp:49
void UpdateTelemetry()
Definition: DiscordRPC.cpp:54
void AddTrackedResource(const char *name, _D3DPOOL pool=D3DPOOL_MANAGED)
Definition: GameClass.cpp:2702
#define GUID_DEVINTERFACE_USB_DEVICE
Definition: GameClass.cpp:12
float displayscale
Definition: GameClass.h:128
void LostVerticalTarget() const
Definition: GameClass.cpp:2222
std::vector< Swaypoint > waypoint
Definition: Bus.h:391
bool AutopilotEngaged
Definition: Bus.h:74
void Stop(int soundEnum)
Definition: Sound.cpp:1946
GameState musicstage
Definition: Sound.h:333
LPDIRECT3DTEXTURE9 m_pddsGUIScroll
Definition: gui.h:736
std::wstring strings[L_ENUMERATION]
Definition: gui.h:749
void PlayEx(int soundEnum, bool loop, float volume=1.0f, float frequencyMod=1.0f, float pan=0.0f, bool restart=true)
Definition: Sound.cpp:606
bool gndvehicle
Definition: globals.h:604
bool g_bShift
Definition: globals.cpp:126
void UpdateTrackedResource(const char *name, int status)
Definition: GameClass.cpp:2725
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
Bus * bus
Definition: GameClass.h:112
HRESULT OnResetDevice(IDirect3DDevice9 *pd3dDevice, const D3DSURFACE_DESC *pBackBufferSurfaceDesc)
virtual void ActiveTab()
float clutchhold
Definition: globals.h:651
HDEVNOTIFY dev_notify
Definition: GameClass.h:55
void SaveConfiguration() const
Definition: gui.cpp:1768
void GearDownShift() const
Definition: GameClass.cpp:2133
float lateraltime
Definition: Viewscreen.h:243
void RequestVerbiage(int helpId) const
Definition: Networking.cpp:168
char gearshift
Definition: globals.h:652
std::vector< unsigned char > vehicleInventory
Definition: globals.h:676
void LoadSounds(short instage)
Definition: Sound.cpp:1073
Displays * displays
Definition: GameClass.h:114
void LoadTextures(IDirect3DDevice9 *pd3dDevice, short *stage, short *instage)
Definition: renderer.cpp:19
LPDIRECT3DTEXTURE9 m_pddsProjectionTexture
Definition: Viewscreen.h:203
SAssayGrid assayGrid
Definition: Bus.h:385
static void TouchFile(const WCHAR *str)
Definition: GameClass.cpp:143
bool maximized
Definition: GameClass.h:56
float PitchAttitudeRadians
Definition: Bus.h:36
float EngineThrustLever[MAX_ENGINES]
Definition: Bus.h:264
void Reset()
Definition: scanDb.cpp:9
SVesselDC vdat
Definition: globals.h:669
float FrameElapsedTime
Definition: GameClass.h:119
static bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings *pDeviceSettings, void *pUserContext)
Definition: GameClass.cpp:516
char connectstatus
Definition: Networking.h:91