📄 isorenderer.cpp
字号:
//IsoRenderer.cpp
#include "IsoRenderer.h"
#include "DDFuncs.h"
//constructor
CRenderer::CRenderer()
{
//blank
}
CRenderer::~CRenderer()
{
//deallocate rectangle list
delete rcUpdateList;
//deallocate update map
delete bMap;
}
//surfaces
void CRenderer::SetBackBuffer(LPDIRECTDRAWSURFACE7 lpdds)
{
//set the back buffer
lpddsBackBuffer=lpdds;
}
void CRenderer::SetFrameBuffer(LPDIRECTDRAWSURFACE7 lpdds)
{
//set the frame buffer
lpddsFrameBuffer=lpdds;
}
//isohexcore components
void CRenderer::SetPlotter(CTilePlotter* pPlotter)
{
//set the plotter
pTilePlotter=pPlotter;
}
void CRenderer::SetWalker(CTileWalker* pWalker)
{
//set the tile walker
pTileWalker=pWalker;
}
void CRenderer::SetMouseMap(CMouseMap* pMMap)
{
//set the mousemap
pMouseMap=pMMap;
}
void CRenderer::SetScroller(CScroller* pScroll)
{
//set the scroller
pScroller=pScroll;
}
//update list
void CRenderer::SetUpdateRectCount(int iMaxRects)//sets up the rectangle list
{
//set the max number of rectangles
iUpdateRectCount=iMaxRects;
//allocate the rectangle list
rcUpdateList=new RECT[iMaxRects];
//set the index to 0
iUpdateRectIndex=0;
}
//update map
void CRenderer::SetMapSize(int MapWidth,int MapHeight)//sets up the update map
{
//allocate a new map
bMap=new bool[MapWidth*MapHeight];
//set the map width and height
iMapWidth=MapWidth;
iMapHeight=MapHeight;
}
//rendering functions
void CRenderer::SetRenderFunction(RENDERFN RendFunc)
{
//set the rendering function
RenderFunction=RendFunc;
}
//extent rect
void CRenderer::SetExtentRect(RECT* rcExt)
{
CopyRect(&rcExtent,rcExt);
}
//add rect to list
void CRenderer::AddRect(RECT* prcAdd)
{
//if there is no more room in the rectangle list, return
if(iUpdateRectIndex>=iUpdateRectCount) return;
//copy rect
RECT rcUpdate;
IntersectRect(&rcUpdate,prcAdd,pScroller->GetScreenSpace());
//if the update rect is empty, return
if(IsRectEmpty(&rcUpdate)) return;
//clear out the frame buffer with black in the update region
DDBLTFX ddbltfx;
DDBLTFX_ColorFill(&ddbltfx,0);
lpddsFrameBuffer->Blt(&rcUpdate,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
//add the rect to the list
CopyRect(&rcUpdateList[iUpdateRectIndex],&rcUpdate);
iUpdateRectIndex++;//add one to the index
//temp variables for calculations
POINT ptTemp;
POINT ptCoarse;
POINT ptMap;
//calculate the corner points
POINT ptCornerUpperLeft;
POINT ptCornerUpperRight;
POINT ptCornerLowerLeft;
POINT ptCornerLowerRight;
//upper left
ptTemp.x=rcUpdate.left;
ptTemp.y=rcUpdate.top;
//screen->world
ptTemp=pScroller->ScreenToWorld(ptTemp);
//subtract mousemap reference point
ptTemp.x-=pMouseMap->GetReferencePoint()->x;
ptTemp.y-=pMouseMap->GetReferencePoint()->y;
//calculate coarse coordinates
ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
//calculate fine cordinates
ptTemp.x%=pMouseMap->GetWidth();
ptTemp.y%=pMouseMap->GetHeight();
//check for negative fine coordinates
if(ptTemp.x<0) ptCoarse.x--;
if(ptTemp.y<0) ptCoarse.y--;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the east
ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
//assign the corner point
ptCornerUpperLeft.x=ptMap.x*ptCoarse.x;
ptCornerUpperLeft.y=ptMap.y*ptCoarse.x;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the south
ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
ptCornerUpperLeft.x+=(ptMap.x*ptCoarse.y);
ptCornerUpperLeft.y+=(ptMap.y*ptCoarse.y);
//upper right
ptTemp.x=rcUpdate.right;
ptTemp.y=rcUpdate.top;
//screen->world
ptTemp=pScroller->ScreenToWorld(ptTemp);
//subtract mousemap reference point
ptTemp.x-=pMouseMap->GetReferencePoint()->x;
ptTemp.y-=pMouseMap->GetReferencePoint()->y;
//calculate coarse coordinates
ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
//calculate fine cordinates
ptTemp.x%=pMouseMap->GetWidth();
ptTemp.y%=pMouseMap->GetHeight();
//check for negative fine coordinates
if(ptTemp.x<0) ptCoarse.x--;
if(ptTemp.y<0) ptCoarse.y--;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the east
ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
//assign the corner point
ptCornerUpperRight.x=ptMap.x*ptCoarse.x;
ptCornerUpperRight.y=ptMap.y*ptCoarse.x;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the south
ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
ptCornerUpperRight.x+=(ptMap.x*ptCoarse.y);
ptCornerUpperRight.y+=(ptMap.y*ptCoarse.y);
//lower left
ptTemp.x=rcUpdate.left;
ptTemp.y=rcUpdate.bottom;
//screen->world
ptTemp=pScroller->ScreenToWorld(ptTemp);
//subtract mousemap reference point
ptTemp.x-=pMouseMap->GetReferencePoint()->x;
ptTemp.y-=pMouseMap->GetReferencePoint()->y;
//calculate coarse coordinates
ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
//calculate fine cordinates
ptTemp.x%=pMouseMap->GetWidth();
ptTemp.y%=pMouseMap->GetHeight();
//check for negative fine coordinates
if(ptTemp.x<0) ptCoarse.x--;
if(ptTemp.y<0) ptCoarse.y--;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the east
ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
//assign the corner point
ptCornerLowerLeft.x=ptMap.x*ptCoarse.x;
ptCornerLowerLeft.y=ptMap.y*ptCoarse.x;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the south
ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
ptCornerLowerLeft.x+=(ptMap.x*ptCoarse.y);
ptCornerLowerLeft.y+=(ptMap.y*ptCoarse.y);
//lower right
ptTemp.x=rcUpdate.right;
ptTemp.y=rcUpdate.bottom;
//screen->world
ptTemp=pScroller->ScreenToWorld(ptTemp);
//subtract mousemap reference point
ptTemp.x-=pMouseMap->GetReferencePoint()->x;
ptTemp.y-=pMouseMap->GetReferencePoint()->y;
//calculate coarse coordinates
ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
//calculate fine cordinates
ptTemp.x%=pMouseMap->GetWidth();
ptTemp.y%=pMouseMap->GetHeight();
//check for negative fine coordinates
if(ptTemp.x<0) ptCoarse.x--;
if(ptTemp.y<0) ptCoarse.y--;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the east
ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
//assign the corner point
ptCornerLowerRight.x=ptMap.x*ptCoarse.x;
ptCornerLowerRight.y=ptMap.y*ptCoarse.x;
//reset map point
ptMap.x=0;
ptMap.y=0;
//move to the south
ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
ptCornerLowerRight.x+=(ptMap.x*ptCoarse.y);
ptCornerLowerRight.y+=(ptMap.y*ptCoarse.y);
//move the corners away from screenspace one step
ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_NORTHWEST);
ptCornerUpperRight=pTileWalker->TileWalk(ptCornerUpperRight,ISO_NORTHEAST);
ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTHWEST);
ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTHEAST);
//move the left corners to the west
ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_WEST);
ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_WEST);
//move the bottom corners to the south
ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTH);
ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTH);
//scan through the tiles
POINT ptRowStart=ptCornerUpperLeft;
POINT ptRowEnd=ptCornerUpperRight;
POINT ptCurrent=ptRowStart;
DWORD dwRowCount=0;
for(;;)
{
//set current point to rowstart
ptCurrent=ptRowStart;
//render a row of tiles
for(;;)
{
//check that ptcurrent is an actual map location
if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
{
//mark tile for updating
bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=true;
}
//is this the last tile in the row?
if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;
//walk to the east
ptCurrent=pTileWalker->TileWalk(ptCurrent,ISO_EAST);
}
//check to see if this is the last row
if(ptRowStart.x==ptCornerLowerLeft.x && ptRowStart.y==ptCornerLowerLeft.y) break;
//move down a row
if(dwRowCount&1)
{
//odd row
//move outward
ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHWEST);
ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHEAST);
}
else
{
//even row
//move inward
ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHEAST);
ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHWEST);
}
//add one to the row count
dwRowCount++;
}
}
void CRenderer::AddTile(int mapx,int mapy)
{
//put x and y into a point
POINT ptMap;
ptMap.x=mapx;
ptMap.y=mapy;
//plot the map coord
POINT ptPlot=pTilePlotter->PlotTile(ptMap);
//convert to screen coords
ptPlot=pScroller->WorldToScreen(ptPlot);
//get ext rect
RECT rcUpdate;
CopyRect(&rcUpdate,&rcExtent);
//offset by plotted point
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -