mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
World view mode drawing: refactoring, part 2 (further merging of common functionalities; abstracted puzzle view to separate blitter);
This commit is contained in:
parent
97d89d1d6c
commit
01029779d7
@ -188,10 +188,7 @@ void CMapHandler::prepareFOWDefs()
|
||||
void CMapHandler::drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info)
|
||||
{
|
||||
assert(info);
|
||||
if (info->scaled)
|
||||
worldViewBlitter->blit(targetSurface, info);
|
||||
else
|
||||
normalBlitter->blit(targetSurface, info);
|
||||
resolveBlitter(info)->blit(targetSurface, info);
|
||||
}
|
||||
|
||||
void CMapHandler::roadsRiverTerrainInit()
|
||||
@ -422,147 +419,49 @@ void CMapHandler::init()
|
||||
|
||||
}
|
||||
|
||||
void CMapHandler::calculateWorldViewCameraPos(int targetTilesX, int targetTilesY, int3 &tile)
|
||||
CMapHandler::CMapBlitter *CMapHandler::resolveBlitter(const MapDrawingInfo * info) const
|
||||
{
|
||||
bool outsideLeft = tile.x < 0;
|
||||
bool outsideTop = tile.y < 0;
|
||||
bool outsideRight = std::max(0, tile.x) + targetTilesX > sizes.x;
|
||||
bool outsideBottom = std::max(0, tile.y) + targetTilesY > sizes.y;
|
||||
if (info->scaled)
|
||||
return worldViewBlitter;
|
||||
if (info->puzzleMode)
|
||||
return puzzleViewBlitter;
|
||||
|
||||
if (targetTilesX > sizes.x)
|
||||
tile.x = sizes.x / 2 - targetTilesX / 2; // center viewport if the whole map can fit into the screen at once
|
||||
else if (outsideLeft)
|
||||
{
|
||||
if (outsideRight)
|
||||
tile.x = sizes.x / 2 - targetTilesX / 2;
|
||||
else
|
||||
tile.x = 0;
|
||||
}
|
||||
else if (outsideRight)
|
||||
tile.x = sizes.x - targetTilesX;
|
||||
|
||||
if (targetTilesY > sizes.y)
|
||||
tile.y = sizes.y / 2 - targetTilesY / 2;
|
||||
else if (outsideTop)
|
||||
{
|
||||
if (outsideBottom)
|
||||
tile.y = sizes.y / 2 - targetTilesY / 2;
|
||||
else
|
||||
tile.y = 0;
|
||||
}
|
||||
else if (outsideBottom)
|
||||
tile.y = sizes.y - targetTilesY;
|
||||
return normalBlitter;
|
||||
}
|
||||
|
||||
void CMapHandler::drawScaledRotatedElement(EMapCacheType type, SDL_Surface * baseSurf, SDL_Surface * targetSurf, ui8 rotation,
|
||||
float scale, SDL_Rect * dstRect, SDL_Rect * srcRect /*= nullptr*/)
|
||||
void CMapHandler::CMapNormalBlitter::drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit, ui8 rotationInfo) const
|
||||
{
|
||||
auto key = cache.genKey((intptr_t)baseSurf, rotation);
|
||||
auto scaledSurf = cache.requestWorldViewCache(type, key);
|
||||
if (scaledSurf) // blitting from cache
|
||||
if (rotationInfo != 0)
|
||||
{
|
||||
if (srcRect)
|
||||
if (!sourceRect)
|
||||
{
|
||||
dstRect->w = srcRect->w;
|
||||
dstRect->h = srcRect->h;
|
||||
Rect sourceRect2(0, 0, sourceSurf->w, sourceSurf->h);
|
||||
if (alphaBlit)
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)(sourceSurf, sourceRect2, targetSurf, *destRect, rotationInfo);
|
||||
else
|
||||
CSDL_Ext::getBlitterWithRotation(targetSurf)(sourceSurf, sourceRect2, targetSurf, *destRect, rotationInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alphaBlit)
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)(sourceSurf, *sourceRect, targetSurf, *destRect, rotationInfo);
|
||||
else
|
||||
CSDL_Ext::getBlitterWithRotation(targetSurf)(sourceSurf, *sourceRect, targetSurf, *destRect, rotationInfo);
|
||||
}
|
||||
CSDL_Ext::blitSurface(scaledSurf, srcRect, targetSurf, dstRect);
|
||||
}
|
||||
else // creating new
|
||||
{
|
||||
auto baseSurfRotated = CSDL_Ext::newSurface(baseSurf->w, baseSurf->h);
|
||||
if (!baseSurfRotated)
|
||||
return;
|
||||
Rect baseRect(0, 0, baseSurf->w, baseSurf->h);
|
||||
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)(baseSurf, baseRect, baseSurfRotated, baseRect, rotation);
|
||||
|
||||
SDL_Surface * scaledSurf2 = CSDL_Ext::scaleSurfaceFast(baseSurfRotated, baseSurf->w * scale, baseSurf->h * scale);
|
||||
|
||||
CSDL_Ext::blitSurface(scaledSurf2, srcRect, targetSurf, dstRect);
|
||||
cache.cacheWorldViewEntry(type, key, scaledSurf2);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawNormalObject(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect)
|
||||
{
|
||||
Rect dstRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(sourceSurf, sourceRect, targetSurf,&dstRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawHeroFlag(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving)
|
||||
{
|
||||
CSDL_Ext::blitSurface(sourceSurf, sourceRect, targetSurf, destRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawHero(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving)
|
||||
{
|
||||
Rect dstRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(sourceSurf,sourceRect,targetSurf,&dstRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawRoad(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile * tinfoUpper)
|
||||
{
|
||||
if (tinfoUpper && tinfoUpper->roadType != ERoadType::NO_ROAD)
|
||||
{
|
||||
Rect source(0, tileSize / 2, tileSize, tileSize / 2);
|
||||
Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)
|
||||
(parent->roadDefs[tinfoUpper->roadType - 1]->ourImages[tinfoUpper->roadDir].bitmap, source, targetSurf, dest, (tinfoUpper->extTileFlags >> 4) % 4);
|
||||
}
|
||||
|
||||
if(tinfo.roadType != ERoadType::NO_ROAD) //print road from this tile
|
||||
{
|
||||
Rect source(0, 0, tileSize, tileSize);
|
||||
Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, tileSize / 2);
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)
|
||||
(parent->roadDefs[tinfo.roadType-1]->ourImages[tinfo.roadDir].bitmap, source, targetSurf, dest, (tinfo.extTileFlags >> 4) % 4);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawRiver(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo)
|
||||
{
|
||||
Rect srcRect(0, 0, tileSize, tileSize);
|
||||
Rect destRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)
|
||||
(parent->staticRiverDefs[tinfo.riverType-1]->ourImages[tinfo.riverDir].bitmap, srcRect, targetSurf, destRect, (tinfo.extTileFlags >> 2) % 4);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawFow(SDL_Surface * targetSurf, const MapDrawingInfo * info)
|
||||
{
|
||||
Rect destRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
std::pair<SDL_Surface *, bool> hide = parent->getVisBitmap(pos, *info->visibilityMap);
|
||||
if(hide.second)
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(hide.first, nullptr, targetSurf, &destRect);
|
||||
else
|
||||
CSDL_Ext::blitSurface(hide.first, nullptr, targetSurf, &destRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawFrame(SDL_Surface * targetSurf, const MapDrawingInfo * info)
|
||||
{
|
||||
SDL_Surface * src = parent->ttiles[pos.x][pos.y][topTile.z].terbitmap;
|
||||
assert(src);
|
||||
Rect dstRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::blitSurface(src, nullptr, targetSurf, &dstRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::drawTileTerrain(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile2 & tile)
|
||||
{
|
||||
Rect srcRect(0, 0, tileSize, tileSize);
|
||||
Rect dstRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
|
||||
if(tile.terbitmap) //if custom terrain graphic - use it
|
||||
{
|
||||
CSDL_Ext::blitSurface(tile.terbitmap, &srcRect, targetSurf, &dstRect);
|
||||
}
|
||||
else //use default terrain graphic
|
||||
{
|
||||
CSDL_Ext::getBlitterWithRotation(targetSurf)(parent->terrainGraphics[tinfo.terType][tinfo.terView], srcRect, targetSurf, dstRect, tinfo.extTileFlags % 4);
|
||||
if (alphaBlit)
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(sourceSurf, sourceRect, targetSurf, destRect);
|
||||
else
|
||||
CSDL_Ext::blitSurface(sourceSurf, sourceRect, targetSurf, destRect);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapNormalBlitter::init(const MapDrawingInfo * info)
|
||||
{ // Width and height of the portion of the map to process. Units in tiles.
|
||||
void CMapHandler::CMapNormalBlitter::init(const MapDrawingInfo * drawingInfo)
|
||||
{
|
||||
info = drawingInfo;
|
||||
// Width and height of the portion of the map to process. Units in tiles.
|
||||
tileCount.x = parent->tilesW;
|
||||
tileCount.y = parent->tilesH;
|
||||
|
||||
@ -570,6 +469,8 @@ void CMapHandler::CMapNormalBlitter::init(const MapDrawingInfo * info)
|
||||
initPos.x = parent->offsetX + info->drawBounds->x;
|
||||
initPos.y = parent->offsetY + info->drawBounds->y;
|
||||
|
||||
realTileRect = Rect(initPos.x, initPos.y, tileSize, tileSize);
|
||||
|
||||
// If moving, we need to add an extra column/line
|
||||
if (info->movement.x != 0)
|
||||
{
|
||||
@ -608,7 +509,7 @@ void CMapHandler::CMapNormalBlitter::init(const MapDrawingInfo * info)
|
||||
tileCount.y = parent->sizes.y + parent->frameH - topTile.y;
|
||||
}
|
||||
|
||||
SDL_Rect CMapHandler::CMapNormalBlitter::clip(SDL_Surface * targetSurf, const MapDrawingInfo * info)
|
||||
SDL_Rect CMapHandler::CMapNormalBlitter::clip(SDL_Surface * targetSurf) const
|
||||
{
|
||||
SDL_Rect prevClip;
|
||||
SDL_GetClipRect(targetSurf, &prevClip);
|
||||
@ -620,9 +521,90 @@ CMapHandler::CMapNormalBlitter::CMapNormalBlitter(CMapHandler * parent)
|
||||
: CMapBlitter(parent)
|
||||
{
|
||||
tileSize = 32;
|
||||
halfTileSizeCeil = 16;
|
||||
defaultTileRect = Rect(0, 0, tileSize, tileSize);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile2 & tile)
|
||||
void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
|
||||
{
|
||||
bool outsideLeft = topTile.x < 0;
|
||||
bool outsideTop = topTile.y < 0;
|
||||
bool outsideRight = std::max(0, topTile.x) + tileCount.x > parent->sizes.x;
|
||||
bool outsideBottom = std::max(0, topTile.y) + tileCount.y > parent->sizes.y;
|
||||
|
||||
if (tileCount.x > parent->sizes.x)
|
||||
topTile.x = parent->sizes.x / 2 - tileCount.x / 2; // center viewport if the whole map can fit into the screen at once
|
||||
else if (outsideLeft)
|
||||
{
|
||||
if (outsideRight)
|
||||
topTile.x = parent->sizes.x / 2 - tileCount.x / 2;
|
||||
else
|
||||
topTile.x = 0;
|
||||
}
|
||||
else if (outsideRight)
|
||||
topTile.x = parent->sizes.x - tileCount.x;
|
||||
|
||||
if (tileCount.y > parent->sizes.y)
|
||||
topTile.y = parent->sizes.y / 2 - tileCount.y / 2;
|
||||
else if (outsideTop)
|
||||
{
|
||||
if (outsideBottom)
|
||||
topTile.y = parent->sizes.y / 2 - tileCount.y / 2;
|
||||
else
|
||||
topTile.y = 0;
|
||||
}
|
||||
else if (outsideBottom)
|
||||
topTile.y = parent->sizes.y - tileCount.y;
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawScaledRotatedElement(EMapCacheType type, SDL_Surface * baseSurf, SDL_Surface * targetSurf, ui8 rotation,
|
||||
float scale, SDL_Rect * dstRect, SDL_Rect * srcRect /*= nullptr*/) const
|
||||
{
|
||||
auto key = parent->cache.genKey((intptr_t)baseSurf, rotation);
|
||||
auto scaledSurf = parent->cache.requestWorldViewCache(type, key);
|
||||
if (scaledSurf) // blitting from cache
|
||||
{
|
||||
if (srcRect)
|
||||
{
|
||||
dstRect->w = srcRect->w;
|
||||
dstRect->h = srcRect->h;
|
||||
}
|
||||
CSDL_Ext::blitSurface(scaledSurf, srcRect, targetSurf, dstRect);
|
||||
}
|
||||
else // creating new
|
||||
{
|
||||
auto baseSurfRotated = CSDL_Ext::newSurface(baseSurf->w, baseSurf->h);
|
||||
if (!baseSurfRotated)
|
||||
return;
|
||||
Rect baseRect(0, 0, baseSurf->w, baseSurf->h);
|
||||
|
||||
CSDL_Ext::getBlitterWithRotationAndAlpha(targetSurf)(baseSurf, baseRect, baseSurfRotated, baseRect, rotation);
|
||||
|
||||
SDL_Surface * scaledSurf2 = CSDL_Ext::scaleSurfaceFast(baseSurfRotated, baseSurf->w * scale, baseSurf->h * scale);
|
||||
|
||||
CSDL_Ext::blitSurface(scaledSurf2, srcRect, targetSurf, dstRect);
|
||||
parent->cache.cacheWorldViewEntry(type, key, scaledSurf2);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit, ui8 rotationInfo) const
|
||||
{
|
||||
if (rotationInfo != 0)
|
||||
{
|
||||
drawScaledRotatedElement(cacheType, sourceSurf, targetSurf, rotationInfo, info->scale, destRect, sourceRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto scaledSurf = parent->cache.requestWorldViewCacheOrCreate(cacheType, (intptr_t) sourceSurf, sourceSurf, info->scale);
|
||||
|
||||
if (alphaBlit)
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf, sourceRect, targetSurf, destRect);
|
||||
else
|
||||
CSDL_Ext::blitSurface(scaledSurf, sourceRect, targetSurf, destRect);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
|
||||
{
|
||||
auto & objects = tile.objects;
|
||||
for(auto & object : objects)
|
||||
@ -686,97 +668,47 @@ void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawNormalObject(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect)
|
||||
void CMapHandler::CMapWorldViewBlitter::drawNormalObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect) const
|
||||
{
|
||||
auto scaledSurf = parent->cache.requestWorldViewCacheOrCreate(EMapCacheType::OBJECTS, (intptr_t)sourceSurf, sourceSurf, info->scale);
|
||||
Rect tempSrc = Rect(sourceRect->x * info->scale, sourceRect->y * info->scale, tileSize, tileSize);
|
||||
Rect tempDst = Rect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf, &tempSrc, targetSurf, &tempDst);
|
||||
Rect scaledSourceRect(sourceRect->x * info->scale, sourceRect->y * info->scale, tileSize, tileSize);
|
||||
CMapBlitter::drawNormalObject(targetSurf, sourceSurf, &scaledSourceRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawHeroFlag(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving)
|
||||
void CMapHandler::CMapWorldViewBlitter::drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const
|
||||
{
|
||||
if (moving)
|
||||
return;
|
||||
|
||||
auto scaledSurf = parent->cache.requestWorldViewCacheOrCreate(EMapCacheType::HERO_FLAGS, (intptr_t)sourceSurf, sourceSurf, info->scale);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf, nullptr, targetSurf, destRect);
|
||||
CMapBlitter::drawHeroFlag(targetSurf, sourceSurf, sourceRect, destRect, false);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawHero(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving)
|
||||
void CMapHandler::CMapWorldViewBlitter::drawHero(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const
|
||||
{
|
||||
if (moving)
|
||||
return;
|
||||
auto scaledSurf = parent->cache.requestWorldViewCacheOrCreate(EMapCacheType::HEROES, (intptr_t)sourceSurf, sourceSurf, info->scale);
|
||||
Rect srcRect(sourceRect->x * info->scale, sourceRect->y * info->scale, sourceRect->w, sourceRect->h);
|
||||
Rect dstRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf,&srcRect,targetSurf,&dstRect);
|
||||
Rect scaledSourceRect(sourceRect->x * info->scale, sourceRect->y * info->scale, sourceRect->w, sourceRect->h);
|
||||
CMapBlitter::drawHero(targetSurf, sourceSurf, &scaledSourceRect, false);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawRoad(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile * tinfoUpper)
|
||||
{
|
||||
//Roads are shifted by 16 pixels to bottom. We have to draw both parts separately
|
||||
if (tinfoUpper && tinfoUpper->roadType != ERoadType::NO_ROAD)
|
||||
{
|
||||
Rect source(0, tileSize / 2, tileSize, tileSize / 2);
|
||||
Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
|
||||
auto baseSurf = parent->roadDefs[tinfoUpper->roadType - 1]->ourImages[tinfoUpper->roadDir].bitmap;
|
||||
parent->drawScaledRotatedElement(EMapCacheType::ROADS, baseSurf, targetSurf, (tinfoUpper->extTileFlags >> 4) % 4, info->scale, &dest, &source);
|
||||
}
|
||||
|
||||
if(tinfo.roadType != ERoadType::NO_ROAD) //print road from this tile
|
||||
{
|
||||
Rect source(0, 0, tileSize, halfTargetTileSizeHigh);
|
||||
Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, halfTargetTileSizeHigh);
|
||||
auto baseSurf = parent->roadDefs[tinfo.roadType-1]->ourImages[tinfo.roadDir].bitmap;
|
||||
parent->drawScaledRotatedElement(EMapCacheType::ROADS, baseSurf, targetSurf, (tinfo.extTileFlags >> 4) % 4, info->scale, &dest, &source);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawRiver(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo)
|
||||
{
|
||||
auto baseSurf = parent->staticRiverDefs[tinfo.riverType-1]->ourImages[tinfo.riverDir].bitmap;
|
||||
Rect destRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
parent->drawScaledRotatedElement(EMapCacheType::RIVERS, baseSurf, targetSurf, (tinfo.extTileFlags >> 2) % 4, info->scale, &destRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawFow(SDL_Surface * targetSurf, const MapDrawingInfo * info)
|
||||
{
|
||||
Rect destRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
std::pair<SDL_Surface *, bool> hide = parent->getVisBitmap(pos, *info->visibilityMap);
|
||||
auto scaledSurf = parent->cache.requestWorldViewCacheOrCreate(EMapCacheType::FOW, (intptr_t)hide.first, hide.first, info->scale);
|
||||
if(hide.second)
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf, nullptr, targetSurf, &destRect);
|
||||
else
|
||||
CSDL_Ext::blitSurface(scaledSurf, nullptr, targetSurf, &destRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::drawTileTerrain(SDL_Surface * targetSurf, const MapDrawingInfo * info,
|
||||
const TerrainTile & tinfo, const TerrainTile2 & tile)
|
||||
void CMapHandler::CMapBlitter::drawTileTerrain(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile2 & tile) const
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
if(tile.terbitmap) //if custom terrain graphic - use it
|
||||
{
|
||||
auto scaledSurf = parent->cache.requestWorldViewCacheOrCreate(EMapCacheType::TERRAIN_CUSTOM, (intptr_t)tile.terbitmap, tile.terbitmap, info->scale);
|
||||
Rect destRect(realPos.x, realPos.y, scaledSurf->w, scaledSurf->h);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf, nullptr, targetSurf, &destRect);
|
||||
}
|
||||
drawElement(EMapCacheType::TERRAIN_CUSTOM, tile.terbitmap, nullptr, targetSurf, &destRect);
|
||||
else //use default terrain graphic
|
||||
{
|
||||
auto baseSurf = parent->terrainGraphics[tinfo.terType][tinfo.terView];
|
||||
Rect destRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
parent->drawScaledRotatedElement(EMapCacheType::TERRAIN, baseSurf, targetSurf, tinfo.extTileFlags % 4, info->scale, &destRect);
|
||||
}
|
||||
|
||||
drawElement(EMapCacheType::TERRAIN, parent->terrainGraphics[tinfo.terType][tinfo.terView],
|
||||
nullptr, targetSurf, &destRect, false, tinfo.extTileFlags % 4);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapWorldViewBlitter::init(const MapDrawingInfo * info)
|
||||
void CMapHandler::CMapWorldViewBlitter::init(const MapDrawingInfo * drawingInfo)
|
||||
{
|
||||
info = drawingInfo;
|
||||
parent->cache.updateWorldViewScale(info->scale);
|
||||
|
||||
topTile = info->topTile;
|
||||
tileSize = (int) floorf(32.0f * info->scale);
|
||||
halfTargetTileSizeHigh = (int)ceilf(tileSize / 2.0f);
|
||||
halfTileSizeCeil = (int)ceilf(tileSize / 2.0f);
|
||||
|
||||
tileCount.x = (int) ceilf((float)info->drawBounds->w / tileSize) + 1;
|
||||
tileCount.y = (int) ceilf((float)info->drawBounds->h / tileSize) + 1;
|
||||
@ -784,11 +716,14 @@ void CMapHandler::CMapWorldViewBlitter::init(const MapDrawingInfo * info)
|
||||
initPos.x = parent->offsetX + info->drawBounds->x;
|
||||
initPos.y = parent->offsetY + info->drawBounds->y;
|
||||
|
||||
parent->calculateWorldViewCameraPos(tileCount.x, tileCount.y, topTile);
|
||||
realTileRect = Rect(initPos.x, initPos.y, tileSize, tileSize);
|
||||
defaultTileRect = Rect(0, 0, tileSize, tileSize);
|
||||
|
||||
calculateWorldViewCameraPos();
|
||||
|
||||
}
|
||||
|
||||
SDL_Rect CMapHandler::CMapWorldViewBlitter::clip(SDL_Surface * targetSurf, const MapDrawingInfo * info)
|
||||
SDL_Rect CMapHandler::CMapWorldViewBlitter::clip(SDL_Surface * targetSurf) const
|
||||
{
|
||||
SDL_Rect prevClip;
|
||||
|
||||
@ -808,7 +743,68 @@ CMapHandler::CMapWorldViewBlitter::CMapWorldViewBlitter(CMapHandler * parent)
|
||||
{
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile2 & tile)
|
||||
void CMapHandler::CMapPuzzleViewBlitter::drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
|
||||
{
|
||||
CMapBlitter::drawObjects(targetSurf, tile);
|
||||
|
||||
// grail X mark
|
||||
if(pos.x == info->grailPos.x && pos.y == info->grailPos.y)
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(graphics->heroMoveArrows->ourImages[0].bitmap, nullptr, targetSurf, &destRect);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapPuzzleViewBlitter::postProcessing(SDL_Surface * targetSurf) const
|
||||
{
|
||||
CSDL_Ext::applyEffect(targetSurf, info->drawBounds, static_cast<int>(!ADVOPT.puzzleSepia));
|
||||
}
|
||||
|
||||
bool CMapHandler::CMapPuzzleViewBlitter::canDrawObject(const CGObjectInstance * obj) const
|
||||
{
|
||||
if (!CMapBlitter::canDrawObject(obj))
|
||||
return false;
|
||||
|
||||
//don't print flaggable objects in puzzle mode
|
||||
if (obj->isVisitable())
|
||||
return false;
|
||||
|
||||
if(std::find(unblittableObjects.begin(), unblittableObjects.end(), obj->ID) != unblittableObjects.end())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CMapHandler::CMapPuzzleViewBlitter::CMapPuzzleViewBlitter(CMapHandler * parent)
|
||||
: CMapNormalBlitter(parent)
|
||||
{
|
||||
unblittableObjects.push_back(Obj::HOLE);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawFrame(SDL_Surface * targetSurf) const
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
drawElement(EMapCacheType::FRAME, parent->ttiles[pos.x][pos.y][topTile.z].terbitmap, nullptr, targetSurf, &destRect);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawNormalObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect) const
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
drawElement(EMapCacheType::OBJECTS, sourceSurf, sourceRect, targetSurf, &destRect, true);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const
|
||||
{
|
||||
drawElement(EMapCacheType::HERO_FLAGS, sourceSurf, sourceRect, targetSurf, destRect, true);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawHero(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const
|
||||
{
|
||||
Rect dstRect(realTileRect);
|
||||
drawElement(EMapCacheType::HEROES, sourceSurf, sourceRect, targetSurf, &dstRect, true);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
|
||||
{
|
||||
auto & objects = tile.objects;
|
||||
for(auto & object : objects)
|
||||
@ -819,17 +815,9 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const MapDr
|
||||
if (!graphics->getDef(obj) && !obj->appearance.animationFile.empty())
|
||||
logGlobal->errorStream() << "Failed to load image " << obj->appearance.animationFile;
|
||||
|
||||
//checking if object has non-empty graphic on this tile
|
||||
if(obj->ID != Obj::HERO && !obj->coveringAt(pos.x, pos.y))
|
||||
if (!canDrawObject(obj))
|
||||
continue;
|
||||
|
||||
static const int notBlittedInPuzzleMode[] = {Obj::HOLE};
|
||||
|
||||
//don't print flaggable objects in puzzle mode
|
||||
if(info->puzzleMode && (obj->isVisitable() || std::find(notBlittedInPuzzleMode, notBlittedInPuzzleMode+1, obj->ID) != notBlittedInPuzzleMode+1)) //?
|
||||
continue;
|
||||
|
||||
|
||||
PlayerColor color = obj->tempOwner;
|
||||
|
||||
SDL_Rect pp = object.second;
|
||||
@ -893,17 +881,17 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const MapDr
|
||||
size_t gg;
|
||||
for(gg=0; gg<iv->size(); ++gg)
|
||||
{
|
||||
if((*iv)[gg].groupNumber==parent->getHeroFrameNum(dir, true))
|
||||
if((*iv)[gg].groupNumber == getHeroFrameNum(dir, true))
|
||||
{
|
||||
tb = (*iv)[gg+info->getHeroAnim()%IMGVAL].bitmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
drawHero(targetSurf, info, tb, &pp, true);
|
||||
drawHero(targetSurf, tb, &pp, true);
|
||||
|
||||
pp.y += IMGVAL * 2 - tileSize;
|
||||
Rect destRect(realPos.x, realPos.y - tileSize / 2, tileSize, tileSize);
|
||||
drawHeroFlag(targetSurf, info, (graphics->*flg)[color.getNum()]->ourImages[gg + info->getHeroAnim() % IMGVAL + 35].bitmap, &pp, &destRect, true);
|
||||
drawHeroFlag(targetSurf, (graphics->*flg)[color.getNum()]->ourImages[gg + info->getHeroAnim() % IMGVAL + 35].bitmap, &pp, &destRect, true);
|
||||
|
||||
}
|
||||
else //hero / boat stands still
|
||||
@ -911,13 +899,13 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const MapDr
|
||||
size_t gg;
|
||||
for(gg=0; gg < iv->size(); ++gg)
|
||||
{
|
||||
if((*iv)[gg].groupNumber==parent->getHeroFrameNum(dir, false))
|
||||
if((*iv)[gg].groupNumber == getHeroFrameNum(dir, false))
|
||||
{
|
||||
tb = (*iv)[gg].bitmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
drawHero(targetSurf, info, tb, &pp, false);
|
||||
drawHero(targetSurf, tb, &pp, false);
|
||||
|
||||
//printing flag
|
||||
if(flg
|
||||
@ -928,8 +916,8 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const MapDr
|
||||
if (dstRect.x - info->drawBounds->x > -tileSize * 2)
|
||||
{
|
||||
auto surf = (graphics->*flg)[color.getNum()]->ourImages
|
||||
[parent->getHeroFrameNum(dir, false) * 8 + (info->getHeroAnim() / 4) % IMGVAL].bitmap;
|
||||
drawHeroFlag(targetSurf, info, surf, nullptr, &dstRect, false);
|
||||
[getHeroFrameNum(dir, false) * 8 + (info->getHeroAnim() / 4) % IMGVAL].bitmap;
|
||||
drawHeroFlag(targetSurf, surf, nullptr, &dstRect, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -937,21 +925,54 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const MapDr
|
||||
else //blit normal object
|
||||
{
|
||||
const std::vector<Cimage> &ourImages = graphics->getDef(obj)->ourImages;
|
||||
SDL_Surface *bitmap = ourImages[(info->anim + parent->getPhaseShift(obj)) % ourImages.size()].bitmap;
|
||||
SDL_Surface *bitmap = ourImages[(info->anim + getPhaseShift(obj)) % ourImages.size()].bitmap;
|
||||
|
||||
//setting appropriate flag color
|
||||
if(color < PlayerColor::PLAYER_LIMIT || color==PlayerColor::NEUTRAL)
|
||||
CSDL_Ext::setPlayerColor(bitmap, color);
|
||||
|
||||
drawNormalObject(targetSurf, info, bitmap, &pp);
|
||||
drawNormalObject(targetSurf, bitmap, &pp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingInfo * const info)
|
||||
void CMapHandler::CMapBlitter::drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const
|
||||
{
|
||||
if (tinfoUpper && tinfoUpper->roadType != ERoadType::NO_ROAD)
|
||||
{
|
||||
Rect source(0, tileSize / 2, tileSize, tileSize / 2);
|
||||
Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
|
||||
drawElement(EMapCacheType::ROADS, parent->roadDefs[tinfoUpper->roadType - 1]->ourImages[tinfoUpper->roadDir].bitmap,
|
||||
&source, targetSurf, &dest, true, (tinfoUpper->extTileFlags >> 4) % 4);
|
||||
}
|
||||
|
||||
if(tinfo.roadType != ERoadType::NO_ROAD) //print road from this tile
|
||||
{
|
||||
Rect source(0, 0, tileSize, halfTileSizeCeil);
|
||||
Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, tileSize / 2);
|
||||
drawElement(EMapCacheType::ROADS, parent->roadDefs[tinfo.roadType - 1]->ourImages[tinfo.roadDir].bitmap,
|
||||
&source, targetSurf, &dest, true, (tinfo.extTileFlags >> 4) % 4);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawRiver(SDL_Surface * targetSurf, const TerrainTile & tinfo) const
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
drawElement(EMapCacheType::RIVERS, parent->staticRiverDefs[tinfo.riverType-1]->ourImages[tinfo.riverDir].bitmap,
|
||||
nullptr, targetSurf, &destRect, true, (tinfo.extTileFlags >> 2) % 4);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
std::pair<SDL_Surface *, bool> hide = getVisBitmap();
|
||||
drawElement(EMapCacheType::FOW, hide.first, nullptr, targetSurf, &destRect, hide.second);
|
||||
}
|
||||
|
||||
void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingInfo * info)
|
||||
{
|
||||
init(info);
|
||||
auto prevClip = clip(targetSurf, info);
|
||||
auto prevClip = clip(targetSurf);
|
||||
|
||||
pos = int3(0, 0, topTile.z);
|
||||
|
||||
@ -965,33 +986,22 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
||||
if (pos.y < 0 || pos.y >= parent->sizes.y)
|
||||
continue;
|
||||
|
||||
if (!info->puzzleMode)
|
||||
{
|
||||
const NeighborTilesInfo neighbors(pos, parent->sizes, *info->visibilityMap);
|
||||
if (!canDrawCurrentTile())
|
||||
continue;
|
||||
|
||||
if(neighbors.areAllHidden())
|
||||
continue;
|
||||
}
|
||||
realTileRect.x = realPos.x;
|
||||
realTileRect.y = realPos.y;
|
||||
|
||||
const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z];
|
||||
const TerrainTile & tinfo = parent->map->getTile(pos);
|
||||
const TerrainTile * tinfoUpper = pos.y > 0 ? &parent->map->getTile(int3(pos.x, pos.y - 1, pos.z)) : nullptr;
|
||||
|
||||
drawTileTerrain(targetSurf, info, tinfo, tile);
|
||||
drawTileTerrain(targetSurf, tinfo, tile);
|
||||
if (tinfo.riverType)
|
||||
drawRiver(targetSurf, info, tinfo);
|
||||
drawRoad(targetSurf, info, tinfo, tinfoUpper);
|
||||
drawRiver(targetSurf, tinfo);
|
||||
drawRoad(targetSurf, tinfo, tinfoUpper);
|
||||
|
||||
drawObjects(targetSurf, info, tile);
|
||||
|
||||
if(info->puzzleMode)
|
||||
{
|
||||
if(pos.x == info->grailPos.x && pos.y == info->grailPos.y)
|
||||
{
|
||||
Rect destRect(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(graphics->heroMoveArrows->ourImages[0].bitmap, nullptr, targetSurf, &destRect);
|
||||
}
|
||||
}
|
||||
drawObjects(targetSurf, tile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -999,20 +1009,23 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
||||
{
|
||||
for (realPos.y = initPos.y, pos.y = topTile.y; pos.y < topTile.y + tileCount.y; pos.y++, realPos.y += tileSize)
|
||||
{
|
||||
realTileRect.x = realPos.x;
|
||||
realTileRect.y = realPos.y;
|
||||
|
||||
if (pos.x < 0 || pos.x >= parent->sizes.x ||
|
||||
pos.y < 0 || pos.y >= parent->sizes.y)
|
||||
{
|
||||
drawFrame(targetSurf, info);
|
||||
drawFrame(targetSurf);
|
||||
}
|
||||
else
|
||||
{
|
||||
const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z];
|
||||
|
||||
if (!(*info->visibilityMap)[pos.x][pos.y][topTile.z] && !info->puzzleMode)
|
||||
drawFow(targetSurf, info);
|
||||
if (!(*info->visibilityMap)[pos.x][pos.y][topTile.z])
|
||||
drawFow(targetSurf);
|
||||
|
||||
// overlay needs to be drawn over fow, because of artifacts-aura-like spells
|
||||
drawTileOverlay(targetSurf, info, tile);
|
||||
drawTileOverlay(targetSurf, tile);
|
||||
|
||||
// drawDebugVisitables()
|
||||
if (settings["session"]["showBlock"].Bool())
|
||||
@ -1023,9 +1036,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
||||
if (!block)
|
||||
block = BitmapHandler::loadBitmap("blocked");
|
||||
|
||||
Rect sr(realPos.x, realPos.y, tileSize, tileSize);
|
||||
|
||||
CSDL_Ext::blitSurface(block, nullptr, targetSurf, &sr);
|
||||
CSDL_Ext::blitSurface(block, nullptr, targetSurf, &realTileRect);
|
||||
}
|
||||
}
|
||||
if (settings["session"]["showVisit"].Bool())
|
||||
@ -1036,8 +1047,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
||||
if (!visit)
|
||||
visit = BitmapHandler::loadBitmap("visitable");
|
||||
|
||||
Rect sr(realPos.x, realPos.y, tileSize, tileSize);
|
||||
CSDL_Ext::blitSurface(visit, nullptr, targetSurf, &sr);
|
||||
CSDL_Ext::blitSurface(visit, nullptr, targetSurf, &realTileRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1051,8 +1061,6 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
||||
{
|
||||
for (realPos.y = initPos.y, pos.y = topTile.y; pos.y < topTile.y + tileCount.y; pos.y++, realPos.y += tileSize)
|
||||
{
|
||||
SDL_Rect sr;
|
||||
|
||||
const int3 color(0x555555, 0x555555, 0x555555);
|
||||
|
||||
if (realPos.y >= info->drawBounds->y &&
|
||||
@ -1072,22 +1080,58 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
||||
}
|
||||
}
|
||||
|
||||
if(info->puzzleMode)
|
||||
{
|
||||
CSDL_Ext::applyEffect(targetSurf, info->drawBounds, static_cast<int>(!ADVOPT.puzzleSepia));
|
||||
}
|
||||
postProcessing(targetSurf);
|
||||
|
||||
SDL_SetClipRect(targetSurf, &prevClip);
|
||||
}
|
||||
|
||||
std::pair<SDL_Surface *, bool> CMapHandler::getVisBitmap( const int3 & pos, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap ) const
|
||||
ui8 CMapHandler::CMapBlitter::getPhaseShift(const CGObjectInstance *object) const
|
||||
{
|
||||
const NeighborTilesInfo info(pos,sizes,visibilityMap);
|
||||
auto i = parent->animationPhase.find(object);
|
||||
if(i == parent->animationPhase.end())
|
||||
{
|
||||
ui8 ret = CRandomGenerator::getDefault().nextInt(254);
|
||||
parent->animationPhase[object] = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int retBitmapID = info.getBitmapID();// >=0 -> partial hide, <0 - full hide
|
||||
return i->second;
|
||||
}
|
||||
|
||||
bool CMapHandler::CMapBlitter::canDrawObject(const CGObjectInstance * obj) const
|
||||
{
|
||||
//checking if object has non-empty graphic on this tile
|
||||
return obj->ID == Obj::HERO || obj->coveringAt(pos.x, pos.y);
|
||||
}
|
||||
|
||||
bool CMapHandler::CMapBlitter::canDrawCurrentTile() const
|
||||
{
|
||||
const NeighborTilesInfo neighbors(pos, parent->sizes, *info->visibilityMap);
|
||||
return !neighbors.areAllHidden();
|
||||
}
|
||||
|
||||
ui8 CMapHandler::CMapBlitter::getHeroFrameNum(ui8 dir, bool isMoving) const
|
||||
{
|
||||
if(isMoving)
|
||||
{
|
||||
static const ui8 frame [] = {0xff, 10, 5, 6, 7, 8, 9, 12, 11};
|
||||
return frame[dir];
|
||||
}
|
||||
else //if(isMoving)
|
||||
{
|
||||
static const ui8 frame [] = {0xff, 13, 0, 1, 2, 3, 4, 15, 14};
|
||||
return frame[dir];
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<SDL_Surface *, bool> CMapHandler::CMapBlitter::getVisBitmap() const
|
||||
{
|
||||
const NeighborTilesInfo neighborInfo(pos, parent->sizes, *info->visibilityMap);
|
||||
|
||||
int retBitmapID = neighborInfo.getBitmapID();// >=0 -> partial hide, <0 - full hide
|
||||
if (retBitmapID < 0)
|
||||
{
|
||||
retBitmapID = - hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden
|
||||
retBitmapID = - parent->hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden
|
||||
}
|
||||
|
||||
if (retBitmapID >= 0)
|
||||
@ -1170,20 +1214,6 @@ bool CMapHandler::removeObject(CGObjectInstance *obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
ui8 CMapHandler::getHeroFrameNum(ui8 dir, bool isMoving) const
|
||||
{
|
||||
if(isMoving)
|
||||
{
|
||||
static const ui8 frame [] = {0xff, 10, 5, 6, 7, 8, 9, 12, 11};
|
||||
return frame[dir];
|
||||
}
|
||||
else //if(isMoving)
|
||||
{
|
||||
static const ui8 frame [] = {0xff, 13, 0, 1, 2, 3, 4, 15, 14};
|
||||
return frame[dir];
|
||||
}
|
||||
}
|
||||
|
||||
void CMapHandler::validateRectTerr(SDL_Rect * val, const SDL_Rect * ext)
|
||||
{
|
||||
if(ext)
|
||||
@ -1322,6 +1352,7 @@ CMapHandler::CMapHandler()
|
||||
graphics->FoWpartialHide = nullptr;
|
||||
normalBlitter = new CMapNormalBlitter(this);
|
||||
worldViewBlitter = new CMapWorldViewBlitter(this);
|
||||
puzzleViewBlitter = new CMapPuzzleViewBlitter(this);
|
||||
}
|
||||
|
||||
void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terName )
|
||||
@ -1344,19 +1375,6 @@ void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terN
|
||||
out = CGI->generaltexth->terrainNames[t.terType];
|
||||
}
|
||||
|
||||
ui8 CMapHandler::getPhaseShift(const CGObjectInstance *object) const
|
||||
{
|
||||
auto i = animationPhase.find(object);
|
||||
if(i == animationPhase.end())
|
||||
{
|
||||
ui8 ret = CRandomGenerator::getDefault().nextInt(254);
|
||||
animationPhase[object] = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void CMapHandler::discardWorldViewCache()
|
||||
{
|
||||
cache.discardWorldViewCache();
|
||||
@ -1454,3 +1472,4 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
#include "../lib/int3.h"
|
||||
#include "gui/Geometries.h"
|
||||
#include "SDL.h"
|
||||
|
||||
/*
|
||||
@ -134,7 +135,7 @@ class CMapHandler
|
||||
{
|
||||
enum class EMapCacheType
|
||||
{
|
||||
TERRAIN, TERRAIN_CUSTOM, OBJECTS, ROADS, RIVERS, FOW, HEROES, HERO_FLAGS
|
||||
TERRAIN, TERRAIN_CUSTOM, OBJECTS, ROADS, RIVERS, FOW, HEROES, HERO_FLAGS, FRAME
|
||||
};
|
||||
|
||||
/// temporarily caches rescaled sdl surfaces for map world view redrawing
|
||||
@ -160,46 +161,81 @@ class CMapHandler
|
||||
class CMapBlitter
|
||||
{
|
||||
protected:
|
||||
CMapHandler * parent;
|
||||
int tileSize;
|
||||
int3 tileCount;
|
||||
int3 topTile;
|
||||
int3 initPos;
|
||||
int3 pos;
|
||||
int3 realPos;
|
||||
CMapHandler * parent; // ptr to enclosing map handler; generally for legacy reasons, probably could/should be refactored out of here
|
||||
int tileSize; // size of a tile drawn on map [in pixels]
|
||||
int halfTileSizeCeil; // half of the tile size, rounded up
|
||||
int3 tileCount; // number of tiles in current viewport
|
||||
int3 topTile; // top-left tile of the viewport
|
||||
int3 initPos; // starting drawing position [in pixels]
|
||||
int3 pos; // current position [in tiles]
|
||||
int3 realPos; // current position [in pixels]
|
||||
Rect realTileRect; // default rect based on current pos: [realPos.x, realPos.y, tileSize, tileSize]
|
||||
Rect defaultTileRect; // default rect based on 0: [0, 0, tileSize, tileSize]
|
||||
const MapDrawingInfo * info; // data for drawing passed from outside
|
||||
|
||||
virtual void drawTileOverlay(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile2 & tile) = 0;
|
||||
virtual void drawNormalObject(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect) = 0;
|
||||
virtual void drawHeroFlag(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) = 0;
|
||||
virtual void drawHero(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) = 0;
|
||||
void drawObjects(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile2 & tile);
|
||||
virtual void drawRoad(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) = 0;
|
||||
virtual void drawRiver(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo) = 0;
|
||||
virtual void drawFow(SDL_Surface * targetSurf, const MapDrawingInfo * info) = 0;
|
||||
virtual void drawFrame(SDL_Surface * targetSurf, const MapDrawingInfo * info) = 0;
|
||||
virtual void drawTileTerrain(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile2 & tile) = 0;
|
||||
virtual void init(const MapDrawingInfo * info) = 0;
|
||||
virtual SDL_Rect clip(SDL_Surface * targetSurf, const MapDrawingInfo * info) = 0;
|
||||
/// general drawing method, called internally by more specialized ones
|
||||
virtual void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
|
||||
SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const = 0;
|
||||
|
||||
// first drawing pass
|
||||
|
||||
/// draws terrain bitmap (or custom bitmap if applicable) on current tile
|
||||
virtual void drawTileTerrain(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile2 & tile) const;
|
||||
/// draws a river segment on current tile
|
||||
virtual void drawRiver(SDL_Surface * targetSurf, const TerrainTile & tinfo) const;
|
||||
/// draws a road segment on current tile
|
||||
virtual void drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const;
|
||||
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
|
||||
virtual void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const;
|
||||
/// current tile: draws non-hero object with given image/position
|
||||
virtual void drawNormalObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect) const;
|
||||
virtual void drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const;
|
||||
virtual void drawHero(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const;
|
||||
|
||||
// second drawing pass
|
||||
|
||||
/// current tile: draws overlay over the map, used to draw world view icons
|
||||
virtual void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const = 0;
|
||||
/// draws fog of war on current tile
|
||||
virtual void drawFow(SDL_Surface * targetSurf) const;
|
||||
/// draws map border frame on current position
|
||||
virtual void drawFrame(SDL_Surface * targetSurf) const;
|
||||
|
||||
// third drawing pass
|
||||
|
||||
/// custom post-processing, if needed (used by puzzle view)
|
||||
virtual void postProcessing(SDL_Surface * targetSurf) const {}
|
||||
|
||||
// misc methods
|
||||
|
||||
/// initializes frame-drawing (called at the start of every redraw)
|
||||
virtual void init(const MapDrawingInfo * drawingInfo) = 0;
|
||||
/// calculates clip region for map viewport
|
||||
virtual SDL_Rect clip(SDL_Surface * targetSurf) const = 0;
|
||||
|
||||
virtual ui8 getHeroFrameNum(ui8 dir, bool isMoving) const;
|
||||
///returns appropriate bitmap and info if alpha blitting is necessary
|
||||
virtual std::pair<SDL_Surface *, bool> getVisBitmap() const;
|
||||
virtual ui8 getPhaseShift(const CGObjectInstance *object) const;
|
||||
|
||||
virtual bool canDrawObject(const CGObjectInstance * obj) const;
|
||||
virtual bool canDrawCurrentTile() const;
|
||||
public:
|
||||
CMapBlitter(CMapHandler * p) : parent(p) {}
|
||||
virtual ~CMapBlitter(){}
|
||||
void blit(SDL_Surface * targetSurf, const MapDrawingInfo * const info);
|
||||
void blit(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
||||
|
||||
};
|
||||
|
||||
class CMapNormalBlitter : public CMapBlitter
|
||||
{
|
||||
protected:
|
||||
void drawTileOverlay(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile2 & tile) {}
|
||||
void drawNormalObject(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect);
|
||||
void drawHeroFlag(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving);
|
||||
void drawHero(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving);
|
||||
void drawRoad(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile * tinfoUpper);
|
||||
void drawRiver(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo);
|
||||
void drawFow(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
||||
void drawFrame(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
||||
void drawTileTerrain(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile2 & tile);
|
||||
void init(const MapDrawingInfo * info);
|
||||
SDL_Rect clip(SDL_Surface * targetSurf, const MapDrawingInfo * info) override;
|
||||
void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
|
||||
SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const override;
|
||||
|
||||
void drawTileOverlay(SDL_Surface * targetSurf,const TerrainTile2 & tile) const override {}
|
||||
void init(const MapDrawingInfo * info) override;
|
||||
SDL_Rect clip(SDL_Surface * targetSurf) const override;
|
||||
public:
|
||||
CMapNormalBlitter(CMapHandler * parent);
|
||||
virtual ~CMapNormalBlitter(){}
|
||||
@ -208,36 +244,47 @@ class CMapHandler
|
||||
class CMapWorldViewBlitter : public CMapBlitter
|
||||
{
|
||||
protected:
|
||||
int halfTargetTileSizeHigh;
|
||||
void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
|
||||
SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const override;
|
||||
|
||||
void drawTileOverlay(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile2 & tile);
|
||||
void drawNormalObject(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect);
|
||||
void drawHeroFlag(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving);
|
||||
void drawHero(SDL_Surface * targetSurf, const MapDrawingInfo * info, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving);
|
||||
void drawRoad(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile * tinfoUpper);
|
||||
void drawRiver(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo);
|
||||
void drawFow(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
||||
void drawFrame(SDL_Surface * targetSurf, const MapDrawingInfo * info) {}
|
||||
void drawTileTerrain(SDL_Surface * targetSurf, const MapDrawingInfo * info, const TerrainTile & tinfo, const TerrainTile2 & tile);
|
||||
void init(const MapDrawingInfo * info);
|
||||
SDL_Rect clip(SDL_Surface * targetSurf, const MapDrawingInfo * info) override;
|
||||
void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
|
||||
void drawNormalObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect) const override;
|
||||
void drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const override;
|
||||
void drawHero(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const;
|
||||
void drawFrame(SDL_Surface * targetSurf) const override {}
|
||||
void init(const MapDrawingInfo * info) override;
|
||||
SDL_Rect clip(SDL_Surface * targetSurf) const override;
|
||||
|
||||
ui8 getHeroFrameNum(ui8 dir, bool isMoving) const override { return 0u; }
|
||||
ui8 getPhaseShift(const CGObjectInstance *object) const override { return 0u; }
|
||||
|
||||
void drawScaledRotatedElement(EMapCacheType type, SDL_Surface * baseSurf, SDL_Surface * targetSurf, ui8 rotation,
|
||||
float scale, SDL_Rect * dstRect, SDL_Rect * srcRect = nullptr) const;
|
||||
void calculateWorldViewCameraPos();
|
||||
public:
|
||||
CMapWorldViewBlitter(CMapHandler * parent);
|
||||
virtual ~CMapWorldViewBlitter(){}
|
||||
};
|
||||
|
||||
// class CPuzzleViewBlitter : public CMapNormalBlitter
|
||||
// {
|
||||
// void drawFow(SDL_Surface * targetSurf, const MapDrawingInfo * info) {} // skipping FoW in puzzle view
|
||||
// };
|
||||
class CMapPuzzleViewBlitter : public CMapNormalBlitter
|
||||
{
|
||||
std::vector<int> unblittableObjects;
|
||||
|
||||
void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
|
||||
void drawFow(SDL_Surface * targetSurf) const override {} // skipping FoW in puzzle view
|
||||
void postProcessing(SDL_Surface * targetSurf) const override;
|
||||
bool canDrawObject(const CGObjectInstance * obj) const override;
|
||||
bool canDrawCurrentTile() const override { return true; }
|
||||
public:
|
||||
CMapPuzzleViewBlitter(CMapHandler * parent);
|
||||
};
|
||||
|
||||
CMapCache cache;
|
||||
CMapBlitter * normalBlitter;
|
||||
CMapBlitter * worldViewBlitter;
|
||||
CMapBlitter * puzzleViewBlitter;
|
||||
|
||||
void drawScaledRotatedElement(EMapCacheType type, SDL_Surface * baseSurf, SDL_Surface * targetSurf, ui8 rotation,
|
||||
float scale, SDL_Rect * dstRect, SDL_Rect * srcRect = nullptr);
|
||||
void calculateWorldViewCameraPos(int targetTilesX, int targetTilesY, int3 &top_tile);
|
||||
CMapBlitter * resolveBlitter(const MapDrawingInfo * info) const;
|
||||
public:
|
||||
PseudoV< PseudoV< PseudoV<TerrainTile2> > > ttiles; //informations about map tiles
|
||||
int3 sizes; //map size (x = width, y = height, z = number of levels)
|
||||
@ -271,9 +318,6 @@ public:
|
||||
CMapHandler(); //c-tor
|
||||
~CMapHandler(); //d-tor
|
||||
|
||||
std::pair<SDL_Surface *, bool> getVisBitmap(const int3 & pos, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap) const; //returns appropriate bitmap and info if alpha blitting is necessary
|
||||
ui8 getPhaseShift(const CGObjectInstance *object) const;
|
||||
|
||||
void getTerrainDescr(const int3 &pos, std::string & out, bool terName); //if tername == false => empty string when tile is clear
|
||||
CGObjectInstance * createObject(int id, int subid, int3 pos, int owner=254); //creates a new object with a certain id and subid
|
||||
bool printObject(const CGObjectInstance * obj); //puts appropriate things to ttiles, so obj will be visible on map
|
||||
@ -288,7 +332,6 @@ public:
|
||||
|
||||
void drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info);
|
||||
void updateWater();
|
||||
ui8 getHeroFrameNum(ui8 dir, bool isMoving) const; //terrainRect helper function
|
||||
void validateRectTerr(SDL_Rect * val, const SDL_Rect * ext); //terrainRect helper
|
||||
static ui8 getDir(const int3 & a, const int3 & b); //returns direction number in range 0 - 7 (0 is left top, clockwise) [direction: form a to b]
|
||||
|
||||
|
@ -209,7 +209,7 @@ public:
|
||||
void updateNextHero(const CGHeroInstance *h);
|
||||
|
||||
/// changes current adventure map mode; used to switch between default view and world view; scale is ignored if EAdvMapMode == NORMAL
|
||||
void changeMode(EAdvMapMode newMode, float newScale = 0.4f);
|
||||
void changeMode(EAdvMapMode newMode, float newScale = 0.36f);
|
||||
};
|
||||
|
||||
extern CAdvMapInt *adventureInt;
|
||||
|
Loading…
Reference in New Issue
Block a user