/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

// WSW defines
#include "wsw_shared.h"

// q_shared.h -- included first by ALL program modules
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

//==============================================

#ifdef _WIN32

// wsw : pb : zlib 1.2.3
# define ZLIB_WINAPI 

// unknown pragmas are SUPPOSED to be ignored, but....
# pragma warning(disable : 4244)		// MIPS
# pragma warning(disable : 4136)		// X86
# pragma warning(disable : 4051)		// ALPHA

//# pragma warning(disable : 4018)		// signed/unsigned mismatch
//# pragma warning(disable : 4305)		// truncation from const double to float
# pragma warning(disable : 4514)		// unreferenced inline function has been removed
# pragma warning(disable : 4152)		// nonstandard extension, function/data pointer conversion in expression
# pragma warning(disable : 4201)		// nonstandard extension used : nameless struct/union
# pragma warning(disable : 4054)		// 'type cast' : from function pointer to data pointer
# pragma warning(disable : 4127)		// conditional expression is constant
# pragma warning(disable : 4100)		// unreferenced formal parameter
# pragma warning(disable : 4706)		// assignment within conditional expression

# define HAVE___INLINE

# define HAVE__SNPRINTF

# define HAVE__VSNPRINTF

# define HAVE__STRICMP

# ifdef LCC_WIN32
#  ifndef C_ONLY
#   define C_ONLY
#  endif
#  define HAVE_TCHAR
#  define HAVE_MMSYSTEM
#  define HAVE_DLLMAIN
# else
#  define HAVE_WSIPX
# endif

# define VID_INITFIRST

# define GL_DRIVERNAME	"opengl32.dll"

# define VORBISFILE_LIBNAME	"libvorbisfile.dll"

# ifdef NDEBUG
#  define BUILDSTRING "Win32 RELEASE"
# else
#  define BUILDSTRING "Win32 DEBUG"
# endif

# ifdef _M_IX86
#  define CPUSTRING	"x86"
# elif defined(_M_ALPHA)
#  define CPUSTRING	"AXP"
# endif

// doh, some compilers need a _ prefix for variables so they can be 
// used in asm code
# ifdef __GNUC__	// mingw
#  define VAR(x)	"_"#x
# else
#  define VAR(x)	#x
# endif

#endif

//==============================================

#ifdef __linux__

# define HAVE_INLINE

# define HAVE_STRCASECMP

//# define GL_FORCEFINISH
# define GL_DRIVERNAME	"libGL.so.1"

# define VORBISFILE_LIBNAME	"libvorbisfile.so"

# define BUILDSTRING "Linux"

# ifdef __i386__
#  define CPUSTRING "i386"
# elif defined(__alpha__)
#  define CPUSTRING "axp"
# else
#  define CPUSTRING "Unknown"
# endif

# define VAR(x)	#x

#endif

//==============================================

#if defined (__APPLE__) || defined (MACOSX)

# define HAVE_INLINE

# define HAVE_STRCASECMP

//# define GL_FORCEFINISH
# define GL_DRIVERNAME	"libGL.dylib"

# define VORBISFILE_LIBNAME	"libvorbisfile.dylib"

# define BUILDSTRING "MacOSX"

# ifdef __i386__
#  define CPUSTRING "i386"
# elif defined(__ppc__)
#  define CPUSTRING "ppc"
# else
#  define CPUSTRING "Unknown"
# endif

# define VAR(x)	#x

#endif

//==============================================

#ifdef HAVE___INLINE
# ifndef inline
#  define inline __inline
# endif
#elif !defined(HAVE_INLINE)
# ifndef inline
#  define inline
# endif
#endif

#ifdef HAVE__SNPRINTF
# ifndef snprintf 
#  define snprintf _snprintf
# endif
#endif

#ifdef HAVE__VSNPRINTF
# ifndef vsnprintf 
#  define vsnprintf _vsnprintf
# endif
#endif

#ifdef HAVE__STRICMP
# ifndef Q_stricmp 
#  define Q_stricmp(s1, s2) _stricmp((s1), (s2))
# endif
# ifndef Q_strnicmp 
#  define Q_strnicmp(s1, s2, n) _strnicmp((s1), (s2), (n))
# endif
#endif

#ifdef HAVE_STRCASECMP
# ifndef Q_stricmp 
#  define Q_stricmp(s1, s2) strcasecmp((s1), (s2))
# endif
# ifndef Q_strnicmp 
#  define Q_strnicmp(s1, s2, n) strncasecmp((s1), (s2), (n))
# endif
#endif

#if (defined(_M_IX86) || defined(__i386__) || defined(__ia64__)) && !defined(C_ONLY)
# define id386
#else
# ifdef id386
#  undef id386
# endif
#endif

#ifndef BUILDSTRING
# define BUILDSTRING "NON-WIN32"
#endif

#ifndef CPUSTRING
# define CPUSTRING	"NON-WIN32"
#endif

#ifdef HAVE_TCHAR
# include <tchar.h>
#endif

//==============================================

typedef unsigned char 			qbyte;
typedef enum {qfalse, qtrue}	qboolean;


#ifndef NULL
# define NULL ((void *)0)
#endif

// angle indexes
#define	PITCH				0		// up / down
#define	YAW					1		// left / right
#define	ROLL				2		// fall over

#define	MAX_OSPATH			128		// max length of a filesystem pathname
#define	MAX_QPATH			64		// max length of a quake game pathname

#define	MAX_STRING_CHARS	1024	// max length of a string passed to Cmd_TokenizeString
#define	MAX_STRING_TOKENS	256		// max tokens resulting from Cmd_TokenizeString
#define	MAX_TOKEN_CHARS		1024	// max length of an individual token
#define MAX_CONFIGSTRING_CHARS MAX_QPATH	// max length of a configstring string

#define MAX_NAME_CHARS		20		// max visible characters name (color tokens not counted)



//
// per-level limits
//
#define	MAX_CLIENTS			256		// absolute limit
#define	MAX_EDICTS			1024	// must change protocol to increase more
#define	MAX_LIGHTSTYLES		256
#define	MAX_MODELS			256		// these are sent over the net as bytes
#define	MAX_SOUNDS			256		// so they cannot be blindly increased
#define	MAX_IMAGES			256
#define MAX_SKINFILES		256
#define	MAX_ITEMS			256
#define MAX_GENERAL			(MAX_CLIENTS*2)	// general config strings

#define MAX_CM_AREAS		0x100

// command line execution flags
#define	EXEC_NOW	0				// don't return until completed
#define	EXEC_INSERT	1				// insert at current position, but don't run yet
#define	EXEC_APPEND	2				// add to end of the command buffer

/*
==============================================================

MATHLIB

==============================================================
*/

typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];

typedef vec_t quat_t[4];

typedef qbyte byte_vec4_t[4];

struct cplane_s;

extern vec3_t vec3_origin;
extern vec3_t axis_identity[3];
extern quat_t quat_identity;

#define	nanmask (255<<23)

#define	IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)

#ifndef M_PI
# define M_PI		3.14159265358979323846	// matches value in gcc v2 math.h
#endif

#ifndef M_TWOPI
# define M_TWOPI	6.28318530717958647692
#endif

#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
#define RAD2DEG( a ) ( a * 180.0F ) / M_PI


// returns b clamped to [a..c] range
//#define bound(a,b,c) (max((a), min((b), (c))))

#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif

#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif

#define bound(a,b,c) ((a) >= (c) ? (a) : (b) < (a) ? (a) : (b) > (c) ? (c) : (b))

// clamps a (must be lvalue) to [b..c] range
#define clamp(a,b,c) ((b) >= (c) ? (a)=(b) : (a) < (b) ? (a)=(b) : (a) > (c) ? (a)=(c) : (a))

#define random()		((rand () & 0x7fff) / ((float)0x7fff))	// 0..1
#define brandom(a,b)	((a)+random()*((b)-(a)))				// a..b
#define crandom()		brandom(-1,1)							// -1..1 

int		Q_rand (int *seed);
#define Q_random(seed)		((Q_rand (seed) & 0x7fff) / ((float)0x7fff))	// 0..1
#define Q_brandom(seed,a,b)	((a)+Q_random(seed)*((b)-(a)))						// a..b
#define Q_crandom(seed)		Q_brandom(seed,-1,1)

float	Q_RSqrt (float number);
int		Q_log2 (int val);

#define SQRTFAST( x ) ( (x) * Q_RSqrt( x ) ) // wsw : jal : //The expression a * rsqrt(b) is intended as a higher performance alternative to a / sqrt(b). The two expressions are comparably accurate, but do not compute exactly the same value in every case. For example, a * rsqrt(a*a + b*b) can be just slightly greater than 1, in rare cases.

#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)

#define DotProduct(x,y)			((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
#define CrossProduct(v1,v2,cross) ((cross)[0]=(v1)[1]*(v2)[2]-(v1)[2]*(v2)[1],(cross)[1]=(v1)[2]*(v2)[0]-(v1)[0]*(v2)[2],(cross)[2]=(v1)[0]*(v2)[1]-(v1)[1]*(v2)[0])

#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)

#define VectorSubtract(a,b,c)	((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
#define VectorAdd(a,b,c)		((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
#define VectorCopy(a,b)			((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
#define VectorClear(a)			((a)[0]=(a)[1]=(a)[2]=0)
#define VectorNegate(a,b)		((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
#define VectorSet(v, x, y, z)	((v)[0]=(x),(v)[1]=(y),(v)[2]=(z))
#define VectorAvg(a,b,c)		((c)[0]=((a)[0]+(b)[0])*0.5f,(c)[1]=((a)[1]+(b)[1])*0.5f, (c)[2]=((a)[2]+(b)[2])*0.5f)
#define VectorMA(a,b,c,d)		((d)[0]=(a)[0]+(b)*(c)[0],(d)[1]=(a)[1]+(b)*(c)[1],(d)[2]=(a)[2]+(b)*(c)[2])
#define VectorCompare(v1,v2)	((v1)[0]==(v2)[0] && (v1)[1]==(v2)[1] && (v1)[2]==(v2)[2])
#define VectorLength(v)			(sqrt(DotProduct((v),(v))))
#define VectorInverse(v)		((v)[0]=-(v)[0],(v)[1]=-(v)[1],(v)[2]=-(v)[2])
#define VectorScale(in,scale,out) ((out)[0]=(in)[0]*(scale),(out)[1]=(in)[1]*(scale),(out)[2]=(in)[2]*(scale))

#define DistanceSquared(v1,v2) (((v1)[0]-(v2)[0])*((v1)[0]-(v2)[0])+((v1)[1]-(v2)[1])*((v1)[1]-(v2)[1])+((v1)[2]-(v2)[2])*((v1)[2]-(v2)[2]))
#define Distance(v1,v2) (sqrt(DistanceSquared(v1,v2)))

#define VectorLengthFast(v)		(SQRTFAST(DotProduct((v),(v))))  // wsw : jal :  //The expression a * rsqrt(b) is intended as a higher performance alternative to a / sqrt(b). The two expressions are comparably accurate, but do not compute exactly the same value in every case. For example, a * rsqrt(a*a + b*b) can be just slightly greater than 1, in rare cases.
#define DistanceFast(v1,v2)		(SQRTFAST(DistanceSquared(v1,v2)))  // wsw : jal :  //The expression a * rsqrt(b) is intended as a higher performance alternative to a / sqrt(b). The two expressions are comparably accurate, but do not compute exactly the same value in every case. For example, a * rsqrt(a*a + b*b) can be just slightly greater than 1, in rare cases.

#define Vector2Copy(a,b)		((b)[0]=(a)[0],(b)[1]=(a)[1])
#define Vector2Avg(a,b,c)		((c)[0]=(((a[0])+(b[0]))*0.5f),(c)[1]=(((a[1])+(b[1]))*0.5f)) 

#define Vector4Set(v, a, b, c, d)	((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3] = (d))
#define Vector4Copy(a,b)		((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
#define Vector4Scale(in,scale,out)		((out)[0]=(in)[0]*scale,(out)[1]=(in)[1]*scale,(out)[2]=(in)[2]*scale,(out)[3]=(in)[3]*scale)
#define Vector4Add(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 Vector4Avg(a,b,c)		((c)[0]=(((a[0])+(b[0]))*0.5f),(c)[1]=(((a[1])+(b[1]))*0.5f),(c)[2]=(((a[2])+(b[2]))*0.5f),(c)[3]=(((a[3])+(b[3]))*0.5f)) 

vec_t VectorNormalize (vec3_t v);		// returns vector length
vec_t VectorNormalize2 (vec3_t v, vec3_t out);
void  VectorNormalizeFast (vec3_t v);

// just in case you do't want to use the macros
void _VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
vec_t _DotProduct (vec3_t v1, vec3_t v2);
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
void _VectorCopy (vec3_t in, vec3_t out);

void ClearBounds (vec3_t mins, vec3_t maxs);
void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs);
float RadiusFromBounds (const vec3_t mins, const vec3_t maxs);
qboolean BoundsIntersect (const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2);
qboolean BoundsAndSphereIntersect (const vec3_t mins, const vec3_t maxs, const vec3_t centre, float radius);
qboolean BoundsAndSphereIntersectSplash(const vec3_t mins, const vec3_t maxs, const vec3_t centre, float radius);

#define NUMVERTEXNORMALS	162
int DirToByte (vec3_t dir);
void ByteToDir (int b, vec3_t dir);

void NormToLatLong ( const vec3_t normal, qbyte latlong[2] );

void MakeNormalVectors (const vec3_t forward, vec3_t right, vec3_t up);
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
int BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, const struct cplane_s *plane);
float anglemod(float a);
float LerpAngle (float a1, float a2, const float frac);
void VecToAngles (const vec3_t vec, vec3_t angles);
void AnglesToAxis (const vec3_t angles, vec3_t axis[3]);
void BuildBoxPoints( vec3_t p[8], vec3_t org, vec3_t mins, vec3_t maxs );

vec_t ColorNormalize( const vec_t *in, vec_t *out );

float CalcFov (float fov_x, float width, float height);

#define Q_rint(x)	((x) < 0 ? ((int)((x)-0.5f)) : ((int)((x)+0.5f)))

#define BOX_ON_PLANE_SIDE(emins, emaxs, p)	\
	(((p)->type < 3)?						\
	(										\
		((p)->dist <= (emins)[(p)->type])?	\
			1								\
		:									\
		(									\
			((p)->dist >= (emaxs)[(p)->type])?\
				2							\
			:								\
				3							\
		)									\
	)										\
	:										\
		BoxOnPlaneSide( (emins), (emaxs), (p)))

void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal );
void PerpendicularVector( vec3_t dst, const vec3_t src );
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );

void Matrix_Identity( vec3_t m[3] );
void Matrix_Copy( vec3_t m1[3], vec3_t m2[3] );
qboolean Matrix_Compare( vec3_t m1[3], vec3_t m2[3] );
void Matrix_Multiply( vec3_t m1[3], vec3_t m2[3], vec3_t out[3] );
void Matrix_TransformVector( vec3_t m[3], vec3_t v, vec3_t out );
void Matrix_Transpose( vec3_t in[3], vec3_t out[3] );
void Matrix_EulerAngles( vec3_t m[3], vec3_t angles );
void Matrix_Rotate( vec3_t m[3], vec_t angle, vec_t x, vec_t y, vec_t z );
void Matrix_FromPoints( const vec3_t v1, const vec3_t v2, const vec3_t v3, vec3_t m[3] );

void Quat_Identity( quat_t q );
void Quat_Copy( const quat_t q1, quat_t q2 );
qboolean Quat_Compare( const quat_t q1, const quat_t q2 );
void Quat_Conjugate( const quat_t q1, quat_t q2 );
vec_t Quat_Normalize( quat_t q );
vec_t Quat_Inverse( const quat_t q1, quat_t q2 );
void Quat_Multiply( const quat_t q1, const quat_t q2, quat_t out );
void Quat_Lerp( const quat_t q1, const quat_t q2, vec_t t, quat_t out );
void Quat_Vectors( const quat_t q, vec3_t f, vec3_t r, vec3_t u );
void Quat_Matrix( const quat_t q, vec3_t m[3] );
void Matrix_Quat( vec3_t m[3], quat_t q );
void Quat_TransformVector( const quat_t q, const vec3_t v, vec3_t out );
void Quat_ConcatTransforms( const quat_t q1, const vec3_t v1, const quat_t q2, const vec3_t v2, quat_t q, vec3_t v );

//=============================================

char *COM_SkipPath (char *pathname);
void COM_StripExtension (char *filename);
char *COM_FileExtension (char *in);
void COM_DefaultExtension (char *path, const char *extension, size_t size);
void COM_ReplaceExtension (char *path, const char *extension, size_t size);
void COM_FileBase (char *in, char *out);
void COM_FilePath (char *in, char *out);

// data is an in/out parm, returns a parsed out token
char *COM_ParseExt2 (char **data_p, qboolean nl, qboolean sq);
#define COM_ParseExt(data_p,nl)	COM_ParseExt2(data_p,nl,qtrue)
#define COM_Parse(data_p)	COM_ParseExt(data_p,qtrue)

char *COM_RemoveColorTokens( const char *in );
char *COM_RemoveJunkChars ( const char *in );
int COM_ReadColorRGBString( const char *in );

//=============================================

extern	vec4_t		colorBlack;
extern	vec4_t		colorRed;
extern	vec4_t		colorGreen;
extern	vec4_t		colorBlue;
extern	vec4_t		colorYellow;
extern	vec4_t		colorMagenta;
extern	vec4_t		colorCyan;
extern	vec4_t		colorWhite;
extern	vec4_t		colorLtGrey;
extern	vec4_t		colorMdGrey;
extern	vec4_t		colorDkGrey;
extern	vec4_t		colorOrange;

#define MAX_S_COLORS 10

#define Q_COLOR_ESCAPE	'^'
#define Q_IsColorString(p)	( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE )

#define COLOR_BLACK		'0'
#define COLOR_RED		'1'
#define COLOR_GREEN		'2'
#define COLOR_YELLOW	'3'
#define COLOR_BLUE		'4'
#define COLOR_CYAN		'5'
#define COLOR_MAGENTA	'6'
#define COLOR_WHITE		'7'
#define COLOR_ORANGE	'8'
#define COLOR_GREY		'9'
#define ColorIndex(c)	( ( ((c)-'0') < MAX_S_COLORS ) && ( ((c)-'0') >= 0 ) ? ( (c) - '0' ) : 0  )

#define	COLOR_R(rgba)		((rgba) & 0xFF)
#define	COLOR_G(rgba)		(((rgba) >> 8) & 0xFF)
#define	COLOR_B(rgba)		(((rgba) >> 16) & 0xFF)
#define	COLOR_A(rgba)		(((rgba) >> 24) & 0xFF)
#define COLOR_RGB(r,g,b)	(((r) << 0)|((g) << 8)|((b) << 16))
#define COLOR_RGBA(r,g,b,a) (((r) << 0)|((g) << 8)|((b) << 16)|((a) << 24))

#define S_COLOR_BLACK	"^0"
#define S_COLOR_RED		"^1"
#define S_COLOR_GREEN	"^2"
#define S_COLOR_YELLOW	"^3"
#define S_COLOR_BLUE	"^4"
#define S_COLOR_CYAN	"^5"
#define S_COLOR_MAGENTA	"^6"
#define S_COLOR_WHITE	"^7"
#define S_COLOR_ORANGE	"^8"
#define S_COLOR_GREY	"^9"

extern vec4_t	color_table[MAX_S_COLORS];

#define DEFAULT_FONT_SMALL "bitstream_10"
#define DEFAULT_FONT_MEDIUM "bitstream_12"
#define DEFAULT_FONT_BIG "virtue_16"
#define DEFAULT_FONT_SCOREBOARD "virtue_10"

#define ALIGN_LEFT_TOP		0
#define ALIGN_CENTER_TOP	1
#define ALIGN_RIGHT_TOP		2
#define ALIGN_LEFT_MIDDLE	3
#define ALIGN_CENTER_MIDDLE	4
#define ALIGN_RIGHT_MIDDLE	5
#define ALIGN_LEFT_BOTTOM	6
#define ALIGN_CENTER_BOTTOM	7
#define ALIGN_RIGHT_BOTTOM	8

//=============================================

void Q_strncpyz( char *dest, const char *src, size_t size );
void Q_strncatz( char *dest, const char *src, size_t size );
void Q_snprintfz( char *dest, size_t size, const char *fmt, ... );
char *Q_strupr( char *s );
char *Q_strlwr( char *s );
qboolean Q_WildCmp( const char *pattern, const char *text );

//=============================================
#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
# if defined(__i386__) || defined(__ia64__) || defined(WIN32) || (defined(__alpha__) || defined(__alpha)) || defined(__arm__) || (defined(__mips__) && defined(__MIPSEL__)) || defined(__LITTLE_ENDIAN__) || defined(__x86_64__)
#  define ENDIAN_LITTLE
# else
#  define ENDIAN_BIG
# endif
#endif

short ShortSwap (short l);
int LongSwap (int l);
float FloatSwap (float f);

#ifdef ENDIAN_LITTLE
// little endian
# define BigShort(l) ShortSwap(l)
# define LittleShort(l) (l)
# define BigLong(l) LongSwap(l)
# define LittleLong(l) (l)
# define BigFloat(l) FloatSwap(l)
# define LittleFloat(l) (l)
#elif defined(ENDIAN_BIG)
// big endian
# define BigShort(l) (l)
# define LittleShort(l) ShortSwap(l)
# define BigLong(l) (l)
# define LittleLong(l) LongSwap(l)
# define BigFloat(l) (l)
# define LittleFloat(l) FloatSwap(l)
#else
// figure it out at runtime
extern short (*BigShort) (short l);
extern short (*LittleShort) (short l);
extern int (*BigLong) (int l);
extern int (*LittleLong) (int l);
extern float (*BigFloat) (float l);
extern float (*LittleFloat) (float l);
#endif

void	Swap_Init (void);

float	*tv (float x, float y, float z);
char	*vtos (vec3_t v);
char	*va(char *format, ...);

//=============================================

//
// key / value info strings
//
#define	MAX_INFO_KEY		64
#define	MAX_INFO_VALUE		64
#define	MAX_INFO_STRING		512

char *Info_ValueForKey (char *s, char *key);
void Info_RemoveKey (char *s, char *key);
void Info_SetValueForKey (char *s, char *key, char *value);
qboolean Info_Validate (char *s);

/*
==============================================================

SYSTEM SPECIFIC

==============================================================
*/

// this is only here so the functions in q_shared.c and q_math.c can link
void Sys_Error (char *error, ...);
void Com_Printf (char *msg, ...);


/*
==============================================================

FILESYSTEM

==============================================================
*/

#define FS_READ		0
#define FS_WRITE	1
#define FS_APPEND	2

#define FS_SEEK_CUR	0
#define FS_SEEK_SET	1
#define FS_SEEK_END	2

/*
==========================================================

CVARS (console variables)

==========================================================
*/

#ifndef CVAR
#define	CVAR

#define	CVAR_ARCHIVE		1	// set to cause it to be saved to vars.rc
#define	CVAR_USERINFO		2	// added to userinfo  when changed
#define	CVAR_SERVERINFO		4	// added to serverinfo when changed
#define	CVAR_NOSET			8	// don't allow change from console at all,
								// but can be set from the command line
#define	CVAR_LATCH			16	// save changes until map restart
#define	CVAR_LATCH_VIDEO	32	// save changes until video restart
#define	CVAR_CHEAT			64	// will be reset to default unless cheats are enabled
#define	CVAR_READONLY		128	// don't allow changing by user, ever

// developer cvars that shouldn't be editable in the release builds
#ifdef WSW_RELEASE
#define	CVAR_DEVELOPER		CVAR_READONLY
#else
#define	CVAR_DEVELOPER		CVAR_ARCHIVE
#endif

// nothing outside the Cvar_*() functions should modify these fields!
typedef struct cvar_s
{
	char		*name;
	char		*string;
	char		*dvalue;
	char		*latched_string;	// for CVAR_LATCH vars
	int			flags;
	qboolean	modified;	// set each time the cvar is changed
	float		value;
	int			integer;
	struct cvar_s *next;
	struct cvar_s *hash_next;
} cvar_t;

#endif		// CVAR

/*
==============================================================

COLLISION DETECTION

==============================================================
*/

// lower bits are stronger, and will eat weaker brushes completely
#define	CONTENTS_SOLID			1		// an eye is never valid in a solid
#define	CONTENTS_LAVA			8
#define	CONTENTS_SLIME			16
#define	CONTENTS_WATER			32
#define	CONTENTS_FOG			64

#define	CONTENTS_AREAPORTAL		0x8000

#define	CONTENTS_PLAYERCLIP		0x10000
#define	CONTENTS_MONSTERCLIP	0x20000

#define	CONTENTS_TELEPORTER		0x40000
#define	CONTENTS_JUMPPAD		0x80000
#define CONTENTS_CLUSTERPORTAL	0x100000
#define CONTENTS_DONOTENTER		0x200000

#define	CONTENTS_ORIGIN			0x1000000	// removed before bsping an entity

#define	CONTENTS_BODY			0x2000000	// should never be on a brush, only in game
#define	CONTENTS_CORPSE			0x4000000
#define	CONTENTS_DETAIL			0x8000000	// brushes not used for the bsp
#define	CONTENTS_STRUCTURAL		0x10000000	// brushes used for the bsp
#define	CONTENTS_TRANSLUCENT	0x20000000	// don't consume surface fragments inside
#define	CONTENTS_TRIGGER		0x40000000
#define	CONTENTS_NODROP			0x80000000	// don't leave bodies or items (death fog, lava)



#define	SURF_NODAMAGE			0x1		// never give falling damage
#define	SURF_SLICK				0x2		// effects game physics
#define	SURF_SKY				0x4		// lighting from environment map
#define	SURF_LADDER				0x8
#define	SURF_NOIMPACT			0x10	// don't make missile explosions
#define	SURF_NOMARKS			0x20	// don't leave missile marks
#define	SURF_FLESH				0x40	// make flesh sounds and effects
#define	SURF_NODRAW				0x80	// don't generate a drawsurface at all
#define	SURF_HINT				0x100	// make a primary bsp splitter
#define	SURF_SKIP				0x200	// completely ignore, allowing non-closed brushes
#define	SURF_NOLIGHTMAP			0x400	// surface doesn't need a lightmap
#define	SURF_POINTLIGHT			0x800	// generate lighting info at vertexes
#define	SURF_METALSTEPS			0x1000	// clanking footsteps
#define	SURF_NOSTEPS			0x2000	// no footstep sounds
#define	SURF_NONSOLID			0x4000	// don't collide against curves with this set
#define SURF_LIGHTFILTER		0x8000	// act as a light filter during q3map -light
#define	SURF_ALPHASHADOW		0x10000	// do per-pixel light shadow casting in q3map
#define	SURF_NODLIGHT			0x20000	// never add dynamic lights
#define SURF_DUST				0x40000 // leave a dust trail when walking on this surface



// content masks
#define	MASK_ALL				(-1)
#define	MASK_SOLID				(CONTENTS_SOLID)
#define	MASK_PLAYERSOLID		(CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY)
#define	MASK_DEADSOLID			(CONTENTS_SOLID|CONTENTS_PLAYERCLIP)
#define	MASK_MONSTERSOLID		(CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_BODY)
#define	MASK_WATER				(CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME)
#define	MASK_OPAQUE				(CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA)
#define	MASK_SHOT				(CONTENTS_SOLID|CONTENTS_BODY|CONTENTS_CORPSE)


// gi.BoxEdicts() can return a list of either solid or trigger entities
// FIXME: eliminate AREA_ distinction?
#define	AREA_SOLID		1
#define	AREA_TRIGGERS	2

// 0-2 are axial planes
#define	PLANE_X			0
#define	PLANE_Y			1
#define	PLANE_Z			2

// 3 is not axial
#define	PLANE_NONAXIAL	3

// cplane_t structure
typedef struct cplane_s
{
	vec3_t	normal;
	float	dist;
	short	type;			// for fast side tests
	short	signbits;		// signx + (signy<<1) + (signz<<1)
} cplane_t;

int SignbitsForPlane ( const cplane_t *out );
int	PlaneTypeForNormal ( const vec3_t normal );
void CategorizePlane ( cplane_t *plane );
void PlaneFromPoints ( vec3_t verts[3], cplane_t *plane );

qboolean ComparePlanes ( const vec3_t p1normal, vec_t p1dist, const vec3_t p2normal, vec_t p2dist );
void SnapVector ( vec3_t normal );
void SnapPlane ( vec3_t normal, vec_t *dist );

// a trace is returned when a box is swept through the world
typedef struct
{
	qboolean	allsolid;	// if true, plane is not valid
	qboolean	startsolid;	// if true, the initial point was in a solid area
	float		fraction;	// time completed, 1.0 = didn't hit anything
	vec3_t		endpos;		// final position
	cplane_t	plane;		// surface normal at impact
	int			surfFlags;	// surface hit
	int			contents;	// contents on other side of surface hit
	int			ent;		// not set by CM_*() functions
} trace_t;


// this structure needs to be communicated bit-accurate
// from the server to the client to guarantee that
// prediction stays in sync, so no floats are used.
// if any part of the game code modifies this struct, it
// will result in a prediction error of some degree.


enum {
//	PM_STAT_JUMPTIME,
	PM_STAT_WJCOUNT,
	PM_STAT_STUN,
	PM_STAT_KNOCKBACK,
	PM_STAT_DASHTIME,
	PM_STAT_WJTIME,
	PM_STAT_SLOW,

	PM_STAT_SIZE
};

typedef struct
{
	int			pm_type;

	int			origin[3];			// 12.3
	int			velocity[3];		// 12.3
	int			pm_flags;			// ducked, jump_held, etc
	int			pm_time;			// each unit = 8 ms
	short		stats[PM_STAT_SIZE];// Kurim : timers for knockback, stun, doublejump, walljump
	int			gravity;
	short		delta_angles[3];	// add to command angles to get view direction
									// changed by spawns, rotating objects, and teleporters
} pmove_state_t;


//
// button bits
//
#define	BUTTON_ATTACK		1
#define	BUTTON_WALK			2		// wsw : jal
#define	BUTTON_SPECIAL		4		// wsw : MiK
#define	BUTTON_USE			8
#define	BUTTON_BUSYICON		16		// wsw : jal

#define	BUTTON_ANY			128		// any key whatsoever


// usercmd_t is sent to the server each client frame
typedef struct usercmd_s
{
	qbyte	msec;
	qbyte	buttons;
	short	angles[3];
	short	forwardmove, sidemove, upmove;
	unsigned int serverTimeStamp;

} usercmd_t;


#define	MAXTOUCH	32
typedef struct
{
	// state (in / out)
	pmove_state_t	s;

	// command (in)
	usercmd_t		cmd;
	qboolean		snapinitial;	// if s has been changed outside pmove

	// results (out)
	int			numtouch;
	int			touchents[MAXTOUCH];
	qboolean	step;				// true if walked up a step

	vec3_t		viewangles;			// clamped
	float		viewheight;

	vec3_t		mins, maxs;			// bounding box size

	int			groundentity;
	int			watertype;
	int			waterlevel;

	// jal : wsw : must be set before calling pmove
	int			max_walljumps;

	// callbacks to test the world
	void		(*trace) (trace_t *tr, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
	int			(*pointcontents) (vec3_t point);
} pmove_t;


// entity_state_t->effects
// Effects are things handled on the client side (lights, particles, frame animations)
// that happen constantly on the given entity.
// An entity that has effects will be sent to the client
// even if it has a zero index model.
#define	EF_ROTATE_AND_BOB	1		// rotate and bob (bonus items)
#define EF_FREE_FOR_USE1	2
#define EF_CORPSE			4		// treat as CONTENTS_CORPSE for collision (for clients)
#define	EF_QUAD				8
#define EF_WEAPON_POWERING	16		// jalfixme: try to find a better way of sending this?
#define EF_BUSYICON			32
#define EF_ENEMY_FLAG		64		// player is carrying the enemy flag
#define EF_OUTLINE			128
// these ones can be only set from client side
#define EF_AMMOBOX			(1<<16)

// entity_state_t->renderfx flags
#define	RF_MINLIGHT			1		// always have some light (viewmodel)
#define	RF_FULLBRIGHT		2		// always draw full intensity
#define	RF_FRAMELERP		4
#define RF_SHELL_RED		8
#define	RF_SHELL_GREEN		16
#define RF_SHELL_BLUE		32
#define RF_NOSHADOW			64

// these flags are set locally by client
#define	RF_VIEWERMODEL		256		// don't draw through eyes, only mirrors
#define	RF_WEAPONMODEL		512		// only draw through eyes and depth hack
#define RF_CULLHACK			1024
#define RF_FORCENOLOD		2048

// sound channels
// channel 0 never willingly overrides
// other channels (1-7) always override a playing sound on that channel
#define	CHAN_AUTO               0
#define	CHAN_WEAPON             1
#define	CHAN_VOICE              2
#define	CHAN_ITEM               3
#define	CHAN_BODY               4
// modifier flags
#define	CHAN_NO_PHS_ADD			8	// send to all clients, not just ones in PHS (ATTN 0 will also do this)
#define	CHAN_RELIABLE			16	// send by reliable message, not datagram

// sound attenuation values
#define	ATTN_NONE               0	// full volume the entire level
#define	ATTN_NORM               1
#define	ATTN_IDLE               2
#define	ATTN_STATIC             3	// diminish very rapidly with distance

typedef enum
{
	key_game, 
	key_console, 
	key_message, 
	key_menu
} keydest_t;

/*
==========================================================

  ELEMENTS COMMUNICATED ACROSS THE NET

==========================================================
*/

// note that Q_rint was causing problems here
// (spawn looking straight up\down at delta_angles wrapping)

#define	ANGLE2SHORT(x)	((int)((x)*65536/360) & 65535)
#define	SHORT2ANGLE(x)	((x)*(360.0/65536))

#define	ANGLE2BYTE(x)	((int)((x)*256/360) & 255)
#define	BYTE2ANGLE(x)	((x)*(360.0/256))

#define MAX_GAMECOMMANDS	64	// wsw : jal : gamecommandscompletion. Strings with command names for command completion
#define MAX_LOCATIONS		64
//
// config strings are a general means of communication from
// the server to all connected clients.
// Each config string can be at most MAX_QPATH characters.
//
#define	CS_MESSAGE			0
#define	CS_MAPNAME			1
#define	CS_AUDIOTRACK		2
#define CS_HOSTNAME			3
#define CS_SERVERSETTINGS	4

#define	CS_MAXCLIENTS		30
#define	CS_MAPCHECKSUM		31		// for catching cheater maps

//precache stuff begins here
#define	CS_MODELS			32
#define	CS_SOUNDS			(CS_MODELS+MAX_MODELS)
#define	CS_IMAGES			(CS_SOUNDS+MAX_SOUNDS)
#define	CS_SKINFILES		(CS_IMAGES+MAX_IMAGES)
#define	CS_LIGHTS			(CS_SKINFILES+MAX_SKINFILES)
#define	CS_ITEMS			(CS_LIGHTS+MAX_LIGHTSTYLES)
#define	CS_PLAYERINFOS		(CS_ITEMS+MAX_ITEMS)
#define CS_GAMECOMMANDS		(CS_PLAYERINFOS+MAX_CLIENTS)	// wsw : jal : gamecommandscompletion : client to game dll commands
#define CS_LOCATIONS		(CS_GAMECOMMANDS+MAX_GAMECOMMANDS)
#define CS_GENERAL			(CS_LOCATIONS+MAX_LOCATIONS)
#define	MAX_CONFIGSTRINGS	(CS_GENERAL+MAX_GENERAL)

//==============================================

// wsw : jal : masterservers cvar is shared by client and server. This ensures both have the same default string
#define	DEFAULT_MASTER_SERVERS_IPS	"dpmaster.deathmask.net ghdigital.com excalibur.nvg.ntnu.no"
#define SERVER_PINGING_TIMEOUT 500
#define DEFAULT_PLAYERMODEL	"viciious"
#define DEFAULT_PLAYERSKIN	"default"

#define DEFAULT_TEAMRED_COLOR		"255 0 0"
#define DEFAULT_TEAMBLUE_COLOR		"25 150 255"
#define DEFAULT_TEAMGREEN_COLOR		"0 255 0"
#define DEFAULT_TEAMYELLOW_COLOR	"255 220 0"


// entity_state_t->event values
// entity events are for effects that take place reletive
// to an existing entities origin.  Very network efficient.

#define EV_INVERSE		128

// entity_state_t is the information conveyed from the server
// in an update message about entities that the client will
// need to render in some way
#define SOLID_BMODEL	31	// special value for bmodel

#define ET_INVERSE		128

typedef struct entity_state_s
{
	int				number;			// edict index

	int				type;			// ET_GENERIC, ET_BEAM, etc
	qboolean		takedamage;		// is sent inside "type" as ET_INVERSE flag

	vec3_t			origin;
	vec3_t			angles;

	union
	{
		vec3_t		old_origin;		// for lerping
		vec3_t		origin2;		// ET_BEAM, ET_PORTALSURFACE, ET_EVENT specific
	};

	int				modelindex;
	union {
		int				modelindex2;
		int				bodyOwner;		// ET_PLAYER specific, for dead bodies 
	};

	union
	{
		int			frame;
		int			ownerNum;		// ET_EVENT specific
	};

	union
	{
		int			skinnum;
		int			firemode;		// for weapon events
		int			damage;			// EV_BLOOD2, EV_BLOOD_SAVED
		int			targetNum;		// ET_EVENT specific
		int			colorRGBA;		// ET_BEAM, ET_EVENT specific
	};

	int			weapon;			// WEAP_ for players, MZ2_ for monsters

	unsigned int	effects;

	union
	{
		int			renderfx;
		int			eventCount;		// ET_EVENT specific
		//int			ownerNum2;		// for bodies
	};

	int				solid;			// for client side prediction, 8*(bits 0-4) is x/y radius
									// 8*(bits 5-9) is z down distance, 8(bits10-15) is z up
									// trap_LinkEntity sets this properly
	int				sound;			// for looping sounds, to guarantee shutoff

	int				events[2];		// impulse events -- muzzle flashes, footsteps, etc
									// events only go out for a single frame, they
									// are automatically cleared each frame
	int				eventParms[2];

	int				light;			// constant light glow

	int				team;			// team in the game	
} entity_state_t;

//==============================================

typedef enum
{
	CA_UNINITIALIZED,
	CA_DISCONNECTED, 	// not talking to a server
	CA_CONNECTING,		// sending request packets to the server
	CA_CONNECTED,		// netchan_t established, waiting for svc_serverdata
	CA_LOADING,
	CA_ACTIVE			// game views should be displayed
} connstate_t;

enum
{
	DROP_TYPE_GENERAL,
	DROP_TYPE_PASSWORD,
	DROP_TYPE_NORECONNECT,
	DROP_TYPE_TOTAL
};

#define DROP_FLAG_AUTORECONNECT 1 // it's okay try reconnectting automatically

//==============================================

typedef struct
{
	int			state;

	unsigned int	clock_msecs;
	unsigned int	clock_secs;
	unsigned int	clock_mins;

	unsigned int	timelimit;

	qboolean		extendedtime;
} match_state_t;

//==============================================

// player_state_t is the information needed in addition to pmove_state_t
// to rendered a view.  There will only be 10 player_state_t sent each second,
// but the number of pmove_state_t changes will be relative to client
// frame rates
#define	PS_MAX_STATS	32
#define MAX_WEAPLIST_STATS 16	// short

typedef struct
{
	pmove_state_t	pmove;		// for prediction

	// these fields do not need to be communicated bit-precise

	vec3_t			viewangles;		// for fixed views

	unsigned int	event;
	unsigned int	POVnum;			// entity number of the player in POV
	float			viewheight;
	float			fov;			// horizontal field of view
	unsigned int	weaponlist[MAX_WEAPLIST_STATS][3];
	short			stats[PS_MAX_STATS];		// fast status bar updates
} player_state_t;


