home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / swat.pak / SWAT.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  12KB  |  522 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   Example interactive debugging game
  4. //----------------------------------------------------------------------------
  5. #include <owl\owlpch.h>
  6. #include <owl\applicat.h>
  7. #include <owl\framewin.h>
  8. #include <owl\dialog.h>
  9. #include <owl\menu.h>
  10. #include <owl\dc.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "swat.h"
  15.  
  16. const int MissedPoints  = -2;
  17. const int HitPoints     = 5;
  18. const int MissedCritter = -1;
  19. const int CritterSize   = 72;
  20. const int MaxPop        = 35;
  21. const int MaxLiveTime   = 30;
  22. const int TimerId       = 1;
  23.  
  24. POINT Holes[5] = {
  25.   { 10, 10 }, { 200, 10 }, { 100, 100 }, { 10, 200 }, { 200, 200 }
  26. };
  27.  
  28. struct THole {
  29.   int  Time;
  30.   BOOL Dead;
  31. };
  32.  
  33. class TGameWindow : public TWindow {
  34.   public:
  35.     TGameWindow();
  36.  
  37.     void         CreateTimer();
  38.     void         DrawGameOver(TDC& DC);
  39.     void         DrawCritter(TDC& DC, int CritterNumber);
  40.     void         DrawScoreBoard(TDC& DC);
  41.     void         WriteScore(TDC& dc);
  42.  
  43.   protected:
  44.     void SetupWindow();
  45.     void Paint(TDC&, BOOL, TRect&);
  46.  
  47.     // message response functions
  48.     //
  49.     void CmAbout();        // IDM_ABOUT
  50.     void CmOptions();      // IDM_OPTION
  51.     void CmPause();        // IDM_PAUSE
  52.     void CmResetGame();    // IDM_RESET
  53.     void CmStopGame();     // IDM_STOP
  54.     void CeResetGame(TCommandEnabler&);
  55.     void CeOptions(TCommandEnabler&); 
  56.     void CeStopGame(TCommandEnabler&);
  57.     BOOL EvEraseBkgnd(HDC hDC);
  58.     void EvDestroy();
  59.     void EvLButtonDown(UINT, TPoint&);
  60.     void EvLButtonUp(UINT, TPoint&);
  61.     void EvTimer(UINT timerID);
  62.     void EvSize(UINT, TSize&);
  63.  
  64.   private:
  65.     TBitmap*    Live;
  66.     TBitmap*    Dead;
  67.     TBitmap*    GameOver;
  68.     TBitmap*    ScoreBoard;
  69.     TCursor*    CursorDown;
  70.     TCursor*    CursorUp;
  71.     int         Counter, Score, LiveTime, Frequence, GameTime;
  72.     int         Hits, Miss, Escaped;
  73.     BOOL        IsGameOver, IsPause;
  74.     THole       HoleInfo[5];
  75.  
  76.   friend class TOptionDialog;
  77.   DECLARE_RESPONSE_TABLE(TGameWindow);
  78. };
  79.  
  80. DEFINE_RESPONSE_TABLE1(TGameWindow, TWindow)
  81.   EV_COMMAND(IDM_ABOUT, CmAbout),
  82.   EV_COMMAND(IDM_PAUSE, CmPause),
  83.   EV_COMMAND(IDM_OPTION, CmOptions),
  84.   EV_COMMAND_ENABLE(IDM_OPTION, CeOptions),
  85.   EV_COMMAND(IDM_RESET, CmResetGame),
  86.   EV_COMMAND_ENABLE(IDM_RESET, CeResetGame),
  87.   EV_COMMAND(IDM_STOP, CmStopGame),
  88.   EV_COMMAND_ENABLE(IDM_STOP, CeStopGame),
  89.   EV_WM_ERASEBKGND,
  90.   EV_WM_DESTROY,
  91.   EV_WM_LBUTTONDOWN,
  92.   EV_WM_LBUTTONUP,
  93.   EV_WM_TIMER,
  94.   EV_WM_SIZE,
  95.   EV_WM_PAINT,
  96. END_RESPONSE_TABLE;
  97.  
  98. class TOptionDialog : public TDialog {
  99.   public:
  100.     TOptionDialog(TWindow* parent, char far* name)
  101.         : TWindow(parent), TDialog(parent, name) {}
  102.  
  103.     BOOL  CanClose();
  104.     void  SetupWindow();
  105.  
  106.     void  EvHScroll(UINT, UINT, HWND);
  107.  
  108.   DECLARE_RESPONSE_TABLE(TOptionDialog);
  109. };
  110. DEFINE_RESPONSE_TABLE1(TOptionDialog, TDialog)
  111.   EV_WM_HSCROLL,
  112. END_RESPONSE_TABLE;
  113.  
  114. //--------------- TOptionDialog ---------------
  115.  
  116. void
  117. TOptionDialog::SetupWindow()
  118. {
  119.   TDialog::SetupWindow();
  120.   TGameWindow* gameParent = (TGameWindow*)Parent; //can cast, no virtual bases
  121.   
  122.   ::SetScrollRange(GetDlgItem(IDD_LIVETIMESB), SB_CTL, 1, MaxLiveTime, FALSE);
  123.   ::SetScrollRange(GetDlgItem(IDD_POPSB), SB_CTL, 1, MaxPop, FALSE);
  124.   ::SetScrollPos(GetDlgItem(IDD_LIVETIMESB), SB_CTL, MaxLiveTime + 1 - gameParent->LiveTime, TRUE);
  125.   ::SetScrollPos(GetDlgItem(IDD_POPSB), SB_CTL, MaxPop+6-gameParent->Frequence, TRUE);
  126.   char str[10];
  127.   itoa(gameParent->GameTime / 10, str, 10);
  128.   SetDlgItemText(IDD_INPUTEDITBOX, str);
  129. }
  130.  
  131. void
  132. TOptionDialog::EvHScroll(UINT scrollCode, UINT thumbPos, HWND WndCtrl)
  133. {
  134.   UINT Pos = ::GetScrollPos(WndCtrl, SB_CTL);
  135.   const int PageStep = 10;
  136.  
  137.   switch (scrollCode) {
  138.   case SB_LINEUP:
  139.     Pos--;
  140.     break;
  141.   case SB_LINEDOWN:
  142.     Pos++;
  143.     break;
  144.   case SB_PAGEUP:
  145.     Pos -= PageStep;
  146.     break;
  147.   case SB_PAGEDOWN:
  148.     Pos += PageStep;
  149.     break;
  150.   case SB_THUMBPOSITION:
  151.   case SB_THUMBTRACK:
  152.     Pos = thumbPos;
  153.     break;
  154.   }
  155.   ::SetScrollPos(WndCtrl, SB_CTL, Pos, TRUE);
  156. }
  157.  
  158. BOOL
  159. TOptionDialog::CanClose()
  160. {
  161.   TGameWindow* gameParent = (TGameWindow*)Parent; //can cast, no virtual bases
  162.  
  163.   gameParent->LiveTime = MaxLiveTime + 1 - ::GetScrollPos(GetDlgItem(IDD_LIVETIMESB), SB_CTL);
  164.   gameParent->Frequence = MaxPop + 1 - ::GetScrollPos(GetDlgItem(IDD_POPSB), SB_CTL) + 5;
  165.  
  166.   BOOL noError;
  167.   int time = GetDlgItemInt(IDD_INPUTEDITBOX, &noError, FALSE) * 10;
  168.   if (noError && time > 0) {
  169.     gameParent->GameTime = time;
  170.     return TRUE;
  171.   } else {
  172.     MessageBox("Game time must be between 0 and 9830!", "Error", MB_OK);
  173.     return FALSE;
  174.   }
  175. }
  176.  
  177. // --------------- TGameWindow -----------------
  178.  
  179. TGameWindow::TGameWindow()
  180.   : TWindow(0, 0, 0)
  181. {
  182.   Attr.W = 282;
  183.   Attr.H = 400;
  184.   randomize();
  185.  
  186.   IsGameOver = TRUE;
  187.   IsPause = FALSE;
  188.   LiveTime = 10;
  189.   Frequence = 20;
  190.   Counter = 0;
  191.   Score = 0;
  192.   Hits = 0;
  193.   Miss = 0;
  194.   Escaped = 0;
  195.   GameTime = 150;        // fifteen seconds
  196.     
  197.   SetCursor(GetModule(), "Malet");
  198. }
  199.  
  200. void
  201. TGameWindow::SetupWindow()
  202. {
  203.   HINSTANCE inst = *GetModule();
  204.   CursorDown = new TCursor(inst, "MaletDown");
  205.   CursorUp = new TCursor(inst, "Malet");
  206.   Live = new TBitmap(inst, "Live");
  207.   Dead = new TBitmap(inst, "Dead");
  208.   GameOver = new TBitmap(inst, "GameOver");
  209.   ScoreBoard = new TBitmap(inst, "Board");
  210. }
  211.  
  212. void
  213. TGameWindow::CreateTimer()
  214. {
  215.   if (SetTimer(TimerId, 100, 0) == 0) {
  216.     MessageBox("No Timers Left", GetApplication()->GetName(),
  217.                MB_OK | MB_ICONEXCLAMATION);
  218.     exit(1);
  219.   }
  220. }
  221.  
  222. static
  223. void
  224. DrawBMP(TDC& dc, int x, int y, TBitmap& bitmap)
  225. {
  226.   TMemoryDC memDC(dc);
  227.   memDC.SelectObject(bitmap);
  228.  
  229.   BITMAP bm;
  230.   bitmap.GetObject(bm);
  231.   dc.BitBlt(x, y, bm.bmWidth, bm.bmHeight, memDC, 0, 0, SRCCOPY);
  232. }
  233.  
  234. void
  235. TGameWindow::DrawGameOver(TDC& dc)
  236. {
  237.   DrawBMP(dc, 10, 70, *GameOver);
  238. }
  239.  
  240. void
  241. TGameWindow::DrawCritter(TDC& dc, int critterNumber)
  242. {
  243.   if (HoleInfo[critterNumber].Time != 0) {
  244.     TMemoryDC memDC(dc);
  245.     if (HoleInfo[critterNumber].Dead)
  246.       memDC.SelectObject(*Dead);
  247.     else
  248.       memDC.SelectObject(*Live);
  249.     dc.BitBlt(Holes[critterNumber].x, Holes[critterNumber].y,
  250.               CritterSize, CritterSize, memDC, 0, 0, SRCCOPY);
  251.   } else {
  252.     dc.SelectStockObject(LTGRAY_BRUSH);
  253.     dc.SelectStockObject(NULL_PEN);
  254.     dc.Rectangle(Holes[critterNumber], TSize(CritterSize+1,CritterSize+1));
  255.   }
  256. }
  257.  
  258. void
  259. TGameWindow::DrawScoreBoard(TDC& dc)
  260. {
  261.   DrawBMP(dc, 11, 214, *ScoreBoard);
  262. }
  263.  
  264. void
  265. TGameWindow::WriteScore(TDC& dc)
  266. {
  267.   TBrush brush(TColor(128, 128, 0));    // Yellow
  268.   dc.SelectObject(brush);
  269.   dc.SelectStockObject(NULL_PEN);
  270.   dc.SetBkMode(TRANSPARENT);
  271.  
  272.   // Timer
  273.   dc.Rectangle(130, 252, 163, 275);
  274.   char s[21];
  275.   sprintf(s, "%3.3d", GameTime - Counter);
  276.   s[3] = s[2];
  277.   s[2]= '.';
  278.   dc.TextOut(TPoint(130, 252), s, 4);
  279.  
  280.   // Hits
  281.   dc.Rectangle(40, 310, 71, 329);
  282.   sprintf(s, "%3.3d", Hits);
  283.   dc.TextOut(TPoint(40, 310), s, strlen(s));
  284.  
  285.   // Misses
  286.   dc.Rectangle(77, 310, 117, 329);
  287.   sprintf(s, "%3.3d", Miss);
  288.   dc.TextOut(TPoint(77, 310), s, strlen(s));
  289.  
  290.   // Escaped
  291.   dc.Rectangle(133, 310, 174, 329);
  292.   sprintf(s, "%3.3d", Escaped);
  293.   dc.TextOut(TPoint(133, 310), s, strlen(s));
  294.  
  295.   // Total
  296.   dc.Rectangle(203, 310, 239, 328);
  297.   sprintf(s, "%3.3d", Score);
  298.   dc.TextOut(TPoint(203, 310), s, strlen(s));
  299.  
  300.   dc.RestoreObjects();
  301. }
  302.  
  303. void
  304. TGameWindow::CmAbout()
  305. {
  306.   TDialog(this, "About").Execute();
  307. }
  308.  
  309. void
  310. TGameWindow::CmOptions()
  311. {
  312.   TOptionDialog(this, "OptionDlg").Execute();
  313. }
  314.  
  315. void
  316. TGameWindow::CmPause()
  317. {
  318.   if (IsGameOver)
  319.     return;
  320.  
  321.   if (IsPause) {
  322.     IsPause = FALSE;
  323.     TMenu(*Parent).ModifyMenu(IDM_PAUSE, MF_BYCOMMAND, IDM_PAUSE, "&Pause");
  324.     Parent->DrawMenuBar();
  325.     CreateTimer();
  326.  
  327.   } else {
  328.     IsPause = TRUE;
  329.     KillTimer(TimerId);
  330.     TMenu(*Parent).ModifyMenu(IDM_PAUSE, MF_BYCOMMAND, IDM_PAUSE, "&Continue");
  331.     Parent->DrawMenuBar();
  332.   }
  333. }
  334.  
  335. void 
  336. TGameWindow::CeResetGame(TCommandEnabler& cmdEnabler)
  337. {
  338.   cmdEnabler.Enable(IsGameOver ? true : false);
  339. }
  340.  
  341. void 
  342. TGameWindow::CeOptions(TCommandEnabler& cmdEnabler) 
  343. {
  344.   cmdEnabler.Enable(IsGameOver ? true : false);    
  345. }
  346.  
  347. void 
  348. TGameWindow::CeStopGame(TCommandEnabler& cmdEnabler)
  349. {
  350.   cmdEnabler.Enable((IsGameOver || IsPause) ? false : true);   
  351. }
  352.  
  353. void
  354. TGameWindow::CmResetGame()
  355. {
  356.   TMenu menu(*Parent);
  357.   menu.ModifyMenu(IDM_PAUSE, MF_BYCOMMAND, IDM_PAUSE, "&Pause");
  358.   Parent->DrawMenuBar();
  359.   Invalidate(TRUE);
  360.   CreateTimer();
  361.   memset(HoleInfo, 0, sizeof(HoleInfo));
  362.   Counter = 0;
  363.   Score = 0;
  364.   Hits = 0;
  365.   Miss = 0;
  366.   Escaped = 0;
  367.   IsGameOver = FALSE;
  368.   if (IsPause) {
  369.     IsPause = FALSE;
  370.     menu.ModifyMenu(IDM_PAUSE, MF_BYCOMMAND, IDM_PAUSE, "&Pause");
  371.     Parent->DrawMenuBar();
  372.   }
  373. }
  374.  
  375. void
  376. TGameWindow::CmStopGame()
  377. {
  378.   KillTimer(TimerId);
  379.   TMenu menu(*Parent);
  380.   menu.ModifyMenu(IDM_PAUSE, MF_BYCOMMAND|MF_GRAYED, IDM_PAUSE, "&Pause");
  381.   IsPause = FALSE;
  382.   Parent->DrawMenuBar();
  383.   IsGameOver = TRUE;
  384.   Invalidate(TRUE);
  385.   Counter = GameTime;
  386. }
  387.  
  388. BOOL
  389. TGameWindow::EvEraseBkgnd(HDC hDC)
  390. {
  391.   TDC dc(hDC);
  392.   dc.TextRect(GetClientRect(), TColor::LtGray);
  393.   return TRUE;
  394. }
  395.  
  396. void
  397. TGameWindow::EvDestroy()
  398. {
  399.   delete Live;
  400.   delete Dead;
  401.   delete GameOver;
  402.   delete ScoreBoard;
  403.   KillTimer(TimerId);
  404.   TWindow::EvDestroy();
  405. }
  406.  
  407. void
  408. TGameWindow::EvLButtonDown(UINT, TPoint& clickPoint)
  409. {
  410.   SetCursor(GetModule(), "MaletDown");
  411.  
  412.   TPoint point;
  413.   GetCursorPos(point);
  414.   SetCursorPos(point.x, point.y);
  415.   if (IsGameOver || IsPause)
  416.     return;
  417.  
  418.   TClientDC dc(*this);
  419.   
  420.   BOOL hit = FALSE;
  421.   for (int i = 0; i < 5; i++) {
  422.     if (!HoleInfo[i].Dead && HoleInfo[i].Time != 0) {
  423.       TRect rect(Holes[i], TSize(CritterSize,CritterSize));
  424.       point = clickPoint;
  425.       if (rect.Contains(point)) {
  426.         Score += HitPoints;
  427.         HoleInfo[i].Dead = TRUE;
  428.         HoleInfo[i].Time = Counter + 2 * LiveTime;
  429.         Hits++;
  430.         hit = TRUE;
  431.         DrawCritter(dc, i);
  432.       }
  433.     }
  434.   }
  435.   if (!hit) {
  436.     Score += MissedPoints;
  437.     Miss++;
  438.   }
  439.   WriteScore(dc);
  440. }
  441.  
  442. void
  443. TGameWindow::EvLButtonUp(UINT, TPoint&)
  444. {
  445.   SetCursor(GetModule(), "Malet");
  446.  
  447.   TPoint point;
  448.   GetCursorPos(point);
  449.   SetCursorPos(point.x, point.y);
  450. }
  451.  
  452. void
  453. TGameWindow::EvTimer(UINT)
  454. {
  455.   TClientDC dc(*this);
  456.  
  457.   Counter++;
  458.   int i = random(Frequence);
  459.   if (i < 5) {
  460.     if (HoleInfo[i].Time == 0) {
  461.       HoleInfo[i].Time = Counter + LiveTime;
  462.       HoleInfo[i].Dead = FALSE;
  463.       DrawCritter(dc, i);
  464.     }
  465.   }
  466.   for (i = 0; i < 5; i++) {
  467.     if (Counter > HoleInfo[i].Time && HoleInfo[i].Time != 0) {
  468.       HoleInfo[i].Time = 0;
  469.       if (!HoleInfo[i].Dead) {
  470.         Score += MissedCritter;
  471.         Escaped++;
  472.       }
  473.       DrawCritter(dc, i);
  474.     }
  475.   }
  476.   WriteScore(dc);
  477.   if (Counter >= GameTime)
  478.     CmStopGame();
  479. }
  480.  
  481. void
  482. TGameWindow::EvSize(UINT /*SizeType*/, TSize& /*Size*/)
  483. {
  484.   if (IsGameOver)
  485.     return;
  486.   if (IsIconic())    // Could check SizeType
  487.     KillTimer(TimerId);
  488.   else if (!IsPause)
  489.     CreateTimer();
  490. }
  491.  
  492. void
  493. TGameWindow::Paint(TDC& dc, BOOL, TRect&)
  494. {
  495.   DrawScoreBoard(dc);
  496.   WriteScore(dc);
  497.   if (IsGameOver)
  498.     DrawGameOver(dc);
  499.   else
  500.     for (int i = 0; i < 5; i++)
  501.       DrawCritter(dc, i);
  502. }
  503.  
  504. // --------------- TApp ------------------------
  505.  
  506. class TApp : public TApplication {
  507.   public:
  508.     TApp() : TApplication() {}
  509.     void InitMainWindow() {
  510.       EnableCtl3d();
  511.       MainWindow = new TFrameWindow(0, "Swat!", new TGameWindow, TRUE);
  512.       MainWindow->AssignMenu("SWATMENU");
  513.       MainWindow->SetIcon(this, "Critter");
  514.     }
  515. };
  516.  
  517. int
  518. OwlMain(int /*argc*/, char* /*argv*/ [])
  519. {
  520.   return TApp().Run();
  521. }
  522.