📄 isorenderer.cpp
字号:
OffsetRect(&rcUpdate,ptPlot.x,ptPlot.y);
//add to rect list
AddRect(&rcUpdate);
}
//scroll the frame
void CRenderer::ScrollFrame(int scrollx,int scrolly)
{
//figure out the actual scrollx and scrolly
POINT ptAnchorOld;
//grab the current anchor position
ptAnchorOld.x=pScroller->GetAnchor()->x;
ptAnchorOld.y=pScroller->GetAnchor()->y;
//move the anchor
pScroller->MoveAnchor(scrollx,scrolly);
//calculate the actual scrollx and scrolly
scrollx=pScroller->GetAnchor()->x-ptAnchorOld.x;
scrolly=pScroller->GetAnchor()->y-ptAnchorOld.y;
//reset the anchor position
pScroller->GetAnchor()->x=ptAnchorOld.x;
pScroller->GetAnchor()->y=ptAnchorOld.y;
//rectangle for blitting
RECT rcSrc;//source RECT(frame buffer)
RECT rcDst;//destination RECT(back buffer)
RECT rcUpdateX;//update rect
RECT rcUpdateY;//update rect
//set both rects to the screen space
CopyRect(&rcSrc,pScroller->GetScreenSpace());
CopyRect(&rcDst,pScroller->GetScreenSpace());
//set both update rects empty
SetRectEmpty(&rcUpdateX);
SetRectEmpty(&rcUpdateY);
//check the sign of scrollx
//if scrollx is 0, we need do nothing
if(scrollx)
{
//scrollx is non-zero
if(scrollx<0)
{
//positive scrollx
//scroll direction: to the right
//set up an update rect for the left side of the screen
SetRect(&rcUpdateX,rcDst.left,rcDst.top,rcDst.left-scrollx,rcDst.bottom);
//adjust the blitting rects
rcDst.left-=scrollx;
rcSrc.right+=scrollx;
}
else
{
//negative scrollx
//scroll direction: to the left
//set up an update rect for the right side of the screen
SetRect(&rcUpdateX,rcDst.right-scrollx,rcDst.top,rcDst.right,rcDst.bottom);
//adjust the blitting rects
rcDst.right-=scrollx;
rcSrc.left+=scrollx;
}
}
//check the sign of scrolly
//if scrolly is 0, we need do nothing
if(scrolly)
{
//scrolly is non-zero
if(scrolly<0)
{
//negative scrolly
//scroll direction: down
//set and update rect for the top of the screen
SetRect(&rcUpdateY,rcDst.left,rcDst.top,rcDst.right,rcDst.top-scrolly);
//adjust the blitting rects
rcDst.top-=scrolly;
rcSrc.bottom+=scrolly;
}
else
{
//positive scrolly
//scroll direction: up
//set an update rect for the bottom of the screen
SetRect(&rcUpdateY,rcDst.left,rcDst.bottom-scrolly,rcDst.right,rcDst.bottom);
//adjust the blitting rects
rcDst.bottom-=scrolly;
rcSrc.top+=scrolly;
}
}
//perform the blit(bulk scrolling)
lpddsBackBuffer->BltFast(rcDst.left,rcDst.top,lpddsFrameBuffer,&rcSrc,DDBLTFAST_WAIT);
//perform the scroll
pScroller->MoveAnchor(scrollx,scrolly);
//add the update rects
AddRect(&rcUpdateX);
AddRect(&rcUpdateY);
}
//update the frame
void CRenderer::UpdateFrame()
{
//update rect
RECT rcUpdate;
//copy from screenspace
CopyRect(&rcUpdate,pScroller->GetScreenSpace());
//temp variables for calculations
POINT ptTemp;
POINT ptCoarse;
POINT ptMap;
POINT ptPlot;
//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(;;)
{
//plot the tile
ptPlot=pTilePlotter->PlotTile(ptCurrent);
ptPlot=pScroller->WorldToScreen(ptPlot);
//check that ptcurrent is an actual map location
if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
{
//is the tile marked?
if(bMap[ptCurrent.x+ptCurrent.y*iMapWidth])
{
//send to rendering function
RenderFunction(lpddsFrameBuffer,&rcUpdate,ptPlot.x,ptPlot.y,ptCurrent.x,ptCurrent.y);
//rest to unmarked
bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=false;
}
}
//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++;
}
//render all update rects from frame buffer to back buffer
for(int iCount=0;iCount<iUpdateRectIndex;iCount++)
{
//render update rect
lpddsBackBuffer->BltFast(rcUpdateList[iCount].left,rcUpdateList[iCount].top,lpddsFrameBuffer,&rcUpdateList[iCount],DDBLTFAST_WAIT);
}
//render from back buffer to frame buffer
lpddsFrameBuffer->BltFast(rcUpdate.left,rcUpdate.top,lpddsBackBuffer,&rcUpdate,DDBLTFAST_WAIT);
//set rectangle index to 0
iUpdateRectIndex=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -