commit before content-tile separation

This commit is contained in:
Perttu Ahola 2010-12-13 21:32:35 +02:00
parent 22037459e3
commit 3ac2abb0b5
14 changed files with 368 additions and 55 deletions

@ -34,8 +34,8 @@ cp -r data/sign_back.png $PACKAGEPATH/data/
cp -r data/rat.png $PACKAGEPATH/data/ cp -r data/rat.png $PACKAGEPATH/data/
cp -r data/mud.png $PACKAGEPATH/data/ cp -r data/mud.png $PACKAGEPATH/data/
cp -r data/torch.png $PACKAGEPATH/data/ cp -r data/torch.png $PACKAGEPATH/data/
cp -r data/torch_floor.png $PACKAGEPATH/data/ cp -r data/torch_on_floor.png $PACKAGEPATH/data/
cp -r data/torch_ceiling.png $PACKAGEPATH/data/ cp -r data/torch_on_ceiling.png $PACKAGEPATH/data/
cp -r data/skybox1.png $PACKAGEPATH/data/ cp -r data/skybox1.png $PACKAGEPATH/data/
cp -r data/skybox2.png $PACKAGEPATH/data/ cp -r data/skybox2.png $PACKAGEPATH/data/
cp -r data/skybox3.png $PACKAGEPATH/data/ cp -r data/skybox3.png $PACKAGEPATH/data/

@ -57,5 +57,6 @@
#max_block_generate_distance = 6 #max_block_generate_distance = 6
#disable_water_climb = true #disable_water_climb = true
# Note that this gets applied at map generation time
#endless_water = true #endless_water = true

@ -41,6 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10) #define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10)
#define SERVER_MAP_SAVE_INTERVAL (60) #define SERVER_MAP_SAVE_INTERVAL (60)
/*#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (10)
#define SERVER_MAP_SAVE_INTERVAL (10)*/
#define FOV_ANGLE (PI/2.5) #define FOV_ANGLE (PI/2.5)

@ -172,25 +172,23 @@ TODO: Remove LazyMeshUpdater. It is not used as supposed.
FIXME: Rats somehow go underground sometimes (you can see it in water) FIXME: Rats somehow go underground sometimes (you can see it in water)
- Does their position get saved to a border value or something? - Does their position get saved to a border value or something?
- Does this happen anymore?
SUGG: MovingObject::move and Player::move are basically the same. SUGG: MovingObject::move and Player::move are basically the same.
combine them. combine them.
TODO: Transfer sign texts as metadata of block and not as data of
object
SUGG: Implement a "Fast check queue" (a queue with a map for checking SUGG: Implement a "Fast check queue" (a queue with a map for checking
if something is already in it) if something is already in it)
- TODO: Use it in active block queue in water flowing - Use it in active block queue in water flowing
TODO: Proper looking torches. SUGG: Signs could be done in the same way as torches. For this, blocks
- Signs could be done in the same way? need an additional metadata field for the texts
TODO: A mapper to map contents to tile names (for each side)
Doing now: Doing now:
====================================================================== ======================================================================
TODO: A mapper to map contents to tile names (for each side)
====================================================================== ======================================================================
*/ */

@ -1504,7 +1504,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
sector->setHeightmap(p_in_sector, hm); sector->setHeightmap(p_in_sector, hm);
//TODO: Make these values configurable //TODO: Make these values configurable
hm->generateContinued(1.0, 0.2, corners); hm->generateContinued(0.0, 0.0, corners);
//hm->generateContinued(1.0, 0.2, corners);
//hm->generateContinued(2.0, 0.2, corners); //hm->generateContinued(2.0, 0.2, corners);
//hm->print(); //hm->print();
@ -3242,8 +3243,8 @@ MapVoxelManipulator::MapVoxelManipulator(Map *map)
MapVoxelManipulator::~MapVoxelManipulator() MapVoxelManipulator::~MapVoxelManipulator()
{ {
dstream<<"MapVoxelManipulator: blocks: "<<m_loaded_blocks.size() /*dstream<<"MapVoxelManipulator: blocks: "<<m_loaded_blocks.size()
<<std::endl; <<std::endl;*/
} }
#if 1 #if 1
@ -3358,7 +3359,7 @@ void MapVoxelManipulator::blitBack
if(m_area.getExtent() == v3s16(0,0,0)) if(m_area.getExtent() == v3s16(0,0,0))
return; return;
TimeTaker timer1("blitBack", g_device); //TimeTaker timer1("blitBack", g_device);
/* /*
Initialize block cache Initialize block cache

@ -68,7 +68,7 @@ void MapBlock::setNodeParent(v3s16 p, MapNode & n)
} }
} }
FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p, FastFace * MapBlock::makeFastFace(u16 tile, u8 light, v3f p,
v3f dir, v3f scale, v3f posRelative_f) v3f dir, v3f scale, v3f posRelative_f)
{ {
FastFace *f = new FastFace; FastFace *f = new FastFace;
@ -111,7 +111,9 @@ FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p,
u8 alpha = 255; u8 alpha = 255;
if(material == CONTENT_WATER || material == CONTENT_OCEAN) //if(material == CONTENT_WATER || material == CONTENT_OCEAN)
if(tile == CONTENT_WATER || tile == CONTENT_OCEAN)
//if(tile == TILE_WATER)
{ {
alpha = 128; alpha = 128;
} }
@ -135,7 +137,7 @@ FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p,
f->vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c, f->vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
core::vector2d<f32>(0,0)); core::vector2d<f32>(0,0));
f->material = material; f->tile = tile;
return f; return f;
} }
@ -475,7 +477,9 @@ void MapBlock::updateMesh()
const u16 indices[] = {0,1,2,2,3,0}; const u16 indices[] = {0,1,2,2,3,0};
collector.append(g_materials[f->material], f->vertices, 4, /*collector.append(g_materials[f->material], f->vertices, 4,
indices, 6);*/
collector.append(g_materials[f->tile], f->vertices, 4,
indices, 6); indices, 6);
} }
@ -817,8 +821,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
os.write((char*)*dest, dest.getSize()); os.write((char*)*dest, dest.getSize());
} }
// All otherversions else if(version <= 10)
else
{ {
/* /*
With compression. With compression.
@ -857,6 +860,44 @@ void MapBlock::serialize(std::ostream &os, u8 version)
compress(pressuredata, os, version); compress(pressuredata, os, version);
} }
} }
// All other versions (newest)
else
{
// First byte
os.write((char*)&is_underground, 1);
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
/*
Get data
*/
SharedBuffer<u8> databuf(nodecount*3);
// Get contents
for(u32 i=0; i<nodecount; i++)
{
databuf[i] = data[i].d;
}
// Get params
for(u32 i=0; i<nodecount; i++)
{
databuf[i+nodecount] = data[i].param;
}
// Get pressure
for(u32 i=0; i<nodecount; i++)
{
databuf[i+nodecount*2] = data[i].pressure;
}
/*
Compress data to output stream
*/
compress(databuf, os, version);
}
} }
void MapBlock::deSerialize(std::istream &is, u8 version) void MapBlock::deSerialize(std::istream &is, u8 version)
@ -885,8 +926,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
data[i].deSerialize(*d, version); data[i].deSerialize(*d, version);
} }
} }
// All other versions else if(version <= 10)
else
{ {
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
@ -936,6 +976,39 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
} }
} }
} }
// All other versions (newest)
else
{
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
u8 t8;
is.read((char*)&t8, 1);
is_underground = t8;
// Uncompress data
std::ostringstream os(std::ios_base::binary);
decompress(is, os, version);
std::string s = os.str();
if(s.size() != nodecount*3)
throw SerializationError
("MapBlock::deSerialize: invalid format");
// Set contents
for(u32 i=0; i<nodecount; i++)
{
data[i].d = s[i];
}
// Set params
for(u32 i=0; i<nodecount; i++)
{
data[i].param = s[i+nodecount];
}
// Set pressure
for(u32 i=0; i<nodecount; i++)
{
data[i].pressure = s[i+nodecount*2];
}
}
} }

@ -46,7 +46,7 @@ enum{
struct FastFace struct FastFace
{ {
u8 material; u16 tile;
video::S3DVertex vertices[4]; // Precalculated vertices video::S3DVertex vertices[4]; // Precalculated vertices
}; };
@ -283,7 +283,7 @@ public:
setNode(x0+x, y0+y, z0+z, node); setNode(x0+x, y0+y, z0+z, node);
} }
static FastFace * makeFastFace(u8 material, u8 light, v3f p, static FastFace * makeFastFace(u16 tile, u8 light, v3f p,
v3f dir, v3f scale, v3f posRelative_f); v3f dir, v3f scale, v3f posRelative_f);
u8 getFaceLight(v3s16 p, v3s16 face_dir); u8 getFaceLight(v3s16 p, v3s16 face_dir);

@ -66,23 +66,23 @@ enum Content
{ {
CONTENT_STONE=0, CONTENT_STONE=0,
CONTENT_GRASS, CONTENT_GRASS=1,
CONTENT_WATER, CONTENT_WATER=2,
CONTENT_LIGHT, CONTENT_LIGHT=3,
CONTENT_TREE, CONTENT_TREE=4,
CONTENT_LEAVES, CONTENT_LEAVES=5,
CONTENT_GRASS_FOOTSTEPS, CONTENT_GRASS_FOOTSTEPS=6,
CONTENT_MESE, CONTENT_MESE=7,
CONTENT_MUD, CONTENT_MUD=8,
CONTENT_OCEAN, CONTENT_OCEAN=9,
// This is set to the number of the actual values in this enum // This is set to the number of the actual values in this enum
USEFUL_CONTENT_COUNT USEFUL_CONTENT_COUNT

@ -17,18 +17,184 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
/*
(c) 2010 Perttu Ahola <celeron55@gmail.com>
*/
#include "serialization.h" #include "serialization.h"
#include "utility.h" #include "utility.h"
#include "zlib.h"
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zerr: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
break;
default:
dstream<<"return value = "<<ret<<"\n";
}
}
void compressZlib(SharedBuffer<u8> data, std::ostream &os)
{
z_stream z;
const s32 bufsize = 16384;
//char input_buffer[bufsize];
char output_buffer[bufsize];
int input_i = 0;
int status = 0;
int ret;
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
ret = deflateInit(&z, -1);
if(ret != Z_OK)
throw SerializationError("compressZlib: deflateInit failed");
z.avail_in = 0;
for(;;)
{
int flush = Z_NO_FLUSH;
z.next_out = (Bytef*)output_buffer;
z.avail_out = bufsize;
if(z.avail_in == 0)
{
//z.next_in = (char*)&data[input_i];
z.next_in = (Bytef*)&data[input_i];
z.avail_in = data.getSize() - input_i;
input_i += z.avail_in;
if(input_i == (int)data.getSize())
flush = Z_FINISH;
}
if(z.avail_in == 0)
break;
status = deflate(&z, flush);
if(status == Z_NEED_DICT || status == Z_DATA_ERROR
|| status == Z_MEM_ERROR)
{
zerr(status);
throw SerializationError("compressZlib: deflate failed");
}
int count = bufsize - z.avail_out;
if(count)
os.write(output_buffer, count);
}
deflateEnd(&z);
}
void decompressZlib(std::istream &is, std::ostream &os)
{
z_stream z;
const s32 bufsize = 16384;
char input_buffer[bufsize];
char output_buffer[bufsize];
int status = 0;
int ret;
int bytes_read = 0;
int input_buffer_len = 0;
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
ret = inflateInit(&z);
if(ret != Z_OK)
throw SerializationError("compressZlib: inflateInit failed");
z.avail_in = 0;
//dstream<<"initial fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
for(;;)
{
z.next_out = (Bytef*)output_buffer;
z.avail_out = bufsize;
if(z.avail_in == 0)
{
z.next_in = (Bytef*)input_buffer;
input_buffer_len = is.readsome(input_buffer, bufsize);
z.avail_in = input_buffer_len;
//dstream<<"read fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
}
if(z.avail_in == 0)
{
//dstream<<"z.avail_in == 0"<<std::endl;
break;
}
//dstream<<"1 z.avail_in="<<z.avail_in<<std::endl;
status = inflate(&z, Z_NO_FLUSH);
//dstream<<"2 z.avail_in="<<z.avail_in<<std::endl;
bytes_read += is.gcount() - z.avail_in;
//dstream<<"bytes_read="<<bytes_read<<std::endl;
if(status == Z_NEED_DICT || status == Z_DATA_ERROR
|| status == Z_MEM_ERROR)
{
zerr(status);
throw SerializationError("compressZlib: inflate failed");
}
int count = bufsize - z.avail_out;
//dstream<<"count="<<count<<std::endl;
if(count)
os.write(output_buffer, count);
if(status == Z_STREAM_END)
{
//dstream<<"Z_STREAM_END"<<std::endl;
//dstream<<"z.avail_in="<<z.avail_in<<std::endl;
//dstream<<"fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
// Unget all the data that inflate didn't take
for(u32 i=0; i < z.avail_in; i++)
{
is.unget();
if(is.fail() || is.bad())
{
dstream<<"unget #"<<i<<" failed"<<std::endl;
dstream<<"fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
throw SerializationError("compressZlib: unget failed");
}
}
break;
}
}
inflateEnd(&z);
}
void compress(SharedBuffer<u8> data, std::ostream &os, u8 version) void compress(SharedBuffer<u8> data, std::ostream &os, u8 version)
{ {
if(version >= 11)
{
compressZlib(data, os);
return;
}
if(data.getSize() == 0) if(data.getSize() == 0)
return; return;
// Write length (u32) // Write length (u32)
u8 tmp[4]; u8 tmp[4];
@ -63,6 +229,12 @@ void compress(SharedBuffer<u8> data, std::ostream &os, u8 version)
void decompress(std::istream &is, std::ostream &os, u8 version) void decompress(std::istream &is, std::ostream &os, u8 version)
{ {
if(version >= 11)
{
decompressZlib(is, os);
return;
}
// Read length (u32) // Read length (u32)
u8 tmp[4]; u8 tmp[4];

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
/*
(c) 2010 Perttu Ahola <celeron55@gmail.com>
*/
#ifndef SERIALIZATION_HEADER #ifndef SERIALIZATION_HEADER
#define SERIALIZATION_HEADER #define SERIALIZATION_HEADER
@ -47,11 +43,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
8: (dev) server-initiated block transfers and all kinds of stuff 8: (dev) server-initiated block transfers and all kinds of stuff
9: (dev) block objects 9: (dev) block objects
10: (dev) water pressure 10: (dev) water pressure
11: (dev) zlib'd blocks
*/ */
// This represents an uninitialized or invalid format // This represents an uninitialized or invalid format
#define SER_FMT_VER_INVALID 255 #define SER_FMT_VER_INVALID 255
// Highest supported serialization version // Highest supported serialization version
#define SER_FMT_VER_HIGHEST 10 #define SER_FMT_VER_HIGHEST 11
// Lowest supported serialization version // Lowest supported serialization version
#define SER_FMT_VER_LOWEST 2 #define SER_FMT_VER_LOWEST 2

@ -412,8 +412,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
maximum_simultaneous_block_sends; maximum_simultaneous_block_sends;
if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D) if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
maximum_simultaneous_block_sends_now = {
maximum_simultaneous_block_sends_setting; maximum_simultaneous_block_sends_now =
maximum_simultaneous_block_sends_setting;
}
{ {
JMutexAutoLock lock(m_blocks_sending_mutex); JMutexAutoLock lock(m_blocks_sending_mutex);
@ -971,11 +973,19 @@ void Server::AsyncRunStep()
{ {
JMutexAutoLock lock1(m_step_dtime_mutex); JMutexAutoLock lock1(m_step_dtime_mutex);
dtime = m_step_dtime; dtime = m_step_dtime;
if(dtime < 0.001)
return;
m_step_dtime = 0.0;
} }
// Send blocks to clients
SendBlocks(dtime);
if(dtime < 0.001)
return;
{
JMutexAutoLock lock1(m_step_dtime_mutex);
m_step_dtime = 0.0;
}
//dstream<<"Server steps "<<dtime<<std::endl; //dstream<<"Server steps "<<dtime<<std::endl;
//dstream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl; //dstream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl;
@ -1098,9 +1108,6 @@ void Server::AsyncRunStep()
} }
}*/ }*/
// Send blocks to clients
SendBlocks(dtime);
// Send object positions // Send object positions
{ {
static float counter = 0.0; static float counter = 0.0;
@ -1876,7 +1883,8 @@ void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
writeS16(&reply[6], p.Z); writeS16(&reply[6], p.Z);
memcpy(&reply[8], *blockdata, blockdata.getSize()); memcpy(&reply[8], *blockdata, blockdata.getSize());
//dstream<<"Sending block: packet size: "<<replysize<<std::endl; dstream<<"Sending block ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<": \tpacket size: "<<replysize<<std::endl;
/* /*
Send packet Send packet

@ -72,6 +72,8 @@ struct TestCompress
{ {
void Run() void Run()
{ {
{ // ver 0
SharedBuffer<u8> fromdata(4); SharedBuffer<u8> fromdata(4);
fromdata[0]=1; fromdata[0]=1;
fromdata[1]=5; fromdata[1]=5;
@ -123,6 +125,64 @@ struct TestCompress
{ {
assert(str_out2[i] == fromdata[i]); assert(str_out2[i] == fromdata[i]);
} }
}
{ // ver HIGHEST
SharedBuffer<u8> fromdata(4);
fromdata[0]=1;
fromdata[1]=5;
fromdata[2]=5;
fromdata[3]=1;
std::ostringstream os(std::ios_base::binary);
compress(fromdata, os, SER_FMT_VER_HIGHEST);
std::string str_out = os.str();
dstream<<"str_out.size()="<<str_out.size()<<std::endl;
dstream<<"TestCompress: 1,5,5,1 -> ";
for(u32 i=0; i<str_out.size(); i++)
{
dstream<<(u32)str_out[i]<<",";
}
dstream<<std::endl;
/*assert(str_out.size() == 10);
assert(str_out[0] == 0);
assert(str_out[1] == 0);
assert(str_out[2] == 0);
assert(str_out[3] == 4);
assert(str_out[4] == 0);
assert(str_out[5] == 1);
assert(str_out[6] == 1);
assert(str_out[7] == 5);
assert(str_out[8] == 0);
assert(str_out[9] == 1);*/
std::istringstream is(str_out, std::ios_base::binary);
std::ostringstream os2(std::ios_base::binary);
decompress(is, os2, SER_FMT_VER_HIGHEST);
std::string str_out2 = os2.str();
dstream<<"decompress: ";
for(u32 i=0; i<str_out2.size(); i++)
{
dstream<<(u32)str_out2[i]<<",";
}
dstream<<std::endl;
assert(str_out2.size() == fromdata.getSize());
for(u32 i=0; i<str_out2.size(); i++)
{
assert(str_out2[i] == fromdata[i]);
}
}
} }
}; };
@ -273,8 +333,8 @@ struct TestVoxelManipulator
active_nodes.clear(); active_nodes.clear();
active_nodes[v3s16(9,1,0)] = 1; active_nodes[v3s16(9,1,0)] = 1;
//v.flowWater(active_nodes, 0, false); //v.flowWater(active_nodes, 0, true, 1000);
v.flowWater(active_nodes, 0, true, 1000); v.flowWater(active_nodes, 0, false, 1000);
dstream<<"Final result of flowWater:"<<std::endl; dstream<<"Final result of flowWater:"<<std::endl;
v.print(dstream, VOXELPRINT_WATERPRESSURE); v.print(dstream, VOXELPRINT_WATERPRESSURE);

@ -461,12 +461,12 @@ inline void getFacePositions(core::list<v3s16> &list, u16 d)
/* /*
This is an optimized sequence of coordinates. This is an optimized sequence of coordinates.
*/ */
list.push_back(v3s16( 0, 1, 0)); // top
list.push_back(v3s16( 0, 0, 1)); // back list.push_back(v3s16( 0, 0, 1)); // back
list.push_back(v3s16(-1, 0, 0)); // left list.push_back(v3s16(-1, 0, 0)); // left
list.push_back(v3s16( 1, 0, 0)); // right list.push_back(v3s16( 1, 0, 0)); // right
list.push_back(v3s16( 0, 0,-1)); // front list.push_back(v3s16( 0, 0,-1)); // front
list.push_back(v3s16( 0,-1, 0)); // bottom list.push_back(v3s16( 0,-1, 0)); // bottom
list.push_back(v3s16( 0, 1, 0)); // top
// 6 // 6
list.push_back(v3s16(-1, 0, 1)); // back left list.push_back(v3s16(-1, 0, 1)); // back left
list.push_back(v3s16( 1, 0, 1)); // back right list.push_back(v3s16( 1, 0, 1)); // back right

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" #include "debug.h"
#include "mapnode.h" #include "mapnode.h"
// For VC++
#undef min #undef min
#undef max #undef max