/********************************************************************************
	math.h: Ultra 64 MARIO Brothers include file

	Copyright (c) 1996 Nintendo co., ltd.  All rights reserved

	February 19, 1996
 ********************************************************************************/

#ifndef MATH_H
#define	MATH_H

#define	COORD_X		0
#define	COORD_Y		1
#define	COORD_Z		2

#define	_AX			0
#define	_AY			1
#define	_AZ			2


#define	roundf(val)		(int)(val+(((val)>0.0f)?0.5f:-0.5f))
#define absf(val)		(((val)>0.0f)?(val):-(val))
#define fixed(val)		((long)((val)*65536.0f))


#define	cvangle(ang)		((float)(ang)*M_PI/32768.0f)
#define	radianf(rad)		(short)((float)(rad)*32768.0f/M_PI+0.5f)
#define	degreef(deg)		(short)((float)(deg)*32768.0f/180.0f+0.5f)
#define	degreei(deg)		(short)((int)(deg)*32768L/180L)


#define	sin(angle)			sintable[((ushort)(angle)) >> 4]
#define	cos(angle)			costable[((ushort)(angle)) >> 4]


typedef	float RotateMtx[3][3];			/* 3x3 rotation matrix					*/
typedef float AffineMtx[4][4];			/* 4x4 affine transformation matrix		*/

typedef struct {
	short	integer[4][4];
	short	fraction[4][4];
} RCPMatrix;

typedef struct {
	short	time;
	short	posx;
	short	posy;
	short	posz;
} BSplineRecord, *BSplinePtr;

typedef short SVector[3];				/* 3D short vector						*/
typedef float FVector[3];				/* 3D float vector						*/

/********************************************************************************
 *
 *	External works
 *
 ********************************************************************************/

extern float sintable[4096];		/* sin table								*/
extern float costable[4096];		/* cos table								*/
extern short atntable[1024];		/* arc tan table							*/


extern Mtx	   fixedIdentMatrix;	/* identity matrix (fixed point value)		*/
extern FVector zeroFVector;			/* 3D float vector (0, 0, 0)				*/
extern SVector zeroSVector;			/* 3D short vector (0, 0, 0)				*/
extern FVector unitFVector;			/* 3D float vector (1, 1, 1)				*/
extern SVector unitSVector;			/* 3D short vector (1, 1, 1)				*/

/********************************************************************************
 *
 *	Function prototypes
 *
 ********************************************************************************/


/* floating point vector oparations */

extern FVector
*SetFVector(FVector vector, float vecx, float vecy, float vecz);

extern FVector
*CopyFVector(FVector desvec, FVector souvec);

extern FVector
*AddFVector(FVector desvec, FVector souvec);

extern FVector
*AddToFVector(FVector desvec, FVector souvec1, FVector souvec2);

extern FVector *
CalcNormalVector(FVector normal, FVector pos1, FVector pos2, FVector pos3);

extern FVector *
CrossProduct(FVector cross, FVector vec1, FVector vec2);

extern FVector *
NormalizeFVector(FVector vec);


/* short interger vector oparations */

extern SVector
*SetSVector(SVector vector, short vecx, short vecy, short vecz);

extern SVector
*CopySVector(SVector desvec, SVector souvec);

extern SVector
*AddSVector(SVector desvec, SVector souvec);

extern SVector
*AddToSVector(SVector desvec, SVector souvec1, SVector souvec2);

extern SVector
*SubSVector(SVector desvec, SVector souvec);


/* vector convertion */

extern FVector *
SVectorToFVector(FVector fvec, SVector svec);

extern SVector *
FVectorToSVector(SVector svec, FVector fvec);



/* matrix oparations */

extern void
CopyAffineMtx(AffineMtx desmat, AffineMtx soumat);

extern void
LoadIdentAffineMtx(AffineMtx mtx);

extern void
CreateTransAffineMtx(AffineMtx matrix, FVector position);

extern void
LookAtAffineMtx(AffineMtx mtx, FVector eye, FVector look, short bank);

#if 0
extern void
CreateCameraAffineMtx(AffineMtx matrix, SVector position, SVector angle);
#endif

extern void
CreateModelAffineMtx(AffineMtx mtx, FVector position, SVector angle);

extern void
CreateJointAffineMtx(AffineMtx matrix, FVector position, SVector angle);

extern void
CreateBboardAffineMtx(AffineMtx mat, AffineMtx cam, FVector position, short bank);

extern void
CreateRotationAffineMtx(AffineMtx matrix, FVector vectorY, FVector position, short angle);

extern void
CreatePostureAffineMtx(AffineMtx matrix, FVector position, short angle, float radius);

extern void
MultAffineMtx(AffineMtx mtx, AffineMtx ma, AffineMtx mb);

extern void
ScaleAffineMtx(AffineMtx desmtx, AffineMtx soumtx, FVector scale);

extern void
RotatePoint(AffineMtx mtx, SVector point);

extern void
AffineToMtx(Mtx *matrix, AffineMtx affine);

extern void
CreateBankMatrix(Mtx *matrix, short bank);

extern void
CalcGlobalPosition(FVector position, AffineMtx mat, AffineMtx cam);




extern void
CrossToPolar(FVector center, FVector point, float *dist, short *angx, short *angy);

extern void
PolarToCross(FVector center, FVector point, float dist, short angx, short angy);


extern int
IConverge(int value, int target, int add, int sub);

extern float
FConverge(float value, float target, float add, float sub);


/* mathematic oparations */

extern short
atan(float x, float y);

extern float
atanf(float x, float y);

extern void
StartBSpline(BSplinePtr data);

extern int
RunBSpline(FVector position);

#endif
