DXIsoMap.cpp
上传用户:pfmy85
上传日期:2007-01-07
资源大小:22k
文件大小:16k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // DXIsoMap.cpp: implementation of the CDXIsoMap class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "DXIsoMap.h"
  6. #include "DDDevice.h"
  7. #include "DDDIBSurface.h"
  8. #include "PackFile.h"
  9. #include "IsoType.h"
  10. //#include "stdafx.h"
  11. //#include "Isotest.h"
  12. #ifdef _DEBUG
  13. #undef THIS_FILE
  14. static char THIS_FILE[]=__FILE__;
  15. #define new DEBUG_NEW
  16. #endif
  17. const CHAR CDXIsoMap::m_CellFigue[16][32] = 
  18. {
  19. {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
  20. {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2},
  21. {1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2},
  22. {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2},
  23. {1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2},
  24. {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2},
  25. {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2},
  26. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  27. {3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4},
  28. {3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4},
  29. {3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4},
  30. {3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4},
  31. {3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4},
  32. {3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4},
  33. {3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4},
  34. {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4}
  35. };
  36. const int CDXIsoMap::m_nCellWidth = 32;
  37. const int CDXIsoMap::m_nCellHeight = 16;
  38. const int CDXIsoMap::m_nCellWidthShift = 5;
  39. const int CDXIsoMap::m_nCellHeightShift = 4;
  40. const BYTE CDXIsoMap::m_CellIdxFlg = 0x10;
  41. const BYTE CDXIsoMap::m_CellRmrFlg = 0X20;
  42. const BYTE CDXIsoMap::m_CellNpcFlg = 0x40;
  43. const BYTE CDXIsoMap::m_CellLnkFlg = 0x80;
  44. //////////////////////////////////////////////////////////////////////
  45. // Construction/Destruction
  46. //////////////////////////////////////////////////////////////////////
  47. CDXIsoMap::CDXIsoMap()
  48. {
  49. m_bAutoDelete = false;
  50. m_pMapData = NULL;
  51. m_nPosX = 0;
  52. m_nPosY = 0;
  53. m_nPosTX = 0;
  54. m_nPosTY = 0;
  55. m_nOffX = 0;
  56. m_nOffY = 0;
  57. m_pPassValues = NULL;
  58. m_pTiles = NULL;
  59. }
  60. CDXIsoMap::~CDXIsoMap()
  61. {
  62. if (m_pPassValues != NULL)
  63. {
  64. delete  []m_pPassValues;
  65. m_pPassValues = NULL;
  66. }
  67. if (m_pMapData != NULL)
  68. {
  69. delete  []m_pMapData;
  70. m_pMapData = NULL;
  71. }
  72. if (m_bAutoDelete == true)
  73. {
  74. if (m_pTiles != NULL)
  75. {
  76. delete  m_pTiles;
  77. }
  78. }
  79. m_pTiles = NULL;
  80. }
  81. bool CDXIsoMap::Create(CDDSurface* pTiles,
  82. LPCTSTR lpszFileName,
  83. CPackFileManager* pPackFileManager/* = NULL*/)
  84. {
  85. ASSERT(pTiles != NULL);
  86. ASSERT(lpszFileName != NULL);
  87. int nCellColumns;
  88. int nCellRows;
  89. CELL* pMapData = NULL;
  90. if (pPackFileManager != NULL) // use CPackFile
  91. {
  92. CPackFile packFile;
  93. if (packFile.Open(pPackFileManager, lpszFileName) == false)
  94. return  false;
  95. packFile.Read(&nCellColumns, sizeof(int));
  96. packFile.Read(&nCellRows, sizeof(int));
  97. int nSize = nCellColumns * nCellRows;
  98. pMapData = new  CELL[nSize];
  99. ASSERT(pMapData != NULL);
  100. packFile.Read(pMapData, sizeof(CELL) * nSize);
  101. }
  102. else
  103. {
  104. HANDLE fh = ::CreateFile(lpszFileName, GENERIC_READ,
  105. FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING,
  106. FILE_ATTRIBUTE_NORMAL, NULL);
  107. if (fh == INVALID_HANDLE_VALUE)
  108. return  false;
  109. DWORD dwRead;
  110. ::ReadFile(fh, &nCellColumns, sizeof(int), &dwRead, NULL);
  111. ::ReadFile(fh, &nCellRows, sizeof(int), &dwRead, NULL);
  112. int nSize = nCellColumns * nCellRows;
  113. pMapData = new  CELL[nSize];
  114. ASSERT(pMapData != NULL);
  115. ::ReadFile(fh, pMapData, sizeof(CELL) * nSize, &dwRead, NULL);
  116. ::CloseHandle(fh);
  117. }
  118. return  Create(pTiles,
  119. nCellColumns, nCellRows,
  120. pMapData);
  121. }
  122. bool CDXIsoMap::Save(LPCTSTR lpszFileName)
  123. {
  124. HANDLE fh = ::CreateFile(lpszFileName, GENERIC_WRITE,
  125. 0, (LPSECURITY_ATTRIBUTES)NULL, CREATE_ALWAYS,
  126.           FILE_ATTRIBUTE_NORMAL, NULL);
  127. if (fh == INVALID_HANDLE_VALUE)
  128. return  false;
  129. DWORD dwWriteBytes;
  130. ::WriteFile(fh, &m_nColumns, sizeof(int), &dwWriteBytes, NULL);
  131. ::WriteFile(fh, &m_nRows, sizeof(int), &dwWriteBytes, NULL);
  132. ::WriteFile(fh, m_pMapData, sizeof(int) * m_nColumns * m_nRows, &dwWriteBytes, NULL);
  133. ::CloseHandle(fh);
  134. return  true;
  135. }
  136. bool CDXIsoMap::Create(CDDSurface*  pTiles,
  137. int  nCellColumns, int  nCellRows,
  138. CELL* pMapData)
  139. {
  140. m_pTiles = pTiles;
  141. m_nPosX = m_nCellWidth >> 1;
  142. m_nPosY = m_nCellHeight >> 1;
  143. m_nColumns = nCellColumns;
  144. m_nRows = nCellRows;
  145. m_nTotalWidth = m_nColumns << (m_nCellWidthShift - 1);
  146. m_nTotalHeight = m_nRows << m_nCellHeightShift;
  147. ASSERT(m_pMapData == NULL);
  148. m_pMapData = pMapData;
  149. m_nSrcSurfaceCellRows = (m_pTiles->GetWidth() / m_nCellWidth);
  150. return  true;
  151. }
  152. bool CDXIsoMap::Create(CDDSurface*  pTiles,
  153. int  nCellColumns, int  nCellRows, int  nFill)
  154. {
  155. int nSize = nCellColumns * nCellRows;
  156. CELL* pMapData = new  CELL[nSize];
  157. ASSERT(pMapData != NULL);
  158. for (int  i = 0; i < nSize; ++ i)
  159. {
  160. pMapData[i].base.index = (BYTE)nFill;
  161. if (nFill & 0X100)
  162. pMapData[i].base.flag = m_CellIdxFlg;
  163. else pMapData[i].base.flag = 0;
  164. pMapData[i].fringe.index = 0;
  165. pMapData[i].fringe.flag = 0;
  166. }
  167. return  Create(pTiles,
  168. nCellColumns, nCellRows,
  169. pMapData);
  170. }
  171. // 在屏幕的(nDestX, nDestY)位置画图块
  172. // IN:
  173. // nDestX
  174. // nDestY: 屏幕坐标
  175. void CDXIsoMap::BltTile(CDDSurface*  pDestSurface,
  176. int nDestX, int nDestY, CELL* pCell)
  177. {
  178. RECT drc, drc0;
  179. drc.left = nDestX;
  180. drc.top = nDestY;
  181. drc.right = nDestX + m_nCellWidth;
  182. drc.bottom = nDestY + m_nCellHeight;
  183. if (IntersectRect(&drc0, &drc, &m_rcDest))
  184. {
  185. int nOffY = drc0.top - drc.top;
  186. int nOffX = drc0.left - drc.left;
  187. int nW = drc0.right - drc0.left;
  188. int nH = drc0.bottom - drc0.top;
  189. int nTileIndex = pCell->base.index;
  190. if (pCell->base.flag & m_CellIdxFlg)
  191. nTileIndex += 0x100;
  192. int x1, y1;
  193. RECT src;
  194. if (nTileIndex)
  195. {
  196. x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
  197. y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
  198. src.top = y1 + nOffY;
  199. src.left = x1 + nOffX;
  200. src.bottom = src.top + nH;
  201. src.right = src.left + nW;
  202. m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
  203. }
  204. nTileIndex = pCell->fringe.index;
  205. if (pCell->fringe.flag & m_CellIdxFlg)
  206. nTileIndex += 0x100;
  207. if (nTileIndex)
  208. {
  209. x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
  210. y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
  211. src.top = y1 + nOffY;
  212. src.left = x1 + nOffX;
  213. src.bottom = src.top + nH;
  214. src.right = src.left + nW;
  215. m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
  216. }
  217. }
  218. }
  219. void CDXIsoMap::SetViewRect(LPRECT lprcView)
  220. {
  221. ASSERT(lprcView != NULL);
  222. m_rcDest.top = lprcView->top;
  223. m_rcDest.left = lprcView->left;
  224. m_rcDest.bottom = lprcView->bottom;
  225. m_rcDest.right = lprcView->right;
  226. }
  227. void CDXIsoMap::Draw(CDDSurface*  pDestSurface, LPRECT lprcDest)
  228. {
  229. if (lprcDest != NULL)
  230. {
  231. m_rcDest.top = lprcDest->top;
  232. m_rcDest.left = lprcDest->left;
  233. m_rcDest.bottom = lprcDest->bottom;
  234. m_rcDest.right = lprcDest->right;
  235. }
  236. int nHalfW = m_nCellWidth >> 1;
  237. int nHalfH = m_nCellHeight >> 1;
  238. int nOffsetX;
  239. int nOffsetY;
  240. if (m_nPosTX & 1)
  241. {
  242. nOffsetX = (m_nPosX-nHalfW) & (m_nCellWidth-1);
  243. nOffsetY = (m_nPosY-nHalfH) & (m_nCellHeight-1);
  244. }
  245. else
  246. {
  247. nOffsetX = m_nPosX & (m_nCellWidth-1);
  248. nOffsetY = m_nPosY & (m_nCellHeight-1);
  249. }
  250. nOffsetX = -nOffsetX;
  251. nOffsetY = -nOffsetY;
  252. int nOffTx, nOffTy;
  253. if (m_nPosTX & 1)
  254. {
  255. nOffTx = m_nPosTX - 1;
  256. nOffTy = m_nPosTY;
  257. nOffsetX = nOffsetX - nHalfW;
  258. nOffsetY = nOffsetY - nHalfH;
  259. }
  260. else
  261. {
  262. nOffTx = m_nPosTX - 2;
  263. nOffTy = m_nPosTY - 1;
  264. nOffsetX = nOffsetX - m_nCellWidth;
  265. nOffsetY = nOffsetY - m_nCellHeight;
  266. }
  267. int dy = nOffsetY+ m_rcDest.top;
  268. for (int i = nOffTy; ; i++)
  269. {
  270. if ((i>=0) && (i < m_nRows))
  271. {
  272. int dx = nOffsetX + m_rcDest.left;
  273. for (int j= nOffTx; ;)
  274. {
  275. if ((j>=0) && (j < m_nColumns))
  276. BltTile(pDestSurface, dx, dy,
  277. &(m_pMapData[i*m_nColumns+j]));
  278. j++;
  279. if ((j>=0) && (j < m_nColumns))
  280. BltTile(pDestSurface, dx+nHalfW, dy+nHalfH, 
  281. &(m_pMapData[i*m_nColumns+j]));
  282. j++;
  283. dx += m_nCellWidth;
  284. if (dx >= m_rcDest.right) break;
  285. }
  286. }
  287. dy += m_nCellHeight;
  288. if (dy >= m_rcDest.bottom) break;
  289. }
  290. }
  291. void CDXIsoMap::AbsoluteCell(int nPixelX, int nPixelY,
  292.  int &nCellX, int &nCellY,
  293.  BOOL bAbsolutePixel/*=TRUE*/)
  294. {
  295. if (bAbsolutePixel) // in map cord
  296. {
  297. nCellX = (nPixelX >> m_nCellWidthShift) << 1;
  298. nCellY = nPixelY >> m_nCellHeightShift;
  299. }
  300. else // in screen cord
  301. {
  302. nCellX = (((nPixelX-m_rcDest.left)+m_nPosX)
  303. >> m_nCellWidthShift) << 1;
  304. nCellY = ((nPixelY-m_rcDest.top)+m_nPosY) >> m_nCellHeightShift;
  305. }
  306. int nPx, nPy;
  307. if (bAbsolutePixel) // in map cord
  308. {
  309. nPx = nPixelX & (m_nCellWidth-1);
  310. nPy = nPixelY & (m_nCellHeight-1);
  311. }
  312. else // in screen cord
  313. {
  314. nPx = ((nPixelX-m_rcDest.left)+m_nPosX) & (m_nCellWidth-1);
  315. nPy = ((nPixelY-m_rcDest.top)+m_nPosY) & (m_nCellHeight-1);
  316. }
  317. switch( m_CellFigue[nPy][nPx] )
  318.     {
  319.     case 1: nCellX--; nCellY--; break;
  320. case 2: nCellX++; nCellY--; break;
  321. case 3: nCellX--; break;
  322. case 4: nCellX++; break;
  323. }
  324. }
  325. // 根据绝对图块坐标计算出象素坐标
  326. // int nCellX  绝对横向图块坐标
  327. // int nCellY  绝对纵向图块坐标
  328. // int nPixelX  横向象素坐标
  329. // int nPixelY  纵向象素坐标
  330. // BOOL bAbsolute  计算绝对象素坐标还是相对(屏幕)象素坐标
  331. void CDXIsoMap::Cell2Pixel(int nCellX, int nCellY,
  332.    int &nPixelX, int &nPixelY,
  333.    BOOL bAbsolute/*=TRUE*/)
  334. {
  335. // 先计算偶数列图块的绝对象素坐标
  336. nPixelX = (nCellX >> 1) << m_nCellWidthShift;
  337. nPixelY = nCellY << m_nCellHeightShift;
  338. // 计算图块的绝对象素坐标
  339. if (nCellX & 1)
  340. {
  341. nPixelX += (m_nCellWidth >> 1);
  342. nPixelY += (m_nCellHeight >> 1);
  343. }
  344. if (!bAbsolute)
  345. {
  346. // 计算相对(屏幕)坐标
  347. nPixelX -= m_nPosX;
  348. nPixelY -= m_nPosY;
  349. nPixelX += m_rcDest.left;
  350. nPixelY += m_rcDest.top;
  351. }
  352. }
  353. // calculate posiontion of the next adjecent cell in nDirection
  354. // nDirection:
  355. // 3 4 5
  356. // 2   6
  357. // 1 0 7
  358. void CDXIsoMap::NextCell(int &x, int &y, int nDirection)
  359. {
  360. if( x & 1)
  361.     {
  362. switch( nDirection )
  363.     {
  364. case DOWN :       y++; break;
  365. case LEFT_DOWN : x--;  y++; break;
  366. case LEFT : x-=2;   break;
  367. case LEFT_UP : x--;       break;
  368. case UP :       y--; break;
  369. case RIGHT_UP : x++;       break;
  370. case RIGHT : x+=2;      break;
  371. case RIGHT_DOWN : x++;  y++; break;
  372.     }
  373.     }
  374.     else
  375.     {
  376. switch( nDirection )
  377.      {
  378. case DOWN :       y++; break;
  379. case LEFT_DOWN : x--;    break;
  380. case LEFT : x-=2;   break;
  381. case LEFT_UP : x--;  y--; break;
  382. case UP :       y--; break;
  383. case RIGHT_UP : x++;  y--; break;
  384. case RIGHT : x+=2;      break;
  385. case RIGHT_DOWN : x++;    break;
  386.      }
  387.     }
  388. }
  389. void CDXIsoMap::MoveTo(int nPosX, int nPosY)
  390. {
  391. static int nHalfW = m_nCellWidth >> 1;
  392. static int nHalfH = m_nCellHeight >> 1;
  393. m_nPosX = nPosX;
  394. m_nPosY = nPosY;
  395. int nLeft = nHalfW;
  396. int nRight = m_nTotalWidth -
  397. (m_rcDest.right - m_rcDest.left) - nHalfW;
  398. if (m_nPosX < nLeft)
  399. m_nPosX = nLeft;
  400. if (m_nPosX > nRight)
  401. m_nPosX = nRight;
  402. int nTop = nHalfH;
  403. int nBottom = m_nTotalHeight -
  404. (m_rcDest.bottom - m_rcDest.top) - nHalfH;
  405. if (m_nPosY < nTop)
  406. m_nPosY = nTop;
  407. if (m_nPosY > nBottom)
  408. m_nPosY = nBottom;
  409. AbsoluteCell(m_nPosX, m_nPosY, m_nPosTX, m_nPosTY);
  410. }
  411. void CDXIsoMap::ScrollX(int nOffset)
  412. {
  413. static int nHalfW = m_nCellWidth >> 1;
  414. int nLeft = nHalfW;
  415. int nRight = m_nTotalWidth -
  416. (m_rcDest.right - m_rcDest.left) - nHalfW;
  417. m_nPosX += nOffset;
  418. if (m_nPosX < nLeft)
  419. m_nPosX = nLeft;
  420. if (m_nPosX > nRight)
  421. m_nPosX = nRight;
  422. AbsoluteCell(m_nPosX, m_nPosY, m_nPosTX, m_nPosTY);
  423. }
  424. void CDXIsoMap::ScrollY(int nOffset)
  425. {
  426. static int nHalfH = m_nCellHeight >> 1;
  427. int nTop = nHalfH;
  428. int nBottom = m_nTotalHeight -
  429. (m_rcDest.bottom - m_rcDest.top) - nHalfH;
  430. m_nPosY += nOffset;
  431. if (m_nPosY < nTop)
  432. m_nPosY = nTop;
  433. if (m_nPosY > nBottom)
  434. m_nPosY = nBottom;
  435. AbsoluteCell(m_nPosX, m_nPosY, m_nPosTX, m_nPosTY);
  436. }
  437. void CDXIsoMap::Scroll(DIRECTION eDir)
  438. {
  439. switch (eDir)
  440. {
  441. case DOWN:
  442. ScrollY(1);
  443. break;
  444. case LEFT_DOWN:
  445. ScrollX(-2);
  446. ScrollY(1);
  447. break;
  448. case LEFT:
  449. ScrollX(-2);
  450. break;
  451. case LEFT_UP:
  452. ScrollX(-2);
  453. ScrollY(-1);
  454. break;
  455. case UP:
  456. ScrollY(-1);
  457. break;
  458. case RIGHT_UP:
  459. ScrollX(2);
  460. ScrollY(-1);
  461. break;
  462. case RIGHT:
  463. ScrollX(2);
  464. break;
  465. case RIGHT_DOWN:
  466. ScrollX(2);
  467. ScrollY(1);
  468. break;
  469. }
  470. }
  471. CELL* CDXIsoMap::GetCell(int nTx, int nTy)
  472. {
  473. ASSERT((nTx< m_nColumns) && (nTy < m_nRows));
  474. return (&m_pMapData[nTy*m_nColumns+nTx]);
  475. }
  476. // 在屏幕的(nDestX, nDestY)位置重画高度高于nHeight的图块
  477. // IN:
  478. // nDestX
  479. // nDestY: 屏幕坐标
  480. void CDXIsoMap::BltTileAbove(CDDSurface*  pDestSurface,
  481. int nDestX, int nDestY, CELL* pCell, int nHeight)
  482. {
  483. RECT drc, drc0;
  484. drc.left = nDestX;
  485. drc.top = nDestY;
  486. drc.right = nDestX + m_nCellWidth;
  487. drc.bottom = nDestY + m_nCellHeight;
  488. if (IntersectRect(&drc0, &drc, &m_rcDest))
  489. {
  490. int nOffY = drc0.top - drc.top;
  491. int nOffX = drc0.left - drc.left; 
  492. int nW = drc0.right - drc0.left;
  493. int nH = drc0.bottom - drc0.top;
  494. int nTileIndex;
  495. int x1, y1;
  496. RECT src;
  497. if ((pCell->base.flag & 0x0F) >= nHeight)
  498. {
  499. nTileIndex = pCell->base.index;
  500. if (pCell->base.flag & m_CellIdxFlg)
  501. nTileIndex += 0x100;
  502. if (nTileIndex)
  503. {
  504. x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
  505. y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
  506. src.top = y1 + nOffY;
  507. src.left = x1 + nOffX;
  508. src.bottom = src.top + nH;
  509. src.right = src.left + nW;
  510. m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
  511. }
  512. }
  513. if ((pCell->fringe.flag & 0x0F) >= nHeight)
  514. {
  515. nTileIndex = pCell->fringe.index;
  516. if (pCell->fringe.flag & m_CellIdxFlg)
  517. nTileIndex += 0x100;
  518. if (nTileIndex)
  519. {
  520. x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
  521. y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
  522. src.top = y1 + nOffY;
  523. src.left = x1 + nOffX;
  524. src.bottom = src.top + nH;
  525. src.right = src.left + nW;
  526. m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
  527. }
  528. }
  529. }
  530. }
  531. // 从图块(nX, nY)开始向上重画8块
  532. // 因为16*8=128为人物高度的最大值
  533. // IN:
  534. // nX:
  535. // nY: 绝对图块坐标
  536. void CDXIsoMap::DrawColAbove(CDDSurface *pDest, int nX, int nY)
  537. {
  538. int tx, ty;
  539. int x, y;
  540. tx = nX;
  541. ty = nY;
  542. for(int i=0; i<8; i++)
  543. {
  544. // 再转换成当前图块左上角的相对象素坐标
  545. Cell2Pixel(tx, ty, x, y, FALSE);
  546. BltTileAbove(pDest, x, y, GetCell(tx, ty), i*2+1);
  547. if (ty>0)
  548. NextCell(tx, ty, UP);
  549. else
  550. break;
  551. }
  552. }
  553. // 遮掩算法
  554. // IN:
  555. // nX: Hero所处的屏幕坐标
  556. // nY: 
  557. void CDXIsoMap::DrawAbove(CDDSurface *pDest, int nX, int nY)
  558. {
  559. int tx, ty;
  560. int x, y;
  561. // 根据相对象素坐标计算绝对图块坐标
  562. AbsoluteCell(nX, nY, x, y, FALSE);
  563. tx = x;
  564. ty = y;
  565. // 中间列
  566. DrawColAbove(pDest, tx, ty);
  567. // 左边列
  568. NextCell(tx, ty, LEFT_DOWN);
  569. DrawColAbove(pDest, tx, ty);
  570. NextCell(tx, ty, LEFT_UP);
  571. DrawColAbove(pDest, tx, ty);
  572. NextCell(tx, ty, LEFT_DOWN);
  573. DrawColAbove(pDest, tx, ty);
  574. // 右边列
  575. tx = x;
  576. ty = y;
  577. NextCell(tx, ty, RIGHT_DOWN);
  578. DrawColAbove(pDest, tx, ty);
  579. NextCell(tx, ty, RIGHT_UP);
  580. DrawColAbove(pDest, tx, ty);
  581. NextCell(tx, ty, RIGHT_DOWN);
  582. DrawColAbove(pDest, tx, ty);
  583. }