Modified block mesh generation to have clearer input and output. Instead of being...
[oweals/minetest.git] / src / utility.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef UTILITY_HEADER
21 #define UTILITY_HEADER
22
23 #include <iostream>
24 #include <fstream>
25 #include <string>
26 #include <sstream>
27 #include <jthread.h>
28 #include <jmutex.h>
29 #include <jmutexautolock.h>
30
31 #include "common_irrlicht.h"
32 #include "debug.h"
33 #include "strfnd.h"
34 #include "exceptions.h"
35 #include "porting.h"
36
37 extern const v3s16 g_6dirs[6];
38
39 extern const v3s16 g_26dirs[26];
40
41 // 26th is (0,0,0)
42 extern const v3s16 g_27dirs[27];
43
44 inline void writeU64(u8 *data, u64 i)
45 {
46         data[0] = ((i>>56)&0xff);
47         data[1] = ((i>>48)&0xff);
48         data[2] = ((i>>40)&0xff);
49         data[3] = ((i>>32)&0xff);
50         data[4] = ((i>>24)&0xff);
51         data[5] = ((i>>16)&0xff);
52         data[6] = ((i>> 8)&0xff);
53         data[7] = ((i>> 0)&0xff);
54 }
55
56 inline void writeU32(u8 *data, u32 i)
57 {
58         data[0] = ((i>>24)&0xff);
59         data[1] = ((i>>16)&0xff);
60         data[2] = ((i>> 8)&0xff);
61         data[3] = ((i>> 0)&0xff);
62 }
63
64 inline void writeU16(u8 *data, u16 i)
65 {
66         data[0] = ((i>> 8)&0xff);
67         data[1] = ((i>> 0)&0xff);
68 }
69
70 inline void writeU8(u8 *data, u8 i)
71 {
72         data[0] = ((i>> 0)&0xff);
73 }
74
75 inline u64 readU64(u8 *data)
76 {
77         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
78                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
79                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
80                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
81 }
82
83 inline u32 readU32(u8 *data)
84 {
85         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
86 }
87
88 inline u16 readU16(u8 *data)
89 {
90         return (data[0]<<8) | (data[1]<<0);
91 }
92
93 inline u8 readU8(u8 *data)
94 {
95         return (data[0]<<0);
96 }
97
98 // Signed variants of the above
99
100 inline void writeS32(u8 *data, s32 i){
101         writeU32(data, (u32)i);
102 }
103 inline s32 readS32(u8 *data){
104         return (s32)readU32(data);
105 }
106
107 inline void writeS16(u8 *data, s16 i){
108         writeU16(data, (u16)i);
109 }
110 inline s16 readS16(u8 *data){
111         return (s16)readU16(data);
112 }
113
114 inline void writeV3S32(u8 *data, v3s32 p)
115 {
116         writeS32(&data[0], p.X);
117         writeS32(&data[4], p.Y);
118         writeS32(&data[8], p.Z);
119 }
120
121 inline v3s32 readV3S32(u8 *data)
122 {
123         v3s32 p;
124         p.X = readS32(&data[0]);
125         p.Y = readS32(&data[4]);
126         p.Z = readS32(&data[8]);
127         return p;
128 }
129
130 inline void writeV2S16(u8 *data, v2s16 p)
131 {
132         writeS16(&data[0], p.X);
133         writeS16(&data[2], p.Y);
134 }
135
136 inline v2s16 readV2S16(u8 *data)
137 {
138         v2s16 p;
139         p.X = readS16(&data[0]);
140         p.Y = readS16(&data[2]);
141         return p;
142 }
143
144 inline void writeV2S32(u8 *data, v2s32 p)
145 {
146         writeS32(&data[0], p.X);
147         writeS32(&data[2], p.Y);
148 }
149
150 inline v2s32 readV2S32(u8 *data)
151 {
152         v2s32 p;
153         p.X = readS32(&data[0]);
154         p.Y = readS32(&data[2]);
155         return p;
156 }
157
158 inline void writeV3S16(u8 *data, v3s16 p)
159 {
160         writeS16(&data[0], p.X);
161         writeS16(&data[2], p.Y);
162         writeS16(&data[4], p.Z);
163 }
164
165 inline v3s16 readV3S16(u8 *data)
166 {
167         v3s16 p;
168         p.X = readS16(&data[0]);
169         p.Y = readS16(&data[2]);
170         p.Z = readS16(&data[4]);
171         return p;
172 }
173
174 /*
175         None of these are used at the moment
176 */
177
178 template <typename T>
179 class SharedPtr
180 {
181 public:
182         SharedPtr(T *t=NULL)
183         {
184                 refcount = new int;
185                 *refcount = 1;
186                 ptr = t;
187         }
188         SharedPtr(SharedPtr<T> &t)
189         {
190                 //*this = t;
191                 drop();
192                 refcount = t.refcount;
193                 (*refcount)++;
194                 ptr = t.ptr;
195         }
196         ~SharedPtr()
197         {
198                 drop();
199         }
200         SharedPtr<T> & operator=(T *t)
201         {
202                 drop();
203                 refcount = new int;
204                 *refcount = 1;
205                 ptr = t;
206                 return *this;
207         }
208         SharedPtr<T> & operator=(SharedPtr<T> &t)
209         {
210                 drop();
211                 refcount = t.refcount;
212                 (*refcount)++;
213                 ptr = t.ptr;
214                 return *this;
215         }
216         T* operator->()
217         {
218                 return ptr;
219         }
220         T & operator*()
221         {
222                 return *ptr;
223         }
224         bool operator!=(T *t)
225         {
226                 return ptr != t;
227         }
228         bool operator==(T *t)
229         {
230                 return ptr == t;
231         }
232         T & operator[](unsigned int i)
233         {
234                 return ptr[i];
235         }
236 private:
237         void drop()
238         {
239                 assert((*refcount) > 0);
240                 (*refcount)--;
241                 if(*refcount == 0)
242                 {
243                         delete refcount;
244                         if(ptr != NULL)
245                                 delete ptr;
246                 }
247         }
248         T *ptr;
249         int *refcount;
250 };
251
252 template <typename T>
253 class Buffer
254 {
255 public:
256         Buffer(unsigned int size)
257         {
258                 m_size = size;
259                 data = new T[size];
260         }
261         Buffer(const Buffer &buffer)
262         {
263                 m_size = buffer.m_size;
264                 data = new T[buffer.m_size];
265                 memcpy(data, buffer.data, buffer.m_size);
266         }
267         Buffer(T *t, unsigned int size)
268         {
269                 m_size = size;
270                 data = new T[size];
271                 memcpy(data, t, size);
272         }
273         ~Buffer()
274         {
275                 delete[] data;
276         }
277         T & operator[](unsigned int i) const
278         {
279                 return data[i];
280         }
281         T * operator*() const
282         {
283                 return data;
284         }
285         unsigned int getSize() const
286         {
287                 return m_size;
288         }
289 private:
290         T *data;
291         unsigned int m_size;
292 };
293
294 template <typename T>
295 class SharedBuffer
296 {
297 public:
298         SharedBuffer(unsigned int size)
299         {
300                 m_size = size;
301                 data = new T[size];
302                 refcount = new unsigned int;
303                 (*refcount) = 1;
304         }
305         SharedBuffer(const SharedBuffer &buffer)
306         {
307                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
308                 m_size = buffer.m_size;
309                 data = buffer.data;
310                 refcount = buffer.refcount;
311                 (*refcount)++;
312         }
313         SharedBuffer & operator=(const SharedBuffer & buffer)
314         {
315                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
316                 if(this == &buffer)
317                         return *this;
318                 drop();
319                 m_size = buffer.m_size;
320                 data = buffer.data;
321                 refcount = buffer.refcount;
322                 (*refcount)++;
323                 return *this;
324         }
325         /*
326                 Copies whole buffer
327         */
328         SharedBuffer(T *t, unsigned int size)
329         {
330                 m_size = size;
331                 data = new T[size];
332                 memcpy(data, t, size);
333                 refcount = new unsigned int;
334                 (*refcount) = 1;
335         }
336         /*
337                 Copies whole buffer
338         */
339         SharedBuffer(const Buffer<T> &buffer)
340         {
341                 m_size = buffer.m_size;
342                 data = new T[buffer.getSize()];
343                 memcpy(data, *buffer, buffer.getSize());
344                 refcount = new unsigned int;
345                 (*refcount) = 1;
346         }
347         ~SharedBuffer()
348         {
349                 drop();
350         }
351         T & operator[](unsigned int i) const
352         {
353                 return data[i];
354         }
355         T * operator*() const
356         {
357                 return data;
358         }
359         unsigned int getSize() const
360         {
361                 return m_size;
362         }
363 private:
364         void drop()
365         {
366                 assert((*refcount) > 0);
367                 (*refcount)--;
368                 if(*refcount == 0)
369                 {
370                         delete[] data;
371                         delete refcount;
372                 }
373         }
374         T *data;
375         unsigned int m_size;
376         unsigned int *refcount;
377 };
378
379 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
380 {
381         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
382         return b;
383 }
384
385 template<typename T>
386 class MutexedVariable
387 {
388 public:
389         MutexedVariable(T value):
390                 m_value(value)
391         {
392                 m_mutex.Init();
393         }
394
395         T get()
396         {
397                 JMutexAutoLock lock(m_mutex);
398                 return m_value;
399         }
400
401         void set(T value)
402         {
403                 JMutexAutoLock lock(m_mutex);
404                 m_value = value;
405         }
406         
407         // You'll want to grab this in a SharedPtr
408         JMutexAutoLock * getLock()
409         {
410                 return new JMutexAutoLock(m_mutex);
411         }
412         
413         // You pretty surely want to grab the lock when accessing this
414         T m_value;
415
416 private:
417         JMutex m_mutex;
418 };
419
420 /*
421         TimeTaker
422 */
423
424 class IrrlichtWrapper;
425
426 class TimeTaker
427 {
428 public:
429         TimeTaker(const char *name, u32 *result=NULL);
430
431         ~TimeTaker()
432         {
433                 stop();
434         }
435
436         u32 stop(bool quiet=false);
437
438         u32 getTime();
439
440 private:
441         const char *m_name;
442         u32 m_time1;
443         bool m_running;
444         u32 *m_result;
445 };
446
447 // Calculates the borders of a "d-radius" cube
448 inline void getFacePositions(core::list<v3s16> &list, u16 d)
449 {
450         if(d == 0)
451         {
452                 list.push_back(v3s16(0,0,0));
453                 return;
454         }
455         if(d == 1)
456         {
457                 /*
458                         This is an optimized sequence of coordinates.
459                 */
460                 list.push_back(v3s16( 0, 1, 0)); // top
461                 list.push_back(v3s16( 0, 0, 1)); // back
462                 list.push_back(v3s16(-1, 0, 0)); // left
463                 list.push_back(v3s16( 1, 0, 0)); // right
464                 list.push_back(v3s16( 0, 0,-1)); // front
465                 list.push_back(v3s16( 0,-1, 0)); // bottom
466                 // 6
467                 list.push_back(v3s16(-1, 0, 1)); // back left
468                 list.push_back(v3s16( 1, 0, 1)); // back right
469                 list.push_back(v3s16(-1, 0,-1)); // front left
470                 list.push_back(v3s16( 1, 0,-1)); // front right
471                 list.push_back(v3s16(-1,-1, 0)); // bottom left
472                 list.push_back(v3s16( 1,-1, 0)); // bottom right
473                 list.push_back(v3s16( 0,-1, 1)); // bottom back
474                 list.push_back(v3s16( 0,-1,-1)); // bottom front
475                 list.push_back(v3s16(-1, 1, 0)); // top left
476                 list.push_back(v3s16( 1, 1, 0)); // top right
477                 list.push_back(v3s16( 0, 1, 1)); // top back
478                 list.push_back(v3s16( 0, 1,-1)); // top front
479                 // 18
480                 list.push_back(v3s16(-1, 1, 1)); // top back-left
481                 list.push_back(v3s16( 1, 1, 1)); // top back-right
482                 list.push_back(v3s16(-1, 1,-1)); // top front-left
483                 list.push_back(v3s16( 1, 1,-1)); // top front-right
484                 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
485                 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
486                 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
487                 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
488                 // 26
489                 return;
490         }
491
492         // Take blocks in all sides, starting from y=0 and going +-y
493         for(s16 y=0; y<=d-1; y++)
494         {
495                 // Left and right side, including borders
496                 for(s16 z=-d; z<=d; z++)
497                 {
498                         list.push_back(v3s16(d,y,z));
499                         list.push_back(v3s16(-d,y,z));
500                         if(y != 0)
501                         {
502                                 list.push_back(v3s16(d,-y,z));
503                                 list.push_back(v3s16(-d,-y,z));
504                         }
505                 }
506                 // Back and front side, excluding borders
507                 for(s16 x=-d+1; x<=d-1; x++)
508                 {
509                         list.push_back(v3s16(x,y,d));
510                         list.push_back(v3s16(x,y,-d));
511                         if(y != 0)
512                         {
513                                 list.push_back(v3s16(x,-y,d));
514                                 list.push_back(v3s16(x,-y,-d));
515                         }
516                 }
517         }
518
519         // Take the bottom and top face with borders
520         // -d<x<d, y=+-d, -d<z<d
521         for(s16 x=-d; x<=d; x++)
522         for(s16 z=-d; z<=d; z++)
523         {
524                 list.push_back(v3s16(x,-d,z));
525                 list.push_back(v3s16(x,d,z));
526         }
527 }
528
529 class IndentationRaiser
530 {
531 public:
532         IndentationRaiser(u16 *indentation)
533         {
534                 m_indentation = indentation;
535                 (*m_indentation)++;
536         }
537         ~IndentationRaiser()
538         {
539                 (*m_indentation)--;
540         }
541 private:
542         u16 *m_indentation;
543 };
544
545 inline s16 getContainerPos(s16 p, s16 d)
546 {
547         return (p>=0 ? p : p-d+1) / d;
548 }
549
550 inline v2s16 getContainerPos(v2s16 p, s16 d)
551 {
552         return v2s16(
553                 getContainerPos(p.X, d),
554                 getContainerPos(p.Y, d)
555         );
556 }
557
558 inline v3s16 getContainerPos(v3s16 p, s16 d)
559 {
560         return v3s16(
561                 getContainerPos(p.X, d),
562                 getContainerPos(p.Y, d),
563                 getContainerPos(p.Z, d)
564         );
565 }
566
567 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
568 {
569         return v2s16(
570                 getContainerPos(p.X, d.X),
571                 getContainerPos(p.Y, d.Y)
572         );
573 }
574
575 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
576 {
577         return v3s16(
578                 getContainerPos(p.X, d.X),
579                 getContainerPos(p.Y, d.Y),
580                 getContainerPos(p.Z, d.Z)
581         );
582 }
583
584 inline bool isInArea(v3s16 p, s16 d)
585 {
586         return (
587                 p.X >= 0 && p.X < d &&
588                 p.Y >= 0 && p.Y < d &&
589                 p.Z >= 0 && p.Z < d
590         );
591 }
592
593 inline bool isInArea(v2s16 p, s16 d)
594 {
595         return (
596                 p.X >= 0 && p.X < d &&
597                 p.Y >= 0 && p.Y < d
598         );
599 }
600
601 inline bool isInArea(v3s16 p, v3s16 d)
602 {
603         return (
604                 p.X >= 0 && p.X < d.X &&
605                 p.Y >= 0 && p.Y < d.Y &&
606                 p.Z >= 0 && p.Z < d.Z
607         );
608 }
609
610 inline s16 rangelim(s16 i, s16 max)
611 {
612         if(i < 0)
613                 return 0;
614         if(i > max)
615                 return max;
616         return i;
617 }
618
619 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
620
621 inline v3s16 arealim(v3s16 p, s16 d)
622 {
623         if(p.X < 0)
624                 p.X = 0;
625         if(p.Y < 0)
626                 p.Y = 0;
627         if(p.Z < 0)
628                 p.Z = 0;
629         if(p.X > d-1)
630                 p.X = d-1;
631         if(p.Y > d-1)
632                 p.Y = d-1;
633         if(p.Z > d-1)
634                 p.Z = d-1;
635         return p;
636 }
637
638 inline std::wstring narrow_to_wide(const std::string& mbs)
639 {
640         size_t wcl = mbs.size();
641         Buffer<wchar_t> wcs(wcl+1);
642         size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
643         if(l == (size_t)(-1))
644                 return L"<invalid multibyte string>";
645         wcs[l] = 0;
646         return *wcs;
647 }
648
649 inline std::string wide_to_narrow(const std::wstring& wcs)
650 {
651         size_t mbl = wcs.size()*4;
652         SharedBuffer<char> mbs(mbl+1);
653         size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
654         if(l == (size_t)(-1))
655                 mbs[0] = 0;
656         else
657                 mbs[l] = 0;
658         return *mbs;
659 }
660
661 /*
662         See test.cpp for example cases.
663         wraps degrees to the range of -360...360
664         NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
665 */
666 inline float wrapDegrees(float f)
667 {
668         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
669         // This results in
670         // 10, 720, -1, -361
671         int i = floor(f);
672         // 0, 2, 0, -1
673         int l = i / 360;
674         // NOTE: This would be used for wrapping to 0...360
675         // 0, 2, -1, -2
676         /*if(i < 0)
677                 l -= 1;*/
678         // 0, 720, 0, -360
679         int k = l * 360;
680         // 10, 0.5, -0.5, -0.5
681         f -= float(k);
682         return f;
683 }
684
685 inline std::string lowercase(const std::string &s)
686 {
687         std::string s2;
688         for(size_t i=0; i<s.size(); i++)
689         {
690                 char c = s[i];
691                 if(c >= 'A' && c <= 'Z')
692                         c -= 'A' - 'a';
693                 s2 += c;
694         }
695         return s2;
696 }
697
698 inline bool is_yes(const std::string &s)
699 {
700         std::string s2 = lowercase(trim(s));
701         if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
702                 return true;
703         return false;
704 }
705
706 inline s32 stoi(const std::string &s, s32 min, s32 max)
707 {
708         s32 i = atoi(s.c_str());
709         if(i < min)
710                 i = min;
711         if(i > max)
712                 i = max;
713         return i;
714 }
715
716 inline s32 stoi(std::string s)
717 {
718         return atoi(s.c_str());
719 }
720
721 inline float stof(std::string s)
722 {
723         float f;
724         std::istringstream ss(s);
725         ss>>f;
726         return f;
727 }
728
729 inline std::string itos(s32 i)
730 {
731         std::ostringstream o;
732         o<<i;
733         return o.str();
734 }
735
736 inline std::string ftos(float f)
737 {
738         std::ostringstream o;
739         o<<f;
740         return o.str();
741 }
742
743 inline void str_replace(std::string & str, std::string const & pattern,
744                 std::string const & replacement)
745 {
746         std::string::size_type start = str.find(pattern, 0);
747         while(start != str.npos)
748         {
749                 str.replace(start, pattern.size(), replacement);
750                 start = str.find(pattern, start+replacement.size());
751         }
752 }
753
754 inline void str_replace_char(std::string & str, char from, char to)
755 {
756         for(unsigned int i=0; i<str.size(); i++)
757         {
758                 if(str[i] == from)
759                         str[i] = to;
760         }
761 }
762
763 /*
764         A base class for simple background thread implementation
765 */
766
767 class SimpleThread : public JThread
768 {
769         bool run;
770         JMutex run_mutex;
771
772 public:
773
774         SimpleThread():
775                 JThread(),
776                 run(true)
777         {
778                 run_mutex.Init();
779         }
780
781         virtual ~SimpleThread()
782         {}
783
784         virtual void * Thread() = 0;
785
786         bool getRun()
787         {
788                 JMutexAutoLock lock(run_mutex);
789                 return run;
790         }
791         void setRun(bool a_run)
792         {
793                 JMutexAutoLock lock(run_mutex);
794                 run = a_run;
795         }
796
797         void stop()
798         {
799                 setRun(false);
800                 while(IsRunning())
801                         sleep_ms(100);
802         }
803 };
804
805 /*
806         Config stuff
807 */
808
809 enum ValueType
810 {
811         VALUETYPE_STRING,
812         VALUETYPE_FLAG // Doesn't take any arguments
813 };
814
815 struct ValueSpec
816 {
817         ValueSpec(ValueType a_type, const char *a_help=NULL)
818         {
819                 type = a_type;
820                 help = a_help;
821         }
822         ValueType type;
823         const char *help;
824 };
825
826 class Settings
827 {
828 public:
829         Settings()
830         {
831                 m_mutex.Init();
832         }
833
834         void writeLines(std::ostream &os)
835         {
836                 JMutexAutoLock lock(m_mutex);
837                 
838                 for(core::map<std::string, std::string>::Iterator
839                                 i = m_settings.getIterator();
840                                 i.atEnd() == false; i++)
841                 {
842                         std::string name = i.getNode()->getKey();
843                         std::string value = i.getNode()->getValue();
844                         os<<name<<" = "<<value<<"\n";
845                 }
846         }
847
848         bool parseConfigLine(const std::string &line)
849         {
850                 JMutexAutoLock lock(m_mutex);
851                 
852                 std::string trimmedline = trim(line);
853                 
854                 // Ignore comments
855                 if(trimmedline[0] == '#')
856                         return true;
857
858                 //dstream<<"trimmedline=\""<<trimmedline<<"\""<<std::endl;
859
860                 Strfnd sf(trim(line));
861
862                 std::string name = sf.next("=");
863                 name = trim(name);
864
865                 if(name == "")
866                         return true;
867                 
868                 std::string value = sf.next("\n");
869                 value = trim(value);
870
871                 /*dstream<<"Config name=\""<<name<<"\" value=\""
872                                 <<value<<"\""<<std::endl;*/
873                 
874                 m_settings[name] = value;
875                 
876                 return true;
877         }
878
879         // Returns false on EOF
880         bool parseConfigObject(std::istream &is)
881         {
882                 if(is.eof())
883                         return false;
884                 
885                 /*
886                         NOTE: This function might be expanded to allow multi-line
887                               settings.
888                 */
889                 std::string line;
890                 std::getline(is, line);
891                 //dstream<<"got line: \""<<line<<"\""<<std::endl;
892
893                 return parseConfigLine(line);
894         }
895
896         /*
897                 Read configuration file
898
899                 Returns true on success
900         */
901         bool readConfigFile(const char *filename)
902         {
903                 std::ifstream is(filename);
904                 if(is.good() == false)
905                 {
906                         dstream<<"Error opening configuration file \""
907                                         <<filename<<"\""<<std::endl;
908                         return false;
909                 }
910
911                 dstream<<"Parsing configuration file: \""
912                                 <<filename<<"\""<<std::endl;
913                                 
914                 while(parseConfigObject(is));
915                 
916                 return true;
917         }
918
919         /*
920                 Reads a configuration object from stream (usually a single line)
921                 and adds it to dst.
922                 
923                 Preserves comments and empty lines.
924
925                 Settings that were added to dst are also added to updated.
926                 key of updated is setting name, value of updated is dummy.
927
928                 Returns false on EOF
929         */
930         bool getUpdatedConfigObject(std::istream &is,
931                         core::list<std::string> &dst,
932                         core::map<std::string, bool> &updated)
933         {
934                 JMutexAutoLock lock(m_mutex);
935                 
936                 if(is.eof())
937                         return false;
938                 
939                 // NOTE: This function will be expanded to allow multi-line settings
940                 std::string line;
941                 std::getline(is, line);
942
943                 std::string trimmedline = trim(line);
944
945                 std::string line_end = "";
946                 if(is.eof() == false)
947                         line_end = "\n";
948                 
949                 // Ignore comments
950                 if(trimmedline[0] == '#')
951                 {
952                         dst.push_back(line+line_end);
953                         return true;
954                 }
955
956                 Strfnd sf(trim(line));
957
958                 std::string name = sf.next("=");
959                 name = trim(name);
960
961                 if(name == "")
962                 {
963                         dst.push_back(line+line_end);
964                         return true;
965                 }
966                 
967                 std::string value = sf.next("\n");
968                 value = trim(value);
969                 
970                 if(m_settings.find(name))
971                 {
972                         std::string newvalue = m_settings[name];
973                         
974                         if(newvalue != value)
975                         {
976                                 dstream<<"Changing value of \""<<name<<"\" = \""
977                                                 <<value<<"\" -> \""<<newvalue<<"\""
978                                                 <<std::endl;
979                         }
980
981                         dst.push_back(name + " = " + newvalue + line_end);
982
983                         updated[name] = true;
984                 }
985                 
986                 return true;
987         }
988
989         /*
990                 Updates configuration file
991
992                 Returns true on success
993         */
994         bool updateConfigFile(const char *filename)
995         {
996                 dstream<<"Updating configuration file: \""
997                                 <<filename<<"\""<<std::endl;
998                 
999                 core::list<std::string> objects;
1000                 core::map<std::string, bool> updated;
1001                 
1002                 // Read and modify stuff
1003                 {
1004                         std::ifstream is(filename);
1005                         if(is.good() == false)
1006                         {
1007                                 dstream<<"INFO: updateConfigFile():"
1008                                                 " Error opening configuration file"
1009                                                 " for reading: \""
1010                                                 <<filename<<"\""<<std::endl;
1011                         }
1012                         else
1013                         {
1014                                 while(getUpdatedConfigObject(is, objects, updated));
1015                         }
1016                 }
1017                 
1018                 JMutexAutoLock lock(m_mutex);
1019                 
1020                 // Write stuff back
1021                 {
1022                         std::ofstream os(filename);
1023                         if(os.good() == false)
1024                         {
1025                                 dstream<<"Error opening configuration file"
1026                                                 " for writing: \""
1027                                                 <<filename<<"\""<<std::endl;
1028                                 return false;
1029                         }
1030                         
1031                         /*
1032                                 Write updated stuff
1033                         */
1034                         for(core::list<std::string>::Iterator
1035                                         i = objects.begin();
1036                                         i != objects.end(); i++)
1037                         {
1038                                 os<<(*i);
1039                         }
1040
1041                         /*
1042                                 Write stuff that was not already in the file
1043                         */
1044                         for(core::map<std::string, std::string>::Iterator
1045                                         i = m_settings.getIterator();
1046                                         i.atEnd() == false; i++)
1047                         {
1048                                 if(updated.find(i.getNode()->getKey()))
1049                                         continue;
1050                                 std::string name = i.getNode()->getKey();
1051                                 std::string value = i.getNode()->getValue();
1052                                 dstream<<"Adding \""<<name<<"\" = \""<<value<<"\""
1053                                                 <<std::endl;
1054                                 os<<name<<" = "<<value<<"\n";
1055                         }
1056                 }
1057                 
1058                 return true;
1059         }
1060
1061         /*
1062                 NOTE: Types of allowed_options are ignored
1063
1064                 returns true on success
1065         */
1066         bool parseCommandLine(int argc, char *argv[],
1067                         core::map<std::string, ValueSpec> &allowed_options)
1068         {
1069                 int i=1;
1070                 for(;;)
1071                 {
1072                         if(i >= argc)
1073                                 break;
1074                         std::string argname = argv[i];
1075                         if(argname.substr(0, 2) != "--")
1076                         {
1077                                 dstream<<"Invalid command-line parameter \""
1078                                                 <<argname<<"\": --<option> expected."<<std::endl;
1079                                 return false;
1080                         }
1081                         i++;
1082
1083                         std::string name = argname.substr(2);
1084
1085                         core::map<std::string, ValueSpec>::Node *n;
1086                         n = allowed_options.find(name);
1087                         if(n == NULL)
1088                         {
1089                                 dstream<<"Unknown command-line parameter \""
1090                                                 <<argname<<"\""<<std::endl;
1091                                 return false;
1092                         }
1093
1094                         ValueType type = n->getValue().type;
1095
1096                         std::string value = "";
1097                         
1098                         if(type == VALUETYPE_FLAG)
1099                         {
1100                                 value = "true";
1101                         }
1102                         else
1103                         {
1104                                 if(i >= argc)
1105                                 {
1106                                         dstream<<"Invalid command-line parameter \""
1107                                                         <<name<<"\": missing value"<<std::endl;
1108                                         return false;
1109                                 }
1110                                 value = argv[i];
1111                                 i++;
1112                         }
1113                         
1114
1115                         dstream<<"Valid command-line parameter: \""
1116                                         <<name<<"\" = \""<<value<<"\""
1117                                         <<std::endl;
1118                         set(name, value);
1119                 }
1120
1121                 return true;
1122         }
1123
1124         void set(std::string name, std::string value)
1125         {
1126                 JMutexAutoLock lock(m_mutex);
1127                 
1128                 m_settings[name] = value;
1129         }
1130
1131         void setDefault(std::string name, std::string value)
1132         {
1133                 JMutexAutoLock lock(m_mutex);
1134                 
1135                 m_defaults[name] = value;
1136         }
1137
1138         bool exists(std::string name)
1139         {
1140                 JMutexAutoLock lock(m_mutex);
1141                 
1142                 return (m_settings.find(name) || m_defaults.find(name));
1143         }
1144
1145         std::string get(std::string name)
1146         {
1147                 JMutexAutoLock lock(m_mutex);
1148                 
1149                 core::map<std::string, std::string>::Node *n;
1150                 n = m_settings.find(name);
1151                 if(n == NULL)
1152                 {
1153                         n = m_defaults.find(name);
1154                         if(n == NULL)
1155                         {
1156                                 dstream<<"INFO: Settings: Setting not found: \""
1157                                                 <<name<<"\""<<std::endl;
1158                                 throw SettingNotFoundException("Setting not found");
1159                         }
1160                 }
1161
1162                 return n->getValue();
1163         }
1164
1165         bool getBool(std::string name)
1166         {
1167                 return is_yes(get(name));
1168         }
1169         
1170         bool getFlag(std::string name)
1171         {
1172                 try
1173                 {
1174                         return getBool(name);
1175                 }
1176                 catch(SettingNotFoundException &e)
1177                 {
1178                         return false;
1179                 }
1180         }
1181
1182         // Asks if empty
1183         bool getBoolAsk(std::string name, std::string question, bool def)
1184         {
1185                 // If it is in settings
1186                 if(exists(name))
1187                         return getBool(name);
1188                 
1189                 std::string s;
1190                 char templine[10];
1191                 std::cout<<question<<" [y/N]: ";
1192                 std::cin.getline(templine, 10);
1193                 s = templine;
1194
1195                 if(s == "")
1196                         return def;
1197
1198                 return is_yes(s);
1199         }
1200
1201         float getFloat(std::string name)
1202         {
1203                 return stof(get(name));
1204         }
1205
1206         u16 getU16(std::string name)
1207         {
1208                 return stoi(get(name), 0, 65535);
1209         }
1210
1211         u16 getU16Ask(std::string name, std::string question, u16 def)
1212         {
1213                 // If it is in settings
1214                 if(exists(name))
1215                         return getU16(name);
1216                 
1217                 std::string s;
1218                 char templine[10];
1219                 std::cout<<question<<" ["<<def<<"]: ";
1220                 std::cin.getline(templine, 10);
1221                 s = templine;
1222
1223                 if(s == "")
1224                         return def;
1225
1226                 return stoi(s, 0, 65535);
1227         }
1228
1229         s16 getS16(std::string name)
1230         {
1231                 return stoi(get(name), -32768, 32767);
1232         }
1233
1234         s32 getS32(std::string name)
1235         {
1236                 return stoi(get(name));
1237         }
1238
1239         v3f getV3F(std::string name)
1240         {
1241                 v3f value;
1242                 Strfnd f(get(name));
1243                 f.next("(");
1244                 value.X = stof(f.next(","));
1245                 value.Y = stof(f.next(","));
1246                 value.Z = stof(f.next(")"));
1247                 return value;
1248         }
1249
1250         u64 getU64(std::string name)
1251         {
1252                 u64 value = 0;
1253                 std::string s = get(name);
1254                 std::istringstream ss(s);
1255                 ss>>value;
1256                 return value;
1257         }
1258
1259         void setS32(std::string name, s32 value)
1260         {
1261                 set(name, itos(value));
1262         }
1263
1264         void setFloat(std::string name, float value)
1265         {
1266                 set(name, ftos(value));
1267         }
1268
1269         void setV3F(std::string name, v3f value)
1270         {
1271                 std::ostringstream os;
1272                 os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")";
1273                 set(name, os.str());
1274         }
1275
1276         void setU64(std::string name, u64 value)
1277         {
1278                 std::ostringstream os;
1279                 os<<value;
1280                 set(name, os.str());
1281         }
1282
1283         void clear()
1284         {
1285                 JMutexAutoLock lock(m_mutex);
1286                 
1287                 m_settings.clear();
1288                 m_defaults.clear();
1289         }
1290
1291         Settings & operator+=(Settings &other)
1292         {
1293                 JMutexAutoLock lock(m_mutex);
1294                 JMutexAutoLock lock2(other.m_mutex);
1295                 
1296                 if(&other == this)
1297                         return *this;
1298
1299                 for(core::map<std::string, std::string>::Iterator
1300                                 i = other.m_settings.getIterator();
1301                                 i.atEnd() == false; i++)
1302                 {
1303                         m_settings.insert(i.getNode()->getKey(),
1304                                         i.getNode()->getValue());
1305                 }
1306                 
1307                 for(core::map<std::string, std::string>::Iterator
1308                                 i = other.m_defaults.getIterator();
1309                                 i.atEnd() == false; i++)
1310                 {
1311                         m_defaults.insert(i.getNode()->getKey(),
1312                                         i.getNode()->getValue());
1313                 }
1314
1315         }
1316
1317         Settings & operator=(Settings &other)
1318         {
1319                 JMutexAutoLock lock(m_mutex);
1320                 JMutexAutoLock lock2(other.m_mutex);
1321                 
1322                 if(&other == this)
1323                         return *this;
1324
1325                 clear();
1326                 (*this) += other;
1327                 
1328                 return *this;
1329         }
1330
1331 private:
1332         core::map<std::string, std::string> m_settings;
1333         core::map<std::string, std::string> m_defaults;
1334         // All methods that access m_settings/m_defaults directly should lock this.
1335         JMutex m_mutex;
1336 };
1337
1338 /*
1339         FIFO queue (well, actually a FILO also)
1340 */
1341 template<typename T>
1342 class Queue
1343 {
1344 public:
1345         void push_back(T t)
1346         {
1347                 m_list.push_back(t);
1348         }
1349         
1350         T pop_front()
1351         {
1352                 if(m_list.size() == 0)
1353                         throw ItemNotFoundException("Queue: queue is empty");
1354
1355                 typename core::list<T>::Iterator begin = m_list.begin();
1356                 T t = *begin;
1357                 m_list.erase(begin);
1358                 return t;
1359         }
1360         T pop_back()
1361         {
1362                 if(m_list.size() == 0)
1363                         throw ItemNotFoundException("Queue: queue is empty");
1364
1365                 typename core::list<T>::Iterator last = m_list.getLast();
1366                 T t = *last;
1367                 m_list.erase(last);
1368                 return t;
1369         }
1370
1371         u32 size()
1372         {
1373                 return m_list.size();
1374         }
1375
1376 protected:
1377         core::list<T> m_list;
1378 };
1379
1380 /*
1381         Thread-safe FIFO queue (well, actually a FILO also)
1382 */
1383
1384 template<typename T>
1385 class MutexedQueue
1386 {
1387 public:
1388         MutexedQueue()
1389         {
1390                 m_mutex.Init();
1391         }
1392         u32 size()
1393         {
1394                 JMutexAutoLock lock(m_mutex);
1395                 return m_list.size();
1396         }
1397         void push_back(T t)
1398         {
1399                 JMutexAutoLock lock(m_mutex);
1400                 m_list.push_back(t);
1401         }
1402         T pop_front(u32 wait_time_max_ms=0)
1403         {
1404                 u32 wait_time_ms = 0;
1405
1406                 for(;;)
1407                 {
1408                         {
1409                                 JMutexAutoLock lock(m_mutex);
1410
1411                                 if(m_list.size() > 0)
1412                                 {
1413                                         typename core::list<T>::Iterator begin = m_list.begin();
1414                                         T t = *begin;
1415                                         m_list.erase(begin);
1416                                         return t;
1417                                 }
1418
1419                                 if(wait_time_ms >= wait_time_max_ms)
1420                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1421                         }
1422
1423                         // Wait a while before trying again
1424                         sleep_ms(10);
1425                         wait_time_ms += 10;
1426                 }
1427         }
1428         T pop_back(u32 wait_time_max_ms=0)
1429         {
1430                 u32 wait_time_ms = 0;
1431
1432                 for(;;)
1433                 {
1434                         {
1435                                 JMutexAutoLock lock(m_mutex);
1436
1437                                 if(m_list.size() > 0)
1438                                 {
1439                                         typename core::list<T>::Iterator last = m_list.getLast();
1440                                         T t = *last;
1441                                         m_list.erase(last);
1442                                         return t;
1443                                 }
1444
1445                                 if(wait_time_ms >= wait_time_max_ms)
1446                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1447                         }
1448
1449                         // Wait a while before trying again
1450                         sleep_ms(10);
1451                         wait_time_ms += 10;
1452                 }
1453         }
1454
1455         JMutex & getMutex()
1456         {
1457                 return m_mutex;
1458         }
1459
1460         core::list<T> & getList()
1461         {
1462                 return m_list;
1463         }
1464
1465 protected:
1466         JMutex m_mutex;
1467         core::list<T> m_list;
1468 };
1469
1470 template<typename Caller, typename Data>
1471 class CallerInfo
1472 {
1473 public:
1474         Caller caller;
1475         Data data;
1476 };
1477
1478 template<typename Key, typename T, typename Caller, typename CallerData>
1479 class GetResult
1480 {
1481 public:
1482         Key key;
1483         T item;
1484         core::list<CallerInfo<Caller, CallerData> > callers;
1485 };
1486
1487 template<typename Key, typename T, typename Caller, typename CallerData>
1488 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1489 {
1490 };
1491
1492 template<typename Key, typename T, typename Caller, typename CallerData>
1493 class GetRequest
1494 {
1495 public:
1496         GetRequest()
1497         {
1498                 dest = NULL;
1499         }
1500         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1501         {
1502                 dest = a_dest;
1503         }
1504         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1505                         Key a_key)
1506         {
1507                 dest = a_dest;
1508                 key = a_key;
1509         }
1510         ~GetRequest()
1511         {
1512         }
1513         
1514         Key key;
1515         ResultQueue<Key, T, Caller, CallerData> *dest;
1516         core::list<CallerInfo<Caller, CallerData> > callers;
1517 };
1518
1519 /*
1520         Quickhands for typical request-result queues.
1521         Used for distributing work between threads.
1522 */
1523
1524 template<typename Key, typename T, typename Caller, typename CallerData>
1525 class RequestQueue
1526 {
1527 public:
1528         u32 size()
1529         {
1530                 return m_queue.size();
1531         }
1532
1533         void add(Key key, Caller caller, CallerData callerdata,
1534                         ResultQueue<Key, T, Caller, CallerData> *dest)
1535         {
1536                 JMutexAutoLock lock(m_queue.getMutex());
1537                 
1538                 /*
1539                         If the caller is already on the list, only update CallerData
1540                 */
1541                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1542                                 i = m_queue.getList().begin();
1543                                 i != m_queue.getList().end(); i++)
1544                 {
1545                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1546
1547                         if(request.key == key)
1548                         {
1549                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1550                                                 i = request.callers.begin();
1551                                                 i != request.callers.end(); i++)
1552                                 {
1553                                         CallerInfo<Caller, CallerData> &ca = *i;
1554                                         if(ca.caller == caller)
1555                                         {
1556                                                 ca.data = callerdata;
1557                                                 return;
1558                                         }
1559                                 }
1560                                 CallerInfo<Caller, CallerData> ca;
1561                                 ca.caller = caller;
1562                                 ca.data = callerdata;
1563                                 request.callers.push_back(ca);
1564                                 return;
1565                         }
1566                 }
1567
1568                 /*
1569                         Else add a new request to the queue
1570                 */
1571
1572                 GetRequest<Key, T, Caller, CallerData> request;
1573                 request.key = key;
1574                 CallerInfo<Caller, CallerData> ca;
1575                 ca.caller = caller;
1576                 ca.data = callerdata;
1577                 request.callers.push_back(ca);
1578                 request.dest = dest;
1579                 
1580                 m_queue.getList().push_back(request);
1581         }
1582
1583         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1584         {
1585                 return m_queue.pop_front(wait_if_empty);
1586         }
1587
1588 private:
1589         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1590 };
1591
1592 /*
1593         Pseudo-random (VC++ rand() sucks)
1594 */
1595 int myrand(void);
1596 void mysrand(unsigned seed);
1597 #define MYRAND_MAX 32767
1598
1599 inline int myrand_range(int min, int max)
1600 {
1601         if(min > max)
1602         {
1603                 assert(0);
1604                 return max;
1605         }
1606         return (myrand()%(max-min+1))+min;
1607 }
1608
1609 /*
1610         Miscellaneous functions
1611 */
1612
1613 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range,
1614                 f32 *distance_ptr=NULL);
1615
1616 /*
1617         Queue with unique values with fast checking of value existence
1618 */
1619
1620 template<typename Value>
1621 class UniqueQueue
1622 {
1623 public:
1624         
1625         /*
1626                 Does nothing if value is already queued.
1627                 Return value:
1628                         true: value added
1629                         false: value already exists
1630         */
1631         bool push_back(Value value)
1632         {
1633                 // Check if already exists
1634                 if(m_map.find(value) != NULL)
1635                         return false;
1636
1637                 // Add
1638                 m_map.insert(value, 0);
1639                 m_list.push_back(value);
1640                 
1641                 return true;
1642         }
1643
1644         Value pop_front()
1645         {
1646                 typename core::list<Value>::Iterator i = m_list.begin();
1647                 Value value = *i;
1648                 m_map.remove(value);
1649                 m_list.erase(i);
1650                 return value;
1651         }
1652
1653         u32 size()
1654         {
1655                 assert(m_list.size() == m_map.size());
1656                 return m_list.size();
1657         }
1658
1659 private:
1660         core::map<Value, u8> m_map;
1661         core::list<Value> m_list;
1662 };
1663
1664 #if 0
1665 template<typename Key, typename Value>
1666 class MutexedCache
1667 {
1668 public:
1669         MutexedCache()
1670         {
1671                 m_mutex.Init();
1672                 assert(m_mutex.IsInitialized());
1673         }
1674         
1675         void set(const Key &name, const Value &value)
1676         {
1677                 JMutexAutoLock lock(m_mutex);
1678
1679                 m_values[name] = value;
1680         }
1681         
1682         bool get(const Key &name, Value *result)
1683         {
1684                 JMutexAutoLock lock(m_mutex);
1685
1686                 typename core::map<Key, Value>::Node *n;
1687                 n = m_values.find(name);
1688
1689                 if(n == NULL)
1690                         return false;
1691
1692                 *result = n->getValue();
1693                 return true;
1694         }
1695
1696 private:
1697         core::map<Key, Value> m_values;
1698         JMutex m_mutex;
1699 };
1700 #endif
1701
1702 /*
1703         Generates ids for comparable values.
1704         Id=0 is reserved for "no value".
1705
1706         Is fast at:
1707         - Returning value by id (very fast)
1708         - Returning id by value
1709         - Generating a new id for a value
1710
1711         Is not able to:
1712         - Remove an id/value pair (is possible to implement but slow)
1713 */
1714 template<typename T>
1715 class MutexedIdGenerator
1716 {
1717 public:
1718         MutexedIdGenerator()
1719         {
1720                 m_mutex.Init();
1721                 assert(m_mutex.IsInitialized());
1722         }
1723         
1724         // Returns true if found
1725         bool getValue(u32 id, T &value)
1726         {
1727                 if(id == 0)
1728                         return false;
1729                 JMutexAutoLock lock(m_mutex);
1730                 if(m_id_to_value.size() < id)
1731                         return false;
1732                 value = m_id_to_value[id-1];
1733                 return true;
1734         }
1735         
1736         // If id exists for value, returns the id.
1737         // Otherwise generates an id for the value.
1738         u32 getId(const T &value)
1739         {
1740                 JMutexAutoLock lock(m_mutex);
1741                 typename core::map<T, u32>::Node *n;
1742                 n = m_value_to_id.find(value);
1743                 if(n != NULL)
1744                         return n->getValue();
1745                 m_id_to_value.push_back(value);
1746                 u32 new_id = m_id_to_value.size();
1747                 m_value_to_id.insert(value, new_id);
1748                 return new_id;
1749         }
1750
1751 private:
1752         JMutex m_mutex;
1753         // Values are stored here at id-1 position (id 1 = [0])
1754         core::array<T> m_id_to_value;
1755         core::map<T, u32> m_value_to_id;
1756 };
1757
1758 /*
1759         Checks if a string contains only supplied characters
1760 */
1761 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1762 {
1763         for(u32 i=0; i<s.size(); i++)
1764         {
1765                 bool confirmed = false;
1766                 for(u32 j=0; j<allowed_chars.size(); j++)
1767                 {
1768                         if(s[i] == allowed_chars[j])
1769                         {
1770                                 confirmed = true;
1771                                 break;
1772                         }
1773                 }
1774                 if(confirmed == false)
1775                         return false;
1776         }
1777         return true;
1778 }
1779
1780 /*
1781         Forcefully wraps string into rows using \n
1782         (no word wrap, used for showing paths in gui)
1783 */
1784 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1785 {
1786         std::string to;
1787         for(u32 i=0; i<from.size(); i++)
1788         {
1789                 if(i != 0 && i%rowlen == 0)
1790                         to += '\n';
1791                 to += from[i];
1792         }
1793         return to;
1794 }
1795
1796 /*
1797         Some helper stuff
1798 */
1799 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1800 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1801
1802 /*
1803         Returns integer position of node in given floating point position
1804 */
1805 inline v3s16 floatToInt(v3f p, f32 d)
1806 {
1807         v3s16 p2(
1808                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1809                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1810                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1811         return p2;
1812 }
1813
1814 /*
1815         Returns floating point position of node in given integer position
1816 */
1817 inline v3f intToFloat(v3s16 p, f32 d)
1818 {
1819         v3f p2(
1820                 (f32)p.X * d,
1821                 (f32)p.Y * d,
1822                 (f32)p.Z * d
1823         );
1824         return p2;
1825 }
1826
1827 /*
1828         More serialization stuff
1829 */
1830
1831 // Creates a string with the length as the first two bytes
1832 inline std::string serializeString(const std::string plain)
1833 {
1834         assert(plain.size() <= 65535);
1835         char buf[2];
1836         writeU16((u8*)&buf[0], plain.size());
1837         std::string s;
1838         s.append(buf, 2);
1839         s.append(plain);
1840         return s;
1841 }
1842
1843 // Reads a string with the length as the first two bytes
1844 inline std::string deSerializeString(const std::string encoded)
1845 {
1846         u16 s_size = readU16((u8*)&encoded.c_str()[0]);
1847         std::string s;
1848         s.reserve(s_size);
1849         s.append(&encoded.c_str()[2], s_size);
1850         return s;
1851 }
1852
1853 // Reads a string with the length as the first two bytes
1854 inline std::string deSerializeString(std::istream &is)
1855 {
1856         char buf[2];
1857         is.read(buf, 2);
1858         if(is.gcount() != 2)
1859                 throw SerializationError("deSerializeString: size not read");
1860         u16 s_size = readU16((u8*)buf);
1861         if(s_size == 0)
1862                 return "";
1863         Buffer<char> buf2(s_size);
1864         is.read(&buf2[0], s_size);
1865         std::string s;
1866         s.reserve(s_size);
1867         s.append(&buf2[0], s_size);
1868         return s;
1869 }
1870
1871 // Creates a string with the length as the first four bytes
1872 inline std::string serializeLongString(const std::string plain)
1873 {
1874         char buf[4];
1875         writeU32((u8*)&buf[0], plain.size());
1876         std::string s;
1877         s.append(buf, 4);
1878         s.append(plain);
1879         return s;
1880 }
1881
1882 // Reads a string with the length as the first four bytes
1883 inline std::string deSerializeLongString(const std::string encoded)
1884 {
1885         u32 s_size = readU32((u8*)&encoded.c_str()[0]);
1886         std::string s;
1887         s.reserve(s_size);
1888         s.append(&encoded.c_str()[2], s_size);
1889         return s;
1890 }
1891
1892 // Reads a string with the length as the first four bytes
1893 inline std::string deSerializeLongString(std::istream &is)
1894 {
1895         char buf[4];
1896         is.read(buf, 4);
1897         if(is.gcount() != 4)
1898                 throw SerializationError("deSerializeLongString: size not read");
1899         u32 s_size = readU32((u8*)buf);
1900         if(s_size == 0)
1901                 return "";
1902         Buffer<char> buf2(s_size);
1903         is.read(&buf2[0], s_size);
1904         std::string s;
1905         s.reserve(s_size);
1906         s.append(&buf2[0], s_size);
1907         return s;
1908 }
1909
1910 //
1911
1912 inline u32 time_to_daynight_ratio(u32 time_of_day)
1913 {
1914         const s32 daylength = 16;
1915         const s32 nightlength = 6;
1916         const s32 daytimelength = 8;
1917         s32 d = daylength;
1918         s32 t = (((time_of_day)%24000)/(24000/d));
1919         if(t < nightlength/2 || t >= d - nightlength/2)
1920                 return 300;
1921         else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
1922                 return 1000;
1923         else
1924                 return 750;
1925 }
1926
1927 // Random helper. Usually d=BS
1928 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
1929 {
1930         return core::aabbox3d<f32>(
1931                 (float)p.X * d - 0.5*d,
1932                 (float)p.Y * d - 0.5*d,
1933                 (float)p.Z * d - 0.5*d,
1934                 (float)p.X * d + 0.5*d,
1935                 (float)p.Y * d + 0.5*d,
1936                 (float)p.Z * d + 0.5*d
1937         );
1938 }
1939         
1940
1941 #endif
1942