
/********************
	course.h
 ********************/

#ifndef	_course_h_
#define _course_h_


/*******************************************************************************
	DEFINE
*******************************************************************************/
#define EDIT_COURSE_SW	1

#define CRS_START_CHECKER_LENGTH	100.0f

#define CRS_DIVISION_EDITOR	0
#define CRS_DIVISION_RACE1	1
#define CRS_DIVISION_RACE2	2

/***********************************************
	BUFFER SIZE
***********************************************/
#define CRS_MAX		56		/* how many course */
#define CRS_TIMES	5		/* how many best time in one course */
#define CRS_POINT_MAX	64		/* how many CrsPoint in one course */
#define CRS_VERTEXES	1024		/* hoe many CrsVertex in one course */

/***********************************************
	TEXTURE SIZE
***********************************************/
#define CRS_TWX1	128
#define CRS_TWX1_S	7
#define CRS_TWY1	16
#define CRS_TWY1_S	4

#define CRS_TWY3	8
#define CRS_TWY3_S	3

#define CRS_TWX2	64
#define CRS_TWX2_S	6
#define CRS_TWY2	32
#define CRS_TWY2_S	5

/***********************************************
	TEXTURE TILE
***********************************************/
#define CRS_LOAD_TILE_128_16	0
#define CRS_RENDER_TILE_128_16	1
#define CRS_RENDER_TILE_128_8_a	2
#define CRS_RENDER_TILE_128_8_b	3
#define CRS_LOAD_TILE_64_32	4
#define CRS_RENDER_TILE_64_32	5
#define CRS_RENDER_TILE_64_16_a	6
#define CRS_RENDER_TILE_64_16_b	7

/***********************************************
	COURSE TEXTURE
***********************************************/
#define ROAD_TYPES			7
#define CRS_TEX_START_GRID		0x00000000
#define CRS_TEX_START_CHECKER		0x00000001
#define CRS_TEX_ROAD_01			0x00000002
#define CRS_TEX_ROAD_02			0x00000003
#define CRS_TEX_ROAD_03			0x00000004
#define CRS_TEX_ROAD_04			0x00000005
#define CRS_TEX_ROAD_05			0x00000006

#define HIROAD_TYPES			3
#define CRS_TEX_HIROAD_01		0x00000000
#define CRS_TEX_HIROAD_02		0x00000001
#define CRS_TEX_HIROAD_03		0x00000002

#define TUBE_TYPES			4
#define CRS_TEX_TUBE_01			0x00000000
#define CRS_TEX_TUBE_02			0x00000001
#define CRS_TEX_TUBE_03			0x00000002
#define CRS_TEX_TUBE_04			0x00000003

#define WIRE_TYPES			4
#define CRS_TEX_WIRE_01			0x00000000
#define CRS_TEX_WIRE_02			0x00000001
#define CRS_TEX_WIRE_03			0x00000002
#define CRS_TEX_WIRE_04			0x00000003

#define HALF_TYPES			4
#define CRS_TEX_HALF_01			0x00000000
#define CRS_TEX_HALF_02			0x00000001
#define CRS_TEX_HALF_03			0x00000002
#define CRS_TEX_HALF_04			0x00000003

#define TUNNEL_TYPES			4
#define CRS_TEX_TUNNEL_01		0x00000000
#define CRS_TEX_TUNNEL_02		0x00000001
#define CRS_TEX_TUNNEL_03		0x00000002
#define CRS_TEX_TUNNEL_04		0x00000003

#define RIBBON_TYPES			3
#define CRS_TEX_RIBBON_01		0x00000000
#define CRS_TEX_RIBBON_02		0x00000001
#define CRS_TEX_RIBBON_03		0x00000002

#define CRS_TEX_NONE			0x0000003F

#define CRS_TEX_MASK			0x0000003F

/***********************************************
	COURSE SHAPE
***********************************************/
#define CRS_SHAPE_ROAD			0x00000000
#define CRS_SHAPE_HIROAD		0x00000040
#define CRS_SHAPE_TUBE			0x00000080
#define CRS_SHAPE_WIRE			0x000000C0
#define CRS_SHAPE_HALF			0x00000100
#define CRS_SHAPE_TUNNEL		0x00000140
#define CRS_SHAPE_AIR			0x00000180
#define CRS_SHAPE_RIBBON		0x000001C0

#define CRS_SHAPE_MASK			0x000001C0

#define CRS_SHAPE_SHIFT			6		/* No. = (X & MASK) >> SHIFT */

/***********************************************
	COURSE JOINT
***********************************************/
#define CRS_JOINT_1			0x00000200
#define CRS_JOINT_2			0x00000400
#define CRS_JOINT_MASK			0x00000600

#define CRS_TRANSFORM_START_1		0x00000800	/* for CrsVertex only */
#define CRS_TRANSFORM_START_2		0x00001000	/* for CrsVertex only */
#define CRS_TRANSFORM_START_MASK	0x00001800

#define CRS_TRANSFORM_END_1		0x00002000	/* for CrsVertex only */
#define CRS_TRANSFORM_END_2		0x00004000	/* for CrsVertex only */
#define CRS_TRANSFORM_END_MASK		0x00006000

/***********************************************
	COURSE FORM
***********************************************/
#define CRS_FORM_ETC			0x00000000
#define CRS_FORM_STRAIGHT		0x00008000
#define CRS_FORM_CURVE_L		0x00010000
#define CRS_FORM_CURVE_R		0x00018000
#define CRS_FORM_S_L			0x00020000
#define CRS_FORM_S_R			0x00028000

#define CRS_FORM_MASK			0x00038000

/***********************************************
	COURSE FLAGS
***********************************************/
#define CRS_FLAG_AI_ROAD		0x08000000
#define CRS_FLAG_JOINT_OK		0x10000000
#define CRS_FLAG_INNER			0x20000000
#define CRS_FLAG_CONTINUE		0x40000000
#define CRS_FLAG_TPRESET		0x80000000	/* for CrsVertex only */

/***********************************************
	COURSE TYPE
***********************************************/
#define CRS_TYPE_START_GRID		(CRS_TEX_START_GRID   |CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_START_CHECKER		(CRS_TEX_START_CHECKER|CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_ROAD_01		(CRS_TEX_ROAD_01|CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_ROAD_02		(CRS_TEX_ROAD_02|CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_ROAD_03		(CRS_TEX_ROAD_03|CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_ROAD_04		(CRS_TEX_ROAD_04|CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_ROAD_05		(CRS_TEX_ROAD_05|CRS_SHAPE_ROAD|CRS_FLAG_JOINT_OK|CRS_FLAG_AI_ROAD)

#define CRS_TYPE_HIROAD_01		(CRS_TEX_HIROAD_01|CRS_SHAPE_HIROAD|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_HIROAD_02		(CRS_TEX_HIROAD_02|CRS_SHAPE_HIROAD|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_HIROAD_03		(CRS_TEX_HIROAD_03|CRS_SHAPE_HIROAD|CRS_FLAG_AI_ROAD)

#define CRS_TYPE_TUBE_01		(CRS_TEX_TUBE_01|CRS_SHAPE_TUBE|CRS_FLAG_INNER)
#define CRS_TYPE_TUBE_02		(CRS_TEX_TUBE_02|CRS_SHAPE_TUBE|CRS_FLAG_INNER)
#define CRS_TYPE_TUBE_03		(CRS_TEX_TUBE_03|CRS_SHAPE_TUBE|CRS_FLAG_INNER)
#define CRS_TYPE_TUBE_04		(CRS_TEX_TUBE_04|CRS_SHAPE_TUBE|CRS_FLAG_INNER)

#define CRS_TYPE_WIRE_01		(CRS_TEX_WIRE_01|CRS_SHAPE_WIRE)
#define CRS_TYPE_WIRE_02		(CRS_TEX_WIRE_02|CRS_SHAPE_WIRE)
#define CRS_TYPE_WIRE_03		(CRS_TEX_WIRE_03|CRS_SHAPE_WIRE)
#define CRS_TYPE_WIRE_04		(CRS_TEX_WIRE_04|CRS_SHAPE_WIRE)

#define CRS_TYPE_HALF_01		(CRS_TEX_HALF_01|CRS_SHAPE_HALF)
#define CRS_TYPE_HALF_02		(CRS_TEX_HALF_02|CRS_SHAPE_HALF)
#define CRS_TYPE_HALF_03		(CRS_TEX_HALF_03|CRS_SHAPE_HALF)
#define CRS_TYPE_HALF_04		(CRS_TEX_HALF_04|CRS_SHAPE_HALF)

#define CRS_TYPE_TUNNEL_01		(CRS_TEX_TUNNEL_01|CRS_SHAPE_TUNNEL|CRS_FLAG_INNER|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_TUNNEL_02		(CRS_TEX_TUNNEL_02|CRS_SHAPE_TUNNEL|CRS_FLAG_INNER|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_TUNNEL_03		(CRS_TEX_TUNNEL_03|CRS_SHAPE_TUNNEL|CRS_FLAG_INNER|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_TUNNEL_04		(CRS_TEX_TUNNEL_04|CRS_SHAPE_TUNNEL|CRS_FLAG_INNER|CRS_FLAG_AI_ROAD)

#define CRS_TYPE_AIR			(CRS_TEX_NONE|CRS_SHAPE_AIR|CRS_FLAG_JOINT_OK)

#define CRS_TYPE_RIBBON_01		(CRS_TEX_RIBBON_01|CRS_SHAPE_RIBBON|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_RIBBON_02		(CRS_TEX_RIBBON_02|CRS_SHAPE_RIBBON|CRS_FLAG_AI_ROAD)
#define CRS_TYPE_RIBBON_03		(CRS_TEX_RIBBON_03|CRS_SHAPE_RIBBON|CRS_FLAG_AI_ROAD)


/***********************************************
	ERROR FLAG
***********************************************/
#define CRS_ERR_POLYGON_OVERLAP		0x00010000
#define CRS_ERR_VTX_BUF_OVER		0x00020000
#define CRS_ERR_NO_JOINT_LENGTH		0x00040000
#define CRS_ERR_TYPE_MASK		0xFFFF0000
#define CRS_ERR_DATA_MASK		0x0000FFFF

/***********************************************
	COURSE GADGET
***********************************************/
#define CRS_GADGET_PIT		1
#define CRS_GADGET_DIRT		2
#define CRS_GADGET_DASH		3
#define CRS_GADGET_SLIP		4


/*******************************************************************************
	TYPEDEF
*******************************************************************************/
typedef struct {
	uint		type ;

	int		crs_pi ;
	float		crs_u ;

	float		z ;
	int		zvec ;

	Fxyz		center ;

	short		cx0 ;
	short		cy0 ;
	short		cz0 ;
	short		cx1 ;
	short		cy1 ;
	short		cz1 ;

	short		lx0 ;
	short		ly0 ;
	short		lz0 ;
	short		lx1 ;
	short		ly1 ;
	short		lz1 ;
	short		lx2 ;
	short		ly2 ;
	short		lz2 ;

	short		rx0 ;
	short		ry0 ;
	short		rz0 ;
	short		rx1 ;
	short		ry1 ;
	short		rz1 ;
	short		rx2 ;
	short		ry2 ;
	short		rz2 ;

	short		ut ;
	short		dt ;
	short		lt ;
	short		rt ;

	short		ut_r ;
	short		dt_r ;
	short		lt_r ;
	short		rt_r ;
} CrsVertex ;


typedef struct {
	Fxyz		pos ;
	Direction	dir ;
	Fxyz		width ;
	CrsVertex	*near_cv ;
} Jumpdai ;


typedef struct {
	int		status ;
	Fxyz		pos ;
	CrsVertex	*near_cv ;
} Landmine ;


typedef struct {
	int		type ;
	float		u1 ;
	float		u2 ;
	Fxyz		r1 ;
	Fxyz		r2 ;
	CrsVertex	*near_cv ;
} CrsGadget ;


typedef struct {
	float		x1 ;
	float		z1 ;
	float		x2 ;
	float		z2 ;
} CrsBlock ;


struct CrsPoint_ {
	Fxyz			pos ;
	Fxyz			uvec ;

	float			radiusL ;	/* wire:in   half:r    */
	float			radiusR ;	/* wire:out  half:high */
	uint			type ;

	float			tension ;
	float			section_dist ;
	float			total_dist ;

	int			number ;
	struct CrsPoint_	*next_pt ;
	struct CrsPoint_	*back_pt ;

	CrsVertex		*cv_start ;
	CrsVertex		*cv_end ;

	Jumpdai			*jump_start ;
	Jumpdai			*jump_end ;

	Landmine		*mine_start ;
	Landmine		*mine_end ;

	CrsGadget		*gadget_start ;
	CrsGadget		*gadget_end ;

	CrsBlock		*block_start ;
	CrsBlock		*block_end ;

	float			winding ;	/* 1(straight) => -1(curve) */

	float			joint_u1 ;
	float			joint_u2 ;
	float			joint_d ;

	Fxyz			d_pos[3] ;
	float			d_length[3] ;
} ;
typedef struct CrsPoint_ 	CrsPoint ;


typedef struct {
	uchar		name ;
	uchar		edit_flag ;

	uchar		body_shape ;
	uchar		engine_shape ;
	uchar		wing_shape ;

	uchar		mark_type ;
	uchar		number_type ;
	uchar		line_type ;

	uchar		body_color_r ;
	uchar		body_color_g ;
	uchar		body_color_b ;
	uchar		number_color_r ;
	uchar		number_color_g ;
	uchar		number_color_b ;
	uchar		line_color_r ;
	uchar		line_color_g ;
	uchar		line_color_b ;
	uchar		glass_color_r ;
	uchar		glass_color_g ;
	uchar		glass_color_b ;
} RankingMachine ;


typedef struct {
	int		id ;

	int		number ;
	int		points ;
	float		distance ;
	CrsPoint	*point ;

	short		road_fogR ;
	short		road_fogG ;
	short		road_fogB ;

	short		hilightR ;
	short		hilightG ;
	short		hilightB ;

	int		best_time[CRS_TIMES] ;
	RankingMachine	best_time_machine[CRS_TIMES] ;
	float		best_time_setting[CRS_TIMES] ;
	uchar		best_time_player[CRS_TIMES][4] ;

	float		max_speed ;
	RankingMachine	max_speed_machine ;

	int		best_lap ;
	RankingMachine	best_lap_machine ;
} Course ;


typedef struct {
	CrsPoint	*pt ;
	float		u ;		/* 0 <= a <= 1 */
	float		d ;		/* 0 <= a <= 1 (use distance) */
	Fxyz		vec ;
	float		vlength ;

	Fxyz		center ;
	Fxyz		ofs ;
	Fxyz		pos ;
	float		ofs_ln ;
	Fxyz		exact_pos ;
} CrsPos ;


typedef struct {
	ushort		*texture ;

	float		scale ;

	int		sizeX ;

	int		load_tile ;
	int		render_tile ;

	short		cal_tpos_mask ;

	short		ts[5] ;
} CrsTex ;


/*******************************************************************************
	VARIABLE
*******************************************************************************/
extern Course		course_BF[CRS_MAX], *course ;
extern int		crs_number ;
extern CrsVertex	crs_vertex[CRS_VERTEXES+1] ;
extern CrsPoint		crs_point_BF[CRS_POINT_MAX] ;
extern Vtx		*crs_vertex_pt ;
extern float		crs_joint_length[] ;
extern int		crs_division_flag ;
extern short		last_gp_crs_number ;


/*******************************************************************************
	FUNCTION
*******************************************************************************/
extern void		init_course_cold( void ) ;
extern void		init_course_hot( void ) ;
extern void		init_course( void ) ;
extern void		move_course( void ) ;
extern Gfx		*make_course_glist( Gfx *gp, int ci ) ;
extern Gfx		*make_course_glist2( Gfx *gp ) ;
extern void		change_crs_division( int flag ) ;
extern void		make_random_course( void ) ;

extern void		get_course_point( CrsPoint *p1, float u, Fxyz *pos ) ;
extern float		get_course_vector( CrsPoint *p1, float u, Fxyz *vec ) ;
extern float		get_course_direction( CrsPoint *p1, float u, Direction *dir, float level ) ;
extern float		get_course_distance( CrsPoint *p1, float u, float *dist ) ;
extern float		get_course_distance2( CrsPos *cp ) ;
extern int		cal_new_course_pos( CrsPos *cp, float new_x, float new_y, float new_z, int n, float err ) ;
extern int		cal_crs_tension( Course *cp ) ;
extern void		cal_crs_distance( Course *cp ) ;
extern int		cal_crs_joint_flag( Course *cp ) ;
extern void		cal_crs_form( Course *cp ) ;
extern void		cal_crs_continue( Course *cp ) ;
extern int		normalize_crs_up_vector( Course *cp ) ;
extern Gfx		*make_mini_course_glist( Gfx *gp, Vtx *vp, int vtxs ) ;
extern int		make_mini_course_vertex( Course *cp, Vtx *vp ) ;
extern void		load_course_data( void ) ;
extern int		get_course_directionZX( CrsPos *cp, float new_x, float new_y, float new_z, Direction *dir ) ;
extern void		set_crs_texture_scale( int scene_no ) ;


#endif
