]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/utility.h
Menu tuning WIP
[dragonfireclient.git] / src / utility.h
index 255b75c08c695bf44da49a014f6a35d15b4f4469..aa64c28bb601ceb3be158917d939c461c60a89ed 100644 (file)
@@ -32,9 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "common_irrlicht.h"
 #include "debug.h"
-#include "strfnd.h"
 #include "exceptions.h"
 #include "porting.h"
+#include "strfnd.h" // For trim()
 
 extern const v3s16 g_6dirs[6];
 
@@ -104,13 +104,6 @@ inline s32 readS32(u8 *data){
        return (s32)readU32(data);
 }
 
-inline void writeF1000(u8 *data, f32 i){
-       writeS32(data, i*1000);
-}
-inline f32 readF1000(u8 *data){
-       return (f32)readS32(data)/1000.;
-}
-
 inline void writeS16(u8 *data, s16 i){
        writeU16(data, (u16)i);
 }
@@ -118,6 +111,20 @@ inline s16 readS16(u8 *data){
        return (s16)readU16(data);
 }
 
+inline void writeS8(u8 *data, s8 i){
+       writeU8(data, (u8)i);
+}
+inline s8 readS8(u8 *data){
+       return (s8)readU8(data);
+}
+
+inline void writeF1000(u8 *data, f32 i){
+       writeS32(data, i*1000);
+}
+inline f32 readF1000(u8 *data){
+       return (f32)readS32(data)/1000.;
+}
+
 inline void writeV3S32(u8 *data, v3s32 p)
 {
        writeS32(&data[0], p.X);
@@ -148,6 +155,19 @@ inline v3f readV3F1000(u8 *data)
        return p;
 }
 
+inline void writeV2F1000(u8 *data, v2f p)
+{
+       writeF1000(&data[0], p.X);
+       writeF1000(&data[4], p.Y);
+}
+inline v2f readV2F1000(u8 *data)
+{
+       v2f p;
+       p.X = (float)readF1000(&data[0]);
+       p.Y = (float)readF1000(&data[4]);
+       return p;
+}
+
 inline void writeV2S16(u8 *data, v2s16 p)
 {
        writeS16(&data[0], p.X);
@@ -222,19 +242,58 @@ inline u16 readU16(std::istream &is)
        return readU16((u8*)buf);
 }
 
-inline void writeU32(std::ostream &os, u16 p)
+inline void writeU32(std::ostream &os, u32 p)
 {
        char buf[4];
-       writeU16((u8*)buf, p);
+       writeU32((u8*)buf, p);
        os.write(buf, 4);
 }
-inline u16 readU32(std::istream &is)
+inline u32 readU32(std::istream &is)
 {
        char buf[4];
        is.read(buf, 4);
        return readU32((u8*)buf);
 }
 
+inline void writeS32(std::ostream &os, s32 p)
+{
+       char buf[4];
+       writeS32((u8*)buf, p);
+       os.write(buf, 4);
+}
+inline s32 readS32(std::istream &is)
+{
+       char buf[4];
+       is.read(buf, 4);
+       return readS32((u8*)buf);
+}
+
+inline void writeS16(std::ostream &os, s16 p)
+{
+       char buf[2];
+       writeS16((u8*)buf, p);
+       os.write(buf, 2);
+}
+inline s16 readS16(std::istream &is)
+{
+       char buf[2];
+       is.read(buf, 2);
+       return readS16((u8*)buf);
+}
+
+inline void writeS8(std::ostream &os, s8 p)
+{
+       char buf[1];
+       writeS8((u8*)buf, p);
+       os.write(buf, 1);
+}
+inline s8 readS8(std::istream &is)
+{
+       char buf[1];
+       is.read(buf, 1);
+       return readS8((u8*)buf);
+}
+
 inline void writeF1000(std::ostream &os, f32 p)
 {
        char buf[4];
@@ -261,6 +320,45 @@ inline v3f readV3F1000(std::istream &is)
        return readV3F1000((u8*)buf);
 }
 
+inline void writeV2F1000(std::ostream &os, v2f p)
+{
+       char buf[8];
+       writeV2F1000((u8*)buf, p);
+       os.write(buf, 8);
+}
+inline v2f readV2F1000(std::istream &is)
+{
+       char buf[8];
+       is.read(buf, 8);
+       return readV2F1000((u8*)buf);
+}
+
+inline void writeV2S16(std::ostream &os, v2s16 p)
+{
+       char buf[4];
+       writeV2S16((u8*)buf, p);
+       os.write(buf, 4);
+}
+inline v2s16 readV2S16(std::istream &is)
+{
+       char buf[4];
+       is.read(buf, 4);
+       return readV2S16((u8*)buf);
+}
+
+inline void writeV3S16(std::ostream &os, v3s16 p)
+{
+       char buf[6];
+       writeV3S16((u8*)buf, p);
+       os.write(buf, 6);
+}
+inline v3s16 readV3S16(std::istream &is)
+{
+       char buf[6];
+       is.read(buf, 6);
+       return readV3S16((u8*)buf);
+}
+
 /*
        None of these are used at the moment
 */
@@ -343,26 +441,59 @@ template <typename T>
 class Buffer
 {
 public:
+       Buffer()
+       {
+               m_size = 0;
+               data = NULL;
+       }
        Buffer(unsigned int size)
        {
                m_size = size;
-               data = new T[size];
+               if(size != 0)
+                       data = new T[size];
+               else
+                       data = NULL;
        }
        Buffer(const Buffer &buffer)
        {
                m_size = buffer.m_size;
-               data = new T[buffer.m_size];
-               memcpy(data, buffer.data, buffer.m_size);
+               if(m_size != 0)
+               {
+                       data = new T[buffer.m_size];
+                       memcpy(data, buffer.data, buffer.m_size);
+               }
+               else
+                       data = NULL;
        }
-       Buffer(T *t, unsigned int size)
+       Buffer(const T *t, unsigned int size)
        {
                m_size = size;
-               data = new T[size];
-               memcpy(data, t, size);
+               if(size != 0)
+               {
+                       data = new T[size];
+                       memcpy(data, t, size);
+               }
+               else
+                       data = NULL;
        }
        ~Buffer()
        {
-               delete[] data;
+               drop();
+       }
+       Buffer& operator=(const Buffer &buffer)
+       {
+               if(this == &buffer)
+                       return *this;
+               drop();
+               m_size = buffer.m_size;
+               if(m_size != 0)
+               {
+                       data = new T[buffer.m_size];
+                       memcpy(data, buffer.data, buffer.m_size);
+               }
+               else
+                       data = NULL;
+               return *this;
        }
        T & operator[](unsigned int i) const
        {
@@ -377,6 +508,11 @@ class Buffer
                return m_size;
        }
 private:
+       void drop()
+       {
+               if(data)
+                       delete[] data;
+       }
        T *data;
        unsigned int m_size;
 };
@@ -471,6 +607,10 @@ class SharedBuffer
        {
                return m_size;
        }
+       operator Buffer<T>() const
+       {
+               return Buffer<T>(data, m_size);
+       }
 private:
        void drop()
        {
@@ -554,10 +694,45 @@ class TimeTaker
        u32 *m_result;
 };
 
-#ifndef SERVER
-// Sets the color of all vertices in the mesh
-void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color);
-#endif
+// Tests if two strings are equal, optionally case insensitive
+inline bool str_equal(const std::wstring& s1, const std::wstring& s2,
+               bool case_insensitive = false)
+{
+       if(case_insensitive)
+       {
+               if(s1.size() != s2.size())
+                       return false;
+               for(size_t i = 0; i < s1.size(); ++i)
+                       if(tolower(s1[i]) != tolower(s2[i]))
+                               return false;
+               return true;
+       }
+       else
+       {
+               return s1 == s2;
+       }
+}
+
+// Tests if the second string is a prefix of the first, optionally case insensitive
+inline bool str_starts_with(const std::wstring& str, const std::wstring& prefix,
+               bool case_insensitive = false)
+{
+       if(str.size() < prefix.size())
+               return false;
+       if(case_insensitive)
+       {
+               for(size_t i = 0; i < prefix.size(); ++i)
+                       if(tolower(str[i]) != tolower(prefix[i]))
+                               return false;
+       }
+       else
+       {
+               for(size_t i = 0; i < prefix.size(); ++i)
+                       if(str[i] != prefix[i])
+                               return false;
+       }
+       return true;
+}
 
 // Calculates the borders of a "d-radius" cube
 inline void getFacePositions(core::list<v3s16> &list, u16 d)
@@ -860,7 +1035,7 @@ inline bool is_yes(const std::string &s)
        return false;
 }
 
-inline s32 stoi(const std::string &s, s32 min, s32 max)
+inline s32 mystoi(const std::string &s, s32 min, s32 max)
 {
        s32 i = atoi(s.c_str());
        if(i < min)
@@ -872,19 +1047,19 @@ inline s32 stoi(const std::string &s, s32 min, s32 max)
 
 
 // MSVC2010 includes it's own versions of these
-#if !defined(_MSC_VER) || _MSC_VER < 1600
+//#if !defined(_MSC_VER) || _MSC_VER < 1600
 
-inline s32 stoi(std::string s)
+inline s32 mystoi(std::string s)
 {
        return atoi(s.c_str());
 }
 
-inline s32 stoi(std::wstring s)
+inline s32 mystoi(std::wstring s)
 {
        return atoi(wide_to_narrow(s).c_str());
 }
 
-inline float stof(std::string s)
+inline float mystof(std::string s)
 {
        float f;
        std::istringstream ss(s);
@@ -892,7 +1067,10 @@ inline float stof(std::string s)
        return f;
 }
 
-#endif
+//#endif
+
+#define stoi mystoi
+#define stof mystof
 
 inline std::string itos(s32 i)
 {
@@ -1230,20 +1408,7 @@ int myrand(void);
 void mysrand(unsigned seed);
 #define MYRAND_MAX 32767
 
-inline int myrand_range(int min, int max)
-{
-       if(max-min > MYRAND_MAX)
-       {
-               dstream<<"WARNING: myrand_range: max-min > MYRAND_MAX"<<std::endl;
-               assert(0);
-       }
-       if(min > max)
-       {
-               assert(0);
-               return max;
-       }
-       return (myrand()%(max-min+1))+min;
-}
+int myrand_range(int min, int max);
 
 /*
        Miscellaneous functions
@@ -1440,6 +1605,15 @@ inline std::string wrap_rows(const std::string &from, u32 rowlen)
 #define MYMIN(a,b) ((a)<(b)?(a):(b))
 #define MYMAX(a,b) ((a)>(b)?(a):(b))
 
+/*
+       Returns nearest 32-bit integer for given floating point number.
+       <cmath> and <math.h> in VC++ don't provide round().
+*/
+inline s32 myround(f32 f)
+{
+       return floor(f + 0.5);
+}
+
 /*
        Returns integer position of node in given floating point position
 */
@@ -1569,6 +1743,12 @@ inline std::string deSerializeLongString(std::istream &is)
        return s;
 }
 
+// Creates a string encoded in JSON format (almost equivalent to a C string literal)
+std::string serializeJsonString(const std::string &plain);
+
+// Reads a string encoded in JSON format
+std::string deSerializeJsonString(std::istream &is);
+
 //
 
 inline u32 time_to_daynight_ratio(u32 time_of_day)
@@ -1626,7 +1806,73 @@ class IntervalLimiter
        float m_accumulator;
 };
 
+/*
+       Splits a list into "pages". For example, the list [1,2,3,4,5] split
+       into two pages would be [1,2,3],[4,5]. This function computes the
+       minimum and maximum indices of a single page.
+
+       length: Length of the list that should be split
+       page: Page number, 1 <= page <= pagecount
+       pagecount: The number of pages, >= 1
+       minindex: Receives the minimum index (inclusive).
+       maxindex: Receives the maximum index (exclusive).
+
+       Ensures 0 <= minindex <= maxindex <= length.
+*/
+inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxindex)
+{
+       if(length < 1 || pagecount < 1 || page < 1 || page > pagecount)
+       {
+               // Special cases or invalid parameters
+               minindex = maxindex = 0;
+       }
+       else if(pagecount <= length)
+       {
+               // Less pages than entries in the list:
+               // Each page contains at least one entry
+               minindex = (length * (page-1) + (pagecount-1)) / pagecount;
+               maxindex = (length * page + (pagecount-1)) / pagecount;
+       }
+       else
+       {
+               // More pages than entries in the list:
+               // Make sure the empty pages are at the end
+               if(page < length)
+               {
+                       minindex = page-1;
+                       maxindex = page;
+               }
+               else
+               {
+                       minindex = 0;
+                       maxindex = 0;
+               }
+       }
+}
+
 std::string translatePassword(std::string playername, std::wstring password);
 
+enum PointedThingType
+{
+       POINTEDTHING_NOTHING,
+       POINTEDTHING_NODE,
+       POINTEDTHING_OBJECT
+};
+
+struct PointedThing
+{
+       PointedThingType type;
+       v3s16 node_undersurface;
+       v3s16 node_abovesurface;
+       s16 object_id;
+
+       PointedThing();
+       std::string dump() const;
+       void serialize(std::ostream &os) const;
+       void deSerialize(std::istream &is);
+       bool operator==(const PointedThing &pt2) const;
+       bool operator!=(const PointedThing &pt2) const;
+};
+
 #endif