home *** CD-ROM | disk | FTP | other *** search
/ Speelhal Klassiekers - Hits des Salles de Jeux / Arcade.bin / games / Xonix32 / SRC / XONIX32.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-05  |  17.4 KB  |  652 lines

  1.  
  2. //===========================
  3. // Xonix32.cpp
  4. // by SA VanNess
  5. // 08 Mar 97
  6. // for the Win32 platform
  7. //===========================
  8. // Xonix32 main module
  9. // Class implementations
  10. //===========================
  11. // Copyright (C) 1997  SA VanNess
  12. // <savanness@pipeline.com>
  13. //
  14. // For copyright information, see the file gnu_license.txt included
  15. // with this source code distribution.
  16. //
  17. // This program is free software; you can redistribute it and/or modify
  18. // it under the terms of the GNU General Public License as published by
  19. // the Free Software Foundation; either version 2 of the License, or
  20. // (at your option) any later version.
  21. //
  22. // This program is distributed in the hope that it will be useful,
  23. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. // GNU General Public License for more details.
  26. //
  27. // You should have received a copy of the GNU General Public License
  28. // along with this program; if not, write to the Free Software
  29. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  30. //===========================
  31.  
  32. #include <afxwin.h>
  33. #include <afxcmn.h>
  34. #include <afxres.h>
  35.  
  36. #include "resource.h"
  37. #include "macros.h"
  38. #include "hiscores.h"
  39. #include "gamewnd.h"
  40. #include "xpoint.h"
  41. #include "xbitmap.h"
  42. #include "xonix32.h"
  43.  
  44.  
  45. //===========================
  46. // CGame
  47.  
  48. //-----------------
  49. CGame::CGame(CGameWnd *pMainWnd)
  50. {
  51. //Attach to the frame-wnd obj
  52. m_pGameWnd = pMainWnd;
  53. m_pGameWnd->m_pGame = this;
  54.  
  55. //Copy shared resources from the frame-wnd obj
  56. m_pdcCli = m_pGameWnd->m_pdcCli;
  57. m_rcXCli = m_pGameWnd->m_rcCli;
  58.  
  59. //Fine-tune the virtual client rectangle
  60. m_rcXCli.right = (OBJ_SIZE+(OBJ_MOVE*((m_rcXCli.right-OBJ_SIZE)/OBJ_MOVE)));
  61. m_rcXCli.bottom = (OBJ_SIZE+(OBJ_MOVE*((m_rcXCli.bottom-OBJ_SIZE)/OBJ_MOVE)));
  62.  
  63. //Clear the msg overlay field
  64. m_szMsgText[0] = '\0';
  65. m_bStall = FALSE;
  66.  
  67. //Alloc obj arrays
  68. m_pBDot = new XBDot[MAXBDOTS];
  69. m_pDot = new XDot[MAXDOTS];
  70. m_pLine = new XLine[MAXLINES];
  71.  
  72. //Set up shadow-bmp DC
  73. m_dcMem.CreateCompatibleDC(m_pGameWnd->m_pdcCli);
  74. m_gBmp.CreateCompatibleBitmap(m_pdcCli,m_pGameWnd->m_rcCli.right,m_pGameWnd->m_rcCli.bottom);
  75. m_dcMem.SelectObject(&m_gBmp);
  76. m_dcMem.SetBkColor(RGB_BLACK);
  77. m_dcMem.SetBkMode(TRANSPARENT);
  78.  
  79. //Set up virtual bitmap
  80. m_xBmp.Create(m_rcXCli.right,m_rcXCli.bottom);
  81.  
  82. //Load BMP objs
  83. m_dcMemObj.CreateCompatibleDC(m_pdcCli);
  84. m_gBmpGuy.LoadBitmap(IDB_GUY1);
  85. m_gBmpBDot.LoadBitmap(IDB_BDOT1);
  86. m_gBmpDot.LoadBitmap(IDB_DOT1);
  87.  
  88. //Create common GDI obj
  89. m_gPenYellow.CreatePen(PS_SOLID,3,RGB_YELLOW);
  90. m_gPenBlack.CreatePen(PS_SOLID,3,RGB_BLACK);
  91. m_gFontFSys.CreateStockObject(SYSTEM_FIXED_FONT);
  92.  
  93. // Paint the splash screen
  94. SplashScreen();
  95. }
  96.  
  97. //-----------------
  98. CGame::~CGame()
  99. {
  100. m_gPenYellow.DeleteObject();
  101. m_gPenBlack.DeleteObject();
  102. m_gBmpGuy.DeleteObject();
  103. m_gBmpBDot.DeleteObject();
  104. m_gBmpDot.DeleteObject();
  105.  
  106. delete [] m_pLine;
  107. delete [] m_pDot;
  108. delete [] m_pBDot;
  109. }
  110.  
  111. //-----------------
  112. UINT CGame::GameOver()
  113. {
  114. Paint(); //clear any previous messages
  115.  
  116. //Display msg
  117. sprintf(m_szMsgText,"G A M E  O V E R");
  118. Paint();
  119. Sleep(1000);
  120. SplashScreen();
  121.  
  122. return m_iScore;
  123. }
  124.  
  125. //-----------------
  126. void CGame::HandleKbd(UINT nChar)
  127. {
  128. switch (nChar)
  129.    {
  130.    //Movement keys
  131.    /*case VK_SPACE: m_Guy.SetDir(0,0); break;*/
  132.    case VK_LEFT:  m_Guy.SetDir(-OBJ_MOVE,0); break;
  133.    case VK_UP:    m_Guy.SetDir(0,-OBJ_MOVE); break;
  134.    case VK_RIGHT: m_Guy.SetDir(OBJ_MOVE,0); break;
  135.    case VK_DOWN:  m_Guy.SetDir(0,OBJ_MOVE); break;
  136.    
  137.    //Cheat key
  138. #ifndef RELEASE
  139.    case VK_RETURN:
  140.    if (m_pGameWnd->MessageBox("Jump ahead 5 levels?","Confirm Cheat Request...",
  141.        MB_OKCANCEL|MB_ICONQUESTION) == IDOK)
  142.       {
  143.       m_iLevel+=5;
  144.       m_nMen+=5; 
  145.  
  146.       Paint();
  147.       Sleep(500); 
  148.       NewLevel(TRUE);
  149.       }
  150.    break;
  151. #endif //!release
  152.    } //end of switch-block
  153. }
  154.  
  155. //-----------------
  156. void CGame::PauseGame(BOOL bPause)
  157. {
  158. return;
  159. }
  160.  
  161. //-----------------
  162. BOOL CGame::RunGame()
  163. {
  164. UINT i;
  165. CPen *pOldPen;
  166. CBitmap *pOldBmp;
  167. BOOL bDead = FALSE, bDone = FALSE, bOldDraw = m_bDrawing;
  168.  
  169. //Check timer
  170. if (--m_iTimeRemaining <= 0)
  171.    {
  172.    bDead = TRUE;
  173.    sprintf(m_szMsgText,"Out of Time!");
  174.    }
  175.  
  176. //Erase guy
  177. pOldBmp = m_dcMemObj.SelectObject(&m_gBmpGuy);
  178.  m_Guy.Draw(m_dcMemObj,m_dcMem);
  179. m_dcMemObj.SelectObject(pOldBmp);
  180.  
  181. //Erase other objs
  182. pOldBmp = m_dcMemObj.SelectObject(&m_gBmpBDot);
  183.  for(i=0;i < m_nBDots;i++) m_pBDot[i].Draw(m_dcMemObj,m_dcMem);
  184. m_dcMemObj.SelectObject(pOldBmp);
  185.  
  186. pOldBmp = m_dcMemObj.SelectObject(&m_gBmpDot);
  187.  for(i=0;i < m_nDots;i++) m_pDot[i].Draw(m_dcMemObj,m_dcMem);
  188. m_dcMemObj.SelectObject(pOldBmp);
  189.  
  190. pOldPen = m_dcMem.SelectObject(&m_gPenBlack);
  191.  for(i=0;i < m_nLines;i++)
  192.     {
  193.     m_pLine[i].Draw(m_dcMem);
  194.     m_pLine[i].EraseBG(m_xBmp);
  195.     }
  196. m_dcMem.SelectObject(pOldPen);
  197.  
  198. //Update guy and do RScan and such
  199. if (m_bDrawing && m_Guy.CldRed(m_xBmp,TRUE)) bDead = TRUE;
  200. m_Guy.Clip(m_rcXCli);
  201. m_bDrawing = m_Guy.Update(m_dcMem, m_xBmp, m_bDrawing);
  202.  
  203. //Connected?
  204. if (!bDead && bOldDraw && !m_bDrawing)
  205.    {
  206.    //Change red to blue on xBmp
  207.    m_xBmp.Wipe(XBC_RED,XBC_BLUEGRN);
  208.    
  209.    //Mark white dots and yellowline endpoints on xBmp
  210.    for(i=0;i < m_nDots;i++)
  211.       {
  212.       m_xBmp.SetPixel(m_pDot[i].x,m_pDot[i].y,XBC_WHITE,TRUE);
  213.       m_xBmp.SetPixel(m_pDot[i].x+1,m_pDot[i].y,XBC_WHITE,TRUE);
  214.       m_xBmp.SetPixel(m_pDot[i].x,m_pDot[i].y+1,XBC_WHITE,TRUE);
  215.       m_xBmp.SetPixel(m_pDot[i].x+1,m_pDot[i].y+1,XBC_WHITE,TRUE);
  216.       }
  217.    for(i=0;i < m_nLines;i++)
  218.       {
  219.       m_xBmp.SetPixel(m_pLine[i].P0.x,m_pLine[i].P0.y,XBC_WHITE,TRUE);
  220.       m_xBmp.SetPixel(m_pLine[i].P0.x+1,m_pLine[i].P0.y,XBC_WHITE,TRUE);
  221.       m_xBmp.SetPixel(m_pLine[i].P0.x,m_pLine[i].P0.y+1,XBC_WHITE,TRUE);
  222.       m_xBmp.SetPixel(m_pLine[i].P0.x+1,m_pLine[i].P0.y+1,XBC_WHITE,TRUE);
  223.       m_xBmp.SetPixel(m_pLine[i].P1.x,m_pLine[i].P1.y,XBC_WHITE,TRUE);
  224.       m_xBmp.SetPixel(m_pLine[i].P1.x+1,m_pLine[i].P1.y,XBC_WHITE,TRUE);
  225.       m_xBmp.SetPixel(m_pLine[i].P1.x,m_pLine[i].P1.y+1,XBC_WHITE,TRUE);
  226.       m_xBmp.SetPixel(m_pLine[i].P1.x+1,m_pLine[i].P1.y+1,XBC_WHITE,TRUE);
  227.       }
  228.  
  229.    //Scan xBmp from four corners of current position
  230.    UINT xx,yy;
  231.    BOOL bFilled = FALSE;
  232.    xx = m_Guy.x - OBJ_OFFSET; yy = m_Guy.y - OBJ_OFFSET;
  233.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  234.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  235.    xx = m_Guy.x - OBJ_OFFSET; yy = m_Guy.y + OBJ_OFFSET;
  236.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  237.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  238.    xx = m_Guy.x + OBJ_OFFSET; yy = m_Guy.y - OBJ_OFFSET;
  239.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  240.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  241.    xx = m_Guy.x + OBJ_OFFSET; yy = m_Guy.y + OBJ_OFFSET;
  242.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  243.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  244.  
  245.    //Scan xBmp from four sides of previous position
  246.    xx = (m_Guy.x-m_Guy.dx) - OBJ_OFFSET; yy = (m_Guy.y-m_Guy.dy);
  247.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  248.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  249.    xx = (m_Guy.x-m_Guy.dx) + OBJ_OFFSET; yy = (m_Guy.y-m_Guy.dy);
  250.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  251.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  252.    xx = (m_Guy.x-m_Guy.dx); yy = (m_Guy.y-m_Guy.dy) - OBJ_OFFSET;
  253.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  254.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  255.    xx = (m_Guy.x-m_Guy.dx); yy = (m_Guy.y-m_Guy.dy) + OBJ_OFFSET;
  256.    if (!m_xBmp.GetPixel(xx,yy) && !m_xBmp.RScan(xx,yy))
  257.       { m_xBmp.FloodFill(xx,yy,XBC_BLUEGRN); bFilled = TRUE; }
  258.  
  259.    //Remove dots and yellowline enpoints from xBmp
  260.    for(i=0;i < m_nDots;i++)
  261.       {
  262.       m_xBmp.SetPixel(m_pDot[i].x,m_pDot[i].y,XBC_WHITE,FALSE);
  263.       m_xBmp.SetPixel(m_pDot[i].x+1,m_pDot[i].y,XBC_WHITE,FALSE);
  264.       m_xBmp.SetPixel(m_pDot[i].x,m_pDot[i].y+1,XBC_WHITE,FALSE);
  265.       m_xBmp.SetPixel(m_pDot[i].x+1,m_pDot[i].y+1,XBC_WHITE,FALSE);
  266.       }
  267.    for(i=0;i < m_nLines;i++)
  268.       {
  269.       m_xBmp.SetPixel(m_pLine[i].P0.x,m_pLine[i].P0.y,XBC_WHITE,FALSE);
  270.       m_xBmp.SetPixel(m_pLine[i].P0.x+1,m_pLine[i].P0.y,XBC_WHITE,FALSE);
  271.       m_xBmp.SetPixel(m_pLine[i].P0.x,m_pLine[i].P0.y+1,XBC_WHITE,FALSE);
  272.       m_xBmp.SetPixel(m_pLine[i].P0.x+1,m_pLine[i].P0.y+1,XBC_WHITE,FALSE);
  273.       m_xBmp.SetPixel(m_pLine[i].P1.x,m_pLine[i].P1.y,XBC_WHITE,FALSE);
  274.       m_xBmp.SetPixel(m_pLine[i].P1.x+1,m_pLine[i].P1.y,XBC_WHITE,FALSE);
  275.       m_xBmp.SetPixel(m_pLine[i].P1.x,m_pLine[i].P1.y+1,XBC_WHITE,FALSE);
  276.       m_xBmp.SetPixel(m_pLine[i].P1.x+1,m_pLine[i].P1.y+1,XBC_WHITE,FALSE);
  277.       }
  278.  
  279.    //Cleanup after rscan calls
  280.    m_xBmp.Wipe(XBC_GREY,XBC_NONE);
  281.  
  282.    //Stop the guy
  283.    m_Guy.SetDir(0,0);
  284.  
  285.    //Refresh the shadow-ram from xBmp
  286.    m_iFillFraction = m_xBmp.CalcFillFraction(m_xBmp.ExpandTo(m_dcMem));
  287.    m_iFilledPixLine = 0;
  288.    m_nFilledPix = 0;
  289.  
  290.    //Update status bar
  291.    UpdateSB();
  292.    } //end of connection if-block
  293.  
  294. //Update other obj positions and perform cld
  295. for(i=0;i < m_nBDots;i++)
  296.    {
  297.    m_pBDot[i].Clip(m_rcXCli);
  298.    m_pBDot[i].Update(m_xBmp);
  299.    if (!m_bDrawing && m_pBDot[i].CheckDist(m_Guy) <= OBJ_SIZE) bDead = TRUE;
  300.    }
  301.  
  302. for(i=0;i < m_nDots;i++)
  303.    {
  304.    m_pDot[i].Update(m_xBmp);
  305.    if (m_bDrawing && m_pDot[i].CldRed(m_xBmp)) bDead = TRUE;
  306.    }
  307.  
  308. for(i=0;i < m_nLines;i++)
  309.    m_pLine[i].Update(m_xBmp);
  310.  
  311. //Draw objs
  312. RenderObjs();
  313.  
  314. //Update fill percentage
  315. m_nFilledPix += m_xBmp.CountFilledPix(m_iFilledPixLine,m_iFilledPixLine+20);
  316. m_iFilledPixLine += 20;
  317.  
  318. if (m_iFilledPixLine >= (UINT)m_rcXCli.bottom)
  319.    {
  320.    m_iFillFraction = m_xBmp.CalcFillFraction(m_nFilledPix);
  321.    m_iFilledPixLine = 0;
  322.    m_nFilledPix = 0;
  323.    }
  324.  
  325. //Check if we've won
  326. if (m_iFillFraction >= 750)
  327.    {
  328.    bDone = TRUE;
  329.    sprintf(m_szMsgText,"Level Complete!");
  330.    }
  331.    
  332. //Check death flag
  333. if (bDead)
  334.    if (--m_nMen)
  335.       {
  336.       Paint();
  337.       Sleep(1500);
  338.       NewLevel(FALSE);
  339.       return TRUE;
  340.       }
  341.    else
  342.       {
  343.       Paint();
  344.       Sleep(1500);
  345.       return FALSE; //game over
  346.       }
  347.  
  348. //Check newlevel flag
  349. if (bDone)
  350.    {
  351.    m_iLevel++;
  352.    m_nMen++;
  353.    m_iScore += 100+10*((1000/m_pGameWnd->m_iGameSpdDelay)-MIN_FPS);
  354.    m_iScore += ((m_bBonusElligible) ? BONUS_CALC(m_iTimeRemaining,m_iLevelTimeLimit) : 0);
  355.  
  356.    Paint();
  357.    Sleep(1500);
  358.    NewLevel(TRUE);
  359.    return TRUE;
  360.    }
  361.  
  362. //Check quit flag
  363. if (m_bQFlag) //escape was pressed
  364.    return FALSE; //game over
  365.  
  366. //Continue running
  367. return TRUE;
  368. }
  369.  
  370. //-----------------
  371. void CGame::RenderObjs()
  372. {
  373. UINT i;
  374. CPen *pOldPen;
  375. CBitmap *pOldBmp;
  376.  
  377. //Draw objs
  378. pOldPen = m_dcMem.SelectObject(&m_gPenYellow);
  379.  for(i=0;i < m_nLines;i++) m_pLine[i].Draw(m_dcMem);
  380. m_dcMem.SelectObject(pOldPen);
  381.  
  382. pOldBmp = m_dcMemObj.SelectObject(&m_gBmpDot);
  383.  for(i=0;i < m_nDots;i++) m_pDot[i].Draw(m_dcMemObj,m_dcMem);
  384. m_dcMemObj.SelectObject(pOldBmp);
  385.  
  386. pOldBmp = m_dcMemObj.SelectObject(&m_gBmpBDot);
  387.  for(i=0;i < m_nBDots;i++) m_pBDot[i].Draw(m_dcMemObj,m_dcMem);
  388. m_dcMemObj.SelectObject(pOldBmp);
  389.  
  390. pOldBmp = m_dcMemObj.SelectObject(&m_gBmpGuy);
  391.  m_Guy.Draw(m_dcMemObj,m_dcMem);
  392. m_dcMemObj.SelectObject(pOldBmp);
  393. }
  394.  
  395. //-----------------
  396. void CGame::Paint()
  397. {
  398. //Msg stalling before bitblt wipe
  399. if (m_bStall)
  400.    {
  401.    Sleep(1500);
  402.    m_szMsgText[0] = '\0';
  403.    m_bStall = FALSE;
  404.    }
  405.  
  406. //BitBlt from shadow-bmp to client-area
  407. m_pdcCli->BitBlt(0,0,m_pGameWnd->m_rcCli.right,m_pGameWnd->m_rcCli.bottom,&m_dcMem,0,0,SRCCOPY);
  408.  
  409. //Overlay messages (if any) onto shadow-bmp
  410. if (m_szMsgText[0])
  411.    {
  412.    CFont *pOldFont = m_pdcCli->SelectObject(&m_gFontFSys);
  413.     m_pdcCli->SetTextAlign(TA_BASELINE|TA_CENTER);
  414.     m_pdcCli->SetTextColor(RGB_YELLOW2);
  415.     m_pdcCli->TextOut((m_rcXCli.right/2),(m_rcXCli.bottom/2),m_szMsgText,strlen(m_szMsgText));
  416.    m_pdcCli->SelectObject(pOldFont);
  417.  
  418.    // Set flag to cause delay before next repaint
  419.    m_bStall = TRUE;
  420.    }
  421. }
  422.  
  423. //-----------------
  424. void CGame::UpdateSB()
  425. {
  426. //Generate status bar text
  427. sprintf(g_szBuffer,"Level:%d   Xonii:%d   Score:%d   Filled:%4.1f%%   Bonus:%d   Time:%d",
  428.         m_iLevel,m_nMen,m_iScore,(float)(m_iFillFraction)/10.0,
  429.         ((m_bBonusElligible) ? BONUS_CALC(m_iTimeRemaining,m_iLevelTimeLimit) : 0),
  430.         (m_iTimeRemaining/NOM_FPS));
  431.         
  432.  
  433. //Append fps info
  434. #ifdef BENCH_FPS
  435. sprintf(g_szBuffer,"%s     fps:%5.2f",
  436.         g_szBuffer,m_pGameWnd->m_fFPS);
  437. #endif //bench_fps
  438.  
  439. //Low-time warnings and bonus display
  440. if (m_iTimeRemaining <= NOM_FPS)
  441.    sprintf(g_szBuffer,"%s   <<< Out of Time!",g_szBuffer);
  442. else if ((m_iTimeRemaining < 31*NOM_FPS) && !((m_iTimeRemaining/NOM_FPS)&0x0001)) //flashing
  443.    sprintf(g_szBuffer,"%s   <<< Low Time!",g_szBuffer);
  444.  
  445. m_pGameWnd->m_sbarc.SetText(g_szBuffer,255,0);
  446. m_pGameWnd->m_sbarc.UpdateWindow();
  447. }
  448.  
  449. //-----------------
  450. void CGame::NewLevel(BOOL bClear)
  451. {
  452. UINT i;
  453. CRect rcTemp;
  454.  
  455. //Init vars
  456. m_bDrawing = FALSE;
  457. m_bQFlag = FALSE;
  458. m_bBonusElligible = bClear;
  459.  
  460. m_nFilledPix = 0;
  461. m_iFilledPixLine = 0;
  462. m_iFillFraction = 0;
  463.  
  464. m_bStall = FALSE;
  465. m_szMsgText[0] = '\0';
  466.  
  467. //Calculate time limit based on level
  468. m_iLevelTimeLimit = NOM_FPS*MIN(60*5,60*m_iLevel);
  469.  
  470. if (!bClear && !m_iTimeRemaining) //if death due to timeout, halve the time limit!
  471.    m_iTimeRemaining = m_iLevelTimeLimit /= 2;
  472. if (bClear) m_iTimeRemaining = m_iLevelTimeLimit;
  473.  
  474. //Set starting position at top center of screen
  475. m_Guy.SetPos((UINT)(OBJ_MOVE*(m_rcXCli.right/OBJ_MOVE)/2)-1,OBJ_MOVE-1);
  476. m_Guy.SetDir(0,0);
  477.  
  478. //Randomize obj positions
  479. m_nBDots = LEVEL2BDOTS(m_iLevel);
  480. rcTemp.SetRect(20,m_rcXCli.bottom-10,m_rcXCli.right-20,m_rcXCli.bottom-8);
  481. for(i=0;i < m_nBDots;i++)
  482.    m_pBDot[i].Randomize(rcTemp,2,OBJ_MOVE-1);
  483.  
  484. if (bClear)
  485.    {
  486.    m_nDots = LEVEL2DOTS(m_iLevel);
  487.    rcTemp.SetRect(50,50,m_rcXCli.right-50,m_rcXCli.bottom-50);
  488.    for(i=0;i < m_nDots;i++)
  489.       m_pDot[i].Randomize(rcTemp,1,OBJ_MOVE-1);
  490.  
  491.    m_nLines = LEVEL2LINES(m_iLevel);
  492.    rcTemp.SetRect(50,50,m_rcXCli.right-50,m_rcXCli.bottom-50);
  493.    for(i=0;i < m_nLines;i++)
  494.       m_pLine[i].Randomize(rcTemp,1,OBJ_MOVE-2);
  495.    }
  496.  
  497. //Draw init screen
  498. if (bClear)
  499.    {
  500.    m_dcMem.FillSolidRect(m_pGameWnd->m_rcCli,RGB_BLUEGRN);
  501.    m_xBmp.Clear();
  502.    m_xBmp.FillSolidRect(m_rcXCli,XBC_BLUEGRN,TRUE);
  503.    rcTemp = m_rcXCli;
  504.    rcTemp.DeflateRect(BORDER_THICKNESS,BORDER_THICKNESS);
  505.    m_xBmp.FillSolidRect(rcTemp,XBC_FULL,FALSE);
  506.    }
  507. else
  508.    {
  509.    m_xBmp.Wipe(XBC_RED,XBC_NONE); //remove redline
  510.    }
  511.  
  512. //Refresh the shadow-ram from xBmp
  513. m_iFillFraction = m_xBmp.CalcFillFraction(m_xBmp.ExpandTo(m_dcMem));
  514.  
  515. //Display msg
  516. sprintf(m_szMsgText,"Ready...");
  517.  
  518. //Update status bar
  519. UpdateSB();
  520.  
  521. //Draw objs
  522. RenderObjs();
  523. }
  524.  
  525. //-----------------
  526. void CGame::NewGame(UINT iInitLevel)
  527. {
  528. //Reset all game-level vars
  529. m_iLevel = iInitLevel;
  530. m_iScore = 0;
  531. m_nMen = 3;
  532.  
  533. //Init the first level
  534. NewLevel(TRUE);
  535. }
  536.  
  537. //-----------------
  538. void CGame::SplashScreen()
  539. {
  540. long x,y;
  541. CBitmap gBmpSplash;
  542. CBitmap* pOldBmp;
  543. CPen* pOldPen;
  544. CRect rcTemp;
  545.  
  546. // Draw blue border
  547. m_dcMem.FillSolidRect(m_pGameWnd->m_rcCli,RGB_BLUEGRN);
  548. rcTemp = m_rcXCli;
  549. rcTemp.DeflateRect(BORDER_THICKNESS,BORDER_THICKNESS);
  550. m_dcMem.FillSolidRect(rcTemp,RGB_BLACK);
  551.  
  552. // Draw title bitmap
  553. x = (m_pGameWnd->m_rcCli.right/2)-(121/2);
  554. y = (m_pGameWnd->m_rcCli.bottom/2)-(47/2);
  555. gBmpSplash.LoadBitmap(IDB_SPLASH); //121x47
  556. pOldBmp = m_dcMemObj.SelectObject(&gBmpSplash);
  557.  m_dcMem.BitBlt(x,y,121,47,&m_dcMemObj,0,0,SRCCOPY);
  558. m_dcMemObj.SelectObject(pOldBmp);
  559. gBmpSplash.DeleteObject();
  560.  
  561. // Draw yellowlines for "X"
  562. x -= 15; y += 15;
  563. m_pLine[0].P0.x = x-20; m_pLine[0].P0.y = y-40;
  564. m_pLine[0].P1.x = x+20; m_pLine[0].P1.y = y+40;
  565. m_pLine[1].P0.x = x-20; m_pLine[1].P0.y = y+40;
  566. m_pLine[1].P1.x = x+20; m_pLine[1].P1.y = y-40;
  567.  
  568. pOldPen = m_dcMem.SelectObject(&m_gPenYellow);
  569.  m_pLine[0].Draw(m_dcMem);
  570.  m_pLine[1].Draw(m_dcMem);
  571. m_dcMem.SelectObject(pOldPen);
  572.  
  573. // BitBlt
  574. Paint();
  575. }
  576.  
  577.  
  578. //===========================
  579. // CXonixApp
  580.  
  581. //-----------------
  582. BOOL CXonixApp::InitInstance()
  583. {
  584. #ifdef _AFXDLL
  585. Enable3dControls(); //when using mfc in a shared dll
  586. #else //!_afxdll
  587. Enable3dControlsStatic(); //when linking to mfc statically
  588. #endif //_afxdll
  589.  
  590. // Register custom class
  591. CString sClassName = AfxRegisterWndClass(0,LoadStandardCursor(IDC_ARROW),0,LoadIcon(IDI_ICON32));
  592.  
  593. // Render the main window
  594. m_pMainWnd = new CGameWnd(sClassName,m_lpCmdLine);
  595. m_pMainWnd->ShowWindow(m_nCmdShow);
  596. m_pMainWnd->UpdateWindow();
  597.  
  598. // Insantiate the game object
  599. m_pGame = new CGame((CGameWnd *)m_pMainWnd);
  600.  
  601. //Open an output file
  602. #ifdef LOGFILE
  603. g_pfLog = fopen("logfile.out","w");
  604. #endif //logfile
  605.  
  606. return TRUE;
  607. }
  608.  
  609. //-----------------
  610. int CXonixApp::ExitInstance()
  611. {
  612. //Close the output file
  613. #ifdef LOGFILE
  614. fclose(g_pfLog);
  615. #endif //logfile
  616.  
  617. // Delete the game object
  618. delete m_pGame;
  619.  
  620. return 0;
  621. }
  622.  
  623. //-----------------
  624. BOOL CXonixApp::OnIdle(long lCount)
  625. {
  626. //Allow system processing
  627. BOOL bMore = CWinApp::OnIdle(lCount);
  628.  
  629. //Check for NULL ptr
  630. if (!m_pGame) return bMore;
  631.  
  632. //Idle-time processing (with hires timing) is used for the main loop
  633. bMore |= m_pGame->m_pGameWnd->MainLoop();
  634. bMore |= m_pGame->m_pGameWnd->AnimLoop();
  635.  
  636. //Allow NT systems to relenquish the remainder of the timeslice
  637. //if (???WinNT???) Sleep(0);
  638.  
  639. return bMore;
  640. }
  641.  
  642. //===========================
  643. // Globals
  644.  
  645. #ifdef LOGFILE
  646. FILE *g_pfLog;
  647. #endif //logfile
  648.  
  649. char g_szBuffer[256];
  650.  
  651. CXonixApp theApp;
  652.