mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- fixed crash in hero window (#963)
- added unused for now image scaling algorithm
This commit is contained in:
		| @@ -1172,8 +1172,9 @@ void VCAI::buildStructure(const CGTownInstance * t) | ||||
| { | ||||
| 	using namespace EBuilding; | ||||
| 	//TODO make *real* town development system | ||||
| 	//TODO: faction-specific development | ||||
| 	//TODO: faction-specific development: use special buildings, build dwellings in better order, etc | ||||
| 	//TODO: build resource silo, defences when needed | ||||
| 	//Possible - allow "locking" on specific building (build prerequisites and then building itself) | ||||
|  | ||||
| 	//Set of buildings for different goals. Does not include any prerequisites. | ||||
| 	const int essential[] = {TAVERN, TOWN_HALL}; | ||||
| @@ -1190,8 +1191,8 @@ void VCAI::buildStructure(const CGTownInstance * t) | ||||
| 	if (tryBuildAnyStructure(t, std::vector<int>(essential, essential + ARRAY_COUNT(essential)))) | ||||
| 		return; | ||||
|  | ||||
| 	//we're running out of gold - try to build something gold-producing. Minimal amount can be tweaked | ||||
| 	if (currentRes[Res::GOLD] + income[Res::GOLD] < 5000) | ||||
| 	//we're running out of gold - try to build something gold-producing. Multiplier can be tweaked | ||||
| 	if (currentRes[Res::GOLD] < income[Res::GOLD] * 4) | ||||
| 		if (tryBuildNextStructure(t, std::vector<int>(goldSource, goldSource + ARRAY_COUNT(goldSource)))) | ||||
| 			return; | ||||
|  | ||||
| @@ -1221,7 +1222,7 @@ void VCAI::buildStructure(const CGTownInstance * t) | ||||
| 		return; | ||||
| 	if (tryBuildNextStructure(t, std::vector<int>(spells, spells + ARRAY_COUNT(spells)))) | ||||
| 		return; | ||||
| 	if (tryBuildNextStructure(t, std::vector<int>(extra, extra + ARRAY_COUNT(extra)))) | ||||
| 	if (tryBuildAnyStructure(t, std::vector<int>(extra, extra + ARRAY_COUNT(extra)))) | ||||
| 		return; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -210,9 +210,15 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals | ||||
| 		} | ||||
|  | ||||
| 		int serial = LOCPLINT->cb->getHeroSerial(curHero, false); | ||||
| 		if (listSelection && active) | ||||
| 			listSelection->deactivate(); | ||||
| 		delChildNUll(listSelection); | ||||
| 		if (serial >= 0) | ||||
| 		{ | ||||
| 			listSelection = new CPicture("HPSYYY", 612, 33 + serial * 54); | ||||
| 			if (active) | ||||
| 				listSelection->activate(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	//primary skills support | ||||
|   | ||||
| @@ -218,6 +218,21 @@ CMenuScreen::CMenuScreen(const JsonNode& configNode): | ||||
| 	if (!images.empty()) | ||||
| 		pos = images[0]->center(); | ||||
|  | ||||
| 	//Work in progress, move along | ||||
| 	/* | ||||
| 	clock_t startTime = clock(); | ||||
| 	if (!images.empty()) | ||||
| 	{ | ||||
| 		SDL_Surface * scaled = images[0]->bg; | ||||
| 		scaled = CSDL_Ext::scaleSurface(scaled, screen->w, screen->h); | ||||
| 		SDL_FreeSurface(images[0]->bg); | ||||
| 		images[0]->bg = scaled; | ||||
| 		images[0]->pos.w = scaled->w; | ||||
| 		images[0]->pos.h = scaled->h; | ||||
| 	} | ||||
| 	clock_t finishTime = clock(); | ||||
| 	tlog1<< "Image scaled in " << finishTime - startTime <<"\n"; | ||||
| */ | ||||
| 	//Hardcoded entry | ||||
| 	menuNameToEntry.push_back("credits"); | ||||
|  | ||||
|   | ||||
| @@ -6207,8 +6207,12 @@ void MoraleLuckBox::set(const IBonusBearer *node) | ||||
| 		imageName = morale ? "IMRL30": "ILCK30"; | ||||
| 	else | ||||
| 		imageName = morale ? "IMRL42" : "ILCK42"; | ||||
| 	if (image && active) | ||||
| 		image->deactivate(); | ||||
| 	delChildNUll(image); | ||||
| 	image = new CAnimImage(imageName, bonusValue + 3); | ||||
| 	if (active) | ||||
| 		image->activate(); | ||||
| 	image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1095,7 +1095,7 @@ void CSDL_Ext::applyEffectBpp( SDL_Surface * surf, const SDL_Rect * rect, int mo | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		throw std::runtime_error("Unsuppoerted efftct!"); | ||||
| 		throw std::runtime_error("Unsupported effect!"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1109,6 +1109,78 @@ void CSDL_Ext::applyEffect( SDL_Surface * surf, const SDL_Rect * rect, int mode | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<int bpp> | ||||
| void scaleSurfaceInternal(SDL_Surface *surf, SDL_Surface *ret) | ||||
| { | ||||
| 	const float factorX = float(surf->w - 1) / float(ret->w), | ||||
| 	            factorY = float(surf->h - 1) / float(ret->h); | ||||
|  | ||||
| 	for(int y = 0; y < ret->h; y++) | ||||
| 	{ | ||||
| 		for(int x = 0; x < ret->w; x++) | ||||
| 		{ | ||||
| 			//coordinates we want to interpolate | ||||
| 			float origX = x * factorX, | ||||
| 			      origY = y * factorY; | ||||
|  | ||||
| 			float x1 = floor(origX), x2 = floor(origX+1), | ||||
| 			      y1 = floor(origY), y2 = floor(origY+1); | ||||
| 			assert( x1 >= 0 && y1 >= 0 && x2 < surf->w && y2 < surf->h);//All pixels are in range | ||||
|  | ||||
| 			// Calculate weights of each source pixel | ||||
| 			float w11 = ((origX - x1) * (origY - y1)); | ||||
| 			float w12 = ((origX - x1) * (y2 - origY)); | ||||
| 			float w21 = ((x2 - origX) * (origY - y1)); | ||||
| 			float w22 = ((x2 - origX) * (y2 - origY)); | ||||
| 			assert( w11 + w12 + w21 + w22 > 0.99 && w11 + w12 + w21 + w22 < 1.01);//total weight is ~1.0 | ||||
|  | ||||
| 			// Get pointers to source pixels | ||||
| 			Uint8 *p11 = (Uint8*)surf->pixels + int(y1) * surf->pitch + int(x1) * bpp; | ||||
| 			Uint8 *p12 = p11 + bpp; | ||||
| 			Uint8 *p21 = p11 + surf->pitch; | ||||
| 			Uint8 *p22 = p21 + bpp; | ||||
| 			// Calculate resulting channels | ||||
| #define PX(X, PTR) Channels::px<bpp>::X.get(PTR) | ||||
| 			int resR = PX(r, p11) * w11 + PX(r, p12) * w12 + PX(r, p21) * w21 + PX(r, p22) * w22; | ||||
| 			int resG = PX(g, p11) * w11 + PX(g, p12) * w12 + PX(g, p21) * w21 + PX(g, p22) * w22; | ||||
| 			int resB = PX(b, p11) * w11 + PX(b, p12) * w12 + PX(b, p21) * w21 + PX(b, p22) * w22; | ||||
| 			int resA = PX(a, p11) * w11 + PX(a, p12) * w12 + PX(a, p21) * w21 + PX(a, p22) * w22; | ||||
| 			assert(resR < 256 && resG < 256 && resB < 256 && resA < 256); | ||||
| #undef PX | ||||
| 			Uint8 *dest = (Uint8*)ret->pixels + y * ret->pitch + x * bpp; | ||||
| 			Channels::px<bpp>::r.set(dest, resR); | ||||
| 			Channels::px<bpp>::g.set(dest, resG); | ||||
| 			Channels::px<bpp>::b.set(dest, resB); | ||||
| 			Channels::px<bpp>::a.set(dest, resA); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// scaling via bilinear interpolation algorithm. | ||||
| /// NOTE: best results are for scaling in range 50%...200% | ||||
| SDL_Surface * CSDL_Ext::scaleSurface(SDL_Surface *surf, int width, int height) | ||||
| { | ||||
| 	if (!surf || !width || !height) | ||||
| 		return nullptr; | ||||
| 	if (surf->format->palette) | ||||
| 	{ | ||||
| 		//it is possible implement but only to power of 2 sizes. May be needed for view world spells | ||||
| 		tlog0 << "scale surface error: Can't scale indexed surface!\n"; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	SDL_Surface *ret = newSurface(width, height, surf); | ||||
|  | ||||
| 	switch(surf->format->BytesPerPixel) | ||||
| 	{ | ||||
| 	case 2: scaleSurfaceInternal<2>(surf, ret); break; | ||||
| 	case 3: scaleSurfaceInternal<3>(surf, ret); break; | ||||
| 	case 4: scaleSurfaceInternal<4>(surf, ret); break; | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void CSDL_Ext::blitSurface( SDL_Surface * src, SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect ) | ||||
| { | ||||
| 	if (dst != screen) | ||||
|   | ||||
| @@ -174,6 +174,8 @@ namespace CSDL_Ext | ||||
| 	SDL_Surface * createSurfaceWithBpp(int width, int height); //create surface with give bits per pixels value | ||||
| 	void VflipSurf(SDL_Surface * surf); //fluipis given surface by vertical axis | ||||
|  | ||||
| 	SDL_Surface * scaleSurface(SDL_Surface *surf, int width, int height); | ||||
|  | ||||
| 	template<int bpp> | ||||
| 	void applyEffectBpp( SDL_Surface * surf, const SDL_Rect * rect, int mode ); | ||||
| 	void applyEffect(SDL_Surface * surf, const SDL_Rect * rect, int mode); //mode: 0 - sepia, 1 - grayscale | ||||
|   | ||||
		Reference in New Issue
	
	Block a user