mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- background for main menu can be scaled. Won't work as default due to non-scalable video
This commit is contained in:
		| @@ -129,7 +129,8 @@ SDL_Surface * BitmapHandler::loadBitmapFromLod(CLodHandler *lod, std::string fna | ||||
| 	} | ||||
| 	if (!lod->haveFile(fname, FILE_GRAPHICS)) | ||||
| 	{ | ||||
| 		tlog2<<"Entry for file "<<fname<<" was not found"<<std::endl; | ||||
| 		//it is possible that this image will be found in another lod archive. Disabling this warning | ||||
| 		//tlog2<<"Entry for file "<<fname<<" was not found"<<std::endl; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -209,30 +209,22 @@ CMenuScreen::CMenuScreen(const JsonNode& configNode): | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
|  | ||||
| 	background = new CPicture(config["background"].String()); | ||||
| 	if (config["scalable"].Bool()) | ||||
| 	{ | ||||
| 		if (background->bg->format->palette) | ||||
| 			background->convertToScreenBPP(); | ||||
| 		background->scaleTo(Point(screen->w, screen->h)); | ||||
| 	} | ||||
|  | ||||
| 	pos = background->center(); | ||||
|  | ||||
| 	BOOST_FOREACH(const JsonNode& node, config["items"].Vector()) | ||||
| 		menuNameToEntry.push_back(node["name"].String()); | ||||
|  | ||||
| 	BOOST_FOREACH(const JsonNode& node, config["images"].Vector()) | ||||
| 		images.push_back(createPicture(node)); | ||||
|  | ||||
| 	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"); | ||||
|  | ||||
| @@ -358,13 +350,22 @@ CAdventureMapButton* CMenuEntry::createButton(CMenuScreen* parent, const JsonNod | ||||
| 	if (!button["help"].isNull() && button["help"].Float() > 0) | ||||
| 		help = CGI->generaltexth->zelp[button["help"].Float()]; | ||||
|  | ||||
| 	return new CAdventureMapButton(help, command, button["x"].Float(), button["y"].Float(), button["name"].String(), button["hotkey"].Float()); | ||||
| 	int posx = button["x"].Float(); | ||||
| 	if (posx < 0) | ||||
| 		posx = pos.w + posx; | ||||
|  | ||||
| 	int posy = button["y"].Float(); | ||||
| 	if (posy < 0) | ||||
| 		posy = pos.h + posy; | ||||
|  | ||||
| 	return new CAdventureMapButton(help, command, posx, posy, button["name"].String(), button["hotkey"].Float()); | ||||
| } | ||||
|  | ||||
| CMenuEntry::CMenuEntry(CMenuScreen* parent, const JsonNode &config) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	type |= REDRAW_PARENT; | ||||
| 	pos = parent->pos; | ||||
|  | ||||
| 	BOOST_FOREACH(const JsonNode& node, config["images"].Vector()) | ||||
| 		images.push_back(createPicture(node)); | ||||
|   | ||||
| @@ -51,6 +51,7 @@ class CMenuScreen : public CIntObject | ||||
|  | ||||
| 	CTabbedInt *tabs; | ||||
|  | ||||
| 	CPicture * background; | ||||
| 	std::vector<CPicture*> images; | ||||
|  | ||||
| 	CIntObject *createTab(size_t index); | ||||
|   | ||||
| @@ -70,6 +70,21 @@ CPicture::CPicture(SDL_Surface *BG, const Rect &SrcRect, int x /*= 0*/, int y /* | ||||
| 	freeSurf = free; | ||||
| } | ||||
|  | ||||
| void CPicture::setSurface(SDL_Surface *to) | ||||
| { | ||||
| 	bg = to; | ||||
| 	if (srcRect) | ||||
| 	{ | ||||
| 		pos.w = srcRect->w; | ||||
| 		pos.h = srcRect->h; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		pos.w = bg->w; | ||||
| 		pos.h = bg->h; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| CPicture::~CPicture() | ||||
| { | ||||
| 	if(freeSurf) | ||||
| @@ -115,6 +130,17 @@ void CPicture::convertToScreenBPP() | ||||
| 	SDL_FreeSurface(hlp); | ||||
| } | ||||
|  | ||||
| void CPicture::scaleTo(Point size) | ||||
| { | ||||
| 	SDL_Surface * scaled = CSDL_Ext::scaleSurface(bg, size.x, size.y); | ||||
|  | ||||
| 	if(freeSurf) | ||||
| 		SDL_FreeSurface(bg); | ||||
|  | ||||
| 	setSurface(scaled); | ||||
| 	freeSurf = false; | ||||
| } | ||||
|  | ||||
| void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color) | ||||
| { | ||||
| 	pos += r; | ||||
|   | ||||
| @@ -34,6 +34,7 @@ public: | ||||
| // Image class | ||||
| class CPicture : public CIntObject | ||||
| { | ||||
| 	void setSurface(SDL_Surface *to); | ||||
| public:  | ||||
| 	SDL_Surface * bg; | ||||
| 	Rect * srcRect; //if NULL then whole surface will be used | ||||
| @@ -53,6 +54,7 @@ public: | ||||
| 	~CPicture(); | ||||
| 	void init(); | ||||
|  | ||||
| 	void scaleTo(Point size); | ||||
| 	void createSimpleRect(const Rect &r, bool screenFormat, ui32 color); | ||||
| 	void show(SDL_Surface * to); | ||||
| 	void showAll(SDL_Surface * to); | ||||
|   | ||||
| @@ -1125,14 +1125,14 @@ void scaleSurfaceInternal(SDL_Surface *surf, SDL_Surface *ret) | ||||
|  | ||||
| 			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 | ||||
| 			//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 | ||||
| 			//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; | ||||
| @@ -1145,7 +1145,7 @@ void scaleSurfaceInternal(SDL_Surface *surf, SDL_Surface *ret) | ||||
| 			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); | ||||
| 			//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); | ||||
| @@ -1156,12 +1156,14 @@ void scaleSurfaceInternal(SDL_Surface *surf, SDL_Surface *ret) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// scaling via bilinear interpolation algorithm. | ||||
| /// NOTE: best results are for scaling in range 50%...200% | ||||
| // scaling via bilinear interpolation algorithm. | ||||
| // NOTE: best results are for scaling in range 50%...200%. | ||||
| // And upscaling looks awful right now - should be fixed somehow | ||||
| 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 | ||||
| @@ -1169,6 +1171,10 @@ SDL_Surface * CSDL_Ext::scaleSurface(SDL_Surface *surf, int width, int height) | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	//Same size? return copy - this should more be faster | ||||
| 	if (width == surf->w && height == surf->h) | ||||
| 		return copySurface(surf); | ||||
|  | ||||
| 	SDL_Surface *ret = newSurface(width, height, surf); | ||||
|  | ||||
| 	switch(surf->format->BytesPerPixel) | ||||
|   | ||||
| @@ -174,6 +174,7 @@ 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 | ||||
|  | ||||
| 	//scale surface to required size. Won't work with indexed surfaces | ||||
| 	SDL_Surface * scaleSurface(SDL_Surface *surf, int width, int height); | ||||
|  | ||||
| 	template<int bpp> | ||||
|   | ||||
| @@ -2,8 +2,10 @@ | ||||
| 	//Main menu window, consists of several sub-menus aka items | ||||
| 	"window": | ||||
| 	{ | ||||
| 		"background" : "ZPIC1005", | ||||
| 		//"scalable" : true, //background will be scaled to screen size | ||||
| 		"video" :    {"x": 8, "y": 105, "name":"ACREDIT.SMK" },//Floating WoG logo | ||||
| 		"images" : [ {"x": 0, "y": 0, "name":"ZPIC1005"} ],//Background image | ||||
| 		//"images" : [],//Optioal, contains any additional images in the same format as video | ||||
| 		"items" :  | ||||
| 		[ | ||||
| 			{ | ||||
| @@ -27,7 +29,7 @@ | ||||
| 					{"x": 545, "y": 358, "name":"ZTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"}, | ||||
| 					{"x": 582, "y": 464, "name":"ZTBACK",  "hotkey" : 27,  "help": 14, "command": "to main"} | ||||
| 				], | ||||
| 				"images": [ {"x": 114, "y": 312, "name":"ZNEWGAM"}	] | ||||
| 				"images": [ {"x": 114, "y": 312, "name":"ZNEWGAM"} ] | ||||
| 			}, | ||||
| 			{ | ||||
| 				"name" : "load", | ||||
| @@ -39,7 +41,7 @@ | ||||
| 					{"x": 545, "y": 358, "name":"ZTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"}, | ||||
| 					{"x": 582, "y": 464, "name":"ZTBACK",  "hotkey" : 27,  "help": 14, "command": "to main"} | ||||
| 				], | ||||
| 				"images": [ {"x": 114, "y": 312, "name":"ZLOADGAM"}	] | ||||
| 				"images": [ {"x": 114, "y": 312, "name":"ZLOADGAM"} ] | ||||
| 			}, | ||||
| 			{ | ||||
| 				"name" : "campaign", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user