Pol  Revision:cb584c9
mapwriter.cpp
Go to the documentation of this file.
1 
7 #include "mapwriter.h"
8 
9 #include <string.h>
10 
11 #include "../clib/cfgelem.h"
12 #include "../clib/cfgfile.h"
13 #include "../clib/fileutil.h"
14 #include "../clib/iohelp.h"
15 #include "../pol/uofile.h"
16 #include "mapcell.h"
17 #include "mapsolid.h"
18 
19 
20 namespace Pol
21 {
22 namespace Plib
23 {
24 extern unsigned int num_map_patches;
25 extern unsigned int num_static_patches;
26 
28  : _realm_name( "" ),
29  _width( 0 ),
30  _height( 0 ),
31  _ofs_base(),
32  _cur_mapblock_index( -1 ),
33  _ofs_solidx1(),
34  _ofs_solidx2(),
35  _ofs_solids(),
36  _ofs_maptile(),
37  _cur_maptile_index( -1 ),
38  solidx2_offset( 0 ),
39  solids_offset( 0 )
40 {
41  _ofs_base.exceptions( std::ios_base::failbit | std::ios_base::badbit );
42  _ofs_solidx1.exceptions( std::ios_base::failbit | std::ios_base::badbit );
43  _ofs_solidx2.exceptions( std::ios_base::failbit | std::ios_base::badbit );
44  _ofs_solids.exceptions( std::ios_base::failbit | std::ios_base::badbit );
45  _ofs_maptile.exceptions( std::ios_base::failbit | std::ios_base::badbit );
46 }
47 
49 {
50  std::string filename = "realm/" + _realm_name + "/realm.cfg";
51  std::ofstream ofs_cfg;
52  ofs_cfg.exceptions( std::ios_base::failbit | std::ios_base::badbit );
53 
54  Clib::open_file( ofs_cfg, filename, std::ios::trunc | std::ios::out );
55 
56  ofs_cfg << "Realm " << _realm_name << std::endl;
57  ofs_cfg << "{" << std::endl;
58  ofs_cfg << " width " << _width << std::endl;
59  ofs_cfg << " height " << _height << std::endl;
60  ofs_cfg << " mapserver memory" << std::endl;
61  ofs_cfg << " uomapid " << Core::uo_mapid << std::endl;
62  ofs_cfg << " uodif " << Core::uo_usedif << std::endl;
63  ofs_cfg << " num_static_patches " << num_static_patches << std::endl;
64  ofs_cfg << " num_map_patches " << num_map_patches << std::endl;
65  ofs_cfg << " season 1" << std::endl;
66  ofs_cfg << "}" << std::endl;
67 }
68 
69 void MapWriter::CreateBaseDat( const std::string& /*realm_name*/, const std::string& directory )
70 {
71  using std::ios;
72 
73  std::string filename = directory + "base.dat";
74  Clib::open_file( _ofs_base, filename, ios::trunc | ios::in | ios::out | ios::binary );
76  memset( &empty, 0, sizeof empty );
77  for ( unsigned i = 0; i < total_blocks(); ++i )
78  {
79  _ofs_base.write( reinterpret_cast<const char*>( &empty ), sizeof empty );
80  }
81 }
82 void MapWriter::CreateSolidx1Dat( const std::string& /*realm_name*/, const std::string& directory )
83 {
84  using std::ios;
85 
86  std::string filename = directory + "solidx1.dat";
87  Clib::open_file( _ofs_solidx1, filename, ios::trunc | ios::in | ios::out | ios::binary );
88  SOLIDX1_ELEM elem;
89  elem.offset = 0;
90  for ( unsigned i = 0; i < total_solid_blocks(); ++i )
91  {
92  _ofs_solidx1.write( reinterpret_cast<const char*>( &elem ), sizeof elem );
93  }
94 }
95 void MapWriter::CreateSolidx2Dat( const std::string& /*realm_name*/, const std::string& directory )
96 {
97  using std::ios;
98  std::string filename = directory + "solidx2.dat";
99  Clib::open_file( _ofs_solidx2, filename, ios::trunc | ios::in | ios::out | ios::binary );
100  _ofs_solidx2.write( "fill", 4 );
101  solidx2_offset = 4;
102 }
103 void MapWriter::CreateSolidsDat( const std::string& /*realm_name*/, const std::string& directory )
104 {
105  using std::ios;
106 
107  std::string filename = directory + "solids.dat";
108  Clib::open_file( _ofs_solids, filename, ios::trunc | ios::in | ios::out | ios::binary );
109  _ofs_solids.write( "filler", 6 ); // multiple of 3
110  solids_offset = 6;
111 }
112 void MapWriter::CreateMaptileDat( const std::string& /*realm_name*/, const std::string& directory )
113 {
114  using std::ios;
115 
116  std::string filename = directory + "maptile.dat";
117  Clib::open_file( _ofs_maptile, filename, ios::trunc | ios::in | ios::out | ios::binary );
118  MAPTILE_BLOCK maptile_empty;
119  memset( &maptile_empty, 0, sizeof maptile_empty );
120  for ( unsigned i = 0; i < total_maptile_blocks(); ++i )
121  {
122  _ofs_maptile.write( reinterpret_cast<const char*>( &maptile_empty ), sizeof maptile_empty );
123  }
124 }
125 
126 void MapWriter::CreateNewFiles( const std::string& realm_name, unsigned short width,
127  unsigned short height )
128 {
129  _realm_name = realm_name;
130  _width = width;
131  _height = height;
132 
133  std::string directory = "realm/" + _realm_name + "/";
134  Clib::make_dir( directory.c_str() );
135 
136  CreateBaseDat( realm_name, directory );
137  // First-level Solids index (solidx1)
138  CreateSolidx1Dat( realm_name, directory );
139  // Second-level Solids index (solidx2)
140  CreateSolidx2Dat( realm_name, directory );
141  // Solids data (solids)
142  CreateSolidsDat( realm_name, directory );
143  // Maptile file (maptile.dat)
144  CreateMaptileDat( realm_name, directory );
145 }
146 
147 void MapWriter::OpenExistingFiles( const std::string& realm_name )
148 {
149  using std::ios;
150 
151  _realm_name = realm_name;
152 
153  std::string directory = "realm/" + _realm_name + "/";
154 
155  std::string realm_cfg_filename = directory + "realm.cfg";
156  Clib::ConfigFile cf( realm_cfg_filename, "REALM" );
157  Clib::ConfigElem elem;
158  if ( !cf.read( elem ) )
159  throw std::runtime_error( "Unable to read realm from " + realm_cfg_filename );
160  _width = elem.remove_ushort( "width" );
161  _height = elem.remove_ushort( "height" );
162 
163  std::string filename = directory + "base.dat";
164  Clib::open_file( _ofs_base, filename, ios::in | ios::out | ios::binary );
165 
166 
167  // First-level Solids index (solidx1)
168  filename = directory + "solidx1.dat";
169  Clib::open_file( _ofs_solidx1, filename, ios::in | ios::out | ios::binary );
170 
171  // Second-level Solids index (solidx2)
172  filename = directory + "solidx2.dat";
173  Clib::open_file( _ofs_solidx2, filename, ios::in | ios::out | ios::binary );
174  _ofs_solidx2.seekp( 0, ios::end );
175  solidx2_offset = _ofs_solidx2.tellp();
176 
177  // Solids data (solids)
178  filename = directory + "solids.dat";
179  Clib::open_file( _ofs_solids, filename, ios::in | ios::out | ios::binary );
180  _ofs_solids.seekp( 0, ios::end );
181  solids_offset = _ofs_solids.tellp();
182 
183  // Maptile (maptile.dat)
184  filename = directory + "maptile.dat";
185  Clib::open_file( _ofs_maptile, filename, ios::in | ios::out | ios::binary );
186  _ofs_maptile.seekp( 0, ios::end );
187 }
188 
190 {
191  Flush();
192 }
193 
195 {
196  FlushBaseFile();
198 }
199 
200 std::fstream::pos_type MapWriter::total_size()
201 {
202  return total_blocks() * sizeof( MAPBLOCK );
203 }
205 {
207 }
209 {
211 }
213 {
215 }
216 
217 void MapWriter::SetMapCell( unsigned short x, unsigned short y, MAPCELL cell )
218 {
219  unsigned short xblock = x >> MAPBLOCK_SHIFT;
220  unsigned short xcell = x & MAPBLOCK_CELLMASK;
221  unsigned short yblock = y >> MAPBLOCK_SHIFT;
222  unsigned short ycell = y & MAPBLOCK_CELLMASK;
223 
224  // doh, need to know map geometry here.
225  int blockIdx = yblock * ( _width >> MAPBLOCK_SHIFT ) + xblock;
226  if ( blockIdx != _cur_mapblock_index )
227  {
228  if ( _cur_mapblock_index >= 0 )
229  {
230  FlushBaseFile();
231  }
232  // read the existing block in
233  size_t offset = blockIdx * sizeof( _block );
234  _ofs_base.seekg( offset, std::ios_base::beg );
235  _ofs_base.read( reinterpret_cast<char*>( &_block ), sizeof _block );
236  _cur_mapblock_index = blockIdx;
237  }
238 
239  _block.cell[xcell][ycell] = cell;
240 }
241 void MapWriter::SetMapTile( unsigned short x, unsigned short y, MAPTILE_CELL cell )
242 {
243  unsigned short xblock = x >> MAPTILE_SHIFT;
244  unsigned short xcell = x & MAPTILE_CELLMASK;
245  unsigned short yblock = y >> MAPTILE_SHIFT;
246  unsigned short ycell = y & MAPTILE_CELLMASK;
247 
248  // doh, need to know map geometry here.
249  int blockIdx = yblock * ( _width >> MAPTILE_SHIFT ) + xblock;
250  if ( blockIdx != _cur_maptile_index )
251  {
252  if ( _cur_maptile_index >= 0 )
253  {
255  }
256  // read the existing block in
257  size_t offset = blockIdx * sizeof _maptile_block;
258  _ofs_maptile.seekg( offset, std::ios_base::beg );
259  _ofs_maptile.read( reinterpret_cast<char*>( &_maptile_block ), sizeof _maptile_block );
260  _cur_maptile_index = blockIdx;
261  }
262 
263  _maptile_block.cell[xcell][ycell] = cell;
264 }
266 {
267  if ( _cur_mapblock_index >= 0 )
268  {
269  size_t offset = _cur_mapblock_index * sizeof( _block );
270  _ofs_base.seekp( offset, std::ios_base::beg );
271  _ofs_base.write( reinterpret_cast<const char*>( &_block ), sizeof _block );
272  }
273 }
275 {
276  if ( _cur_maptile_index >= 0 )
277  {
278  size_t offset = _cur_maptile_index * sizeof( _maptile_block );
279  _ofs_maptile.seekp( offset, std::ios_base::beg );
280  _ofs_maptile.write( reinterpret_cast<const char*>( &_maptile_block ), sizeof _maptile_block );
281  }
282 }
283 
285 {
286  return static_cast<unsigned int>( solids_offset );
287 }
288 
290 {
291  return NextSolidOffset() / sizeof( SOLIDS_ELEM );
292 }
293 
295 {
296  return static_cast<unsigned int>( solidx2_offset );
297 }
298 
300 {
301  _ofs_solids.write( reinterpret_cast<const char*>( &solid ), sizeof( SOLIDS_ELEM ) );
302  solids_offset += sizeof( SOLIDS_ELEM );
303 }
304 
306 {
307  _ofs_solidx2.write( reinterpret_cast<const char*>( &elem ), sizeof elem );
308  solidx2_offset += sizeof elem;
309 }
310 
311 void MapWriter::SetSolidx2Offset( unsigned short x_base, unsigned short y_base,
312  unsigned int offset )
313 {
314  unsigned int elems_per_row = ( _width / SOLIDX_X_SIZE );
315  unsigned int index = ( y_base / SOLIDX_Y_SIZE ) * elems_per_row + ( x_base / SOLIDX_X_SIZE );
316  size_t file_offset = index * sizeof( SOLIDX1_ELEM );
317 
318  _ofs_solidx1.seekp( file_offset, std::ios_base::beg );
319  _ofs_solidx1.write( reinterpret_cast<const char*>( &offset ), sizeof offset );
320 }
321 }
322 }
unsigned int offset
Definition: mapblob.h:24
void AppendSolid(const SOLIDS_ELEM &solid)
Definition: mapwriter.cpp:299
std::string _realm_name
Definition: mapwriter.h:69
const unsigned MAPBLOCK_CELLMASK
Definition: mapblock.h:20
unsigned int NextSolidOffset()
Definition: mapwriter.cpp:284
unsigned short _height
Definition: mapwriter.h:71
unsigned width() const
Definition: mapwriter.h:55
std::fstream _ofs_maptile
Definition: mapwriter.h:80
unsigned int total_maptile_blocks()
Definition: mapwriter.cpp:212
unsigned int total_solid_blocks()
Definition: mapwriter.cpp:208
unsigned int total_blocks()
Definition: mapwriter.cpp:204
char * binary(unsigned int val, int nbits)
void open_file(std::fstream &ofs, std::string &filename, std::ios::openmode mode)
Definition: iohelp.cpp:17
MAPTILE_CELL cell[MAPTILE_CHUNK][MAPTILE_CHUNK]
Definition: maptile.h:27
#define SOLIDX_X_SIZE
Definition: mapblob.h:10
void CreateBaseDat(const std::string &realm_name, const std::string &directory)
Definition: mapwriter.cpp:69
unsigned int num_static_patches
Definition: uofile02.cpp:25
const unsigned MAPTILE_SHIFT
Definition: maptile.h:14
void CreateSolidx1Dat(const std::string &realm_name, const std::string &directory)
Definition: mapwriter.cpp:82
unsigned int num_map_patches
Definition: uofile08.cpp:28
const unsigned MAPBLOCK_CHUNK
Definition: mapblock.h:18
void CreateSolidx2Dat(const std::string &realm_name, const std::string &directory)
Definition: mapwriter.cpp:95
int uo_mapid
Definition: uofile00.cpp:85
void SetMapTile(unsigned short x, unsigned short y, MAPTILE_CELL cell)
Definition: mapwriter.cpp:241
std::fstream _ofs_solids
Definition: mapwriter.h:78
std::fstream _ofs_solidx2
Definition: mapwriter.h:77
MAPCELL cell[MAPBLOCK_CHUNK][MAPBLOCK_CHUNK]
Definition: mapblock.h:24
unsigned int NextSolidIndex()
Definition: mapwriter.cpp:289
unsigned height() const
Definition: mapwriter.h:56
std::fstream::pos_type total_size()
Definition: mapwriter.cpp:200
void AppendSolidx2Elem(const SOLIDX2_ELEM &elem)
Definition: mapwriter.cpp:305
std::fstream _ofs_base
Definition: mapwriter.h:72
void CreateMaptileDat(const std::string &realm_name, const std::string &directory)
Definition: mapwriter.cpp:112
#define SOLIDX_Y_SIZE
Definition: mapblob.h:14
void CreateSolidsDat(const std::string &realm_name, const std::string &directory)
Definition: mapwriter.cpp:103
void SetMapCell(unsigned short x, unsigned short y, MAPCELL cell)
Definition: mapwriter.cpp:217
MAPTILE_BLOCK _maptile_block
Definition: mapwriter.h:82
const unsigned MAPTILE_CHUNK
Definition: maptile.h:13
unsigned short remove_ushort(const char *propname)
Definition: cfgfile.cpp:318
void SetSolidx2Offset(unsigned short x_base, unsigned short y_base, unsigned int offset)
Definition: mapwriter.cpp:311
int uo_usedif
Definition: uofile00.cpp:86
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
void CreateNewFiles(const std::string &realm_name, unsigned short width, unsigned short height)
Definition: mapwriter.cpp:126
std::fstream _ofs_solidx1
Definition: mapwriter.h:76
unsigned int NextSolidx2Offset()
Definition: mapwriter.cpp:294
const unsigned MAPBLOCK_SHIFT
Definition: mapblock.h:19
Definition: berror.cpp:12
void OpenExistingFiles(const std::string &realm_name)
Definition: mapwriter.cpp:147
unsigned short _width
Definition: mapwriter.h:70
int make_dir(const char *dir)
Definition: fileutil.cpp:82
const unsigned MAPTILE_CELLMASK
Definition: maptile.h:15