1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

fixes and cleanup

This commit is contained in:
AlexVinS 2016-11-08 22:14:38 +03:00
parent a8a661b159
commit b248642468
6 changed files with 76 additions and 335 deletions

View File

@ -89,7 +89,7 @@ public:
void draw(SDL_Surface * where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override;
void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha=255) const override;
SDL_Surface * scaleFast(float scale) const override;
std::unique_ptr<IImage> scaleFast(float scale) const override;
void playerColored(PlayerColor player) override;
void setFlagColor(PlayerColor player) override;
@ -145,7 +145,7 @@ public:
void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override;
void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha=255) const override;
SDL_Surface * scaleFast(float scale) const override;
std::unique_ptr<IImage> scaleFast(float scale) const override;
void playerColored(PlayerColor player) override;
void setFlagColor(PlayerColor player) override;
@ -781,7 +781,7 @@ void SDLImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alpha
Rect sourceRect(0, 0, surf->w, surf->h);
Point destShift(0,0);
Point destShift(0, 0);
if(src)
{
@ -798,15 +798,12 @@ void SDLImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alpha
else
destShift = margins;
Rect destRect(margins.x, margins.y, surf->w, surf->h);
Rect destRect(destShift.x, destShift.y, surf->w, surf->h);
if(dest)
{
destRect = *dest;
destRect = destRect & Rect(destRect.x, destRect.y, sourceRect.w, sourceRect.h);
destRect += destShift;
destRect.x += dest->x;
destRect.y += dest->y;
}
if(surf->format->BitsPerPixel == 8)
@ -819,9 +816,8 @@ void SDLImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alpha
}
}
SDL_Surface * SDLImage::scaleFast(float scale) const
std::unique_ptr<IImage> SDLImage::scaleFast(float scale) const
{
//todo: margins
auto scaled = CSDL_Ext::scaleSurfaceFast(surf, surf->w * scale, surf->h * scale);
if (scaled->format && scaled->format->palette) // fix color keying, because SDL loses it at this point
@ -831,7 +827,15 @@ SDL_Surface * SDLImage::scaleFast(float scale) const
else
CSDL_Ext::setDefaultColorKey(scaled);//just in case
return scaled;
std::unique_ptr<SDLImage> ret = make_unique<SDLImage>(scaled, false);
ret->fullSize.x = (int) round((float)fullSize.x * scale);
ret->fullSize.y = (int) round((float)fullSize.y * scale);
ret->margins.x = (int) round((float)margins.x * scale);
ret->margins.y = (int) round((float)margins.y * scale);
return ret;
}
void SDLImage::playerColored(PlayerColor player)
@ -857,24 +861,22 @@ int SDLImage::height() const
void SDLImage::horizontalFlip()
{
SDL_Surface * flipped = CSDL_Ext::horizontalFlip(surf);
SDL_FreeSurface(surf);
surf = flipped;
margins.y = fullSize.y - surf->h - margins.y;
//todo: modify in-place
SDL_Surface * flipped = CSDL_Ext::horizontalFlip(surf);
SDL_FreeSurface(surf);
surf = flipped;
}
void SDLImage::verticalFlip()
{
SDL_Surface * flipped = CSDL_Ext::verticalFlip(surf);
SDL_FreeSurface(surf);
surf = flipped;
margins.x = fullSize.x - surf->w - margins.x;
//todo: modify in-place
SDL_Surface * flipped = CSDL_Ext::verticalFlip(surf);
SDL_FreeSurface(surf);
surf = flipped;
}
void SDLImage::shiftPalette(int from, int howMany)
@ -1000,13 +1002,13 @@ void CompImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alph
}
SDL_Surface * CompImage::scaleFast(float scale) const
std::unique_ptr<IImage> CompImage::scaleFast(float scale) const
{
//todo: CompImage::scaleFast
logAnim->error("CompImage::scaleFast is not implemented");
return CSDL_Ext::newSurface(width() * scale, height() * scale);
return nullptr;
}
#define CASEBPP(x,y) case x: BlitBlock<x,y>(type, size, data, dest, alpha); break

View File

@ -30,7 +30,7 @@ public:
virtual void draw(SDL_Surface * where, int posX = 0, int posY = 0, Rect * src = nullptr, ui8 alpha = 255) const=0;
virtual void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha = 255) const = 0;
virtual SDL_Surface * scaleFast(float scale) const = 0;
virtual std::unique_ptr<IImage> scaleFast(float scale) const = 0;
//decrease ref count, returns true if image can be deleted (refCount <= 0)
bool decreaseRef();

View File

@ -79,6 +79,10 @@ void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * dst)
SDL_Surface * CSDL_Ext::verticalFlip(SDL_Surface * toRot)
{
SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags);
SDL_LockSurface(ret);
SDL_LockSurface(toRot);
const int bpp = ret->format->BytesPerPixel;
char * src = reinterpret_cast<char *>(toRot->pixels);
@ -86,26 +90,29 @@ SDL_Surface * CSDL_Ext::verticalFlip(SDL_Surface * toRot)
for(int i=0; i<ret->h; i++)
{
char * srcPxl = src;
char * dstPxl = dst + ret->w * bpp;
//FIXME: optimization bugged
// if (bpp == 1)
// {
// // much faster for 8-bit surfaces (majority of our data)
// std::reverse_copy(src, src + toRot->pitch, dst);
// }
// else
// {
char * srcPxl = src;
char * dstPxl = dst + ret->w * bpp;
if (bpp == 1)
{
// much faster for 8-bit surfaces (majority of our data)
std::reverse_copy(src, src + ret->pitch, dst);
}
else
{
for(int j=0; j<ret->w; j++)
{
dstPxl -= bpp;
std::copy(srcPxl, srcPxl + bpp, dstPxl);
srcPxl += bpp;
}
}
// }
src += toRot->pitch;
dst += ret->pitch;
}
SDL_UnlockSurface(ret);
SDL_UnlockSurface(toRot);
return ret;
}
@ -113,6 +120,8 @@ SDL_Surface * CSDL_Ext::verticalFlip(SDL_Surface * toRot)
SDL_Surface * CSDL_Ext::horizontalFlip(SDL_Surface * toRot)
{
SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags);
SDL_LockSurface(ret);
SDL_LockSurface(toRot);
char * src = reinterpret_cast<char *>(toRot->pixels);
char * dst = reinterpret_cast<char *>(ret->pixels) + ret->h * ret->pitch;
@ -122,6 +131,8 @@ SDL_Surface * CSDL_Ext::horizontalFlip(SDL_Surface * toRot)
std::copy(src, src + toRot->pitch, dst);
src += toRot->pitch;
}
SDL_UnlockSurface(ret);
SDL_UnlockSurface(toRot);
return ret;
};
@ -171,180 +182,6 @@ void CSDL_Ext::alphaTransform(SDL_Surface *src)
SDL_SetColorKey(src, SDL_TRUE, 0);
}
static void prepareOutRect(SDL_Rect *src, SDL_Rect *dst, const SDL_Rect & clip_rect)
{
const int xoffset = std::max(clip_rect.x - dst->x, 0),
yoffset = std::max(clip_rect.y - dst->y, 0);
src->x += xoffset;
src->y += yoffset;
dst->x += xoffset;
dst->y += yoffset;
src->w = dst->w = std::max(0,std::min(dst->w - xoffset, clip_rect.x + clip_rect.w - dst->x));
src->h = dst->h = std::max(0,std::min(dst->h - yoffset, clip_rect.y + clip_rect.h - dst->y));
}
template<int bpp>
void CSDL_Ext::blitWithRotateClip(SDL_Surface *src,SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect, ui8 rotation)//srcRect is not used, works with 8bpp sources and 24bpp dests
{
if(!rotation)
{
CSDL_Ext::blitSurface(src, srcRect, dst, dstRect);
}
else
{
static void (*blitWithRotate[])(const SDL_Surface *, const SDL_Rect *, SDL_Surface *, const SDL_Rect *) = {blitWithRotate1<bpp>, blitWithRotate2<bpp>, blitWithRotate3<bpp>};
prepareOutRect(srcRect, dstRect, dst->clip_rect);
blitWithRotate[rotation-1](src, srcRect, dst, dstRect);
}
}
template<int bpp>
void CSDL_Ext::blitWithRotateClipVal( SDL_Surface *src,SDL_Rect srcRect, SDL_Surface * dst, SDL_Rect dstRect, ui8 rotation )
{
blitWithRotateClip<bpp>(src, &srcRect, dst, &dstRect, rotation);
}
template<int bpp>
void CSDL_Ext::blitWithRotateClipWithAlpha(SDL_Surface *src,SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect, ui8 rotation)//srcRect is not used, works with 8bpp sources and 24bpp dests
{
if(!rotation)
{
blit8bppAlphaTo24bpp(src, srcRect, dst, dstRect);
}
else
{
static void (*blitWithRotate[])(const SDL_Surface *, const SDL_Rect *, SDL_Surface *, const SDL_Rect *) = {blitWithRotate1WithAlpha<bpp>, blitWithRotate2WithAlpha<bpp>, blitWithRotate3WithAlpha<bpp>};
prepareOutRect(srcRect, dstRect, dst->clip_rect);
blitWithRotate[rotation-1](src, srcRect, dst, dstRect);
}
}
template<int bpp>
void CSDL_Ext::blitWithRotateClipValWithAlpha( SDL_Surface *src,SDL_Rect srcRect, SDL_Surface * dst, SDL_Rect dstRect, ui8 rotation )
{
blitWithRotateClipWithAlpha<bpp>(src, &srcRect, dst, &dstRect, rotation);
}
template<int bpp>
void CSDL_Ext::blitWithRotate1(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect)//srcRect is not used, works with 8bpp sources and 24/32 bpp dests
{
Uint8 *sp = getPxPtr(src, src->w - srcRect->w - srcRect->x, srcRect->y);
Uint8 *dporg = (Uint8 *)dst->pixels + dstRect->y*dst->pitch + (dstRect->x+dstRect->w)*bpp;
const SDL_Color * const colors = src->format->palette->colors;
for(int i=dstRect->h; i>0; i--, dporg += dst->pitch)
{
Uint8 *dp = dporg;
for(int j=dstRect->w; j>0; j--, sp++)
ColorPutter<bpp, -1>::PutColor(dp, colors[*sp]);
sp += src->w - dstRect->w;
}
}
template<int bpp>
void CSDL_Ext::blitWithRotate2(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect)//srcRect is not used, works with 8bpp sources and 24/32 bpp dests
{
Uint8 *sp = getPxPtr(src, srcRect->x, src->h - srcRect->h - srcRect->y);
Uint8 *dporg = (Uint8 *)dst->pixels + (dstRect->y + dstRect->h - 1)*dst->pitch + dstRect->x*bpp;
const SDL_Color * const colors = src->format->palette->colors;
for(int i=dstRect->h; i>0; i--, dporg -= dst->pitch)
{
Uint8 *dp = dporg;
for(int j=dstRect->w; j>0; j--, sp++)
ColorPutter<bpp, 1>::PutColor(dp, colors[*sp]);
sp += src->w - dstRect->w;
}
}
template<int bpp>
void CSDL_Ext::blitWithRotate3(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect)//srcRect is not used, works with 8bpp sources and 24/32 bpp dests
{
Uint8 *sp = (Uint8 *)src->pixels + (src->h - srcRect->h - srcRect->y)*src->pitch + (src->w - srcRect->w - srcRect->x);
Uint8 *dporg = (Uint8 *)dst->pixels +(dstRect->y + dstRect->h - 1)*dst->pitch + (dstRect->x+dstRect->w)*bpp;
const SDL_Color * const colors = src->format->palette->colors;
for(int i=dstRect->h; i>0; i--, dporg -= dst->pitch)
{
Uint8 *dp = dporg;
for(int j=dstRect->w; j>0; j--, sp++)
ColorPutter<bpp, -1>::PutColor(dp, colors[*sp]);
sp += src->w - dstRect->w;
}
}
template<int bpp>
void CSDL_Ext::blitWithRotate1WithAlpha(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect)//srcRect is not used, works with 8bpp sources and 24/32 bpp dests
{
Uint8 *sp = (Uint8 *)src->pixels + srcRect->y*src->pitch + (src->w - srcRect->w - srcRect->x);
Uint8 *dporg = (Uint8 *)dst->pixels + dstRect->y*dst->pitch + (dstRect->x+dstRect->w)*bpp;
const SDL_Color * const colors = src->format->palette->colors;
for(int i=dstRect->h; i>0; i--, dporg += dst->pitch)
{
Uint8 *dp = dporg;
for(int j=dstRect->w; j>0; j--, sp++)
{
if(*sp)
ColorPutter<bpp, -1>::PutColor(dp, colors[*sp]);
else
dp -= bpp;
}
sp += src->w - dstRect->w;
}
}
template<int bpp>
void CSDL_Ext::blitWithRotate2WithAlpha(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect)//srcRect is not used, works with 8bpp sources and 24/32 bpp dests
{
Uint8 *sp = (Uint8 *)src->pixels + (src->h - srcRect->h - srcRect->y)*src->pitch + srcRect->x;
Uint8 *dporg = (Uint8 *)dst->pixels + (dstRect->y + dstRect->h - 1)*dst->pitch + dstRect->x*bpp;
const SDL_Color * const colors = src->format->palette->colors;
for(int i=dstRect->h; i>0; i--, dporg -= dst->pitch)
{
Uint8 *dp = dporg;
for(int j=dstRect->w; j>0; j--, sp++)
{
if(*sp)
ColorPutter<bpp, 1>::PutColor(dp, colors[*sp]);
else
dp += bpp;
}
sp += src->w - dstRect->w;
}
}
template<int bpp>
void CSDL_Ext::blitWithRotate3WithAlpha(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect)//srcRect is not used, works with 8bpp sources and 24/32 bpp dests
{
Uint8 *sp = (Uint8 *)src->pixels + (src->h - srcRect->h - srcRect->y)*src->pitch + (src->w - srcRect->w - srcRect->x);
Uint8 *dporg = (Uint8 *)dst->pixels +(dstRect->y + dstRect->h - 1)*dst->pitch + (dstRect->x+dstRect->w)*bpp;
const SDL_Color * const colors = src->format->palette->colors;
for(int i=dstRect->h; i>0; i--, dporg -= dst->pitch)
{
Uint8 *dp = dporg;
for(int j=dstRect->w; j>0; j--, sp++)
{
if(*sp)
ColorPutter<bpp, -1>::PutColor(dp, colors[*sp]);
else
dp -= bpp;
}
sp += src->w - dstRect->w;
}
}
template<int bpp>
int CSDL_Ext::blit8bppAlphaTo24bppT(const SDL_Surface * src, const SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect)
{
@ -666,38 +503,6 @@ void CSDL_Ext::SDL_PutPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int
SDL_PutPixelWithoutRefresh(ekran, x, y, R, G, B, A);
}
BlitterWithRotationVal CSDL_Ext::getBlitterWithRotation(SDL_Surface *dest)
{
switch(dest->format->BytesPerPixel)
{
case 2: return blitWithRotateClipVal<2>;
case 3: return blitWithRotateClipVal<3>;
case 4: return blitWithRotateClipVal<4>;
default:
logGlobal->errorStream() << (int)dest->format->BitsPerPixel << " bpp is not supported!!!";
break;
}
assert(0);
return nullptr;
}
BlitterWithRotationVal CSDL_Ext::getBlitterWithRotationAndAlpha(SDL_Surface *dest)
{
switch(dest->format->BytesPerPixel)
{
case 2: return blitWithRotateClipValWithAlpha<2>;
case 3: return blitWithRotateClipValWithAlpha<3>;
case 4: return blitWithRotateClipValWithAlpha<4>;
default:
logGlobal->errorStream() << (int)dest->format->BitsPerPixel << " bpp is not supported!!!";
break;
}
assert(0);
return nullptr;
}
template<int bpp>
void CSDL_Ext::applyEffectBpp( SDL_Surface * surf, const SDL_Rect * rect, int mode )
{

View File

@ -185,21 +185,6 @@ namespace CSDL_Ext
Uint8 *getPxPtr(const SDL_Surface * const &srf, const int x, const int y);
TColorPutter getPutterFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1
TColorPutterAlpha getPutterAlphaFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1
BlitterWithRotationVal getBlitterWithRotation(SDL_Surface *dest);
BlitterWithRotationVal getBlitterWithRotationAndAlpha(SDL_Surface *dest);
template<int bpp> void blitWithRotateClip(SDL_Surface *src,SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect, ui8 rotation);//srcRect is not used, works with 8bpp sources and 24bpp dests preserving clip_rect
template<int bpp> void blitWithRotateClipVal(SDL_Surface *src,SDL_Rect srcRect, SDL_Surface * dst, SDL_Rect dstRect, ui8 rotation);//srcRect is not used, works with 8bpp sources and 24bpp dests preserving clip_rect
template<int bpp> void blitWithRotateClipWithAlpha(SDL_Surface *src,SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect, ui8 rotation);//srcRect is not used, works with 8bpp sources and 24bpp dests preserving clip_rect
template<int bpp> void blitWithRotateClipValWithAlpha(SDL_Surface *src,SDL_Rect srcRect, SDL_Surface * dst, SDL_Rect dstRect, ui8 rotation);//srcRect is not used, works with 8bpp sources and 24bpp dests preserving clip_rect
template<int bpp> void blitWithRotate1(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
template<int bpp> void blitWithRotate2(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
template<int bpp> void blitWithRotate3(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
template<int bpp> void blitWithRotate1WithAlpha(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
template<int bpp> void blitWithRotate2WithAlpha(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
template<int bpp> void blitWithRotate3WithAlpha(const SDL_Surface *src, const SDL_Rect * srcRect, SDL_Surface * dst, const SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
template<int bpp>
int blit8bppAlphaTo24bppT(const SDL_Surface * src, const SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect); //blits 8 bpp surface with alpha channel to 24 bpp surface

View File

@ -22,7 +22,6 @@
#include "../lib/CTownHandler.h"
#include "Graphics.h"
#include "../lib/mapping/CMap.h"
#include "CDefHandler.h"
#include "../lib/CConfigHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/GameConstants.h"
@ -538,12 +537,10 @@ void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
void CMapHandler::CMapWorldViewBlitter::drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const
{
SDL_Surface * scaledSurf = parent->cache.requestWorldViewCacheOrCreate(cacheType, (intptr_t) source, source, info->scale);
IImage * scaled = parent->cache.requestWorldViewCacheOrCreate(cacheType, source);
if(scaledSurf->format->BitsPerPixel == 8)
CSDL_Ext::blit8bppAlphaTo24bpp(scaledSurf, sourceRect, targetSurf, destRect);
else
CSDL_Ext::blitSurface(scaledSurf, sourceRect, targetSurf, destRect);
if(scaled)
scaled->draw(targetSurf, destRect, sourceRect);
}
void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
@ -813,7 +810,7 @@ void CMapHandler::CMapBlitter::drawRiver(SDL_Surface * targetSurf, const Terrain
{
Rect destRect(realTileRect);
ui8 rotation = (tinfo.extTileFlags >> 2) % 4;
drawElement(EMapCacheType::RIVERS, parent->riverImages[tinfo.riverType-1][tinfo.riverDir][rotation],nullptr, targetSurf, &destRect);
drawElement(EMapCacheType::RIVERS, parent->riverImages[tinfo.riverType-1][tinfo.riverDir][rotation], nullptr, targetSurf, &destRect);
}
void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
@ -1400,18 +1397,9 @@ void CMapHandler::discardWorldViewCache()
void CMapHandler::CMapCache::discardWorldViewCache()
{
for (auto & cache : data)
{
for (auto &cacheEntryPair : cache)
{
if (cacheEntryPair.second)
{
SDL_FreeSurface(cacheEntryPair.second);
}
}
for(auto & cache : data)
cache.clear();
}
logGlobal->debugStream() << "Discarded world view cache";
logAnim->debug("Discarded world view cache");
}
void CMapHandler::CMapCache::updateWorldViewScale(float scale)
@ -1421,53 +1409,23 @@ void CMapHandler::CMapCache::updateWorldViewScale(float scale)
worldViewCachedScale = scale;
}
SDL_Surface * CMapHandler::CMapCache::requestWorldViewCache(CMapHandler::EMapCacheType type, intptr_t key)
IImage * CMapHandler::CMapCache::requestWorldViewCacheOrCreate(CMapHandler::EMapCacheType type, const IImage * fullSurface)
{
auto iter = data[(ui8)type].find(key);
if (iter == data[(ui8)type].end())
return nullptr;
return (*iter).second;
}
intptr_t key = (intptr_t) fullSurface;
auto & cache = data[(ui8)type];
SDL_Surface * CMapHandler::CMapCache::requestWorldViewCacheOrCreate(CMapHandler::EMapCacheType type, intptr_t key, SDL_Surface * fullSurface, float scale)
{
auto cached = requestWorldViewCache(type, key);
if (cached)
return cached;
auto scaled = CSDL_Ext::scaleSurfaceFast(fullSurface, fullSurface->w * scale, fullSurface->h * scale);
if (scaled->format && scaled->format->palette) // fix color keying, because SDL loses it at this point
CSDL_Ext::setColorKey(scaled, scaled->format->palette->colors[0]);
return cacheWorldViewEntry(type, key, scaled);
}
SDL_Surface * CMapHandler::CMapCache::requestWorldViewCacheOrCreate(CMapHandler::EMapCacheType type, intptr_t key,const IImage * fullSurface, float scale)
{
auto cached = requestWorldViewCache(type, key);
if (cached)
return cached;
auto scaled = fullSurface->scaleFast(scale);
data[(ui8)type][key] = scaled;
return scaled;
}
SDL_Surface *CMapHandler::CMapCache::cacheWorldViewEntry(CMapHandler::EMapCacheType type, intptr_t key, SDL_Surface * entry)
{
if (!entry)
return nullptr;
if (requestWorldViewCache(type, key)) // valid cache already present, no need to do it again
return requestWorldViewCache(type, key);
data[(ui8)type][key] = entry;
return entry;
}
intptr_t CMapHandler::CMapCache::genKey(intptr_t realPtr, ui8 mod)
{
return (intptr_t)(realPtr ^ (mod << (sizeof(intptr_t) - 2))); // maybe some cleaner method to pack rotation into cache key?
auto iter = cache.find(key);
if(iter == cache.end())
{
auto scaled = fullSurface->scaleFast(worldViewCachedScale);
IImage * ret = scaled.get();
cache[key] = std::move(scaled);
return ret;
}
else
{
return (*iter).second.get();
}
}
bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b)

View File

@ -20,12 +20,9 @@ class CGObjectInstance;
class CGHeroInstance;
class CGBoat;
class CMap;
class CGDefInfo;
class CDefHandler;
struct TerrainTile;
struct SDL_Surface;
struct SDL_Rect;
class CDefEssential;
class CAnimation;
class IImage;
class CFadeAnimation;
@ -159,26 +156,21 @@ class CMapHandler
TERRAIN, OBJECTS, ROADS, RIVERS, FOW, HEROES, HERO_FLAGS, FRAME, AFTER_LAST
};
/// temporarily caches rescaled sdl surfaces for map world view redrawing
/// temporarily caches rescaled frames for map world view redrawing
class CMapCache
{
std::array< std::map<intptr_t, SDL_Surface *>, (ui8)EMapCacheType::AFTER_LAST> data;
std::array< std::map<intptr_t, std::unique_ptr<IImage>>, (ui8)EMapCacheType::AFTER_LAST> data;
float worldViewCachedScale;
public:
/// destroys all cached data (frees surfaces)
void discardWorldViewCache();
/// updates scale and determines if currently cached data is still valid
void updateWorldViewScale(float scale);
/// asks for cached data; @returns cached surface or nullptr if data is not in cache
SDL_Surface * requestWorldViewCache(EMapCacheType type, intptr_t key);
/// asks for cached data; @returns cached data if found, new scaled surface otherwise
SDL_Surface * requestWorldViewCacheOrCreate(EMapCacheType type, intptr_t key, SDL_Surface * fullSurface, float scale);
SDL_Surface * requestWorldViewCacheOrCreate(EMapCacheType type, intptr_t key, const IImage * fullSurface, float scale);
SDL_Surface * cacheWorldViewEntry(EMapCacheType type, intptr_t key, SDL_Surface * entry);
intptr_t genKey(intptr_t realPtr, ui8 mod);
/// asks for cached data; @returns cached data if found, new scaled surface otherwise, may return nullptr in case of scaling error
IImage * requestWorldViewCacheOrCreate(EMapCacheType type, const IImage * fullSurface);
};
/// helper struct to pass around resolved bitmaps of an object; surfaces can be nullptr if object doesn't have bitmap of that type
/// helper struct to pass around resolved bitmaps of an object; images can be nullptr if object doesn't have bitmap of that type
struct AnimBitmapHolder
{
IImage * objBitmap; // main object bitmap
@ -192,7 +184,6 @@ class CMapHandler
{}
};
class CMapBlitter
{
protected: