Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Change mainmenu texture handling + small misc changes
Texture names must now be escaped in formspec elements image[],
background[], image_button[], image_button_exit[].

Instead of special-case handling of texture loading (and unloading
which was missing) in guiFormSpecMenu.cpp, use the newly created
ISimpleTextureSource interface which is a minimal subset of
ITextureSource. There is an implementation of this interface
used by GUIEngine (MenuTextureSource).

Fix an off-by-one bug in unescape_string; it caused requests for a
texture called "\0".
  • Loading branch information
kahrl committed Sep 10, 2013
1 parent da9fe64 commit 3c4734d
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 90 deletions.
6 changes: 4 additions & 2 deletions builtin/gamemgr.lua
Expand Up @@ -225,7 +225,8 @@ function gamemgr.tab()
if current_game.menuicon_path ~= nil and
current_game.menuicon_path ~= "" then
retval = retval ..
"image[5.8,-0.25;2,2;" .. current_game.menuicon_path .. "]"
"image[5.8,-0.25;2,2;" ..
engine.formspec_escape(current_game.menuicon_path) .. "]"
end

retval = retval ..
Expand All @@ -251,7 +252,8 @@ function gamemgr.dialog_edit_game()
if current_game.menuicon_path ~= nil and
current_game.menuicon_path ~= "" then
retval = retval ..
"image[5.25,0;2,2;" .. current_game.menuicon_path .. "]"
"image[5.25,0;2,2;" ..
engine.formspec_escape(current_game.menuicon_path) .. "]"
end

retval = retval ..
Expand Down
5 changes: 3 additions & 2 deletions builtin/mainmenu.lua
Expand Up @@ -1047,16 +1047,17 @@ function tabbuilder.tab_texture_packs()
return retval ..
menu.render_texture_pack_list(list) ..
";" .. index .. "]" ..
"image[0.65,0.25;4.0,3.7;"..(screenfile or no_screenshot).."]"..
"image[0.65,0.25;4.0,3.7;"..engine.formspec_escape(screenfile or no_screenshot).."]"..
"textarea[1.0,3.25;3.7,1.5;;"..engine.formspec_escape(infotext or "")..";]"
end

--------------------------------------------------------------------------------
function tabbuilder.tab_credits()
local logofile = menu.defaulttexturedir .. "logo.png"
return "vertlabel[0,-0.5;CREDITS]" ..
"label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
"label[0.5,3.3;http://minetest.net]" ..
"image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
"image[0.5,1;" .. engine.formspec_escape(logofile) .. "]" ..
"textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
"#FFFF00" .. fgettext("Core Developers") .."," ..
"Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
Expand Down
5 changes: 3 additions & 2 deletions builtin/mm_menubar.lua
Expand Up @@ -51,7 +51,8 @@ function menubar.refresh()

menubar.formspec = menubar.formspec ..
"image_button[" .. buttonpos .. ",5.7;1.3,1.3;" ..
gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
engine.formspec_escape(gamemgr.games[i].menuicon_path) .. ";" ..
btn_name .. ";;true;false]"
else

local part1 = gamemgr.games[i].id:sub(1,5)
Expand All @@ -75,4 +76,4 @@ function menubar.refresh()

table.insert(menubar.buttons,toadd)
end
end
end
2 changes: 1 addition & 1 deletion builtin/modstore.lua
Expand Up @@ -227,7 +227,7 @@ function modstore.getmodlist(list)
end

retval = retval .. "image[0,".. screenshot_ypos .. ";3,2;" ..
list.data[i].texturename .. "]"
engine.formspec_escape(list.data[i].texturename) .. "]"

--title + author
retval = retval .."label[2.75," .. screenshot_ypos .. ";" ..
Expand Down
6 changes: 3 additions & 3 deletions src/game.cpp
Expand Up @@ -1720,7 +1720,7 @@ void the_game(
GUIFormSpecMenu *menu =
new GUIFormSpecMenu(device, guiroot, -1,
&g_menumgr,
&client, gamedef);
&client, gamedef, tsrc);

InventoryLocation inventoryloc;
inventoryloc.setCurrentPlayer();
Expand Down Expand Up @@ -2259,7 +2259,7 @@ void the_game(
GUIFormSpecMenu *menu =
new GUIFormSpecMenu(device, guiroot, -1,
&g_menumgr,
&client, gamedef);
&client, gamedef, tsrc);
menu->setFormSource(current_formspec);
menu->setTextDest(current_textdest);
menu->drop();
Expand Down Expand Up @@ -2755,7 +2755,7 @@ void the_game(
GUIFormSpecMenu *menu =
new GUIFormSpecMenu(device, guiroot, -1,
&g_menumgr,
&client, gamedef);
&client, gamedef, tsrc);
menu->setFormSpec(meta->getString("formspec"),
inventoryloc);
menu->setFormSource(new NodeMetadataFormSource(
Expand Down
48 changes: 46 additions & 2 deletions src/guiEngine.cpp
Expand Up @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiMainMenu.h"
#include "sound.h"
#include "sound_openal.h"
#include "clouds.h"

#include <IGUIStaticText.h>
#include <ICameraSceneNode.h>
Expand All @@ -36,6 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <curl/curl.h>
#endif

/******************************************************************************/
/** TextDestGuiEngine */
/******************************************************************************/
TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
{
Expand All @@ -54,6 +57,38 @@ void TextDestGuiEngine::gotText(std::wstring text)
m_engine->getScriptIface()->handleMainMenuEvent(wide_to_narrow(text));
}

/******************************************************************************/
/** MenuTextureSource */
/******************************************************************************/
MenuTextureSource::MenuTextureSource(video::IVideoDriver *driver)
{
m_driver = driver;
}

/******************************************************************************/
MenuTextureSource::~MenuTextureSource()
{
for (std::set<std::string>::iterator it = m_to_delete.begin();
it != m_to_delete.end(); ++it) {
const char *tname = (*it).c_str();
video::ITexture *texture = m_driver->getTexture(tname);
m_driver->removeTexture(texture);
}
}

/******************************************************************************/
video::ITexture* MenuTextureSource::getTexture(const std::string &name, u32 *id)
{
if(id)
*id = 0;
if(name.empty())
return NULL;
m_to_delete.insert(name);
return m_driver->getTexture(name.c_str());
}

/******************************************************************************/
/** MenuMusicFetcher */
/******************************************************************************/
void MenuMusicFetcher::fetchSounds(const std::string &name,
std::set<std::string> &dst_paths,
Expand All @@ -74,6 +109,8 @@ void MenuMusicFetcher::fetchSounds(const std::string &name,
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
}

/******************************************************************************/
/** GUIEngine */
/******************************************************************************/
GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
gui::IGUIElement* parent,
Expand All @@ -86,6 +123,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
m_menumanager(menumgr),
m_smgr(smgr),
m_data(data),
m_texture_source(NULL),
m_sound_manager(NULL),
m_formspecgui(0),
m_buttonhandler(0),
Expand All @@ -105,6 +143,9 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
// is deleted by guiformspec!
m_buttonhandler = new TextDestGuiEngine(this);

//create texture source
m_texture_source = new MenuTextureSource(m_device->getVideoDriver());

//create soundmanager
MenuMusicFetcher soundfetcher;
#if USE_SOUND
Expand Down Expand Up @@ -132,7 +173,8 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
-1,
m_menumanager,
0 /* &client */,
0 /* gamedef */);
0 /* gamedef */,
m_texture_source);

m_menu->allowClose(false);
m_menu->lockSize(true,v2u32(800,600));
Expand Down Expand Up @@ -264,11 +306,13 @@ GUIEngine::~GUIEngine()

m_irr_toplefttext->setText(L"");

//initialize texture pointers
//clean up texture pointers
for (unsigned int i = 0; i < TEX_LAYER_MAX; i++) {
if (m_textures[i] != 0)
driver->removeTexture(m_textures[i]);
}

delete m_texture_source;

if (m_cloud.clouds)
m_cloud.clouds->drop();
Expand Down
55 changes: 47 additions & 8 deletions src/guiEngine.h
Expand Up @@ -25,17 +25,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/******************************************************************************/
#include "irrlichttypes.h"
#include "modalMenu.h"
#include "clouds.h"
#include "guiFormSpecMenu.h"
#include "sound.h"
#include "tile.h"

/******************************************************************************/
/* Typedefs and macros */
/******************************************************************************/
#define MAX_MENUBAR_BTN_COUNT 10
#define MAX_MENUBAR_BTN_ID 256
#define MIN_MENUBAR_BTN_ID (MAX_MENUBAR_BTN_ID - MAX_MENUBAR_BTN_COUNT)

/** texture layer ids */
typedef enum {
TEX_LAYER_BACKGROUND = 0,
Expand All @@ -50,8 +46,8 @@ typedef enum {
/******************************************************************************/
class GUIEngine;
class MainMenuScripting;
class Clouds;
struct MainMenuData;
struct SimpleSoundSpec;

/******************************************************************************/
/* declarations */
Expand All @@ -66,6 +62,7 @@ class TextDestGuiEngine : public TextDest
* @param engine the engine data is transmitted for further processing
*/
TextDestGuiEngine(GUIEngine* engine);

/**
* receive fields transmitted by guiFormSpecMenu
* @param fields map containing formspec field elements currently active
Expand All @@ -77,18 +74,58 @@ class TextDestGuiEngine : public TextDest
* @param text textual representation of event
*/
void gotText(std::wstring text);

private:
/** target to transmit data to */
GUIEngine* m_engine;
};

/** GUIEngine specific implementation of ISimpleTextureSource */
class MenuTextureSource : public ISimpleTextureSource
{
public:
/**
* default constructor
* @param driver the video driver to load textures from
*/
MenuTextureSource(video::IVideoDriver *driver);

/**
* destructor, removes all loaded textures
*/
virtual ~MenuTextureSource();

/**
* get a texture, loading it if required
* @param name path to the texture
* @param id receives the texture ID, always 0 in this implementation
*/
video::ITexture* getTexture(const std::string &name, u32 *id = NULL);

private:
/** driver to get textures from */
video::IVideoDriver *m_driver;
/** set of texture names to delete */
std::set<std::string> m_to_delete;
};

/** GUIEngine specific implementation of OnDemandSoundFetcher */
class MenuMusicFetcher: public OnDemandSoundFetcher
{
std::set<std::string> m_fetched;
public:
/**
* get sound file paths according to sound name
* @param name sound name
* @param dst_paths receives possible paths to sound files
* @param dst_datas receives binary sound data (not used here)
*/
void fetchSounds(const std::string &name,
std::set<std::string> &dst_paths,
std::set<std::string> &dst_datas);

private:
/** set of fetched sound names */
std::set<std::string> m_fetched;
};

/** implementation of main menu based uppon formspecs */
Expand Down Expand Up @@ -150,6 +187,8 @@ class GUIEngine {
scene::ISceneManager* m_smgr;
/** pointer to data beeing transfered back to main game handling */
MainMenuData* m_data;
/** pointer to texture source */
ISimpleTextureSource* m_texture_source;
/** pointer to soundmanager*/
ISoundManager* m_sound_manager;

Expand All @@ -167,7 +206,7 @@ class GUIEngine {
bool m_startgame;

/** scripting interface */
MainMenuScripting* m_script;
MainMenuScripting* m_script;

/** script basefolder */
std::string m_scriptdir;
Expand Down

0 comments on commit 3c4734d

Please sign in to comment.