home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / SWAT.PAK / SWAT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  12.3 KB  |  627 lines

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