From 4e249fb3fbf75f0359758760d88e22aa5b14533c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 27 Nov 2010 01:02:21 +0200 Subject: Initial files --- src/utility.h | 607 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 src/utility.h (limited to 'src/utility.h') diff --git a/src/utility.h b/src/utility.h new file mode 100644 index 000000000..4178e9d95 --- /dev/null +++ b/src/utility.h @@ -0,0 +1,607 @@ +/* +(c) 2010 Perttu Ahola +*/ + +#ifndef UTILITY_HEADER +#define UTILITY_HEADER + +#include "common_irrlicht.h" +#include "debug.h" +#include "strfnd.h" +#include +#include + +extern const v3s16 g_26dirs[26]; + +inline void writeU32(u8 *data, u32 i) +{ + data[0] = ((i>>24)&0xff); + data[1] = ((i>>16)&0xff); + data[2] = ((i>> 8)&0xff); + data[3] = ((i>> 0)&0xff); +} + +inline void writeU16(u8 *data, u16 i) +{ + data[0] = ((i>> 8)&0xff); + data[1] = ((i>> 0)&0xff); +} + +inline void writeU8(u8 *data, u8 i) +{ + data[0] = ((i>> 0)&0xff); +} + +inline u32 readU32(u8 *data) +{ + return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0); +} + +inline u16 readU16(u8 *data) +{ + return (data[0]<<8) | (data[1]<<0); +} + +inline u8 readU8(u8 *data) +{ + return (data[0]<<0); +} + +// Signed variants of the above + +inline void writeS32(u8 *data, s32 i){ + writeU32(data, (u32)i); +} +inline s32 readS32(u8 *data){ + return (s32)readU32(data); +} + +inline void writeS16(u8 *data, s16 i){ + writeU16(data, (u16)i); +} +inline s16 readS16(u8 *data){ + return (s16)readU16(data); +} + +inline void writeV3S32(u8 *data, v3s32 p) +{ + writeS32(&data[0], p.X); + writeS32(&data[4], p.Y); + writeS32(&data[8], p.Z); +} + +inline v3s32 readV3S32(u8 *data) +{ + v3s32 p; + p.X = readS32(&data[0]); + p.Y = readS32(&data[4]); + p.Z = readS32(&data[8]); + return p; +} + +inline void writeV2S16(u8 *data, v2s16 p) +{ + writeS16(&data[0], p.X); + writeS16(&data[2], p.Y); +} + +inline v2s16 readV2S16(u8 *data) +{ + v2s16 p; + p.X = readS16(&data[0]); + p.Y = readS16(&data[2]); + return p; +} + +inline void writeV2S32(u8 *data, v2s32 p) +{ + writeS32(&data[0], p.X); + writeS32(&data[2], p.Y); +} + +inline v2s32 readV2S32(u8 *data) +{ + v2s32 p; + p.X = readS32(&data[0]); + p.Y = readS32(&data[2]); + return p; +} + +inline void writeV3S16(u8 *data, v3s16 p) +{ + writeS16(&data[0], p.X); + writeS16(&data[2], p.Y); + writeS16(&data[4], p.Z); +} + +inline v3s16 readV3S16(u8 *data) +{ + v3s16 p; + p.X = readS16(&data[0]); + p.Y = readS16(&data[2]); + p.Z = readS16(&data[4]); + return p; +} + +/* + None of these are used at the moment +*/ + +template +class SharedPtr +{ +public: + SharedPtr(T *t=NULL) + { + refcount = new int; + *refcount = 1; + ptr = t; + } + SharedPtr(SharedPtr &t) + { + //*this = t; + drop(); + refcount = t.refcount; + (*refcount)++; + ptr = t.ptr; + } + ~SharedPtr() + { + drop(); + } + SharedPtr & operator=(T *t) + { + drop(); + refcount = new int; + *refcount = 1; + ptr = t; + return *this; + } + SharedPtr & operator=(SharedPtr &t) + { + drop(); + refcount = t.refcount; + (*refcount)++; + ptr = t.ptr; + return *this; + } + T* operator->() + { + return ptr; + } + T & operator*() + { + return *ptr; + } + bool operator!=(T *t) + { + return ptr != t; + } + bool operator==(T *t) + { + return ptr == t; + } +private: + void drop() + { + assert((*refcount) > 0); + (*refcount)--; + if(*refcount == 0) + { + delete refcount; + if(ptr != NULL) + delete ptr; + } + } + T *ptr; + int *refcount; +}; + +template +class Buffer +{ +public: + Buffer(unsigned int size) + { + m_size = size; + data = new T[size]; + } + Buffer(const Buffer &buffer) + { + m_size = buffer.m_size; + data = new T[buffer.m_size]; + memcpy(data, buffer.data, buffer.m_size); + } + Buffer(T *t, unsigned int size) + { + m_size = size; + data = new T[size]; + memcpy(data, t, size); + } + ~Buffer() + { + delete[] data; + } + T & operator[](unsigned int i) const + { + return data[i]; + } + T * operator*() const + { + return data; + } + unsigned int getSize() const + { + return m_size; + } +private: + T *data; + unsigned int m_size; +}; + +template +class SharedBuffer +{ +public: + SharedBuffer(unsigned int size) + { + m_size = size; + data = new T[size]; + refcount = new unsigned int; + (*refcount) = 1; + } + SharedBuffer(const SharedBuffer &buffer) + { + //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"< &buffer) + { + m_size = buffer.m_size; + data = new T[buffer.getSize()]; + memcpy(data, *buffer, buffer.getSize()); + refcount = new unsigned int; + (*refcount) = 1; + } + ~SharedBuffer() + { + drop(); + } + T & operator[](unsigned int i) const + { + return data[i]; + } + T * operator*() const + { + return data; + } + unsigned int getSize() const + { + return m_size; + } +private: + void drop() + { + assert((*refcount) > 0); + (*refcount)--; + if(*refcount == 0) + { + delete[] data; + delete refcount; + } + } + T *data; + unsigned int m_size; + unsigned int *refcount; +}; + +inline SharedBuffer SharedBufferFromString(const char *string) +{ + SharedBuffer b((u8*)string, strlen(string)+1); + return b; +} + +template +class MutexedVariable +{ +public: + MutexedVariable(T value): + m_value(value) + { + m_mutex.Init(); + } + + T get() + { + JMutexAutoLock lock(m_mutex); + return m_value; + } + + void set(T value) + { + JMutexAutoLock lock(m_mutex); + m_value = value; + } + + // You'll want to grab this in a SharedPtr + JMutexAutoLock * getLock() + { + return new JMutexAutoLock(m_mutex); + } + + // You pretty surely want to grab the lock when accessing this + T m_value; + +private: + JMutex m_mutex; +}; + +/* + TimeTaker +*/ + +class TimeTaker +{ +public: + TimeTaker(const char *name, IrrlichtDevice *dev) + { + m_name = name; + m_dev = dev; + m_time1 = m_dev->getTimer()->getRealTime(); + m_running = true; + } + ~TimeTaker() + { + stop(); + } + u32 stop(bool quiet=false) + { + if(m_running) + { + u32 time2 = m_dev->getTimer()->getRealTime(); + u32 dtime = time2 - m_time1; + if(quiet == false) + std::cout< &list, u16 d) +{ + if(d == 0) + { + list.push_back(v3s16(0,0,0)); + return; + } + if(d == 1) + { + /* + This is an optimized sequence of coordinates. + */ + list.push_back(v3s16( 0, 0, 1)); // back + list.push_back(v3s16(-1, 0, 0)); // left + list.push_back(v3s16( 1, 0, 0)); // right + list.push_back(v3s16( 0, 0,-1)); // front + list.push_back(v3s16( 0,-1, 0)); // bottom + list.push_back(v3s16( 0, 1, 0)); // top + // 6 + list.push_back(v3s16(-1, 0, 1)); // back left + list.push_back(v3s16( 1, 0, 1)); // back right + list.push_back(v3s16(-1, 0,-1)); // front left + list.push_back(v3s16( 1, 0,-1)); // front right + list.push_back(v3s16(-1,-1, 0)); // bottom left + list.push_back(v3s16( 1,-1, 0)); // bottom right + list.push_back(v3s16( 0,-1, 1)); // bottom back + list.push_back(v3s16( 0,-1,-1)); // bottom front + list.push_back(v3s16(-1, 1, 0)); // top left + list.push_back(v3s16( 1, 1, 0)); // top right + list.push_back(v3s16( 0, 1, 1)); // top back + list.push_back(v3s16( 0, 1,-1)); // top front + // 18 + list.push_back(v3s16(-1, 1, 1)); // top back-left + list.push_back(v3s16( 1, 1, 1)); // top back-right + list.push_back(v3s16(-1, 1,-1)); // top front-left + list.push_back(v3s16( 1, 1,-1)); // top front-right + list.push_back(v3s16(-1,-1, 1)); // bottom back-left + list.push_back(v3s16( 1,-1, 1)); // bottom back-right + list.push_back(v3s16(-1,-1,-1)); // bottom front-left + list.push_back(v3s16( 1,-1,-1)); // bottom front-right + // 26 + return; + } + + // Take blocks in all sides, starting from y=0 and going +-y + for(s16 y=0; y<=d-1; y++) + { + // Left and right side, including borders + for(s16 z=-d; z<=d; z++) + { + list.push_back(v3s16(d,y,z)); + list.push_back(v3s16(-d,y,z)); + if(y != 0) + { + list.push_back(v3s16(d,-y,z)); + list.push_back(v3s16(-d,-y,z)); + } + } + // Back and front side, excluding borders + for(s16 x=-d+1; x<=d-1; x++) + { + list.push_back(v3s16(x,y,d)); + list.push_back(v3s16(x,y,-d)); + if(y != 0) + { + list.push_back(v3s16(x,-y,d)); + list.push_back(v3s16(x,-y,-d)); + } + } + } + + // Take the bottom and top face with borders + // -d=0 ? p : p-d+1) / d; +} + +inline v2s16 getContainerPos(v2s16 p, s16 d) +{ + return v2s16( + getContainerPos(p.X, d), + getContainerPos(p.Y, d) + ); +} + +inline v3s16 getContainerPos(v3s16 p, s16 d) +{ + return v3s16( + getContainerPos(p.X, d), + getContainerPos(p.Y, d), + getContainerPos(p.Z, d) + ); +} + +inline bool isInArea(v3s16 p, s16 d) +{ + return ( + p.X >= 0 && p.X < d && + p.Y >= 0 && p.Y < d && + p.Z >= 0 && p.Z < d + ); +} + +inline bool isInArea(v2s16 p, s16 d) +{ + return ( + p.X >= 0 && p.X < d && + p.Y >= 0 && p.Y < d + ); +} + +inline std::wstring narrow_to_wide(const std::string& mbs) +{ + size_t wcl = mbs.size(); + SharedBuffer wcs(wcl+1); + size_t l = mbstowcs(*wcs, mbs.c_str(), wcl); + wcs[l] = 0; + return *wcs; +} + +inline std::string wide_to_narrow(const std::wstring& wcs) +{ + size_t mbl = wcs.size()*4; + SharedBuffer mbs(mbl+1); + size_t l = wcstombs(*mbs, wcs.c_str(), mbl); + if((int)l == -1) + mbs[0] = 0; + else + mbs[l] = 0; + return *mbs; +} + +/* + See test.cpp for example cases. + wraps degrees to the range of -360...360 + NOTE: Wrapping to 0...360 is not used because pitch needs negative values. +*/ +inline float wrapDegrees(float f) +{ + // Take examples of f=10, f=720.5, f=-0.5, f=-360.5 + // This results in + // 10, 720, -1, -361 + int i = floor(f); + // 0, 2, 0, -1 + int l = i / 360; + // NOTE: This would be used for wrapping to 0...360 + // 0, 2, -1, -2 + /*if(i < 0) + l -= 1;*/ + // 0, 720, 0, -360 + int k = l * 360; + // 10, 0.5, -0.5, -0.5 + f -= float(k); + return f; +} + +inline std::string lowercase(std::string s) +{ + for(size_t i=0; i= 'A' && s[i] <= 'Z') + s[i] -= 'A' - 'a'; + } + return s; +} + +inline bool is_yes(std::string s) +{ + s = lowercase(trim(s)); + if(s == "y" || s == "yes" || s == "true") + return true; + return false; +} + +#endif + -- cgit v1.2.3