Selaa lähdekoodia

Removed loading of images from file into SDL_Surface

Ivan Savenko 2 vuotta sitten
vanhempi
sitoutus
e14290fde0

+ 6 - 6
client/CMessage.cpp

@@ -64,7 +64,7 @@ namespace
 	std::array<std::unique_ptr<CAnimation>, PlayerColor::PLAYER_LIMIT_I> dialogBorders;
 	std::array<std::vector<std::shared_ptr<IImage>>, PlayerColor::PLAYER_LIMIT_I> piecesOfBox;
 
-	SDL_Surface * background = nullptr;//todo: should be CFilledTexture
+	std::shared_ptr<IImage> background;//todo: should be CFilledTexture
 }
 
 void CMessage::init()
@@ -84,27 +84,27 @@ void CMessage::init()
 		}
 	}
 
-	background = BitmapHandler::loadBitmap("DIBOXBCK.BMP");
+	background = IImage::createFromFile("DIBOXBCK.BMP");
 }
 
 void CMessage::dispose()
 {
 	for(auto & item : dialogBorders)
 		item.reset();
-	SDL_FreeSurface(background);
 }
 
 SDL_Surface * CMessage::drawDialogBox(int w, int h, PlayerColor playerColor)
 {
 	//prepare surface
 	SDL_Surface * ret = CSDL_Ext::newSurface(w,h);
-	for (int i=0; i<w; i+=background->w)//background
+	for (int i=0; i<w; i+=background->width())//background
 	{
-		for (int j=0; j<h; j+=background->h)
+		for (int j=0; j<h; j+=background->height())
 		{
-			CSDL_Ext::blitSurface(background, ret, Point(i,j));
+			background->draw(ret, i, j);
 		}
 	}
+
 	drawBorder(playerColor, ret, w, h);
 	return ret;
 }

+ 4 - 4
client/battle/BattleStacksController.cpp

@@ -89,10 +89,10 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
 	static const auto shifterNegative = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 0.2f, 0.2f );
 	static const auto shifterNeutral  = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 1.0f, 0.2f );
 
-	amountNormal->adjustPalette(shifterNormal);
-	amountPositive->adjustPalette(shifterPositive);
-	amountNegative->adjustPalette(shifterNegative);
-	amountEffNeutral->adjustPalette(shifterNeutral);
+	amountNormal->adjustPalette(shifterNormal, 0);
+	amountPositive->adjustPalette(shifterPositive, 0);
+	amountNegative->adjustPalette(shifterNegative, 0);
+	amountEffNeutral->adjustPalette(shifterNeutral, 0);
 
 	//Restore border color {255, 231, 132, 255} to its original state
 	amountNormal->resetPalette(26);

+ 1 - 1
client/battle/CreatureAnimation.cpp

@@ -345,7 +345,7 @@ void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter,
 		genSpecialPalette(SpecialPalette);
 
 		image->setSpecialPallete(SpecialPalette);
-		image->adjustPalette(shifter);
+		image->adjustPalette(shifter, 8);
 
 		canvas.draw(image, pos.topLeft(), Rect(0, 0, pos.w, pos.h));
 

+ 4 - 4
client/gui/CAnimation.cpp

@@ -108,7 +108,7 @@ public:
 	void verticalFlip() override;
 
 	void shiftPalette(int from, int howMany) override;
-	void adjustPalette(const ColorFilter & shifter) override;
+	void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) override;
 	void resetPalette(int colorID) override;
 	void resetPalette() override;
 
@@ -807,15 +807,15 @@ void SDLImage::shiftPalette(int from, int howMany)
 	}
 }
 
-void SDLImage::adjustPalette(const ColorFilter & shifter)
+void SDLImage::adjustPalette(const ColorFilter & shifter, size_t colorsToSkip)
 {
 	if(originalPalette == nullptr)
 		return;
 
 	SDL_Palette* palette = surf->format->palette;
 
-	// Note: here we skip the first 8 colors in the palette that predefined in H3Palette
-	for(int i = 8; i < palette->ncolors; i++)
+	// Note: here we skip first colors in the palette that are predefined in H3 images
+	for(int i = colorsToSkip; i < palette->ncolors; i++)
 	{
 		palette->colors[i] = shifter.shiftColor(originalPalette->colors[i]);
 	}

+ 1 - 1
client/gui/CAnimation.h

@@ -63,7 +63,7 @@ public:
 
 	//only indexed bitmaps, 16 colors maximum
 	virtual void shiftPalette(int from, int howMany) = 0;
-	virtual void adjustPalette(const ColorFilter & shifter) = 0;
+	virtual void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) = 0;
 	virtual void resetPalette(int colorID) = 0;
 	virtual void resetPalette() = 0;
 

+ 0 - 20
client/gui/SDL_Extensions.cpp

@@ -880,26 +880,6 @@ void CSDL_Ext::fillRect( SDL_Surface *dst, const Rect & dstrect, const SDL_Color
 	SDL_FillRect(dst, &newRect, sdlColor);
 }
 
-void CSDL_Ext::fillTexture(SDL_Surface *dst, SDL_Surface * src)
-{
-	SDL_Rect srcRect;
-	SDL_Rect dstRect;
-
-	SDL_GetClipRect(src, &srcRect);
-	SDL_GetClipRect(dst, &dstRect);
-
-	for (int y=dstRect.y; y < dstRect.y + dstRect.h; y+=srcRect.h)
-	{
-		for (int x=dstRect.x; x < dstRect.x + dstRect.w; x+=srcRect.w)
-		{
-			int xLeft = std::min<int>(srcRect.w, dstRect.x + dstRect.w - x);
-			int yLeft = std::min<int>(srcRect.h, dstRect.y + dstRect.h - y);
-			SDL_Rect currentDest{x, y, xLeft, yLeft};
-			SDL_BlitSurface(src, &srcRect, dst, &currentDest);
-		}
-	}
-}
-
 SDL_Color CSDL_Ext::makeColor(ui8 r, ui8 g, ui8 b, ui8 a)
 {
 	SDL_Color ret = {r, g, b, a};

+ 0 - 2
client/gui/SDL_Extensions.h

@@ -128,8 +128,6 @@ typedef void (*TColorPutterAlpha)(Uint8 *&ptr, const Uint8 & R, const Uint8 & G,
 
 	void fillSurface(SDL_Surface *dst, const SDL_Color & color);
 	void fillRect(SDL_Surface *dst, const Rect & dstrect, const SDL_Color & color);
-	//fill dest image with source texture.
-	void fillTexture(SDL_Surface *dst, SDL_Surface * sourceTexture);
 
 	void updateRect(SDL_Surface *surface, const Rect & rect);
 

+ 6 - 6
client/mapHandler.cpp

@@ -899,22 +899,22 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
 				{
 					if(parent->map->getTile(int3(pos.x, pos.y, pos.z)).blocked) //temporary hiding blocked positions
 					{
-						static SDL_Surface * block = nullptr;
+						static std::shared_ptr<IImage> block;
 						if (!block)
-							block = BitmapHandler::loadBitmap("blocked");
+							block = IImage::createFromFile("blocked");
 
-						CSDL_Ext::blitSurface(block, targetSurf, realTileRect.topLeft());
+						block->draw(targetSurf, realTileRect.x, realTileRect.y);
 					}
 				}
 				if (settings["session"]["showVisit"].Bool())
 				{
 					if(parent->map->getTile(int3(pos.x, pos.y, pos.z)).visitable) //temporary hiding visitable positions
 					{
-						static SDL_Surface * visit = nullptr;
+						static std::shared_ptr<IImage> visit;
 						if (!visit)
-							visit = BitmapHandler::loadBitmap("visitable");
+							visit = IImage::createFromFile("visitable");
 
-						CSDL_Ext::blitSurface(visit, targetSurf, realTileRect.topLeft());
+						visit->draw(targetSurf, realTileRect.x, realTileRect.y);
 					}
 				}
 			}

+ 8 - 13
client/widgets/AdventureMapClasses.cpp

@@ -23,6 +23,7 @@
 
 #include "../gui/CGuiHandler.h"
 #include "../gui/SDL_Pixels.h"
+#include "../gui/CAnimation.h"
 
 #include "../windows/InfoWindows.h"
 #include "../windows/CAdvmapInterface.h"
@@ -1168,9 +1169,9 @@ void CInGameConsole::refreshEnteredText()
 		statusbar->setEnteredText(enteredText);
 }
 
-CAdvMapPanel::CAdvMapPanel(SDL_Surface * bg, Point position)
-	: CIntObject(),
-	  background(bg)
+CAdvMapPanel::CAdvMapPanel(std::shared_ptr<IImage> bg, Point position)
+	: CIntObject()
+	, background(bg)
 {
 	defActions = 255;
 	recActions = 255;
@@ -1178,17 +1179,11 @@ CAdvMapPanel::CAdvMapPanel(SDL_Surface * bg, Point position)
 	pos.y += position.y;
 	if (bg)
 	{
-		pos.w = bg->w;
-		pos.h = bg->h;
+		pos.w = bg->width();
+		pos.h = bg->height();
 	}
 }
 
-CAdvMapPanel::~CAdvMapPanel()
-{
-	if (background)
-		SDL_FreeSurface(background);
-}
-
 void CAdvMapPanel::addChildColorableButton(std::shared_ptr<CButton> button)
 {
 	colorableButtons.push_back(button);
@@ -1206,7 +1201,7 @@ void CAdvMapPanel::setPlayerColor(const PlayerColor & clr)
 void CAdvMapPanel::showAll(SDL_Surface * to)
 {
 	if(background)
-		CSDL_Ext::blitAt(background, pos.x, pos.y, to);
+		background->draw(to, pos.x, pos.y);
 
 	CIntObject::showAll(to);
 }
@@ -1219,7 +1214,7 @@ void CAdvMapPanel::addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions)
 	addChild(obj.get(), false);
 }
 
-CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, SDL_Surface * bg, Point position, int spaceBottom, const PlayerColor &color)
+CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, std::shared_ptr<IImage> bg, Point position, int spaceBottom, const PlayerColor &color)
 	: CAdvMapPanel(bg, position), icons(_icons)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);

+ 4 - 4
client/widgets/AdventureMapClasses.h

@@ -35,6 +35,7 @@ class CComponent;
 class CHeroTooltip;
 class CTownTooltip;
 class CTextBox;
+class IImage;
 
 /// Base UI Element for hero\town lists
 class CList : public CIntObject
@@ -370,10 +371,9 @@ class CAdvMapPanel : public CIntObject
 	std::vector<std::shared_ptr<CButton>> colorableButtons;
 	std::vector<std::shared_ptr<CIntObject>> otherObjects;
 	/// the surface passed to this obj will be freed in dtor
-	SDL_Surface * background;
+	std::shared_ptr<IImage> background;
 public:
-	CAdvMapPanel(SDL_Surface * bg, Point position);
-	virtual ~CAdvMapPanel();
+	CAdvMapPanel(std::shared_ptr<IImage> bg, Point position);
 
 	void addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions = 0);
 	void addChildColorableButton(std::shared_ptr<CButton> button);
@@ -394,7 +394,7 @@ class CAdvMapWorldViewPanel : public CAdvMapPanel
 	std::shared_ptr<CFilledTexture> backgroundFiller;
 	std::shared_ptr<CAnimation> icons;
 public:
-	CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, SDL_Surface * bg, Point position, int spaceBottom, const PlayerColor &color);
+	CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, std::shared_ptr<IImage> bg, Point position, int spaceBottom, const PlayerColor &color);
 	virtual ~CAdvMapWorldViewPanel();
 
 	void addChildIcon(std::pair<int, Point> data, int indexOffset);

+ 7 - 7
client/widgets/Images.cpp

@@ -113,21 +113,21 @@ void CPicture::colorize(PlayerColor player)
 
 CFilledTexture::CFilledTexture(std::string imageName, Rect position):
     CIntObject(0, position.topLeft()),
-    texture(BitmapHandler::loadBitmap(imageName))
+	texture(IImage::createFromFile(imageName))
 {
 	pos.w = position.w;
 	pos.h = position.h;
 }
 
-CFilledTexture::~CFilledTexture()
-{
-	SDL_FreeSurface(texture);
-}
-
 void CFilledTexture::showAll(SDL_Surface *to)
 {
 	CSDL_Ext::CClipRectGuard guard(to, pos);
-	CSDL_Ext::fillTexture(to, texture);
+
+	for (int y=pos.top(); y < pos.bottom(); y+= texture->height())
+	{
+		for (int x=pos.left(); x < pos.right(); x+=texture->width())
+			texture->draw(to, x, y);
+	}
 }
 
 CAnimImage::CAnimImage(const std::string & name, size_t Frame, size_t Group, int x, int y, ui8 Flags):

+ 2 - 2
client/widgets/Images.h

@@ -68,11 +68,11 @@ public:
 /// area filled with specific texture
 class CFilledTexture : public CIntObject
 {
-	SDL_Surface * texture;
+	std::shared_ptr<IImage> texture;
 
 public:
 	CFilledTexture(std::string imageName, Rect position);
-	~CFilledTexture();
+
 	void showAll(SDL_Surface *to) override;
 };
 

+ 5 - 10
client/windows/CAdvmapInterface.cpp

@@ -566,10 +566,10 @@ CAdvMapInt::CAdvMapInt():
 	pos.h = screen->h;
 	strongInterest = true; // handle all mouse move events to prevent dead mouse move space in fullscreen mode
 	townList.onSelect = std::bind(&CAdvMapInt::selectionChanged,this);
-	bg = BitmapHandler::loadBitmap(ADVOPT.mainGraphic);
+	bg = IImage::createFromFile(ADVOPT.mainGraphic);
 	if(!ADVOPT.worldViewGraphic.empty())
 	{
-		bgWorldView = BitmapHandler::loadBitmap(ADVOPT.worldViewGraphic);
+		bgWorldView = IImage::createFromFile(ADVOPT.worldViewGraphic);
 	}
 	else
 	{
@@ -579,7 +579,7 @@ CAdvMapInt::CAdvMapInt():
 	if (!bgWorldView)
 	{
 		logGlobal->warn("bgWorldView not defined in resolution config; fallback to VWorld.bmp");
-		bgWorldView = BitmapHandler::loadBitmap("VWorld.bmp");
+		bgWorldView = IImage::createFromFile("VWorld.bmp");
 	}
 
 	worldViewIcons = std::make_shared<CAnimation>("VwSymbol");//todo: customize with ADVOPT
@@ -712,11 +712,6 @@ CAdvMapInt::CAdvMapInt():
 	addUsedEvents(MOVE);
 }
 
-CAdvMapInt::~CAdvMapInt()
-{
-	SDL_FreeSurface(bg);
-}
-
 void CAdvMapInt::fshowOverview()
 {
 	GH.pushIntT<CKingdomInterface>();
@@ -976,7 +971,7 @@ void CAdvMapInt::deactivate()
 
 void CAdvMapInt::showAll(SDL_Surface * to)
 {
-	blitAt(bg,0,0,to);
+	bg->draw(to, 0, 0);
 
 	if(state != INGAME)
 		return;
@@ -1507,7 +1502,7 @@ void CAdvMapInt::startHotSeatWait(PlayerColor Player)
 void CAdvMapInt::setPlayer(PlayerColor Player)
 {
 	player = Player;
-	graphics->blueToPlayersAdv(bg,player);
+	bg->playerColored(player);
 
 	panelMain->setPlayerColor(player);
 	panelWorldView->setPlayerColor(player);

+ 2 - 3
client/windows/CAdvmapInterface.h

@@ -132,7 +132,6 @@ class CAdvMapInt : public CIntObject
 
 public:
 	CAdvMapInt();
-	~CAdvMapInt();
 
 	int3 position; //top left corner of visible map part
 	PlayerColor player;
@@ -170,8 +169,8 @@ public:
 
 	WorldViewOptions worldViewOptions;
 
-	SDL_Surface * bg;
-	SDL_Surface * bgWorldView;
+	std::shared_ptr<IImage> bg;
+	std::shared_ptr<IImage> bgWorldView;
 	std::vector<std::shared_ptr<CAnimImage>> gems;
 	CMinimap minimap;
 	std::shared_ptr<CGStatusBar> statusbar;

+ 23 - 35
client/windows/CCastleInterface.cpp

@@ -24,6 +24,8 @@
 #include "../CPlayerInterface.h"
 #include "../Graphics.h"
 #include "../gui/CGuiHandler.h"
+#include "../gui/CAnimation.h"
+#include "../gui/ColorFilter.h"
 #include "../gui/SDL_Extensions.h"
 #include "../widgets/MiscWidgets.h"
 #include "../widgets/CComponent.h"
@@ -68,24 +70,16 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
 	}
 
 	if(!str->borderName.empty())
-		border = BitmapHandler::loadBitmap(str->borderName);
+		border = IImage::createFromFile(str->borderName);
 	else
 		border = nullptr;
 
 	if(!str->areaName.empty())
-		area = BitmapHandler::loadBitmap(str->areaName);
+		area = IImage::createFromFile(str->areaName);
 	else
 		area = nullptr;
 }
 
-CBuildingRect::~CBuildingRect()
-{
-	if(border)
-		SDL_FreeSurface(border);
-	if(area)
-		SDL_FreeSurface(area);
-}
-
 const CBuilding * CBuildingRect::getBuilding()
 {
 	if (!str->building)
@@ -127,7 +121,7 @@ void CBuildingRect::clickLeft(tribool down, bool previousState)
 {
 	if(previousState && getBuilding() && area && !down && (parent->selectedBuilding==this))
 	{
-		if(!CSDL_Ext::isTransparent(area, GH.getCursorPosition() - pos.topLeft())) //inside building image
+		if(!area->isTransparent(GH.getCursorPosition() - pos.topLeft())) //inside building image
 		{
 			auto building = getBuilding();
 			parent->buildingClicked(building->bid, building->subId, building->upgrade);
@@ -139,7 +133,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
 {
 	if((!area) || (!((bool)down)) || (this!=parent->selectedBuilding) || getBuilding() == nullptr)
 		return;
-	if( !CSDL_Ext::isTransparent(area, GH.getCursorPosition() - pos.topLeft()) ) //inside building image
+	if( !area->isTransparent(GH.getCursorPosition() - pos.topLeft()) ) //inside building image
 	{
 		BuildingID bid = getBuilding()->bid;
 		const CBuilding *bld = town->town->buildings.at(bid);
@@ -186,33 +180,27 @@ void CBuildingRect::show(SDL_Surface * to)
 		if(stateTimeCounter >= BUILD_ANIMATION_FINISHED_TIMEPOINT)
 		{
 			if(parent->selectedBuilding == this)
-				blitAtLoc(border,0,0,to);
+				border->draw(to, pos.x, pos.y);
 			return;
 		}
-		if(border->format->palette != nullptr)
-		{
-			// key colors in glowing border
-			SDL_Color c1 = {200, 200, 200, 255}; // x2
-			SDL_Color c2 = {120, 100,  60, 255}; // x0.5
-			SDL_Color c3 = {210, 180, 110, 255}; // x1
 
-			ui32 colorID = SDL_MapRGB(border->format, c3.r, c3.g, c3.b);
-			SDL_Color oldColor = border->format->palette->colors[colorID];
-			SDL_Color newColor;
+		auto darkBorder = ColorFilter::genRangeShifter(0.f, 0.f, 0.f, 0.5f, 0.5f, 0.5f );
+		auto lightBorder = ColorFilter::genRangeShifter(0.f, 0.f, 0.f, 2.0f, 2.0f, 2.0f );
+		auto baseBorder = ColorFilter::genEmptyShifter();
 
-			if (stateTimeCounter < BUILDING_WHITE_BORDER_TIMEPOINT)
-				newColor = multiplyColors(c1, c2, static_cast<double>(stateTimeCounter % stageDelay) / stageDelay);
-			else
-			if (stateTimeCounter < BUILDING_YELLOW_BORDER_TIMEPOINT)
-				newColor = multiplyColors(c2, c3, static_cast<double>(stateTimeCounter % stageDelay) / stageDelay);
-			else
-				newColor = oldColor;
+		float progress = float(stateTimeCounter % stageDelay) / stageDelay;
 
-			CSDL_Ext::setColors(border, &newColor, colorID, 1);
-			blitAtLoc(border, 0, 0, to);
-			CSDL_Ext::setColors(border, &oldColor, colorID, 1);
-		}
+		if (stateTimeCounter < BUILDING_WHITE_BORDER_TIMEPOINT)
+			border->adjustPalette(ColorFilter::genInterpolated(lightBorder, darkBorder, progress), 0);
+		else
+		if (stateTimeCounter < BUILDING_YELLOW_BORDER_TIMEPOINT)
+			border->adjustPalette(ColorFilter::genInterpolated(darkBorder, baseBorder, progress), 0);
+		else
+			border->adjustPalette(baseBorder, 0);
+
+		border->draw(to, pos.x, pos.y);
 	}
+
 	if(stateTimeCounter < BUILD_ANIMATION_FINISHED_TIMEPOINT)
 		stateTimeCounter += GH.mainFPSmng->getElapsedMilliseconds();
 }
@@ -224,7 +212,7 @@ void CBuildingRect::showAll(SDL_Surface * to)
 
 	CShowableAnim::showAll(to);
 	if(!active && parent->selectedBuilding == this && border)
-		blitAtLoc(border,0,0,to);
+		border->draw(to, pos.x, pos.y);
 }
 
 std::string CBuildingRect::getSubtitle()//hover text for building
@@ -256,7 +244,7 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 {
 	if(area && pos.isInside(sEvent.x, sEvent.y))
 	{
-		if(CSDL_Ext::isTransparent(area, GH.getCursorPosition() - pos.topLeft())) //hovered pixel is inside this building
+		if(area->isTransparent(GH.getCursorPosition() - pos.topLeft())) //hovered pixel is inside this building
 		{
 			if(parent->selectedBuilding == this)
 			{

+ 2 - 3
client/windows/CCastleInterface.h

@@ -56,13 +56,12 @@ public:
 	CCastleBuildings * parent;
 	const CGTownInstance * town;
 	const CStructure* str;
-	SDL_Surface* border;
-	SDL_Surface* area;
+	std::shared_ptr<IImage> border;
+	std::shared_ptr<IImage> area;
 
 	ui32 stateTimeCounter;//For building construction - current stage in animation
 
 	CBuildingRect(CCastleBuildings * Par, const CGTownInstance *Town, const CStructure *Str);
-	~CBuildingRect();
 	bool operator<(const CBuildingRect & p2) const;
 	void hover(bool on) override;
 	void clickLeft(tribool down, bool previousState) override;