From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_game_8cpp_source.html | 1692 +++++++++++++++++++++++++++++++ 1 file changed, 1692 insertions(+) create mode 100644 Doc/doxygen/html/_game_8cpp_source.html (limited to 'Doc/doxygen/html/_game_8cpp_source.html') diff --git a/Doc/doxygen/html/_game_8cpp_source.html b/Doc/doxygen/html/_game_8cpp_source.html new file mode 100644 index 0000000..085244a --- /dev/null +++ b/Doc/doxygen/html/_game_8cpp_source.html @@ -0,0 +1,1692 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/Game.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Game.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: Game.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 */
+
10 
+
11 #include "MemDebug.h"
+
12 #include "Game.h"
+
13 #include "Mouse.h"
+
14 #include "Universe.h"
+
15 #include "Screen.h"
+
16 #include "Window.h"
+
17 #include "EventDispatch.h"
+
18 #include "Color.h"
+
19 #include "DataLoader.h"
+
20 #include "Keyboard.h"
+
21 #include "Pcx.h"
+
22 #include "Resource.h"
+
23 #include "Bitmap.h"
+
24 #include "MachineInfo.h"
+
25 #include "Video.h"
+
26 #include "VideoFactory.h"
+
27 #include "VideoSettings.h"
+
28 #include "AviFile.h"
+
29 #include "ContentBundle.h"
+
30 
+
31 // +--------------------------------------------------------------------+
+
32 
+
33 FILE* ErrLog = 0;
+
34 int ErrLine = 0;
+
35 char ErrBuf[256];
+
36 
+
37 Game* game = 0;
+
38 
+
39 bool Game::active = false;
+
40 bool Game::paused = false;
+
41 bool Game::server = false;
+
42 bool Game::show_mouse = false;
+
43 DWORD Game::base_game_time = 0;
+
44 DWORD Game::real_time = 0;
+
45 DWORD Game::game_time = 0;
+
46 DWORD Game::time_comp = 1;
+
47 DWORD Game::frame_number = 0;
+
48 
+
49 const int VIDEO_FPS = 30;
+
50 const double MAX_FRAME_TIME_VIDEO = 1.0 / (double) VIDEO_FPS;
+
51 const double MAX_FRAME_TIME_NORMAL = 1.0 / 5.0;
+
52 const double MIN_FRAME_TIME_NORMAL = 1.0 / 60.0;
+
53 
+ + +
56 
+
57 char Game::panicbuf[256];
+
58 
+
59 static LARGE_INTEGER perf_freq;
+
60 static LARGE_INTEGER perf_cnt1;
+
61 static LARGE_INTEGER perf_cnt2;
+
62 
+
63 // +--------------------------------------------------------------------+
+
64 
+ +
66 : world(0), video_factory(0), video(0), video_settings(0), soundcard(0),
+
67 gamma(128), max_tex_size(2048), screen(0), totaltime(0),
+
68 hInst(0), hwnd(0), frame_rate(0), frame_count(0), frame_count0(0),
+
69 frame_time(0), frame_time0(0), gui_seconds(0), content(0),
+
70 status(Game::OK), exit_code(0), window_style(0), avi_file(0)
+
71 {
+
72  if (!game) {
+
73  panicbuf[0] = 0;
+
74  game = this;
+
75  ZeroMemory(ErrBuf, 256);
+
76 
+
77  video_settings = new(__FILE__,__LINE__) VideoSettings;
+
78 
+
79  is_windowed = false;
+
80  is_active = false;
+
81  is_device_lost = false;
+
82  is_minimized = false;
+
83  is_maximized = false;
+
84  ignore_size_change = false;
+
85  is_device_initialized = false;
+
86  is_device_restored = false;
+
87  }
+
88  else
+
89  status = TOO_MANY;
+
90 }
+
91 
+ +
93 {
+
94  if (game == this)
+
95  game = 0;
+
96 
+
97  delete content;
+
98  delete world;
+
99  delete screen;
+
100  delete video_factory;
+
101  delete video;
+
102  delete soundcard;
+
103  delete video_settings;
+
104  delete avi_file;
+
105 
+
106  if (status == EXIT)
+
107  ShowStats();
+
108 }
+
109 
+
110 // +--------------------------------------------------------------------+
+
111 
+
112 HINSTANCE Game::GetHINST()
+
113 {
+
114  if (game)
+
115  return game->hInst;
+
116 
+
117  return 0;
+
118 }
+
119 
+ +
121 {
+
122  if (game)
+
123  return game->hwnd;
+
124 
+
125  return 0;
+
126 }
+
127 
+ +
129 {
+
130  if (game)
+
131  return game->is_windowed;
+
132 
+
133  return false;
+
134 }
+
135 
+
136 // +--------------------------------------------------------------------+
+
137 
+
138 Text
+
139 Game::GetText(const char* key)
+
140 {
+
141  if (game && game->content && game->content->IsLoaded())
+
142  return game->content->GetText(key);
+
143 
+
144  return key;
+
145 }
+
146 
+
147 // +--------------------------------------------------------------------+
+
148 
+
149 int
+ +
151 {
+
152  if (game)
+
153  return game->gamma;
+
154 
+
155  return 0;
+
156 }
+
157 
+
158 void
+ +
160 {
+
161  if (game) {
+
162  game->gamma = g;
+
163 
+
164  if (game->video)
+
165  game->video->SetGammaLevel(g);
+
166  }
+
167 }
+
168 
+
169 int
+ +
171 {
+
172  if (game && game->video) {
+
173  int max_vid_size = game->video->MaxTexSize();
+
174  return max_vid_size < game->max_tex_size ?
+
175  max_vid_size : game->max_tex_size;
+
176  }
+
177  else if (Video::GetInstance()) {
+
178  return Video::GetInstance()->MaxTexSize();
+
179  }
+
180 
+
181  return 256;
+
182 }
+
183 
+
184 int
+ +
186 {
+
187  if (game && game->video) {
+
188  return game->video->MaxTexAspect();
+
189  }
+
190  else if (Video::GetInstance()) {
+
191  return Video::GetInstance()->MaxTexAspect();
+
192  }
+
193 
+
194  return 1;
+
195 }
+
196 
+
197 void
+ +
199 {
+
200  if (game && n >= 64 && n <= 4096)
+
201  game->max_tex_size = n;
+
202 }
+
203 
+
204 bool
+
205 Game::DisplayModeSupported(int w, int h, int bpp)
+
206 {
+
207  return game && game->video && game->video->IsModeSupported(w,h,bpp);
+
208 }
+
209 
+
210 double
+ +
212 {
+
213  if (game)
+
214  return game->frame_rate;
+
215 
+
216  return 0;
+
217 }
+
218 
+
219 double
+ +
221 {
+
222  if (game)
+
223  return game->seconds;
+
224 
+
225  return 0;
+
226 }
+
227 
+
228 double
+ +
230 {
+
231  if (game)
+
232  return game->gui_seconds;
+
233 
+
234  return 0;
+
235 }
+
236 
+
237 // +--------------------------------------------------------------------+
+
238 
+
239 bool
+
240 Game::Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow)
+
241 {
+
242  status = OK;
+
243  hInst = hi;
+
244 
+
245  Print(" Initializing Game\n");
+
246 
+
247  stats.Clear();
+
248 
+
249  if (!InitApplication(hInst)) { // Initialize shared things
+
250  Panic("Could not initialize the application.");
+ +
252  }
+
253 
+
254  if (status == OK && !video_settings) {
+
255  Panic("No video settings specified");
+ +
257  }
+
258 
+
259  if (status == OK) {
+
260  static int os_version = MachineInfo::GetPlatform();
+
261 
+
262  if (os_version == MachineInfo::OS_WIN95 || os_version == MachineInfo::OS_WIN98) {
+
263  Panic(" Windows 95 and 98 are no longer supported. Please update to Windows XP or higher.");
+ +
265  } else if (os_version == MachineInfo::OS_WINNT) {
+
266  Panic(" D3D not available under WinNT 4");
+ + +
269  Panic(" Insufficient DirectX detected (Dx9 IS REQUIRED)");
+ +
271  }
+
272 
+
273  Print(" Gamma Level = %d\n", gamma);
+
274  }
+
275 
+
276  if (status == OK) {
+
277  Print("\n Initializing instance...\n");
+
278  // Perform initializations that apply to a specific instance
+
279  if (!InitInstance(hInst, nCmdShow)) {
+
280  Panic("Could not initialize the instance.");
+ +
282  }
+
283  }
+
284 
+
285  if (status == OK) {
+
286  Print(" Initializing content...\n");
+
287  InitContent();
+
288 
+
289  Print(" Initializing game...\n");
+
290  if (!InitGame()) {
+
291  if (!panicbuf[0])
+
292  Panic("Could not initialize the game.");
+ +
294  }
+
295  }
+
296 
+
297  return status == OK;
+
298 }
+
299 
+
300 // +--------------------------------------------------------------------+
+
301 
+
302 bool
+
303 Game::InitApplication(HINSTANCE hInstance)
+
304 {
+
305  WNDCLASS wc;
+
306  LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 };
+
307 
+
308  if (server)
+
309  brush.lbColor = RGB(255,255,255);
+
310 
+
311  // Fill in window class structure with parameters that
+
312  // describe the main window.
+
313  wc.style = CS_HREDRAW | CS_VREDRAW;
+
314  wc.lpfnWndProc = (WNDPROC) WndProc;
+
315  wc.cbClsExtra = 0;
+
316  wc.cbWndExtra = 0;
+
317  wc.hInstance = hInstance;
+
318  wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(100));
+
319  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+
320 
+
321  wc.hbrBackground = CreateBrushIndirect(&brush);
+
322  wc.lpszMenuName = app_name;
+
323  wc.lpszClassName = app_name;
+
324 
+
325  // Register the window class and return success/failure code.
+
326  if (RegisterClass(&wc) == 0) {
+
327  DWORD err = GetLastError();
+
328 
+
329  if (err == 1410) // class already exists, this is OK
+
330  return true;
+
331 
+
332  else
+
333  Print("WARNING: Register Window Class: %08x\n", err);
+
334  }
+
335 
+
336  return true;
+
337 }
+
338 
+
339 // +--------------------------------------------------------------------+
+
340 
+
341 bool
+
342 Game::InitInstance(HINSTANCE hInstance, int nCmdShow)
+
343 {
+
344  hInst = hInstance;
+
345 
+
346  // initialize the game timer:
+
347  base_game_time = 0;
+
348  QueryPerformanceFrequency(&perf_freq);
+
349  QueryPerformanceCounter(&perf_cnt1);
+
350 
+
351  // center window on display:
+
352  int screenx = GetSystemMetrics(SM_CXSCREEN);
+
353  int screeny = GetSystemMetrics(SM_CYSCREEN);
+
354  int x_offset = 0;
+
355  int y_offset = 0;
+
356  int s_width = 800;
+
357  int s_height = 600;
+
358 
+
359  if (server) {
+
360  s_width = 320;
+
361  s_height = 200;
+
362  }
+
363 
+
364  else if (video_settings) {
+
365  s_width = video_settings->window_width;
+
366  s_height = video_settings->window_height;
+
367  }
+
368 
+
369  if (s_width < screenx)
+
370  x_offset = (screenx - s_width) / 2;
+
371 
+
372  if (s_height < screeny)
+
373  y_offset = (screeny - s_height) / 2;
+
374 
+
375  // Create a main window for this application instance
+
376  RECT rctmp;
+
377  rctmp.left = x_offset;
+
378  rctmp.top = y_offset;
+
379  rctmp.right = x_offset + s_width;
+
380  rctmp.bottom = y_offset + s_height;
+
381 
+
382  window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME |
+
383  WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE;
+
384 
+
385  AdjustWindowRect(&rctmp, window_style, 1);
+
386 
+
387  hwnd = CreateWindow(
+
388  app_name, // Class name
+
389  app_name, // Caption
+
390 
+
391  window_style,
+
392 
+
393  x_offset, // Position
+
394  y_offset,
+
395 
+
396  rctmp.right - rctmp.left, // Size
+
397  rctmp.bottom - rctmp.top,
+
398 
+
399  0, // Parent window (no parent)
+
400  0, // use class menu
+
401  hInst, // handle to window instance
+
402  0); // no params to pass on
+
403 
+
404  // If window could not be created, return "failure"
+
405  if (!hwnd) {
+
406  Panic("Could not create window\n");
+
407  return false;
+
408  }
+
409 
+
410  Print(" Window created.\n");
+
411 
+
412  // Make the window visible and draw it
+
413  ShowWindow(hwnd, nCmdShow); // Show the window
+
414  UpdateWindow(hwnd); // Sends WM_PAINT message
+
415 
+
416  // Save window properties
+
417  window_style = GetWindowLong(hwnd, GWL_STYLE);
+
418  GetWindowRect(hwnd, &bounds_rect);
+
419  GetClientRect(hwnd, &client_rect);
+
420 
+
421  // Use client area to set video window size
+ + +
424 
+
425  Print(" Instance initialized.\n");
+
426  return true;
+
427 }
+
428 
+
429 // +--------------------------------------------------------------------+
+
430 
+
431 bool
+ +
433 {
+
434  if (server) return true;
+
435 
+
436  // create a video factory, and video object:
+
437  video_factory = new(__FILE__,__LINE__) VideoFactory(hwnd);
+
438 
+
439  if (video_factory) {
+
440  Print(" Init Video...\n");
+
441  Print(" Request %s mode\n", video_settings->GetModeDescription());
+
442 
+ +
444 
+
445  if (video) {
+
446  if (!video->IsHardware()) {
+
447  video_factory->DestroyVideo(video);
+
448  video = 0;
+
449 
+
450  Panic("3D Hardware Not Found");
+
451  }
+
452 
+
453  // save a copy of the device-specific video settings:
+
454  else if (video->GetVideoSettings()) {
+
455  *video_settings = *video->GetVideoSettings();
+ +
457  }
+
458  }
+
459 
+ +
461  }
+
462 
+
463  return (video && video->Status() == Video::VIDEO_OK);
+
464 }
+
465 
+
466 // +--------------------------------------------------------------------+
+
467 
+
468 bool
+ +
470 {
+
471  if (server) return true;
+
472  if (!video_factory) return InitVideo();
+
473 
+
474  Print(" Reset Video...\n");
+
475  Print(" Request %s mode\n", video_settings->GetModeDescription());
+
476 
+
477  delete screen;
+
478 
+
479  if (video && !video->Reset(video_settings)) {
+ + +
482  }
+
483 
+
484  if (!video || video->Status() != Video::VIDEO_OK) {
+
485  Panic("Could not re-create Video Interface.");
+
486  return false;
+
487  }
+
488 
+
489  Print(" Re-created video object.\n");
+
490 
+
491  // save a copy of the device-specific video settings:
+
492  if (video->GetVideoSettings()) {
+ + +
495  }
+
496 
+ +
498 
+
499  screen = new(__FILE__,__LINE__) Screen(video);
+
500  if (!screen) {
+
501  Panic("Could not re-create Screen object.");
+
502  return false;
+
503  }
+
504 
+
505  Print(" Re-created screen object.\n");
+
506 
+
507  if (!screen->SetBackgroundColor(Color::Black))
+
508  Print(" WARNING: could not set video background color to Black\n");
+
509 
+
510  screen->ClearAllFrames(true);
+ +
512 
+
513  Print(" Re-established requested video parameters.\n");
+
514 
+ +
516  Print(" Refreshed texture bitmaps.\n\n");
+
517  return true;
+
518 }
+
519 
+
520 // +--------------------------------------------------------------------+
+
521 
+
522 bool
+ +
524 {
+
525  if (!video || !video_settings) return false;
+
526  if (!is_windowed) return false;
+
527  if (ignore_size_change) return true;
+
528 
+
529  HRESULT hr = S_OK;
+
530  RECT client_old;
+
531 
+
532  client_old = client_rect;
+
533 
+
534  // Update window properties
+
535  GetWindowRect(hwnd, &bounds_rect);
+
536  GetClientRect(hwnd, &client_rect);
+
537 
+
538  if (client_old.right - client_old.left !=
+
539  client_rect.right - client_rect.left ||
+
540  client_old.bottom - client_old.top !=
+
541  client_rect.bottom - client_rect.top) {
+
542 
+
543  // A new window size will require a new backbuffer
+
544  // size, so the 3D structures must be changed accordingly.
+
545  Pause(true);
+
546 
+
547  video_settings->is_windowed = true;
+ + +
550 
+
551  ::Print("ResizeVideo() %d x %d\n", video_settings->window_width, video_settings->window_height);
+
552 
+
553  if (video) {
+ +
555  }
+
556 
+
557  Pause(false);
+
558  }
+
559 
+
560  // save a copy of the device-specific video settings:
+
561  if (video->GetVideoSettings()) {
+ + +
564  }
+
565 
+ +
567 
+
568  return hr == S_OK;
+
569 }
+
570 
+
571 bool
+ +
573 {
+
574  bool result = false;
+
575 
+
576  if (video && video_settings) {
+
577  Pause(true);
+
578  ignore_size_change = true;
+
579 
+
580  // Toggle the windowed state
+ + +
583 
+
584  // Prepare window for windowed/fullscreen change
+ +
586 
+
587  // Reset the 3D device
+
588  if (!video->Reset(video_settings)) {
+
589  // reset failed, try to restore...
+
590  ignore_size_change = false;
+
591 
+
592  if (!is_windowed) {
+
593  // Restore window type to windowed mode
+ + +
596 
+ +
598 
+
599  SetWindowPos(hwnd,
+
600  HWND_NOTOPMOST,
+
601  bounds_rect.left,
+
602  bounds_rect.top,
+
603  bounds_rect.right - bounds_rect.left,
+
604  bounds_rect.bottom - bounds_rect.top,
+
605  SWP_SHOWWINDOW);
+
606  }
+
607 
+
608  ::Print("Unable to toggle %s fullscreen mode.\n", is_windowed ? "into" : "out of");
+
609  }
+
610 
+
611  else {
+
612  ignore_size_change = false;
+
613 
+
614  // When moving from fullscreen to windowed mode, it is important to
+
615  // adjust the window size after resetting the device rather than
+
616  // beforehand to ensure that you get the window size you want. For
+
617  // example, when switching from 640x480 fullscreen to windowed with
+
618  // a 1000x600 window on a 1024x768 desktop, it is impossible to set
+
619  // the window size to 1000x600 until after the display mode has
+
620  // changed to 1024x768, because windows cannot be larger than the
+
621  // desktop.
+
622 
+
623  if (is_windowed) {
+
624  SetWindowPos(hwnd,
+
625  HWND_NOTOPMOST,
+
626  bounds_rect.left,
+
627  bounds_rect.top,
+
628  bounds_rect.right - bounds_rect.left,
+
629  bounds_rect.bottom - bounds_rect.top,
+
630  SWP_SHOWWINDOW);
+
631  }
+
632 
+
633  GetClientRect(hwnd, &client_rect); // Update our copy
+
634  Pause(false);
+
635 
+
636  if (is_windowed)
+ + +
639 
+
640  else
+ + +
643 
+
644  result = true;
+
645  }
+
646  }
+
647 
+
648  return result;
+
649 }
+
650 
+
651 bool
+ +
653 {
+
654  if (is_windowed) {
+
655  // Set windowed-mode style
+
656  SetWindowLong(hwnd, GWL_STYLE, window_style);
+
657  if (hmenu != NULL) {
+
658  SetMenu(hwnd, hmenu);
+
659  hmenu = NULL;
+
660  }
+
661  }
+
662  else {
+
663  // Set fullscreen-mode style
+
664  SetWindowLong(hwnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE);
+
665  if (hmenu == NULL) {
+
666  hmenu = GetMenu(hwnd);
+
667  SetMenu(hwnd, NULL);
+
668  }
+
669  }
+
670 
+
671  return true;
+
672 }
+
673 
+
674 
+
675 // +--------------------------------------------------------------------+
+
676 
+
677 bool
+ +
679 {
+
680  if (server) {
+
681  Print(" InitGame() - server mode.\n");
+
682  }
+
683 
+
684  else {
+
685  if (!SetupPalette()) {
+
686  Panic("Could not set up the palette.");
+
687  return false;
+
688  }
+
689 
+
690  Print(" Palette loaded.\n");
+
691 
+
692  if (!InitVideo() || !video || video->Status() != Video::VIDEO_OK) {
+
693  if (!panicbuf[0])
+
694  Panic("Could not create the Video Interface.");
+
695  return false;
+
696  }
+
697 
+
698  Print(" Created video object.\n");
+
699 
+ +
701 
+
702  screen = new(__FILE__,__LINE__) Screen(video);
+
703  if (!screen) {
+
704  if (!panicbuf[0])
+
705  Panic("Could not create the Screen object.");
+
706  return false;
+
707  }
+
708 
+
709  Print(" Created screen object.\n");
+
710 
+ +
712  Print(" WARNING: could not set video background color to Black\n");
+
713  screen->ClearAllFrames(true);
+
714 
+ +
716 
+
717  Print(" Established requested video parameters.\n\n");
+
718  }
+
719 
+
720  return true;
+
721 }
+
722 
+
723 
+
724 // +--------------------------------------------------------------------+
+
725 
+
726 bool
+ +
728 {
+
729  DataLoader* loader = DataLoader::GetLoader();
+
730  List<Text> bundles;
+
731 
+
732  loader->SetDataPath("Content/");
+
733  loader->ListFiles("content*", bundles);
+
734 
+
735  ListIter<Text> iter = bundles;
+
736  while (++iter) {
+
737  Text* filename = iter.value();
+
738  int n = filename->indexOf('_');
+
739 
+
740  if (n > 0) {
+
741  Locale::ParseLocale(filename->data() + n);
+
742  }
+
743  else {
+
744  delete content;
+
745  content = new(__FILE__,__LINE__) ContentBundle("content", 0);
+
746  }
+
747  }
+
748 
+
749  loader->SetDataPath(0);
+
750  return true;
+
751 }
+
752 
+
753 void
+ +
755 {
+
756  if (game) {
+
757  DataLoader* loader = DataLoader::GetLoader();
+
758  loader->SetDataPath("Content/");
+
759  delete game->content;
+
760 
+
761  game->content = new(__FILE__,__LINE__) ContentBundle("content", locale);
+
762 
+
763  loader->SetDataPath(0);
+
764  }
+
765 }
+
766 
+
767 // +--------------------------------------------------------------------+
+
768 
+
769 bool
+ +
771 {
+ + +
774  return true;
+
775  }
+
776 
+
777  return false;
+
778 }
+
779 
+
780 // +--------------------------------------------------------------------+
+
781 
+
782 bool
+
783 Game::LoadPalette(PALETTEENTRY* pal, BYTE* inv)
+
784 {
+
785  char palheader[32];
+
786  struct {
+
787  WORD Version;
+
788  WORD NumberOfEntries;
+
789  PALETTEENTRY Entries[256];
+
790 
+
791  } Palette = { 0x300, 256 };
+
792 
+
793  DataLoader* loader = DataLoader::GetLoader();
+
794  BYTE* block;
+
795  char fname[256];
+
796  sprintf_s(fname, "%s.pal", palette_name);
+
797 
+
798  if (!loader->LoadBuffer(fname, block)) {
+
799  Print(" Could not open file '%s'\n", fname);
+
800  return false;
+
801  }
+
802 
+
803  memcpy(&palheader, block, 24);
+
804  memcpy((char*) Palette.Entries, (block+24), 256*4);
+
805 
+
806  for (int i = 0; i < 256; i++) {
+
807  *pal++ = Palette.Entries[i];
+
808  }
+
809 
+
810  loader->ReleaseBuffer(block);
+
811 
+
812  sprintf_s(fname, "%s.ipl", palette_name);
+
813  int size = loader->LoadBuffer(fname, block);
+
814  if (size < 32768) {
+
815  Print(" Could not open file '%s'\n", fname);
+
816  return false;
+
817  }
+
818 
+
819  memcpy(inv, block, 32768);
+
820  loader->ReleaseBuffer(block);
+
821 
+
822  return true;
+
823 }
+
824 
+
825 // +--------------------------------------------------------------------+
+
826 
+
827 int
+ +
829 {
+
830  MSG msg;
+
831 
+
832  status = RUN;
+
833  Print("\n");
+
834  Print("+====================================================================+\n");
+
835  Print("| RUN |\n");
+
836  Print("+====================================================================+\n");
+
837 
+
838  // Polling messages from event queue until quit
+
839  while (status < EXIT) {
+
840  if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
+
841  if (msg.message == WM_QUIT)
+
842  break;
+
843 
+
844  TranslateMessage(&msg);
+
845  DispatchMessage(&msg);
+
846  }
+
847  else {
+
848  if (ProfileGameLoop())
+
849  WaitMessage();
+
850  }
+
851  }
+
852 
+
853  return exit_code ? exit_code : msg.wParam;
+
854 }
+
855 
+
856 // +--------------------------------------------------------------------+
+
857 
+
858 void
+ +
860 {
+
861  Print("\n\n*** Game::Exit()\n");
+
862  status = EXIT;
+
863 }
+
864 
+
865 void
+
866 Game::Panic(const char* msg)
+
867 {
+
868  if (msg) Print("*** PANIC: %s\n", msg);
+
869  else Print("*** PANIC! ***\n");
+
870 
+
871  if (!msg) msg = "Unspecified fatal error.";
+
872  sprintf_s(panicbuf, "%s\nThis game will now terminate.", msg);
+
873 
+
874  if (game) {
+
875  game->status = PANIC;
+
876  }
+
877 }
+
878 
+
879 // +--------------------------------------------------------------------+
+
880 
+
881 void
+ +
883 {
+
884  active = f;
+
885 
+
886  if (active && video)
+ +
888 }
+
889 
+
890 // +--------------------------------------------------------------------+
+
891 
+
892 void
+
893 Game::Pause(bool f)
+
894 {
+
895  if (f) {
+
896  if (soundcard)
+
897  soundcard->Pause();
+
898  paused = true;
+
899  }
+
900  else {
+
901  if (soundcard)
+
902  soundcard->Resume();
+
903  paused = false;
+
904  }
+
905 }
+
906 
+
907 // +--------------------------------------------------------------------+
+
908 
+
909 bool ProfileGameLoop(void)
+
910 {
+
911  return game->GameLoop();
+
912 }
+
913 
+
914 bool
+ +
916 {
+
917  bool wait_for_windows_events = true;
+
918 
+
919  if (active && !paused) {
+
920  if (!server) {
+
921  // Route Events to EventTargets
+ +
923  if (ed)
+
924  ed->Dispatch();
+
925  }
+
926 
+
927  UpdateWorld();
+
928  GameState();
+
929 
+
930  if (!server) {
+
931  UpdateScreen();
+
932  CollectStats();
+
933  }
+
934 
+
935  wait_for_windows_events = false;
+
936  }
+
937  else if (active && paused) {
+
938  if (GetKey()=='P')
+
939  Pause(false);
+
940  }
+
941 
+
942  QueryPerformanceCounter(&perf_cnt2);
+
943 
+
944  double freq = (double) (perf_freq.QuadPart);
+
945  double msec = (double) (perf_cnt2.QuadPart - perf_cnt1.QuadPart);
+
946 
+
947  msec /= freq;
+
948  msec *= 1000.0;
+
949 
+
950  if (msec < 1)
+
951  msec = 1;
+
952 
+
953  real_time += (DWORD) msec;
+
954 
+
955  frame_number++;
+
956  Mouse::w = 0;
+
957 
+
958  perf_cnt1 = perf_cnt2;
+
959 
+
960  return wait_for_windows_events;
+
961 }
+
962 
+
963 // +--------------------------------------------------------------------+
+
964 
+
965 void
+ +
967 {
+
968  long new_time = real_time;
+
969  double delta = new_time - frame_time;
+
970  gui_seconds = delta * 0.001;
+ +
972 
+
973  if (time_comp == 1)
+
974  {
+
975  if (delta < max_frame_length * 1000)
+
976  seconds = delta * 0.001;
+
977  }
+
978  else
+
979  {
+
980  seconds = time_comp * delta * 0.001;
+
981  }
+
982 
+
983  frame_time = new_time;
+
984  game_time += (DWORD) (seconds * 1000);
+
985 
+
986  if (world)
+ +
988 }
+
989 
+
990 // +--------------------------------------------------------------------+
+
991 
+
992 void
+ +
994 {
+
995 }
+
996 
+
997 // +--------------------------------------------------------------------+
+
998 
+
999 void
+ +
1001 {
+
1002  if (!screen || !video) return;
+
1003 
+
1004  if (screen->Refresh()) {
+
1005  if (Keyboard::KeyDown(VK_F12)) {
+
1006  if (Keyboard::KeyDown(VK_SHIFT)) {
+
1007  if (!avi_file) {
+
1008  AVICapture(); // begin capturing
+ +
1010  }
+
1011  else {
+
1012  delete avi_file; // end capture;
+
1013  avi_file = 0;
+ +
1015  }
+
1016  }
+
1017  else {
+
1018  if (!avi_file) {
+
1019  ScreenCapture();
+
1020  }
+
1021  else {
+
1022  delete avi_file; // end capture;
+
1023  avi_file = 0;
+ +
1025  }
+
1026  }
+
1027  }
+
1028  else if (avi_file) {
+
1029  AVICapture(); // continue capturing...
+
1030  }
+
1031 
+
1032  video->Present();
+
1033  }
+
1034  else {
+
1035  Panic("Screen refresh failed.");
+
1036  }
+
1037 }
+
1038 
+
1039 // +--------------------------------------------------------------------+
+
1040 
+
1041 Game*
+ +
1043 {
+
1044  return game;
+
1045 }
+
1046 
+
1047 Video*
+ +
1049 {
+
1050  if (game)
+
1051  return game->video;
+
1052 
+
1053  return 0;
+
1054 }
+
1055 
+
1056 Color
+ +
1058 {
+
1059  if (game)
+
1060  return game->screen_color;
+
1061 
+
1062  return Color::Black;
+
1063 }
+
1064 
+
1065 void
+ +
1067 {
+
1068  if (game) {
+
1069  game->screen_color = c;
+
1070 
+
1071  if (game->screen)
+
1072  game->screen->SetBackgroundColor(c);
+
1073  }
+
1074 }
+
1075 
+
1076 int
+ +
1078 {
+
1079  if (game && game->video)
+
1080  return game->video->Width();
+
1081 
+
1082  return 0;
+
1083 }
+
1084 
+
1085 int
+ +
1087 {
+
1088  if (game && game->video)
+
1089  return game->video->Height();
+
1090 
+
1091  return 0;
+
1092 }
+
1093 
+
1094 // +--------------------------------------------------------------------+
+
1095 
+
1096 void
+
1097 Game::ScreenCapture(const char* name)
+
1098 {
+
1099  if (server || !video || !screen) return;
+
1100 
+
1101  static DWORD last_shot = 0;
+
1102  static DWORD shot_num = 1;
+
1103  DataLoader* loader = DataLoader::GetLoader();
+
1104  char filename[256];
+
1105 
+
1106  if (!name && (real_time - last_shot) < 1000)
+
1107  return;
+
1108 
+
1109  // try not to overwrite existing screen shots...
+
1110  if (loader) {
+
1111  bool use_file_sys = loader->IsFileSystemEnabled();
+
1112  loader->UseFileSystem(true);
+
1113  loader->SetDataPath(0);
+
1114  List<Text> shot_list;
+
1115  loader->ListFiles("*.PCX", shot_list);
+
1116  loader->UseFileSystem(use_file_sys);
+
1117 
+
1118  for (int i = 0; i < shot_list.size(); i++) {
+
1119  Text* s = shot_list[i];
+
1120  int n = 0;
+
1121 
+
1122  sscanf_s(s->data()+1, "%d", &n);
+
1123  if (shot_num <= (DWORD) n)
+
1124  shot_num = n+1;
+
1125  }
+
1126 
+
1127  shot_list.destroy();
+
1128  }
+
1129 
+
1130  if (name)
+
1131  strcpy_s(filename, name);
+
1132  else
+
1133  sprintf_s(filename, "A%d.PCX", shot_num++);
+
1134 
+
1135  Bitmap bmp;
+
1136 
+
1137  if (video && video->Capture(bmp)) {
+
1138  PcxImage pcx(bmp.Width(), bmp.Height(), (LPDWORD) bmp.HiPixels());
+
1139  pcx.Save((char*) filename);
+
1140  }
+
1141 
+
1142  last_shot = real_time;
+
1143 }
+
1144 
+
1145 // +--------------------------------------------------------------------+
+
1146 
+
1147 void
+
1148 Game::AVICapture(const char* name)
+
1149 {
+
1150  if (server || !video || !screen) return;
+
1151 
+
1152  if (!avi_file) {
+
1153  char filename[256];
+
1154  Bitmap bmp;
+
1155  DataLoader* loader = DataLoader::GetLoader();
+
1156  DWORD avi_num = 1;
+
1157 
+
1158  // try not to overwrite existing screen shots...
+
1159  if (loader) {
+
1160  bool use_file_sys = loader->IsFileSystemEnabled();
+
1161  loader->UseFileSystem(true);
+
1162  loader->SetDataPath(0);
+
1163  List<Text> avi_list;
+
1164  loader->ListFiles("*.avi", avi_list);
+
1165  loader->UseFileSystem(use_file_sys);
+
1166 
+
1167  for (int i = 0; i < avi_list.size(); i++) {
+
1168  Text* s = avi_list[i];
+
1169  int n = 0;
+
1170 
+
1171  sscanf_s(s->data()+1, "%d", &n);
+
1172  if (avi_num <= (DWORD) n)
+
1173  avi_num = n+1;
+
1174  }
+
1175 
+
1176  avi_list.destroy();
+
1177  }
+
1178 
+
1179  if (name)
+
1180  strcpy_s(filename, name);
+
1181  else
+
1182  sprintf_s(filename, "A%d.avi", avi_num);
+
1183 
+
1184  if (video && video->Capture(bmp)) {
+
1185  //bmp.ScaleTo(bmp.Width()/2, bmp.Height()/2);
+
1186  avi_file = new(__FILE__,__LINE__) AviFile(filename, Rect(0,0,bmp.Width(),bmp.Height()), VIDEO_FPS);
+
1187  }
+
1188 
+
1189  }
+
1190 
+
1191  else {
+
1192  Bitmap bmp;
+
1193 
+
1194  if (video && video->Capture(bmp)) {
+
1195  //bmp.ScaleTo(bmp.Width()/2, bmp.Height()/2);
+
1196  avi_file->AddFrame(bmp);
+
1197  }
+
1198  }
+
1199 }
+
1200 
+
1201 
+
1202 
+
1203 // +--------------------------------------------------------------------+
+
1204 
+
1205 void
+ +
1207 {
+
1208  frame_count++;
+
1209 
+
1210  if (!totaltime) totaltime = real_time;
+
1211 
+
1212  if (frame_time - frame_time0 > 200) {
+ + + +
1216  }
+
1217 
+
1218  if (video) {
+ + + + + +
1224 
+ + + +
1228  }
+
1229 }
+
1230 
+
1231 // +--------------------------------------------------------------------+
+
1232 
+
1233 void
+ +
1235 {
+
1236  if (server) return;
+
1237 
+ +
1239 
+
1240  Print("\n");
+
1241  Print("Performance Data:\n");
+
1242  Print("-----------------\n");
+
1243 
+
1244  Print(" Time: %d msec\n", totaltime);
+
1245  Print(" Frames: %d\n", stats.nframe);
+
1246  Print(" Polys Rendered: %d\n", stats.total_polys);
+
1247  Print(" Lines Rendered: %d\n", stats.total_lines);
+
1248  Print(" Verts Rendered: %d\n", stats.total_verts);
+
1249  Print(" Render Calls: %d\n", stats.ncalls);
+
1250  Print("\n");
+
1251 
+
1252  Print("Performance Statistics:\n");
+
1253  Print("-----------------------\n");
+
1254 
+
1255  Print(" Frames/Second: %.2f\n", (stats.nframe * 1000.0) / totaltime);
+
1256  Print(" Polys/Frame: %.2f\n", (double) stats.total_polys / (double) stats.nframe);
+
1257  Print(" Polys/Call: %.2f\n", (double) stats.total_polys / (double) stats.ncalls);
+
1258  Print(" Polys/Second: %.2f\n", (stats.total_polys * 1000.0) / totaltime);
+
1259  Print(" Lines/Second: %.2f\n", (stats.total_lines * 1000.0) / totaltime);
+
1260  Print(" Verts/Second: %.2f\n", (stats.total_verts * 1000.0) / totaltime);
+
1261 
+
1262  Print("\n");
+
1263 }
+
1264 
+
1265 // +====================================================================+
+
1266 // WndProc
+
1267 // +====================================================================+
+
1268 
+
1269 #ifndef WM_MOUSEWHEEL
+
1270 #define WM_MOUSEWHEEL 0x20A
+
1271 #endif
+
1272 
+
1273 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM uParam, LPARAM lParam)
+
1274 {
+
1275  switch (message) {
+
1276  case WM_SYSKEYDOWN:
+
1277  if (uParam == VK_TAB || uParam == VK_F4)
+
1278  return DefWindowProc(hwnd, message, uParam, lParam);
+
1279 
+
1280  return 0;
+
1281 
+
1282  case WM_MENUCHAR:
+
1283  return MNC_CLOSE << 16;
+
1284 
+
1285  case WM_ACTIVATEAPP:
+
1286  // Keep track of whether or not the app is in the foreground
+
1287  if (game)
+
1288  game->Activate(uParam?true:false);
+
1289  break;
+
1290 
+
1291  case WM_PAINT:
+
1292  if (!game || !game->OnPaint())
+
1293  return DefWindowProc(hwnd, message, uParam, lParam);
+
1294  break;
+
1295 
+
1296  case WM_SETCURSOR:
+
1297  if (Game::ShowMouse()) {
+
1298  return DefWindowProc(hwnd, message, uParam, lParam);
+
1299  }
+
1300  else {
+
1301  // hide the windows mouse cursor
+
1302  SetCursor(NULL);
+
1303  return 1;
+
1304  }
+
1305  break;
+
1306 
+
1307  case WM_ENTERSIZEMOVE:
+
1308  // Halt frame movement while the app is sizing or moving
+
1309  if (game)
+
1310  game->Pause(true);
+
1311  break;
+
1312 
+
1313  case WM_SIZE:
+
1314  // Pick up possible changes to window style due to maximize, etc.
+
1315  if (game && game->hwnd != NULL ) {
+
1316  game->window_style = GetWindowLong(game->hwnd, GWL_STYLE );
+
1317 
+
1318  if (uParam == SIZE_MINIMIZED) {
+
1319  game->Pause(true); // Pause while we're minimized
+
1320  game->is_minimized = true;
+
1321  game->is_maximized = false;
+
1322  }
+
1323 
+
1324  else if (uParam == SIZE_MAXIMIZED) {
+
1325  if (game->is_minimized)
+
1326  game->Pause(false); // Unpause since we're no longer minimized
+
1327 
+
1328  game->is_minimized = false;
+
1329  game->is_maximized = true;
+
1330  game->ResizeVideo();
+
1331  }
+
1332 
+
1333  else if (uParam == SIZE_RESTORED) {
+
1334  if (game->is_maximized) {
+
1335  game->is_maximized = false;
+
1336  game->ResizeVideo();
+
1337  }
+
1338 
+
1339  else if (game->is_minimized) {
+
1340  game->Pause(false); // Unpause since we're no longer minimized
+
1341  game->is_minimized = false;
+
1342  game->ResizeVideo();
+
1343  }
+
1344  else {
+
1345  // If we're neither maximized nor minimized, the window size
+
1346  // is changing by the user dragging the window edges. In this
+
1347  // case, we don't reset the device yet -- we wait until the
+
1348  // user stops dragging, and a WM_EXITSIZEMOVE message comes.
+
1349  }
+
1350  }
+
1351  }
+
1352  break;
+
1353 
+
1354  case WM_EXITSIZEMOVE:
+
1355  if (game) {
+
1356  game->Pause(false);
+
1357  game->ResizeVideo();
+
1358  }
+
1359  break;
+
1360 
+
1361 
+
1362  case WM_ENTERMENULOOP:
+
1363  if (game)
+
1364  game->Pause(true);
+
1365  break;
+
1366 
+
1367  case WM_EXITMENULOOP:
+
1368  if (game)
+
1369  game->Pause(false);
+
1370  break;
+
1371 
+
1372  /*
+
1373 case WM_HELP:
+
1374  if (game)
+
1375  return game->OnHelp();
+
1376  break;
+
1377 */
+
1378 
+
1379  case WM_KEYDOWN:
+
1380  BufferKey(uParam);
+
1381  return 0;
+
1382 
+
1383  case WM_DESTROY:
+
1384  PostQuitMessage(0);
+
1385  break;
+
1386 
+
1387  case WM_MOUSEMOVE:
+
1388  Mouse::x = LOWORD(lParam);
+
1389  Mouse::y = HIWORD(lParam);
+
1390  break;
+
1391 
+
1392  case WM_LBUTTONDOWN:
+
1393  Mouse::l = 1;
+
1394  break;
+
1395 
+
1396  case WM_LBUTTONDBLCLK:
+
1397  Mouse::l = 2;
+
1398  break;
+
1399 
+
1400  case WM_LBUTTONUP:
+
1401  Mouse::l = 0;
+
1402  break;
+
1403 
+
1404  case WM_MBUTTONDOWN:
+
1405  Mouse::m = 1;
+
1406  break;
+
1407 
+
1408  case WM_MBUTTONDBLCLK:
+
1409  Mouse::m = 2;
+
1410  break;
+
1411 
+
1412  case WM_MBUTTONUP:
+
1413  Mouse::m = 0;
+
1414  break;
+
1415 
+
1416  case WM_RBUTTONDOWN:
+
1417  Mouse::r = 1;
+
1418  break;
+
1419 
+
1420  case WM_RBUTTONDBLCLK:
+
1421  Mouse::r = 2;
+
1422  break;
+
1423 
+
1424  case WM_RBUTTONUP:
+
1425  Mouse::r = 0;
+
1426  break;
+
1427 
+
1428  case WM_MOUSEWHEEL:
+
1429  {
+
1430  int w = (int) (uParam >> 16);
+
1431  if (w > 32000) w -= 65536;
+
1432  Mouse::w += w;
+
1433  }
+
1434  break;
+
1435 
+
1436  case WM_CLOSE:
+
1437  if (game) // && game->Server())
+
1438  game->Exit();
+
1439  break;
+
1440 
+
1441  default:
+
1442  return DefWindowProc(hwnd, message, uParam, lParam);
+
1443  }
+
1444 
+
1445  return 0;
+
1446 }
+
1447 
+
1448 // +====================================================================+
+
1449 
+
1450 const int MAX_KEY_BUF = 512;
+
1451 static int vkbuf[MAX_KEY_BUF];
+
1452 static int vkshiftbuf[MAX_KEY_BUF];
+
1453 static int vkins = 0;
+
1454 static int vkext = 0;
+
1455 
+
1456 void
+ +
1458 {
+ +
1460  vkins = vkext = 0;
+
1461 }
+
1462 
+
1463 void
+
1464 BufferKey(int vkey)
+
1465 {
+
1466  if (vkey < 1) return;
+
1467 
+
1468  int shift = 0;
+
1469 
+
1470  if (GetAsyncKeyState(VK_SHIFT))
+
1471  shift |= 1;
+
1472 
+
1473  if (GetAsyncKeyState(VK_CONTROL))
+
1474  shift |= 2;
+
1475 
+
1476  if (GetAsyncKeyState(VK_MENU))
+
1477  shift |= 4;
+
1478 
+
1479  vkbuf[vkins] = vkey;
+
1480  vkshiftbuf[vkins++] = shift;
+
1481 
+
1482  if (vkins >= MAX_KEY_BUF)
+
1483  vkins = 0;
+
1484 
+
1485  if (vkins == vkext) {
+
1486  vkext++;
+
1487  if (vkext >= MAX_KEY_BUF)
+
1488  vkext = 0;
+
1489  }
+
1490 }
+
1491 
+
1492 int
+ +
1494 {
+
1495  if (vkins == vkext) return 0;
+
1496 
+
1497  int result = vkbuf[vkext++];
+
1498  if (vkext >= MAX_KEY_BUF)
+
1499  vkext = 0;
+
1500 
+
1501  return result;
+
1502 }
+
1503 
+
1504 int
+
1505 GetKeyPlus(int& key, int& shift)
+
1506 {
+
1507  if (vkins == vkext) return 0;
+
1508 
+
1509  key = vkbuf[vkext];
+
1510  shift = vkshiftbuf[vkext++];
+
1511 
+
1512  if (vkext >= MAX_KEY_BUF)
+
1513  vkext = 0;
+
1514 
+
1515  return key;
+
1516 }
+
1517 
+
1518 // +====================================================================+
+
1519 
+
1520 void Print(const char* fmt, ...)
+
1521 {
+
1522  if (ErrLog) {
+
1523  vsprintf_s(ErrBuf, fmt, (char *)(&fmt+1));
+
1524 
+
1525  fprintf(ErrLog, ErrBuf);
+
1526  fflush(ErrLog);
+
1527  }
+
1528 }
+
1529 
+
1530 // +====================================================================+
+
1531 
+ +
1533 {
+
1534  if (game)
+
1535  return Game::RealTime();
+
1536 
+
1537  return timeGetTime();
+
1538 }
+
1539 
+ +
1541 {
+
1542  return real_time;
+
1543 }
+
1544 
+ +
1546 {
+
1547  return game_time;
+
1548 }
+
1549 
+ +
1551 {
+
1552  return time_comp;
+
1553 }
+
1554 
+ +
1556 {
+
1557  if (comp > 0 && comp <= 100)
+
1558  time_comp = comp;
+
1559 }
+
1560 
+ +
1562 {
+
1563  return frame_number;
+
1564 }
+
1565 
+ +
1567 {
+
1568  game_time = 0;
+
1569 }
+
1570 
+
1571 void Game::SkipGameTime(double seconds)
+
1572 {
+
1573  if (seconds > 0)
+
1574  game_time += (DWORD) (seconds * 1000);
+
1575 }
+
+
+ + + + -- cgit v1.1