3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #ifndef UTILITY_HEADER
21 #define UTILITY_HEADER
30 #include <jmutexautolock.h>
33 #include "common_irrlicht.h"
36 #include "exceptions.h"
39 extern const v3s16 g_6dirs[6];
41 extern const v3s16 g_26dirs[26];
44 extern const v3s16 g_27dirs[27];
46 inline void writeU64(u8 *data, u64 i)
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);
58 inline void writeU32(u8 *data, u32 i)
60 data[0] = ((i>>24)&0xff);
61 data[1] = ((i>>16)&0xff);
62 data[2] = ((i>> 8)&0xff);
63 data[3] = ((i>> 0)&0xff);
66 inline void writeU16(u8 *data, u16 i)
68 data[0] = ((i>> 8)&0xff);
69 data[1] = ((i>> 0)&0xff);
72 inline void writeU8(u8 *data, u8 i)
74 data[0] = ((i>> 0)&0xff);
77 inline u64 readU64(u8 *data)
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);
85 inline u32 readU32(u8 *data)
87 return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
90 inline u16 readU16(u8 *data)
92 return (data[0]<<8) | (data[1]<<0);
95 inline u8 readU8(u8 *data)
100 inline void writeS32(u8 *data, s32 i){
101 writeU32(data, (u32)i);
103 inline s32 readS32(u8 *data){
104 return (s32)readU32(data);
107 inline void writeF1000(u8 *data, f32 i){
108 writeS32(data, i*1000);
110 inline f32 readF1000(u8 *data){
111 return (f32)readS32(data)/1000.;
114 inline void writeS16(u8 *data, s16 i){
115 writeU16(data, (u16)i);
117 inline s16 readS16(u8 *data){
118 return (s16)readU16(data);
121 inline void writeV3S32(u8 *data, v3s32 p)
123 writeS32(&data[0], p.X);
124 writeS32(&data[4], p.Y);
125 writeS32(&data[8], p.Z);
127 inline v3s32 readV3S32(u8 *data)
130 p.X = readS32(&data[0]);
131 p.Y = readS32(&data[4]);
132 p.Z = readS32(&data[8]);
136 inline void writeV3F1000(u8 *data, v3f p)
138 writeF1000(&data[0], p.X);
139 writeF1000(&data[4], p.Y);
140 writeF1000(&data[8], p.Z);
142 inline v3f readV3F1000(u8 *data)
145 p.X = (float)readF1000(&data[0]);
146 p.Y = (float)readF1000(&data[4]);
147 p.Z = (float)readF1000(&data[8]);
151 inline void writeV2S16(u8 *data, v2s16 p)
153 writeS16(&data[0], p.X);
154 writeS16(&data[2], p.Y);
157 inline v2s16 readV2S16(u8 *data)
160 p.X = readS16(&data[0]);
161 p.Y = readS16(&data[2]);
165 inline void writeV2S32(u8 *data, v2s32 p)
167 writeS32(&data[0], p.X);
168 writeS32(&data[2], p.Y);
171 inline v2s32 readV2S32(u8 *data)
174 p.X = readS32(&data[0]);
175 p.Y = readS32(&data[2]);
179 inline void writeV3S16(u8 *data, v3s16 p)
181 writeS16(&data[0], p.X);
182 writeS16(&data[2], p.Y);
183 writeS16(&data[4], p.Z);
186 inline v3s16 readV3S16(u8 *data)
189 p.X = readS16(&data[0]);
190 p.Y = readS16(&data[2]);
191 p.Z = readS16(&data[4]);
196 The above stuff directly interfaced to iostream
199 inline void writeU8(std::ostream &os, u8 p)
202 writeU8((u8*)buf, p);
205 inline u8 readU8(std::istream &is)
209 return readU8((u8*)buf);
212 inline void writeU16(std::ostream &os, u16 p)
215 writeU16((u8*)buf, p);
218 inline u16 readU16(std::istream &is)
222 return readU16((u8*)buf);
225 inline void writeU32(std::ostream &os, u32 p)
228 writeU16((u8*)buf, p);
231 inline u32 readU32(std::istream &is)
235 return readU32((u8*)buf);
238 inline void writeF1000(std::ostream &os, f32 p)
241 writeF1000((u8*)buf, p);
244 inline f32 readF1000(std::istream &is)
248 return readF1000((u8*)buf);
251 inline void writeV3F1000(std::ostream &os, v3f p)
254 writeV3F1000((u8*)buf, p);
257 inline v3f readV3F1000(std::istream &is)
261 return readV3F1000((u8*)buf);
265 None of these are used at the moment
268 template <typename T>
278 SharedPtr(SharedPtr<T> &t)
282 refcount = t.refcount;
290 SharedPtr<T> & operator=(T *t)
298 SharedPtr<T> & operator=(SharedPtr<T> &t)
301 refcount = t.refcount;
314 bool operator!=(T *t)
318 bool operator==(T *t)
322 T & operator[](unsigned int i)
329 assert((*refcount) > 0);
342 template <typename T>
351 Buffer(unsigned int size)
359 Buffer(const Buffer &buffer)
361 m_size = buffer.m_size;
364 data = new T[buffer.m_size];
365 memcpy(data, buffer.data, buffer.m_size);
370 Buffer(T *t, unsigned int size)
376 memcpy(data, t, size);
385 Buffer& operator=(const Buffer &buffer)
390 m_size = buffer.m_size;
393 data = new T[buffer.m_size];
394 memcpy(data, buffer.data, buffer.m_size);
400 T & operator[](unsigned int i) const
404 T * operator*() const
408 unsigned int getSize() const
422 template <typename T>
430 refcount = new unsigned int;
433 SharedBuffer(unsigned int size)
437 data = new T[m_size];
440 refcount = new unsigned int;
443 SharedBuffer(const SharedBuffer &buffer)
445 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
446 m_size = buffer.m_size;
448 refcount = buffer.refcount;
451 SharedBuffer & operator=(const SharedBuffer & buffer)
453 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
457 m_size = buffer.m_size;
459 refcount = buffer.refcount;
466 SharedBuffer(T *t, unsigned int size)
471 data = new T[m_size];
472 memcpy(data, t, m_size);
476 refcount = new unsigned int;
482 SharedBuffer(const Buffer<T> &buffer)
484 m_size = buffer.getSize();
487 data = new T[m_size];
488 memcpy(data, *buffer, buffer.getSize());
492 refcount = new unsigned int;
499 T & operator[](unsigned int i) const
504 T * operator*() const
508 unsigned int getSize() const
512 operator Buffer<T>() const
514 return Buffer<T>(data, m_size);
519 assert((*refcount) > 0);
530 unsigned int *refcount;
533 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
535 SharedBuffer<u8> b((u8*)string, strlen(string)+1);
540 class MutexedVariable
543 MutexedVariable(T value):
551 JMutexAutoLock lock(m_mutex);
557 JMutexAutoLock lock(m_mutex);
561 // You'll want to grab this in a SharedPtr
562 JMutexAutoLock * getLock()
564 return new JMutexAutoLock(m_mutex);
567 // You pretty surely want to grab the lock when accessing this
581 TimeTaker(const char *name, u32 *result=NULL);
588 u32 stop(bool quiet=false);
600 // Sets the color of all vertices in the mesh
601 void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color);
604 // Calculates the borders of a "d-radius" cube
605 inline void getFacePositions(core::list<v3s16> &list, u16 d)
609 list.push_back(v3s16(0,0,0));
615 This is an optimized sequence of coordinates.
617 list.push_back(v3s16( 0, 1, 0)); // top
618 list.push_back(v3s16( 0, 0, 1)); // back
619 list.push_back(v3s16(-1, 0, 0)); // left
620 list.push_back(v3s16( 1, 0, 0)); // right
621 list.push_back(v3s16( 0, 0,-1)); // front
622 list.push_back(v3s16( 0,-1, 0)); // bottom
624 list.push_back(v3s16(-1, 0, 1)); // back left
625 list.push_back(v3s16( 1, 0, 1)); // back right
626 list.push_back(v3s16(-1, 0,-1)); // front left
627 list.push_back(v3s16( 1, 0,-1)); // front right
628 list.push_back(v3s16(-1,-1, 0)); // bottom left
629 list.push_back(v3s16( 1,-1, 0)); // bottom right
630 list.push_back(v3s16( 0,-1, 1)); // bottom back
631 list.push_back(v3s16( 0,-1,-1)); // bottom front
632 list.push_back(v3s16(-1, 1, 0)); // top left
633 list.push_back(v3s16( 1, 1, 0)); // top right
634 list.push_back(v3s16( 0, 1, 1)); // top back
635 list.push_back(v3s16( 0, 1,-1)); // top front
637 list.push_back(v3s16(-1, 1, 1)); // top back-left
638 list.push_back(v3s16( 1, 1, 1)); // top back-right
639 list.push_back(v3s16(-1, 1,-1)); // top front-left
640 list.push_back(v3s16( 1, 1,-1)); // top front-right
641 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
642 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
643 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
644 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
649 // Take blocks in all sides, starting from y=0 and going +-y
650 for(s16 y=0; y<=d-1; y++)
652 // Left and right side, including borders
653 for(s16 z=-d; z<=d; z++)
655 list.push_back(v3s16(d,y,z));
656 list.push_back(v3s16(-d,y,z));
659 list.push_back(v3s16(d,-y,z));
660 list.push_back(v3s16(-d,-y,z));
663 // Back and front side, excluding borders
664 for(s16 x=-d+1; x<=d-1; x++)
666 list.push_back(v3s16(x,y,d));
667 list.push_back(v3s16(x,y,-d));
670 list.push_back(v3s16(x,-y,d));
671 list.push_back(v3s16(x,-y,-d));
676 // Take the bottom and top face with borders
677 // -d<x<d, y=+-d, -d<z<d
678 for(s16 x=-d; x<=d; x++)
679 for(s16 z=-d; z<=d; z++)
681 list.push_back(v3s16(x,-d,z));
682 list.push_back(v3s16(x,d,z));
686 class IndentationRaiser
689 IndentationRaiser(u16 *indentation)
691 m_indentation = indentation;
702 inline s16 getContainerPos(s16 p, s16 d)
704 return (p>=0 ? p : p-d+1) / d;
707 inline v2s16 getContainerPos(v2s16 p, s16 d)
710 getContainerPos(p.X, d),
711 getContainerPos(p.Y, d)
715 inline v3s16 getContainerPos(v3s16 p, s16 d)
718 getContainerPos(p.X, d),
719 getContainerPos(p.Y, d),
720 getContainerPos(p.Z, d)
724 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
727 getContainerPos(p.X, d.X),
728 getContainerPos(p.Y, d.Y)
732 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
735 getContainerPos(p.X, d.X),
736 getContainerPos(p.Y, d.Y),
737 getContainerPos(p.Z, d.Z)
741 inline bool isInArea(v3s16 p, s16 d)
744 p.X >= 0 && p.X < d &&
745 p.Y >= 0 && p.Y < d &&
750 inline bool isInArea(v2s16 p, s16 d)
753 p.X >= 0 && p.X < d &&
758 inline bool isInArea(v3s16 p, v3s16 d)
761 p.X >= 0 && p.X < d.X &&
762 p.Y >= 0 && p.Y < d.Y &&
763 p.Z >= 0 && p.Z < d.Z
767 inline s16 rangelim(s16 i, s16 max)
776 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
778 inline v3s16 arealim(v3s16 p, s16 d)
795 inline std::wstring narrow_to_wide(const std::string& mbs)
797 size_t wcl = mbs.size();
798 Buffer<wchar_t> wcs(wcl+1);
799 size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
800 if(l == (size_t)(-1))
801 return L"<invalid multibyte string>";
806 inline std::string wide_to_narrow(const std::wstring& wcs)
808 size_t mbl = wcs.size()*4;
809 SharedBuffer<char> mbs(mbl+1);
810 size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
811 if(l == (size_t)(-1))
818 // Split a string using the given delimiter. Returns a vector containing
819 // the component parts.
820 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
822 std::vector<std::wstring> parts;
823 std::wstringstream sstr(str);
825 while(std::getline(sstr, part, delimiter))
826 parts.push_back(part);
832 See test.cpp for example cases.
833 wraps degrees to the range of -360...360
834 NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
836 inline float wrapDegrees(float f)
838 // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
844 // NOTE: This would be used for wrapping to 0...360
850 // 10, 0.5, -0.5, -0.5
855 /* Wrap to 0...360 */
856 inline float wrapDegrees_0_360(float f)
858 // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
870 // 10, 0.5, -0.5, -0.5
875 /* Wrap to -180...180 */
876 inline float wrapDegrees_180(float f)
879 f = wrapDegrees_0_360(f);
884 inline std::string lowercase(const std::string &s)
887 for(size_t i=0; i<s.size(); i++)
890 if(c >= 'A' && c <= 'Z')
897 inline bool is_yes(const std::string &s)
899 std::string s2 = lowercase(trim(s));
900 if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
905 inline s32 stoi(const std::string &s, s32 min, s32 max)
907 s32 i = atoi(s.c_str());
916 // MSVC2010 includes it's own versions of these
917 #if !defined(_MSC_VER) || _MSC_VER < 1600
919 inline s32 stoi(std::string s)
921 return atoi(s.c_str());
924 inline s32 stoi(std::wstring s)
926 return atoi(wide_to_narrow(s).c_str());
929 inline float stof(std::string s)
932 std::istringstream ss(s);
939 inline std::string itos(s32 i)
941 std::ostringstream o;
946 inline std::string ftos(float f)
948 std::ostringstream o;
953 inline void str_replace(std::string & str, std::string const & pattern,
954 std::string const & replacement)
956 std::string::size_type start = str.find(pattern, 0);
957 while(start != str.npos)
959 str.replace(start, pattern.size(), replacement);
960 start = str.find(pattern, start+replacement.size());
964 inline void str_replace_char(std::string & str, char from, char to)
966 for(unsigned int i=0; i<str.size(); i++)
974 A base class for simple background thread implementation
977 class SimpleThread : public JThread
991 virtual ~SimpleThread()
994 virtual void * Thread() = 0;
998 JMutexAutoLock lock(run_mutex);
1001 void setRun(bool a_run)
1003 JMutexAutoLock lock(run_mutex);
1016 FIFO queue (well, actually a FILO also)
1018 template<typename T>
1024 m_list.push_back(t);
1029 if(m_list.size() == 0)
1030 throw ItemNotFoundException("Queue: queue is empty");
1032 typename core::list<T>::Iterator begin = m_list.begin();
1034 m_list.erase(begin);
1039 if(m_list.size() == 0)
1040 throw ItemNotFoundException("Queue: queue is empty");
1042 typename core::list<T>::Iterator last = m_list.getLast();
1050 return m_list.size();
1054 core::list<T> m_list;
1058 Thread-safe FIFO queue (well, actually a FILO also)
1061 template<typename T>
1071 JMutexAutoLock lock(m_mutex);
1072 return m_list.size();
1076 JMutexAutoLock lock(m_mutex);
1077 m_list.push_back(t);
1079 T pop_front(u32 wait_time_max_ms=0)
1081 u32 wait_time_ms = 0;
1086 JMutexAutoLock lock(m_mutex);
1088 if(m_list.size() > 0)
1090 typename core::list<T>::Iterator begin = m_list.begin();
1092 m_list.erase(begin);
1096 if(wait_time_ms >= wait_time_max_ms)
1097 throw ItemNotFoundException("MutexedQueue: queue is empty");
1100 // Wait a while before trying again
1105 T pop_back(u32 wait_time_max_ms=0)
1107 u32 wait_time_ms = 0;
1112 JMutexAutoLock lock(m_mutex);
1114 if(m_list.size() > 0)
1116 typename core::list<T>::Iterator last = m_list.getLast();
1122 if(wait_time_ms >= wait_time_max_ms)
1123 throw ItemNotFoundException("MutexedQueue: queue is empty");
1126 // Wait a while before trying again
1137 core::list<T> & getList()
1144 core::list<T> m_list;
1148 A single worker thread - multiple client threads queue framework.
1151 template<typename Caller, typename Data>
1159 template<typename Key, typename T, typename Caller, typename CallerData>
1165 core::list<CallerInfo<Caller, CallerData> > callers;
1168 template<typename Key, typename T, typename Caller, typename CallerData>
1169 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1173 template<typename Key, typename T, typename Caller, typename CallerData>
1181 GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1185 GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1196 ResultQueue<Key, T, Caller, CallerData> *dest;
1197 core::list<CallerInfo<Caller, CallerData> > callers;
1200 template<typename Key, typename T, typename Caller, typename CallerData>
1206 return m_queue.size();
1209 void add(Key key, Caller caller, CallerData callerdata,
1210 ResultQueue<Key, T, Caller, CallerData> *dest)
1212 JMutexAutoLock lock(m_queue.getMutex());
1215 If the caller is already on the list, only update CallerData
1217 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1218 i = m_queue.getList().begin();
1219 i != m_queue.getList().end(); i++)
1221 GetRequest<Key, T, Caller, CallerData> &request = *i;
1223 if(request.key == key)
1225 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1226 i = request.callers.begin();
1227 i != request.callers.end(); i++)
1229 CallerInfo<Caller, CallerData> &ca = *i;
1230 if(ca.caller == caller)
1232 ca.data = callerdata;
1236 CallerInfo<Caller, CallerData> ca;
1238 ca.data = callerdata;
1239 request.callers.push_back(ca);
1245 Else add a new request to the queue
1248 GetRequest<Key, T, Caller, CallerData> request;
1250 CallerInfo<Caller, CallerData> ca;
1252 ca.data = callerdata;
1253 request.callers.push_back(ca);
1254 request.dest = dest;
1256 m_queue.getList().push_back(request);
1259 GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1261 return m_queue.pop_front(wait_if_empty);
1265 MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1269 Pseudo-random (VC++ rand() sucks)
1272 void mysrand(unsigned seed);
1273 #define MYRAND_MAX 32767
1275 int myrand_range(int min, int max);
1278 Miscellaneous functions
1281 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
1282 f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
1285 Queue with unique values with fast checking of value existence
1288 template<typename Value>
1294 Does nothing if value is already queued.
1297 false: value already exists
1299 bool push_back(Value value)
1301 // Check if already exists
1302 if(m_map.find(value) != NULL)
1306 m_map.insert(value, 0);
1307 m_list.push_back(value);
1314 typename core::list<Value>::Iterator i = m_list.begin();
1316 m_map.remove(value);
1323 assert(m_list.size() == m_map.size());
1324 return m_list.size();
1328 core::map<Value, u8> m_map;
1329 core::list<Value> m_list;
1333 template<typename Key, typename Value>
1340 assert(m_mutex.IsInitialized());
1343 void set(const Key &name, const Value &value)
1345 JMutexAutoLock lock(m_mutex);
1347 m_values[name] = value;
1350 bool get(const Key &name, Value *result)
1352 JMutexAutoLock lock(m_mutex);
1354 typename core::map<Key, Value>::Node *n;
1355 n = m_values.find(name);
1361 *result = n->getValue();
1367 core::map<Key, Value> m_values;
1373 Generates ids for comparable values.
1374 Id=0 is reserved for "no value".
1377 - Returning value by id (very fast)
1378 - Returning id by value
1379 - Generating a new id for a value
1382 - Remove an id/value pair (is possible to implement but slow)
1384 template<typename T>
1385 class MutexedIdGenerator
1388 MutexedIdGenerator()
1391 assert(m_mutex.IsInitialized());
1394 // Returns true if found
1395 bool getValue(u32 id, T &value)
1399 JMutexAutoLock lock(m_mutex);
1400 if(m_id_to_value.size() < id)
1402 value = m_id_to_value[id-1];
1406 // If id exists for value, returns the id.
1407 // Otherwise generates an id for the value.
1408 u32 getId(const T &value)
1410 JMutexAutoLock lock(m_mutex);
1411 typename core::map<T, u32>::Node *n;
1412 n = m_value_to_id.find(value);
1414 return n->getValue();
1415 m_id_to_value.push_back(value);
1416 u32 new_id = m_id_to_value.size();
1417 m_value_to_id.insert(value, new_id);
1423 // Values are stored here at id-1 position (id 1 = [0])
1424 core::array<T> m_id_to_value;
1425 core::map<T, u32> m_value_to_id;
1429 Checks if a string contains only supplied characters
1431 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1433 for(u32 i=0; i<s.size(); i++)
1435 bool confirmed = false;
1436 for(u32 j=0; j<allowed_chars.size(); j++)
1438 if(s[i] == allowed_chars[j])
1444 if(confirmed == false)
1451 Forcefully wraps string into rows using \n
1452 (no word wrap, used for showing paths in gui)
1454 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1457 for(u32 i=0; i<from.size(); i++)
1459 if(i != 0 && i%rowlen == 0)
1469 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1470 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1473 Returns integer position of node in given floating point position
1475 inline v3s16 floatToInt(v3f p, f32 d)
1478 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1479 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1480 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1485 Returns floating point position of node in given integer position
1487 inline v3f intToFloat(v3s16 p, f32 d)
1498 More serialization stuff
1501 // Creates a string with the length as the first two bytes
1502 inline std::string serializeString(const std::string &plain)
1504 //assert(plain.size() <= 65535);
1505 if(plain.size() > 65535)
1506 throw SerializationError("String too long for serializeString");
1508 writeU16((u8*)&buf[0], plain.size());
1515 // Creates a string with the length as the first two bytes from wide string
1516 inline std::string serializeWideString(const std::wstring &plain)
1518 //assert(plain.size() <= 65535);
1519 if(plain.size() > 65535)
1520 throw SerializationError("String too long for serializeString");
1522 writeU16((u8*)buf, plain.size());
1525 for(u32 i=0; i<plain.size(); i++)
1527 writeU16((u8*)buf, plain[i]);
1533 // Reads a string with the length as the first two bytes
1534 inline std::string deSerializeString(std::istream &is)
1538 if(is.gcount() != 2)
1539 throw SerializationError("deSerializeString: size not read");
1540 u16 s_size = readU16((u8*)buf);
1543 Buffer<char> buf2(s_size);
1544 is.read(&buf2[0], s_size);
1547 s.append(&buf2[0], s_size);
1551 // Reads a wide string with the length as the first two bytes
1552 inline std::wstring deSerializeWideString(std::istream &is)
1556 if(is.gcount() != 2)
1557 throw SerializationError("deSerializeString: size not read");
1558 u16 s_size = readU16((u8*)buf);
1563 for(u32 i=0; i<s_size; i++)
1565 is.read(&buf[0], 2);
1566 wchar_t c16 = readU16((u8*)buf);
1572 // Creates a string with the length as the first four bytes
1573 inline std::string serializeLongString(const std::string &plain)
1576 writeU32((u8*)&buf[0], plain.size());
1583 // Reads a string with the length as the first four bytes
1584 inline std::string deSerializeLongString(std::istream &is)
1588 if(is.gcount() != 4)
1589 throw SerializationError("deSerializeLongString: size not read");
1590 u32 s_size = readU32((u8*)buf);
1593 Buffer<char> buf2(s_size);
1594 is.read(&buf2[0], s_size);
1597 s.append(&buf2[0], s_size);
1603 inline u32 time_to_daynight_ratio(u32 time_of_day)
1605 const s32 daylength = 16;
1606 const s32 nightlength = 6;
1607 const s32 daytimelength = 8;
1609 s32 t = (((time_of_day)%24000)/(24000/d));
1610 if(t < nightlength/2 || t >= d - nightlength/2)
1613 else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
1619 // Random helper. Usually d=BS
1620 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
1622 return core::aabbox3d<f32>(
1623 (float)p.X * d - 0.5*d,
1624 (float)p.Y * d - 0.5*d,
1625 (float)p.Z * d - 0.5*d,
1626 (float)p.X * d + 0.5*d,
1627 (float)p.Y * d + 0.5*d,
1628 (float)p.Z * d + 0.5*d
1632 class IntervalLimiter
1640 dtime: time from last call to this method
1641 wanted_interval: interval wanted
1643 true: action should be skipped
1644 false: action should be done
1646 bool step(float dtime, float wanted_interval)
1648 m_accumulator += dtime;
1649 if(m_accumulator < wanted_interval)
1651 m_accumulator -= wanted_interval;
1655 float m_accumulator;
1658 std::string translatePassword(std::string playername, std::wstring password);