mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- background for main menu can be scaled. Won't work as default due to non-scalable video
This commit is contained in:
parent
88639be91b
commit
59255a4cad
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user