1 #ifndef H_UTILS
2 #define H_UTILS
3 
4 #include <stdlib.h>
5 #include <math.h>
6 #include <float.h>
7 
8 //#define TEST_SLOW_FIO
9 
10 #ifdef _DEBUG
11     #if defined(_OS_LINUX) || defined(_OS_RPI) || defined(_OS_CLOVER)
12         #define debugBreak() raise(SIGTRAP);
13     #elif defined(_OS_3DS)
14         #define debugBreak() svcBreak(USERBREAK_ASSERT);
15     #else
16         #define debugBreak() _asm { int 3 }
17     #endif
18 
19     #define ASSERT(expr) if (expr) {} else { LOG("ASSERT:\n  %s:%d\n  %s => %s\n", __FILE__, __LINE__, __FUNCTION__, #expr); debugBreak(); }
20     #define ASSERTV(expr) ASSERT(expr)
21 
22     #ifndef _OS_ANDROID
23         #define LOG printf
24     #endif
25 
26     #if defined(_OS_XBOX) || defined(_OS_XB1)
27         #define MAX_LOG_LENGTH 1024
28 
29         #undef LOG
LOG(const char * format,...)30         void LOG(const char *format, ...) {
31             char str[MAX_LOG_LENGTH];
32             va_list arglist;
33             va_start(arglist, format);
34             _vsnprintf(str, MAX_LOG_LENGTH, format, arglist);
35             va_end(arglist);
36             OutputDebugStringA(str);
37         }
38     #endif
39 
40 #else
41 
42     #define ASSERT(expr)
43     #define ASSERTV(expr) (expr) ? 1 : 0
44 
45     #ifdef PROFILE
46         #ifdef _OS_LINUX
47             #define LOG(...) printf(__VA_ARGS__); fflush(stdout)
48         #else
49             #define LOG(...) printf(__VA_ARGS__)
50         #endif
51     #else
52         #define LOG printf
53     #endif
54 #endif
55 
56 #ifdef _OS_PSV
57     #undef LOG
58     #define LOG(...) psvDebugScreenPrintf(__VA_ARGS__)
59 #endif
60 
61 #ifdef _OS_ANDROID
62     #include <android/log.h>
63     #undef LOG
64     #define LOG(...) __android_log_print(ANDROID_LOG_INFO,"OpenLara",__VA_ARGS__)
65 #endif
66 
67 
68 #ifdef _OS_PSP
69     extern "C" {
70     // pspmath.h
71         extern float vfpu_sinf(float x);
72         extern float vfpu_cosf(float x);
73         extern float vfpu_atan2f(float x, float y);
74         extern void  vfpu_sincos(float r, float *s, float *c);
75     }
76 
77     #define sinf(x)         vfpu_sinf(x)
78     #define cosf(x)         vfpu_cosf(x)
79     #define atan2f(x, y)    vfpu_atan2f(x, y)
80     #define sincos(a, s, c) vfpu_sincos(a, s, c)
81 #else
sincos(float r,float * s,float * c)82     void sincos(float r, float *s, float *c) {
83         *s = sinf(r);
84         *c = cosf(r);
85     }
86 #endif
87 
88 #define DECL_ENUM(v) v,
89 #define DECL_STR(v)  #v,
90 
91 #define EPS     FLT_EPSILON
92 #define INF     FLT_MAX
93 #define PI      3.14159265358979323846f
94 #define PIH     (PI * 0.5f)
95 #define PI2     (PI * 2.0f)
96 #define DEG2RAD (PI / 180.0f)
97 #define RAD2DEG (180.0f / PI)
98 
99 #define COS30   0.86602540378f
100 #define COS45   0.70710678118f
101 #define COS60   0.50000000000f
102 
103 #define SQR(x)  ((x)*(x))
104 #define randf() (float(rand())/float(RAND_MAX))
105 
106 typedef signed char        int8;
107 typedef signed short       int16;
108 typedef signed int         int32;
109 typedef signed long long   int64;
110 typedef unsigned char      uint8;
111 typedef unsigned short     uint16;
112 typedef unsigned int       uint32;
113 typedef unsigned long long uint64;
114 
115 #define FOURCC(str)        uint32( ((uint8*)(str))[0] | (((uint8*)(str))[1] << 8) | (((uint8*)(str))[2] << 16) | (((uint8*)(str))[3] << 24) )
116 #define TWOCC(str)         uint32( ((uint8*)(str))[0] | (((uint8*)(str))[1] << 8) )
117 
118 #define ALIGNADDR(x, a)    (((x) + ((a) - 1)) & ~((a) - 1))
119 #define COUNT(arr)         int(sizeof(arr) / sizeof(arr[0]))
120 #define OFFSETOF(T, E)     ((size_t)&(((T*)0)->E))
121 #define TEST_BIT(arr, bit) ((arr[bit / 32] >> (bit % 32)) & 1)
122 
123 template <typename T>
min(const T & a,const T & b)124 inline const T& min(const T &a, const T &b) {
125     return a < b ? a : b;
126 }
127 
128 template <typename T>
min(const T & a,const T & b,const T & c)129 inline const T& min(const T &a, const T &b, const T &c) {
130     return (a < b && a < c) ? a : ((b < a && b < c) ? b : c);
131 }
132 
133 template <class T>
max(const T & a,const T & b)134 inline const T& max(const T &a, const T &b) {
135     return a > b ? a : b;
136 }
137 
138 template <typename T>
max(const T & a,const T & b,const T & c)139 inline const T& max(const T &a, const T &b, const T &c) {
140     return (a > b && a > c) ? a : ((b > a && b > c) ? b : c);
141 }
142 
143 template <class T>
clamp(const T & x,const T & a,const T & b)144 inline const T& clamp(const T &x, const T &a, const T &b) {
145     return x < a ? a : (x > b ? b : x);
146 }
147 
148 template <class T>
sign(const T & x)149 inline const T sign(const T &x) {
150     return (T)(x > 0 ? 1 : (x < 0 ? -1 : 0));
151 }
152 
153 template <class T>
swap(T & a,T & b)154 inline void swap(T &a, T &b) {
155     T tmp = a;
156     a = b;
157     b = tmp;
158 }
159 
swap16(uint16 x)160 inline uint16 swap16(uint16 x) {
161     return ((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8);
162 }
163 
swap32(uint32 x)164 inline uint32 swap32(uint32 x) {
165     return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24);
166 }
167 
clampAngle(float a)168 float clampAngle(float a) {
169     return a < -PI ? a + PI2 : (a >= PI ? a - PI2 : a);
170 }
171 
shortAngle(float a,float b)172 float shortAngle(float a, float b) {
173     float n = clampAngle(b) - clampAngle(a);
174     return clampAngle(n - int(n / PI2) * PI2);
175 }
176 
normalizeAngle(float angle)177 float normalizeAngle(float angle) {
178     while (angle < 0.0f) angle += PI2;
179     while (angle > PI2)  angle -= PI2;
180     return angle;
181 }
182 
angleQuadrant(float angle,float offset)183 int angleQuadrant(float angle, float offset) {
184     return int(normalizeAngle(angle + PI * offset) / (PI * 0.5f));
185 }
186 
decrease(float delta,float & value,float & speed)187 float decrease(float delta, float &value, float &speed) {
188     if (speed > 0.0f && fabsf(delta) > 0.001f) {
189         if (delta > 0) speed = min(delta,  speed);
190         if (delta < 0) speed = max(delta, -speed);
191         value += speed;
192         return speed;
193     } else
194         return 0.0f;
195 }
196 
hermite(float x)197 inline float hermite(float x) {
198     return x * x * (3 - 2 * x);
199 }
200 
quintic(float x)201 inline float quintic(float x) {
202     return x * x * x * (x * (x * 6 - 15) + 10);
203 }
204 
lerp(float a,float b,float t)205 inline float lerp(float a, float b, float t) {
206     if (t <= 0.0f) return a;
207     if (t >= 1.0f) return b;
208     return a + (b - a) * t;
209 }
210 
lerpAngle(float a,float b,float t)211 float lerpAngle(float a, float b, float t) {
212     if (t <= 0.0f) return a;
213     if (t >= 1.0f) return b;
214     return a + shortAngle(a, b) * t;
215 }
216 
nextPow2(uint32 x)217 int nextPow2(uint32 x) {
218     x--;
219     x |= x >> 1;
220     x |= x >> 2;
221     x |= x >> 4;
222     x |= x >> 8;
223     x |= x >> 16;
224     x++;
225     return x;
226 }
227 
log2i(uint32 value)228 inline uint32 log2i(uint32 value) {
229     int res = 0;
230     for(; value; value >>= 1, res++);
231     return res ? res - 1 : res;
232 }
233 
234 uint32 fnv32(const char *data, int32 size, uint32 hash = 0x811c9dc5) {
235     for (int i = 0; i < size; i++)
236         hash = (hash ^ data[i]) * 0x01000193;
237     return hash;
238 }
239 
240 template <class T>
qsort(T * v,int L,int R)241 void qsort(T* v, int L, int R) {
242     int i = L;
243     int j = R;
244     const T m = v[(L + R) / 2];
245 
246     while (i <= j) {
247         while (T::cmp(v[i], m) < 0) i++;
248         while (T::cmp(m, v[j]) < 0) j--;
249 
250         if (i <= j)
251             swap(v[i++], v[j--]);
252     }
253 
254     if (L < j) qsort(v, L, j);
255     if (i < R) qsort(v, i, R);
256 }
257 
258 template <class T>
sort(T * items,int count)259 void sort(T *items, int count) {
260     if (count)
261         qsort(items, 0, count - 1);
262 }
263 
264 
265 namespace Noise { // based on https://github.com/Auburns/FastNoise
266     int seed;
267 
268     uint8 m_perm[512];
269     uint8 m_perm12[512];
270 
271     const float GRAD_X[] = { 1, -1, 1, -1, 1, -1, 1, -1, 0, 0, 0, 0 };
272     const float GRAD_Y[] = { 1, 1, -1, -1, 0, 0, 0, 0, 1, -1, 1, -1 };
273     const float GRAD_Z[] = { 0, 0, 0, 0, 1, 1, -1, -1, 1, 1, -1, -1 };
274 
index(int x,int y,int z)275     uint8 index(int x, int y, int z) {
276         return m_perm12[(x & 0xff) + m_perm[(y & 0xff) + m_perm[(z & 0xff)]]];
277     }
278 
noise(int x,int y,int z,float xd,float yd,float zd)279     float noise(int x, int y, int z, float xd, float yd, float zd) {
280         uint8 lutPos = index(x, y, z);
281         return xd * GRAD_X[lutPos] + yd * GRAD_Y[lutPos] + zd * GRAD_Z[lutPos];
282     }
283 
setSeed(int seed)284     void setSeed(int seed) {
285         Noise::seed = seed;
286         srand(seed);
287 
288         for (int i = 0; i < 256; i++)
289             m_perm[i] = i;
290 
291         for (int j = 0; j < 256; j++) {
292             int k       = (rand() % (256 - j)) + j;
293             int p       = m_perm[j];
294             m_perm[j]   = m_perm[j + 256] = m_perm[k];
295             m_perm[k]   = p;
296             m_perm12[j] = m_perm12[j + 256] = m_perm[j] % 12;
297         }
298     }
299 
value(float x,float y,float z,int size)300     float value(float x, float y, float z, int size) {
301         x *= size;
302         y *= size;
303         z *= size;
304 
305         int x0 = (int)x;
306         int y0 = (int)y;
307         int z0 = (int)z;
308         int x1 = (x0 + 1) % size;
309         int y1 = (y0 + 1) % size;
310         int z1 = (z0 + 1) % size;
311 
312         float dx0 = x - x0;
313         float dy0 = y - y0;
314         float dz0 = z - z0;
315         float dx1 = dx0 - 1;
316         float dy1 = dy0 - 1;
317         float dz1 = dz0 - 1;
318 
319         float fx = quintic(dx0);
320         float fy = quintic(dy0);
321         float fz = quintic(dz0);
322 
323         return lerp(lerp(lerp(noise(x0, y0, z0, dx0, dy0, dz0), noise(x1, y0, z0, dx1, dy0, dz0), fx),
324                          lerp(noise(x0, y1, z0, dx0, dy1, dz0), noise(x1, y1, z0, dx1, dy1, dz0), fx), fy),
325                     lerp(lerp(noise(x0, y0, z1, dx0, dy0, dz1), noise(x1, y0, z1, dx1, dy0, dz1), fx),
326                          lerp(noise(x0, y1, z1, dx0, dy1, dz1), noise(x1, y1, z1, dx1, dy1, dz1), fx), fy), fz);
327     }
328 
generate(uint32 seed,int size,int octaves,int frequency,float amplitude)329     uint8* generate(uint32 seed, int size, int octaves, int frequency, float amplitude) {
330         setSeed(seed);
331 
332         float *out = new float[size * size * size];
333         memset(out, 0, size * size * size * sizeof(float));
334 
335         float isize = 1.0f / size;
336 
337         for (int j = 0; j < octaves; j++) {
338             float *ptr = out;
339 
340             for (int z = 0; z < size; z++) {
341                 float iz = z * isize;
342                 for (int y = 0; y < size; y++) {
343                     float iy = y * isize;
344                     for (int x = 0; x < size; x++) {
345                         float ix = x * isize;
346                         *ptr++ += value(ix, iy, iz, frequency) * amplitude;
347                     }
348                 }
349             }
350 
351             frequency *= 2;
352             amplitude *= 0.5f;
353         }
354 
355         uint8 *dst = new uint8[size * size * size];
356         for (int i = 0; i < size * size * size; i++) {
357             dst[i] = clamp(int((out[i] * 0.5f + 0.5f) * 255.0f), 0, 255);
358         }
359 
360         delete[] out;
361 
362         return dst;
363     }
364 }
365 
366 struct vec2 {
367     float x, y;
vec2vec2368     vec2() {}
vec2vec2369     vec2(float s) : x(s), y(s) {}
vec2vec2370     vec2(float x, float y) : x(x), y(y) {}
371 
372     inline float& operator [] (int index) const { ASSERT(index >= 0 && index <= 1); return ((float*)this)[index]; }
373 
374     inline bool operator == (const vec2 &v) const { return x == v.x && y == v.y; }
375     inline bool operator != (const vec2 &v) const { return !(*this == v); }
376     inline bool operator == (float s)       const { return x == s && y == s; }
377     inline bool operator != (float s)       const { return !(*this == s); }
378     inline bool operator <  (const vec2 &v) const { return x < v.x && y < v.y; }
379     inline bool operator >  (const vec2 &v) const { return x > v.x && y > v.y; }
380     inline vec2 operator -  ()              const { return vec2(-x, -y); }
381 
382     vec2& operator += (const vec2 &v) { x += v.x; y += v.y; return *this; }
383     vec2& operator -= (const vec2 &v) { x -= v.x; y -= v.y; return *this; }
384     vec2& operator *= (const vec2 &v) { x *= v.x; y *= v.y; return *this; }
385     vec2& operator /= (const vec2 &v) { x /= v.x; y /= v.y; return *this; }
386     vec2& operator += (float s)       { x += s;   y += s;   return *this; }
387     vec2& operator -= (float s)       { x -= s;   y -= s;   return *this; }
388     vec2& operator *= (float s)       { x *= s;   y *= s;   return *this; }
389     vec2& operator /= (float s)       { x /= s;   y /= s;   return *this; }
390 
391     vec2 operator + (const vec2 &v) const { return vec2(x + v.x, y + v.y); }
392     vec2 operator - (const vec2 &v) const { return vec2(x - v.x, y - v.y); }
393     vec2 operator * (const vec2 &v) const { return vec2(x * v.x, y * v.y); }
394     vec2 operator / (const vec2 &v) const { return vec2(x / v.x, y / v.y); }
395     vec2 operator + (float s)       const { return vec2(x + s,   y + s  ); }
396     vec2 operator - (float s)       const { return vec2(x - s,   y - s  ); }
397     vec2 operator * (float s)       const { return vec2(x * s,   y * s  ); }
398     vec2 operator / (float s)       const { return vec2(x / s,   y / s  ); }
399 
dotvec2400     float dot(const vec2 &v)   const { return x * v.x + y * v.y; }
crossvec2401     float cross(const vec2 &v) const { return x * v.y - y * v.x; }
402 
length2vec2403     float length2() const { return dot(*this); }
lengthvec2404     float length()  const { return sqrtf(length2()); }
absvec2405     vec2  abs()     const { return vec2(fabsf(x), fabsf(y)); }
normalvec2406     vec2  normal()  const { float s = length(); return s == 0.0 ? (*this) : (*this)*(1.0f/s); }
anglevec2407     float angle()   const { return atan2f(y, x); }
rotatevec2408     vec2& rotate(const vec2 &cs) { *this = vec2(x*cs.x - y*cs.y, x*cs.y + y*cs.x); return *this; }
rotatevec2409     vec2& rotate(float angle)    { vec2 cs; sincos(angle, &cs.y, &cs.x); return rotate(cs); }
410 
lerpvec2411     vec2 lerp(const vec2 &v, const float t) const {
412         if (t <= 0.0f) return *this;
413         if (t >= 1.0f) return v;
414         return *this + (v - *this) * t;
415     }
416 };
417 
418 struct vec3 {
419     float x, y, z;
420 
vec3vec3421     vec3() {}
vec3vec3422     vec3(float s) : x(s), y(s), z(s) {}
vec3vec3423     vec3(float x, float y, float z) : x(x), y(y), z(z) {}
424     vec3(const vec2 &xy, float z = 0.0f) : x(xy.x), y(xy.y), z(z) {}
vec3vec3425     vec3(float lng, float lat) : x(sinf(lat) * cosf(lng)), y(-sinf(lng)), z(cosf(lat) * cosf(lng)) {}
426 
xyvec3427     vec2& xy() const { return *((vec2*)&x); }
yzvec3428     vec2& yz() const { return *((vec2*)&y); }
429 
430     inline float& operator [] (int index) const { ASSERT(index >= 0 && index <= 2); return ((float*)this)[index]; }
431 
432     inline bool operator == (const vec3 &v) const { return x == v.x && y == v.y && z == v.z; }
433     inline bool operator != (const vec3 &v) const { return !(*this == v); }
434     inline bool operator == (float s)       const { return x == s && y == s && z == s; }
435     inline bool operator != (float s)       const { return !(*this == s); }
436     inline bool operator <  (const vec3 &v) const { return x < v.x && y < v.y && z < v.z; }
437     inline bool operator >  (const vec3 &v) const { return x > v.x && y > v.y && z > v.z; }
438     inline vec3 operator -  ()              const { return vec3(-x, -y, -z); }
439 
440     vec3& operator += (const vec3 &v) { x += v.x; y += v.y; z += v.z; return *this; }
441     vec3& operator -= (const vec3 &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
442     vec3& operator *= (const vec3 &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
443     vec3& operator /= (const vec3 &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
444     vec3& operator += (float s)       { x += s;   y += s;   z += s;   return *this; }
445     vec3& operator -= (float s)       { x -= s;   y -= s;   z -= s;   return *this; }
446     vec3& operator *= (float s)       { x *= s;   y *= s;   z *= s;   return *this; }
447     vec3& operator /= (float s)       { x /= s;   y /= s;   z /= s;   return *this; }
448 
449     vec3 operator + (const vec3 &v) const { return vec3(x + v.x, y + v.y, z + v.z); }
450     vec3 operator - (const vec3 &v) const { return vec3(x - v.x, y - v.y, z - v.z); }
451     vec3 operator * (const vec3 &v) const { return vec3(x * v.x, y * v.y, z * v.z); }
452     vec3 operator / (const vec3 &v) const { return vec3(x / v.x, y / v.y, z / v.z); }
453     vec3 operator + (float s)       const { return vec3(x + s,   y + s,   z + s);   }
454     vec3 operator - (float s)       const { return vec3(x - s,   y - s,   z - s);   }
455     vec3 operator * (float s)       const { return vec3(x * s,   y * s,   z * s);   }
456     vec3 operator / (float s)       const { return vec3(x / s,   y / s,   z / s);   }
457 
dotvec3458     float dot(const vec3 &v)   const { return x * v.x + y * v.y + z * v.z; }
crossvec3459     vec3  cross(const vec3 &v) const { return vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); }
460 
length2vec3461     float length2() const { return dot(*this); }
lengthvec3462     float length()  const { return sqrtf(length2()); }
absvec3463     vec3  abs()     const { return vec3(fabsf(x), fabsf(y), fabsf(z)); }
normalvec3464     vec3  normal()  const { float s = length(); return s == 0.0f ? (*this) : (*this)*(1.0f/s); }
axisXZvec3465     vec3  axisXZ()  const { return (fabsf(x) > fabsf(z)) ? vec3(float(sign(x)), 0, 0) : vec3(0, 0, float(sign(z))); }
466 
reflectvec3467     vec3 reflect(const vec3 &n) const {
468         return *this - n * (dot(n) * 2.0f);
469     }
470 
lerpvec3471     vec3 lerp(const vec3 &v, const float t) const {
472         if (t <= 0.0f) return *this;
473         if (t >= 1.0f) return v;
474         return *this + (v - *this) * t;
475     }
476 
rotateYvec3477     vec3 rotateY(float angle) const {
478         float s, c;
479         sincos(angle, &s, &c);
480         return vec3(x*c - z*s, y, x*s + z*c);
481     }
482 
anglevec3483     float angle(const vec3 &v) const {
484         return dot(v) / (length() * v.length());
485     }
486 
angleXvec3487     float angleX() const { return atan2f(sqrtf(x * x + z * z), y); }
angleYvec3488     float angleY() const { return atan2f(z, x); }
489 };
490 
491 struct vec4 {
492     float x, y, z, w;
493 
xyvec4494     vec2& xy()  const { return *((vec2*)&x); }
xyzvec4495     vec3& xyz() const { return *((vec3*)&x); }
496 
vec4vec4497     vec4() {}
vec4vec4498     vec4(float s) : x(s), y(s), z(s), w(s) {}
vec4vec4499     vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
vec4vec4500     vec4(const vec3 &xyz) : x(xyz.x), y(xyz.y), z(xyz.z), w(0) {}
vec4vec4501     vec4(const vec3 &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {}
vec4vec4502     vec4(const vec2 &xy, const vec2 &zw) : x(xy.x), y(xy.y), z(zw.x), w(zw.y) {}
503 
504     inline float& operator [] (int index) const { ASSERT(index >= 0 && index <= 3); return ((float*)this)[index]; }
505 
506     inline bool operator == (const vec4 &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; }
507     inline bool operator != (const vec4 &v) const { return !(*this == v); }
508 
509     vec4 operator + (const vec4 &v) const { return vec4(x + v.x, y + v.y, z + v.z, w + v.w); }
510     vec4 operator - (const vec4 &v) const { return vec4(x - v.x, y - v.y, z - v.z, w - v.w); }
511     vec4 operator * (const vec4 &v) const { return vec4(x*v.x, y*v.y, z*v.z, w*v.w); }
512     vec4& operator *= (const vec4 &v) { x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this; }
513 
dotvec4514     float dot(const vec4 &v) const { return x * v.x + y * v.y + z * v.z + w * v.w; }
515 
lerpvec4516     vec4 lerp(const vec4 &v, const float t) const {
517         if (t <= 0.0f) return *this;
518         if (t >= 1.0f) return v;
519         return *this + (v - *this) * t;
520     }
521 };
522 
523 struct quat {
524     float x, y, z, w;
525 
xyzquat526     vec3& xyz() const { return *((vec3*)&x); }
527 
quatquat528     quat() {}
quatquat529     quat(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
530 
quatquat531     quat(const vec3 &axis, float angle) {
532         float s, c;
533         sincos(angle * 0.5f, &s, &c);
534         x = axis.x * s;
535         y = axis.y * s;
536         z = axis.z * s;
537         w = c;
538     }
539 
540     inline bool operator == (const quat &q) const { return x == q.x && y == q.y && z == q.z && w == q.w; }
541     inline bool operator != (const quat &v) const { return !(*this == v); }
542 
543     quat operator - () const {
544         return quat(-x, -y, -z, -w);
545     }
546 
547     quat operator + (const quat &q) const {
548         return quat(x + q.x, y + q.y, z + q.z, w + q.w);
549     }
550 
551     quat operator - (const quat &q) const {
552         return quat(x - q.x, y - q.y, z - q.z, w - q.w);
553     }
554 
555     quat operator * (const float s) const {
556         return quat(x * s, y * s, z * s, w * s);
557     }
558 
559     quat operator * (const quat &q) const {
560         return quat(w * q.x + x * q.w + y * q.z - z * q.y,
561                     w * q.y + y * q.w + z * q.x - x * q.z,
562                     w * q.z + z * q.w + x * q.y - y * q.x,
563                     w * q.w - x * q.x - y * q.y - z * q.z);
564     }
565 
566     vec3 operator * (const vec3 &v) const {
567         return v + xyz().cross(xyz().cross(v) + v * w) * 2.0f;
568     }
569 
dotquat570     float dot(const quat &q) const {
571         return x * q.x + y * q.y + z * q.z + w * q.w;
572     }
573 
length2quat574     float length2() const {
575         return dot(*this);
576     }
577 
lengthquat578     float length() const {
579         return sqrtf(length2());
580     }
581 
normalizequat582     void normalize() {
583         *this = normal();
584     }
585 
normalquat586     quat normal() const {
587         return *this * (1.0f / length());
588     }
589 
conjugatequat590     quat conjugate() const {
591         return quat(-x, -y, -z, w);
592     }
593 
inversequat594     quat inverse() const {
595         return conjugate() * (1.0f / length2());
596     }
597 
lerpquat598     quat lerp(const quat &q, float t) const {
599         if (t <= 0.0f) return *this;
600         if (t >= 1.0f) return q;
601 
602         return dot(q) < 0 ? (*this - (q + *this) * t) :
603                             (*this + (q - *this) * t);
604     }
605 
slerpquat606     quat slerp(const quat &q, float t) const {
607         if (t <= 0.0f) return *this;
608         if (t >= 1.0f) return q;
609 
610         quat temp;
611         float omega, cosom, sinom, scale0, scale1;
612 
613         cosom = dot(q);
614         if (cosom < 0.0f) {
615             temp = -q;
616             cosom = -cosom;
617         } else
618             temp = q;
619 
620         if (1.0f - cosom > EPS) {
621             omega = acosf(cosom);
622             sinom = 1.0f / sinf(omega);
623             scale0 = sinf((1.0f - t) * omega) * sinom;
624             scale1 = sinf(t * omega) * sinom;
625         } else {
626             scale0 = 1.0f - t;
627             scale1 = t;
628         }
629 
630         return *this * scale0 + temp * scale1;
631     }
632 };
633 
634 struct mat4 {
635 
636     enum ProjRange {
637         PROJ_NEG_POS,
638         PROJ_NEG_ZERO,
639         PROJ_ZERO_POS,
640     };
641 
642     float e00, e10, e20, e30,
643           e01, e11, e21, e31,
644           e02, e12, e22, e32,
645           e03, e13, e23, e33;
646 
rightmat4647     vec4& right()  const { return *((vec4*)&e00); }
upmat4648     vec4& up()     const { return *((vec4*)&e01); }
dirmat4649     vec4& dir()    const { return *((vec4*)&e02); }
offsetmat4650     vec4& offset() const { return *((vec4*)&e03); }
651 
mat4mat4652     mat4() {}
653 
mat4mat4654     mat4(float e00, float e10, float e20, float e30,
655          float e01, float e11, float e21, float e31,
656          float e02, float e12, float e22, float e32,
657          float e03, float e13, float e23, float e33) :
658          e00(e00), e10(e10), e20(e20), e30(e30),
659          e01(e01), e11(e11), e21(e21), e31(e31),
660          e02(e02), e12(e12), e22(e22), e32(e32),
661          e03(e03), e13(e13), e23(e23), e33(e33) {}
662 
mat4mat4663     mat4(const quat &rot, const vec3 &pos) {
664         setRot(rot);
665         setPos(pos);
666         e30 = e31 = e32 = 0.0f;
667         e33 = 1.0f;
668     }
669 
670     void ortho(ProjRange range, float l, float r, float b, float t, float znear, float zfar, bool rotate90 = false) {
671         identity();
672 
673         if (rotate90) {
674             e00 = e11 = 0.0f;
675             e10 = 2.0f / (l - r);
676             e01 = 2.0f / (t - b);
677         } else {
678             e00 = 2.0f / (r - l);
679             e11 = 2.0f / (t - b);
680         }
681 
682         e03 = (l + r) / (l - r);
683         e13 = (t + b) / (b - t);
684 
685         switch (range) {
686             case PROJ_NEG_POS :
687                 e22 = 2.0f / (znear - zfar);
688                 e23 = (znear + zfar) / (znear - zfar);
689                 break;
690             case PROJ_NEG_ZERO :
691                 e22 = 1.0f / (znear - zfar);
692                 e23 = (znear + zfar) / (znear - zfar) * 0.5f - 0.5f;
693                 e03 = -e03;
694                 break;
695             case PROJ_ZERO_POS :
696                 e22 = 2.0f / (znear - zfar);
697                 e23 = znear / (znear - zfar);
698                 break;
699         }
700     }
701 
702     void frustum(ProjRange range, float l, float r, float b, float t, float znear, float zfar, bool rotate90 = false) {
703         identity();
704 
705         if (rotate90) {
706             e00 = e11 = 0.0f;
707             e01 = 2.0f * znear / (r - l);
708             e10 = 2.0f * znear / (b - t);
709         } else {
710             e00 = 2.0f * znear / (r - l);
711             e11 = 2.0f * znear / (t - b);
712         }
713 
714         e02 = (r + l) / (r - l);
715         e12 = (t + b) / (t - b);
716         e32 = -1.0f;
717         e33 = 0.0f;
718 
719         switch (range) {
720             case PROJ_NEG_POS :
721                 e22 = (znear + zfar) / (znear - zfar);
722                 e23 = 2.0f * zfar * znear / (znear - zfar);
723                 break;
724             case PROJ_NEG_ZERO :
725                 e22 = znear / (znear - zfar);
726                 e23 = zfar * znear / (znear - zfar);
727                 break;
728             case PROJ_ZERO_POS :
729                 e22 = zfar / (znear - zfar);
730                 e23 = znear * e22;
731                 break;
732         }
733     }
734 
735     void perspective(ProjRange range, float fov, float aspect, float znear, float zfar, float eye = 0.0f, bool rotate90 = false) {
736         float y = tanf(fov * 0.5f * DEG2RAD) * znear;
737         float x = y;
738         float eyeX, eyeY;
739 
740         if (rotate90) {
741             eyeX = 0.0f;
742             eyeY = -eye;
743             aspect = 1.0f / aspect;
744             swap(x, y);
745         } else {
746             eyeX = eye;
747             eyeY = 0.0f;
748         }
749 
750         if (aspect >= 1.0f) {
751             x = y * aspect;
752         } else {
753             y /= aspect;
754         }
755 
756         frustum(range, -x - eyeX, x - eyeX, -y - eyeY, y - eyeY, znear, zfar, rotate90);
757     }
758 
viewportmat4759     void viewport(float x, float y, float width, float height, float n, float f) {
760         identity();
761         e00 = width   * 0.5f;
762         e11 = height  * 0.5f;
763         e22 = (f - n) * 0.5f;
764         e23 = (f + n) * 0.5f;
765         e03 = x + e00;
766         e13 = y + e11;
767     }
768 
mat4mat4769     mat4(const vec3 &from, const vec3 &at, const vec3 &up) {
770         vec3 r, u, d;
771         d = (from - at).normal();
772         r = up.cross(d).normal();
773         u = d.cross(r);
774 
775         this->right()   = vec4(r, 0.0f);
776         this->up()      = vec4(u, 0.0f);
777         this->dir()     = vec4(d, 0.0f);
778         this->offset()  = vec4(from, 1.0f);
779     }
780 
mat4mat4781     mat4(const vec4 &reflectPlane) {
782         float a = reflectPlane.x,
783               b = reflectPlane.y,
784               c = reflectPlane.z,
785               d = reflectPlane.w;
786 
787         right()  = vec4(1 - 2*a*a,   - 2*b*a,   - 2*c*a, 0);
788         up()     = vec4(  - 2*a*b, 1 - 2*b*b,   - 2*c*b, 0);
789         dir()    = vec4(  - 2*a*c,   - 2*b*c, 1 - 2*c*c, 0);
790         offset() = vec4(  - 2*a*d,   - 2*b*d,   - 2*c*d, 1);
791     }
792 
793 
identitymat4794     void identity() {
795         e10 = e20 = e30 = e01 = e21 = e31 = e02 = e12 = e32 = e03 = e13 = e23 = 0.0f;
796         e00 = e11 = e22 = e33 = 1.0f;
797     }
798 
799     mat4 operator * (const mat4 &m) const {
800         mat4 r;
801         r.e00 = e00 * m.e00 + e01 * m.e10 + e02 * m.e20 + e03 * m.e30;
802         r.e10 = e10 * m.e00 + e11 * m.e10 + e12 * m.e20 + e13 * m.e30;
803         r.e20 = e20 * m.e00 + e21 * m.e10 + e22 * m.e20 + e23 * m.e30;
804         r.e30 = e30 * m.e00 + e31 * m.e10 + e32 * m.e20 + e33 * m.e30;
805         r.e01 = e00 * m.e01 + e01 * m.e11 + e02 * m.e21 + e03 * m.e31;
806         r.e11 = e10 * m.e01 + e11 * m.e11 + e12 * m.e21 + e13 * m.e31;
807         r.e21 = e20 * m.e01 + e21 * m.e11 + e22 * m.e21 + e23 * m.e31;
808         r.e31 = e30 * m.e01 + e31 * m.e11 + e32 * m.e21 + e33 * m.e31;
809         r.e02 = e00 * m.e02 + e01 * m.e12 + e02 * m.e22 + e03 * m.e32;
810         r.e12 = e10 * m.e02 + e11 * m.e12 + e12 * m.e22 + e13 * m.e32;
811         r.e22 = e20 * m.e02 + e21 * m.e12 + e22 * m.e22 + e23 * m.e32;
812         r.e32 = e30 * m.e02 + e31 * m.e12 + e32 * m.e22 + e33 * m.e32;
813         r.e03 = e00 * m.e03 + e01 * m.e13 + e02 * m.e23 + e03 * m.e33;
814         r.e13 = e10 * m.e03 + e11 * m.e13 + e12 * m.e23 + e13 * m.e33;
815         r.e23 = e20 * m.e03 + e21 * m.e13 + e22 * m.e23 + e23 * m.e33;
816         r.e33 = e30 * m.e03 + e31 * m.e13 + e32 * m.e23 + e33 * m.e33;
817         return r;
818     }
819 
820     vec3 operator * (const vec3 &v) const {
821         return vec3(
822             e00 * v.x + e01 * v.y + e02 * v.z + e03,
823             e10 * v.x + e11 * v.y + e12 * v.z + e13,
824             e20 * v.x + e21 * v.y + e22 * v.z + e23);
825     }
826 
827     vec4 operator * (const vec4 &v) const {
828         return vec4(
829             e00 * v.x + e01 * v.y + e02 * v.z + e03 * v.w,
830             e10 * v.x + e11 * v.y + e12 * v.z + e13 * v.w,
831             e20 * v.x + e21 * v.y + e22 * v.z + e23 * v.w,
832             e30 * v.x + e31 * v.y + e32 * v.z + e33 * v.w);
833     }
834 
translatemat4835     void translate(const vec3 &offset) {
836         mat4 m;
837         m.identity();
838         m.setPos(offset);
839         *this = *this * m;
840     };
841 
scalemat4842     void scale(const vec3 &factor) {
843         mat4 m;
844         m.identity();
845         m.e00 = factor.x;
846         m.e11 = factor.y;
847         m.e22 = factor.z;
848         *this = *this * m;
849     }
850 
rotateXmat4851     void rotateX(float angle) {
852         mat4 m;
853         m.identity();
854         float s, c;
855         sincos(angle, &s, &c);
856         m.e11 = c;  m.e21 = s;
857         m.e12 = -s; m.e22 = c;
858         *this = *this * m;
859     }
860 
rotateYmat4861     void rotateY(float angle) {
862         mat4 m;
863         m.identity();
864         float s, c;
865         sincos(angle, &s, &c);
866         m.e00 = c;  m.e20 = -s;
867         m.e02 = s;  m.e22 = c;
868         *this = *this * m;
869     }
870 
rotateZmat4871     void rotateZ(float angle) {
872         mat4 m;
873         m.identity();
874         float s, c;
875         sincos(angle, &s, &c);
876         m.e00 = c;  m.e01 = -s;
877         m.e10 = s;  m.e11 = c;
878         *this = *this * m;
879     }
880 
rotateYXZmat4881     void rotateYXZ(const vec3 &angle) {
882         float s, c, a, b;
883 
884         if (angle.y != 0.0f) {
885             sincos(angle.y, &s, &c);
886 
887             a = e00 * c - e02 * s;
888             b = e02 * c + e00 * s;
889             e00 = a;
890             e02 = b;
891 
892             a = e10 * c - e12 * s;
893             b = e12 * c + e10 * s;
894             e10 = a;
895             e12 = b;
896 
897             a = e20 * c - e22 * s;
898             b = e22 * c + e20 * s;
899             e20 = a;
900             e22 = b;
901         }
902 
903         if (angle.x != 0.0f) {
904             sincos(angle.x, &s, &c);
905 
906             a = e01 * c + e02 * s;
907             b = e02 * c - e01 * s;
908             e01 = a;
909             e02 = b;
910 
911             a = e11 * c + e12 * s;
912             b = e12 * c - e11 * s;
913             e11 = a;
914             e12 = b;
915 
916             a = e21 * c + e22 * s;
917             b = e22 * c - e21 * s;
918             e21 = a;
919             e22 = b;
920         }
921 
922         if (angle.z != 0.0f) {
923             sincos(angle.z, &s, &c);
924 
925             a = e00 * c + e01 * s;
926             b = e01 * c - e00 * s;
927             e00 = a;
928             e01 = b;
929 
930             a = e10 * c + e11 * s;
931             b = e11 * c - e10 * s;
932             e10 = a;
933             e11 = b;
934 
935             a = e20 * c + e21 * s;
936             b = e21 * c - e20 * s;
937             e20 = a;
938             e21 = b;
939         }
940     }
941 
lerpmat4942     void lerp(const mat4 &m, float t) {
943         e00 += (m.e00 - e00) * t;
944         e01 += (m.e01 - e01) * t;
945         e02 += (m.e02 - e02) * t;
946         e03 += (m.e03 - e03) * t;
947 
948         e10 += (m.e10 - e10) * t;
949         e11 += (m.e11 - e11) * t;
950         e12 += (m.e12 - e12) * t;
951         e13 += (m.e13 - e13) * t;
952 
953         e20 += (m.e20 - e20) * t;
954         e21 += (m.e21 - e21) * t;
955         e22 += (m.e22 - e22) * t;
956         e23 += (m.e23 - e23) * t;
957     }
958 
detmat4959     float det() const {
960         return  e00 * (e11 * (e22 * e33 - e32 * e23) - e21 * (e12 * e33 - e32 * e13) + e31 * (e12 * e23 - e22 * e13)) -
961                 e10 * (e01 * (e22 * e33 - e32 * e23) - e21 * (e02 * e33 - e32 * e03) + e31 * (e02 * e23 - e22 * e03)) +
962                 e20 * (e01 * (e12 * e33 - e32 * e13) - e11 * (e02 * e33 - e32 * e03) + e31 * (e02 * e13 - e12 * e03)) -
963                 e30 * (e01 * (e12 * e23 - e22 * e13) - e11 * (e02 * e23 - e22 * e03) + e21 * (e02 * e13 - e12 * e03));
964     }
965 
inversemat4966     mat4 inverse() const {
967         float idet = 1.0f / det();
968         mat4 r;
969         r.e00 =  (e11 * (e22 * e33 - e32 * e23) - e21 * (e12 * e33 - e32 * e13) + e31 * (e12 * e23 - e22 * e13)) * idet;
970         r.e01 = -(e01 * (e22 * e33 - e32 * e23) - e21 * (e02 * e33 - e32 * e03) + e31 * (e02 * e23 - e22 * e03)) * idet;
971         r.e02 =  (e01 * (e12 * e33 - e32 * e13) - e11 * (e02 * e33 - e32 * e03) + e31 * (e02 * e13 - e12 * e03)) * idet;
972         r.e03 = -(e01 * (e12 * e23 - e22 * e13) - e11 * (e02 * e23 - e22 * e03) + e21 * (e02 * e13 - e12 * e03)) * idet;
973         r.e10 = -(e10 * (e22 * e33 - e32 * e23) - e20 * (e12 * e33 - e32 * e13) + e30 * (e12 * e23 - e22 * e13)) * idet;
974         r.e11 =  (e00 * (e22 * e33 - e32 * e23) - e20 * (e02 * e33 - e32 * e03) + e30 * (e02 * e23 - e22 * e03)) * idet;
975         r.e12 = -(e00 * (e12 * e33 - e32 * e13) - e10 * (e02 * e33 - e32 * e03) + e30 * (e02 * e13 - e12 * e03)) * idet;
976         r.e13 =  (e00 * (e12 * e23 - e22 * e13) - e10 * (e02 * e23 - e22 * e03) + e20 * (e02 * e13 - e12 * e03)) * idet;
977         r.e20 =  (e10 * (e21 * e33 - e31 * e23) - e20 * (e11 * e33 - e31 * e13) + e30 * (e11 * e23 - e21 * e13)) * idet;
978         r.e21 = -(e00 * (e21 * e33 - e31 * e23) - e20 * (e01 * e33 - e31 * e03) + e30 * (e01 * e23 - e21 * e03)) * idet;
979         r.e22 =  (e00 * (e11 * e33 - e31 * e13) - e10 * (e01 * e33 - e31 * e03) + e30 * (e01 * e13 - e11 * e03)) * idet;
980         r.e23 = -(e00 * (e11 * e23 - e21 * e13) - e10 * (e01 * e23 - e21 * e03) + e20 * (e01 * e13 - e11 * e03)) * idet;
981         r.e30 = -(e10 * (e21 * e32 - e31 * e22) - e20 * (e11 * e32 - e31 * e12) + e30 * (e11 * e22 - e21 * e12)) * idet;
982         r.e31 =  (e00 * (e21 * e32 - e31 * e22) - e20 * (e01 * e32 - e31 * e02) + e30 * (e01 * e22 - e21 * e02)) * idet;
983         r.e32 = -(e00 * (e11 * e32 - e31 * e12) - e10 * (e01 * e32 - e31 * e02) + e30 * (e01 * e12 - e11 * e02)) * idet;
984         r.e33 =  (e00 * (e11 * e22 - e21 * e12) - e10 * (e01 * e22 - e21 * e02) + e20 * (e01 * e12 - e11 * e02)) * idet;
985         return r;
986     }
987 
inverseOrthomat4988     mat4 inverseOrtho() const {
989         mat4 r;
990         r.e00 =  e00; r.e10 = e01; r.e20 = e02; r.e30 = 0;
991         r.e01 =  e10; r.e11 = e11; r.e21 = e12; r.e31 = 0;
992         r.e02 =  e20; r.e12 = e21; r.e22 = e22; r.e32 = 0;
993         r.e03 = -(e03 * e00 + e13 * e10 + e23 * e20); // -dot(pos, right)
994         r.e13 = -(e03 * e01 + e13 * e11 + e23 * e21); // -dot(pos, up)
995         r.e23 = -(e03 * e02 + e13 * e12 + e23 * e22); // -dot(pos, dir)
996         r.e33 = 1;
997         return r;
998     }
999 
transposemat41000     mat4 transpose() const {
1001         mat4 r;
1002         r.e00 = e00; r.e10 = e01; r.e20 = e02; r.e30 = e03;
1003         r.e01 = e10; r.e11 = e11; r.e21 = e12; r.e31 = e13;
1004         r.e02 = e20; r.e12 = e21; r.e22 = e22; r.e32 = e23;
1005         r.e03 = e30; r.e13 = e31; r.e23 = e32; r.e33 = e33;
1006         return r;
1007     }
1008 
getRotmat41009     quat getRot() const {
1010         float t, s;
1011         t = 1.0f + e00 + e11 + e22;
1012         if (t > 0.0001f) {
1013             s = 0.5f / sqrtf(t);
1014             return quat((e21 - e12) * s, (e02 - e20) * s, (e10 - e01) * s, 0.25f / s);
1015         } else
1016             if (e00 > e11 && e00 > e22) {
1017                 s = 0.5f / sqrtf(1.0f + e00 - e11 - e22);
1018                 return quat(0.25f / s, (e01 + e10) * s, (e02 + e20) * s, (e21 - e12) * s);
1019             } else
1020                 if (e11 > e22) {
1021                     s = 0.5f / sqrtf(1.0f - e00 + e11 - e22);
1022                     return quat((e01 + e10) * s, 0.25f / s, (e12 + e21) * s, (e02 - e20) * s);
1023                 } else {
1024                     s = 0.5f / sqrtf(1.0f - e00 - e11 + e22);
1025                     return quat((e02 + e20) * s, (e12 + e21) * s, 0.25f / s, (e10 - e01) * s);
1026                 }
1027     }
1028 
setRotmat41029     void setRot(const quat &rot) {
1030         float   sx = rot.x * rot.x,
1031                 sy = rot.y * rot.y,
1032                 sz = rot.z * rot.z,
1033                 sw = rot.w * rot.w,
1034                 inv = 1.0f / (sx + sy + sz + sw);
1035 
1036         e00 = ( sx - sy - sz + sw) * inv;
1037         e11 = (-sx + sy - sz + sw) * inv;
1038         e22 = (-sx - sy + sz + sw) * inv;
1039         inv *= 2.0f;
1040 
1041         float t1 = rot.x * rot.y;
1042         float t2 = rot.z * rot.w;
1043         e10 = (t1 + t2) * inv;
1044         e01 = (t1 - t2) * inv;
1045 
1046         t1 = rot.x * rot.z;
1047         t2 = rot.y * rot.w;
1048         e20 = (t1 - t2) * inv;
1049         e02 = (t1 + t2) * inv;
1050 
1051         t1 = rot.y * rot.z;
1052         t2 = rot.x * rot.w;
1053         e21 = (t1 + t2) * inv;
1054         e12 = (t1 - t2) * inv;
1055     }
1056 
getPosmat41057     vec3 getPos() const {
1058         return offset().xyz();
1059     }
1060 
setPosmat41061     void setPos(const vec3 &pos) {
1062         offset().xyz() = pos;
1063     }
1064 };
1065 
1066 struct Basis {
1067     quat    rot;
1068     vec3    pos;
1069     float   w;
1070 
BasisBasis1071     Basis() {}
BasisBasis1072     Basis(const quat &rot, const vec3 &pos) : rot(rot), pos(pos), w(1.0f) {}
BasisBasis1073     Basis(const mat4 &matrix) : rot(matrix.getRot()), pos(matrix.getPos()), w(1.0f) {}
1074 
identityBasis1075     void identity() {
1076         rot = quat(0, 0, 0, 1);
1077         pos = vec3(0, 0, 0);
1078         w   = 1.0f;
1079     }
1080 
1081     Basis operator * (const Basis &basis) const {
1082         return Basis(rot * basis.rot, pos + rot * basis.pos);
1083     }
1084 
1085     vec3 operator * (const vec3 &v) const {
1086         return rot * v + pos;
1087     }
1088 
inverseBasis1089     Basis inverse() const {
1090         quat q = rot.conjugate();
1091         return Basis(q, -(q * pos));
1092     }
1093 
translateBasis1094     void translate(const vec3 &v) {
1095         pos += rot * v;
1096     }
1097 
rotateBasis1098     void rotate(const quat &q) {
1099         rot = rot * q;
1100     }
1101 
lerpBasis1102     Basis lerp(const Basis &basis, float t) {
1103         if (t <= 0.0f) return *this;
1104         if (t >= 1.0f) return basis;
1105         Basis b;
1106         b.rot = rot.lerp(basis.rot, t);
1107         b.pos = pos.lerp(basis.pos, t);
1108         return b;
1109     }
1110 };
1111 
1112 struct ubyte2 {
1113     uint8 x, y;
1114 };
1115 
1116 union ubyte4 {
1117     struct { uint8 x, y, z, w; };
1118     uint32 value;
1119 
ubyte4()1120     ubyte4() {}
ubyte4(uint8 x,uint8 y,uint8 z,uint8 w)1121     ubyte4(uint8 x, uint8 y, uint8 z, uint8 w) : x(x), y(y), z(z), w(w) {}
1122 };
1123 
1124 struct short2 {
1125     int16 x, y;
1126 
short2short21127     short2() {}
short2short21128     short2(int16 x, int16 y) : x(x), y(y) {}
1129 
1130     inline bool operator == (const short2 &v) const { return x == v.x && y == v.y; }
1131 };
1132 
1133 struct short3 {
1134     int16 x, y, z;
1135 
short3short31136     short3() {}
short3short31137     short3(int16 x, int16 y, int16 z) : x(x), y(y), z(z) {}
1138 
vec3short31139     operator vec3() const { return vec3((float)x, (float)y, (float)z); };
1140 
1141     short3 operator + (const short3 &v) const { return short3(x + v.x, y + v.y, z + v.z); }
1142     short3 operator - (const short3 &v) const { return short3(x - v.x, y - v.y, z - v.z); }
1143     inline bool operator == (const short3 &v) const { return x == v.x && y == v.y && z == v.z; }
1144 };
1145 
1146 struct short4 {
1147     int16 x, y, z, w;
1148 
short4short41149     short4() {}
short4short41150     short4(int16 x, int16 y, int16 z, int16 w) : x(x), y(y), z(z), w(w) {}
1151 
vec2short41152     operator vec2()   const { return vec2((float)x, (float)y); };
vec3short41153     operator vec3()   const { return vec3((float)x, (float)y, (float)z); };
vec4short41154     operator vec4()   const { return vec4((float)x, (float)y, (float)z, (float)w); };
1155 
short2short41156     operator short2() const { return *((short2*)this); }
short3short41157     operator short3() const { return *((short3*)this); }
1158 
1159     inline bool operator == (const short4 &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; }
1160     inline bool operator != (const short4 &v) const { return !(*this == v); }
1161 
1162     inline int16& operator [] (int index) const { ASSERT(index >= 0 && index <= 3); return ((int16*)this)[index]; }
1163 };
1164 
rotYXZ(const vec3 & angle)1165 quat rotYXZ(const vec3 &angle) {
1166     mat4 m;
1167     m.identity();
1168     m.rotateYXZ(angle);
1169     return m.getRot();
1170 }
1171 
lerpAngle(const vec3 & a,const vec3 & b,float t)1172 quat lerpAngle(const vec3 &a, const vec3 &b, float t) { // TODO: optimization
1173 
1174     return rotYXZ(a).lerp(rotYXZ(b), t);//.normal();
1175 }
1176 
boxNormal(int x,int z)1177 vec3 boxNormal(int x, int z) {
1178     x %= 1024;
1179     z %= 1024;
1180 
1181     if (x > 1024 - z)
1182         return x < z ? vec3(0, 0, 1)  : vec3(1, 0, 0);
1183     else
1184         return x < z ? vec3(-1, 0, 0) : vec3(0, 0, -1);
1185 }
1186 
1187 
1188 struct Sphere {
1189     vec3  center;
1190     float radius;
1191 
SphereSphere1192     Sphere() {}
SphereSphere1193     Sphere(const vec3 &center, float radius) : center(center), radius(radius) {}
1194 
intersectSphere1195     bool intersect(const Sphere &s) const {
1196         float d = (center - s.center).length2();
1197         float r = (radius + s.radius);
1198         return d < r * r;
1199     }
1200 
intersectSphere1201     bool intersect(const vec3 &rayPos, const vec3 &rayDir, float &t) const {
1202         vec3 v = rayPos - center;
1203         float h = -v.dot(rayDir);
1204         float d = h * h + radius * radius - v.length2();
1205 
1206         if (d > 0.0f) {
1207             d = sqrtf(d);
1208             float tMin = h - d;
1209             float tMax = h + d;
1210             if (tMax > 0.0f) {
1211                 if (tMin < 0.0f)
1212                     tMin = 0.0f;
1213                 t = tMin;
1214                 return true;
1215             }
1216         }
1217         return false;
1218     }
1219 };
1220 
1221 
1222 struct Box {
1223     vec3 min, max;
1224 
BoxBox1225     Box() {}
BoxBox1226     Box(const vec3 &min, const vec3 &max) : min(min), max(max) {}
1227 
1228     vec3 operator [] (int index) const {
1229         ASSERT(index >= 0 && index <= 7);
1230         switch (index) {
1231             case 0 : return min;
1232             case 1 : return max;
1233             case 2 : return vec3(min.x, max.y, max.z);
1234             case 3 : return vec3(max.x, min.y, max.z);
1235             case 4 : return vec3(min.x, min.y, max.z);
1236             case 5 : return vec3(max.x, max.y, min.z);
1237             case 6 : return vec3(min.x, max.y, min.z);
1238             case 7 : return vec3(max.x, min.y, min.z);
1239         }
1240         return min;
1241     }
1242 
intersection2DBox1243     Box intersection2D(const Box &b) const {
1244         Box r(vec3(0.0f), vec3(0.0f));
1245         if (max.x < b.min.x || min.x > b.max.x) return r;
1246         if (max.y < b.min.y || min.y > b.max.y) return r;
1247         r.max.x = ::min(max.x, b.max.x);
1248         r.max.y = ::min(max.y, b.max.y);
1249         r.min.x = ::max(min.x, b.min.x);
1250         r.min.y = ::max(min.y, b.min.y);
1251         return r;
1252     }
1253 
1254     Box& operator += (const Box &box) {
1255         min.x = ::min(min.x, box.min.x);
1256         min.y = ::min(min.y, box.min.y);
1257         min.z = ::min(min.z, box.min.z);
1258         max.x = ::max(max.x, box.max.x);
1259         max.y = ::max(max.y, box.max.y);
1260         max.z = ::max(max.z, box.max.z);
1261         return *this;
1262     }
1263 
1264     Box& operator += (const vec3 &v) {
1265         min.x = ::min(min.x, v.x);
1266         min.y = ::min(min.y, v.y);
1267         min.z = ::min(min.z, v.z);
1268         max.x = ::max(max.x, v.x);
1269         max.y = ::max(max.y, v.y);
1270         max.z = ::max(max.z, v.z);
1271         return *this;
1272     }
1273 
1274     Box& operator -= (const Box &box) {
1275         min.x = ::max(min.x, box.min.x);
1276         min.y = ::max(min.y, box.min.y);
1277         min.z = ::max(min.z, box.min.z);
1278         max.x = ::min(max.x, box.max.x);
1279         max.y = ::min(max.y, box.max.y);
1280         max.z = ::min(max.z, box.max.z);
1281         return *this;
1282     }
1283 
1284     Box operator * (const mat4 &m) const {
1285         Box res(vec3(+INF), vec3(-INF));
1286         for (int i = 0; i < 8; i++) {
1287             vec4 v = m * vec4((*this)[i], 1.0f);
1288             res += v.xyz() /= v.w;
1289         }
1290         return res;
1291     }
1292 
centerBox1293     vec3 center() const {
1294         return (min + max) * 0.5f;
1295     }
1296 
sizeBox1297     vec3 size() const {
1298         return max - min;
1299     }
1300 
expandBox1301     void expand(const vec3 &v) {
1302         min -= v;
1303         max += v;
1304     }
1305 
rotate90Box1306     void rotate90(int n) {
1307         switch (n) {
1308             case 0  : break;
1309             case 1  : *this = Box(vec3( min.z, min.y, -max.x), vec3( max.z, max.y, -min.x)); break;
1310             case 2  : *this = Box(vec3(-max.x, min.y, -max.z), vec3(-min.x, max.y, -min.z)); break;
1311             case 3  : *this = Box(vec3(-max.z, min.y,  min.x), vec3(-min.z, max.y,  max.x)); break;
1312             default : ASSERT(false);
1313         }
1314     }
1315 
translateBox1316     void translate(const vec3 &offset) {
1317         min += offset;
1318         max += offset;
1319     }
1320 
closestPointBox1321     vec3 closestPoint(const vec3 &p) const {
1322         return vec3(clamp(p.x, min.x, max.x),
1323                     clamp(p.y, min.y, max.y),
1324                     clamp(p.z, min.z, max.z));
1325     }
1326 
containsBox1327     bool contains(const vec3 &v) const {
1328         return v.x >= min.x && v.x <= max.x && v.y >= min.y && v.y <= max.y && v.z >= min.z && v.z <= max.z;
1329     }
1330 
pushOut2DBox1331     vec3 pushOut2D(const vec3 &v) const {
1332         float ax = v.x - min.x;
1333         float bx = max.x - v.x;
1334         float az = v.z - min.z;
1335         float bz = max.z - v.z;
1336 
1337         vec3 p = vec3(0.0f);
1338         if (ax <= bx && ax <= az && ax <= bz)
1339             p.x = -ax;
1340         else if (bx <= ax && bx <= az && bx <= bz)
1341             p.x =  bx;
1342         else if (az <= ax && az <= bx && az <= bz)
1343             p.z = -az;
1344         else
1345             p.z =  bz;
1346 
1347         return p;
1348     }
1349 
pushOut2DBox1350     vec3 pushOut2D(const Box &b) const {
1351         float ax = b.max.x - min.x;
1352         float bx = max.x - b.min.x;
1353         float az = b.max.z - min.z;
1354         float bz = max.z - b.min.z;
1355 
1356         vec3 p = vec3(0.0f);
1357         if (ax <= bx && ax <= az && ax <= bz)
1358             p.x -= ax;
1359         else if (bx <= ax && bx <= az && bx <= bz)
1360             p.x += bx;
1361         else if (az <= ax && az <= bx && az <= bz)
1362             p.z -= az;
1363         else
1364             p.z += bz;
1365 
1366         return p;
1367     }
1368 
intersectBox1369     bool intersect(const Box &box) const {
1370         return !((max.x < box.min.x || min.x > box.max.x) || (max.y < box.min.y || min.y > box.max.y) || (max.z < box.min.z || min.z > box.max.z));
1371     }
1372 
intersectBox1373     bool intersect(const Sphere &sphere) const {
1374         if (contains(sphere.center))
1375             return true;
1376         vec3 dir = sphere.center - closestPoint(sphere.center);
1377         return (dir.length2() < sphere.radius * sphere.radius);
1378     }
1379 
intersectBox1380     bool intersect(const vec3 &rayPos, const vec3 &rayDir, float &t) const {
1381         float tMax = INF, tMin = -tMax;
1382 
1383         for (int i = 0; i < 3; i++)
1384             if (rayDir[i] != 0) {
1385                 float lo = (min[i] - rayPos[i]) / rayDir[i];
1386                 float hi = (max[i] - rayPos[i]) / rayDir[i];
1387                 tMin = ::max(tMin, ::min(lo, hi));
1388                 tMax = ::min(tMax, ::max(lo, hi));
1389             } else
1390                 if (rayPos[i] < min[i] || rayPos[i] > max[i])
1391                     return false;
1392         t = tMin;
1393         return (tMin <= tMax) && (tMax > 0.0f);
1394     }
1395 
intersectBox1396     bool intersect(const mat4 &matrix, const vec3 &rayPos, const vec3 &rayDir, float &t) const {
1397         mat4 mInv = matrix.inverseOrtho();
1398         return intersect(mInv * rayPos, (mInv * vec4(rayDir, 0)).xyz(), t);
1399     }
1400 };
1401 
1402 union Color32 { // RGBA8888
1403     uint32 value;
1404     struct { uint8 r, g, b, a; };
1405 
Color32()1406     Color32() {}
Color32(uint32 value)1407     Color32(uint32 value) : value(value) {}
Color32(uint8 r,uint8 g,uint8 b,uint8 a)1408     Color32(uint8 r, uint8 g, uint8 b, uint8 a) : r(r), g(g), b(b), a(a) {}
1409 
SetRGB15(uint16 v)1410     void SetRGB15(uint16 v) {
1411         r = (v & 0x7C00) >> 7;
1412         g = (v & 0x03E0) >> 2;
1413         b = (v & 0x001F) << 3;
1414         a = 255;
1415     }
1416 
YCbCr_T871_420(int32 Y0,int32 Y1,int32 Y2,int32 Y3,int32 Cb,int32 Cr,int32 F,Color32 & C0,Color32 & C1,Color32 & C2,Color32 & C3)1417     static void YCbCr_T871_420(int32 Y0, int32 Y1, int32 Y2, int32 Y3, int32 Cb, int32 Cr, int32 F, Color32 &C0, Color32 &C1, Color32 &C2, Color32 &C3) {
1418         static const uint32 dither[8] = {
1419             0x00000600, 0x00060006, 0x00040204, 0x00020402,
1420             0x00000000, 0x00000000, 0x00000000, 0x00000000,
1421         };
1422 
1423         ASSERT(F == 0 || F == 4);
1424 
1425         int32 R = ( 91881  * Cr              ) >> 16;
1426         int32 G = ( 22550  * Cb + 46799 * Cr ) >> 16;
1427         int32 B = ( 116129 * Cb              ) >> 16;
1428 
1429         const Color32 *d = (Color32*)dither + F;
1430 
1431         C0.r = clamp(Y0 + R + d->r, 0, 255);
1432         C0.g = clamp(Y0 - G + d->g, 0, 255);
1433         C0.b = clamp(Y0 + B + d->b, 0, 255);
1434         C0.a = 255;
1435         d++;
1436 
1437         C1.r = clamp(Y1 + R + d->r, 0, 255);
1438         C1.g = clamp(Y1 - G + d->g, 0, 255);
1439         C1.b = clamp(Y1 + B + d->b, 0, 255);
1440         C1.a = 255;
1441         d++;
1442 
1443         C2.r = clamp(Y2 + R + d->r, 0, 255);
1444         C2.g = clamp(Y2 - G + d->g, 0, 255);
1445         C2.b = clamp(Y2 + B + d->b, 0, 255);
1446         C2.a = 255;
1447         d++;
1448 
1449         C3.r = clamp(Y3 + R + d->r, 0, 255);
1450         C3.g = clamp(Y3 - G + d->g, 0, 255);
1451         C3.b = clamp(Y3 + B + d->b, 0, 255);
1452         C3.a = 255;
1453     }
1454 };
1455 
1456 struct Color24 { // RGB888
1457     uint8 r, g, b;
1458 
Color24Color241459     Color24() {}
Color24Color241460     Color24(uint8 r, uint8 g, uint8 b) : r(r), g(g), b(b) {}
1461 
Color32Color241462     operator Color32() const { return Color32(r, g, b, 255); }
1463 };
1464 
1465 union Color16 { // RGBA5551
1466     struct { uint16 b:5, g:5, r:5, a:1; };
1467     uint16 value;
1468 
Color16()1469     Color16() {}
Color16(uint16 value)1470     Color16(uint16 value) : value(value) {}
1471 
Color24()1472     operator Color24() const { return Color24((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2)); }
Color32()1473     operator Color32() const { return Color32((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), -a); }
1474 };
1475 
1476 union ColorCLUT { // RGBA5551
1477     struct { uint16 r:5, g:5, b:5, a:1; };
1478     uint16 value;
1479 
ColorCLUT()1480     ColorCLUT() {}
ColorCLUT(uint16 value)1481     ColorCLUT(uint16 value) : value(value) {}
1482 
Color24()1483     operator Color24() const { return Color24((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2)); }
Color32()1484     operator Color32() const { return Color32((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), -a); }
1485 };
1486 
1487 
1488 struct ColorIndex4 {
1489     uint8 a:4, b:4;
1490 };
1491 
1492 struct Tile4 {
1493     ColorIndex4 index[256 * 256 / 2];
1494 };
1495 
1496 struct Tile8 {
1497     uint8 index[256 * 256];
1498 };
1499 
1500 struct Tile16 {
1501     Color16 color[256 * 256];
1502 };
1503 
1504 #ifdef USE_ATLAS_RGBA16
1505 union AtlasColor {
1506     struct { uint16 a:1, b:5, g:5, r:5; };
1507     uint16 value;
1508 
AtlasColor()1509     AtlasColor() {}
AtlasColor(uint16 value)1510     AtlasColor(uint16 value) : value(value) {}
AtlasColor(const Color16 & value)1511     AtlasColor(const Color16 &value) : a(value.a), b(value.b), g(value.g), r(value.r) {}
AtlasColor(const Color24 & value)1512     AtlasColor(const Color24 &value) : a(1), b(value.b >> 3), g(value.g >> 3), r(value.r >> 3) {}
AtlasColor(const Color32 & value)1513     AtlasColor(const Color32 &value) : a(value.a ? 1 : 0), b(value.b >> 3), g(value.g >> 3), r(value.r >> 3) {}
AtlasColor(const ColorCLUT & value)1514     AtlasColor(const ColorCLUT &value) : a(value.a), b(value.b), g(value.g), r(value.r) {}
1515 };
1516 
1517 #define ATLAS_FORMAT FMT_RGBA16
1518 #else
1519 typedef Color32 AtlasColor;
1520 #define ATLAS_FORMAT FMT_RGBA
1521 #endif
1522 
1523 struct AtlasTile {
1524     AtlasColor color[256 * 256];
1525 };
1526 
1527 struct Tile32 {
1528     Color32 color[256 * 256];
1529 };
1530 
1531 struct CLUT {
1532     ColorCLUT color[16];
1533 };
1534 
1535 namespace StrUtils {
1536 
toLower(char * str)1537     void toLower(char *str) {
1538         if (!str) return;
1539 
1540         while (char &c = *str++) {
1541             if (c >= 'A' && c <= 'Z')
1542                 c -= 'Z' - 'z';
1543         }
1544     }
1545 
copy(const char * str)1546     char* copy(const char *str) {
1547         if (str == NULL) {
1548             return NULL;
1549         }
1550         char *res = new char[strlen(str) + 1];
1551         strcpy(res, str);
1552         return res;
1553     }
1554 
length(uint16 * str)1555     int32 length(uint16 *str) {
1556         if (!str || !str[0]) return 0;
1557         int32 len = 0;
1558         while (*str++) {
1559             len++;
1560         }
1561         return len;
1562     }
1563 }
1564 
1565 
1566 template <typename T>
1567 struct Array {
1568     int capacity;
1569     int length;
1570     T   *items;
1571 
capacityArray1572     Array(int capacity = 32) : capacity(capacity), length(0), items(NULL) {}
1573 
~ArrayArray1574     ~Array() {
1575         clear();
1576     }
1577 
reserveArray1578     void reserve(int capacity) {
1579         this->capacity = capacity;
1580         if (items)
1581             items = (T*)realloc(items, capacity * sizeof(T));
1582         else
1583             items = (T*)malloc(capacity * sizeof(T));
1584     }
1585 
pushArray1586     int push(const T &item) {
1587         if (!items)
1588             items = (T*)malloc(capacity * sizeof(T));
1589 
1590         if (length == capacity)
1591             reserve(capacity + capacity / 2);
1592 
1593         items[length] = item;
1594         return length++;
1595     }
1596 
popArray1597     int pop() {
1598         ASSERT(length > 0);
1599         return --length;
1600     }
1601 
removeFastArray1602     void removeFast(int index) {
1603         (*this)[index] = (*this)[length - 1];
1604         length--;
1605     }
1606 
removeArray1607     void remove(int index) {
1608         length--;
1609         ASSERT(length >= 0);
1610         for (int i = index; i < length; i++)
1611             items[i] = items[i + 1];
1612     }
1613 
resizeArray1614     void resize(int length) {
1615         if (capacity < length)
1616             reserve(length);
1617         this->length = length;
1618     }
1619 
resetArray1620     void reset() {
1621         length = 0;
1622     }
1623 
clearArray1624     void clear() {
1625         reset();
1626         free(items);
1627         items = NULL;
1628     }
1629 
findArray1630     int find(const T &item) {
1631         for (int i = 0; i < length; i++) {
1632             if (items[i] == item)
1633                 return i;
1634         }
1635         return -1;
1636     }
1637 
sortArray1638     void sort() {
1639         ::sort(items, length);
1640     }
1641 
1642     T& operator[] (int index) {
1643         ASSERT(index >= 0 && index < length);
1644         return items[index];
1645     };
1646 };
1647 
1648 
1649 struct Stream;
1650 
1651 extern void osCacheWrite (Stream *stream);
1652 extern void osCacheRead  (Stream *stream);
1653 
1654 extern void osReadSlot   (Stream *stream);
1655 extern void osWriteSlot  (Stream *stream);
1656 
1657 #ifdef _OS_WEB
1658 extern void osDownload   (Stream *stream);
1659 #endif
1660 
1661 char cacheDir[255];
1662 char saveDir[255];
1663 char contentDir[255];
1664 
1665 #define STREAM_BUFFER_SIZE (16 * 1024)
1666 
1667 #define MAX_PACKS 32
1668 
1669 struct Stream {
1670     typedef void (Callback)(Stream *stream, void *userData);
1671     Callback    *callback;
1672     void        *userData;
1673 
1674     FILE        *f;
1675     char        *data;
1676     char        *name;
1677     int         size, pos, fpos;
1678 
1679     char        *buffer;
1680     int         bufferIndex;
1681     bool        buffering;
1682     uint32      baseOffset;
1683 
1684     struct Pack
1685     {
1686         Stream* stream;
1687         uint8*  table;
1688         uint32  count;
1689 
1690         struct FileInfo
1691         {
1692             uint32 size;
1693             uint32 offset;
1694         };
1695 
findFileStream::Pack1696         bool findFile(const char* name, FileInfo &info)
1697         {
1698             if (!table || !name || !name[0]) {
1699                 return false;
1700             }
1701 
1702             uint16 len = (uint16)strlen(name);
1703             uint8* ptr = table;
1704 
1705             for (uint32 i = 0; i < count; i++)
1706             {
1707                 uint32 magic;
1708                 memcpy(&magic, ptr, sizeof(magic));
1709                 if (magic != 0x02014B50) {
1710                     ASSERT(false);
1711                     return false;
1712                 }
1713 
1714                 uint16 nameLen, extraLen, infoLen;
1715                 memcpy(&nameLen, ptr + 28, sizeof(nameLen));
1716                 memcpy(&extraLen, ptr + 30, sizeof(extraLen));
1717 
1718                 if ((nameLen == len) && (memcmp(ptr + 46, name, len) == 0))
1719                 {
1720                     uint16 compression;
1721                     memcpy(&compression, ptr + 10, sizeof(compression));
1722 
1723                     if (compression != 0)
1724                     {
1725                         ASSERT(false);
1726                         return false;
1727                     }
1728 
1729                     memcpy(&info.size,   ptr + 24, sizeof(info.size));
1730                     memcpy(&info.offset, ptr + 42, sizeof(info.offset));
1731 
1732                     stream->setPos(info.offset);
1733                     magic = stream->readLE32();
1734 
1735                     if (magic != 0x04034B50) {
1736                         ASSERT(false);
1737                         return false;
1738                     }
1739                     stream->seek(22);
1740                     nameLen = stream->readLE16();
1741                     extraLen = stream->readLE16();
1742 
1743                     info.offset += 4 + 22 + 2 + 2 + nameLen + extraLen;
1744 
1745                     return true;
1746                 }
1747 
1748                 memcpy(&infoLen,  ptr + 32, sizeof(infoLen));
1749 
1750                 ptr += 46 + nameLen + extraLen + infoLen;
1751             }
1752 
1753             return false;
1754         }
1755 
PackStream::Pack1756         Pack(const char *name) : stream(NULL), table(NULL), count(0)
1757         {
1758             stream = new Stream(name);
1759             stream->buffering = false;
1760             stream->setPos(stream->size - 22);
1761             uint32 magic = stream->readLE32();
1762 
1763             if (magic != 0x06054B50)
1764             {
1765                 ASSERT(false);
1766                 return;
1767             }
1768 
1769             stream->seek(6);
1770             count = stream->readLE16();
1771             uint32 tableSize = stream->readLE32();
1772             uint32 tableOffset = stream->readLE32();
1773 
1774             stream->setPos(tableOffset);
1775 
1776             table = new uint8[tableSize];
1777             stream->raw(table, tableSize);
1778         }
1779 
~PackStream::Pack1780         ~Pack() {
1781             delete stream;
1782             delete[] table;
1783         }
1784     };
1785 
1786     static Pack* packs[MAX_PACKS];
1787 
1788     static Array<char*> fileList;
1789 
addPackStream1790     static bool addPack(const char *name)
1791     {
1792         if (!existsContent(name)) {
1793             return false;
1794         }
1795 
1796         for (int i = 0; i < MAX_PACKS; i++)
1797         {
1798             if (!packs[i])
1799             {
1800                 packs[i] = new Pack(name);
1801                 return true;
1802             }
1803         }
1804         return false;
1805     }
1806 
initStream1807     static void init() {
1808         readFileList();
1809     }
1810 
deinitStream1811     static void deinit()
1812     {
1813         for (int i = 0; i < MAX_PACKS; i++)
1814         {
1815             if (!packs[i]) break;
1816             delete packs[i];
1817         }
1818 
1819         for (int i = 0; i < fileList.length; i++) {
1820             delete[] fileList[i];
1821         }
1822         fileList.clear();
1823     }
1824 
1825 private:
1826 #ifdef _OS_3DS
streamThreadStream1827     static void streamThread(void *arg) {
1828         Stream* stream = (Stream*)arg;
1829         stream->openFile();
1830     }
1831 #endif
1832 
openFileStream1833     void openFile() {
1834         char path[255];
1835 
1836         path[0] = 0;
1837         if (contentDir[0] && (!cacheDir[0] || !strstr(name, cacheDir))) {
1838             strcpy(path, contentDir);
1839         }
1840         strcat(path, name);
1841         fixBackslash(path);
1842 
1843         f = fopen(path, "rb");
1844 
1845         if (!f) {
1846             #ifdef _OS_WEB
1847                 osDownload(this);
1848             #else
1849                 LOG("error loading file \"%s\"\n", name);
1850                 if (callback) {
1851                     callback(NULL, userData);
1852                     delete this;
1853                 } else {
1854                     ASSERT(false);
1855                 }
1856             #endif
1857         } else {
1858             fseek(f, 0, SEEK_END);
1859             size = (int32)ftell(f);
1860             fseek(f, 0, SEEK_SET);
1861 
1862             fpos = 0;
1863             bufferIndex = -1;
1864 
1865             if (callback) callback(this, userData);
1866         }
1867     }
1868 public:
1869 
callbackStream1870     Stream(const char *name, const void *data, int size, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data((char*)data), name(NULL), size(size), pos(0), buffer(NULL) {
1871         this->name = StrUtils::copy(name);
1872     }
1873 
callbackStream1874     Stream(const char *name, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data(NULL), name(NULL), size(-1), pos(0), buffer(NULL), buffering(true), baseOffset(0) {
1875         if (!name && callback) {
1876             callback(NULL, userData);
1877             delete this;
1878             return;
1879         }
1880 
1881         if (!name) {
1882             ASSERT(false);
1883         }
1884 
1885         Stream::Pack::FileInfo info;
1886 
1887         char path[256];
1888 
1889         for (int i = 0; i < MAX_PACKS; i++)
1890         {
1891             if (!packs[i]) break;
1892 
1893             if (packs[i]->findFile(name, info))
1894             {
1895                 path[0] = 0;
1896                 if (contentDir[0] && (!cacheDir[0] || !strstr(name, cacheDir))) {
1897                     strcpy(path, contentDir);
1898                 }
1899                 strcat(path, packs[i]->stream->name);
1900                 fixBackslash(path);
1901 
1902                 f = fopen(path, "rb");
1903                 if (!f) {
1904                     LOG("error loading file from pack \"%s -> %s\"\n", packs[i]->stream->name, name);
1905                     ASSERT(false);
1906                     return;
1907                 }
1908                 baseOffset = info.offset;
1909                 fseek(f, info.offset, SEEK_SET);
1910                 size = info.size;
1911 
1912                 fpos = 0;
1913                 bufferIndex = -1;
1914 
1915                 this->name = StrUtils::copy(name);
1916                 if (callback) callback(this, userData);
1917                 return;
1918             }
1919         }
1920 
1921         this->name = StrUtils::copy(name);
1922 
1923     #ifdef _OS_3DS /* TODO
1924         if (callback) {
1925             s32 priority = 0;
1926             svcGetThreadPriority(&priority, CUR_THREAD_HANDLE);
1927             threadCreate(streamThread, this, 64 * 1024, priority - 1, -2, false);
1928             return;
1929         }*/
1930     #endif
1931 
1932         openFile();
1933     }
1934 
~StreamStream1935     ~Stream() {
1936         delete[] name;
1937         delete[] buffer;
1938         if (f) fclose(f);
1939     }
1940 
1941 #if _OS_3DS
readDirectoryStream1942     static void readDirectory(const FS_Archive &archive, const char* path) {
1943         char buf[255];
1944         strcpy(buf, contentDir + 5); // 5 to skip "sdmc:"
1945         strcat(buf, path);
1946 
1947         FS_Path fsPath = fsMakePath(FS_PathType::PATH_ASCII, buf);
1948 
1949         Handle dir;
1950         if (FSUSER_OpenDirectory(&dir, archive, fsPath) != 0) {
1951             return;
1952         }
1953 
1954         int32 pathLen = strlen(path);
1955         strcpy(buf, path);
1956 
1957         while (1) {
1958             FS_DirectoryEntry entry;
1959 
1960             u32 entriesRead = 0;
1961             FSDIR_Read(dir, &entriesRead, 1, &entry);
1962 
1963             if (entriesRead == 0) {
1964                 break;
1965             }
1966 
1967             int32 len = utf16_to_utf8((uint8*)buf + pathLen, entry.name, StrUtils::length(entry.name));
1968             buf[pathLen + len] = 0;
1969 
1970             if (entry.attributes & FS_ATTRIBUTE_DIRECTORY) {
1971                 strcat(buf, "/");
1972                 readDirectory(archive, buf);
1973             } else {
1974                 fileList.push(StrUtils::copy(buf));
1975             }
1976         }
1977 
1978         FSDIR_Close(dir);
1979     }
1980 
readFileListStream1981     static void readFileList() {
1982         FS_Archive sdmc;
1983         FS_Path fsRoot = fsMakePath(FS_PathType::PATH_ASCII, "");
1984 
1985         if (FSUSER_OpenArchive(&sdmc, FS_ArchiveID::ARCHIVE_SDMC, fsRoot) != 0) {
1986             return;
1987         }
1988 
1989         readDirectory(sdmc, "");
1990 
1991         FSUSER_CloseArchive(sdmc);
1992     }
1993 #elif _OS_PSV
readDirectoryStream1994     static void readDirectory(char* path) {
1995         SceUID dd = sceIoDopen(path);
1996 
1997         size_t len = strlen(path);
1998 
1999         SceIoDirent entry;
2000         while (sceIoDread(dd, &entry) > 0)
2001         {
2002             strcat(path, entry.d_name);
2003 
2004             if (SCE_S_ISDIR(entry.d_stat.st_mode))
2005             {
2006                 strcat(path, "/");
2007                 readDirectory(path);
2008             } else {
2009                 fileList.push(StrUtils::copy(path + strlen(contentDir)));
2010             }
2011 
2012             path[len] = 0;
2013         }
2014 
2015         sceIoClose(dd);
2016     }
2017 
readFileListStream2018     static void readFileList() {
2019         char path[255];
2020         strcpy(path, contentDir);
2021         readDirectory(path);
2022     }
2023 #else
readFileListStream2024     static void readFileList() {};
2025 #endif
2026 
2027     static void cacheRead(const char *name, Callback *callback = NULL, void *userData = NULL) {
2028         Stream *stream = new Stream(name, NULL, 0, callback, userData);
2029         #ifdef _OS_ANDROID // use saveDir for settings on android devices
2030             if (name && strcmp(name, "settings") == 0) {
2031                 osReadSlot(stream);
2032                 return;
2033             }
2034         #endif
2035         osCacheRead(stream);
2036     }
2037 
2038     static void cacheWrite(const char *name, const char *data, int size, Callback *callback = NULL, void *userData = NULL) {
2039         Stream *stream = new Stream(name, data, size, callback, userData);
2040         #ifdef _OS_ANDROID // use saveDir for settings on android devices
2041             if (name && strcmp(name, "settings") == 0) {
2042                 osWriteSlot(stream);
2043                 return;
2044             }
2045         #endif
2046         osCacheWrite(stream);
2047     }
2048 
fixBackslashStream2049     static void fixBackslash(char *str) {
2050     #ifdef _OS_XBOX
2051         int len = strlen(str);
2052         for (int i = 0; i < len; i++) {
2053             if (str[i] == '/') {
2054                 str[i] = '\\';
2055             }
2056         }
2057     #endif
2058     }
2059 
existsStream2060     static bool exists(const char *name) {
2061         FILE *f = fopen(name, "rb");
2062         if (!f) return false;
2063         fclose(f);
2064         return true;
2065     }
2066 
existsContentStream2067     static bool existsContent(const char *name) {
2068         for (uint32 i = 0; i < MAX_PACKS; i++)
2069         {
2070             if (!packs[i]) break;
2071 
2072             Pack::FileInfo info;
2073             if (packs[i]->findFile(name, info))
2074                 return true;
2075         }
2076 
2077         if (fileList.length) {
2078             for (int i = 0; i < fileList.length; i++) {
2079                 if (strcmp(fileList[i], name) == 0) {
2080                     return true;
2081                 }
2082             }
2083             return false;
2084         }
2085 
2086         char fileName[1024];
2087         strcpy(fileName, contentDir);
2088         strcat(fileName, name);
2089         fixBackslash(fileName);
2090         return exists(fileName);
2091     }
2092 
setPosStream2093     void setPos(int pos) {
2094         this->pos = pos;
2095     }
2096 
seekStream2097     void seek(int offset) {
2098         pos += offset;
2099     }
2100 
rawStream2101     void raw(void *data, int count) {
2102         if (!count) return;
2103 
2104         if (f) {
2105 
2106             if (!buffering) {
2107                 if (fpos != pos) {
2108                     fseek(f, baseOffset + pos, SEEK_SET);
2109                     fpos = pos;
2110                 }
2111                 fread(data, 1, count, f);
2112                 pos += count;
2113                 fpos += count;
2114                 return;
2115             }
2116 
2117             uint8 *ptr = (uint8*)data;
2118 
2119             while (count > 0) {
2120                 int bIndex = pos / STREAM_BUFFER_SIZE;
2121 
2122                 if (bufferIndex != bIndex) {
2123                     bufferIndex = bIndex;
2124 
2125                     int readed;
2126                     int part;
2127 
2128                     if (fpos == pos) {
2129                         part = min(count / STREAM_BUFFER_SIZE * STREAM_BUFFER_SIZE, size - fpos);
2130                         if (part > STREAM_BUFFER_SIZE) {
2131                             readed = (int)fread(ptr, 1, part, f);
2132 
2133                             #ifdef TEST_SLOW_FIO
2134                                 LOG("%s read %d + %d\n", name, fpos, readed);
2135                                 Sleep(5);
2136                             #endif
2137 
2138                             ASSERT(part == readed);
2139                             count -= readed;
2140                             fpos  += readed;
2141                             pos   += readed;
2142                             ptr   += readed;
2143 
2144                             if (count <= 0) {
2145                                 bufferIndex = -1;
2146                                 break;
2147                             }
2148 
2149                             bufferIndex = pos / STREAM_BUFFER_SIZE;
2150                         }
2151                     }
2152 
2153                     if (fpos != bufferIndex * STREAM_BUFFER_SIZE) {
2154                         fpos = bufferIndex * STREAM_BUFFER_SIZE;
2155                         fseek(f, baseOffset + fpos, SEEK_SET);
2156 
2157                         #ifdef TEST_SLOW_FIO
2158                             LOG("%s seek %d\n", name, fpos);
2159                             Sleep(5);
2160                         #endif
2161                     }
2162 
2163                     if (!buffer) {
2164                         buffer = new char[STREAM_BUFFER_SIZE];
2165                     }
2166 
2167                     part   = min(STREAM_BUFFER_SIZE, size - fpos);
2168                     readed = (int)fread(buffer, 1, part, f);
2169 
2170                     #ifdef TEST_SLOW_FIO
2171                         LOG("%s read %d + %d\n", name, fpos, readed);
2172                         Sleep(5);
2173                     #endif
2174 
2175                     ASSERT(part == readed);
2176                     fpos += readed;
2177                 }
2178 
2179                 ASSERT(buffer);
2180 
2181                 int bPos   = pos % STREAM_BUFFER_SIZE;
2182                 int delta  = min(STREAM_BUFFER_SIZE - bPos, count);
2183 
2184                 memcpy(ptr, buffer + bPos, delta);
2185                 count -= delta;
2186                 pos   += delta;
2187                 ptr   += delta;
2188             }
2189         } else {
2190             memcpy(data, this->data + pos, count);
2191             pos += count;
2192         }
2193     }
2194 
2195     template <typename T>
readStream2196     inline T& read(T &x) {
2197         raw(&x, sizeof(x));
2198         return x;
2199     }
2200 
2201     template <typename T>
readStream2202     inline T* read(T *&a, int count) {
2203         if (count) {
2204             a = new T[count];
2205             raw(a, count * sizeof(T));
2206         } else
2207             a = NULL;
2208         return a;
2209     }
2210 
readStream2211     inline uint8 read() {
2212         uint8 x;
2213         return read(x);
2214     }
2215 
readLE16Stream2216     inline uint16 readLE16() {
2217         uint16 x;
2218         return read(x);
2219     }
2220 
readLE32Stream2221     inline uint32 readLE32() {
2222         uint32 x;
2223         return read(x);
2224     }
2225 
readBE16Stream2226     inline uint16 readBE16() {
2227         uint16 x;
2228         return swap16(read(x));
2229     }
2230 
readBE32Stream2231     inline uint32 readBE32() {
2232         uint32 x;
2233         return swap32(read(x));
2234     }
2235 
read64Stream2236     inline uint64 read64() {
2237         uint64 x;
2238         return read(x);
2239     }
2240 };
2241 
2242 Stream::Pack* Stream::packs[MAX_PACKS];
2243 Array<char*> Stream::fileList;
2244 
2245 #ifdef OS_FILEIO_CACHE
osDataWrite(Stream * stream,const char * dir)2246 void osDataWrite(Stream *stream, const char *dir) {
2247     char path[255];
2248     strcpy(path, dir);
2249     strcat(path, stream->name);
2250     FILE *f = fopen(path, "wb");
2251     if (f) {
2252         fwrite(stream->data, 1, stream->size, f);
2253         fclose(f);
2254         if (stream->callback)
2255             stream->callback(new Stream(stream->name, stream->data, stream->size), stream->userData);
2256     } else
2257         if (stream->callback)
2258             stream->callback(NULL, stream->userData);
2259 
2260     delete stream;
2261 }
2262 
osDataRead(Stream * stream,const char * dir)2263 void osDataRead(Stream *stream, const char *dir) {
2264     char path[255];
2265     strcpy(path, dir);
2266     strcat(path, stream->name);
2267     FILE *f = fopen(path, "rb");
2268     if (f) {
2269         fseek(f, 0, SEEK_END);
2270         int size = (int)ftell(f);
2271         fseek(f, 0, SEEK_SET);
2272         char *data = new char[size];
2273         fread(data, 1, size, f);
2274         fclose(f);
2275         if (stream->callback)
2276             stream->callback(new Stream(stream->name, data, size), stream->userData);
2277         delete[] data;
2278     } else
2279         if (stream->callback)
2280             stream->callback(NULL, stream->userData);
2281     delete stream;
2282 }
2283 
osCacheWrite(Stream * stream)2284 void osCacheWrite(Stream *stream) {
2285     osDataWrite(stream, cacheDir);
2286 }
2287 
osCacheRead(Stream * stream)2288 void osCacheRead(Stream *stream) {
2289     osDataRead(stream, cacheDir);
2290 }
2291 
osWriteSlot(Stream * stream)2292 void osWriteSlot(Stream *stream) {
2293     osDataWrite(stream, saveDir);
2294 }
2295 
osReadSlot(Stream * stream)2296 void osReadSlot(Stream *stream) {
2297     osDataRead(stream, saveDir);
2298 }
2299 
2300 #endif
2301 
2302 
2303 #ifdef OS_PTHREAD_MT
2304 #include <pthread.h>
2305 
2306 // multi-threading
osMutexInit()2307 void* osMutexInit() {
2308     pthread_mutexattr_t attr;
2309     pthread_mutexattr_init(&attr);
2310     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2311 
2312     pthread_mutex_t *mutex = new pthread_mutex_t();
2313     pthread_mutex_init(mutex, &attr);
2314     return mutex;
2315 }
2316 
osMutexFree(void * obj)2317 void osMutexFree(void *obj) {
2318     pthread_mutex_destroy((pthread_mutex_t*)obj);
2319     delete (pthread_mutex_t*)obj;
2320 }
2321 
osMutexLock(void * obj)2322 void osMutexLock(void *obj) {
2323     pthread_mutex_lock((pthread_mutex_t*)obj);
2324 }
2325 
osMutexUnlock(void * obj)2326 void osMutexUnlock(void *obj) {
2327     pthread_mutex_unlock((pthread_mutex_t*)obj);
2328 }
2329 
osRWLockInit()2330 void* osRWLockInit() {
2331     pthread_rwlock_t *lock = new pthread_rwlock_t();
2332     pthread_rwlock_init(lock, NULL);
2333     return lock;
2334 }
2335 
osRWLockFree(void * obj)2336 void osRWLockFree(void *obj) {
2337     pthread_rwlock_destroy((pthread_rwlock_t*)obj);
2338     delete (pthread_rwlock_t*)obj;
2339 }
2340 
osRWLockRead(void * obj)2341 void osRWLockRead(void *obj) {
2342     pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
2343 }
2344 
osRWUnlockRead(void * obj)2345 void osRWUnlockRead(void *obj) {
2346     pthread_rwlock_unlock((pthread_rwlock_t*)obj);
2347 }
2348 
osRWLockWrite(void * obj)2349 void osRWLockWrite(void *obj) {
2350     pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
2351 }
2352 
osRWUnlockWrite(void * obj)2353 void osRWUnlockWrite(void *obj) {
2354     pthread_rwlock_unlock((pthread_rwlock_t*)obj);
2355 }
2356 #endif
2357 
2358 
2359 static const uint32 BIT_MASK[] = {
2360     0x00000000,
2361     0x00000001, 0x00000003, 0x00000007, 0x0000000F,
2362     0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
2363     0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
2364     0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
2365     0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
2366     0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
2367     0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
2368     0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
2369 };
2370 
2371 // TODO: refactor for LE, BE, byte and word reading
2372 struct BitStream {
2373     uint8  *data;
2374     uint8  *end;
2375     uint16 index;
2376     uint16 value;
2377 
BitStreamBitStream2378     BitStream(uint8 *data, int size) : data(data), end(data + size), index(0), value(0) {}
2379 
readBitBitStream2380     inline uint32 readBit() {
2381        uint32 bit;
2382 
2383        if (!index--) {
2384           value = *data++;
2385           index = 7;
2386        }
2387 
2388        bit = value & 1;
2389        value >>= 1;
2390 
2391        return bit;
2392     }
2393 
readBitStream2394     uint32 read(int count) {
2395         uint32 bits = 0, mask = 1;
2396 
2397         if (index == 0) {
2398             if (count > 7) {
2399                 count -= 8;
2400                 mask <<= 8;
2401                 bits = *data++;
2402             }
2403         }
2404 
2405         while (count--) {
2406             if (readBit())
2407                 bits += mask;
2408             mask <<= 1;
2409         }
2410 
2411         return bits;
2412     }
2413 
readBEBitStream2414     uint8 readBE(int count) {
2415         uint32 bits = 0;
2416 
2417         while (count--) {
2418             if (!index) {
2419                 ASSERT(data < end);
2420                 value = *data++;
2421                 index = 8;
2422             }
2423 
2424             bits <<= 1;
2425 
2426             if (value & 0x80)
2427                 bits |= 1;
2428 
2429             value <<= 1;
2430             index--;
2431         }
2432 
2433         return bits;
2434     }
2435 
readBitBEBitStream2436     uint8 readBitBE() {
2437         return readBE(1);
2438     }
2439 
readByteBitStream2440     uint8 readByte() {
2441         ASSERT(data < end);
2442         return *data++;
2443     }
2444 
readWordBitStream2445     uint32 readWord(bool littleEndian) {
2446         uint8 a, b;
2447         if (littleEndian) {
2448             a = data[0];
2449             b = data[1];
2450         } else {
2451             b = data[0];
2452             a = data[1];
2453         }
2454         data += 2;
2455         return a + (b << 8);
2456     }
2457 
readUBitStream2458     uint32 readU(int count) {
2459         if (!index) {
2460             value = readWord(true);
2461             index = 16;
2462         }
2463 
2464         uint32 bits;
2465         if (count <= index) {
2466             bits = (value >> (index - count)) & BIT_MASK[count];
2467             index -= count;
2468         } else {
2469             bits = value & BIT_MASK[index];
2470             count -= index;
2471             index = 0;
2472 
2473             while (count >= 16) {
2474                 bits = (bits << 16) | readWord(true);
2475                 count -= 16;
2476             }
2477 
2478             if (count > 0) {
2479                 value = readWord(true);
2480                 index = 16 - count;
2481                 bits = (bits << count) | (value >> index);
2482             }
2483         }
2484 
2485         return bits;
2486     }
2487 
skipBitStream2488     void skip(int count) {
2489         readU(count);
2490     }
2491 };
2492 
2493 
2494 template <int N>
2495 struct FixedStr {
2496     char data[N];
2497 
getFixedStr2498     void get(char *dst) {
2499         memcpy(dst, data, sizeof(data));
2500         dst[sizeof(data)] = 0;
2501     }
2502 
2503     FixedStr<N>& operator = (const char *str) {
2504         size_t len = min(sizeof(data), strlen(str));
2505         memset(data, 0, sizeof(data));
2506         memcpy(data, str, len);
2507         return *this;
2508     }
2509 };
2510 
2511 typedef FixedStr<16> str16;
2512 
2513 #endif
2514