DXIsoMap.cpp
上传用户:pfmy85
上传日期:2007-01-07
资源大小:22k
文件大小:16k
- // DXIsoMap.cpp: implementation of the CDXIsoMap class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "DXIsoMap.h"
- #include "DDDevice.h"
- #include "DDDIBSurface.h"
- #include "PackFile.h"
- #include "IsoType.h"
- //#include "stdafx.h"
- //#include "Isotest.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- const CHAR CDXIsoMap::m_CellFigue[16][32] =
- {
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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}
- };
- const int CDXIsoMap::m_nCellWidth = 32;
- const int CDXIsoMap::m_nCellHeight = 16;
- const int CDXIsoMap::m_nCellWidthShift = 5;
- const int CDXIsoMap::m_nCellHeightShift = 4;
- const BYTE CDXIsoMap::m_CellIdxFlg = 0x10;
- const BYTE CDXIsoMap::m_CellRmrFlg = 0X20;
- const BYTE CDXIsoMap::m_CellNpcFlg = 0x40;
- const BYTE CDXIsoMap::m_CellLnkFlg = 0x80;
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CDXIsoMap::CDXIsoMap()
- {
- m_bAutoDelete = false;
- m_pMapData = NULL;
- m_nPosX = 0;
- m_nPosY = 0;
- m_nPosTX = 0;
- m_nPosTY = 0;
- m_nOffX = 0;
- m_nOffY = 0;
- m_pPassValues = NULL;
- m_pTiles = NULL;
- }
- CDXIsoMap::~CDXIsoMap()
- {
- if (m_pPassValues != NULL)
- {
- delete []m_pPassValues;
- m_pPassValues = NULL;
- }
- if (m_pMapData != NULL)
- {
- delete []m_pMapData;
- m_pMapData = NULL;
- }
- if (m_bAutoDelete == true)
- {
- if (m_pTiles != NULL)
- {
- delete m_pTiles;
- }
- }
- m_pTiles = NULL;
- }
- bool CDXIsoMap::Create(CDDSurface* pTiles,
- LPCTSTR lpszFileName,
- CPackFileManager* pPackFileManager/* = NULL*/)
- {
- ASSERT(pTiles != NULL);
- ASSERT(lpszFileName != NULL);
- int nCellColumns;
- int nCellRows;
- CELL* pMapData = NULL;
- if (pPackFileManager != NULL) // use CPackFile
- {
- CPackFile packFile;
- if (packFile.Open(pPackFileManager, lpszFileName) == false)
- return false;
- packFile.Read(&nCellColumns, sizeof(int));
- packFile.Read(&nCellRows, sizeof(int));
- int nSize = nCellColumns * nCellRows;
- pMapData = new CELL[nSize];
- ASSERT(pMapData != NULL);
- packFile.Read(pMapData, sizeof(CELL) * nSize);
- }
- else
- {
- HANDLE fh = ::CreateFile(lpszFileName, GENERIC_READ,
- FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (fh == INVALID_HANDLE_VALUE)
- return false;
- DWORD dwRead;
- ::ReadFile(fh, &nCellColumns, sizeof(int), &dwRead, NULL);
- ::ReadFile(fh, &nCellRows, sizeof(int), &dwRead, NULL);
- int nSize = nCellColumns * nCellRows;
- pMapData = new CELL[nSize];
- ASSERT(pMapData != NULL);
- ::ReadFile(fh, pMapData, sizeof(CELL) * nSize, &dwRead, NULL);
- ::CloseHandle(fh);
- }
- return Create(pTiles,
- nCellColumns, nCellRows,
- pMapData);
- }
- bool CDXIsoMap::Save(LPCTSTR lpszFileName)
- {
- HANDLE fh = ::CreateFile(lpszFileName, GENERIC_WRITE,
- 0, (LPSECURITY_ATTRIBUTES)NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (fh == INVALID_HANDLE_VALUE)
- return false;
- DWORD dwWriteBytes;
- ::WriteFile(fh, &m_nColumns, sizeof(int), &dwWriteBytes, NULL);
- ::WriteFile(fh, &m_nRows, sizeof(int), &dwWriteBytes, NULL);
- ::WriteFile(fh, m_pMapData, sizeof(int) * m_nColumns * m_nRows, &dwWriteBytes, NULL);
- ::CloseHandle(fh);
- return true;
- }
- bool CDXIsoMap::Create(CDDSurface* pTiles,
- int nCellColumns, int nCellRows,
- CELL* pMapData)
- {
- m_pTiles = pTiles;
- m_nPosX = m_nCellWidth >> 1;
- m_nPosY = m_nCellHeight >> 1;
- m_nColumns = nCellColumns;
- m_nRows = nCellRows;
- m_nTotalWidth = m_nColumns << (m_nCellWidthShift - 1);
- m_nTotalHeight = m_nRows << m_nCellHeightShift;
- ASSERT(m_pMapData == NULL);
- m_pMapData = pMapData;
- m_nSrcSurfaceCellRows = (m_pTiles->GetWidth() / m_nCellWidth);
- return true;
- }
- bool CDXIsoMap::Create(CDDSurface* pTiles,
- int nCellColumns, int nCellRows, int nFill)
- {
- int nSize = nCellColumns * nCellRows;
- CELL* pMapData = new CELL[nSize];
- ASSERT(pMapData != NULL);
- for (int i = 0; i < nSize; ++ i)
- {
- pMapData[i].base.index = (BYTE)nFill;
- if (nFill & 0X100)
- pMapData[i].base.flag = m_CellIdxFlg;
- else pMapData[i].base.flag = 0;
- pMapData[i].fringe.index = 0;
- pMapData[i].fringe.flag = 0;
- }
- return Create(pTiles,
- nCellColumns, nCellRows,
- pMapData);
- }
- // 在屏幕的(nDestX, nDestY)位置画图块
- // IN:
- // nDestX
- // nDestY: 屏幕坐标
- void CDXIsoMap::BltTile(CDDSurface* pDestSurface,
- int nDestX, int nDestY, CELL* pCell)
- {
- RECT drc, drc0;
- drc.left = nDestX;
- drc.top = nDestY;
- drc.right = nDestX + m_nCellWidth;
- drc.bottom = nDestY + m_nCellHeight;
- if (IntersectRect(&drc0, &drc, &m_rcDest))
- {
- int nOffY = drc0.top - drc.top;
- int nOffX = drc0.left - drc.left;
- int nW = drc0.right - drc0.left;
- int nH = drc0.bottom - drc0.top;
- int nTileIndex = pCell->base.index;
- if (pCell->base.flag & m_CellIdxFlg)
- nTileIndex += 0x100;
- int x1, y1;
- RECT src;
- if (nTileIndex)
- {
- x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
- y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
- src.top = y1 + nOffY;
- src.left = x1 + nOffX;
- src.bottom = src.top + nH;
- src.right = src.left + nW;
- m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
- }
- nTileIndex = pCell->fringe.index;
- if (pCell->fringe.flag & m_CellIdxFlg)
- nTileIndex += 0x100;
- if (nTileIndex)
- {
- x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
- y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
- src.top = y1 + nOffY;
- src.left = x1 + nOffX;
- src.bottom = src.top + nH;
- src.right = src.left + nW;
- m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
- }
- }
- }
- void CDXIsoMap::SetViewRect(LPRECT lprcView)
- {
- ASSERT(lprcView != NULL);
- m_rcDest.top = lprcView->top;
- m_rcDest.left = lprcView->left;
- m_rcDest.bottom = lprcView->bottom;
- m_rcDest.right = lprcView->right;
- }
- void CDXIsoMap::Draw(CDDSurface* pDestSurface, LPRECT lprcDest)
- {
- if (lprcDest != NULL)
- {
- m_rcDest.top = lprcDest->top;
- m_rcDest.left = lprcDest->left;
- m_rcDest.bottom = lprcDest->bottom;
- m_rcDest.right = lprcDest->right;
- }
- int nHalfW = m_nCellWidth >> 1;
- int nHalfH = m_nCellHeight >> 1;
- int nOffsetX;
- int nOffsetY;
- if (m_nPosTX & 1)
- {
- nOffsetX = (m_nPosX-nHalfW) & (m_nCellWidth-1);
- nOffsetY = (m_nPosY-nHalfH) & (m_nCellHeight-1);
- }
- else
- {
- nOffsetX = m_nPosX & (m_nCellWidth-1);
- nOffsetY = m_nPosY & (m_nCellHeight-1);
- }
- nOffsetX = -nOffsetX;
- nOffsetY = -nOffsetY;
- int nOffTx, nOffTy;
- if (m_nPosTX & 1)
- {
- nOffTx = m_nPosTX - 1;
- nOffTy = m_nPosTY;
- nOffsetX = nOffsetX - nHalfW;
- nOffsetY = nOffsetY - nHalfH;
- }
- else
- {
- nOffTx = m_nPosTX - 2;
- nOffTy = m_nPosTY - 1;
- nOffsetX = nOffsetX - m_nCellWidth;
- nOffsetY = nOffsetY - m_nCellHeight;
- }
-
- int dy = nOffsetY+ m_rcDest.top;
- for (int i = nOffTy; ; i++)
- {
- if ((i>=0) && (i < m_nRows))
- {
- int dx = nOffsetX + m_rcDest.left;
- for (int j= nOffTx; ;)
- {
- if ((j>=0) && (j < m_nColumns))
- BltTile(pDestSurface, dx, dy,
- &(m_pMapData[i*m_nColumns+j]));
- j++;
- if ((j>=0) && (j < m_nColumns))
- BltTile(pDestSurface, dx+nHalfW, dy+nHalfH,
- &(m_pMapData[i*m_nColumns+j]));
- j++;
- dx += m_nCellWidth;
- if (dx >= m_rcDest.right) break;
- }
- }
- dy += m_nCellHeight;
- if (dy >= m_rcDest.bottom) break;
- }
- }
- void CDXIsoMap::AbsoluteCell(int nPixelX, int nPixelY,
- int &nCellX, int &nCellY,
- BOOL bAbsolutePixel/*=TRUE*/)
- {
- if (bAbsolutePixel) // in map cord
- {
- nCellX = (nPixelX >> m_nCellWidthShift) << 1;
- nCellY = nPixelY >> m_nCellHeightShift;
- }
- else // in screen cord
- {
- nCellX = (((nPixelX-m_rcDest.left)+m_nPosX)
- >> m_nCellWidthShift) << 1;
- nCellY = ((nPixelY-m_rcDest.top)+m_nPosY) >> m_nCellHeightShift;
- }
- int nPx, nPy;
- if (bAbsolutePixel) // in map cord
- {
- nPx = nPixelX & (m_nCellWidth-1);
- nPy = nPixelY & (m_nCellHeight-1);
- }
- else // in screen cord
- {
- nPx = ((nPixelX-m_rcDest.left)+m_nPosX) & (m_nCellWidth-1);
- nPy = ((nPixelY-m_rcDest.top)+m_nPosY) & (m_nCellHeight-1);
- }
- switch( m_CellFigue[nPy][nPx] )
- {
- case 1: nCellX--; nCellY--; break;
- case 2: nCellX++; nCellY--; break;
- case 3: nCellX--; break;
- case 4: nCellX++; break;
- }
- }
- // 根据绝对图块坐标计算出象素坐标
- // int nCellX 绝对横向图块坐标
- // int nCellY 绝对纵向图块坐标
- // int nPixelX 横向象素坐标
- // int nPixelY 纵向象素坐标
- // BOOL bAbsolute 计算绝对象素坐标还是相对(屏幕)象素坐标
- void CDXIsoMap::Cell2Pixel(int nCellX, int nCellY,
- int &nPixelX, int &nPixelY,
- BOOL bAbsolute/*=TRUE*/)
- {
- // 先计算偶数列图块的绝对象素坐标
- nPixelX = (nCellX >> 1) << m_nCellWidthShift;
- nPixelY = nCellY << m_nCellHeightShift;
- // 计算图块的绝对象素坐标
- if (nCellX & 1)
- {
- nPixelX += (m_nCellWidth >> 1);
- nPixelY += (m_nCellHeight >> 1);
- }
- if (!bAbsolute)
- {
- // 计算相对(屏幕)坐标
- nPixelX -= m_nPosX;
- nPixelY -= m_nPosY;
- nPixelX += m_rcDest.left;
- nPixelY += m_rcDest.top;
- }
- }
- // calculate posiontion of the next adjecent cell in nDirection
- // nDirection:
- // 3 4 5
- // 2 6
- // 1 0 7
- void CDXIsoMap::NextCell(int &x, int &y, int nDirection)
- {
- if( x & 1)
- {
- switch( nDirection )
- {
- case DOWN : y++; break;
- case LEFT_DOWN : x--; y++; break;
- case LEFT : x-=2; break;
- case LEFT_UP : x--; break;
- case UP : y--; break;
- case RIGHT_UP : x++; break;
- case RIGHT : x+=2; break;
- case RIGHT_DOWN : x++; y++; break;
- }
- }
- else
- {
- switch( nDirection )
- {
- case DOWN : y++; break;
- case LEFT_DOWN : x--; break;
- case LEFT : x-=2; break;
- case LEFT_UP : x--; y--; break;
- case UP : y--; break;
- case RIGHT_UP : x++; y--; break;
- case RIGHT : x+=2; break;
- case RIGHT_DOWN : x++; break;
- }
- }
- }
- void CDXIsoMap::MoveTo(int nPosX, int nPosY)
- {
- static int nHalfW = m_nCellWidth >> 1;
- static int nHalfH = m_nCellHeight >> 1;
- m_nPosX = nPosX;
- m_nPosY = nPosY;
- int nLeft = nHalfW;
- int nRight = m_nTotalWidth -
- (m_rcDest.right - m_rcDest.left) - nHalfW;
- if (m_nPosX < nLeft)
- m_nPosX = nLeft;
- if (m_nPosX > nRight)
- m_nPosX = nRight;
- int nTop = nHalfH;
- int nBottom = m_nTotalHeight -
- (m_rcDest.bottom - m_rcDest.top) - nHalfH;
- if (m_nPosY < nTop)
- m_nPosY = nTop;
- if (m_nPosY > nBottom)
- m_nPosY = nBottom;
- AbsoluteCell(m_nPosX, m_nPosY, m_nPosTX, m_nPosTY);
- }
- void CDXIsoMap::ScrollX(int nOffset)
- {
- static int nHalfW = m_nCellWidth >> 1;
- int nLeft = nHalfW;
- int nRight = m_nTotalWidth -
- (m_rcDest.right - m_rcDest.left) - nHalfW;
- m_nPosX += nOffset;
- if (m_nPosX < nLeft)
- m_nPosX = nLeft;
- if (m_nPosX > nRight)
- m_nPosX = nRight;
- AbsoluteCell(m_nPosX, m_nPosY, m_nPosTX, m_nPosTY);
- }
- void CDXIsoMap::ScrollY(int nOffset)
- {
- static int nHalfH = m_nCellHeight >> 1;
- int nTop = nHalfH;
- int nBottom = m_nTotalHeight -
- (m_rcDest.bottom - m_rcDest.top) - nHalfH;
- m_nPosY += nOffset;
- if (m_nPosY < nTop)
- m_nPosY = nTop;
- if (m_nPosY > nBottom)
- m_nPosY = nBottom;
- AbsoluteCell(m_nPosX, m_nPosY, m_nPosTX, m_nPosTY);
- }
- void CDXIsoMap::Scroll(DIRECTION eDir)
- {
- switch (eDir)
- {
- case DOWN:
- ScrollY(1);
- break;
- case LEFT_DOWN:
- ScrollX(-2);
- ScrollY(1);
- break;
- case LEFT:
- ScrollX(-2);
- break;
- case LEFT_UP:
- ScrollX(-2);
- ScrollY(-1);
- break;
- case UP:
- ScrollY(-1);
- break;
- case RIGHT_UP:
- ScrollX(2);
- ScrollY(-1);
- break;
- case RIGHT:
- ScrollX(2);
- break;
- case RIGHT_DOWN:
- ScrollX(2);
- ScrollY(1);
- break;
- }
- }
- CELL* CDXIsoMap::GetCell(int nTx, int nTy)
- {
- ASSERT((nTx< m_nColumns) && (nTy < m_nRows));
- return (&m_pMapData[nTy*m_nColumns+nTx]);
- }
- // 在屏幕的(nDestX, nDestY)位置重画高度高于nHeight的图块
- // IN:
- // nDestX
- // nDestY: 屏幕坐标
- void CDXIsoMap::BltTileAbove(CDDSurface* pDestSurface,
- int nDestX, int nDestY, CELL* pCell, int nHeight)
- {
- RECT drc, drc0;
- drc.left = nDestX;
- drc.top = nDestY;
- drc.right = nDestX + m_nCellWidth;
- drc.bottom = nDestY + m_nCellHeight;
- if (IntersectRect(&drc0, &drc, &m_rcDest))
- {
- int nOffY = drc0.top - drc.top;
- int nOffX = drc0.left - drc.left;
- int nW = drc0.right - drc0.left;
- int nH = drc0.bottom - drc0.top;
- int nTileIndex;
- int x1, y1;
- RECT src;
- if ((pCell->base.flag & 0x0F) >= nHeight)
- {
- nTileIndex = pCell->base.index;
- if (pCell->base.flag & m_CellIdxFlg)
- nTileIndex += 0x100;
- if (nTileIndex)
- {
- x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
- y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
- src.top = y1 + nOffY;
- src.left = x1 + nOffX;
- src.bottom = src.top + nH;
- src.right = src.left + nW;
- m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
- }
- }
- if ((pCell->fringe.flag & 0x0F) >= nHeight)
- {
- nTileIndex = pCell->fringe.index;
- if (pCell->fringe.flag & m_CellIdxFlg)
- nTileIndex += 0x100;
- if (nTileIndex)
- {
- x1 = (nTileIndex % m_nSrcSurfaceCellRows) << m_nCellWidthShift;
- y1 = (nTileIndex / m_nSrcSurfaceCellRows) << m_nCellHeightShift;
- src.top = y1 + nOffY;
- src.left = x1 + nOffX;
- src.bottom = src.top + nH;
- src.right = src.left + nW;
- m_pTiles->Draw(pDestSurface, drc0.left, drc0.top, &src);
- }
- }
- }
- }
- // 从图块(nX, nY)开始向上重画8块
- // 因为16*8=128为人物高度的最大值
- // IN:
- // nX:
- // nY: 绝对图块坐标
- void CDXIsoMap::DrawColAbove(CDDSurface *pDest, int nX, int nY)
- {
- int tx, ty;
- int x, y;
- tx = nX;
- ty = nY;
- for(int i=0; i<8; i++)
- {
- // 再转换成当前图块左上角的相对象素坐标
- Cell2Pixel(tx, ty, x, y, FALSE);
- BltTileAbove(pDest, x, y, GetCell(tx, ty), i*2+1);
- if (ty>0)
- NextCell(tx, ty, UP);
- else
- break;
- }
- }
- // 遮掩算法
- // IN:
- // nX: Hero所处的屏幕坐标
- // nY:
- void CDXIsoMap::DrawAbove(CDDSurface *pDest, int nX, int nY)
- {
- int tx, ty;
- int x, y;
- // 根据相对象素坐标计算绝对图块坐标
- AbsoluteCell(nX, nY, x, y, FALSE);
- tx = x;
- ty = y;
- // 中间列
- DrawColAbove(pDest, tx, ty);
- // 左边列
- NextCell(tx, ty, LEFT_DOWN);
- DrawColAbove(pDest, tx, ty);
- NextCell(tx, ty, LEFT_UP);
- DrawColAbove(pDest, tx, ty);
- NextCell(tx, ty, LEFT_DOWN);
- DrawColAbove(pDest, tx, ty);
- // 右边列
- tx = x;
- ty = y;
- NextCell(tx, ty, RIGHT_DOWN);
- DrawColAbove(pDest, tx, ty);
- NextCell(tx, ty, RIGHT_UP);
- DrawColAbove(pDest, tx, ty);
- NextCell(tx, ty, RIGHT_DOWN);
- DrawColAbove(pDest, tx, ty);
- }