diff --git a/client/CBitmapHandler.cpp b/client/CBitmapHandler.cpp index 58be8b899..ad7bab3da 100644 --- a/client/CBitmapHandler.cpp +++ b/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 "<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)); diff --git a/client/CPreGame.h b/client/CPreGame.h index 89d51c922..78998d106 100644 --- a/client/CPreGame.h +++ b/client/CPreGame.h @@ -51,6 +51,7 @@ class CMenuScreen : public CIntObject CTabbedInt *tabs; + CPicture * background; std::vector images; CIntObject *createTab(size_t index); diff --git a/client/UIFramework/CIntObjectClasses.cpp b/client/UIFramework/CIntObjectClasses.cpp index b5f109eb9..d1b90438f 100644 --- a/client/UIFramework/CIntObjectClasses.cpp +++ b/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; diff --git a/client/UIFramework/CIntObjectClasses.h b/client/UIFramework/CIntObjectClasses.h index c9646b216..204489420 100644 --- a/client/UIFramework/CIntObjectClasses.h +++ b/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); diff --git a/client/UIFramework/SDL_Extensions.cpp b/client/UIFramework/SDL_Extensions.cpp index 821954cbe..9a375afac 100644 --- a/client/UIFramework/SDL_Extensions.cpp +++ b/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::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) diff --git a/client/UIFramework/SDL_Extensions.h b/client/UIFramework/SDL_Extensions.h index 5ff1ee86e..5131ae751 100644 --- a/client/UIFramework/SDL_Extensions.h +++ b/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 diff --git a/config/mainmenu.json b/config/mainmenu.json index 5c1bb3a8f..e06fc5a33 100644 --- a/config/mainmenu.json +++ b/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",