13typedef unsigned char uchar;
14typedef unsigned short ushort;
15typedef unsigned int uint;
16typedef unsigned long ulong;
17typedef signed long long int llong;
18typedef unsigned long long int ullong;
20#if defined(__GNUC__) || defined(_MSC_VER)
21 #define RESTRICT __restrict
38inline T max(T a, T b, T c)
40 return max(max(a, b), c);
48inline T min(T a, T b, T c)
50 return min(min(a, b), c);
54 #define BITSCAN(mask) (__builtin_ffs(mask)-1)
57 #pragma intrinsic(_BitScanForward)
58 inline int BITSCAN(uint mask)
61 return _BitScanForward(&i, mask) ? i : -1;
64 inline int BITSCAN(uint mask)
68 if(!(mask&0xFFFF)) { i += 16; mask >>= 16; }
69 if(!(mask&0xFF)) { i += 8; mask >>= 8; }
70 if(!(mask&0xF)) { i += 4; mask >>= 4; }
71 if(!(mask&3)) { i += 2; mask >>= 2; }
77inline int randomint(
int x)
81inline float randomfloat(
int x)
83 return (
float((rand()*
float(x))/
float(RAND_MAX)));
86inline float detrnd(uint s,
int x)
88 return static_cast<int>(((s*1103515245+12345)>>16)%x);
91constexpr double SQRT2 = 1.4142135623731;
92constexpr double SQRT3 = 1.73205080756888;
96 constexpr double M_PI = 3.14159265358979323846;
99 constexpr double M_LN2 = 0.693147180559945309417;
103 #pragma warning (3: 4189)
104 #pragma warning (disable: 4244)
105 #pragma warning (disable: 4267)
106 #pragma warning (disable: 4355)
107 #pragma warning (disable: 4996)
110 #define strcasecmp _stricmp
111 #define strncasecmp _strnicmp
116 #define _vsnprintf vsnprintf
120#define RAD static_cast<float>(180.0f / M_PI)
124 #define PRINTFARGS(fmt, args) __attribute__((format(printf, fmt, args)))
126 #define PRINTFARGS(fmt, args)
130const int maxstrlen = 260;
132typedef char string[maxstrlen];
134inline void vformatstring(
char *d,
const char *fmt, va_list v,
int len) { _vsnprintf(d, len, fmt, v); d[len-1] = 0; }
137inline void vformatstring(
char (&d)[N],
const char *fmt, va_list v) { vformatstring(d, fmt, v, N); }
139inline char *copystring(
char *d,
const char *s,
size_t len)
141 size_t slen = min(strlen(s), len-1);
142 std::memcpy(d, s, slen);
147inline char *copystring(
char (&d)[N],
const char *s) {
return copystring(d, s, N); }
149inline char *concatstring(
char *d,
const char *s,
size_t len) {
size_t used = strlen(d);
return used < len ? copystring(d+used, s, len-used) : d; }
152inline char *concatstring(
char (&d)[N],
const char *s) {
return concatstring(d, s, N); }
154inline void nformatstring(
char *d,
int len,
const char *fmt, ...) PRINTFARGS(3, 4);
155inline
void nformatstring(
char *d,
int len, const
char *fmt, ...)
159 vformatstring(d, fmt, v, len);
164inline void formatstring(
char (&d)[N],
const char *fmt, ...) PRINTFARGS(2, 3);
167inline
void formatstring(
char (&d)[N], const
char *fmt, ...)
171 vformatstring(d, fmt, v,
static_cast<int>(N));
176inline void concformatstring(
char (&d)[N],
const char *fmt, ...) PRINTFARGS(2, 3);
179inline
void concformatstring(
char (&d)[N], const
char *fmt, ...)
184 vformatstring(d + len, fmt, v,
static_cast<int>(N) - len);
188extern char *tempformatstring(
const char *fmt, ...) PRINTFARGS(1, 2);
190#define DEF_FORMAT_STRING(d,...) string d; formatstring(d, __VA_ARGS__)
191#define DEFV_FORMAT_STRING(d,last,fmt) string d; { va_list ap; va_start(ap, last); vformatstring(d, fmt, ap); va_end(ap); }
193inline bool matchstring(std::string_view s,
size_t len, std::string_view d)
195 return len == d.size() && !std::memcmp(s.data(), d.data(), d.size());
198inline char *newstring(
size_t l)
200 return new char[l+1];
202inline char *newstring(
const char *s,
size_t l)
204 return copystring(newstring(l), s, l+1);
206inline char *newstring(
const char *s)
208 size_t l = strlen(s);
209 char *d = newstring(l);
210 std::memcpy(d, s, l+1);
214inline char *newconcatstring(
const char *s,
const char *t)
216 size_t slen = strlen(s),
218 char *r = newstring(slen + tlen);
219 std::memcpy(r, s, slen);
220 std::memcpy(&r[slen], t, tlen);
238 databuf() : buf(
nullptr), len(0), maxlen(0), flags(0) {}
241 databuf(T *buf, U maxlen) : buf(buf), len(0), maxlen((
int)maxlen), flags(0) {}
249 void reset(T *buf_,
int maxlen_)
267 static const T overreadval = 0;
291 sz = std::clamp(sz, 0, maxlen-len);
293 return databuf(&buf[len-sz], sz);
309 len += min(numvals, maxlen-len);
332 void put(
const T *vals,
int numvals)
334 if(maxlen - len < numvals)
336 numvals = maxlen - len;
339 std::memcpy(&buf[len], (
const void *)vals, numvals*
sizeof(T));
343 int get(T *vals,
int numvals)
345 if(maxlen - len < numvals)
347 numvals = maxlen - len;
350 std::memcpy(vals, (
void *)&buf[len], numvals*
sizeof(T));
379 bool empty()
const {
return len==0; }
412 bool overread()
const {
return (flags&OVERREAD)!=0; }
425 bool check(
int n) {
return remaining() >= n; }
437inline uint memhash(
const void *ptr,
int len)
439 const uchar *data = (
const uchar *)ptr;
441 for(
int i = 0; i < static_cast<int>(len); ++i)
443 h = ((h<<5)+h)^data[i];
449inline T endianswap(T n) {
union { T t; uint i; } conv; conv.t = n; conv.i = SDL_Swap32(conv.i);
return conv.t; }
452inline uint endianswap<uint>(uint n) {
return SDL_Swap32(n); }
455inline int endianswap<int>(
int n) {
return SDL_Swap32(n); }
468 #if defined(__GNUC__) && !defined(__MINGW32__)
469 typedef off64_t offset;
471 typedef __int64 offset;
474 typedef off_t offset;
478 virtual void close() = 0;
479 virtual bool end() = 0;
480 virtual offset tell() {
return -1; }
481 virtual offset rawtell() {
return tell(); }
482 virtual bool seek(offset,
int) {
return false; }
483 virtual offset size();
484 virtual offset rawsize() {
return size(); }
485 virtual size_t read(
void *,
size_t) {
return 0; }
486 virtual size_t write(
const void *,
size_t) {
return 0; }
487 virtual bool flush() {
return true; }
488 virtual int getchar() { uchar c;
return read(&c, 1) == 1 ? c : -1; }
489 virtual bool putchar(
int n) { uchar c = n;
return write(&c, 1) == 1; }
490 virtual bool getline(
char *str,
size_t len);
491 virtual bool putstring(
const char *str) {
size_t len = strlen(str);
return write(str, len) == len; }
492 virtual bool putline(
const char *str) {
return putstring(str) && putchar(
'\n'); }
493 virtual size_t printf(
const char *fmt, ...) PRINTFARGS(2, 3);
494 virtual uint getcrc() {
return 0; }
497 size_t put(
const T *v,
size_t n) {
return write(v, n*
sizeof(T))/
sizeof(T); }
500 bool put(T n) {
return write(&n,
sizeof(n)) ==
sizeof(n); }
503 size_t get(T *v,
size_t n) {
return read(v, n*
sizeof(T))/
sizeof(T); }
506 T get() { T n;
return read(&n,
sizeof(n)) ==
sizeof(n) ? n : 0; }
509 bool putbig(T n) {
return put<T>(endianswap(n)); }
514extern string homedir;
516extern char *path(
char *s);
517extern std::string path(std::string s);
518extern char *copypath(
const char *s);
519extern const char *sethomedir(
const char *dir);
520extern const char *findfile(
const char *filename,
const char *mode);
531extern stream *openrawfile(
const char *filename,
const char *mode);
532extern stream *openzipfile(
const char *filename,
const char *mode);
533extern stream *openfile(
const char *filename,
const char *mode);
534extern stream *opengzfile(
const char *filename,
const char *mode,
stream *file =
nullptr,
int level = Z_BEST_COMPRESSION);
537inline void putint_(T &p,
int n)
543 else if(n<0x8000 && n>=-0x8000)
560inline void putuint_(T &p,
int n)
562 if(n < 0 || n >= (1<<21))
564 p.put(0x80 | (n & 0x7F));
565 p.put(0x80 | ((n >> 7) & 0x7F));
566 p.put(0x80 | ((n >> 14) & 0x7F));
575 p.put(0x80 | (n & 0x7F));
580 p.put(0x80 | (n & 0x7F));
581 p.put(0x80 | ((n >> 7) & 0x7F));
586extern void putint(std::vector<uchar> &p,
int n);
589inline void vectorput(std::vector<uint8_t>& buf,
const T& data)
591 const uint8_t* data_ptr =
reinterpret_cast<const uint8_t*
>(&data);
592 buf.insert(buf.end(), data_ptr, data_ptr +
sizeof(T));
595inline void vectorput(std::vector<uint8_t>& buf,
const uint8_t* data,
size_t size)
597 buf.insert(buf.end(), data, data + size);
601inline void sendstring_(
const char *t, T &p)
611inline void putfloat_(T &p,
float f)
613 p.put((uchar *)&f,
sizeof(
float));
616extern void putint(ucharbuf &p,
int n);
617extern int getint(ucharbuf &p);
618extern void putuint(ucharbuf &p,
int n);
619extern int getuint(ucharbuf &p);
620extern void putfloat(ucharbuf &p,
float f);
621extern float getfloat(ucharbuf &p);
622extern void sendstring(
const char *t, ucharbuf &p);
623extern void getstring(
char *t, ucharbuf &p,
size_t len);
626inline void getstring(
char (&t)[N], ucharbuf &p) { getstring(t, p, N); }
628extern void filtertext(
char *dst,
const char *src,
bool whitespace,
bool forcespace,
size_t len);
631inline void filtertext(
char (&dst)[N],
const char *src,
bool whitespace =
true,
bool forcespace =
false) { filtertext(dst, src, whitespace, forcespace, N-1); }
const T & get()
Adds an existing value in the underlying buffer to the databuf.
Definition tools.h:265
int length() const
Returns the number of allocated entries in the databuf.
Definition tools.h:389
void put(const T &val)
Adds an entry to the databuf if space is available.
Definition tools.h:320
databuf subbuf(int sz)
Returns a databuf<T> object containing the first n entries.
Definition tools.h:289
bool overread() const
Returns whether the databuf has been accessed with too large of an index.
Definition tools.h:412
T * pad(int numvals)
Adds N empty elements to the end of the array and returns a pointer.
Definition tools.h:306
int remaining() const
Returns the number of values remaining before the databuf overflows.
Definition tools.h:400
bool empty() const
Returns whether any entries have been assigned to the array.
Definition tools.h:379
T * getbuf() const
Returns a pointer to the internal data array.
Definition tools.h:371
bool overwrote() const
Returns whether the databuf has had invalid writes to it.
Definition tools.h:423