Jelajahi Sumber

- background for main menu can be scaled. Won't work as default due to non-scalable video

Ivan Savenko 13 tahun lalu
induk
melakukan
59255a4cad

+ 2 - 1
client/CBitmapHandler.cpp

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

+ 20 - 19
client/CPreGame.cpp

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

+ 1 - 0
client/CPreGame.h

@@ -51,6 +51,7 @@ class CMenuScreen : public CIntObject
 
 	CTabbedInt *tabs;
 
+	CPicture * background;
 	std::vector<CPicture*> images;
 
 	CIntObject *createTab(size_t index);

+ 26 - 0
client/UIFramework/CIntObjectClasses.cpp

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

+ 2 - 0
client/UIFramework/CIntObjectClasses.h

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

+ 11 - 5
client/UIFramework/SDL_Extensions.cpp

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

+ 1 - 0
client/UIFramework/SDL_Extensions.h

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

+ 5 - 3
config/mainmenu.json

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