X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Futility.h;h=07216a27decfb89a84762e5768c7eab70d351ba7;hb=ef0ec3155440b770103cc5ad36819659d7ce2c1b;hp=98fa83e8928e5a116d265b89666dfa3432fd5ec5;hpb=28660b4c1af1b1b6ac2d3fda6984bda2a1199dc1;p=dragonfireclient.git diff --git a/src/utility.h b/src/utility.h index 98fa83e89..07216a27d 100644 --- a/src/utility.h +++ b/src/utility.h @@ -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); @@ -225,7 +245,7 @@ inline u16 readU16(std::istream &is) inline void writeU32(std::ostream &os, u32 p) { char buf[4]; - writeU16((u8*)buf, p); + writeU32((u8*)buf, p); os.write(buf, 4); } inline u32 readU32(std::istream &is) @@ -235,6 +255,45 @@ inline u32 readU32(std::istream &is) 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 */ @@ -367,7 +465,7 @@ class Buffer else data = NULL; } - Buffer(T *t, unsigned int size) + Buffer(const T *t, unsigned int size) { m_size = size; if(size != 0) @@ -596,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 &list, u16 d) @@ -902,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) @@ -914,27 +1047,33 @@ 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(const std::string &s) { return atoi(s.c_str()); } -inline s32 stoi(std::wstring s) +inline s32 mystoi(const std::wstring &s) { return atoi(wide_to_narrow(s).c_str()); } -inline float stof(std::string s) +inline float mystof(const std::string &s) { - float f; + // This crap causes a segfault in certain cases on MinGW + /*float f; std::istringstream ss(s); ss>>f; - return f; + return f;*/ + // This works in that case + return atof(s.c_str()); } -#endif +//#endif + +#define stoi mystoi +#define stof mystof inline std::string itos(s32 i) { @@ -1469,6 +1608,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. + and 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 */ @@ -1598,23 +1746,13 @@ 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); -inline u32 time_to_daynight_ratio(u32 time_of_day) -{ - const s32 daylength = 16; - const s32 nightlength = 6; - const s32 daytimelength = 8; - s32 d = daylength; - s32 t = (((time_of_day)%24000)/(24000/d)); - if(t < nightlength/2 || t >= d - nightlength/2) - //return 300; - return 350; - else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2) - return 1000; - else - return 750; -} +// Reads a string encoded in JSON format +std::string deSerializeJsonString(std::istream &is); + +// // Random helper. Usually d=BS inline core::aabbox3d getNodeBox(v3s16 p, float d) @@ -1655,7 +1793,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