+
+#define lhcheeserand(seed) ((seed) = ((seed) * 987211u) ^ ((seed) >> 13u) ^ 914867)
+#define lhcheeserandom(seed,MIN,MAX) ((double)(lhcheeserand(seed) + 0.5) / ((double)4096.0*1024.0*1024.0) * ((MAX)-(MIN)) + (MIN))
+#define VectorCheeseRandom(seed,v) do{(v)[0] = lhcheeserandom(seed,-1, 1);(v)[1] = lhcheeserandom(seed,-1, 1);(v)[2] = lhcheeserandom(seed,-1, 1);}while(DotProduct(v, v) > 1)
+#define VectorLehmerRandom(seed,v) do{(v)[0] = Math_crandomf(seed);(v)[1] = Math_crandomf(seed);(v)[2] = Math_crandomf(seed);}while(DotProduct(v, v) > 1)
+
+/*
+// LadyHavoc: quaternion math, untested, don't know if these are correct,
+// need to add conversion to/from matrices
+// LadyHavoc: later note: the matrix faq is useful: http://skal.planet-d.net/demo/matrixfaq.htm
+// LadyHavoc: these are probably very wrong and I'm not sure I care, not used by anything
+
+// returns length of quaternion
+#define qlen(a) ((float) sqrt((a)[0]*(a)[0]+(a)[1]*(a)[1]+(a)[2]*(a)[2]+(a)[3]*(a)[3]))
+// returns squared length of quaternion
+#define qlen2(a) ((a)[0]*(a)[0]+(a)[1]*(a)[1]+(a)[2]*(a)[2]+(a)[3]*(a)[3])
+// makes a quaternion from x, y, z, and a rotation angle (in degrees)
+#define QuatMake(x,y,z,r,c)\
+{\
+if (r == 0)\
+{\
+(c)[0]=(float) ((x) * (1.0f / 0.0f));\
+(c)[1]=(float) ((y) * (1.0f / 0.0f));\
+(c)[2]=(float) ((z) * (1.0f / 0.0f));\
+(c)[3]=(float) 1.0f;\
+}\
+else\
+{\
+float r2 = (r) * 0.5 * (M_PI / 180);\
+float r2is = 1.0f / sin(r2);\
+(c)[0]=(float) ((x)/r2is);\
+(c)[1]=(float) ((y)/r2is);\
+(c)[2]=(float) ((z)/r2is);\
+(c)[3]=(float) (cos(r2));\
+}\
+}
+// makes a quaternion from a vector and a rotation angle (in degrees)
+#define QuatFromVec(a,r,c) QuatMake((a)[0],(a)[1],(a)[2],(r))
+// copies a quaternion
+#define QuatCopy(a,c) {(c)[0]=(a)[0];(c)[1]=(a)[1];(c)[2]=(a)[2];(c)[3]=(a)[3];}
+#define QuatSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];(c)[3]=(a)[3]-(b)[3];}
+#define QuatAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];(c)[3]=(a)[3]+(b)[3];}
+#define QuatScale(a,b,c) {(c)[0]=(a)[0]*b;(c)[1]=(a)[1]*b;(c)[2]=(a)[2]*b;(c)[3]=(a)[3]*b;}
+// FIXME: this is wrong, do some more research on quaternions
+//#define QuatMultiply(a,b,c) {(c)[0]=(a)[0]*(b)[0];(c)[1]=(a)[1]*(b)[1];(c)[2]=(a)[2]*(b)[2];(c)[3]=(a)[3]*(b)[3];}
+// FIXME: this is wrong, do some more research on quaternions
+//#define QuatMultiplyAdd(a,b,d,c) {(c)[0]=(a)[0]*(b)[0]+d[0];(c)[1]=(a)[1]*(b)[1]+d[1];(c)[2]=(a)[2]*(b)[2]+d[2];(c)[3]=(a)[3]*(b)[3]+d[3];}
+#define qdist(a,b) ((float) sqrt(((b)[0]-(a)[0])*((b)[0]-(a)[0])+((b)[1]-(a)[1])*((b)[1]-(a)[1])+((b)[2]-(a)[2])*((b)[2]-(a)[2])+((b)[3]-(a)[3])*((b)[3]-(a)[3])))
+#define qdist2(a,b) (((b)[0]-(a)[0])*((b)[0]-(a)[0])+((b)[1]-(a)[1])*((b)[1]-(a)[1])+((b)[2]-(a)[2])*((b)[2]-(a)[2])+((b)[3]-(a)[3])*((b)[3]-(a)[3]))
+*/
+
+#define VectorCopy4(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];(b)[3]=(a)[3];}
+
+/// returns vector length
+float VectorNormalizeLength (vec3_t v);
+
+#define NUMVERTEXNORMALS 162
+extern float m_bytenormals[NUMVERTEXNORMALS][3];
+
+unsigned char NormalToByte(const vec3_t n);
+void ByteToNormal(unsigned char num, vec3_t n);
+
+void R_ConcatRotations (const float in1[3*3], const float in2[3*3], float out[3*3]);
+void R_ConcatTransforms (const float in1[3*4], const float in2[3*4], float out[3*4]);
+
+void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
+/// LadyHavoc: proper matrix version of AngleVectors
+void AngleVectorsFLU (const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up);
+/// divVerent: improper matrix version of AngleVectors
+void AngleVectorsDuke3DFLU (const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up, double maxShearAngle);
+/// LadyHavoc: builds a [3][4] matrix
+void AngleMatrix (const vec3_t angles, const vec3_t translate, vec_t matrix[][4]);
+/// LadyHavoc: calculates pitch/yaw/roll angles from forward and up vectors
+void AnglesFromVectors (vec3_t angles, const vec3_t forward, const vec3_t up, qbool flippitch);
+
+/// LadyHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
+void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up);
+void VectorVectorsDouble(const double *forward, double *right, double *up);
+
+void PlaneClassify(struct mplane_s *p);
+int BoxOnPlaneSide(const vec3_t emins, const vec3_t emaxs, const struct mplane_s *p);
+int BoxOnPlaneSide_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, const vec_t dist);
+void BoxPlaneCorners(const vec3_t emins, const vec3_t emaxs, const struct mplane_s *p, vec3_t outnear, vec3_t outfar);
+void BoxPlaneCorners_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, vec3_t outnear, vec3_t outfar);
+void BoxPlaneCornerDistances(const vec3_t emins, const vec3_t emaxs, const struct mplane_s *p, vec_t *outnear, vec_t *outfar);
+void BoxPlaneCornerDistances_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, vec_t *outnear, vec_t *outfar);
+
+#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
+#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
+
+/// LadyHavoc: minimal plane structure
+typedef struct tinyplane_s
+{
+ float normal[3], dist;
+}
+tinyplane_t;
+
+typedef struct tinydoubleplane_s
+{
+ double normal[3], dist;
+}
+tinydoubleplane_t;
+
+void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees);
+
+float RadiusFromBounds (const vec3_t mins, const vec3_t maxs);
+float RadiusFromBoundsAndOrigin (const vec3_t mins, const vec3_t maxs, const vec3_t origin);
+
+struct matrix4x4_s;
+/// print a matrix to the console
+void Matrix4x4_Print(const struct matrix4x4_s *in);
+int Math_atov(const char *s, prvm_vec3_t out);
+
+void BoxFromPoints(vec3_t mins, vec3_t maxs, int numpoints, vec_t *point3f);
+
+int LoopingFrameNumberFromDouble(double t, int loopframes);
+
+// implementation of 128bit Lehmer Random Number Generator with 2^126 period
+// https://en.wikipedia.org/Lehmer_random_number_generator
+typedef struct randomseed_s
+{
+ unsigned int s[4];
+}
+randomseed_t;
+
+void Math_RandomSeed_Reset(randomseed_t *r);
+void Math_RandomSeed_FromInts(randomseed_t *r, unsigned int s0, unsigned int s1, unsigned int s2, unsigned int s3);
+unsigned long long Math_rand64(randomseed_t *r);
+float Math_randomf(randomseed_t *r);
+float Math_crandomf(randomseed_t *r);
+float Math_randomrangef(randomseed_t *r, float minf, float maxf);
+int Math_randomrangei(randomseed_t *r, int mini, int maxi);
+
+void Mathlib_Init(void);
+
+#endif
+