#define DEG90  16384
#define DEG180 32768
#define DEG270 49152
#define DEG360 65536


#ifndef __TORNADO
#define __TORNADO
typedef struct {
	int cx,cy,mag,cpz,lx,ly;
} PROJ;

typedef struct {
	int x,y,z;
} IPOINT;

typedef struct {
	int h,p,b;
} IANGLE;

typedef struct {
	IPOINT p;
	IANGLE a;
} IPNTANG;

typedef struct {
	int sh,ch,sp,cp,sb,cb;
} ITRIGON;


typedef struct {
	int x,y;
} IPOINT2;    /* 2D */

typedef struct {
	int s,c;
} ITRIGON2;   /* 2D */



typedef int 
	fix;      /* Fixed Point */
#endif



/* Basic Functions 一般整数型関数 */
#define DegToAng(deg) (deg)*16384/90
#define AngToDeg(ang) (ang)*90/16384

#define SetIangleByDeg(a,hh,pp,bb)  \
{                                   \
	(a)->h = DegToAng(hh);          \
	(a)->p = DegToAng(pp);          \
	(a)->b = DegToAng(bb);          \
}

#define SetIpoint(p,xx,yy,zz) {((p)->x)=(xx);((p)->y)=(yy);((p)->z)=(zz);}
#define SetIangle(a,hh,pp,bb) {((a)->h)=(hh);((a)->p)=(pp);((a)->b)=(bb);}

#define AddIpoint(d,s,v) \
	{((d)->x) = ((s)->x)+((v)->x);\
	 ((d)->y) = ((s)->y)+((v)->y);\
	 ((d)->z) = ((s)->z)+((v)->z);}

#define SubIpoint(d,s,v) \
	{((d)->x) = ((s)->x)-((v)->x);\
	 ((d)->y) = ((s)->y)-((v)->y);\
	 ((d)->z) = ((s)->z)-((v)->z);}

#define MulIpoint(d,s,m) \
	{((d)->x) = ((s)->x)*(m);\
	 ((d)->y) = ((s)->y)*(m);\
	 ((d)->z) = ((s)->z)*(m);}

#define DivIpoint(d,s,v) \
	{((d)->x) = ((s)->x)/(v);\
	 ((d)->y) = ((s)->y)/(v);\
	 ((d)->z) = ((s)->z)/(v);}

#define MakeItrigonomy(trg,ang) \
	{((trg)->sh) = FxSinHq((ang)->h);\
	 ((trg)->ch) = FxCosHq((ang)->h);\
	 ((trg)->sp) = FxSinHq((ang)->p);\
	 ((trg)->cp) = FxCosHq((ang)->p);\
	 ((trg)->sb) = FxSinHq((ang)->b);\
	 ((trg)->cb) = FxCosHq((ang)->b);}

#define MakeItrigonomy2(trg,ang) \
	{((trg)->s) = FxSinHq(ang);\
	 ((trg)->c) = FxCosHq(ang);}\


int MulSin(int val,int ang);
int MulCos(int val,int ang);
int MulTan(int val,int ang);

int MulSinHq(int val,int ang);
int MulCosHq(int val,int ang);
int MulTanHq(int val,int ang);

int InnerSgn(IPOINT *,IPOINT *);

void Rot2(int *x,int *y,int ang);
void Rot2Hq(int *x,int *y,int ang);
void Rot2Fast(int *x,int *y,ITRIGON2 *trg);

void RotGtoL(int n,IPOINT *d,IPOINT *s,IANGLE *ang);
void RotGtoLHq(int n,IPOINT *d,IPOINT *s,IANGLE *ang);
void RotGtoLFast(int n,IPOINT *d,IPOINT *s,ITRIGON *trg);
void RotLtoG(int n,IPOINT *d,IPOINT *s,IANGLE *ang);
void RotLtoGHq(int n,IPOINT *d,IPOINT *s,IANGLE *ang);
void RotLtoGFast(int n,IPOINT *d,IPOINT *s,ITRIGON *trg);
void Move3(int n,IPOINT *d,IPOINT *s,IPOINT *vec);

void ProjectToScreen(int n,IPOINT2 *d,IPOINT *s,PROJ *prj);


int Length2(int x,int y);
#define Length3(x,y,z) (Length2(Length2((x),(y)),(z)))

int Angle2(int,int);


int PitchUp(IANGLE *d,IANGLE *s,int d);
int YawLeft(IANGLE *d,IANGLE *s,int d);

void InterpolateAngle(IANGLE *o,IANGLE *a1,IANGLE *a2,int a,int b);
void InterpolateVector(IPOINT *o,IPOINT *v1,IPOINT *v2,int a,int b);
void AngleToVector(IPOINT *eyv,IPOINT *upv,IANGLE *ang);
void VectorToAngle(IANGLE *ang,IPOINT *eyv,IPOINT *upv);


int ClipPolyg3(int *dnp,IPOINT *d,int snp,IPOINT *s,int cpz);
	/* 戻り値  クリップ後の頂点数 ∴0ならなんも書かない */
int ClipLine3(IPOINT *d,IPOINT *s,int cpz);
	/* 戻り値  0以外なら見える  0なら見えない */





/* Primitive Functions 固定小数点型関数 */
extern fix Fx_sintbl[],Fx_costbl[],Fx_tantbl[];
extern fix Fx_asintbl[],Fx_acostbl[],Fx_atantbl[];

fix FxMul(fix,fix);
fix FxDiv(fix,fix);

fix FxSinHq(fix);
fix FxCosHq(fix);
fix FxTanHq(fix);

int FxAsin(fix);
int FxAcos(fix);
int FxAtan(fix);
