]> git.lizzy.rs Git - dragonfireclient.git/blob - src/utility.h
Improve item serialization
[dragonfireclient.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 <vector>
28 #include <jthread.h>
29 #include <jmutex.h>
30 #include <jmutexautolock.h>
31 #include <cstring>
32
33 #include "common_irrlicht.h"
34 #include "debug.h"
35 #include "exceptions.h"
36 #include "porting.h"
37 #include "strfnd.h" // For trim()
38
39 extern const v3s16 g_6dirs[6];
40
41 extern const v3s16 g_26dirs[26];
42
43 // 26th is (0,0,0)
44 extern const v3s16 g_27dirs[27];
45
46 inline void writeU64(u8 *data, u64 i)
47 {
48         data[0] = ((i>>56)&0xff);
49         data[1] = ((i>>48)&0xff);
50         data[2] = ((i>>40)&0xff);
51         data[3] = ((i>>32)&0xff);
52         data[4] = ((i>>24)&0xff);
53         data[5] = ((i>>16)&0xff);
54         data[6] = ((i>> 8)&0xff);
55         data[7] = ((i>> 0)&0xff);
56 }
57
58 inline void writeU32(u8 *data, u32 i)
59 {
60         data[0] = ((i>>24)&0xff);
61         data[1] = ((i>>16)&0xff);
62         data[2] = ((i>> 8)&0xff);
63         data[3] = ((i>> 0)&0xff);
64 }
65
66 inline void writeU16(u8 *data, u16 i)
67 {
68         data[0] = ((i>> 8)&0xff);
69         data[1] = ((i>> 0)&0xff);
70 }
71
72 inline void writeU8(u8 *data, u8 i)
73 {
74         data[0] = ((i>> 0)&0xff);
75 }
76
77 inline u64 readU64(u8 *data)
78 {
79         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
80                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
81                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
82                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
83 }
84
85 inline u32 readU32(u8 *data)
86 {
87         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
88 }
89
90 inline u16 readU16(u8 *data)
91 {
92         return (data[0]<<8) | (data[1]<<0);
93 }
94
95 inline u8 readU8(u8 *data)
96 {
97         return (data[0]<<0);
98 }
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 writeF1000(u8 *data, f32 i){
108         writeS32(data, i*1000);
109 }
110 inline f32 readF1000(u8 *data){
111         return (f32)readS32(data)/1000.;
112 }
113
114 inline void writeS16(u8 *data, s16 i){
115         writeU16(data, (u16)i);
116 }
117 inline s16 readS16(u8 *data){
118         return (s16)readU16(data);
119 }
120
121 inline void writeV3S32(u8 *data, v3s32 p)
122 {
123         writeS32(&data[0], p.X);
124         writeS32(&data[4], p.Y);
125         writeS32(&data[8], p.Z);
126 }
127 inline v3s32 readV3S32(u8 *data)
128 {
129         v3s32 p;
130         p.X = readS32(&data[0]);
131         p.Y = readS32(&data[4]);
132         p.Z = readS32(&data[8]);
133         return p;
134 }
135
136 inline void writeV3F1000(u8 *data, v3f p)
137 {
138         writeF1000(&data[0], p.X);
139         writeF1000(&data[4], p.Y);
140         writeF1000(&data[8], p.Z);
141 }
142 inline v3f readV3F1000(u8 *data)
143 {
144         v3f p;
145         p.X = (float)readF1000(&data[0]);
146         p.Y = (float)readF1000(&data[4]);
147         p.Z = (float)readF1000(&data[8]);
148         return p;
149 }
150
151 inline void writeV2S16(u8 *data, v2s16 p)
152 {
153         writeS16(&data[0], p.X);
154         writeS16(&data[2], p.Y);
155 }
156
157 inline v2s16 readV2S16(u8 *data)
158 {
159         v2s16 p;
160         p.X = readS16(&data[0]);
161         p.Y = readS16(&data[2]);
162         return p;
163 }
164
165 inline void writeV2S32(u8 *data, v2s32 p)
166 {
167         writeS32(&data[0], p.X);
168         writeS32(&data[2], p.Y);
169 }
170
171 inline v2s32 readV2S32(u8 *data)
172 {
173         v2s32 p;
174         p.X = readS32(&data[0]);
175         p.Y = readS32(&data[2]);
176         return p;
177 }
178
179 inline void writeV3S16(u8 *data, v3s16 p)
180 {
181         writeS16(&data[0], p.X);
182         writeS16(&data[2], p.Y);
183         writeS16(&data[4], p.Z);
184 }
185
186 inline v3s16 readV3S16(u8 *data)
187 {
188         v3s16 p;
189         p.X = readS16(&data[0]);
190         p.Y = readS16(&data[2]);
191         p.Z = readS16(&data[4]);
192         return p;
193 }
194
195 /*
196         The above stuff directly interfaced to iostream
197 */
198
199 inline void writeU8(std::ostream &os, u8 p)
200 {
201         char buf[1];
202         writeU8((u8*)buf, p);
203         os.write(buf, 1);
204 }
205 inline u8 readU8(std::istream &is)
206 {
207         char buf[1];
208         is.read(buf, 1);
209         return readU8((u8*)buf);
210 }
211
212 inline void writeU16(std::ostream &os, u16 p)
213 {
214         char buf[2];
215         writeU16((u8*)buf, p);
216         os.write(buf, 2);
217 }
218 inline u16 readU16(std::istream &is)
219 {
220         char buf[2];
221         is.read(buf, 2);
222         return readU16((u8*)buf);
223 }
224
225 inline void writeU32(std::ostream &os, u32 p)
226 {
227         char buf[4];
228         writeU32((u8*)buf, p);
229         os.write(buf, 4);
230 }
231 inline u32 readU32(std::istream &is)
232 {
233         char buf[4];
234         is.read(buf, 4);
235         return readU32((u8*)buf);
236 }
237
238 inline void writeS32(std::ostream &os, u32 p)
239 {
240         char buf[4];
241         writeS32((u8*)buf, p);
242         os.write(buf, 4);
243 }
244 inline u32 readS32(std::istream &is)
245 {
246         char buf[4];
247         is.read(buf, 4);
248         return readS32((u8*)buf);
249 }
250
251 inline void writeF1000(std::ostream &os, f32 p)
252 {
253         char buf[4];
254         writeF1000((u8*)buf, p);
255         os.write(buf, 4);
256 }
257 inline f32 readF1000(std::istream &is)
258 {
259         char buf[4];
260         is.read(buf, 4);
261         return readF1000((u8*)buf);
262 }
263
264 inline void writeV3F1000(std::ostream &os, v3f p)
265 {
266         char buf[12];
267         writeV3F1000((u8*)buf, p);
268         os.write(buf, 12);
269 }
270 inline v3f readV3F1000(std::istream &is)
271 {
272         char buf[12];
273         is.read(buf, 12);
274         return readV3F1000((u8*)buf);
275 }
276
277 /*
278         None of these are used at the moment
279 */
280
281 template <typename T>
282 class SharedPtr
283 {
284 public:
285         SharedPtr(T *t=NULL)
286         {
287                 refcount = new int;
288                 *refcount = 1;
289                 ptr = t;
290         }
291         SharedPtr(SharedPtr<T> &t)
292         {
293                 //*this = t;
294                 drop();
295                 refcount = t.refcount;
296                 (*refcount)++;
297                 ptr = t.ptr;
298         }
299         ~SharedPtr()
300         {
301                 drop();
302         }
303         SharedPtr<T> & operator=(T *t)
304         {
305                 drop();
306                 refcount = new int;
307                 *refcount = 1;
308                 ptr = t;
309                 return *this;
310         }
311         SharedPtr<T> & operator=(SharedPtr<T> &t)
312         {
313                 drop();
314                 refcount = t.refcount;
315                 (*refcount)++;
316                 ptr = t.ptr;
317                 return *this;
318         }
319         T* operator->()
320         {
321                 return ptr;
322         }
323         T & operator*()
324         {
325                 return *ptr;
326         }
327         bool operator!=(T *t)
328         {
329                 return ptr != t;
330         }
331         bool operator==(T *t)
332         {
333                 return ptr == t;
334         }
335         T & operator[](unsigned int i)
336         {
337                 return ptr[i];
338         }
339 private:
340         void drop()
341         {
342                 assert((*refcount) > 0);
343                 (*refcount)--;
344                 if(*refcount == 0)
345                 {
346                         delete refcount;
347                         if(ptr != NULL)
348                                 delete ptr;
349                 }
350         }
351         T *ptr;
352         int *refcount;
353 };
354
355 template <typename T>
356 class Buffer
357 {
358 public:
359         Buffer()
360         {
361                 m_size = 0;
362                 data = NULL;
363         }
364         Buffer(unsigned int size)
365         {
366                 m_size = size;
367                 if(size != 0)
368                         data = new T[size];
369                 else
370                         data = NULL;
371         }
372         Buffer(const Buffer &buffer)
373         {
374                 m_size = buffer.m_size;
375                 if(m_size != 0)
376                 {
377                         data = new T[buffer.m_size];
378                         memcpy(data, buffer.data, buffer.m_size);
379                 }
380                 else
381                         data = NULL;
382         }
383         Buffer(const T *t, unsigned int size)
384         {
385                 m_size = size;
386                 if(size != 0)
387                 {
388                         data = new T[size];
389                         memcpy(data, t, size);
390                 }
391                 else
392                         data = NULL;
393         }
394         ~Buffer()
395         {
396                 drop();
397         }
398         Buffer& operator=(const Buffer &buffer)
399         {
400                 if(this == &buffer)
401                         return *this;
402                 drop();
403                 m_size = buffer.m_size;
404                 if(m_size != 0)
405                 {
406                         data = new T[buffer.m_size];
407                         memcpy(data, buffer.data, buffer.m_size);
408                 }
409                 else
410                         data = NULL;
411                 return *this;
412         }
413         T & operator[](unsigned int i) const
414         {
415                 return data[i];
416         }
417         T * operator*() const
418         {
419                 return data;
420         }
421         unsigned int getSize() const
422         {
423                 return m_size;
424         }
425 private:
426         void drop()
427         {
428                 if(data)
429                         delete[] data;
430         }
431         T *data;
432         unsigned int m_size;
433 };
434
435 template <typename T>
436 class SharedBuffer
437 {
438 public:
439         SharedBuffer()
440         {
441                 m_size = 0;
442                 data = NULL;
443                 refcount = new unsigned int;
444                 (*refcount) = 1;
445         }
446         SharedBuffer(unsigned int size)
447         {
448                 m_size = size;
449                 if(m_size != 0)
450                         data = new T[m_size];
451                 else
452                         data = NULL;
453                 refcount = new unsigned int;
454                 (*refcount) = 1;
455         }
456         SharedBuffer(const SharedBuffer &buffer)
457         {
458                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
459                 m_size = buffer.m_size;
460                 data = buffer.data;
461                 refcount = buffer.refcount;
462                 (*refcount)++;
463         }
464         SharedBuffer & operator=(const SharedBuffer & buffer)
465         {
466                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
467                 if(this == &buffer)
468                         return *this;
469                 drop();
470                 m_size = buffer.m_size;
471                 data = buffer.data;
472                 refcount = buffer.refcount;
473                 (*refcount)++;
474                 return *this;
475         }
476         /*
477                 Copies whole buffer
478         */
479         SharedBuffer(T *t, unsigned int size)
480         {
481                 m_size = size;
482                 if(m_size != 0)
483                 {
484                         data = new T[m_size];
485                         memcpy(data, t, m_size);
486                 }
487                 else
488                         data = NULL;
489                 refcount = new unsigned int;
490                 (*refcount) = 1;
491         }
492         /*
493                 Copies whole buffer
494         */
495         SharedBuffer(const Buffer<T> &buffer)
496         {
497                 m_size = buffer.getSize();
498                 if(m_size != 0)
499                 {
500                         data = new T[m_size];
501                         memcpy(data, *buffer, buffer.getSize());
502                 }
503                 else
504                         data = NULL;
505                 refcount = new unsigned int;
506                 (*refcount) = 1;
507         }
508         ~SharedBuffer()
509         {
510                 drop();
511         }
512         T & operator[](unsigned int i) const
513         {
514                 //assert(i < m_size)
515                 return data[i];
516         }
517         T * operator*() const
518         {
519                 return data;
520         }
521         unsigned int getSize() const
522         {
523                 return m_size;
524         }
525         operator Buffer<T>() const
526         {
527                 return Buffer<T>(data, m_size);
528         }
529 private:
530         void drop()
531         {
532                 assert((*refcount) > 0);
533                 (*refcount)--;
534                 if(*refcount == 0)
535                 {
536                         if(data)
537                                 delete[] data;
538                         delete refcount;
539                 }
540         }
541         T *data;
542         unsigned int m_size;
543         unsigned int *refcount;
544 };
545
546 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
547 {
548         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
549         return b;
550 }
551
552 template<typename T>
553 class MutexedVariable
554 {
555 public:
556         MutexedVariable(T value):
557                 m_value(value)
558         {
559                 m_mutex.Init();
560         }
561
562         T get()
563         {
564                 JMutexAutoLock lock(m_mutex);
565                 return m_value;
566         }
567
568         void set(T value)
569         {
570                 JMutexAutoLock lock(m_mutex);
571                 m_value = value;
572         }
573         
574         // You'll want to grab this in a SharedPtr
575         JMutexAutoLock * getLock()
576         {
577                 return new JMutexAutoLock(m_mutex);
578         }
579         
580         // You pretty surely want to grab the lock when accessing this
581         T m_value;
582
583 private:
584         JMutex m_mutex;
585 };
586
587 /*
588         TimeTaker
589 */
590
591 class TimeTaker
592 {
593 public:
594         TimeTaker(const char *name, u32 *result=NULL);
595
596         ~TimeTaker()
597         {
598                 stop();
599         }
600
601         u32 stop(bool quiet=false);
602
603         u32 getTime();
604
605 private:
606         const char *m_name;
607         u32 m_time1;
608         bool m_running;
609         u32 *m_result;
610 };
611
612 #ifndef SERVER
613 // Sets the color of all vertices in the mesh
614 void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color);
615 #endif
616
617 // Calculates the borders of a "d-radius" cube
618 inline void getFacePositions(core::list<v3s16> &list, u16 d)
619 {
620         if(d == 0)
621         {
622                 list.push_back(v3s16(0,0,0));
623                 return;
624         }
625         if(d == 1)
626         {
627                 /*
628                         This is an optimized sequence of coordinates.
629                 */
630                 list.push_back(v3s16( 0, 1, 0)); // top
631                 list.push_back(v3s16( 0, 0, 1)); // back
632                 list.push_back(v3s16(-1, 0, 0)); // left
633                 list.push_back(v3s16( 1, 0, 0)); // right
634                 list.push_back(v3s16( 0, 0,-1)); // front
635                 list.push_back(v3s16( 0,-1, 0)); // bottom
636                 // 6
637                 list.push_back(v3s16(-1, 0, 1)); // back left
638                 list.push_back(v3s16( 1, 0, 1)); // back right
639                 list.push_back(v3s16(-1, 0,-1)); // front left
640                 list.push_back(v3s16( 1, 0,-1)); // front right
641                 list.push_back(v3s16(-1,-1, 0)); // bottom left
642                 list.push_back(v3s16( 1,-1, 0)); // bottom right
643                 list.push_back(v3s16( 0,-1, 1)); // bottom back
644                 list.push_back(v3s16( 0,-1,-1)); // bottom front
645                 list.push_back(v3s16(-1, 1, 0)); // top left
646                 list.push_back(v3s16( 1, 1, 0)); // top right
647                 list.push_back(v3s16( 0, 1, 1)); // top back
648                 list.push_back(v3s16( 0, 1,-1)); // top front
649                 // 18
650                 list.push_back(v3s16(-1, 1, 1)); // top back-left
651                 list.push_back(v3s16( 1, 1, 1)); // top back-right
652                 list.push_back(v3s16(-1, 1,-1)); // top front-left
653                 list.push_back(v3s16( 1, 1,-1)); // top front-right
654                 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
655                 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
656                 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
657                 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
658                 // 26
659                 return;
660         }
661
662         // Take blocks in all sides, starting from y=0 and going +-y
663         for(s16 y=0; y<=d-1; y++)
664         {
665                 // Left and right side, including borders
666                 for(s16 z=-d; z<=d; z++)
667                 {
668                         list.push_back(v3s16(d,y,z));
669                         list.push_back(v3s16(-d,y,z));
670                         if(y != 0)
671                         {
672                                 list.push_back(v3s16(d,-y,z));
673                                 list.push_back(v3s16(-d,-y,z));
674                         }
675                 }
676                 // Back and front side, excluding borders
677                 for(s16 x=-d+1; x<=d-1; x++)
678                 {
679                         list.push_back(v3s16(x,y,d));
680                         list.push_back(v3s16(x,y,-d));
681                         if(y != 0)
682                         {
683                                 list.push_back(v3s16(x,-y,d));
684                                 list.push_back(v3s16(x,-y,-d));
685                         }
686                 }
687         }
688
689         // Take the bottom and top face with borders
690         // -d<x<d, y=+-d, -d<z<d
691         for(s16 x=-d; x<=d; x++)
692         for(s16 z=-d; z<=d; z++)
693         {
694                 list.push_back(v3s16(x,-d,z));
695                 list.push_back(v3s16(x,d,z));
696         }
697 }
698
699 class IndentationRaiser
700 {
701 public:
702         IndentationRaiser(u16 *indentation)
703         {
704                 m_indentation = indentation;
705                 (*m_indentation)++;
706         }
707         ~IndentationRaiser()
708         {
709                 (*m_indentation)--;
710         }
711 private:
712         u16 *m_indentation;
713 };
714
715 inline s16 getContainerPos(s16 p, s16 d)
716 {
717         return (p>=0 ? p : p-d+1) / d;
718 }
719
720 inline v2s16 getContainerPos(v2s16 p, s16 d)
721 {
722         return v2s16(
723                 getContainerPos(p.X, d),
724                 getContainerPos(p.Y, d)
725         );
726 }
727
728 inline v3s16 getContainerPos(v3s16 p, s16 d)
729 {
730         return v3s16(
731                 getContainerPos(p.X, d),
732                 getContainerPos(p.Y, d),
733                 getContainerPos(p.Z, d)
734         );
735 }
736
737 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
738 {
739         return v2s16(
740                 getContainerPos(p.X, d.X),
741                 getContainerPos(p.Y, d.Y)
742         );
743 }
744
745 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
746 {
747         return v3s16(
748                 getContainerPos(p.X, d.X),
749                 getContainerPos(p.Y, d.Y),
750                 getContainerPos(p.Z, d.Z)
751         );
752 }
753
754 inline bool isInArea(v3s16 p, s16 d)
755 {
756         return (
757                 p.X >= 0 && p.X < d &&
758                 p.Y >= 0 && p.Y < d &&
759                 p.Z >= 0 && p.Z < d
760         );
761 }
762
763 inline bool isInArea(v2s16 p, s16 d)
764 {
765         return (
766                 p.X >= 0 && p.X < d &&
767                 p.Y >= 0 && p.Y < d
768         );
769 }
770
771 inline bool isInArea(v3s16 p, v3s16 d)
772 {
773         return (
774                 p.X >= 0 && p.X < d.X &&
775                 p.Y >= 0 && p.Y < d.Y &&
776                 p.Z >= 0 && p.Z < d.Z
777         );
778 }
779
780 inline s16 rangelim(s16 i, s16 max)
781 {
782         if(i < 0)
783                 return 0;
784         if(i > max)
785                 return max;
786         return i;
787 }
788
789 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
790
791 inline v3s16 arealim(v3s16 p, s16 d)
792 {
793         if(p.X < 0)
794                 p.X = 0;
795         if(p.Y < 0)
796                 p.Y = 0;
797         if(p.Z < 0)
798                 p.Z = 0;
799         if(p.X > d-1)
800                 p.X = d-1;
801         if(p.Y > d-1)
802                 p.Y = d-1;
803         if(p.Z > d-1)
804                 p.Z = d-1;
805         return p;
806 }
807
808 inline std::wstring narrow_to_wide(const std::string& mbs)
809 {
810         size_t wcl = mbs.size();
811         Buffer<wchar_t> wcs(wcl+1);
812         size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
813         if(l == (size_t)(-1))
814                 return L"<invalid multibyte string>";
815         wcs[l] = 0;
816         return *wcs;
817 }
818
819 inline std::string wide_to_narrow(const std::wstring& wcs)
820 {
821         size_t mbl = wcs.size()*4;
822         SharedBuffer<char> mbs(mbl+1);
823         size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
824         if(l == (size_t)(-1))
825                 mbs[0] = 0;
826         else
827                 mbs[l] = 0;
828         return *mbs;
829 }
830
831 // Split a string using the given delimiter. Returns a vector containing
832 // the component parts.
833 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
834 {
835         std::vector<std::wstring> parts;
836         std::wstringstream sstr(str);
837         std::wstring part;
838         while(std::getline(sstr, part, delimiter))
839                 parts.push_back(part);
840         return parts;
841 }
842
843
844 /*
845         See test.cpp for example cases.
846         wraps degrees to the range of -360...360
847         NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
848 */
849 inline float wrapDegrees(float f)
850 {
851         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
852         // This results in
853         // 10, 720, -1, -361
854         int i = floor(f);
855         // 0, 2, 0, -1
856         int l = i / 360;
857         // NOTE: This would be used for wrapping to 0...360
858         // 0, 2, -1, -2
859         /*if(i < 0)
860                 l -= 1;*/
861         // 0, 720, 0, -360
862         int k = l * 360;
863         // 10, 0.5, -0.5, -0.5
864         f -= float(k);
865         return f;
866 }
867
868 /* Wrap to 0...360 */
869 inline float wrapDegrees_0_360(float f)
870 {
871         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
872         // This results in
873         // 10, 720, -1, -361
874         int i = floor(f);
875         // 0, 2, 0, -1
876         int l = i / 360;
877         // Wrap to 0...360
878         // 0, 2, -1, -2
879         if(i < 0)
880                 l -= 1;
881         // 0, 720, 0, -360
882         int k = l * 360;
883         // 10, 0.5, -0.5, -0.5
884         f -= float(k);
885         return f;
886 }
887
888 /* Wrap to -180...180 */
889 inline float wrapDegrees_180(float f)
890 {
891         f += 180;
892         f = wrapDegrees_0_360(f);
893         f -= 180;
894         return f;
895 }
896
897 inline std::string lowercase(const std::string &s)
898 {
899         std::string s2;
900         for(size_t i=0; i<s.size(); i++)
901         {
902                 char c = s[i];
903                 if(c >= 'A' && c <= 'Z')
904                         c -= 'A' - 'a';
905                 s2 += c;
906         }
907         return s2;
908 }
909
910 inline bool is_yes(const std::string &s)
911 {
912         std::string s2 = lowercase(trim(s));
913         if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
914                 return true;
915         return false;
916 }
917
918 inline s32 stoi(const std::string &s, s32 min, s32 max)
919 {
920         s32 i = atoi(s.c_str());
921         if(i < min)
922                 i = min;
923         if(i > max)
924                 i = max;
925         return i;
926 }
927
928
929 // MSVC2010 includes it's own versions of these
930 #if !defined(_MSC_VER) || _MSC_VER < 1600
931
932 inline s32 stoi(std::string s)
933 {
934         return atoi(s.c_str());
935 }
936
937 inline s32 stoi(std::wstring s)
938 {
939         return atoi(wide_to_narrow(s).c_str());
940 }
941
942 inline float stof(std::string s)
943 {
944         float f;
945         std::istringstream ss(s);
946         ss>>f;
947         return f;
948 }
949
950 #endif
951
952 inline std::string itos(s32 i)
953 {
954         std::ostringstream o;
955         o<<i;
956         return o.str();
957 }
958
959 inline std::string ftos(float f)
960 {
961         std::ostringstream o;
962         o<<f;
963         return o.str();
964 }
965
966 inline void str_replace(std::string & str, std::string const & pattern,
967                 std::string const & replacement)
968 {
969         std::string::size_type start = str.find(pattern, 0);
970         while(start != str.npos)
971         {
972                 str.replace(start, pattern.size(), replacement);
973                 start = str.find(pattern, start+replacement.size());
974         }
975 }
976
977 inline void str_replace_char(std::string & str, char from, char to)
978 {
979         for(unsigned int i=0; i<str.size(); i++)
980         {
981                 if(str[i] == from)
982                         str[i] = to;
983         }
984 }
985
986 /*
987         A base class for simple background thread implementation
988 */
989
990 class SimpleThread : public JThread
991 {
992         bool run;
993         JMutex run_mutex;
994
995 public:
996
997         SimpleThread():
998                 JThread(),
999                 run(true)
1000         {
1001                 run_mutex.Init();
1002         }
1003
1004         virtual ~SimpleThread()
1005         {}
1006
1007         virtual void * Thread() = 0;
1008
1009         bool getRun()
1010         {
1011                 JMutexAutoLock lock(run_mutex);
1012                 return run;
1013         }
1014         void setRun(bool a_run)
1015         {
1016                 JMutexAutoLock lock(run_mutex);
1017                 run = a_run;
1018         }
1019
1020         void stop()
1021         {
1022                 setRun(false);
1023                 while(IsRunning())
1024                         sleep_ms(100);
1025         }
1026 };
1027
1028 /*
1029         FIFO queue (well, actually a FILO also)
1030 */
1031 template<typename T>
1032 class Queue
1033 {
1034 public:
1035         void push_back(T t)
1036         {
1037                 m_list.push_back(t);
1038         }
1039         
1040         T pop_front()
1041         {
1042                 if(m_list.size() == 0)
1043                         throw ItemNotFoundException("Queue: queue is empty");
1044
1045                 typename core::list<T>::Iterator begin = m_list.begin();
1046                 T t = *begin;
1047                 m_list.erase(begin);
1048                 return t;
1049         }
1050         T pop_back()
1051         {
1052                 if(m_list.size() == 0)
1053                         throw ItemNotFoundException("Queue: queue is empty");
1054
1055                 typename core::list<T>::Iterator last = m_list.getLast();
1056                 T t = *last;
1057                 m_list.erase(last);
1058                 return t;
1059         }
1060
1061         u32 size()
1062         {
1063                 return m_list.size();
1064         }
1065
1066 protected:
1067         core::list<T> m_list;
1068 };
1069
1070 /*
1071         Thread-safe FIFO queue (well, actually a FILO also)
1072 */
1073
1074 template<typename T>
1075 class MutexedQueue
1076 {
1077 public:
1078         MutexedQueue()
1079         {
1080                 m_mutex.Init();
1081         }
1082         u32 size()
1083         {
1084                 JMutexAutoLock lock(m_mutex);
1085                 return m_list.size();
1086         }
1087         void push_back(T t)
1088         {
1089                 JMutexAutoLock lock(m_mutex);
1090                 m_list.push_back(t);
1091         }
1092         T pop_front(u32 wait_time_max_ms=0)
1093         {
1094                 u32 wait_time_ms = 0;
1095
1096                 for(;;)
1097                 {
1098                         {
1099                                 JMutexAutoLock lock(m_mutex);
1100
1101                                 if(m_list.size() > 0)
1102                                 {
1103                                         typename core::list<T>::Iterator begin = m_list.begin();
1104                                         T t = *begin;
1105                                         m_list.erase(begin);
1106                                         return t;
1107                                 }
1108
1109                                 if(wait_time_ms >= wait_time_max_ms)
1110                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1111                         }
1112
1113                         // Wait a while before trying again
1114                         sleep_ms(10);
1115                         wait_time_ms += 10;
1116                 }
1117         }
1118         T pop_back(u32 wait_time_max_ms=0)
1119         {
1120                 u32 wait_time_ms = 0;
1121
1122                 for(;;)
1123                 {
1124                         {
1125                                 JMutexAutoLock lock(m_mutex);
1126
1127                                 if(m_list.size() > 0)
1128                                 {
1129                                         typename core::list<T>::Iterator last = m_list.getLast();
1130                                         T t = *last;
1131                                         m_list.erase(last);
1132                                         return t;
1133                                 }
1134
1135                                 if(wait_time_ms >= wait_time_max_ms)
1136                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1137                         }
1138
1139                         // Wait a while before trying again
1140                         sleep_ms(10);
1141                         wait_time_ms += 10;
1142                 }
1143         }
1144
1145         JMutex & getMutex()
1146         {
1147                 return m_mutex;
1148         }
1149
1150         core::list<T> & getList()
1151         {
1152                 return m_list;
1153         }
1154
1155 protected:
1156         JMutex m_mutex;
1157         core::list<T> m_list;
1158 };
1159
1160 /*
1161         A single worker thread - multiple client threads queue framework.
1162 */
1163
1164 template<typename Caller, typename Data>
1165 class CallerInfo
1166 {
1167 public:
1168         Caller caller;
1169         Data data;
1170 };
1171
1172 template<typename Key, typename T, typename Caller, typename CallerData>
1173 class GetResult
1174 {
1175 public:
1176         Key key;
1177         T item;
1178         core::list<CallerInfo<Caller, CallerData> > callers;
1179 };
1180
1181 template<typename Key, typename T, typename Caller, typename CallerData>
1182 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1183 {
1184 };
1185
1186 template<typename Key, typename T, typename Caller, typename CallerData>
1187 class GetRequest
1188 {
1189 public:
1190         GetRequest()
1191         {
1192                 dest = NULL;
1193         }
1194         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1195         {
1196                 dest = a_dest;
1197         }
1198         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1199                         Key a_key)
1200         {
1201                 dest = a_dest;
1202                 key = a_key;
1203         }
1204         ~GetRequest()
1205         {
1206         }
1207         
1208         Key key;
1209         ResultQueue<Key, T, Caller, CallerData> *dest;
1210         core::list<CallerInfo<Caller, CallerData> > callers;
1211 };
1212
1213 template<typename Key, typename T, typename Caller, typename CallerData>
1214 class RequestQueue
1215 {
1216 public:
1217         u32 size()
1218         {
1219                 return m_queue.size();
1220         }
1221
1222         void add(Key key, Caller caller, CallerData callerdata,
1223                         ResultQueue<Key, T, Caller, CallerData> *dest)
1224         {
1225                 JMutexAutoLock lock(m_queue.getMutex());
1226                 
1227                 /*
1228                         If the caller is already on the list, only update CallerData
1229                 */
1230                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1231                                 i = m_queue.getList().begin();
1232                                 i != m_queue.getList().end(); i++)
1233                 {
1234                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1235
1236                         if(request.key == key)
1237                         {
1238                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1239                                                 i = request.callers.begin();
1240                                                 i != request.callers.end(); i++)
1241                                 {
1242                                         CallerInfo<Caller, CallerData> &ca = *i;
1243                                         if(ca.caller == caller)
1244                                         {
1245                                                 ca.data = callerdata;
1246                                                 return;
1247                                         }
1248                                 }
1249                                 CallerInfo<Caller, CallerData> ca;
1250                                 ca.caller = caller;
1251                                 ca.data = callerdata;
1252                                 request.callers.push_back(ca);
1253                                 return;
1254                         }
1255                 }
1256
1257                 /*
1258                         Else add a new request to the queue
1259                 */
1260
1261                 GetRequest<Key, T, Caller, CallerData> request;
1262                 request.key = key;
1263                 CallerInfo<Caller, CallerData> ca;
1264                 ca.caller = caller;
1265                 ca.data = callerdata;
1266                 request.callers.push_back(ca);
1267                 request.dest = dest;
1268                 
1269                 m_queue.getList().push_back(request);
1270         }
1271
1272         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1273         {
1274                 return m_queue.pop_front(wait_if_empty);
1275         }
1276
1277 private:
1278         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1279 };
1280
1281 /*
1282         Pseudo-random (VC++ rand() sucks)
1283 */
1284 int myrand(void);
1285 void mysrand(unsigned seed);
1286 #define MYRAND_MAX 32767
1287
1288 int myrand_range(int min, int max);
1289
1290 /*
1291         Miscellaneous functions
1292 */
1293
1294 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
1295                 f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
1296
1297 /*
1298         Queue with unique values with fast checking of value existence
1299 */
1300
1301 template<typename Value>
1302 class UniqueQueue
1303 {
1304 public:
1305         
1306         /*
1307                 Does nothing if value is already queued.
1308                 Return value:
1309                         true: value added
1310                         false: value already exists
1311         */
1312         bool push_back(Value value)
1313         {
1314                 // Check if already exists
1315                 if(m_map.find(value) != NULL)
1316                         return false;
1317
1318                 // Add
1319                 m_map.insert(value, 0);
1320                 m_list.push_back(value);
1321                 
1322                 return true;
1323         }
1324
1325         Value pop_front()
1326         {
1327                 typename core::list<Value>::Iterator i = m_list.begin();
1328                 Value value = *i;
1329                 m_map.remove(value);
1330                 m_list.erase(i);
1331                 return value;
1332         }
1333
1334         u32 size()
1335         {
1336                 assert(m_list.size() == m_map.size());
1337                 return m_list.size();
1338         }
1339
1340 private:
1341         core::map<Value, u8> m_map;
1342         core::list<Value> m_list;
1343 };
1344
1345 #if 1
1346 template<typename Key, typename Value>
1347 class MutexedMap
1348 {
1349 public:
1350         MutexedMap()
1351         {
1352                 m_mutex.Init();
1353                 assert(m_mutex.IsInitialized());
1354         }
1355         
1356         void set(const Key &name, const Value &value)
1357         {
1358                 JMutexAutoLock lock(m_mutex);
1359
1360                 m_values[name] = value;
1361         }
1362         
1363         bool get(const Key &name, Value *result)
1364         {
1365                 JMutexAutoLock lock(m_mutex);
1366
1367                 typename core::map<Key, Value>::Node *n;
1368                 n = m_values.find(name);
1369
1370                 if(n == NULL)
1371                         return false;
1372                 
1373                 if(result != NULL)
1374                         *result = n->getValue();
1375                         
1376                 return true;
1377         }
1378
1379 private:
1380         core::map<Key, Value> m_values;
1381         JMutex m_mutex;
1382 };
1383 #endif
1384
1385 /*
1386         Generates ids for comparable values.
1387         Id=0 is reserved for "no value".
1388
1389         Is fast at:
1390         - Returning value by id (very fast)
1391         - Returning id by value
1392         - Generating a new id for a value
1393
1394         Is not able to:
1395         - Remove an id/value pair (is possible to implement but slow)
1396 */
1397 template<typename T>
1398 class MutexedIdGenerator
1399 {
1400 public:
1401         MutexedIdGenerator()
1402         {
1403                 m_mutex.Init();
1404                 assert(m_mutex.IsInitialized());
1405         }
1406         
1407         // Returns true if found
1408         bool getValue(u32 id, T &value)
1409         {
1410                 if(id == 0)
1411                         return false;
1412                 JMutexAutoLock lock(m_mutex);
1413                 if(m_id_to_value.size() < id)
1414                         return false;
1415                 value = m_id_to_value[id-1];
1416                 return true;
1417         }
1418         
1419         // If id exists for value, returns the id.
1420         // Otherwise generates an id for the value.
1421         u32 getId(const T &value)
1422         {
1423                 JMutexAutoLock lock(m_mutex);
1424                 typename core::map<T, u32>::Node *n;
1425                 n = m_value_to_id.find(value);
1426                 if(n != NULL)
1427                         return n->getValue();
1428                 m_id_to_value.push_back(value);
1429                 u32 new_id = m_id_to_value.size();
1430                 m_value_to_id.insert(value, new_id);
1431                 return new_id;
1432         }
1433
1434 private:
1435         JMutex m_mutex;
1436         // Values are stored here at id-1 position (id 1 = [0])
1437         core::array<T> m_id_to_value;
1438         core::map<T, u32> m_value_to_id;
1439 };
1440
1441 /*
1442         Checks if a string contains only supplied characters
1443 */
1444 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1445 {
1446         for(u32 i=0; i<s.size(); i++)
1447         {
1448                 bool confirmed = false;
1449                 for(u32 j=0; j<allowed_chars.size(); j++)
1450                 {
1451                         if(s[i] == allowed_chars[j])
1452                         {
1453                                 confirmed = true;
1454                                 break;
1455                         }
1456                 }
1457                 if(confirmed == false)
1458                         return false;
1459         }
1460         return true;
1461 }
1462
1463 /*
1464         Forcefully wraps string into rows using \n
1465         (no word wrap, used for showing paths in gui)
1466 */
1467 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1468 {
1469         std::string to;
1470         for(u32 i=0; i<from.size(); i++)
1471         {
1472                 if(i != 0 && i%rowlen == 0)
1473                         to += '\n';
1474                 to += from[i];
1475         }
1476         return to;
1477 }
1478
1479 /*
1480         Some helper stuff
1481 */
1482 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1483 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1484
1485 /*
1486         Returns integer position of node in given floating point position
1487 */
1488 inline v3s16 floatToInt(v3f p, f32 d)
1489 {
1490         v3s16 p2(
1491                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1492                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1493                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1494         return p2;
1495 }
1496
1497 /*
1498         Returns floating point position of node in given integer position
1499 */
1500 inline v3f intToFloat(v3s16 p, f32 d)
1501 {
1502         v3f p2(
1503                 (f32)p.X * d,
1504                 (f32)p.Y * d,
1505                 (f32)p.Z * d
1506         );
1507         return p2;
1508 }
1509
1510 /*
1511         More serialization stuff
1512 */
1513
1514 // Creates a string with the length as the first two bytes
1515 inline std::string serializeString(const std::string &plain)
1516 {
1517         //assert(plain.size() <= 65535);
1518         if(plain.size() > 65535)
1519                 throw SerializationError("String too long for serializeString");
1520         char buf[2];
1521         writeU16((u8*)&buf[0], plain.size());
1522         std::string s;
1523         s.append(buf, 2);
1524         s.append(plain);
1525         return s;
1526 }
1527
1528 // Creates a string with the length as the first two bytes from wide string
1529 inline std::string serializeWideString(const std::wstring &plain)
1530 {
1531         //assert(plain.size() <= 65535);
1532         if(plain.size() > 65535)
1533                 throw SerializationError("String too long for serializeString");
1534         char buf[2];
1535         writeU16((u8*)buf, plain.size());
1536         std::string s;
1537         s.append(buf, 2);
1538         for(u32 i=0; i<plain.size(); i++)
1539         {
1540                 writeU16((u8*)buf, plain[i]);
1541                 s.append(buf, 2);
1542         }
1543         return s;
1544 }
1545
1546 // Reads a string with the length as the first two bytes
1547 inline std::string deSerializeString(std::istream &is)
1548 {
1549         char buf[2];
1550         is.read(buf, 2);
1551         if(is.gcount() != 2)
1552                 throw SerializationError("deSerializeString: size not read");
1553         u16 s_size = readU16((u8*)buf);
1554         if(s_size == 0)
1555                 return "";
1556         Buffer<char> buf2(s_size);
1557         is.read(&buf2[0], s_size);
1558         std::string s;
1559         s.reserve(s_size);
1560         s.append(&buf2[0], s_size);
1561         return s;
1562 }
1563
1564 // Reads a wide string with the length as the first two bytes
1565 inline std::wstring deSerializeWideString(std::istream &is)
1566 {
1567         char buf[2];
1568         is.read(buf, 2);
1569         if(is.gcount() != 2)
1570                 throw SerializationError("deSerializeString: size not read");
1571         u16 s_size = readU16((u8*)buf);
1572         if(s_size == 0)
1573                 return L"";
1574         std::wstring s;
1575         s.reserve(s_size);
1576         for(u32 i=0; i<s_size; i++)
1577         {
1578                 is.read(&buf[0], 2);
1579                 wchar_t c16 = readU16((u8*)buf);
1580                 s.append(&c16, 1);
1581         }
1582         return s;
1583 }
1584
1585 // Creates a string with the length as the first four bytes
1586 inline std::string serializeLongString(const std::string &plain)
1587 {
1588         char buf[4];
1589         writeU32((u8*)&buf[0], plain.size());
1590         std::string s;
1591         s.append(buf, 4);
1592         s.append(plain);
1593         return s;
1594 }
1595
1596 // Reads a string with the length as the first four bytes
1597 inline std::string deSerializeLongString(std::istream &is)
1598 {
1599         char buf[4];
1600         is.read(buf, 4);
1601         if(is.gcount() != 4)
1602                 throw SerializationError("deSerializeLongString: size not read");
1603         u32 s_size = readU32((u8*)buf);
1604         if(s_size == 0)
1605                 return "";
1606         Buffer<char> buf2(s_size);
1607         is.read(&buf2[0], s_size);
1608         std::string s;
1609         s.reserve(s_size);
1610         s.append(&buf2[0], s_size);
1611         return s;
1612 }
1613
1614 //
1615
1616 inline u32 time_to_daynight_ratio(u32 time_of_day)
1617 {
1618         const s32 daylength = 16;
1619         const s32 nightlength = 6;
1620         const s32 daytimelength = 8;
1621         s32 d = daylength;
1622         s32 t = (((time_of_day)%24000)/(24000/d));
1623         if(t < nightlength/2 || t >= d - nightlength/2)
1624                 //return 300;
1625                 return 350;
1626         else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
1627                 return 1000;
1628         else
1629                 return 750;
1630 }
1631
1632 // Random helper. Usually d=BS
1633 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
1634 {
1635         return core::aabbox3d<f32>(
1636                 (float)p.X * d - 0.5*d,
1637                 (float)p.Y * d - 0.5*d,
1638                 (float)p.Z * d - 0.5*d,
1639                 (float)p.X * d + 0.5*d,
1640                 (float)p.Y * d + 0.5*d,
1641                 (float)p.Z * d + 0.5*d
1642         );
1643 }
1644         
1645 class IntervalLimiter
1646 {
1647 public:
1648         IntervalLimiter():
1649                 m_accumulator(0)
1650         {
1651         }
1652         /*
1653                 dtime: time from last call to this method
1654                 wanted_interval: interval wanted
1655                 return value:
1656                         true: action should be skipped
1657                         false: action should be done
1658         */
1659         bool step(float dtime, float wanted_interval)
1660         {
1661                 m_accumulator += dtime;
1662                 if(m_accumulator < wanted_interval)
1663                         return false;
1664                 m_accumulator -= wanted_interval;
1665                 return true;
1666         }
1667 protected:
1668         float m_accumulator;
1669 };
1670
1671 std::string translatePassword(std::string playername, std::wstring password);
1672
1673 #endif
1674