Add header.png and footer.png support for games, and support texture packs via <gamei...
authorPerttu Ahola <celeron55@gmail.com>
Sat, 4 May 2013 07:03:56 +0000 (10:03 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 4 May 2013 07:05:12 +0000 (10:05 +0300)
src/main.cpp
src/subgame.cpp
src/subgame.h

index 501e4cdf4031059572c4b541bf4f00702f12fe06..3cf6728e47681d8c36d099467548dce719d8ed8b 100644 (file)
@@ -612,15 +612,53 @@ private:
        bool rightreleased;
 };
 
-void drawMenuBackground(video::IVideoDriver* driver, const SubgameSpec *spec)
+struct MenuTextures
 {
-       v2u32 screensize = driver->getScreenSize();
+       std::string current_gameid;
+       video::ITexture *background;
+       video::ITexture *overlay;
+       video::ITexture *header;
+       video::ITexture *footer;
+
+       MenuTextures():
+               background(NULL),
+               overlay(NULL),
+               header(NULL),
+               footer(NULL)
+       {}
 
-       /* Figure out background texture */
-       video::ITexture *texture = NULL;
-       if(spec && spec->menubackground_path != ""){
-               texture = driver->getTexture(spec->menubackground_path.c_str());
+       static video::ITexture* getMenuTexture(const std::string &tname,
+                       video::IVideoDriver* driver, const SubgameSpec *spec)
+       {
+               std::string path;
+               // eg. minetest_menu_background.png (for texture packs)
+               std::string pack_tname = spec->id + "_menu_" + tname + ".png";
+               path = getTexturePath(pack_tname);
+               if(path != "")
+                       return driver->getTexture(path.c_str());
+               // eg. games/minetest_game/menu/background.png
+               path = getImagePath(spec->path + DIR_DELIM + "menu" + DIR_DELIM + tname + ".png");
+               if(path != "")
+                       return driver->getTexture(path.c_str());
+               return NULL;
+       }
+
+       void update(video::IVideoDriver* driver, const SubgameSpec *spec)
+       {
+               if(spec->id == current_gameid)
+                       return;
+               current_gameid = spec->id;
+               background = getMenuTexture("background", driver, spec);
+               overlay = getMenuTexture("overlay", driver, spec);
+               header = getMenuTexture("header", driver, spec);
+               footer = getMenuTexture("footer", driver, spec);
        }
+};
+
+void drawMenuBackground(video::IVideoDriver* driver, const MenuTextures &menutextures)
+{
+       v2u32 screensize = driver->getScreenSize();
+       video::ITexture *texture = menutextures.background;
 
        /* If no texture, draw background of solid color */
        if(!texture){
@@ -638,15 +676,10 @@ void drawMenuBackground(video::IVideoDriver* driver, const SubgameSpec *spec)
                NULL, NULL, true);
 }
 
-void drawMenuOverlay(video::IVideoDriver* driver, const SubgameSpec *spec)
+void drawMenuOverlay(video::IVideoDriver* driver, const MenuTextures &menutextures)
 {
        v2u32 screensize = driver->getScreenSize();
-
-       /* Figure out overlay texture */
-       video::ITexture *texture = NULL;
-       if(spec && spec->menuoverlay_path != ""){
-               texture = driver->getTexture(spec->menuoverlay_path.c_str());
-       }
+       video::ITexture *texture = menutextures.overlay;
 
        /* If no texture, draw nothing */
        if(!texture)
@@ -660,6 +693,66 @@ void drawMenuOverlay(video::IVideoDriver* driver, const SubgameSpec *spec)
                NULL, NULL, true);
 }
 
+void drawMenuHeader(video::IVideoDriver* driver, const MenuTextures &menutextures)
+{
+       core::dimension2d<u32> screensize = driver->getScreenSize();
+       video::ITexture *texture = menutextures.header;
+
+       /* If no texture, draw nothing */
+       if(!texture)
+               return;
+
+       f32 mult = (((f32)screensize.Width / 2)) /
+               ((f32)texture->getOriginalSize().Width);
+
+       v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult,
+                       ((f32)texture->getOriginalSize().Height) * mult);
+
+       // Don't draw the header is there isn't enough room
+       s32 free_space = (((s32)screensize.Height)-320)/2;
+       if (free_space > splashsize.Y) {
+               core::rect<s32> splashrect(0, 0, splashsize.X, splashsize.Y);
+               splashrect += v2s32((screensize.Width/2)-(splashsize.X/2),
+                       ((free_space/2)-splashsize.Y/2)+10);
+
+               video::SColor bgcolor(255,50,50,50);
+
+               driver->draw2DImage(texture, splashrect,
+                       core::rect<s32>(core::position2d<s32>(0,0),
+                       core::dimension2di(texture->getSize())),
+                       NULL, NULL, true);
+       }
+}
+
+void drawMenuFooter(video::IVideoDriver* driver, const MenuTextures &menutextures)
+{
+       core::dimension2d<u32> screensize = driver->getScreenSize();
+       video::ITexture *texture = menutextures.footer;
+
+       /* If no texture, draw nothing */
+       if(!texture)
+               return;
+
+       f32 mult = (((f32)screensize.Width)) /
+               ((f32)texture->getOriginalSize().Width);
+
+       v2s32 footersize(((f32)texture->getOriginalSize().Width) * mult,
+                       ((f32)texture->getOriginalSize().Height) * mult);
+
+       // Don't draw the footer if there isn't enough room
+       s32 free_space = (((s32)screensize.Height)-320)/2;
+       if (free_space > footersize.Y) {
+               core::rect<s32> rect(0,0,footersize.X,footersize.Y);
+               rect += v2s32(screensize.Width/2,screensize.Height-footersize.Y);
+               rect -= v2s32(footersize.X/2, 0);
+
+               driver->draw2DImage(texture, rect,
+                       core::rect<s32>(core::position2d<s32>(0,0),
+                       core::dimension2di(texture->getSize())),
+                       NULL, NULL, true);
+       }
+}
+
 static const SubgameSpec* getMenuGame(const MainMenuData &menudata)
 {
        for(size_t i=0; i<menudata.games.size(); i++){
@@ -1567,6 +1660,9 @@ int main(int argc, char *argv[])
                                }
                                const SubgameSpec *menugame = getMenuGame(menudata);
 
+                               MenuTextures menutextures;
+                               menutextures.update(driver, menugame);
+
                                if(skip_main_menu == false)
                                {
                                        video::IVideoDriver* driver = device->getVideoDriver();
@@ -1578,7 +1674,7 @@ int main(int argc, char *argv[])
                                                        break;
                                                driver->beginScene(true, true,
                                                                video::SColor(255,128,128,128));
-                                               drawMenuBackground(driver, menugame);
+                                               drawMenuBackground(driver, menutextures);
                                                guienv->drawAll();
                                                driver->endScene();
                                                // On some computers framerate doesn't seem to be
@@ -1628,18 +1724,17 @@ int main(int argc, char *argv[])
 
                                                // Game can be selected in the menu
                                                menugame = getMenuGame(menudata);
+                                               menutextures.update(driver, menugame);
                                                // Clouds for the main menu
                                                bool cloud_menu_background = g_settings->getBool("menu_clouds");
                                                if(menugame){
                                                        // If game has regular background and no overlay, don't use clouds
-                                                       if(cloud_menu_background &&
-                                                                       menugame->menuoverlay_path.empty() &&
-                                                                       !menugame->menubackground_path.empty()){
+                                                       if(cloud_menu_background && menutextures.background &&
+                                                                       !menutextures.overlay){
                                                                cloud_menu_background = false;
                                                        }
                                                        // If game game has overlay and no regular background, always draw clouds
-                                                       else if(menugame->menubackground_path.empty() &&
-                                                                       !menugame->menuoverlay_path.empty()){
+                                                       else if(menutextures.overlay && !menutextures.background){
                                                                cloud_menu_background = true;
                                                        }
                                                }
@@ -1663,9 +1758,13 @@ int main(int argc, char *argv[])
                                                        clouds->step(dtime*3); 
                                                        clouds->render();
                                                        smgr->drawAll();
-                                                       drawMenuOverlay(driver, menugame);
+                                                       drawMenuOverlay(driver, menutextures);
+                                                       drawMenuHeader(driver, menutextures);
+                                                       drawMenuFooter(driver, menutextures);
                                                } else {
-                                                       drawMenuBackground(driver, menugame);
+                                                       drawMenuBackground(driver, menutextures);
+                                                       drawMenuHeader(driver, menutextures);
+                                                       drawMenuFooter(driver, menutextures);
                                                }
 
                                                guienv->drawAll();
index 1bee630b257de20b80904d93eef5019d4dad7723..cdb5466197554cab4f411f1901536a8822ad6c09 100644 (file)
@@ -97,16 +97,12 @@ SubgameSpec findSubgame(const std::string &id)
        std::string game_name = getGameName(game_path);
        if(game_name == "")
                game_name = id;
-       std::string menubackground_path;
-       std::string menuoverlay_path;
        std::string menuicon_path;
 #ifndef SERVER
-       menubackground_path = getImagePath(game_path + DIR_DELIM + "menu" + DIR_DELIM + "background.png");
-       menuoverlay_path = getImagePath(game_path + DIR_DELIM + "menu" + DIR_DELIM + "overlay.png");
        menuicon_path = getImagePath(game_path + DIR_DELIM + "menu" + DIR_DELIM + "icon.png");
 #endif
        return SubgameSpec(id, game_path, gamemod_path, mods_paths, game_name,
-                       menubackground_path, menuoverlay_path, menuicon_path);
+                       menuicon_path);
 }
 
 SubgameSpec findWorldSubgame(const std::string &world_path)
index 2e16c2fec7f8357980cebdc74cfc78086d0a5328..4b15faa8d570546fe1c30ee0696b39271bf22fd3 100644 (file)
@@ -35,8 +35,6 @@ struct SubgameSpec
        std::string gamemods_path; //path to mods of the game
        std::set<std::string> addon_mods_paths; //paths to addon mods for this game
        std::string name;
-       std::string menubackground_path;
-       std::string menuoverlay_path;
        std::string menuicon_path;
 
        SubgameSpec(const std::string &id_="",
@@ -44,16 +42,12 @@ struct SubgameSpec
                        const std::string &gamemods_path_="",
                        const std::set<std::string> &addon_mods_paths_=std::set<std::string>(),
                        const std::string &name_="",
-                       const std::string &menubackground_path_="",
-                       const std::string &menuoverlay_path_="",
                        const std::string &menuicon_path_=""):
                id(id_),
                path(path_),
                gamemods_path(gamemods_path_),          
                addon_mods_paths(addon_mods_paths_),
                name(name_),
-               menubackground_path(menubackground_path_),
-               menuoverlay_path(menuoverlay_path_),
                menuicon_path(menuicon_path_)
        {}