GAMEOA.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:32k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //---------------------------------------------------------------------------
  2. // GameOA.cpp
  3. //---------------------------------------------------------------------------
  4. // Sample spr program, OLE Automation implementation
  5. //---------------------------------------------------------------------------
  6. // (C) Copyright 1992-1997 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. #include "Main.h"
  14. #pragma hdrstop
  15. #include "Game.h"
  16. #include "App.h"
  17. #include "Spr.h"
  18. #include "Score.h"
  19. #include "DispIDs.h"
  20. #include <math.h>
  21. //---------------------------------------------------------------------------
  22. // DEBUG info
  23. //---------------------------------------------------------------------------
  24. SZTHISFILE
  25. //---------------------------------------------------------------------------
  26. // Various Globals
  27. //---------------------------------------------------------------------------
  28. extern CGame *g_pgame;
  29. ITypeInfo *g_ptinfoClsGameOA = NULL;
  30. ITypeInfo *g_ptinfoIntGameOA = NULL;
  31. //***************************************************************************
  32. // Constructor / Destructor
  33. //***************************************************************************
  34. //---------------------------------------------------------------------------
  35. //
  36. //---------------------------------------------------------------------------
  37. CGameOA::CGameOA
  38. (
  39.   CGame *pgame
  40. )
  41. {
  42.   m_pgame           = pgame;
  43.   m_pdispBaseObject = NULL;
  44. }
  45. //***************************************************************************
  46. // Fire IGameEvents Events
  47. //***************************************************************************
  48. //---------------------------------------------------------------------------
  49. //
  50. //---------------------------------------------------------------------------
  51. void CGameOA::FireNewGame
  52. (
  53.   void
  54. )
  55. {
  56.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  57.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  58.     if (*ppdisp)
  59.       InvokeEvent(*ppdisp, DISPID_GameEvents_NewGame, NULL, 0);
  60. }
  61. //---------------------------------------------------------------------------
  62. //
  63. //---------------------------------------------------------------------------
  64. void CGameOA::FireNewLevel
  65. (
  66.   void
  67. )
  68. {
  69.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  70.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  71.     if (*ppdisp)
  72.       InvokeEvent(*ppdisp, DISPID_GameEvents_NewLevel, NULL, 0);
  73. }
  74. //---------------------------------------------------------------------------
  75. //
  76. //---------------------------------------------------------------------------
  77. void CGameOA::FireNewShip
  78. (
  79.   void
  80. )
  81. {
  82.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  83.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  84.     if (*ppdisp)
  85.       InvokeEvent(*ppdisp, DISPID_GameEvents_NewShip, NULL, 0);
  86. }
  87. //---------------------------------------------------------------------------
  88. //
  89. //---------------------------------------------------------------------------
  90. void CGameOA::FireCollide
  91. (
  92.   CSprite *psprLowId,
  93.   CSprite *psprHighId,
  94.   int      maskCollide
  95. )
  96. {
  97.   IDispatch **ppdisp = g_pgame->m_pgameoa->m_cp.m_rgpdisp;
  98.   VARIANTARG  var[3];
  99.   VariantInit(&var[2]);
  100.   var[2].vt = VT_DISPATCH;
  101.   var[2].pdispVal = psprLowId->GetDispatch();
  102.   psprLowId->AddRef();
  103.   VariantInit(&var[1]);
  104.   var[1].vt = VT_DISPATCH;
  105.   var[1].pdispVal = psprHighId->GetDispatch();
  106.   psprHighId->AddRef();
  107.   VariantInit(&var[0]);
  108.   var[0].vt = VT_I4;
  109.   var[0].lVal = maskCollide;
  110.   for (; ppdisp < &g_pgame->m_pgameoa->m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  111.     if (*ppdisp)
  112.       InvokeEvent(*ppdisp, DISPID_GameEvents_Collide, var, 3);
  113.   psprLowId->Release();     // For var[2].pdispVal
  114.   psprHighId->Release();    // For var[1].pdispVal
  115. }
  116. //---------------------------------------------------------------------------
  117. //
  118. //---------------------------------------------------------------------------
  119. void CGameOA::FireTick
  120. (
  121.   void
  122. )
  123. {
  124.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  125.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  126.     if (*ppdisp)
  127.       InvokeEvent(*ppdisp, DISPID_GameEvents_Tick, NULL, 0);
  128. }
  129. //---------------------------------------------------------------------------
  130. //
  131. //---------------------------------------------------------------------------
  132. void CGameOA::FireKeyDown
  133. (
  134.   int vk
  135. )
  136. {
  137.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  138.   VARIANTARG  var[2];
  139.   VariantInit(&var[0]);
  140.   var[0].vt   = VT_I4;
  141.   var[0].lVal = vk;
  142.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  143.     if (*ppdisp)
  144.       InvokeEvent(*ppdisp, DISPID_GameEvents_KeyDown, var, 1);
  145. }
  146. //---------------------------------------------------------------------------
  147. //
  148. //---------------------------------------------------------------------------
  149. void CGameOA::FireKeyPress
  150. (
  151.   int ascii
  152. )
  153. {
  154.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  155.   VARIANTARG  var[1];
  156.   VariantInit(&var[0]);
  157.   var[0].vt   = VT_I4;
  158.   var[0].lVal = ascii;
  159.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  160.     if (*ppdisp)
  161.       InvokeEvent(*ppdisp, DISPID_GameEvents_KeyPress, var, 1);
  162. }
  163. //---------------------------------------------------------------------------
  164. //
  165. //---------------------------------------------------------------------------
  166. void CGameOA::FireKeyUp
  167. (
  168.   int vk
  169. )
  170. {
  171.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  172.   VARIANTARG  var[2];
  173.   VariantInit(&var[0]);
  174.   var[0].vt   = VT_I4;
  175.   var[0].lVal = vk;
  176.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  177.     if (*ppdisp)
  178.       InvokeEvent(*ppdisp, DISPID_GameEvents_KeyUp, var, 1);
  179. }
  180. //---------------------------------------------------------------------------
  181. //
  182. //---------------------------------------------------------------------------
  183. void CGameOA::FireMouseMove
  184. (
  185.   int  x,
  186.   int  y,
  187.   long mk
  188. )
  189. {
  190.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  191.   VARIANTARG  var[4];
  192.   VariantInit(&var[3]);
  193.   var[3].vt = VT_I4;
  194.   var[3].lVal = (mk & MK_SHIFT   ? 1 : 0) |
  195.                 (mk & MK_CONTROL ? 2 : 0);
  196.   VariantInit(&var[2]);
  197.   var[2].vt = VT_I4;
  198.   var[2].lVal = (mk & MK_LBUTTON ? 1 : 0) |
  199.                 (mk & MK_RBUTTON ? 2 : 0) |
  200.                 (mk & MK_MBUTTON ? 4 : 0);
  201.   VariantInit(&var[1]);
  202.   var[1].vt = VT_I4;
  203.   var[1].lVal = x;
  204.   VariantInit(&var[0]);
  205.   var[0].vt = VT_I4;
  206.   var[0].lVal = y;
  207.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  208.     if (*ppdisp)
  209.       InvokeEvent(*ppdisp, DISPID_GameEvents_MouseMove, var, 4);
  210. }
  211. //---------------------------------------------------------------------------
  212. //
  213. //---------------------------------------------------------------------------
  214. void CGameOA::FireMouseDown
  215. (
  216.   int  x,
  217.   int  y,
  218.   long mk,
  219.   long button
  220. )
  221. {
  222.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  223.   VARIANTARG  var[4];
  224.   VariantInit(&var[3]);
  225.   var[3].vt = VT_I4;
  226.   var[3].lVal = (mk & MK_SHIFT   ? 1 : 0) |
  227.                 (mk & MK_CONTROL ? 2 : 0);
  228.   VariantInit(&var[2]);
  229.   var[2].vt = VT_I4;
  230.   var[2].lVal = (button & MK_LBUTTON ? 1 : 0) |
  231.                 (button & MK_RBUTTON ? 2 : 0) |
  232.                 (button & MK_MBUTTON ? 4 : 0);
  233.   VariantInit(&var[1]);
  234.   var[1].vt = VT_I4;
  235.   var[1].lVal = x;
  236.   VariantInit(&var[0]);
  237.   var[0].vt = VT_I4;
  238.   var[0].lVal = y;
  239.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  240.     if (*ppdisp)
  241.       InvokeEvent(*ppdisp, DISPID_GameEvents_MouseDown, var, 4);
  242. }
  243. //---------------------------------------------------------------------------
  244. //
  245. //---------------------------------------------------------------------------
  246. void CGameOA::FireMouseUp
  247. (
  248.   int  x,
  249.   int  y,
  250.   long mk,
  251.   long button
  252. )
  253. {
  254.   IDispatch **ppdisp = m_cp.m_rgpdisp;
  255.   VARIANTARG  var[4];
  256.   VariantInit(&var[3]);
  257.   var[3].vt = VT_I4;
  258.   var[3].lVal = (mk & MK_SHIFT   ? 1 : 0) |
  259.                 (mk & MK_CONTROL ? 2 : 0);
  260.   VariantInit(&var[2]);
  261.   var[2].vt = VT_I4;
  262.   var[2].lVal = (button & MK_LBUTTON ? 1 : 0) |
  263.                 (button & MK_RBUTTON ? 2 : 0) |
  264.                 (button & MK_MBUTTON ? 4 : 0);
  265.   VariantInit(&var[1]);
  266.   var[1].vt = VT_I4;
  267.   var[1].lVal = x;
  268.   VariantInit(&var[0]);
  269.   var[0].vt = VT_I4;
  270.   var[0].lVal = y;
  271.   for (; ppdisp < &m_cp.m_rgpdisp[GAME_cADVISE]; ppdisp++)
  272.     if (*ppdisp)
  273.       InvokeEvent(*ppdisp, DISPID_GameEvents_MouseUp, var, 4);
  274. }
  275. //***************************************************************************
  276. // IGame Interface
  277. //***************************************************************************
  278. //---------------------------------------------------------------------------
  279. // 
  280. //---------------------------------------------------------------------------
  281. STDMETHODIMP CGameOA::get_Caption
  282. (
  283.   BSTR* pRet
  284. )
  285. {
  286.   if (!pRet)
  287.     return E_INVALIDARG;
  288.   UINT cch = GetWindowTextLength(m_pgame->m_hwndDlg);
  289.   char *pszT = new char[cch+1];
  290.   if (!pszT)
  291.     return E_OUTOFMEMORY;
  292.   *pRet = SysAllocStringLen(NULL, cch);
  293.   if (!*pRet)
  294.     {
  295.     delete [] pszT;
  296.     return E_OUTOFMEMORY;
  297.     }
  298.   GetWindowText(m_pgame->m_hwndDlg, pszT, cch+1);
  299.   MultiByteToWideChar(CP_ACP, 0, pszT, -1, *pRet, cch+1);
  300.   delete [] pszT;
  301.   return S_OK;
  302. }
  303. //---------------------------------------------------------------------------
  304. // 
  305. //---------------------------------------------------------------------------
  306. STDMETHODIMP CGameOA::put_Caption
  307. (
  308.   BSTR bstr
  309. )
  310. {
  311.   WCHAR *pwsz = bstr ? bstr : L"";
  312.   MAKE_ANSIPTR_FROMWIDE(pszT, pwsz);
  313.   SetWindowText(m_pgame->m_hwndDlg, pszT);
  314.   return S_OK;
  315. }
  316. //---------------------------------------------------------------------------
  317. // 
  318. //---------------------------------------------------------------------------
  319. STDMETHODIMP CGameOA::get_StatusText
  320. (
  321.   BSTR* pRet
  322. )
  323. {
  324.   if (!pRet)
  325.     return E_INVALIDARG;
  326.   UINT cch = GetWindowTextLength(m_pgame->m_hwndStat);
  327.   char *pszT = new char[cch+1];
  328.   if (!pszT)
  329.     return E_OUTOFMEMORY;
  330.   *pRet = SysAllocStringLen(NULL, cch);
  331.   if (!*pRet)
  332.     {
  333.     delete [] pszT;
  334.     return E_OUTOFMEMORY;
  335.     }
  336.   GetWindowText(m_pgame->m_hwndStat, pszT, cch+1);
  337.   MultiByteToWideChar(CP_ACP, 0, pszT, -1, *pRet, cch+1);
  338.   delete [] pszT;
  339.   return S_OK;
  340. }
  341. //---------------------------------------------------------------------------
  342. // 
  343. //---------------------------------------------------------------------------
  344. STDMETHODIMP CGameOA::put_StatusText
  345. (
  346.   BSTR bstr
  347. )
  348. {
  349.   WCHAR *pwsz = bstr ? bstr : L"";
  350.   MAKE_ANSIPTR_FROMWIDE(pszT, pwsz);
  351.   m_pgame->m_pscore->SetStatusText(pszT);
  352.   return S_OK;
  353. }
  354. //---------------------------------------------------------------------------
  355. // 
  356. //---------------------------------------------------------------------------
  357. STDMETHODIMP CGameOA::get_Application
  358. (
  359.   ISpruuidsApp** lppaReturn
  360. )
  361. {
  362.   return g_papp->QueryInterface(IID_ISpruuidsApp, (void **)lppaReturn);
  363. }
  364. //---------------------------------------------------------------------------
  365. // 
  366. //---------------------------------------------------------------------------
  367. STDMETHODIMP CGameOA::get_Parent
  368. (
  369.   ISpruuidsApp** lppaReturn
  370. )
  371. {
  372.   return g_papp->QueryInterface(IID_ISpruuidsApp, (void **)lppaReturn);
  373. }
  374. //---------------------------------------------------------------------------
  375. // 
  376. //---------------------------------------------------------------------------
  377. STDMETHODIMP CGameOA::StartGame
  378. (
  379.   void 
  380. )
  381. {
  382.   m_pgame->NewGame();
  383.   return S_OK;
  384. }
  385. //---------------------------------------------------------------------------
  386. // 
  387. //---------------------------------------------------------------------------
  388. STDMETHODIMP CGameOA::EndGame
  389. (
  390.   void 
  391. )
  392. {
  393.   m_pgame->GameOver();
  394.   return S_OK;
  395. }
  396. //---------------------------------------------------------------------------
  397. // 
  398. //---------------------------------------------------------------------------
  399. STDMETHODIMP CGameOA::RemoveAllSprites
  400. (
  401.   void 
  402. )
  403. {
  404.   m_pgame->m_pdisp->DestroyAll();
  405.   return S_OK;
  406. }
  407. //---------------------------------------------------------------------------
  408. // 
  409. //---------------------------------------------------------------------------
  410. STDMETHODIMP CGameOA::NextLevel
  411. (
  412.   void 
  413. )
  414. {
  415.   m_pgame->NewLevel();
  416.   return S_OK;
  417. }
  418. //---------------------------------------------------------------------------
  419. // 
  420. //---------------------------------------------------------------------------
  421. STDMETHODIMP CGameOA::Refresh
  422. (
  423.   void 
  424. )
  425. {
  426.   m_pgame->m_pdisp->Refresh();
  427.   return S_OK;
  428. }
  429. //---------------------------------------------------------------------------
  430. // 
  431. //---------------------------------------------------------------------------
  432. STDMETHODIMP CGameOA::AddScore
  433. (
  434.   int val
  435. )
  436. {
  437.   m_pgame->m_pscore->Add(val);
  438.   return S_OK;
  439. }
  440. //---------------------------------------------------------------------------
  441. //
  442. //---------------------------------------------------------------------------
  443. STDMETHODIMP CGameOA::StdBorderBounce
  444. (
  445.   ISprite *psprite,
  446.   int      brd
  447. )
  448. {
  449.   CSprite *pspr = SPRITEOFI(psprite);
  450.   if ((brd & SPR_brdTOP) && pspr->m_vyFull < 0)
  451.     {
  452.     pspr->m_vyFull = -pspr->m_vyFull;
  453.     pspr->IgnoreMove();
  454.     }
  455.   if ((brd & SPR_brdLEFT) && pspr->m_vxFull < 0)
  456.     {
  457.     pspr->m_vxFull = -pspr->m_vxFull;
  458.     pspr->IgnoreMove();
  459.     }
  460.   if ((brd & SPR_brdBOTTOM) && pspr->m_vyFull > 0)
  461.     {
  462.     pspr->m_vyFull = -pspr->m_vyFull;
  463.     pspr->IgnoreMove();
  464.     }
  465.   if ((brd & SPR_brdRIGHT) && pspr->m_vxFull > 0)
  466.     {
  467.     pspr->m_vxFull = -pspr->m_vxFull;
  468.     pspr->IgnoreMove();
  469.     }
  470.   return S_OK;
  471. }
  472. //---------------------------------------------------------------------------
  473. //
  474. //---------------------------------------------------------------------------
  475. STDMETHODIMP CGameOA::StdBorderWrap
  476. (
  477.   ISprite *psprite,
  478.   int      brd
  479. )
  480. {
  481.   CSprite *pspr = SPRITEOFI(psprite);
  482.   if ((brd & SPR_brdTOP) && pspr->m_vyFull < 0)
  483.     pspr->m_y = pspr->m_pdisp->m_cy;
  484.   if ((brd & SPR_brdLEFT) && pspr->m_vxFull < 0)
  485.     pspr->m_x = pspr->m_pdisp->m_cx;
  486.   if ((brd & SPR_brdBOTTOM) && pspr->m_vyFull > 0)
  487.     pspr->m_y = -pspr->m_pimg->cy;
  488.   if ((brd & SPR_brdRIGHT) && pspr->m_vxFull > 0)
  489.     pspr->m_x = -pspr->m_pimg->cx;
  490.   return S_OK;
  491. }
  492. //---------------------------------------------------------------------------
  493. // Generate a random number between 0 and n.
  494. //---------------------------------------------------------------------------
  495. int MyRand
  496. (
  497.   int n
  498. )
  499. {
  500.   int t, u;
  501.   static nLast=0, tLast=0;
  502.   if (n <= 1)
  503.     return 0;
  504.   n &= RAND_MAX;
  505.   if (n == nLast)
  506.     t = tLast;
  507.   else
  508.     {
  509.     nLast = n;
  510.     for (t=2; t<n; t<<=1)
  511.       ;
  512.     t--;
  513.     tLast = t;
  514.     }
  515.   do
  516.     {
  517.     u = t & rand();
  518.     } while (u >= n);
  519.   return u;
  520. }
  521. //---------------------------------------------------------------------------
  522. // Init to random position which doesn't cause a collision event.
  523. //---------------------------------------------------------------------------
  524. STDMETHODIMP CGameOA::StdInitRand
  525. (
  526.   ISprite *psprite,
  527.   VARIANT  varUser
  528. )
  529. {
  530.   CSprite *pspr = SPRITEOFI(psprite);
  531.   CSprite *psprT;
  532.   LONG     x, y, dx, dy;
  533.   int      cx, cy;
  534.   int      lUser = (varUser.vt == VT_I4) ? varUser.lVal : 0;
  535.   LONG     dist = 8128;
  536.   cx = pspr->m_pimg->cx;
  537.   cy = pspr->m_pimg->cy;
  538.   do
  539.     {
  540. Loop:
  541.     x = MyRand(pspr->m_pdisp->m_cx - cx);
  542.     y = MyRand(pspr->m_pdisp->m_cy - cy);
  543.     for (psprT=pspr->m_pdisp->m_psprFirst; psprT; psprT=psprT->m_psprNext)
  544.       {
  545.       if (!(psprT->m_psc->m_maskCollide & pspr->m_psc->m_maskCollide) && // if potential collision doesn't matter
  546.           x <= psprT->m_x+psprT->m_pimg->cx && x+cx >= psprT->m_x &&  // and we collide
  547.           y <= psprT->m_y+psprT->m_pimg->cy && y+cy >= psprT->m_y)
  548. goto Loop;                              // then try another location
  549.       }
  550.     dx = (x - (pspr->m_pdisp->m_cx>>1));
  551.     dy = (y - (pspr->m_pdisp->m_cy>>1));
  552.     } while (dx*dx + dy*dy < dist);
  553.   pspr->m_x = (int)x;
  554.   pspr->m_y = (int)y;
  555.   return S_OK;
  556. }
  557. //---------------------------------------------------------------------------
  558. // Init to random position along edge of disp.
  559. //---------------------------------------------------------------------------
  560. STDMETHODIMP CGameOA::StdInitEdge
  561. (
  562.   ISprite *psprite,
  563.   VARIANT  varUser
  564. )
  565. {
  566.   CSprite *pspr = SPRITEOFI(psprite);
  567.   if (rand() & 1)
  568.     {
  569.     pspr->m_x = MyRand(pspr->m_pdisp->m_cx - pspr->m_pimg->cx);
  570.     if (rand() & 1)
  571.       pspr->m_y = pspr->m_pdisp->m_cy - pspr->m_pimg->cy;
  572.     }
  573.   else
  574.     {
  575.     pspr->m_y = MyRand(pspr->m_pdisp->m_cy - pspr->m_pimg->cy);
  576.     if (rand() & 1)
  577.       pspr->m_x = pspr->m_pdisp->m_cx - pspr->m_pimg->cx;
  578.     }
  579.   return S_OK;
  580. }
  581. //---------------------------------------------------------------------------
  582. // 
  583. //---------------------------------------------------------------------------
  584. STDMETHODIMP CGameOA::get_Paused
  585. (
  586.   VARIANT_BOOL* pRet
  587. )
  588. {
  589.   *pRet = m_pgame->m_fPaused;
  590.   return S_OK;
  591. }
  592. //---------------------------------------------------------------------------
  593. // 
  594. //---------------------------------------------------------------------------
  595. STDMETHODIMP CGameOA::put_Paused
  596. (
  597.   VARIANT_BOOL val
  598. )
  599. {
  600.   m_pgame->Pause(!!val);
  601.   return S_OK;
  602. }
  603. //---------------------------------------------------------------------------
  604. // 
  605. //---------------------------------------------------------------------------
  606. STDMETHODIMP CGameOA::get_Width
  607. (
  608.   int* pRet
  609. )
  610. {
  611.   *pRet = m_pgame->m_pdisp->m_cx;
  612.   return S_OK;
  613. }
  614. //---------------------------------------------------------------------------
  615. // 
  616. //---------------------------------------------------------------------------
  617. STDMETHODIMP CGameOA::put_Width
  618. (
  619.   int val
  620. )
  621. {
  622.   if (val < 20 || val > 1024)
  623.     return E_FAIL;
  624.   m_pgame->m_pscore->Size(val, m_pgame->m_pdisp->m_cy);
  625.   return S_OK;
  626. }
  627. //---------------------------------------------------------------------------
  628. // 
  629. //---------------------------------------------------------------------------
  630. STDMETHODIMP CGameOA::get_Height
  631. (
  632.   int* pRet
  633. )
  634. {
  635.   *pRet = m_pgame->m_pdisp->m_cy;
  636.   return S_OK;
  637. }
  638. //---------------------------------------------------------------------------
  639. // 
  640. //---------------------------------------------------------------------------
  641. STDMETHODIMP CGameOA::put_Height
  642. (
  643.   int val
  644. )
  645. {
  646.   if (val < 20 || val > 1024)
  647.     return E_FAIL;
  648.   m_pgame->m_pscore->Size(m_pgame->m_pdisp->m_cx, val);
  649.   return S_OK;
  650. }
  651. //---------------------------------------------------------------------------
  652. // 
  653. //---------------------------------------------------------------------------
  654. STDMETHODIMP CGameOA::get_BackColor
  655. (
  656.   long* pRet
  657. )
  658. {
  659.   *pRet = m_pgame->m_pdisp->m_colorBack;
  660.   return S_OK;
  661. }
  662. //---------------------------------------------------------------------------
  663. // 
  664. //---------------------------------------------------------------------------
  665. STDMETHODIMP CGameOA::put_BackColor
  666. (
  667.   long val
  668. )
  669. {
  670.   if (val & 0xff000000)
  671.     return E_FAIL;
  672.   m_pgame->m_pdisp->SetBackColor(val);
  673.   return S_OK;
  674. }
  675. //---------------------------------------------------------------------------
  676. // 
  677. //---------------------------------------------------------------------------
  678. STDMETHODIMP CGameOA::get_Score
  679. (
  680.   int* pRet
  681. )
  682. {
  683.   *pRet = m_pgame->m_pscore->GetScore();
  684.   return S_OK;
  685. }
  686. //---------------------------------------------------------------------------
  687. // 
  688. //---------------------------------------------------------------------------
  689. STDMETHODIMP CGameOA::put_Score
  690. (
  691.   int val
  692. )
  693. {
  694.   m_pgame->m_pscore->SetScore(val);
  695.   return S_OK;
  696. }
  697. //---------------------------------------------------------------------------
  698. // 
  699. //---------------------------------------------------------------------------
  700. STDMETHODIMP CGameOA::get_Level
  701. (
  702.   int* pRet
  703. )
  704. {
  705.   *pRet = m_pgame->m_pscore->GetLevel();
  706.   return S_OK;
  707. }
  708. //---------------------------------------------------------------------------
  709. // 
  710. //---------------------------------------------------------------------------
  711. STDMETHODIMP CGameOA::put_Level
  712. (
  713.   int val
  714. )
  715. {
  716.   m_pgame->m_pscore->SetLevel(val);
  717.   return S_OK;
  718. }
  719. //---------------------------------------------------------------------------
  720. // 
  721. //---------------------------------------------------------------------------
  722. STDMETHODIMP CGameOA::get_ShipCount
  723. (
  724.   int* pRet
  725. )
  726. {
  727.   *pRet = m_pgame->m_pscore->GetCShip();
  728.   return S_OK;
  729. }
  730. //---------------------------------------------------------------------------
  731. // 
  732. //---------------------------------------------------------------------------
  733. STDMETHODIMP CGameOA::put_ShipCount
  734. (
  735.   int val
  736. )
  737. {
  738.   m_pgame->m_pscore->SetCShip(val);
  739.   return S_OK;
  740. }
  741. //---------------------------------------------------------------------------
  742. // 
  743. //---------------------------------------------------------------------------
  744. STDMETHODIMP CGameOA::get_ScoreFirst1Up
  745. (
  746.   int* pRet
  747. )
  748. {
  749.   *pRet = m_pgame->m_pscore->m_scoreFirst1Up;
  750.   return S_OK;
  751. }
  752. //---------------------------------------------------------------------------
  753. // 
  754. //---------------------------------------------------------------------------
  755. STDMETHODIMP CGameOA::put_ScoreFirst1Up
  756. (
  757.   int val
  758. )
  759. {
  760.   if (val < 0)
  761.     return E_FAIL;
  762.   m_pgame->m_pscore->m_scoreFirst1Up = val;
  763.   if (m_pgame->m_pscore->m_scoreSecond1Up < val)
  764.     m_pgame->m_pscore->m_scoreSecond1Up = val;
  765.   if (m_pgame->m_pscore->GetScore() < m_pgame->m_pscore->m_scoreFirst1Up)
  766.     m_pgame->m_pscore->m_scoreNext1Up = val;
  767.   return S_OK;
  768. }
  769. //---------------------------------------------------------------------------
  770. // 
  771. //---------------------------------------------------------------------------
  772. STDMETHODIMP CGameOA::get_ScoreSecond1Up
  773. (
  774.   int* pRet
  775. )
  776. {
  777.   *pRet = m_pgame->m_pscore->m_scoreSecond1Up;
  778.   return S_OK;
  779. }
  780. //---------------------------------------------------------------------------
  781. // 
  782. //---------------------------------------------------------------------------
  783. STDMETHODIMP CGameOA::put_ScoreSecond1Up
  784. (
  785.   int val
  786. )
  787. {
  788.   if (val < 0)
  789.     return E_FAIL;
  790.   m_pgame->m_pscore->m_scoreSecond1Up = val;
  791.   if (val < m_pgame->m_pscore->m_scoreFirst1Up)
  792.     m_pgame->m_pscore->m_scoreFirst1Up = val;
  793.   if (m_pgame->m_pscore->GetScore() > m_pgame->m_pscore->m_scoreFirst1Up  &&
  794.       m_pgame->m_pscore->GetScore() < m_pgame->m_pscore->m_scoreSecond1Up)
  795.     m_pgame->m_pscore->m_scoreNext1Up = val;
  796.   return S_OK;
  797. }
  798. //---------------------------------------------------------------------------
  799. // 
  800. //---------------------------------------------------------------------------
  801. STDMETHODIMP CGameOA::get_DScoreNext1Up
  802. (
  803.   int* pRet
  804. )
  805. {
  806.   *pRet = m_pgame->m_pscore->m_dscoreNext1Up;
  807.   return S_OK;
  808. }
  809. //---------------------------------------------------------------------------
  810. // 
  811. //---------------------------------------------------------------------------
  812. STDMETHODIMP CGameOA::put_DScoreNext1Up
  813. (
  814.   int val
  815. )
  816. {
  817.   if (val < 0)
  818.     return E_FAIL;
  819.   m_pgame->m_pscore->m_dscoreNext1Up = val;
  820.   if (m_pgame->m_pscore->GetScore() > m_pgame->m_pscore->m_scoreFirst1Up && m_pgame->m_pscore->GetScore() > 0)
  821.     {
  822.     m_pgame->m_pscore->m_scoreNext1Up = m_pgame->m_pscore->m_scoreFirst1Up;
  823.     while (m_pgame->m_pscore->m_scoreNext1Up < m_pgame->m_pscore->GetScore())
  824.       m_pgame->m_pscore->m_scoreNext1Up += m_pgame->m_pscore->m_dscoreNext1Up;
  825.     }
  826.   return S_OK;
  827. }
  828. //---------------------------------------------------------------------------
  829. // 
  830. //---------------------------------------------------------------------------
  831. STDMETHODIMP CGameOA::get_ShipsStart
  832. (
  833.   int* pRet
  834. )
  835. {
  836.   *pRet = m_pgame->m_pscore->m_cshipStart;
  837.   return S_OK;
  838. }
  839. //---------------------------------------------------------------------------
  840. // 
  841. //---------------------------------------------------------------------------
  842. STDMETHODIMP CGameOA::put_ShipsStart
  843. (
  844.   int val
  845. )
  846. {
  847.   if (val < 0)
  848.     return E_FAIL;
  849.   m_pgame->m_pscore->m_cshipStart = val;
  850.   return S_OK;
  851. }
  852. //---------------------------------------------------------------------------
  853. // 
  854. //---------------------------------------------------------------------------
  855. STDMETHODIMP CGameOA::get_Tag
  856. (
  857.   VARIANT* pRet
  858. )
  859. {
  860.   if (!pRet)
  861.     return E_INVALIDARG;
  862.   VariantInit(pRet);
  863.   return VariantCopy(pRet, &m_pgame->m_varTag);
  864. }
  865. //---------------------------------------------------------------------------
  866. // 
  867. //---------------------------------------------------------------------------
  868. STDMETHODIMP CGameOA::put_Tag
  869. (
  870.   VARIANT val
  871. )
  872. {
  873.   return VariantCopy(&m_pgame->m_varTag, &val);
  874. }
  875. //***************************************************************************
  876. // IDispatch Interface
  877. //***************************************************************************
  878. //---------------------------------------------------------------------------
  879. // Method needed by COleAuto, so it can implement IDispatch for us.
  880. //---------------------------------------------------------------------------
  881. HRESULT CGameOA::GetTypeLibInfo
  882. (
  883.   HINSTANCE    *phinstOut,
  884.   const GUID  **pplibidOut, 
  885.   SHORT        *pwMajLib, 
  886.   SHORT        *pwMinLib,
  887.   const CLSID **ppclsidOut, 
  888.   const IID   **ppiidOut, 
  889.   ITypeLib   ***ppptlOut
  890. )
  891. {
  892.   *phinstOut  = g_hinst;
  893.   *pplibidOut = &LIBID_SPRUUIDS;
  894.   *pwMajLib   = 1;
  895.   *pwMinLib   = 0;
  896.   *ppclsidOut = &CLSID_Game;
  897.   *ppiidOut   = &IID_IGame;
  898.   *ppptlOut   = &g_ptlMain;
  899.   return S_OK;
  900. }
  901. //***************************************************************************
  902. // IProvideClassInfo Interfaces
  903. //***************************************************************************
  904. //---------------------------------------------------------------------------
  905. // 
  906. //---------------------------------------------------------------------------
  907. STDMETHODIMP CGameOA::GetClassInfo
  908. (
  909.   ITypeInfo** pptinfoOut
  910. )
  911. {
  912.   HRESULT hr = ((COleAuto *)this)->CheckTypeInfo(0, 0x0409);
  913.   if (hr)
  914.     return hr;
  915.   *pptinfoOut = g_ptinfoClsGameOA;
  916.   (*pptinfoOut)->AddRef();
  917.   return S_OK;
  918. }
  919. //***************************************************************************
  920. // IConnectionPointContainer Interface
  921. //***************************************************************************
  922. //---------------------------------------------------------------------------
  923. // 
  924. //---------------------------------------------------------------------------
  925. STDMETHODIMP CGameOA::EnumConnectionPoints
  926. (
  927.   LPENUMCONNECTIONPOINTS* ppEnum
  928. )
  929. {
  930.   return E_NOTIMPL;   // UNDONE: Implement this method
  931. }
  932. //---------------------------------------------------------------------------
  933. // 
  934. //---------------------------------------------------------------------------
  935. STDMETHODIMP CGameOA::FindConnectionPoint
  936. (
  937.   REFIID             iid,
  938.   LPCONNECTIONPOINT* ppCpOut
  939. )
  940. {
  941.   if (!ppCpOut)
  942.     return E_INVALIDARG;
  943.   if (iid == DIID_IGameEvents || iid == IID_IDispatch)
  944.     {
  945.     *ppCpOut = &m_cp;
  946.     (*ppCpOut)->AddRef();
  947.     return S_OK;
  948.     }
  949.     
  950.   return E_NOINTERFACE;
  951. }
  952. //***************************************************************************
  953. // Embedded IConnectionPoint Class
  954. //***************************************************************************
  955. //---------------------------------------------------------------------------
  956. // 
  957. //---------------------------------------------------------------------------
  958. CGameOA::XCP::XCP
  959. (
  960.   void
  961. )
  962. {
  963.   m_cref = 1;
  964.   for (int i=0; i<GAME_cADVISE; i++)
  965.     m_rgpdisp[i] = NULL;
  966. }
  967. //---------------------------------------------------------------------------
  968. // 
  969. //---------------------------------------------------------------------------
  970. void CGameOA::XCP::Close
  971. (
  972.   void
  973. )
  974. {
  975.   for (int i=0; i<SC_cADVISE; i++)
  976.     if (m_rgpdisp[i])
  977.       {
  978.       m_rgpdisp[i]->Release();
  979.       m_rgpdisp[i] = NULL;
  980.       }
  981. }
  982. //---------------------------------------------------------------------------
  983. // 
  984. //---------------------------------------------------------------------------
  985. STDMETHODIMP CGameOA::XCP::QueryInterface
  986. (
  987.   REFIID  iid,
  988.   LPVOID* ppvObjOut
  989. )
  990. {
  991.   if (!ppvObjOut)
  992.     return E_INVALIDARG;
  993.   *ppvObjOut = NULL;
  994.   if (iid == IID_IUnknown)
  995.     *ppvObjOut = this->GetUnknown();
  996.   else if (iid == IID_IConnectionPoint)
  997.     *ppvObjOut = (IConnectionPoint *)this;
  998.   if (*ppvObjOut)
  999.     {
  1000.     this->AddRef();
  1001.     return S_OK;
  1002.     }
  1003.   return E_NOINTERFACE;
  1004. }
  1005. //---------------------------------------------------------------------------
  1006. // 
  1007. //---------------------------------------------------------------------------
  1008. STDMETHODIMP_(ULONG) CGameOA::XCP::AddRef
  1009. (
  1010.   void 
  1011. )
  1012. {
  1013.   return ++m_cref;
  1014. }
  1015. //---------------------------------------------------------------------------
  1016. // 
  1017. //---------------------------------------------------------------------------
  1018. STDMETHODIMP_(ULONG) CGameOA::XCP::Release
  1019. (
  1020.   void 
  1021. )
  1022. {
  1023.   CGame *pgame = this->PGAMEOA()->m_pgame;
  1024.   ASSERT(m_cref, "bad m_cref");
  1025.   m_cref--;
  1026.   if (!m_cref && !pgame->m_cref)
  1027.     {
  1028.     delete pgame;
  1029.     return 0;
  1030.     }
  1031.   return m_cref;
  1032. }
  1033. //***************************************************************************
  1034. // IConnectionPoint Interface
  1035. //***************************************************************************
  1036. //---------------------------------------------------------------------------
  1037. // 
  1038. //---------------------------------------------------------------------------
  1039. STDMETHODIMP CGameOA::XCP::GetConnectionInterface
  1040. (
  1041.   IID* piid
  1042. )
  1043. {
  1044.   if (!piid)
  1045.     return E_INVALIDARG;
  1046.   memcpy(piid, &DIID_ISpriteClassEvents, sizeof(IID));
  1047.   return S_OK;
  1048. }
  1049. //---------------------------------------------------------------------------
  1050. // 
  1051. //---------------------------------------------------------------------------
  1052. STDMETHODIMP CGameOA::XCP::GetConnectionPointContainer
  1053. (
  1054.   IConnectionPointContainer** ppCPC
  1055. )
  1056. {
  1057.   if (!ppCPC)
  1058.     return E_INVALIDARG;
  1059.   *ppCPC = this->PGAMEOA();
  1060.   (*ppCPC)->AddRef();
  1061.   return S_OK;
  1062. }
  1063. //---------------------------------------------------------------------------
  1064. // 
  1065. //---------------------------------------------------------------------------
  1066. STDMETHODIMP CGameOA::XCP::Advise
  1067. (
  1068.   IUnknown* punkSink,
  1069.   DWORD*    pdwCookie
  1070. )
  1071. {
  1072.   IDispatch  *psce = NULL;
  1073.   IDispatch **ppdisp;
  1074.   HRESULT     hr;
  1075.   if (!punkSink || !pdwCookie)
  1076.     return E_INVALIDARG;
  1077.   *pdwCookie = 0;
  1078.   // Look for empty slot
  1079.   for (ppdisp=m_rgpdisp; *ppdisp && ppdisp<&m_rgpdisp[GAME_cADVISE]; ppdisp++)
  1080.     ;
  1081.   // Did we find one?
  1082.   if (ppdisp >= &m_rgpdisp[GAME_cADVISE])
  1083.     return E_FAIL;          // UNDONE: Error?
  1084.   // Now see if sink supports correct interface
  1085.   hr = punkSink->QueryInterface(DIID_ISpriteClassEvents, (void **)&psce);
  1086.   if (hr == E_NOINTERFACE)
  1087.     {
  1088.     hr = punkSink->QueryInterface(IID_IDispatch, (void **)&psce);
  1089.     if (hr)
  1090.       return hr;
  1091.     }
  1092.   ASSERT(psce, "QI but no ptr");
  1093.   // Finish advise by stashing punkSink QI'd to our interface
  1094.   *ppdisp = psce;       // AddRef'd from QI
  1095.   *pdwCookie = (ppdisp - m_rgpdisp) + 1;
  1096.   return S_OK;
  1097. }
  1098. //---------------------------------------------------------------------------
  1099. // 
  1100. //---------------------------------------------------------------------------
  1101. STDMETHODIMP CGameOA::XCP::Unadvise
  1102. (
  1103.   DWORD dwCookie
  1104. )
  1105. {
  1106.   if (!dwCookie || dwCookie > GAME_cADVISE)
  1107.     return E_INVALIDARG;
  1108.   m_rgpdisp[dwCookie-1]->Release();
  1109.   m_rgpdisp[dwCookie-1] = NULL;
  1110.   return S_OK;
  1111. }
  1112. //---------------------------------------------------------------------------
  1113. // 
  1114. //---------------------------------------------------------------------------
  1115. STDMETHODIMP CGameOA::XCP::EnumConnections
  1116. (
  1117.   LPENUMCONNECTIONS* ppEnum
  1118. )
  1119. {
  1120.   return E_NOTIMPL;   // UNDONE: Implement this method
  1121. }
  1122. //--- EOF -------------------------------------------------------------------