framework for modifying textures
authorPerttu Ahola <celeron55@gmail.com>
Mon, 20 Dec 2010 20:03:49 +0000 (22:03 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 20 Dec 2010 20:03:49 +0000 (22:03 +0200)
19 files changed:
Makefile
minetest.conf.example
src/constants.h
src/debug.h
src/defaultsettings.cpp
src/exceptions.h
src/inventory.cpp
src/inventory.h
src/main.cpp
src/main.h
src/map.cpp
src/mapblock.cpp
src/mapnode.cpp
src/porting.h
src/tile.cpp
src/tile.h
src/utility.cpp
src/utility.h
src/voxel.cpp

index 38a59c2dedf48429368fe3f44057912615b09bc2..7aacb4c4adc542eeb569f0f5a653a9ab63dd94fa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,9 +2,9 @@
 # It's usually sufficient to change just the target name and source file list\r
 # and be sure that CXX is set to a valid compiler\r
 TARGET = test\r
-SOURCE_FILES = guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp\r
+SOURCE_FILES = irrlichtwrapper.cpp guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp\r
 SOURCES = $(addprefix src/, $(SOURCE_FILES))\r
-BUILD_DIR = build/\r
+BUILD_DIR = build\r
 OBJECTS = $(addprefix $(BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o))\r
 #OBJECTS = $(SOURCES:.cpp=.o)\r
 \r
@@ -13,7 +13,7 @@ FAST_TARGET = fasttest
 SERVER_TARGET = server\r
 SERVER_SOURCE_FILES = defaultsettings.cpp mapnode.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp servermain.cpp test.cpp\r
 SERVER_SOURCES = $(addprefix src/, $(SERVER_SOURCE_FILES))\r
-SERVER_BUILD_DIR = serverbuild/\r
+SERVER_BUILD_DIR = serverbuild\r
 SERVER_OBJECTS = $(addprefix $(SERVER_BUILD_DIR)/, $(SERVER_SOURCE_FILES:.cpp=.o))\r
 #SERVER_OBJECTS = $(SERVER_SOURCES:.cpp=.o)\r
 \r
index ed3f8ebefbf7414a4544300675290a91850d717b..3e9f49b0e236060cb724913c02e8818201c2f582 100644 (file)
@@ -13,8 +13,8 @@
 #fps_max = 60
 #viewing_range_nodes_max = 300
 #viewing_range_nodes_min = 50
-#screenW = 
-#screenH = 
+#screenW = 800
+#screenH = 600
 #host_game = 
 #port = 30000
 #address = kray.dy.fi
index 3c9b50eff2610de4faba9c6451140f60ca2fde27..c3fca432f83761cc891e05988128dbbb4e208215 100644 (file)
@@ -62,8 +62,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 // Viewing range stuff
 
-//#define FREETIME_RATIO 0.2
-#define FREETIME_RATIO 0.15
+//#define FREETIME_RATIO 0.15
+#define FREETIME_RATIO 0.0
 
 // Sectors are split to SECTOR_HEIGHTMAP_SPLIT^2 heightmaps
 #define SECTOR_HEIGHTMAP_SPLIT 2
index 9a2e282f5c2d7eba4c5f69c670aa5f5b272aa89e..44fcf4b5150f83aa20312efdad2e1cd7d6140f91 100644 (file)
@@ -30,29 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <jmutexautolock.h>
 #include <iostream>
 #include "common_irrlicht.h"
-
-/*
-       Compatibility stuff
-*/
-
-#if (defined(WIN32) || defined(_WIN32_WCE))
-typedef DWORD threadid_t;
-#define __NORETURN __declspec(noreturn)
-#define __FUNCTION_NAME __FUNCTION__
-#else
-typedef pthread_t threadid_t;
-#define __NORETURN __attribute__ ((__noreturn__))
-#define __FUNCTION_NAME __PRETTY_FUNCTION__
-#endif
-
-inline threadid_t get_current_thread_id()
-{
-#if (defined(WIN32) || defined(_WIN32_WCE))
-       return GetCurrentThreadId();
-#else
-       return pthread_self();
-#endif
-}
+#include "threads.h"
 
 /*
        Debug output
index a9b8dc279be24b5661830449264a8bf37f6522f5..04cdf16bce29660eb9d61c32eacb95f3c4e2670f 100644 (file)
@@ -28,8 +28,8 @@ void set_default_settings()
        g_settings.setDefault("fps_max", "60");
        g_settings.setDefault("viewing_range_nodes_max", "300");
        g_settings.setDefault("viewing_range_nodes_min", "35");
-       g_settings.setDefault("screenW", "");
-       g_settings.setDefault("screenH", "");
+       g_settings.setDefault("screenW", "800");
+       g_settings.setDefault("screenH", "600");
        g_settings.setDefault("host_game", "");
        g_settings.setDefault("port", "");
        g_settings.setDefault("address", "");
index 95b9eea97ee6ba5e70bf2737047e8cbef7f6ae15..40a0db4aa86110e14f96dac38e0e085a7282a270 100644 (file)
@@ -132,6 +132,14 @@ public:
        {}
 };
 
+class ItemNotFoundException : public BaseException
+{
+public:
+       ItemNotFoundException(const char *s):
+               BaseException(s)
+       {}
+};
+
 /*
        Some "old-style" interrupts:
 */
index ba8cf45801d6cf1e03da775572599b1cb397b1b3..079be87931a7558e2a9b9f044b3d71a4d13f4d9e 100644 (file)
@@ -80,10 +80,12 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
 video::ITexture * MapBlockObjectItem::getImage()
 {
        if(m_inventorystring.substr(0,3) == "Rat")
-               return g_device->getVideoDriver()->getTexture("../data/rat.png");
+               //return g_device->getVideoDriver()->getTexture("../data/rat.png");
+               return g_irrlicht->getTexture("../data/rat.png");
        
        if(m_inventorystring.substr(0,4) == "Sign")
-               return g_device->getVideoDriver()->getTexture("../data/sign.png");
+               //return g_device->getVideoDriver()->getTexture("../data/sign.png");
+               return g_irrlicht->getTexture("../data/sign.png");
 
        return NULL;
 }
index cb5b54851b99ef30306840f41d40f528f0611d50..59ff89ed8bbd4c82dc49995ed287134f367d85a6 100644 (file)
@@ -96,7 +96,7 @@ public:
                if(m_content >= USEFUL_CONTENT_COUNT)
                        return NULL;
                        
-               return g_texturecache.get(g_content_inventory_textures[m_content]);
+               return g_irrlicht->getTexture(g_content_inventory_textures[m_content]);
        }
 #endif
        std::string getText()
index 3dc111201af703e883c2eeedbfc70d3db341ae47..56e725722a6a36c9981083b44811cbfbd36397bc 100644 (file)
@@ -183,6 +183,9 @@ TODO: Node cracking animation when digging
       - TODO: A way to generate new textures by combining textures\r
          - TODO: Mesh update to fetch cracked faces from the former\r
 \r
+TODO: A thread-safe wrapper for irrlicht for threads, to get rid of\r
+      g_device\r
+\r
 ======================================================================\r
 \r
 */\r
@@ -247,28 +250,7 @@ TODO: Node cracking animation when digging
 #include "porting.h"\r
 #include "guiPauseMenu.h"\r
 \r
-IrrlichtDevice *g_device = NULL;\r
-\r
-/*const char *g_content_filenames[MATERIALS_COUNT] =\r
-{\r
-       "../data/stone.png",\r
-       "../data/grass.png",\r
-       "../data/water.png",\r
-       "../data/torch_on_floor.png",\r
-       "../data/tree.png",\r
-       "../data/leaves.png",\r
-       "../data/grass_footsteps.png",\r
-       "../data/mese.png",\r
-       "../data/mud.png",\r
-       "../data/water.png", // CONTENT_OCEAN\r
-};\r
-\r
-// Material cache\r
-video::SMaterial g_materials[MATERIALS_COUNT];*/\r
-\r
-// Texture cache\r
-TextureCache g_texturecache;\r
-\r
+IrrlichtWrapper *g_irrlicht;\r
 \r
 // All range-related stuff below is locked behind this\r
 JMutex g_range_mutex;\r
@@ -852,9 +834,10 @@ void updateViewingRange(f32 frametime, Client *client)
 \r
        static bool fraction_is_good = false;\r
        \r
-       float fraction_good_threshold = 0.1;\r
+       //float fraction_good_threshold = 0.1;\r
        //float fraction_bad_threshold = 0.25;\r
-       float fraction_bad_threshold = 0.1;\r
+       float fraction_good_threshold = 0.075;\r
+       float fraction_bad_threshold = 0.125;\r
        float fraction_limit;\r
        // Use high limit if fraction is good AND the fraction would\r
        // lower the range. We want to keep the range fairly high.\r
@@ -1283,7 +1266,12 @@ int main(int argc, char *argv[])
        /*\r
                Resolution selection\r
        */\r
+       \r
+       bool fullscreen = false;\r
+       u16 screenW = atoi(g_settings.get("screenW").c_str());\r
+       u16 screenH = atoi(g_settings.get("screenH").c_str());\r
 \r
+#if 0\r
        u16 screenW;\r
        u16 screenH;\r
        bool fullscreen = false;\r
@@ -1345,6 +1333,7 @@ int main(int argc, char *argv[])
                screenH = resolutions[r0-1][1];\r
                fullscreen = resolutions[r0-1][2];\r
        }\r
+#endif\r
 \r
        //\r
 \r
@@ -1372,8 +1361,10 @@ int main(int argc, char *argv[])
 \r
        if (device == 0)\r
                return 1; // could not create selected driver.\r
+       \r
+       g_irrlicht = new IrrlichtWrapper(device);\r
 \r
-       g_device = device;\r
+       //g_device = device;\r
        \r
        device->setResizable(true);\r
 \r
@@ -1432,10 +1423,11 @@ int main(int argc, char *argv[])
        /*\r
                Preload some random textures that are used in threads\r
        */\r
-       \r
+#if 0\r
        g_texturecache.set("torch", driver->getTexture("../data/torch.png"));\r
        g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));\r
        g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));\r
+       g_texturecache.set("crack", driver->getTexture("../data/crack.png"));\r
        \r
        /*\r
                Load tile textures\r
@@ -1452,7 +1444,11 @@ int main(int argc, char *argv[])
                g_texturecache.set(name, driver->getTexture(filename.c_str()));\r
        }\r
 \r
-       tile_materials_preload(g_texturecache);\r
+#endif\r
+\r
+       //tile_materials_preload(g_texturecache);\r
+       tile_materials_preload(g_irrlicht);\r
+       //tile_materials_init();\r
 \r
        /*\r
                Make a scope here for the client so that it gets removed\r
@@ -1641,6 +1637,11 @@ int main(int argc, char *argv[])
 \r
        while(device->run())\r
        {\r
+               /*\r
+                       Run global IrrlichtWrapper's main thread processing stuff\r
+               */\r
+               g_irrlicht->Run();\r
+\r
                /*\r
                        Random calculations\r
                */\r
@@ -1653,7 +1654,7 @@ int main(int argc, char *argv[])
                // Info text\r
                std::wstring infotext;\r
 \r
-               //TimeTaker //timer1("//timer1", device);\r
+               //TimeTaker //timer1("//timer1", g_irrlicht);\r
                \r
                // Time of frame without fps limit\r
                float busytime;\r
@@ -1843,20 +1844,20 @@ int main(int argc, char *argv[])
                */\r
                \r
                {\r
-                       //TimeTaker timer("client.step(dtime)", device);\r
+                       //TimeTaker timer("client.step(dtime)", g_irrlicht);\r
                        client.step(dtime);\r
                        //client.step(dtime_avg1);\r
                }\r
 \r
                if(server != NULL)\r
                {\r
-                       //TimeTaker timer("server->step(dtime)", device);\r
+                       //TimeTaker timer("server->step(dtime)", g_irrlicht);\r
                        server->step(dtime);\r
                }\r
 \r
                v3f player_position = client.getPlayerPosition();\r
                \r
-               //TimeTaker //timer2("//timer2", device);\r
+               //TimeTaker //timer2("//timer2", g_irrlicht);\r
 \r
                /*\r
                        Mouse and camera control\r
@@ -1910,12 +1911,12 @@ int main(int argc, char *argv[])
                }\r
                else{\r
                        //client.m_env.getMap().updateCamera(camera_position, camera_direction);\r
-                       //TimeTaker timer("client.updateCamera", device);\r
+                       //TimeTaker timer("client.updateCamera", g_irrlicht);\r
                        client.updateCamera(camera_position, camera_direction);\r
                }\r
                \r
                //timer2.stop();\r
-               //TimeTaker //timer3("//timer3", device);\r
+               //TimeTaker //timer3("//timer3", g_irrlicht);\r
 \r
                /*\r
                        Calculate what block is the crosshair pointing to\r
@@ -2266,7 +2267,7 @@ int main(int argc, char *argv[])
                        Update gui stuff (0ms)\r
                */\r
 \r
-               //TimeTaker guiupdatetimer("Gui updating", device);\r
+               //TimeTaker guiupdatetimer("Gui updating", g_irrlicht);\r
                \r
                {\r
                        wchar_t temptext[150];\r
@@ -2376,14 +2377,14 @@ int main(int argc, char *argv[])
                        Drawing begins\r
                */\r
 \r
-               TimeTaker drawtimer("Drawing", device);\r
+               TimeTaker drawtimer("Drawing", g_irrlicht);\r
 \r
                \r
                {\r
-               TimeTaker timer("beginScene", device);\r
-               driver->beginScene(true, true, bgcolor);\r
-               //driver->beginScene(false, true, bgcolor);\r
-               beginscenetime = timer.stop(true);\r
+                       TimeTaker timer("beginScene", g_irrlicht);\r
+                       driver->beginScene(true, true, bgcolor);\r
+                       //driver->beginScene(false, true, bgcolor);\r
+                       beginscenetime = timer.stop(true);\r
                }\r
 \r
                //timer3.stop();\r
@@ -2391,13 +2392,13 @@ int main(int argc, char *argv[])
                //std::cout<<DTIME<<"smgr->drawAll()"<<std::endl;\r
                \r
                {\r
-               TimeTaker timer("smgr", device);\r
-               smgr->drawAll();\r
-               scenetime = timer.stop(true);\r
+                       TimeTaker timer("smgr", g_irrlicht);\r
+                       smgr->drawAll();\r
+                       scenetime = timer.stop(true);\r
                }\r
                \r
                {\r
-               //TimeTaker timer9("auxiliary drawings", device);\r
+               //TimeTaker timer9("auxiliary drawings", g_irrlicht);\r
                // 0ms\r
 \r
                driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),\r
@@ -2408,7 +2409,7 @@ int main(int argc, char *argv[])
                                video::SColor(255,255,255,255));\r
 \r
                //timer9.stop();\r
-               //TimeTaker //timer10("//timer10", device);\r
+               //TimeTaker //timer10("//timer10", g_irrlicht);\r
                \r
                video::SMaterial m;\r
                m.Thickness = 10;\r
@@ -2431,7 +2432,7 @@ int main(int argc, char *argv[])
                }\r
 \r
                //timer10.stop();\r
-               //TimeTaker //timer11("//timer11", device);\r
+               //TimeTaker //timer11("//timer11", g_irrlicht);\r
 \r
                /*\r
                        Draw gui\r
@@ -2441,9 +2442,9 @@ int main(int argc, char *argv[])
                \r
                // End drawing\r
                {\r
-               TimeTaker timer("endScene", device);\r
-               driver->endScene();\r
-               endscenetime = timer.stop(true);\r
+                       TimeTaker timer("endScene", g_irrlicht);\r
+                       driver->endScene();\r
+                       endscenetime = timer.stop(true);\r
                }\r
 \r
                drawtime = drawtimer.stop(true);\r
index 98af41249b91003b6882ad31cc9c7f7670a3116e..22b5157d70250c7c3d6ae324bed939819ada6393 100644 (file)
@@ -46,12 +46,14 @@ extern std::ostream *derr_server_ptr;
 #define dout_server (*dout_server_ptr)
 #define derr_server (*derr_server_ptr)
 
-#ifndef SERVER
+/*#ifndef SERVER
        #include "utility.h"
        extern TextureCache g_texturecache;
-#endif
+#endif*/
 
-extern IrrlichtDevice *g_device;
+#include "irrlichtwrapper.h"
+//extern IrrlichtDevice *g_device;
+extern IrrlichtWrapper *g_irrlicht;
 
 #endif
 
index acaebe25743f7b4f7f0f6a789db94652fb99b158..13db9265145d077390a748e38c7fa891e3a4fd81 100644 (file)
@@ -740,7 +740,7 @@ void Map::updateLighting(enum LightBank bank,
        }
        
        {
-               //TimeTaker timer("unspreadLight", g_device);
+               //TimeTaker timer("unspreadLight", g_irrlicht);
                unspreadLight(bank, unlight_from, light_sources, modified_blocks);
        }
        
@@ -759,7 +759,7 @@ void Map::updateLighting(enum LightBank bank,
        //       - Find out why it works
 
        {
-               //TimeTaker timer("spreadLight", g_device);
+               //TimeTaker timer("spreadLight", g_irrlicht);
                spreadLight(bank, light_sources, modified_blocks);
        }
        
@@ -1065,7 +1065,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
 #ifndef SERVER
 void Map::expireMeshes(bool only_daynight_diffed)
 {
-       TimeTaker timer("expireMeshes()", g_device);
+       TimeTaker timer("expireMeshes()", g_irrlicht);
 
        core::map<v2s16, MapSector*>::Iterator si;
        si = m_sectors.getIterator();
@@ -3017,7 +3017,7 @@ MapVoxelManipulator::~MapVoxelManipulator()
 #if 1
 void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
 {
-       TimeTaker timer1("emerge", g_device, &emerge_time);
+       TimeTaker timer1("emerge", g_irrlicht, &emerge_time);
 
        // Units of these are MapBlocks
        v3s16 p_min = getNodeBlockPos(a.MinEdge);
@@ -3041,7 +3041,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
                bool block_data_inexistent = false;
                try
                {
-                       TimeTaker timer1("emerge load", g_device, &emerge_load_time);
+                       TimeTaker timer1("emerge load", g_irrlicht, &emerge_load_time);
 
                        /*dstream<<"Loading block (caller_id="<<caller_id<<")"
                                        <<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@@ -3082,7 +3082,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
 #if 0
 void MapVoxelManipulator::emerge(VoxelArea a)
 {
-       TimeTaker timer1("emerge", g_device, &emerge_time);
+       TimeTaker timer1("emerge", g_irrlicht, &emerge_time);
        
        v3s16 size = a.getExtent();
        
@@ -3101,7 +3101,7 @@ void MapVoxelManipulator::emerge(VoxelArea a)
                        continue;
                try
                {
-                       TimeTaker timer1("emerge load", g_device, &emerge_load_time);
+                       TimeTaker timer1("emerge load", g_irrlicht, &emerge_load_time);
                        MapNode n = m_map->getNode(a.MinEdge + p);
                        m_data[i] = n;
                        m_flags[i] = 0;
@@ -3126,7 +3126,7 @@ void MapVoxelManipulator::blitBack
        if(m_area.getExtent() == v3s16(0,0,0))
                return;
        
-       //TimeTaker timer1("blitBack", g_device);
+       //TimeTaker timer1("blitBack", g_irrlicht);
        
        /*
                Initialize block cache
index 9372c8fb1a6f23a0226f1df77836d09fb4361bf0..af08cadaa45b3c870b040069690ec713dd46ed76 100644 (file)
@@ -646,7 +646,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                        
                        if(f.tile.feature == TILEFEAT_NONE)
                        {
-                               collector.append(g_tile_materials[f.tile.id], f.vertices, 4,
+                               /*collector.append(g_tile_materials[f.tile.id], f.vertices, 4,
+                                               indices, 6);*/
+                               collector.append(tile_material_get(f.tile.id), f.vertices, 4,
                                                indices, 6);
                        }
                        else
@@ -748,16 +750,21 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                                        = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                        if(dir == v3s16(0,-1,0))
                                buf->getMaterial().setTexture(0,
-                                               g_texturecache.get("torch_on_floor"));
+                                               g_irrlicht->getTexture("../data/torch_on_floor.png"));
+                                               //g_texturecache.get("torch_on_floor"));
                        else if(dir == v3s16(0,1,0))
                                buf->getMaterial().setTexture(0,
-                                               g_texturecache.get("torch_on_ceiling"));
+                                               g_irrlicht->getTexture("../data/torch_on_ceiling.png"));
+                                               //g_texturecache.get("torch_on_ceiling"));
                        // For backwards compatibility
                        else if(dir == v3s16(0,0,0))
                                buf->getMaterial().setTexture(0,
-                                               g_texturecache.get("torch_on_floor"));
+                                               g_irrlicht->getTexture("../data/torch_on_floor.png"));
+                                               //g_texturecache.get("torch_on_floor"));
                        else
-                               buf->getMaterial().setTexture(0, g_texturecache.get("torch"));
+                               buf->getMaterial().setTexture(0, 
+                                               g_irrlicht->getTexture("../data/torch.png"));
+                               //buf->getMaterial().setTexture(0, g_texturecache.get("torch"));
 
                        // Add to mesh
                        mesh_new->addMeshBuffer(buf);
index 883c188427ad3b649bc1b486c5b6494f8ac21835..c41560ee5d465ae69276be3ab03e242af6a82c93 100644 (file)
@@ -46,16 +46,16 @@ u16 g_content_tiles[USEFUL_CONTENT_COUNT][6] =
 
 const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] =
 {
-       "stone",
-       "grass",
-       "water",
-       "torch_on_floor",
-       "tree_top",
-       "leaves",
-       "grass_footsteps",
-       "mese",
-       "mud",
-       "water",
-       "cloud",
+       "../data/stone.png",
+       "../data/grass.png",
+       "../data/water.png",
+       "../data/torch_on_floor.png",
+       "../data/tree_top.png",
+       "../data/leaves.png",
+       "../data/grass_footsteps.png",
+       "../data/mese.png",
+       "../data/mud.png",
+       "../data/water.png",
+       "../data/cloud.png",
 };
 
index 9f139d82512bed1581c5909660fbd9526dbce9b4..5938b91d4b783ac96100fa415f6d9537038cb298 100644 (file)
@@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 /*
-(c) 2010 Perttu Ahola <celeron55@gmail.com>
+       Random portability stuff
 */
 
 #ifndef PORTING_HEADER
index 5161b22848244d7b7a40db416f6b72d10ad828a8..174c72fdfbf0870b0c7ed9f4ca8360719b0b9b44 100644 (file)
@@ -18,36 +18,40 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "tile.h"
+#include "irrlichtwrapper.h"
 
-const char * g_tile_texture_names[TILES_COUNT] =
+// A mapping from tiles to paths of textures
+const char * g_tile_texture_paths[TILES_COUNT] =
 {
        NULL,
-       "stone",
-       "water",
-       "grass",
-       "tree",
-       "leaves",
-       "grass_footsteps",
-       "mese",
-       "mud",
-       "tree_top",
-       "mud_with_grass",
-       "cloud",
+       "../data/stone.png",
+       "../data/water.png",
+       "../data/grass.png",
+       "../data/tree.png",
+       "../data/leaves.png",
+       "../data/grass_footsteps.png",
+       "../data/mese.png",
+       "../data/mud.png",
+       "../data/tree_top.png",
+       "../data/mud_with_grass.png",
+       "../data/cloud.png",
 };
 
+// A mapping from tiles to materials
+// Initialized at run-time.
 video::SMaterial g_tile_materials[TILES_COUNT];
 
-void tile_materials_preload(TextureCache &cache)
+void tile_materials_preload(IrrlichtWrapper *irrlicht)
 {
        for(s32 i=0; i<TILES_COUNT; i++)
        {
-               const char *name = g_tile_texture_names[i];
+               const char *path = g_tile_texture_paths[i];
 
                video::ITexture *t = NULL;
 
-               if(name != NULL)
+               if(path != NULL)
                {
-                       t = cache.get(name);
+                       t = irrlicht->getTexture(path);
                        assert(t != NULL);
                }
 
@@ -68,3 +72,10 @@ void tile_materials_preload(TextureCache &cache)
        //g_tile_materials[TILE_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
 }
 
+video::SMaterial & tile_material_get(u32 i)
+{
+       assert(i < TILES_COUNT);
+
+       return g_tile_materials[i];
+}
+
index f1aa100fcca3d1dfaa4b267cbd2a63fcf910df49..d9756766124581880bf9ada047865f4abe2e5625 100644 (file)
@@ -93,18 +93,16 @@ struct TileSpec
        } param;
 };
 
-// A mapping from tiles to names of cached textures
-extern const char * g_tile_texture_names[TILES_COUNT];
-
-// A mapping from tiles to materials
-// Initialized at run-time.
-extern video::SMaterial g_tile_materials[TILES_COUNT];
+/*extern const char * g_tile_texture_paths[TILES_COUNT];
+extern video::SMaterial g_tile_materials[TILES_COUNT];*/
 
 /*
        Functions
 */
 
 // Initializes g_tile_materials
-void tile_materials_preload(TextureCache &cache);
+void tile_materials_preload(IrrlichtWrapper *irrlicht);
+
+video::SMaterial & tile_material_get(u32 i);
 
 #endif
index 5f3833e167397d75c4558b9b7158f4bc4e088d80..3da2f48d56766f947c218827ab417b3a7d0ebc97 100644 (file)
@@ -22,6 +22,49 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "utility.h"
+#include "irrlichtwrapper.h"
+
+TimeTaker::TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result)
+{
+       m_name = name;
+       m_irrlicht = irrlicht;
+       m_result = result;
+       m_running = true;
+       if(irrlicht == NULL)
+       {
+               m_time1 = 0;
+               return;
+       }
+       m_time1 = m_irrlicht->getTime();
+}
+
+u32 TimeTaker::stop(bool quiet)
+{
+       if(m_running)
+       {
+               if(m_irrlicht == NULL)
+               {
+                       /*if(quiet == false)
+                               std::cout<<"Couldn't measure time for "<<m_name
+                                               <<": irrlicht==NULL"<<std::endl;*/
+                       return 0;
+               }
+               u32 time2 = m_irrlicht->getTime();
+               u32 dtime = time2 - m_time1;
+               if(m_result != NULL)
+               {
+                       (*m_result) += dtime;
+               }
+               else
+               {
+                       if(quiet == false)
+                               std::cout<<m_name<<" took "<<dtime<<"ms"<<std::endl;
+               }
+               m_running = false;
+               return dtime;
+       }
+       return 0;
+}
 
 const v3s16 g_26dirs[26] =
 {
index e4494948c1d9e77adfdf41151763b10a0c8e665f..cde5557605137cf19765a18afc5ad1fb27a3289d 100644 (file)
@@ -17,10 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-/*
-(c) 2010 Perttu Ahola <celeron55@gmail.com>
-*/
-
 #ifndef UTILITY_HEADER
 #define UTILITY_HEADER
 
@@ -403,56 +399,23 @@ private:
        TimeTaker
 */
 
+class IrrlichtWrapper;
+
 class TimeTaker
 {
 public:
-       TimeTaker(const char *name, IrrlichtDevice *dev, u32 *result=NULL)
-       {
-               m_name = name;
-               m_dev = dev;
-               m_result = result;
-               m_running = true;
-               if(dev == NULL)
-               {
-                       m_time1 = 0;
-                       return;
-               }
-               m_time1 = m_dev->getTimer()->getRealTime();
-       }
+       TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result=NULL);
+
        ~TimeTaker()
        {
                stop();
        }
-       u32 stop(bool quiet=false)
-       {
-               if(m_running)
-               {
-                       if(m_dev == NULL)
-                       {
-                               /*if(quiet == false)
-                                       std::cout<<"Couldn't measure time for "<<m_name
-                                                       <<": dev==NULL"<<std::endl;*/
-                               return 0;
-                       }
-                       u32 time2 = m_dev->getTimer()->getRealTime();
-                       u32 dtime = time2 - m_time1;
-                       if(m_result != NULL)
-                       {
-                               (*m_result) += dtime;
-                       }
-                       else
-                       {
-                               if(quiet == false)
-                                       std::cout<<m_name<<" took "<<dtime<<"ms"<<std::endl;
-                       }
-                       m_running = false;
-                       return dtime;
-               }
-               return 0;
-       }
+
+       u32 stop(bool quiet=false);
+
 private:
        const char *m_name;
-       IrrlichtDevice *m_dev;
+       IrrlichtWrapper *m_irrlicht;
        u32 m_time1;
        bool m_running;
        u32 *m_result;
@@ -673,6 +636,48 @@ inline s32 stoi(std::string s)
        return atoi(s.c_str());
 }
 
+/*
+       A base class for simple background thread implementation
+*/
+
+class SimpleThread : public JThread
+{
+       bool run;
+       JMutex run_mutex;
+
+public:
+
+       SimpleThread():
+               JThread(),
+               run(true)
+       {
+               run_mutex.Init();
+       }
+
+       virtual ~SimpleThread()
+       {}
+
+       virtual void * Thread() = 0;
+
+       bool getRun()
+       {
+               JMutexAutoLock lock(run_mutex);
+               return run;
+       }
+       void setRun(bool a_run)
+       {
+               JMutexAutoLock lock(run_mutex);
+               run = a_run;
+       }
+
+       void stop()
+       {
+               setRun(false);
+               while(IsRunning())
+                       sleep_ms(100);
+       }
+};
+
 /*
        Config stuff
 */
@@ -1070,81 +1075,205 @@ private:
 };
 
 /*
-       A thread-safe texture cache.
-
-       This is used so that irrlicht doesn't get called from many threads
+       A thread-safe queue
 */
 
-class TextureCache
+template<typename T>
+class MutexedQueue
 {
 public:
-       TextureCache()
+       MutexedQueue()
        {
                m_mutex.Init();
-               assert(m_mutex.IsInitialized());
+               m_is_empty_mutex.Init();
        }
-       
-       void set(std::string name, video::ITexture *texture)
+       u32 size()
        {
-               JMutexAutoLock lock(m_mutex);
-
-               m_textures[name] = texture;
+               return m_list.size();
        }
-       
-       video::ITexture* get(std::string name)
+       void push_back(T t)
        {
                JMutexAutoLock lock(m_mutex);
+               m_list.push_back(t);
+               
+               if(m_list.size() == 1)
+                       m_is_empty_mutex.Unlock();
+       }
+       T pop_front(bool wait_if_empty=false)
+       {
+               for(;;)
+               {
+                       {
+                               JMutexAutoLock lock(m_mutex);
 
-               core::map<std::string, video::ITexture*>::Node *n;
-               n = m_textures.find(name);
+                               if(m_list.size() > 0)
+                               {
+                                       if(m_list.size() == 1)
+                                               m_is_empty_mutex.Lock();
+                                       
+                                       typename core::list<T>::Iterator begin = m_list.begin();
+                                       T t = *begin;
+                                       m_list.erase(begin);
+                                       return t;
+                               }
 
-               if(n != NULL)
-                       return n->getValue();
+                               if(wait_if_empty == false)
+                                       throw ItemNotFoundException("MutexedQueue: item not found");
+                       }
+                       
+                       // To wait for an empty list, we're gonna hang on this mutex
+                       m_is_empty_mutex.Lock();
+                       m_is_empty_mutex.Unlock();
 
-               return NULL;
+                       // Then loop to the beginning and hopefully return something
+               }
        }
 
-private:
-       core::map<std::string, video::ITexture*> m_textures;
+       JMutex & getMutex()
+       {
+               return m_mutex;
+       }
+
+       JMutex & getIsEmptyMutex()
+       {
+               return m_is_empty_mutex;
+       }
+       
+       core::list<T> & getList()
+       {
+               return m_list;
+       }
+
+protected:
        JMutex m_mutex;
+       // This is locked always when the list is empty
+       JMutex m_is_empty_mutex;
+       core::list<T> m_list;
 };
 
-class SimpleThread : public JThread
+template<typename Caller, typename Data>
+class CallerInfo
 {
-       bool run;
-       JMutex run_mutex;
+public:
+       Caller caller;
+       Data data;
+};
 
+template<typename Key, typename T, typename Caller, typename CallerData>
+class GetResult
+{
 public:
+       Key key;
+       T item;
+       core::list<CallerInfo<Caller, CallerData> > callers;
+};
 
-       SimpleThread():
-               JThread(),
-               run(true)
+template<typename Key, typename T, typename Caller, typename CallerData>
+class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
+{
+};
+
+template<typename Key, typename T, typename Caller, typename CallerData>
+class GetRequest
+{
+public:
+       GetRequest()
        {
-               run_mutex.Init();
+               dest = NULL;
        }
+       GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
+       {
+               dest = a_dest;
+       }
+       GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
+                       Key a_key)
+       {
+               dest = a_dest;
+               key = a_key;
+       }
+       ~GetRequest()
+       {
+       }
+       
+       Key key;
+       ResultQueue<Key, T, Caller, CallerData> *dest;
+       core::list<CallerInfo<Caller, CallerData> > callers;
+};
 
-       virtual ~SimpleThread()
-       {}
-
-       virtual void * Thread() = 0;
+/*
+       Quickhands for typical request-result queues.
+       Used for distributing work between threads.
+*/
 
-       bool getRun()
+template<typename Key, typename T, typename Caller, typename CallerData>
+class RequestQueue
+{
+public:
+       u32 size()
        {
-               JMutexAutoLock lock(run_mutex);
-               return run;
+               return m_queue.size();
        }
-       void setRun(bool a_run)
+
+       void add(Key key, Caller caller, CallerData callerdata,
+                       ResultQueue<Key, T, Caller, CallerData> *dest)
        {
-               JMutexAutoLock lock(run_mutex);
-               run = a_run;
+               JMutexAutoLock lock(m_queue.getMutex());
+               
+               /*
+                       If the caller is already on the list, only update CallerData
+               */
+               for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
+                               i = m_queue.getList().begin();
+                               i != m_queue.getList().end(); i++)
+               {
+                       GetRequest<Key, T, Caller, CallerData> &request = *i;
+
+                       if(request.key == key)
+                       {
+                               for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
+                                               i = request.callers.begin();
+                                               i != request.callers.end(); i++)
+                               {
+                                       CallerInfo<Caller, CallerData> &ca = *i;
+                                       if(ca.caller == caller)
+                                       {
+                                               ca.data = callerdata;
+                                               return;
+                                       }
+                               }
+                               CallerInfo<Caller, CallerData> ca;
+                               ca.caller = caller;
+                               ca.data = callerdata;
+                               request.callers.push_back(ca);
+                               return;
+                       }
+               }
+
+               /*
+                       Else add a new request to the queue
+               */
+
+               GetRequest<Key, T, Caller, CallerData> request;
+               request.key = key;
+               CallerInfo<Caller, CallerData> ca;
+               ca.caller = caller;
+               ca.data = callerdata;
+               request.callers.push_back(ca);
+               request.dest = dest;
+               
+               m_queue.getList().push_back(request);
+               
+               if(m_queue.getList().size() == 1)
+                       m_queue.getIsEmptyMutex().Unlock();
        }
 
-       void stop()
+       GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
        {
-               setRun(false);
-               while(IsRunning())
-                       sleep_ms(100);
+               return m_queue.pop_front(wait_if_empty);
        }
+
+private:
+       MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
 };
 
 #endif
index f8a98942cc7e72873803875a4c91791ce09a10d0..29f79992b750f1b30211685ad7539c6c92b6bcf9 100644 (file)
@@ -138,7 +138,7 @@ void VoxelManipulator::addArea(VoxelArea area)
        if(m_area.contains(area))
                return;
        
-       TimeTaker timer("addArea", g_device, &addarea_time);
+       TimeTaker timer("addArea", g_irrlicht, &addarea_time);
 
        // Calculate new area
        VoxelArea new_area;
@@ -290,7 +290,7 @@ void VoxelManipulator::interpolate(VoxelArea area)
 void VoxelManipulator::clearFlag(u8 flags)
 {
        // 0-1ms on moderate area
-       TimeTaker timer("clearFlag", g_device, &clearflag_time);
+       TimeTaker timer("clearFlag", g_irrlicht, &clearflag_time);
 
        v3s16 s = m_area.getExtent();
 
@@ -539,7 +539,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
                core::map<v3s16, u8> &active_nodes,
                bool checked3_is_clear)
 {
-       TimeTaker timer("updateAreaWaterPressure", g_device,
+       TimeTaker timer("updateAreaWaterPressure", g_irrlicht,
                        &updateareawaterpressure_time);
 
        emerge(a, 3);
@@ -585,7 +585,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
                try
                {
                        // 0-1ms @ recur_count <= 100
-                       //TimeTaker timer("getWaterPressure", g_device);
+                       //TimeTaker timer("getWaterPressure", g_irrlicht);
                        pr = getWaterPressure(p, highest_y, recur_count);
                }
                catch(ProcessingLimitException &e)
@@ -613,7 +613,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
                try
                {
                        // 0ms
-                       //TimeTaker timer("spreadWaterPressure", g_device);
+                       //TimeTaker timer("spreadWaterPressure", g_irrlicht);
                        spreadWaterPressure(p, pr, a, active_nodes, 0);
                }
                catch(ProcessingLimitException &e)
@@ -653,7 +653,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
        //dstream<<"s1="<<s1<<", s2="<<s2<<std::endl;
 
        {
-       TimeTaker timer1("flowWater pre", g_device, &flowwater_pre_time);
+       TimeTaker timer1("flowWater pre", g_irrlicht, &flowwater_pre_time);
        
        // Load neighboring nodes
        emerge(VoxelArea(removed_pos - v3s16(1,1,1), removed_pos + v3s16(1,1,1)), 4);
@@ -802,9 +802,9 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
                                debugprint, stoptime);
        }
        
-       if(stoptime != 0 && g_device != NULL)
+       if(stoptime != 0 && g_irrlicht != NULL)
        {
-               u32 timenow = g_device->getTimer()->getRealTime();
+               u32 timenow = g_irrlicht->getTime();
                if(timenow >= stoptime ||
                                (stoptime < 0x80000000 && timenow > 0x80000000))
                {
@@ -870,15 +870,15 @@ void VoxelManipulator::flowWater(
                return;
        }
 
-       //TimeTaker timer1("flowWater (active_nodes)", g_device);
+       //TimeTaker timer1("flowWater (active_nodes)", g_irrlicht);
 
        //dstream<<"active_nodes.size() = "<<active_nodes.size()<<std::endl;
 
 
        u32 stoptime = 0;
-       if(g_device != NULL)
+       if(g_irrlicht != NULL)
        {
-               stoptime = g_device->getTimer()->getRealTime() + timelimit;
+               stoptime = g_irrlicht->getTime() + timelimit;
        }
 
        // Count of handled active nodes