home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / gamesystem / source / gs_application.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-11  |  7.6 KB  |  375 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    gsCApplication
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    12/03/00
  8. //
  9. // Base:    None
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "gamesystem.h"
  16.  
  17. //-------------------------------------------------------------
  18. // Static variables
  19.  
  20. const char *gsCApplication::m_app_name = "GameSystem";
  21.  
  22. HINSTANCE    gsCApplication::m_instance = 0;
  23. HWND        gsCApplication::m_window = 0;
  24. bool        gsCApplication::m_isActive = false;
  25. bool        gsCApplication::m_isReady = false;
  26. bool        gsCApplication::m_running = false;
  27. bool        gsCApplication::m_isWindowed = false;
  28. bool        gsCApplication::m_isPaused = false;
  29.  
  30. gsCPoint    gsCApplication::m_default_size(640,480);
  31.  
  32. gsCScreen  *gsCApplication::m_screen = 0;
  33. gsCApplication *gsCApplication::m_app = 0;
  34.  
  35. gsCFrameCounter gsCApplication::m_frame_counter;
  36. float        gsCApplication::m_last_time_stamp = 0;
  37.  
  38. bool        gsCApplication::m_restarting = false;
  39.  
  40. //-------------------------------------------------------------
  41. // Constructor
  42.  
  43. gsCApplication::gsCApplication(const char *app_name)
  44. {
  45.     if (app_name)
  46.         m_app_name = app_name;
  47.  
  48.     // currently active application
  49.  
  50.     m_app = this;
  51. }
  52.  
  53. //-------------------------------------------------------------
  54. // Destructor
  55.  
  56. gsCApplication::~gsCApplication()
  57. {
  58.     // remove currently active application
  59.  
  60.     m_app = 0;
  61. }
  62.  
  63. //-------------------------------------------------------------
  64. // Window procedure
  65.  
  66. LRESULT CALLBACK gsCApplication::windowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  67. {
  68.     switch (msg) {
  69.         case WM_ACTIVATEAPP:
  70.  
  71.             // pause if minimized or not the top window
  72.             
  73.             m_isActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE);
  74.             return 0L;
  75.         
  76.         case WM_DESTROY:
  77.  
  78.             // stop game running to force exit
  79.  
  80.             m_running = false;
  81.             return 0L;
  82.  
  83. #ifdef gsESCAPE_TO_EXIT
  84.  
  85.         case WM_KEYUP:
  86.             
  87.             // pressing Esc closes program
  88.             
  89.             switch (wParam) {
  90.                 case VK_ESCAPE:
  91.                     PostMessage(hWnd,WM_CLOSE,0,0);
  92.                     return 0L;
  93.                 }
  94.             break;
  95.  
  96. #endif
  97.                 
  98.         case WM_MOVE:
  99.             
  100.             // update window rectangle if moved
  101.             
  102.             if (m_isActive && m_isReady && m_isWindowed) {
  103.                 if (m_screen)
  104.                     m_screen->updateRect(hWnd);
  105.                 }
  106.             break;
  107.  
  108.         case WM_PAINT:
  109.             
  110.             // update the screen if we need to refresh
  111.             
  112.             if (m_isWindowed && m_isReady) {
  113.                 if (m_screen)
  114.                     m_screen->flip();
  115.                 }
  116.             break;
  117.         
  118.         case WM_SETCURSOR:
  119.  
  120.             // display the cursor in the window if windowed
  121.  
  122. //            if (m_isActive && m_isReady && !m_isWindowed) {
  123.                 SetCursor(NULL);
  124.                 return TRUE;
  125. //                }
  126. //          break;
  127.         
  128.         case WM_SIZE:
  129.             
  130.             // check to see if we are losing our window
  131.             
  132.             switch (wParam) {
  133.                 case SIZE_MAXHIDE:
  134.                 case SIZE_MINIMIZED:
  135.                     m_isActive = false;
  136.                 default:
  137.                     m_isActive = true;
  138.                     break;
  139.                 }
  140.             }
  141.  
  142.     // call default window procedure
  143.  
  144.     return DefWindowProc(hWnd,msg,wParam,lParam);
  145. }
  146.  
  147. //-------------------------------------------------------------
  148. // Run application
  149.  
  150. int gsCApplication::run(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
  151. {
  152.     MSG msg;
  153.     msg.wParam = 0;
  154.     WNDCLASS wc;
  155.     
  156.     do {
  157.  
  158.         m_isWindowed = true;
  159.  
  160.         // save instance handle
  161.  
  162.         m_instance = hInstance;
  163.  
  164.         // create window class
  165.  
  166.         wc.lpszClassName = m_app_name;
  167.         wc.style = CS_HREDRAW | CS_VREDRAW;
  168.         wc.lpfnWndProc = windowProc;
  169.         wc.cbClsExtra = 0;
  170.         wc.cbWndExtra = 0;
  171.         wc.hInstance = m_instance;
  172.         wc.hIcon = 0;
  173.         wc.hCursor = LoadCursor(0, IDC_ARROW);
  174.         wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  175.         wc.lpszMenuName = 0;
  176.  
  177.         // register window class
  178.  
  179.         RegisterClass(&wc);
  180.  
  181.         // create the main window
  182.  
  183.         m_window = CreateWindowEx(
  184.             0,
  185.             m_app_name,
  186.             m_app_name,
  187.             WS_VISIBLE, // | WS_SYSMENU,
  188.             CW_USEDEFAULT,
  189.             CW_USEDEFAULT,
  190.             m_default_size.getX(),
  191.             m_default_size.getY(),
  192.             NULL,
  193.             NULL,
  194.             m_instance,
  195.             NULL);
  196.  
  197.         // fail if no window created
  198.  
  199.         if(m_window == NULL)
  200.             return 0;
  201.  
  202.         // set the window style
  203.  
  204.     /*    DWORD dwStyle = GetWindowLong(m_window,GWL_STYLE);
  205.         dwStyle &= ~WS_POPUP;
  206.         dwStyle |= 0; //WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
  207.         SetWindowLong(m_window, GWL_STYLE, dwStyle);
  208.     */
  209.         // calculate window size for required client area size
  210.  
  211.         gsCRect rc(gsCPoint(0,0),m_default_size);
  212.         
  213.         AdjustWindowRectEx(LPRECT(rc),
  214.                            GetWindowLong(m_window,GWL_STYLE),
  215.                            FALSE,
  216.                            GetWindowLong(m_window,GWL_EXSTYLE));
  217.  
  218.         // resize window
  219.  
  220.         SetWindowPos(m_window,
  221.                      NULL,
  222.                      0,0,
  223.                      rc.getWidth(),rc.getHeight(),
  224.                      SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  225.  
  226.         SetWindowPos(m_window,
  227.                      HWND_NOTOPMOST,
  228.                      0,0,
  229.                      0,0,
  230.                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  231.  
  232.         ShowWindow(m_window,nCmdShow);
  233.         UpdateWindow(m_window);
  234.  
  235.     //# Save the window size/pos for switching modes
  236.     //#    GetWindowRect(m_window,&m_window_rect);
  237.     
  238.     // initialize game
  239.  
  240.         m_restarting = false;
  241.  
  242.         if (initialize()) {
  243.             
  244.             m_isReady = true;
  245.  
  246.             // acquire any required inputs
  247.  
  248.             gsCInput::acquireAll();
  249.  
  250.             // setup frame counter
  251.  
  252.             m_frame_counter.reset();
  253.  
  254.             // main message pump
  255.  
  256.             m_running = true;
  257.  
  258.             m_last_time_stamp = gsCTimer::getCurrentTime();
  259.  
  260.             while (m_running) {
  261.  
  262.                 // process windows messages
  263.  
  264.                 if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
  265.                     if (!GetMessage(&msg,NULL,0,0)) {
  266.                         m_running = false;
  267.                         }
  268.                     else {
  269.                         TranslateMessage(&msg);
  270.                         DispatchMessage(&msg);
  271.                         }
  272.                     }
  273.                 else {
  274.  
  275.                     if (m_isActive && m_isReady) {
  276.  
  277.                         // wait for at least (1/FRAME_RATE) seconds since last frame
  278.  
  279.                         float end_time = m_last_time_stamp + 1.f / gsFRAME_RATE;
  280.  
  281.                         float t;
  282.  
  283.                         for (;;) {
  284.                             t = gsCTimer::getCurrentTime();
  285.                             if (t >= end_time)
  286.                                 break;
  287.                             }
  288.  
  289.                         m_last_time_stamp = t;
  290.  
  291.                         // update system time (used by all timers) unless paused
  292.  
  293.                         if (!m_isPaused)
  294.                             gsCTimer::update(false);
  295.  
  296.                         // mark start of frame for frame counter
  297.  
  298.                         m_frame_counter.markFrame();
  299.  
  300.                         // update any required inputs
  301.  
  302.                         gsCInput::updateAll();
  303.  
  304.                         // execute main game loop - returns false when game over
  305.  
  306.                         if (!mainloop())
  307.                             m_running = false;
  308.                         }
  309.                     }
  310.                 }
  311.             }
  312.  
  313.         // shutdown game
  314.  
  315.         shutdown();
  316.  
  317.         // clear up window and window class
  318.  
  319.         DestroyWindow(m_window);
  320.  
  321.         UnregisterClass(m_app_name,m_instance);
  322.  
  323.         // if we're restarting we'll do it all again
  324.         }
  325.     while (m_restarting);
  326.  
  327.     return msg.wParam;
  328. }
  329.  
  330. //-------------------------------------------------------------
  331. // Default initialize
  332.  
  333. bool gsCApplication::initialize()
  334. {
  335.     // create input handler
  336.  
  337.     if (!gsCInput::initialize())
  338.         return false;
  339.  
  340.     // create visual handler
  341.  
  342.     if (!gsCVisual::initialize())
  343.         return false;
  344.  
  345.     gsCTimer::initialize();
  346.  
  347.     return true;
  348. }
  349.  
  350. //-------------------------------------------------------------
  351. // Default main loop - does nothing
  352.  
  353. bool gsCApplication::mainloop()
  354. {
  355.     return true;
  356. }
  357.  
  358. //-------------------------------------------------------------
  359. // Default shutdown
  360.  
  361. bool gsCApplication::shutdown()
  362. {
  363.     // destroy visual handler
  364.  
  365.     gsCVisual::shutdown();
  366.  
  367.     // destroy input handler
  368.  
  369.     gsCInput::shutdown();
  370.  
  371.     return true;
  372. }
  373.  
  374. //-------------------------------------------------------------
  375.