// Copyright 1994 Brad Pitzel
//
// Feel free to use/distribute/modify as long as credit/copyrights for myself 
// are included.

#ifndef __FastMath__
#define __FastMath__



#define FP_MULT	1024	// scale factor for fixed <-> int conversion
#define FP_S    10	// binary shift for above factor
#define FP_SH   5	// half of above

typedef int FixedPoint;

// conversion routines
#define INT2FP(x)		( (FixedPoint)((x)<<FP_S) )
#define FLOAT2FP(x)	((int)((x)*(double)FP_MULT))

#define FP2INT(x)		( (FixedPoint)((x)>>FP_S) )
#define FP2FLOAT(x)	( ((double)x) / FP_MULT )

// macro to multiply 2 fixedpoint numbers
#define FPMULT(x,y) ( ((x)>>FP_SH) * ((y)>>FP_SH) )

// macro to divide 2 fixed point #'s
#define FPDIV(x,y) ( ((x)<<FP_SH) / ((y)>>FP_SH) )


// Size of trig table - should be power of 2
#define TRIGSIZE 256

// change char to match size of trig table (but always use 'unsigned' )
typedef unsigned char Angle;

// make no bigger than 255*255 (sqrt table returns 'char' type)
#define SQRTSIZE 10000

#define ABS(x) ( (x)<0 ? -(x) : (x) )

class FastMath {
    public:

	static double cos(Angle d) 
			{ 
			return Vcos[d];
			}
	static double sin(Angle d) 
			{
			return Vsin[d];
			}
	inline static FixedPoint Fcos(Angle d) 
			{ 
			return VFcos[d];
			}
	inline static FixedPoint Fsin(Angle d) 
			{
			return VFsin[d];
			}
	static void   init(int verbose=0); //verbose=1, send stuff to stdout

	static int    intSqrt(int d)
			{
			return (d>=SQRTSIZE) ? VintSqrt[SQRTSIZE-1] : VintSqrt[d];
			}

    private:
    	static double Vcos[TRIGSIZE+1], Vsin[TRIGSIZE+1];
    	static FixedPoint    VFcos[TRIGSIZE+1], VFsin[TRIGSIZE+1];

    	static unsigned char VintSqrt[SQRTSIZE];
 
    };

#endif
