aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKahrl <kahrl@gmx.net>2013-08-20 22:38:14 +0200
committerKahrl <kahrl@gmx.net>2013-09-11 00:08:56 +0200
commit3c4734d69a44aea133e5bd7df66a5dedb87785fb (patch)
treef3961c8855c0d864b672ae79857de9b993c3e95c /src
parentda9fe6485134ec81cc3628b1bc4847c3b2226c76 (diff)
downloadminetest-3c4734d69a44aea133e5bd7df66a5dedb87785fb.tar.gz
minetest-3c4734d69a44aea133e5bd7df66a5dedb87785fb.tar.bz2
minetest-3c4734d69a44aea133e5bd7df66a5dedb87785fb.zip
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".
Diffstat (limited to 'src')
-rw-r--r--src/game.cpp6
-rw-r--r--src/guiEngine.cpp48
-rw-r--r--src/guiEngine.h55
-rw-r--r--src/guiFormSpecMenu.cpp58
-rw-r--r--src/guiFormSpecMenu.h7
-rw-r--r--src/tile.h46
-rw-r--r--src/util/string.h2
7 files changed, 139 insertions, 83 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 5d8365781..f313ae28f 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -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();
@@ -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();
@@ -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(
diff --git a/src/guiEngine.cpp b/src/guiEngine.cpp
index f00cd039c..547f393a4 100644
--- a/src/guiEngine.cpp
+++ b/src/guiEngine.cpp
@@ -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>
@@ -37,6 +38,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif
/******************************************************************************/
+/** TextDestGuiEngine */
+/******************************************************************************/
TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
{
m_engine = engine;
@@ -55,6 +58,38 @@ void TextDestGuiEngine::gotText(std::wstring 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,
std::set<std::string> &dst_datas)
@@ -75,6 +110,8 @@ void MenuMusicFetcher::fetchSounds(const std::string &name,
}
/******************************************************************************/
+/** GUIEngine */
+/******************************************************************************/
GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
gui::IGUIElement* parent,
IMenuManager *menumgr,
@@ -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),
@@ -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
@@ -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));
@@ -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();
diff --git a/src/guiEngine.h b/src/guiEngine.h
index 6b7d3b6ed..484459395 100644
--- a/src/guiEngine.h
+++ b/src/guiEngine.h
@@ -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,
@@ -50,8 +46,8 @@ typedef enum {
/******************************************************************************/
class GUIEngine;
class MainMenuScripting;
+class Clouds;
struct MainMenuData;
-struct SimpleSoundSpec;
/******************************************************************************/
/* declarations */
@@ -66,6 +62,7 @@ public:
* @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
@@ -77,18 +74,58 @@ public:
* @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 */
@@ -150,6 +187,8 @@ private:
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;
@@ -167,7 +206,7 @@ private:
bool m_startgame;
/** scripting interface */
- MainMenuScripting* m_script;
+ MainMenuScripting* m_script;
/** script basefolder */
std::string m_scriptdir;
diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index bc33143a4..28cb6740e 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -69,12 +69,14 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr,
InventoryManager *invmgr,
- IGameDef *gamedef
+ IGameDef *gamedef,
+ ISimpleTextureSource *tsrc
):
GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr),
m_device(dev),
m_invmgr(invmgr),
m_gamedef(gamedef),
+ m_tsrc(tsrc),
m_form_src(NULL),
m_text_dst(NULL),
m_selected_item(NULL),
@@ -483,7 +485,7 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element) {
if (parts.size() == 3) {
std::vector<std::string> v_pos = split(parts[0],',');
std::vector<std::string> v_geom = split(parts[1],',');
- std::string name = parts[2];
+ std::string name = unescape_string(parts[2]);
MY_CHECKPOS("image",0);
MY_CHECKGEOM("image",1);
@@ -504,7 +506,7 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element) {
if (parts.size() == 2) {
std::vector<std::string> v_pos = split(parts[0],',');
- std::string name = parts[1];
+ std::string name = unescape_string(parts[1]);
MY_CHECKPOS("image",0);
@@ -605,7 +607,7 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) {
if (parts.size() == 3) {
std::vector<std::string> v_pos = split(parts[0],',');
std::vector<std::string> v_geom = split(parts[1],',');
- std::string name = parts[2];
+ std::string name = unescape_string(parts[2]);
MY_CHECKPOS("background",0);
MY_CHECKGEOM("background",1);
@@ -769,11 +771,6 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) {
if (str_initial_selection != "")
e->setSelected(stoi(str_initial_selection.c_str())-1);
- //if (data->listbox_selections.find(fname_w) != data->listbox_selections.end()) {
- // e->setSelected(data->listbox_selections[fname_w]);
- //}
-
- //m_listboxes.push_back(std::pair<FieldSpec,gui::IGUIListBox*>(spec,e));
m_fields.push_back(spec);
return;
}
@@ -1149,6 +1146,8 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,std:
if(data->bp_set != 2)
errorstream<<"WARNING: invalid use of item_image_button without a size[] element"<<std::endl;
+ image_name = unescape_string(image_name);
+ pressed_image_name = unescape_string(pressed_image_name);
label = unescape_string(label);
std::wstring wlabel = narrow_to_wide(label.c_str());
@@ -1165,24 +1164,10 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,std:
video::ITexture *texture = 0;
video::ITexture *pressed_texture = 0;
- //if there's no gamedef specified try to get direct
- //TODO check for possible texture leak
- if (m_gamedef != 0) {
- texture = m_gamedef->tsrc()->getTexture(image_name);
- if ((parts.size() == 8)) {
- pressed_texture = m_gamedef->tsrc()->getTexture(pressed_image_name);
- }
- } else {
- if (fs::PathExists(image_name)) {
- texture = Environment->getVideoDriver()->getTexture(image_name.c_str());
- m_Textures.push_back(texture);
- }
- if (fs::PathExists(pressed_image_name)) {
- pressed_texture = Environment->getVideoDriver()->getTexture(pressed_image_name.c_str());
- m_Textures.push_back(pressed_texture);
- }
- }
- if (parts.size() < 8)
+ texture = m_tsrc->getTexture(image_name);
+ if (parts.size() == 8)
+ pressed_texture = m_tsrc->getTexture(pressed_image_name);
+ else
pressed_texture = texture;
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
@@ -1797,15 +1782,7 @@ void GUIFormSpecMenu::drawMenu()
for(u32 i=0; i<m_backgrounds.size(); i++)
{
const ImageDrawSpec &spec = m_backgrounds[i];
- video::ITexture *texture = 0;
-
- if (m_gamedef != 0)
- texture = m_gamedef->tsrc()->getTexture(spec.name);
- else
- {
- texture = driver->getTexture(spec.name.c_str());
- m_Textures.push_back(texture);
- }
+ video::ITexture *texture = m_tsrc->getTexture(spec.name);
if (texture != 0) {
// Image size on screen
@@ -1847,15 +1824,8 @@ void GUIFormSpecMenu::drawMenu()
for(u32 i=0; i<m_images.size(); i++)
{
const ImageDrawSpec &spec = m_images[i];
- video::ITexture *texture = 0;
+ video::ITexture *texture = m_tsrc->getTexture(spec.name);
- if (m_gamedef != 0)
- texture = m_gamedef->tsrc()->getTexture(spec.name);
- else
- {
- texture = driver->getTexture(spec.name.c_str());
- m_Textures.push_back(texture);
- }
if (texture != 0) {
const core::dimension2d<u32>& img_origsize = texture->getOriginalSize();
// Image size on screen
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 73c21b72d..c244e458f 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class IGameDef;
class InventoryManager;
+class ISimpleTextureSource;
typedef enum {
f_Button,
@@ -176,7 +177,8 @@ public:
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr,
InventoryManager *invmgr,
- IGameDef *gamedef
+ IGameDef *gamedef,
+ ISimpleTextureSource *tsrc
);
~GUIFormSpecMenu();
@@ -245,6 +247,7 @@ protected:
irr::IrrlichtDevice* m_device;
InventoryManager *m_invmgr;
IGameDef *m_gamedef;
+ ISimpleTextureSource *m_tsrc;
std::string m_formspec_string;
InventoryLocation m_current_inventory_location;
@@ -302,8 +305,6 @@ private:
bool key_escape;
} fs_key_pendig;
- std::vector<video::ITexture *> m_Textures;
-
fs_key_pendig current_keys_pending;
// Determine whether listbox click was double click
diff --git a/src/tile.h b/src/tile.h
index 23c214350..90e180a48 100644
--- a/src/tile.h
+++ b/src/tile.h
@@ -82,22 +82,27 @@ struct TextureFromMeshParams
TextureSource creates and caches textures.
*/
-class ITextureSource
+class ISimpleTextureSource
+{
+public:
+ ISimpleTextureSource(){}
+ virtual ~ISimpleTextureSource(){}
+ virtual video::ITexture* getTexture(
+ const std::string &name, u32 *id = NULL) = 0;
+};
+
+class ITextureSource : public ISimpleTextureSource
{
public:
ITextureSource(){}
virtual ~ITextureSource(){}
- virtual u32 getTextureId(const std::string &name){return 0;}
- virtual u32 getTextureIdDirect(const std::string &name){return 0;}
- virtual std::string getTextureName(u32 id){return "";}
- virtual video::ITexture* getTexture(u32 id){return NULL;}
+ virtual u32 getTextureId(const std::string &name)=0;
+ virtual u32 getTextureIdDirect(const std::string &name)=0;
+ virtual std::string getTextureName(u32 id)=0;
+ virtual video::ITexture* getTexture(u32 id)=0;
virtual video::ITexture* getTexture(
- const std::string &name, u32 *id = NULL){
- if(id) *id = 0;
- return NULL;
- }
- virtual IrrlichtDevice* getDevice()
- {return NULL;}
+ const std::string &name, u32 *id = NULL)=0;
+ virtual IrrlichtDevice* getDevice()=0;
virtual bool isKnownSourceImage(const std::string &name)=0;
virtual video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params)=0;
@@ -108,23 +113,20 @@ class IWritableTextureSource : public ITextureSource
public:
IWritableTextureSource(){}
virtual ~IWritableTextureSource(){}
- virtual u32 getTextureId(const std::string &name){return 0;}
- virtual u32 getTextureIdDirect(const std::string &name){return 0;}
- virtual std::string getTextureName(u32 id){return "";}
- virtual video::ITexture* getTexture(u32 id){return NULL;}
+ virtual u32 getTextureId(const std::string &name)=0;
+ virtual u32 getTextureIdDirect(const std::string &name)=0;
+ virtual std::string getTextureName(u32 id)=0;
+ virtual video::ITexture* getTexture(u32 id)=0;
virtual video::ITexture* getTexture(
- const std::string &name, u32 *id = NULL){
- if(id) *id = 0;
- return NULL;
- }
- virtual IrrlichtDevice* getDevice(){return NULL;}
+ const std::string &name, u32 *id = NULL)=0;
+ virtual IrrlichtDevice* getDevice()=0;
virtual bool isKnownSourceImage(const std::string &name)=0;
+ virtual video::ITexture* generateTextureFromMesh(
+ const TextureFromMeshParams &params)=0;
virtual void processQueue()=0;
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
virtual void rebuildImagesAndTextures()=0;
- virtual video::ITexture* generateTextureFromMesh(
- const TextureFromMeshParams &params)=0;
};
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
diff --git a/src/util/string.h b/src/util/string.h
index d9390e33c..7531600e3 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -307,7 +307,7 @@ inline std::string unescape_string(std::string &s)
{
std::string res;
- for (size_t i = 0; i <= s.length(); i++) {
+ for (size_t i = 0; i < s.length(); i++) {
if (s[i] == '\\')
i++;
res += s[i];