/************************************************************************************
 *			In Here you will find amongst other stuff
 *			3D system global variable definitions
 ************************************************************************************/
#ifndef PSX_3D_H
#define PSX_3D_H

//#define HIRES_FRIG			// Define to enable dude's 512 wide muckabout...

enum {TP_4BIT,TP_8BIT,TP_16BIT};
enum {ABR_HALF,ABR_ADD,ABR_SUB,ABR_QUARTER,ABR_DONTCARE=0};

#define MAX_MATRICES	50					// maximum matrices in stack...
#define W2V_SHIFT 		14					// Shift scale of View.Frame to World.Frame
#define	W2V_SCALE 		(1<<W2V_SHIFT)		//  Scale of View Frame to World Frame

#define MAX_OBJECT_VERTICES	256

#define ABS(x) ((x)<0 ? (-(x)):(x))
#define MIN(x,y) ((x)<=(y) ? (x):(y))
#define MAX(x,y) ((x)>=(y) ? (x):(y))

#define	TRIGMULT2(A, B)		( ( (A)*(B) ) >> W2V_SHIFT )
#define	TRIGMULT3(A, B, C)	( TRIGMULT2((TRIGMULT2(A, B)), C ))

#define MAKE_RGB(r,g,b) ((r)|((g)<<8)|((b)<<16))

enum msoff { M00,M01,M02,M03,
			 M10,M11,M12,M13,
			 M20,M21,M22,M23 };


//****************************************************************************
#define SHADE_SHIFT			5                          // Corresponds to Depth Cue of 8 Blocks
#define DPQ_LENGTH			(256<<SHADE_SHIFT)
#define DPQ_END				(20*1024)
#define DPQ_START			(DPQ_END - DPQ_LENGTH)

#define WIBBLE_SIZE	64
#define MAX_WIBBLE	2
#define MAX_SHADE	24



//******************* 3D System Constant Defines ******************************
#define phd_viewdist	DPQ_END
#define phd_zfar		(phd_viewdist<<W2V_SHIFT)
#define phd_znear       (20<<W2V_SHIFT)

#define phd_scrheight	MY_PSX_H
#define phd_winheight	MY_PSX_H
#define phd_winymax		(MY_PSX_H-1)
#define phd_centery		(MY_PSX_H/2)


/*****************************************************************************
 *					Structures And Unions
 ****************************************************************************/
typedef	struct	phd_vector {
			sint32	x;
			sint32	y;
			sint32	z;
}PHD_VECTOR;

typedef	sint16	PHD_ANGLE;


typedef struct	phd_3dpos {
			sint32 		x_pos;
			sint32 		y_pos;
			sint32		z_pos;
			PHD_ANGLE	x_rot;
			PHD_ANGLE	y_rot;
			PHD_ANGLE	z_rot;
}PHD_3DPOS;

typedef	struct	phd_light {
	PHD_3DPOS	pos;
	sint32		ambient;             // Ambient Light Level
	sint32		intensity;           // 0-16384 inclusive
	sint32		fodist;              // distance squared of fall off
}PHD_LIGHT;


typedef struct psxspritestruct {			// Sprite Information Structure...
		sint16			x1,y1,x2,y2;
		uint16			clut,tpage;
		uint8			u1,v1,u2,v2;
} PSXSPRITESTRUCT;


typedef struct psxtextstruct {
		uint32		 	u0v0clut;			// Cunningly packed structure!!!
		uint32		   	u1v1tpage;          // Which Allows Me to grab
		uint32   		u2v2pad;            // U and Vs and clut and tpage
		uint32   		u3v3pad;            // IDs in easy go!!
} PSXTEXTSTRUCT;

typedef struct psxtexti {
		uint8			u0,v0;				// Structure to Allow
		uint16			clut;               // insertion of Approp Bits..
		uint8			u1,v1;				// and extraction...
		uint16			tpage;
		uint8			u2,v2;
		uint8			codeGT4,codeGT3;
//		uint16			pad2;
		uint8			u3,v3;
		uint16			pad3;
} PSXTEXTI;


typedef struct phd_ft3 {
		uint32			tag;					// Structures Of PSX Polygon structures
		uint8			r0,g0,b0,code;          // Rearranged to allow easy insert of data
		sint16			x0,y0;
		uint32			u0v0clut;
		sint16			x1,y1;
		uint32			u1v1tpage;
		sint16			x2,y2;
		uint32			u2v2pad;
} PHD_FT3;

typedef struct phd_ft4 {
		uint32			tag;
		uint8			r0,g0,b0,code;
		sint16			x0,y0;
		uint32			u0v0clut;
		sint16			x1,y1;
		uint32			u1v1tpage;
		sint16			x2,y2;
		uint32			u2v2pad;
		sint16			x3,y3;
		uint32			u3v3pad;
} PHD_FT4;

typedef struct phd_gt3 {						// Gouraud Shaded
		uint32			*tag;					// Texture Structure
		uint8			r0,g0,b0,code;
		sint32			xy0;
		uint32			u0v0clut;
		uint8   		r1,g1,b1,pad1;
		sint32			xy1;
		uint32			u1v1tpage;
		uint8			r2,g2,b2,pad2;
		sint32			xy2;
		uint32			u2v2pad;
} PHD_GT3;

typedef struct phd_gt4 {						// Gouraud shaded room
		uint32			*tag;					// Texture Structure
		uint8			r0,g0,b0,code;
		sint32			xy0;
		uint32			u0v0clut;
		uint8   		r1,g1,b1,pad1;
		sint32			xy1;
		uint32			u1v1tpage;
		uint8			r2,g2,b2,pad2;
		sint32			xy2;
		uint32			u2v2pad;
		uint8			r3,g3,b3,pad3;
		sint32			xy3;
		uint32			u3v3pad;
} PHD_GT4;


#define phd_PopMatrix()		phd_mxptr -= 12

/******************************************************************************
 *						3D Variables
 *****************************************************************************/

extern	int emap_flag;				// Enable Environment mapping!!
extern	uint32 emap_tint;			// What colour to tint the envmapping!!!
extern	uint32 dude_envmap_tpage;	// The tpage of the environment map!!!

extern	sint32 ls_adder;  			// Light Source Thingys
extern	sint32 ls_divider;

extern	sint32 phd_left;
extern	sint32 phd_right;			// Clipping Values For
extern	sint32 phd_top;
extern	sint32 phd_bottom;

extern	sint32 phd_winxmax;		// max X coord of window
extern	sint32 phd_winwidth;	// Width of Window
extern	sint32 phd_centerx;		// XCenter of Window
extern	sint32 phd_scrwidth;	// Width of Screen In Pixels

//extern	sint32 phd_winymax;		// max Y coord of window
//extern	sint32 phd_winheight;	// Height of Window
//extern	sint32 phd_centery;		// YCenter of Window
//extern	sint32 phd_znear;		// Minimum Z coord in View Frame
//extern	sint32 phd_zfar;		// Maximum Z coord in View Frame
//extern	sint32 phd_viewdist;	// Maximum View distance in World Frame
extern	sint32 phd_persp;			// Perspective Scale Factor
extern	sint32* phd_mxptr;			// Pointer to Current Matrix

extern	sint32 w2v_matrix[];		// World to View Matrix...
extern	sint32 matrix_stack[];		// matrix stack for animations etc..

extern	PHD_VECTOR	ls_vector_view;
extern	PHD_ANGLE	phd_ls_yaw,phd_ls_pitch;

extern	PSXTEXTSTRUCT	*psxtextinfo;  		// Texture information
extern	PSXSPRITESTRUCT	*psxspriteinfo;     // Sprite information

#endif
