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