home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / vjplusb / activex / inetsdk / samples / axscript / spruuids / src / score.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-15  |  10.6 KB  |  332 lines

  1. //---------------------------------------------------------------------------
  2. // Score.cpp
  3. //---------------------------------------------------------------------------
  4. // Score object to track score, # lives, level.
  5. //---------------------------------------------------------------------------
  6. // (C) Copyright 1995-1996 by Microsoft Corporation.  All rights reserved.
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  9. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  10. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  11. // PARTICULAR PURPOSE.
  12. //---------------------------------------------------------------------------
  13.  
  14. #include "Main.h"
  15. #include "Score.h"
  16. #include "Spr.h"
  17. #include "Game.h"
  18. extern CGame *g_pgame;
  19.  
  20.  
  21. //---------------------------------------------------------------------------
  22. // DEBUG info
  23. //---------------------------------------------------------------------------
  24. SZTHISFILE
  25.  
  26.  
  27. //---------------------------------------------------------------------------
  28. // Initialize score stuff
  29. //---------------------------------------------------------------------------
  30. HRESULT CScore::s_hr = E_FAIL;
  31.  
  32. HRESULT CScore::CreateScore
  33. (
  34.   HINSTANCE hinst,          // Needed to load bitmaps
  35.   HWND      hwnd,           // hwnd on which to draw the Score, Level, # Lives
  36.   HWND      hwndPS,         // hwnd of PlaySurface
  37.   HWND      hwndStat,       // hwnd of Status Bar
  38.   long      scoreFirst1Up,  // Score to first new life
  39.   long      scoreSecond1Up, // Score to 2nd new life
  40.   long      dscoreNext1Up,  // Score to next new life
  41.   int       cship,          // Number lives to start
  42.   IDBMP     idbmpShip,      // Bitmap for display of # lives
  43.   IDBMP     idbmpPlus,      // Bitmap for "+" when out of room for # lives
  44.   CScore  **ppscoreOut      // Return value: new score object
  45. )
  46. {
  47.   // Initialize output parameters
  48.   *ppscoreOut = NULL;
  49.  
  50.   // Validate required args, etc.
  51.   if (!idbmpShip || !hwnd)
  52.     return E_INVALIDARG;
  53.  
  54.   *ppscoreOut = new CScore(hinst, hwnd, hwndPS, hwndStat, scoreFirst1Up, scoreSecond1Up, dscoreNext1Up, cship, idbmpShip, idbmpPlus);
  55.   if (!ppscoreOut)
  56.     return E_OUTOFMEMORY;
  57.   if (s_hr)
  58.     {
  59.     delete *ppscoreOut;
  60.     return s_hr;
  61.     }
  62.  
  63.   return S_OK;
  64. }
  65.  
  66.  
  67. //---------------------------------------------------------------------------
  68. // Initialize score stuff
  69. //---------------------------------------------------------------------------
  70. CScore::CScore
  71. (
  72.   HINSTANCE hinst,          // Needed to load bitmaps
  73.   HWND      hwnd,           // hwnd on which to draw the Score, Level, # Lives
  74.   HWND      hwndPS,         // hwnd of PlaySurface
  75.   HWND      hwndStat,       // hwnd of Status Bar
  76.   long      scoreFirst1Up,  // Score to first new life
  77.   long      scoreSecond1Up, // Score to 2nd new life
  78.   long      dscoreNext1Up,  // Score to next new life
  79.   int       cshipStart,     // Number lives to start
  80.   IDBMP     idbmpShip,      // Bitmap for display of # lives
  81.   IDBMP     idbmpPlus       // Bitmap for "+" when out of room for # lives
  82. )
  83. {
  84.   BITMAP bmp;
  85.   RECT   rectStat;
  86.  
  87.   INIT_SIGNATURE(SIG_Score);
  88.  
  89.   // Assume success
  90.   s_hr = S_OK;
  91.  
  92.   // Assume reasonable default values, if not supplied
  93.   m_hinst          = hinst;
  94.   m_hwnd           = hwnd;
  95.   m_hwndStat       = hwndStat;
  96.   m_hwndPS         = hwndPS;
  97.   m_scoreFirst1Up  = scoreFirst1Up  ? scoreFirst1Up : 0x7fffffff;
  98.   m_scoreSecond1Up = scoreSecond1Up ? scoreFirst1Up : 0x7fffffff;
  99.   m_dscoreNext1Up  = dscoreNext1Up  ? dscoreNext1Up : 0x7fffffff;
  100.   m_cshipStart     = cshipStart;
  101.  
  102.   // Init rest of class
  103.   m_hbmpShip  = NULL;
  104.   m_hbmpPlus  = NULL;
  105.   m_cyMax     = 0;
  106.   m_cxShip    = 0;
  107.   m_cyShip    = 0;
  108.   m_cxPlus    = 0;
  109.   m_cyPlus    = 0;
  110.   // m_scoreNext1Up = m_scoreFirst1Up;    // Handled by NewGame()
  111.   // m_score        = 0;                  // Handled by NewGame()
  112.   // m_cship        = m_cshipStart;       // Handled by NewGame()
  113.   // m_lvl          = 0;                  // Handled by NewGame()
  114.   // m_rectScore    = 0;                  // Handled below
  115.   // m_rectShip     = 0;                  // Handled below
  116.   // m_rectLvl      = 0;                  // Handled below
  117.  
  118.   // Finish initing the score object
  119.   this->NewGame();
  120.   ASSERT(m_scoreNext1Up == m_scoreFirst1Up, "NewGame() not initing all");
  121.   ASSERT(!m_score, "NewGame() not initing all");
  122.   ASSERT(m_cship == cshipStart, "NewGame() not initing all");
  123.   ASSERT(!m_lvl, "NewGame() not initing all");
  124.  
  125.   // Load the bmp for the display of lives
  126.   m_hbmpShip = LoadBitmap(hinst, MAKEINTRESOURCE(idbmpShip));
  127.   if (!m_hbmpShip)
  128.     {
  129.     s_hr = E_FAIL;
  130.     return;
  131.     }
  132.   GetObject(m_hbmpShip, sizeof(bmp), (HGDIOBJ)&bmp);
  133.   m_cxPlus = m_cxShip = bmp.bmWidth;
  134.   m_cyPlus = m_cyShip = m_cyMax = bmp.bmHeight;
  135.  
  136.   // Load the bmp of the "+" for the display of lives
  137.   if (idbmpPlus)
  138.     {
  139.     m_hbmpPlus = LoadBitmap(hinst, MAKEINTRESOURCE(idbmpPlus));
  140.     if (!m_hbmpPlus)
  141.       {
  142.       s_hr = E_FAIL;
  143.       return;
  144.       }
  145.     GetObject(m_hbmpPlus, sizeof(bmp), (HGDIOBJ)&bmp);
  146.     m_cxPlus = bmp.bmWidth;
  147.     m_cyPlus = bmp.bmHeight;
  148.     if (m_cyPlus > m_cyMax)
  149.       m_cyMax = m_cyPlus;
  150.     }
  151.  
  152.   // Calc height of Text.
  153.   // HACK: Cheat and use DrawText() with a "|" instead of getting TextMetrics...
  154.   rectStat.top = 0;
  155.   DrawText(GetDC(hwnd), "|", 1, &rectStat, DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_CALCRECT);
  156.   m_cyStat = rectStat.bottom;
  157.   if (rectStat.bottom > m_cyMax)
  158.     m_cyMax = rectStat.bottom;
  159.  
  160.   // Place PlaySurface correctly
  161.   this->Size(372, 282);
  162. }
  163.  
  164.  
  165. //---------------------------------------------------------------------------
  166. // Given the size of the PlaySurface, calculate the size of the Dlg & other
  167. // components.
  168. //---------------------------------------------------------------------------
  169. void CScore::Size
  170. (
  171.   int cx,
  172.   int cy
  173. )
  174. {
  175.   RECT rect, rectCli;
  176.  
  177. #define cBRD  (6)
  178.   GetWindowRect(m_hwnd, &rect);
  179.   GetClientRect(m_hwnd, &rectCli);
  180.   ClientToScreen(m_hwnd, (LPPOINT)&rectCli);
  181.   ClientToScreen(m_hwnd, (LPPOINT)&rectCli.right);
  182.   MoveWindow(m_hwnd,     rect.left,
  183.                          rect.top,
  184.                          cx + (2 * cBRD) + (rect.right - rect.left) - (rectCli.right - rectCli.left),
  185.                          cy + (3 * cBRD + m_cyMax + m_cyStat) + (rect.bottom - rect.top) - (rectCli.bottom - rectCli.top),
  186.                          TRUE);
  187.   GetClientRect(m_hwnd, &rect);
  188.   MoveWindow(m_hwndStat, cBRD,
  189.                          rect.bottom - (m_cyStat + cBRD),
  190.                          rect.right  - (2 * cBRD),
  191.                          m_cyStat, TRUE);
  192.   MoveWindow(m_hwndPS,   cBRD,
  193.                          cBRD + m_cyMax,
  194.                          rect.right  - (2 * cBRD),
  195.                          rect.bottom - (3 * cBRD + m_cyMax + m_cyStat), TRUE);
  196.   GetWindowRect(m_hwndPS, &rect);
  197.   ScreenToClient(m_hwnd, (LPPOINT)&rect);
  198.   ScreenToClient(m_hwnd, (LPPOINT)&rect.right);
  199.   rect.top    = 1;
  200.   rect.bottom = m_cyMax + 4;
  201.   m_rectScore = rect;
  202.   m_rectShip  = rect;
  203.   m_rectLvl   = rect;
  204.   m_rectShip.right = m_rectLvl.left   = rect.left +  (rect.right - rect.left) / 3;
  205.   m_rectLvl.right  = m_rectScore.left = rect.left + ((rect.right - rect.left) / 3 * 2);
  206.   GetClientRect(m_hwndPS, &rect);
  207.   g_pgame->m_pdisp->m_cx = rect.right  - rect.left;
  208.   g_pgame->m_pdisp->m_cy = rect.bottom - rect.top;
  209.   InvalidateRect(m_hwnd,   NULL, TRUE);
  210.   InvalidateRect(m_hwndPS, NULL, TRUE);
  211. }
  212.  
  213.  
  214. //---------------------------------------------------------------------------
  215. // Terminate score stuff
  216. //---------------------------------------------------------------------------
  217. CScore::~CScore
  218. (
  219.   void
  220. )
  221. {
  222.   CHECK_SIGNATURE(SIG_Score);
  223.  
  224.   if (m_hbmpShip)
  225.     DeleteObject((HGDIOBJ)m_hbmpShip);
  226.   if (m_hbmpPlus)
  227.     DeleteObject((HGDIOBJ)m_hbmpPlus);
  228.  
  229.   DESTROY_SIGNATURE(SIG_Score);
  230. }
  231.  
  232.  
  233. //---------------------------------------------------------------------------
  234. // Re-initialize score stuff for new game
  235. //---------------------------------------------------------------------------
  236. void CScore::NewGame
  237. (
  238.   void
  239. )
  240. {
  241.   m_scoreNext1Up = m_scoreFirst1Up;
  242.   m_score        = 0;
  243.   m_cship        = m_cshipStart;
  244.   m_lvl          = 0;
  245.  
  246.   InvalidateRect(m_hwnd, NULL, TRUE);
  247. }
  248.  
  249.  
  250. //---------------------------------------------------------------------------
  251. // Paint score stuff: # 1Ups, current level, score
  252. //---------------------------------------------------------------------------
  253. void CScore::Paint
  254. (
  255.   HDC hdc
  256. )
  257. {
  258.   char     rgch[100];
  259.   int     x, y;
  260.   int     i;
  261.   extern HDC     g_hdcMem;
  262.   extern HBITMAP g_hbmpStock;
  263.  
  264.   SelectObject(g_hdcMem, m_hbmpShip);
  265.   x = m_rectShip.left;
  266.   y = m_rectShip.top + ((m_rectShip.bottom - m_rectShip.top - m_cyShip) >> 1);
  267.  
  268.   // Draw the 1Ups w/a "+", if necessary
  269.   for (i=1; i<m_cship; i++)
  270.     {
  271.     BitBlt(hdc, x, y, m_cxShip, m_cyShip, g_hdcMem, 0, 0, SRCCOPY);
  272.     x += m_cxShip + (m_cxShip >> 2);
  273.  
  274.     // If we only have more 1Ups, but only room for the "+", draw the "+"
  275.     if (x + m_cxShip + m_cxPlus > m_rectShip.right && m_hbmpPlus && i+1<m_cship)
  276.       {
  277.       y = m_rectShip.top + ((m_rectShip.bottom - m_rectShip.top - m_cyPlus) >> 1);
  278.       SelectObject(g_hdcMem, m_hbmpPlus);
  279.       BitBlt(hdc, x, y, m_cxPlus, m_cyPlus, g_hdcMem, 0, 0, SRCCOPY);
  280.       break;
  281.       }
  282.     }
  283.   SelectObject(g_hdcMem, g_hbmpStock);
  284.  
  285.   SetBkMode(hdc, TRANSPARENT);
  286.   wsprintf(rgch, "%ld", m_score);
  287.   DrawText(hdc, rgch, -1, &m_rectScore, DT_RIGHT|DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
  288.  
  289.   wsprintf(rgch, "%d", m_lvl);
  290.   DrawText(hdc, rgch, -1, &m_rectLvl,   DT_CENTER|DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
  291. }
  292.  
  293.  
  294. //---------------------------------------------------------------------------
  295. // Change the score by the delta d.
  296. //---------------------------------------------------------------------------
  297. void CScore::Add
  298. (
  299.   long d      // Change the score by this amount (signed)
  300. )
  301. {
  302.   m_score += d;
  303.   if (m_score < 0)
  304.     m_score = 0;
  305.   if (m_score >= m_scoreNext1Up)
  306.     {
  307.     if (m_score > m_scoreSecond1Up)
  308.       m_scoreNext1Up += m_dscoreNext1Up;
  309.     else
  310.       m_scoreNext1Up = m_scoreSecond1Up;
  311.     m_cship++;
  312.     InvalidateRect(m_hwnd, &m_rectShip, TRUE);
  313.     g_pgame->m_pgameoa->FireNewShip();
  314.     }
  315.  
  316.   InvalidateRect(m_hwnd, &m_rectScore, TRUE);
  317. }
  318.  
  319.  
  320. //---------------------------------------------------------------------------
  321. // Called when pausing or unpausing
  322. //---------------------------------------------------------------------------
  323. void CScore::SetStatusText
  324. (
  325.   const char *pszText
  326. )
  327. {
  328.   SetWindowText(m_hwndStat, pszText);
  329. }
  330.  
  331. //--- EOF -------------------------------------------------------------------
  332.