浏览代码

fixes and cleanup

AlexVinS 9 年之前
父节点
当前提交
b248642468
共有 6 个文件被更改,包括 72 次插入331 次删除
  1. 24 22
      client/gui/CAnimation.cpp
  2. 1 1
      client/gui/CAnimation.h
  3. 21 216
      client/gui/SDL_Extensions.cpp
  4. 0 15
      client/gui/SDL_Extensions.h
  5. 21 63
      client/mapHandler.cpp
  6. 5 14
      client/mapHandler.h

+ 24 - 22
client/gui/CAnimation.cpp

@@ -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);
+	margins.y = fullSize.y - surf->h - margins.y;
 
+	//todo: modify in-place
+	SDL_Surface * flipped = CSDL_Ext::horizontalFlip(surf);
 	SDL_FreeSurface(surf);
-
 	surf = flipped;
-
-	margins.y = fullSize.y - surf->h - margins.y;
 }
 
 void SDLImage::verticalFlip()
 {
-	SDL_Surface * flipped = CSDL_Ext::verticalFlip(surf);
+	margins.x = fullSize.x - surf->w - margins.x;
 
+	//todo: modify in-place
+	SDL_Surface * flipped = CSDL_Ext::verticalFlip(surf);
 	SDL_FreeSurface(surf);
-
 	surf = flipped;
-
-	margins.x = fullSize.x - surf->w - margins.x;
 }
 
 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

+ 1 - 1
client/gui/CAnimation.h

@@ -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();

+ 21 - 216
client/gui/SDL_Extensions.cpp

@@ -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 )
 {

+ 0 - 15
client/gui/SDL_Extensions.h

@@ -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

+ 21 - 63
client/mapHandler.cpp

@@ -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)
-{
-	auto iter = data[(ui8)type].find(key);
-	if (iter == data[(ui8)type].end())
-		return nullptr;
-	return (*iter).second;
-}
-
-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)
+IImage * CMapHandler::CMapCache::requestWorldViewCacheOrCreate(CMapHandler::EMapCacheType type, const IImage * fullSurface)
 {
-	auto cached = requestWorldViewCache(type, key);
-	if (cached)
-		return cached;
-
-	auto scaled = fullSurface->scaleFast(scale);
+	intptr_t key = (intptr_t) fullSurface;
+	auto & cache = data[(ui8)type];
 
-	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)

+ 5 - 14
client/mapHandler.h

@@ -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: