Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
5.1 KiB

  1. /*************************************************
  2. * slot.cpp *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. #include "stdafx.h"
  8. #include "cblocks.h"
  9. #include "dib.h"
  10. #include "dibpal.h"
  11. #include "spriteno.h"
  12. #include "sprite.h"
  13. #include "phsprite.h"
  14. #include "myblock.h"
  15. #include "splstno.h"
  16. #include "spritlst.h"
  17. #include "osbview.h"
  18. #include "blockvw.h"
  19. #include "blockdoc.h"
  20. #include "slot.h"
  21. CSlot::CSlot(int nBlockNo)
  22. {
  23. m_nBlockNo = nBlockNo;
  24. m_nCurrentLayer = 0;
  25. m_pRunningBlock = NULL;
  26. m_nIndex = -1;
  27. }
  28. CSlot::~CSlot()
  29. {
  30. RemoveAll();
  31. }
  32. BOOL CSlot::IsOver() const
  33. {
  34. return (GetCount() >= m_nBlockNo);
  35. }
  36. CBlock* CSlot::GetRunningBlock() const
  37. {
  38. return m_pRunningBlock;
  39. }
  40. int CSlot::GetCurrentLayer() const
  41. {
  42. return m_nCurrentLayer;
  43. }
  44. void CSlot::SetCurrentLayer(int nLayer)
  45. {
  46. m_nCurrentLayer = nLayer;
  47. }
  48. void CSlot::ResetCurrentLayer()
  49. {
  50. m_nCurrentLayer = 0;
  51. }
  52. void CSlot::ResetSlot()
  53. {
  54. m_pRunningBlock = NULL;
  55. m_nCurrentLayer = 0;
  56. }
  57. void CSlot::SetIndex(int nNdx)
  58. {
  59. m_nIndex = nNdx;
  60. }
  61. int CSlot::GetIndex() const
  62. {
  63. return m_nIndex;
  64. }
  65. CBlock* CSlot::Hit(WORD wCode,BOOL &bRunning,int& nLayer)
  66. {
  67. CBlock* pBlock = NULL;
  68. bRunning = FALSE;
  69. if (m_pRunningBlock)
  70. {
  71. if (m_pRunningBlock->Hit(wCode))
  72. {
  73. nLayer = m_nCurrentLayer;
  74. pBlock = m_pRunningBlock;
  75. int iVX,iVY;
  76. pBlock->GetVelocity(&iVX,&iVY);
  77. pBlock->SetVelocity(0,iVY * -2);
  78. ResetRunningBlock();
  79. bRunning = TRUE;
  80. return pBlock;
  81. }
  82. }
  83. if (GetCount())
  84. {
  85. pBlock = (CBlock*) GetHead();
  86. if (pBlock->Hit(wCode))
  87. {
  88. nLayer = 1;
  89. RemoveHead();
  90. pBlock->SetVelocity(0,-500);
  91. return pBlock;
  92. }
  93. }
  94. return NULL;
  95. }
  96. void CSlot::ResetRunningBlock()
  97. {
  98. m_pRunningBlock = NULL;
  99. m_nCurrentLayer = 0;
  100. }
  101. void CSlot::StepCurrentLayer()
  102. {
  103. m_nCurrentLayer++;
  104. }
  105. BOOL CSlot::IsIdle() const
  106. {
  107. return m_pRunningBlock == NULL;
  108. }
  109. void CSlot::SetRunningBlock(CBlock* pBlock)
  110. {
  111. m_pRunningBlock = pBlock;
  112. ResetCurrentLayer();
  113. }
  114. int m_nBottom;
  115. CSlotManager::CSlotManager(CBlockDoc* pDoc)
  116. {
  117. ASSERT_VALID(pDoc);
  118. m_pDoc = pDoc;
  119. m_pQueue = (CQueue *) new CQueue(pDoc->GetNumofCols());
  120. for (int i=0; i<pDoc->GetNumofCols(); i++)
  121. {
  122. CSlot* pSlot = new CSlot(pDoc->GetNumofRows());
  123. pSlot->SetIndex(i);
  124. Add(pSlot);
  125. m_pQueue->Add(i);
  126. }
  127. m_pLayer = new int[pDoc->GetNumofRows()];
  128. for (i=0; i<pDoc->GetNumofRows(); i++)
  129. m_pLayer[i] = pDoc->GetRowHeight() * i;
  130. m_nBottom = pDoc->GetRowHeight() * (pDoc->GetNumofRows()-1);
  131. }
  132. CSlotManager::~CSlotManager()
  133. {
  134. for (int i=0; i<GetSize(); i++)
  135. {
  136. CSlot* pObj = (CSlot*) GetAt(i);
  137. delete pObj;
  138. }
  139. RemoveAll();
  140. m_DeadList.RemoveAll();
  141. delete[] m_pLayer;
  142. delete m_pQueue;
  143. }
  144. void CSlotManager::Land()
  145. {
  146. static char szBuf[100];
  147. for (int i=0; i<m_pDoc->GetNumofCols(); i++)
  148. {
  149. CSlot* pSlot = (CSlot *) GetAt(i);
  150. CBlock* pBlock = pSlot->GetRunningBlock() ;
  151. if (pBlock)
  152. {
  153. if (pBlock->GetY() >= m_pLayer[m_pDoc->GetNumofRows()-pSlot->GetCount()-1])
  154. {
  155. pBlock->Stop();
  156. pBlock->SetPosition(pBlock->GetX(),m_pLayer[m_pDoc->GetNumofRows()-pSlot->GetCount()-1]);
  157. pSlot->AddHead(pBlock);
  158. pSlot->SetRunningBlock(NULL);
  159. m_pDoc->SoundGround();
  160. if (pSlot->GetCount() == m_pDoc->GetNumofRows())
  161. {
  162. m_pDoc->GameOver();
  163. }
  164. else
  165. {
  166. m_pQueue->Add(i);
  167. }
  168. }
  169. else
  170. {
  171. if (pBlock->GetY() >= m_pLayer[pSlot->GetCurrentLayer()+1])
  172. pSlot->StepCurrentLayer();
  173. }
  174. }
  175. if (m_DeadList.GetCount() > 0)
  176. {
  177. POSITION pPos = m_DeadList.GetHeadPosition();
  178. for (; pPos; )
  179. {
  180. POSITION pOldPos = pPos;
  181. CBlock* pBlock = (CBlock *) m_DeadList.GetNext(pPos);
  182. if (pBlock)
  183. {
  184. if (pBlock->GetY() <= -m_pDoc->GetRowHeight())
  185. {
  186. m_DeadList.RemoveAt(pOldPos);
  187. m_pDoc->Remove(pBlock);
  188. }
  189. }
  190. }
  191. }
  192. }
  193. }
  194. #define INC(x) {x = ((x+1) > m_pDoc->GetNumofCols()) ? 0 : x+1;}
  195. int CSlotManager::GetIdleSlot()
  196. {
  197. static int nCount=0;
  198. if (m_pQueue->IsEmpty())
  199. return -1;
  200. else
  201. {
  202. int nTmp = m_pQueue->Get();
  203. int nPassed = rand();
  204. switch (m_pDoc->GetExpertise())
  205. {
  206. case LEVEL_EXPERT:
  207. nPassed = nPassed % 2;
  208. break;
  209. case LEVEL_ORDINARY:
  210. nPassed = nPassed % 5;
  211. break;
  212. case LEVEL_BEGINNER:
  213. nPassed = nPassed % 7;
  214. break;
  215. }
  216. if ((nPassed == 0) || (nCount > 15))
  217. {
  218. nCount = 0;
  219. return nTmp;
  220. }
  221. else
  222. {
  223. m_pQueue->Add(nTmp);
  224. nCount++;
  225. return -1;
  226. }
  227. }
  228. }
  229. void CSlotManager::AddRunningBlock(int nSlotNo,CBlock* pBlock)
  230. {
  231. ASSERT((nSlotNo >=0) && (nSlotNo < m_pDoc->GetNumofCols()));
  232. CSlot* pSlot = (CSlot *) GetAt(nSlotNo);
  233. pSlot->SetRunningBlock(pBlock);
  234. }
  235. CBlock* CSlotManager::Hit(WORD wCode,int& nLayer)
  236. {
  237. BOOL bRunning = FALSE;
  238. for (int i=0; i<m_pDoc->GetNumofCols(); i++)
  239. {
  240. CSlot* pSlot = (CSlot*)GetAt(i);
  241. CBlock* pBlock = pSlot->Hit(wCode,bRunning,nLayer);
  242. if (pBlock)
  243. {
  244. if (bRunning)
  245. {
  246. m_pQueue->Add(i);
  247. nLayer = m_pDoc->GetNumofRows() - nLayer;
  248. }
  249. m_DeadList.AddTail(pBlock);
  250. return pBlock;
  251. }
  252. }
  253. return NULL;
  254. }