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

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