2 (c) 2010 Perttu Ahola <celeron55@gmail.com>
8 #include "common_irrlicht.h"
14 extern const v3s16 g_26dirs[26];
16 inline void writeU32(u8 *data, u32 i)
18 data[0] = ((i>>24)&0xff);
19 data[1] = ((i>>16)&0xff);
20 data[2] = ((i>> 8)&0xff);
21 data[3] = ((i>> 0)&0xff);
24 inline void writeU16(u8 *data, u16 i)
26 data[0] = ((i>> 8)&0xff);
27 data[1] = ((i>> 0)&0xff);
30 inline void writeU8(u8 *data, u8 i)
32 data[0] = ((i>> 0)&0xff);
35 inline u32 readU32(u8 *data)
37 return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
40 inline u16 readU16(u8 *data)
42 return (data[0]<<8) | (data[1]<<0);
45 inline u8 readU8(u8 *data)
50 // Signed variants of the above
52 inline void writeS32(u8 *data, s32 i){
53 writeU32(data, (u32)i);
55 inline s32 readS32(u8 *data){
56 return (s32)readU32(data);
59 inline void writeS16(u8 *data, s16 i){
60 writeU16(data, (u16)i);
62 inline s16 readS16(u8 *data){
63 return (s16)readU16(data);
66 inline void writeV3S32(u8 *data, v3s32 p)
68 writeS32(&data[0], p.X);
69 writeS32(&data[4], p.Y);
70 writeS32(&data[8], p.Z);
73 inline v3s32 readV3S32(u8 *data)
76 p.X = readS32(&data[0]);
77 p.Y = readS32(&data[4]);
78 p.Z = readS32(&data[8]);
82 inline void writeV2S16(u8 *data, v2s16 p)
84 writeS16(&data[0], p.X);
85 writeS16(&data[2], p.Y);
88 inline v2s16 readV2S16(u8 *data)
91 p.X = readS16(&data[0]);
92 p.Y = readS16(&data[2]);
96 inline void writeV2S32(u8 *data, v2s32 p)
98 writeS32(&data[0], p.X);
99 writeS32(&data[2], p.Y);
102 inline v2s32 readV2S32(u8 *data)
105 p.X = readS32(&data[0]);
106 p.Y = readS32(&data[2]);
110 inline void writeV3S16(u8 *data, v3s16 p)
112 writeS16(&data[0], p.X);
113 writeS16(&data[2], p.Y);
114 writeS16(&data[4], p.Z);
117 inline v3s16 readV3S16(u8 *data)
120 p.X = readS16(&data[0]);
121 p.Y = readS16(&data[2]);
122 p.Z = readS16(&data[4]);
127 None of these are used at the moment
130 template <typename T>
140 SharedPtr(SharedPtr<T> &t)
144 refcount = t.refcount;
152 SharedPtr<T> & operator=(T *t)
160 SharedPtr<T> & operator=(SharedPtr<T> &t)
163 refcount = t.refcount;
176 bool operator!=(T *t)
180 bool operator==(T *t)
187 assert((*refcount) > 0);
200 template <typename T>
204 Buffer(unsigned int size)
209 Buffer(const Buffer &buffer)
211 m_size = buffer.m_size;
212 data = new T[buffer.m_size];
213 memcpy(data, buffer.data, buffer.m_size);
215 Buffer(T *t, unsigned int size)
219 memcpy(data, t, size);
225 T & operator[](unsigned int i) const
229 T * operator*() const
233 unsigned int getSize() const
242 template <typename T>
246 SharedBuffer(unsigned int size)
250 refcount = new unsigned int;
253 SharedBuffer(const SharedBuffer &buffer)
255 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
256 m_size = buffer.m_size;
258 refcount = buffer.refcount;
261 SharedBuffer & operator=(const SharedBuffer & buffer)
263 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
267 m_size = buffer.m_size;
269 refcount = buffer.refcount;
276 SharedBuffer(T *t, unsigned int size)
280 memcpy(data, t, size);
281 refcount = new unsigned int;
287 SharedBuffer(const Buffer<T> &buffer)
289 m_size = buffer.m_size;
290 data = new T[buffer.getSize()];
291 memcpy(data, *buffer, buffer.getSize());
292 refcount = new unsigned int;
299 T & operator[](unsigned int i) const
303 T * operator*() const
307 unsigned int getSize() const
314 assert((*refcount) > 0);
324 unsigned int *refcount;
327 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
329 SharedBuffer<u8> b((u8*)string, strlen(string)+1);
334 class MutexedVariable
337 MutexedVariable(T value):
345 JMutexAutoLock lock(m_mutex);
351 JMutexAutoLock lock(m_mutex);
355 // You'll want to grab this in a SharedPtr
356 JMutexAutoLock * getLock()
358 return new JMutexAutoLock(m_mutex);
361 // You pretty surely want to grab the lock when accessing this
375 TimeTaker(const char *name, IrrlichtDevice *dev)
379 m_time1 = m_dev->getTimer()->getRealTime();
386 u32 stop(bool quiet=false)
390 u32 time2 = m_dev->getTimer()->getRealTime();
391 u32 dtime = time2 - m_time1;
393 std::cout<<m_name<<" took "<<dtime<<"ms"<<std::endl;
401 IrrlichtDevice *m_dev;
406 // Calculates the borders of a "d-radius" cube
407 inline void getFacePositions(core::list<v3s16> &list, u16 d)
411 list.push_back(v3s16(0,0,0));
417 This is an optimized sequence of coordinates.
419 list.push_back(v3s16( 0, 0, 1)); // back
420 list.push_back(v3s16(-1, 0, 0)); // left
421 list.push_back(v3s16( 1, 0, 0)); // right
422 list.push_back(v3s16( 0, 0,-1)); // front
423 list.push_back(v3s16( 0,-1, 0)); // bottom
424 list.push_back(v3s16( 0, 1, 0)); // top
426 list.push_back(v3s16(-1, 0, 1)); // back left
427 list.push_back(v3s16( 1, 0, 1)); // back right
428 list.push_back(v3s16(-1, 0,-1)); // front left
429 list.push_back(v3s16( 1, 0,-1)); // front right
430 list.push_back(v3s16(-1,-1, 0)); // bottom left
431 list.push_back(v3s16( 1,-1, 0)); // bottom right
432 list.push_back(v3s16( 0,-1, 1)); // bottom back
433 list.push_back(v3s16( 0,-1,-1)); // bottom front
434 list.push_back(v3s16(-1, 1, 0)); // top left
435 list.push_back(v3s16( 1, 1, 0)); // top right
436 list.push_back(v3s16( 0, 1, 1)); // top back
437 list.push_back(v3s16( 0, 1,-1)); // top front
439 list.push_back(v3s16(-1, 1, 1)); // top back-left
440 list.push_back(v3s16( 1, 1, 1)); // top back-right
441 list.push_back(v3s16(-1, 1,-1)); // top front-left
442 list.push_back(v3s16( 1, 1,-1)); // top front-right
443 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
444 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
445 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
446 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
451 // Take blocks in all sides, starting from y=0 and going +-y
452 for(s16 y=0; y<=d-1; y++)
454 // Left and right side, including borders
455 for(s16 z=-d; z<=d; z++)
457 list.push_back(v3s16(d,y,z));
458 list.push_back(v3s16(-d,y,z));
461 list.push_back(v3s16(d,-y,z));
462 list.push_back(v3s16(-d,-y,z));
465 // Back and front side, excluding borders
466 for(s16 x=-d+1; x<=d-1; x++)
468 list.push_back(v3s16(x,y,d));
469 list.push_back(v3s16(x,y,-d));
472 list.push_back(v3s16(x,-y,d));
473 list.push_back(v3s16(x,-y,-d));
478 // Take the bottom and top face with borders
479 // -d<x<d, y=+-d, -d<z<d
480 for(s16 x=-d; x<=d; x++)
481 for(s16 z=-d; z<=d; z++)
483 list.push_back(v3s16(x,-d,z));
484 list.push_back(v3s16(x,d,z));
488 class IndentationRaiser
491 IndentationRaiser(u16 *indentation)
493 m_indentation = indentation;
504 inline s16 getContainerPos(s16 p, s16 d)
506 return (p>=0 ? p : p-d+1) / d;
509 inline v2s16 getContainerPos(v2s16 p, s16 d)
512 getContainerPos(p.X, d),
513 getContainerPos(p.Y, d)
517 inline v3s16 getContainerPos(v3s16 p, s16 d)
520 getContainerPos(p.X, d),
521 getContainerPos(p.Y, d),
522 getContainerPos(p.Z, d)
526 inline bool isInArea(v3s16 p, s16 d)
529 p.X >= 0 && p.X < d &&
530 p.Y >= 0 && p.Y < d &&
535 inline bool isInArea(v2s16 p, s16 d)
538 p.X >= 0 && p.X < d &&
543 inline std::wstring narrow_to_wide(const std::string& mbs)
545 size_t wcl = mbs.size();
546 SharedBuffer<wchar_t> wcs(wcl+1);
547 size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
552 inline std::string wide_to_narrow(const std::wstring& wcs)
554 size_t mbl = wcs.size()*4;
555 SharedBuffer<char> mbs(mbl+1);
556 size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
565 See test.cpp for example cases.
566 wraps degrees to the range of -360...360
567 NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
569 inline float wrapDegrees(float f)
571 // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
577 // NOTE: This would be used for wrapping to 0...360
583 // 10, 0.5, -0.5, -0.5
588 inline std::string lowercase(std::string s)
590 for(size_t i=0; i<s.size(); i++)
592 if(s[i] >= 'A' && s[i] <= 'Z')
598 inline bool is_yes(std::string s)
600 s = lowercase(trim(s));
601 if(s == "y" || s == "yes" || s == "true")