]> git.lizzy.rs Git - minetest.git/blobdiff - src/map.h
added dedicated server build without irrlicht
[minetest.git] / src / map.h
index 482ab2ac79ef03e547af42d067e29125925d6bc9..581708a361efc2a0975be1e020bdc57450d6035a 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -1,5 +1,20 @@
 /*
-(c) 2010 Perttu Ahola <celeron55@gmail.com>
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 #ifndef MAP_HEADER
 #include "mapblock.h"
 #include "mapsector.h"
 #include "constants.h"
+#include "voxel.h"
 
-class InvalidFilenameException : public BaseException
+class Map;
+
+/*
+       A cache for short-term fast access to map data
+
+       NOTE: This doesn't really make anything more efficient
+       NOTE: Use VoxelManipulator, if possible
+       TODO: Get rid of this?
+       NOTE: CONFIRMED: THIS CACHE DOESN'T MAKE ANYTHING ANY FASTER
+*/
+class MapBlockPointerCache : public NodeContainer
 {
 public:
-       InvalidFilenameException(const char *s):
-               BaseException(s)
-       {}
+       MapBlockPointerCache(Map *map);
+       ~MapBlockPointerCache();
+
+       virtual u16 nodeContainerId() const
+       {
+               return NODECONTAINER_ID_MAPBLOCKCACHE;
+       }
+
+       MapBlock * getBlockNoCreate(v3s16 p);
+
+       // virtual from NodeContainer
+       bool isValidPosition(v3s16 p)
+       {
+               v3s16 blockpos = getNodeBlockPos(p);
+               MapBlock *blockref;
+               try{
+                       blockref = getBlockNoCreate(blockpos);
+               }
+               catch(InvalidPositionException &e)
+               {
+                       return false;
+               }
+               return true;
+       }
+       
+       // virtual from NodeContainer
+       MapNode getNode(v3s16 p)
+       {
+               v3s16 blockpos = getNodeBlockPos(p);
+               MapBlock * blockref = getBlockNoCreate(blockpos);
+               v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+
+               return blockref->getNodeNoCheck(relpos);
+       }
+
+       // virtual from NodeContainer
+       void setNode(v3s16 p, MapNode & n)
+       {
+               v3s16 blockpos = getNodeBlockPos(p);
+               MapBlock * block = getBlockNoCreate(blockpos);
+               v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+               block->setNodeNoCheck(relpos, n);
+               m_modified_blocks[blockpos] = block;
+       }
+
+       core::map<v3s16, MapBlock*> m_modified_blocks;
+       
+private:
+       Map *m_map;
+       core::map<v3s16, MapBlock*> m_blocks;
+
+       u32 m_from_cache_count;
+       u32 m_from_map_count;
+};
+
+class CacheLock
+{
+public:
+       CacheLock()
+       {
+               m_count = 0;
+               m_count_mutex.Init();
+               m_cache_mutex.Init();
+               m_waitcache_mutex.Init();
+       }
+
+       void cacheCreated()
+       {
+               //dstream<<"cacheCreated() begin"<<std::endl;
+               JMutexAutoLock waitcachelock(m_waitcache_mutex);
+               JMutexAutoLock countlock(m_count_mutex);
+
+               // If this is the first cache, grab the cache lock
+               if(m_count == 0)
+                       m_cache_mutex.Lock();
+                       
+               m_count++;
+
+               //dstream<<"cacheCreated() end"<<std::endl;
+       }
+
+       void cacheRemoved()
+       {
+               //dstream<<"cacheRemoved() begin"<<std::endl;
+               JMutexAutoLock countlock(m_count_mutex);
+
+               assert(m_count > 0);
+
+               m_count--;
+               
+               // If this is the last one, release the cache lock
+               if(m_count == 0)
+                       m_cache_mutex.Unlock();
+
+               //dstream<<"cacheRemoved() end"<<std::endl;
+       }
+
+       /*
+               This lock should be taken when removing stuff that can be
+               pointed by the cache.
+
+               You'll want to grab this in a SharedPtr.
+       */
+       JMutexAutoLock * waitCaches()
+       {
+               //dstream<<"waitCaches() begin"<<std::endl;
+               JMutexAutoLock waitcachelock(m_waitcache_mutex);
+               JMutexAutoLock *lock = new JMutexAutoLock(m_cache_mutex);
+               //dstream<<"waitCaches() end"<<std::endl;
+               return lock;
+       }
+
+private:
+       // Count of existing caches
+       u32 m_count;
+       JMutex m_count_mutex;
+       // This is locked always when there are some caches
+       JMutex m_cache_mutex;
+       // Locked so that when waitCaches() is called, no more caches are created
+       JMutex m_waitcache_mutex;
 };
 
 #define MAPTYPE_BASE 0
@@ -60,6 +203,13 @@ class Map : public NodeContainer, public Heightmappish
 public:
 
        v3s16 drawoffset; // for drawbox()
+       
+       /*
+               Used by MapBlockPointerCache.
+
+               waitCaches() can be called to remove all caches before continuing
+       */
+       CacheLock m_blockcachelock;
 
        Map(std::ostream &dout);
        virtual ~Map();
@@ -74,6 +224,11 @@ class Map : public NodeContainer, public Heightmappish
                return MAPTYPE_BASE;
        }
 
+       virtual void drop()
+       {
+               delete this;
+       }
+
        void updateCamera(v3f pos, v3f dir)
        {
                JMutexAutoLock lock(m_camera_mutex);
@@ -154,7 +309,7 @@ class Map : public NodeContainer, public Heightmappish
                MapBlock * blockref = getBlockNoCreate(blockpos);
                v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
 
-               return blockref->getNode(relpos);
+               return blockref->getNodeNoCheck(relpos);
        }
 
        // virtual from NodeContainer
@@ -163,7 +318,7 @@ class Map : public NodeContainer, public Heightmappish
                v3s16 blockpos = getNodeBlockPos(p);
                MapBlock * blockref = getBlockNoCreate(blockpos);
                v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
-               blockref->setNode(relpos, n);
+               blockref->setNodeNoCheck(relpos, n);
        }
 
        /*MapNode getNodeGenerate(v3s16 p)
@@ -183,25 +338,33 @@ class Map : public NodeContainer, public Heightmappish
                blockref->setNode(relpos, n);
        }*/
 
-       void unspreadLight(core::map<v3s16, u8> & from_nodes,
+       void unspreadLight(enum LightBank bank,
+                       core::map<v3s16, u8> & from_nodes,
                        core::map<v3s16, bool> & light_sources,
                        core::map<v3s16, MapBlock*> & modified_blocks);
 
-       void unLightNeighbors(v3s16 pos, u8 lightwas,
+       void unLightNeighbors(enum LightBank bank,
+                       v3s16 pos, u8 lightwas,
                        core::map<v3s16, bool> & light_sources,
                        core::map<v3s16, MapBlock*> & modified_blocks);
        
-       void spreadLight(core::map<v3s16, bool> & from_nodes,
+       void spreadLight(enum LightBank bank,
+                       core::map<v3s16, bool> & from_nodes,
                        core::map<v3s16, MapBlock*> & modified_blocks);
        
-       void lightNeighbors(v3s16 pos,
+       void lightNeighbors(enum LightBank bank,
+                       v3s16 pos,
                        core::map<v3s16, MapBlock*> & modified_blocks);
 
-       v3s16 getBrightestNeighbour(v3s16 p);
+       v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
 
        s16 propagateSunlight(v3s16 start,
                        core::map<v3s16, MapBlock*> & modified_blocks);
        
+       void updateLighting(enum LightBank bank,
+                       core::map<v3s16, MapBlock*>  & a_blocks,
+                       core::map<v3s16, MapBlock*> & modified_blocks);
+                       
        void updateLighting(core::map<v3s16, MapBlock*>  & a_blocks,
                        core::map<v3s16, MapBlock*> & modified_blocks);
                        
@@ -213,11 +376,20 @@ class Map : public NodeContainer, public Heightmappish
        void removeNodeAndUpdate(v3s16 p,
                        core::map<v3s16, MapBlock*> &modified_blocks);
        
+#ifndef SERVER
+       void expireMeshes(bool only_daynight_diffed);
+       
        /*
                Updates the faces of the given block and blocks on the
                leading edge.
        */
-       void updateMeshes(v3s16 blockpos);
+       void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
+#endif
+
+       /*
+               Takes the blocks at the trailing edges into account
+       */
+       bool dayNightDiffed(v3s16 blockpos);
 
        //core::aabbox3d<s16> getDisplayedBlockArea();
 
@@ -247,15 +419,15 @@ struct HMParams
 {
        HMParams()
        {
-               heightmap_blocksize = 64;
-               height_randmax = "constant 70.0";
-               height_randfactor = "constant 0.6";
-               height_base = "linear 0 80 0";
+               blocksize = 64;
+               randmax = "constant 70.0";
+               randfactor = "constant 0.6";
+               base = "linear 0 80 0";
        }
-       s16 heightmap_blocksize;
-       std::string height_randmax;
-       std::string height_randfactor;
-       std::string height_base;
+       s16 blocksize;
+       std::string randmax;
+       std::string randfactor;
+       std::string base;
 };
 
 // Map parameters
@@ -264,9 +436,11 @@ struct MapParams
        MapParams()
        {
                plants_amount = 1.0;
+               ravines_amount = 1.0;
                //max_objects_in_block = 30;
        }
        float plants_amount;
+       float ravines_amount;
        //u16 max_objects_in_block;
 };
 
@@ -363,6 +537,8 @@ class ServerMap : public Map
        bool m_map_saving_enabled;
 };
 
+#ifndef SERVER
+
 class Client;
 
 class ClientMap : public Map, public scene::ISceneNode
@@ -370,7 +546,9 @@ class ClientMap : public Map, public scene::ISceneNode
 public:
        ClientMap(
                        Client *client,
-                       video::SMaterial *materials,
+                       JMutex &range_mutex,
+                       s16 &viewing_range_nodes,
+                       bool &viewing_range_all,
                        scene::ISceneNode* parent,
                        scene::ISceneManager* mgr,
                        s32 id
@@ -383,6 +561,11 @@ class ClientMap : public Map, public scene::ISceneNode
                return MAPTYPE_CLIENT;
        }
 
+       void drop()
+       {
+               ISceneNode::drop();
+       }
+
        /*
                Forcefully get a sector from somewhere
        */
@@ -394,23 +577,13 @@ class ClientMap : public Map, public scene::ISceneNode
                ISceneNode methods
        */
 
-       virtual void OnRegisterSceneNode()
-       {
-               if(IsVisible)
-               {
-                       //SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX);
-                       SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
-                       SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
-               }
-
-               ISceneNode::OnRegisterSceneNode();
-       }
+       virtual void OnRegisterSceneNode();
 
        virtual void render()
        {
                video::IVideoDriver* driver = SceneManager->getVideoDriver();
                driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
-               renderMap(driver, m_materials, SceneManager->getSceneNodeRenderPass());
+               renderMap(driver, SceneManager->getSceneNodeRenderPass());
        }
        
        virtual const core::aabbox3d<f32>& getBoundingBox() const
@@ -418,8 +591,7 @@ class ClientMap : public Map, public scene::ISceneNode
                return m_box;
        }
 
-       void renderMap(video::IVideoDriver* driver,
-               video::SMaterial *materials, s32 pass);
+       void renderMap(video::IVideoDriver* driver, s32 pass);
 
        // Update master heightmap mesh
        void updateMesh();
@@ -430,13 +602,44 @@ class ClientMap : public Map, public scene::ISceneNode
 private:
        Client *m_client;
        
-       video::SMaterial *m_materials;
-
        core::aabbox3d<f32> m_box;
        
        // This is the master heightmap mesh
        scene::SMesh *mesh;
        JMutex mesh_mutex;
+
+       JMutex &m_range_mutex;
+       s16 &m_viewing_range_nodes;
+       bool &m_viewing_range_all;
+};
+
+#endif
+
+class MapVoxelManipulator : public VoxelManipulator
+{
+public:
+       MapVoxelManipulator(Map *map);
+       virtual ~MapVoxelManipulator();
+       
+       virtual void clear()
+       {
+               VoxelManipulator::clear();
+               m_loaded_blocks.clear();
+       }
+
+       virtual void emerge(VoxelArea a, s32 caller_id=-1);
+
+       void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
+
+private:
+       Map *m_map;
+       /*
+               NOTE: This might be used or not
+               bool is dummy value
+               SUGG: How 'bout an another VoxelManipulator for storing the
+                     information about which block is loaded?
+       */
+       core::map<v3s16, bool> m_loaded_blocks;
 };
 
 #endif