

#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED




#include "teamdata.h"

#include "skel.h"
#include "anim.h"
#include "ctrl.h"
#include "3dtypes.h"
//#include "Genmath.h"

//#define SHOT_TEST
#define	PMR(p)			((p)->main_routine)
#define	MOM_MAX(team)	(mom_team==team && momentum==100)
#define	CPL_NOLOCK		-1
#define	PID				(plyr->plyrROM->uw___pIndx)
#define	IS_PLYR_ONLY(pid)	(PID==PID_##pid)
#define	IS_PLYR(pid)	(PID==PID_##pid || ArcadeMode)
#define	QUARTER_LENGTH	((12-3*pcl__gMatch->pcl__mOptions->sb___QuarterLen)*ONE_MIN)
#define	TROM(i)			pcl__gMatch->apcl_mTeamRom[i]
#define	TRAM(i)			pcl__gMatch->apcl_mTeamRam[i]
#define	SCORET(t)		(pcl__gMatch->apcl_mTeamRam[t]->uw___tPoints)
#define	SUBMOM(x)		{ momentum-=(x); if (momentum<0) { momentum=0; mom_team^=1; } }
#define	ADDMOM(x)		{ momentum+=(x); if (momentum>100) momentum=100; }
#define	MOMUP(t,x)		{ if ((t)^mom_team) SUBMOM(x) else ADDMOM(x); }
#define	MOMDOWN(t,x)	{ if ((t)^mom_team) ADDMOM(x) else SUBMOM(x); }

#define	TEMPO(x)		(((int)(x)*tempo)>>8)
#define	INVTEMPO(x)		(((int)(x)<<8)/tempo)
#define INVTEMPOA(x)	(((x)+INVTEMPO(x))/2)
#define	DA(d,s)			((SW)((d)-(s)))
#define	PLY(p)			((p)->yco*(((p)->team)? -1:1))
#define	BLY(p)			(ball.yco*(((p)->team)? -1:1))
#define	TPLY(p,y)		((y)*(((p)->team)? -1:1))
#define	PPA(d,s)		LFPAtn((d)->xco-(s)->xco,(d)->yco-(s)->yco)
#define	PPRA(d,s)		((SW)(PPA((d),(s))-(s)->angle))

#define	IN_KEY(p)		(abs((p)->xco)<LANE_X && (PLY(p)>FOUL_LINE))

#define	IN_DOMAIN(v,l,h)	((v)>(l) && (v)<(h))

#define	FPOT(p)				((p)=&player[plyr->base])		// First Player On Team
#define	LPOT(p)				((p)=&player[plyr->base+5])		// Last Player On Team
#define	TPPB(p,e)			FPOT(p);LPOT(e)					// Team Player Pointer Boundaries

#define	IS_DUNKING(p)		(((p)->main_routine==dunk_take_off) ||	\
							 ((p)->main_routine==dunk_up_rou) ||	\
							 ((p)->main_routine==dunk_down_rou) )

//#define FLAG60	//60hz AI

#define	ARCADE_MODE	0

#define	CAN_STEAL		!(ARCADE_MODE)
#define	CAN_HELPER_D	!(ARCADE_MODE)

// Ball stuff...

#define	NUM_BALLS	50				// Number of "active" balls in 3-point contest
#define	BALL_RADIUS	0x18000			// Radius of the ball in world coordinate space
#define BALL_DUNK_ZVEL -(256<<10)

#define BALLTYPE_NONE    0
#define BALLTYPE_REGULAR 1
#define BALLTYPE_MONEY   2


#define MAX_BONES 17
#define NODE_HIPS	0
#define NODE_CHEST	1
#define NODE_HEAD	2
#define NODE_LSHOULDER 3
#define NODE_LBICEP	4
#define NODE_LFORARM	5
#define NODE_LHAND	6
#define NODE_RSHOULDER 7
#define NODE_RBICEP	8
#define NODE_RFORARM 9
#define NODE_RHAND	10
#define NODE_LTHIGH	11
#define NODE_LSHIN	12
#define NODE_LFOOT	13
#define NODE_RTHIGH	14
#define NODE_RSHIN	15
#define NODE_RFOOT	16


#define DEFENDING (((ball_handler-5) ^ (plyr->no-5)) < 0)
#define ATTACKING (((ball_handler-5) ^ (plyr->no-5)) >= 0)
#define BALL_HANDLER ((plyr->no == ball_handler) && (possession_flag))


/* */

#define	FTST(x)	(stricmp(x,plyr->plyrROM->pcz__pCName)==0)
#define	LTST(x)	(stricmp(x,plyr->plyrROM->pcz__pSName)==0)
#define	FI		"H"
#define	FN		"hENrY"
#define	LI		"s"
#define	LN		"sTeRChI"
#define	HSTEST	((FTST(FI)||FTST(FN))&&(LTST(LI)||LTST(LN)))
#define	HTST	(player[pnum].plyrROM->uw___pIndx==PID_HENRY_STERCHI_NOA && SecretModeX)
#define	HSDN	"IDIOT"

//positional AI
#define SLOW_ZONE			TEMPO(0x100000)
#define STOP_ZONE			(int)TEMPO(0x70000)
#define SHUFFLE_STOP_ZONE	TEMPO(((0x1000/5) * plyr->scale))
#define SHUFFLE_SLOW_ZONE	(int)TEMPO(.6 * 0x100000)
#define BACK_STOP_ZONE		(int)TEMPO(.4 * 0x100000)

#define	IS_SHUF_LEGS(p)		( (p)->leg_anim==LEG_READY || ( ((p)->leg_anim>=LEG_GUARD1) && ((p)->leg_anim<=LEG_GUARD4)  ) )
#define	SHUF_ANIM_IDX(p)	( ((p)->markee=ball_handler)? 2 : is_boxing(p) )

//set play
#define PASS    0x20
#define PICK    0x21
#define NOTHING 0x22
#define SCREEN  0x23
#define DRIBBLE 0x40
#define SHOOT	0x50

typedef struct playS
{
char move;
SB	 curve;
char delay;
SW   arg1;
SW   arg2;
}playT;


typedef struct ball_path_listS
{
UB lower_ang_lim;
UB upper_ang_lim;
UB lower_rng_lim;
UB upper_rng_lim;
UB *list;
}ball_path_listT;



//************************************************************************
//	Miscellaneous Configuration
//************************************************************************
#define	TOGGLE_P3	1		// Allow third controller to toggle on/off



//************************************************************************
//	Initial Controller Configuration
//************************************************************************

//------------------------------------------------------------------------
//	Pad Team Assignment Values
//------------------------------------------------------------------------
#define	PAD_HOME	0
#define	PAD_AWAY	1
#define	PAD_NONE	2


//************************************************************************
// Collision Detection Constants
//************************************************************************
#define COL_DI		0xe0000			// Diameter for running players
#define SHUF_DI		0xa0000			// Diameter for shuffle circles
#define SHUF_SEP	((COL_DI-SHUF_DI)/2)		// Lateral offset of two shuffle circles
#define DUNK_DI		0x50000			// Diameter for dunking 



//************************************************************************
//	Blocking Constants
//************************************************************************
#define BLOCK_TIME	2
#define	BLOCK_DIST	0x30000			// Distance at which blocker strikes ball



/* */
/* */
/* */

#ifdef USA


 #ifndef FLAG60

  #define ONE_SEC			30			/* 30Hz */
  #define HALF_SEC		15
  #define ONE_MIN			30*60		/* 30Hz */

#if 0
  #define LITTLE_G        0x4000 // gravitational acceleration
#else
  #define LITTLE_G		TEMPO(0x4000)
#endif

  #define TURN_SPEED      0xc00
  
  #define WALK_THRESHOLD    0x900
  #define JOG_THRESHOLD     0xc80
  #define TURBO_THRESHOLD   ((BALL_HANDLER) ? 0x1180:0x1280)
  
  #define TURBO_SPEED     0x1500  // running top speed
  
  #define RUN_ACCEL       0x100   // running acceleration
  #define RUN_BRAKE     0x400     // running braking
  #define DRIBBLE_BRAKE 0x400     // dribble braking
  #define DRIB_FACT     0xd0		// how much to slow down ball handler
  
  #define COAST_BRAKE 0x200
  
  #define RUN_START   0x200       // start running speed
  #define DRIBBLE_START 0x200     // dribble start speed
  
  #define COL_SPEED   0x400       // how fast knocked back
  #define COL_RADIUS  0xa0000     // collision detect radius
  #define SHUF_RADIUS  0xa0000    // collision detect radius
  
  #define BCOL_RADIUS 0x100000    // ball catch detect radius
#if 0  
  #define CH_PASS_SPD   0x70000   // chest pass speed
  #define OSH_PASS_SPD  0x50000	// over shoulder pass speed
  #define SHOV_PASS_SPD 0x38000   // soft pass speed
  #define BASE_PASS_SPD 0xa0000	// base ball pass speed
#else
  #define CH_PASS_SPD	TEMPO(0x70000)
  #define OSH_PASS_SPD	CH_PASS_SPD //TEMPO(0x50000)
  #define SHOV_PASS_SPD	TEMPO(0x38000)
  #define BASE_PASS_SPD	TEMPO(0xa0000)

#endif

  #define J_ZVEL      (LITTLE_G*INVTEMPOA(9))
  #define B_ZVEL      (LITTLE_G*INVTEMPOA(95/10))
  #define HC_ZVEL     (LITTLE_G*INVTEMPOA(8))
  #define HK_ZVEL     (LITTLE_G*INVTEMPOA(9))
  #define BHK_ZVEL    (LITTLE_G*INVTEMPOA(10))
  
  #define TURBO_DEPLETE	3
  #define TURBO_RECOVER	1
  #define TURBO_LIMIT		0x100
  #define TURBO_STEAL		0x40
  #define TURBO_DRIBBLE	0x40
  #define TURBO_SPIN		0x60
  
  #define TIME_FACTOR		(1)

 #else

  #define ONE_SEC			60			/* 30Hz */
  #define HALF_SEC		30
  #define ONE_MIN			60*60		/* 30Hz */
  #define LITTLE_G        0x1000 // gravitational acceleration
  
  #define TURN_SPEED      0x600
  
  #define WALK_THRESHOLD    0x900
  #define JOG_THRESHOLD     0xc80
  #define TURBO_THRESHOLD   ((BALL_HANDLER) ? 0x1180:0x1280)
  
  #define TURBO_SPEED     0x1500  // running top speed
  
  #define RUN_ACCEL       0x80   // running acceleration
  #define RUN_BRAKE     0x200     // running braking
  #define DRIBBLE_BRAKE 0x200     // dribble braking
  #define DRIB_FACT     0xd0		// how much to slow down ball handler
  
  #define COAST_BRAKE 0x100
  
  #define RUN_START   0x200       // start running speed
  #define DRIBBLE_START 0x100     // dribble start speed
  
  #define COL_SPEED   0x400       // how fast knocked back
  
  #define BCOL_RADIUS 0x100000    // ball catch detect radius
  
  #define CH_PASS_SPD   0x38000   // chest pass speed
  #define OSH_PASS_SPD  0x28000	// over shoulder pass speed
  #define SHOV_PASS_SPD 0x1c000   // soft pass speed
  #define BASE_PASS_SPD 0x50000	// base ball pass speed
  
  #define J_ZVEL      (LITTLE_G*18)
  #define B_ZVEL      (LITTLE_G*18)
  #define HC_ZVEL     (LITTLE_G*16)
  #define HK_ZVEL     (LITTLE_G*18)
  #define BHK_ZVEL    (LITTLE_G*20)
  
  #define TURBO_DEPLETE	3
  #define TURBO_RECOVER	1
  #define TURBO_LIMIT		0x100
  #define TURBO_STEAL		0x40
  #define TURBO_DRIBBLE	0x80
  #define TURBO_SPIN		0x60
  
  #define TIME_FACTOR		(2)

 #endif
#endif


#ifdef JAPAN
 #define ONE_SEC			30			/* 30Hz */
 #define HALF_SEC		15
 #define ONE_MIN			30*60		/* 30Hz */
 #define LITTLE_G        0x4000 // gravitational acceleration

 #define TURN_SPEED      0xc00

 #define WALK_THRESHOLD    0x900
 #define JOG_THRESHOLD     0xc80
 #define TURBO_THRESHOLD   ((BALL_HANDLER) ? 0x1180:0x1280)

 #define TURBO_SPEED     0x1500  // running top speed

 #define RUN_ACCEL       0x100   // running acceleration
 #define RUN_BRAKE     0x400     // running braking
 #define DRIBBLE_BRAKE 0x400     // dribble braking
 #define DRIB_FACT     0xd0		// how much to slow down ball handler

 #define COAST_BRAKE 0x200

 #define RUN_START   0x200       // start running speed
 #define DRIBBLE_START 0x200     // dribble start speed

 #define COL_SPEED   0x400       // how fast knocked back
 #define BCOL_RADIUS 0x100000    // ball catch detect radius

 #define CH_PASS_SPD   0x70000   // chest pass speed
 #define OSH_PASS_SPD  0x50000	// over shoulder pass speed
 #define SHOV_PASS_SPD 0x38000   // soft pass speed
 #define BASE_PASS_SPD 0xa0000	// base ball pass speed
 
 #define J_ZVEL      (LITTLE_G*9)
 #define B_ZVEL      (LITTLE_G*9)
 #define HC_ZVEL     (LITTLE_G*8)
 #define HK_ZVEL     (LITTLE_G*9)
 #define BHK_ZVEL    (LITTLE_G*10)

 #define TURBO_DEPLETE	3
 #define TURBO_RECOVER	1
 #define TURBO_LIMIT		0x100
 #define TURBO_STEAL		0x40
 #define TURBO_DRIBBLE	0x80
 #define TURBO_SPIN		0x60

 #define TIME_FACTOR		(1)

#endif


#ifdef PAL

 #define ONE_SEC			25			/* 25Hz */
 #define HALF_SEC			12
 #define ONE_MIN			25*60		/* 25Hz */
 #define LITTLE_G        0x5c28			// 0x4000*(1.2^2)	gravitational acceleration

 #define TURN_SPEED      (0xc00*1.2)

 #define WALK_THRESHOLD    0x900
 #define JOG_THRESHOLD     0xc80
 #define TURBO_THRESHOLD   ((BALL_HANDLER) ? 0x1180:0x1280)
 #define TURBO_SPEED     0x1500  // running top speed

 #define RUN_ACCEL      (0x100*1.2)	  // running acceleration
 #define RUN_BRAKE		(0x400*1.2)   // running braking
 #define DRIBBLE_BRAKE	(0x400*1.2)   // dribble braking
 #define DRIB_FACT		0xd0		  // how much to slow down ball handler

 #define COAST_BRAKE	(0x200*1.2)

 #define RUN_START		(0x200*1.2)     // start running speed
 #define DRIBBLE_START  (0x200*1.2)     // dribble start speed

 #define CH_PASS_SPD   0x86000	//0x70000   // chest pass speed
 #define OSH_PASS_SPD  0x60000	//0x50000	// over shoulder pass speed
 #define SHOV_PASS_SPD 0x43000	//0x38000   // soft pass speed
 #define BASE_PASS_SPD 0xc0000	//0xa0000	// base ball pass speed
 
 #define J_ZVEL      (LITTLE_G*8)
 #define B_ZVEL      (LITTLE_G*8)
 #define HC_ZVEL     (LITTLE_G*7)
 #define HK_ZVEL     (LITTLE_G*8)
 #define BHK_ZVEL    (LITTLE_G*9)

 #define TURBO_DEPLETE	3
 #define TURBO_RECOVER	1
 #define TURBO_LIMIT	0x100
 #define TURBO_STEAL	0x40
 #define TURBO_DRIBBLE	0x80
 #define TURBO_SPIN		0x60

//multiply all time constants by this value.
 #define TIME_FACTOR		(0.83333)

#endif










#define SUBS_ALLOWED		(((!in_play_flag) && (scored_flag==0) && (possession_flag)) || (timeout_called))
#define TIMEOUT_ALLOWED(x)  (( ((possession_flag) && ((x)==(bhp->no/5)) && (bhp->zco==0) && (!dunk_flag)) || ((!in_play_flag) && ((scored_flag==0) || (ft_flag && possession_flag)) ) ) && (!tip_off_flag))

#define TIMEOUT_CPU_ALLOWED(x)  (TIMEOUT_ALLOWED(x) & (!fast_break_flag))


#define BASKET_Y	0xd00000			// Used in AI and GFX code.


#define MADE	 255
#define GLS		 253
#define RIM		 252	// straight rim
#define RIM_RAND 254	// random rim




//can't be bothered to import new models to pc so use different posts
#ifdef PC
 #define POST_Y1     -BASKET_Y-0x224000
 #define POST_Y2     BASKET_Y+0x224000
#else
 #define POST_Y1     -BASKET_Y-0x2b0000
 #define POST_Y2     BASKET_Y+0x2b0000
#endif

#define	GLASS_Y		0xd40000			// Used in AI and GFX code.
#define BASKET_Z	0x2f0000			// Used in AI and GFX code.
#define ALLEY_Z	    0x330000

#define	METER		0x100000
#define	SIDE_LINE	0x740000
#define	BASE_LINE	0xe00000
#define	FOUL_LINE	0x800000
#define EDGE        0x60000
#define LANE_X		0x280000

#define HALFWAY 0

#define BOARD_EDGE_Y  0x1040000
#define BOARD_EDGE_X  0x860000


#define ball player[10]
#define DUMMY player[15]
#define RECVR player[16]
#define OFFND player[17]


#define jmask(A) current_ctrlr->c_mask |= (A)

#define LFPSin(x) ((int) sin_tbl[(UW)(x)>>5])
#define LFPCos(x) ((int) sin_tbl[(UW)((x)+0x4000)>>5])

#define UPPER_ARM 360
#define FORE_ARM  440


/*personal fouls */
#define	HACKING1	1
#define HACKING2	2
#define HACKING3	3
#define	REACHING_IN 4
#define FLAGRANT	5
#define	CHARGING	6
#define TECHNICAL	7

/*non shooting fouls */
#define TRAVELING		8
#define	THREE_SECOND	9
#define	TEN_SECOND		10
#define	FIVE_SECOND		11
#define SHOT_CLOCK		12
#define HALF_COURT		13
#define	ILLEGAL_DEFENSE	14
#define OUT_OF_BOUNDS	15
#define OVER_THE_TOP	16

#define	ILLEGAL_DIST	0x2A0000
#define	ILLEGAL_TIME	(ONE_SEC*3)

#define	PREFS			1

#ifdef N64

 extern Preferences_T  cl___gPreferences;
 extern Preferences_T *pcl__gPreferences;

#if PREFS

 #define HALF_COURT_ON	 pcl__gMatch->pcl__mOptions->sb___BackCourt
 #define KEY_ON			 pcl__gMatch->pcl__mOptions->sb___3InTheKey
 #define SEC5_CLOCK		 pcl__gMatch->pcl__mOptions->sb___5SecInbounds
 #define SEC10_CLOCK	 pcl__gMatch->pcl__mOptions->sb___10SecHalfcourt
 #define SEC24_CLOCK	 (pcl__gMatch->pcl__mOptions->sb___ShotClock && !PracticeMode)
 #define OFFENSIVE_FOULS pcl__gMatch->pcl__mOptions->sb___OffFouls
 #define DEFENSIVE_FOULS pcl__gMatch->pcl__mOptions->sb___DefFouls
 #define CROSS_FLAG		 pcl__gPreferences->sb___IndicateRebound
 #define AUTO_SWITCH	 pcl__gPreferences->sb___AutoPlyrSwitch
 #define CAMERAS		 pcl__gPreferences->sb___SpecialCameras
 #define FOUL_OUTS		 pcl__gMatch->pcl__mOptions->sb___FoulOuts
 #define GOALTENDING	 pcl__gMatch->pcl__mOptions->sb___GoalTending
 #define BOUNDARIES		 (pcl__gMatch->pcl__mOptions->sb___OutOfBounds && !PracticeMode)
 #define DIFFICULTY		 pcl__gMatch->pcl__mOptions->sb___Difficulty
 #define SCORE			 pcl__gPreferences->sb___ShowClock
#endif

#endif

#if !PREFS
 #define HALF_COURT_ON	 0
 #define KEY_ON			 0
 #define SEC5_CLOCK		 0
 #define SEC10_CLOCK	 0
 #define SEC24_CLOCK	 0
 #define OFFENSIVE_FOULS 1
 #define DEFENSIVE_FOULS 1
 #define CROSS_FLAG		 1
 #define AUTO_SWITCH	 0
 #define GOALTENDING	 0
 #define FOUL_OUTS		 0
 #define BOUNDARIES		 1
 #define CAMERAS		 0//2
 #define DIFFICULTY		 1
 #define SCORE			 1
#endif

#define CPU_RT 3


//*****************************************************************************
//	Cotrollers
//*****************************************************************************

//=============================================================================
//	Defines
//=============================================================================
#if	defined(DEBUG)
	#define TIME_TAP				5	// Since debug runs slower, less frames
#else
	#define	TIME_TAP				7	// Maximum number of frames classifed as tap
#endif

#define	NUM_BUTTONS				18

#define	CTL_TAP(ctrl,btn)		((ctrl)->tap&(btn))
#define	CTL_HOLD(ctrl,btn)		((ctrl)->hold&(btn))
#define	CTL_TAPHOLD(ctrl,btn)	(((ctrl)->tap|(ctrl)->hold)&(btn))
#define	CTL_DOWN(ctrl,btn)		((ctrl)->mctrlr&(btn))
#define	CTL_PRESS(ctrl,btn)		((ctrl)->ctrlr&(btn))
#define	CTL_NEWPRESS(ctrl,btn)	((ctrl)->mctrlr&(~(ctrl)->last)&(btn))

#define	CTL_RMASK(ctrl,btn)		((ctrl)->r_mask|=(btn))
#define CTL_SETTAP(ctrl,btn)	((ctrl)->tap|=(btn))
#define CTL_SETHOLD(ctrl,btn)	((ctrl)->hold|=(btn))
#define CTL_SETDOWN(ctrl,btn)	((ctrl)->mctrlr|=(btn))
#define	CTL_CLRDOWN(ctrl,btn)	((ctrl)->mctrlr&=~(btn),(ctrl)->ctrlr&=~(btn))

#define	CCTL_TAP(btn)			CTL_TAP(current_ctrlr,(btn))
#define	CCTL_HOLD(btn)			CTL_HOLD(current_ctrlr,(btn))
#define	CCTL_TAPHOLD(btn)		CTL_TAPHOLD(current_ctrlr,(btn))
#define	CCTL_DOWN(btn)			CTL_DOWN(current_ctrlr,(btn))
#define	CCTL_PRESS(btn)			CTL_PRESS(current_ctrlr,(btn))
#define	CCTL_NEWPRESS(btn)		CTL_PRESS(current_ctrlr,(btn))
#define	CCTL_RMASK(btn)			CTL_RMASK(current_ctrlr,(btn))
#define	CCTL_SETTAP(btn)		CTL_SETTAP(current_ctrlr,(btn))
#define	CCTL_SETHOLD(btn)		CTL_SETHOLD(current_ctrlr,(btn))
#define	CCTL_SETDOWN(btn)		CTL_SETDOWN(current_ctrlr,(btn))
#define	CCTL_CLRDOWN(btn)		CTL_CLRDOWN(current_ctrlr,(btn))



//=============================================================================
// Structures
//=============================================================================

//-----------------------------------------------------------------------------
//	ctrlrT : Device-Independent Controller Data Type
//-----------------------------------------------------------------------------
typedef struct ctrlrS
{
	int	raw;			//just the pure data
	int	ctrlr;			//current bits
 	int last;			//last current
	int	db_ctrlr;		//new presses only
	int	d_pad;			//just direction buttons
	int	mctrlr;			//masked bits
	int	c_mask;			//mask for mctrlr
	int	r_mask;			// mask until release
	int force;			//0-15

	SW	d_angle;		//angle of analogue stick 0-0x10000
	int icon_ctr;		//pass icons
	int zero_timer;		//how long has pad been left zero
	int last_switch;	//last time someone

	SB	roleplay;		// In roleplaying mode?
	SB	level;			// Rookie or Pro?

	int	tap;			// Button(s) being tapped
	int	hold;			// Button(s) being held down

	SW	htime[NUM_BUTTONS];		// Timers for button tap/hold
}ctrlrT;


#define	CL_ROOKIE		0
#define	CL_PRO			1

#define	ICL_ROOKIE(c)	((c)->level==CL_ROOKIE)
#define	ICL_PRO(c)		((c)->level==CL_PRO)

#define	ICCL_ROOKIE		ICL_ROOKIE(current_ctrlr)
#define	ICCL_PRO		ICL_PRO(current_ctrlr)


//*****************************************************************************
//*****************************************************************************
typedef struct _ikFrame
{
	int  node;
	Quat q;
	SW   angle;
	SW   axisX;
	SW   axisY;
	SW   axisZ;
}ikFrameT;


typedef struct players
{
	animFrame	aFrame;

	vector   nodeOffset[MAX_BONES];		//offsets for unanimated bones (scaled for player size)
	vector16 nodeVector[MAX_BONES];		//positions of each node (animated)

	Quat   rootQuat;					//root rotation quat
	Quat   skelQuat[MAX_BONES];			//bone roation quats
	matrix rootMatrix;					//root rotation matrix
	matrix skelMatrix[MAX_BONES];		//bone roatation matrices

#ifdef DEBUG
	vector momentVector[MAX_BONES];		//debug stuff
#endif

    PlyrRomData_T *plyrROM;				//ptr to plyr ROM data
    PlyrRamData_T *plyrRAM;				//ptr to plyr RAM data
    TeamRomData_T *teamROM;				//ptr to team ROM data
    TeamRamData_T *teamRAM;				//ptr to team RAM data

	int		ikFrameNo;					//index to IK frame ptr (0 = no IK)
	int		ikBlend;					//how much of IK frame (0=none, 256 = all IK)
	int 	ikBlendSpeed;				//how fast to change ikBlend

	int		rlx;							// Last root node position
	int		rly;
	int		rlz;

	int		xco;						//aprox 0x800000 to -0x800000 court width
	int		yco;						//aprox 0x1000000 to -0x1000000 court length
	int		zco;						//same scale
	int		angle;						//0-0xffff  0 faces along x-axis, 0x4000 faces along y axis
	int		xvel;						//x-speed
	int		yvel;						//y-speed
	int		zvel;						
	int		angle2;						//2nd angle
	int		angle_vel;

	SW		shuffle_angle;				//0-15      0 moves in direction player is facing, 1 clockwise 360/16
	SW		last_shuffle_angle;			//0-15		as above but used for blending

	int		col_angle;					//angle of last player bumped in 

	int		flags;						

	bool	play_flag;					
	bool	pick_arm;					// Use the pick arm?
	bool	backdown;					// Automatically backing down?
	UB		bdcc;						// Backing down collision counter
	UB		bdcp;						// Backing down collision player

	int		sx;							//screen x
	int		sy;							//screen y
	int		scale;						//size of player (256= 6ft6)

	int		score;
	int		score2;

	int		proj_x;						//roughly where would be by time ball was passed to him 
	int		proj_y;

	int		ball_dist;					//distance to ball
	int		ball_angle;					//angle to ball
	int		basket_dist;				//distance to basket
	int		basket_angle;				//angle to basket

	int		defense_dist;				//how far away from attacker shoul I be
	int		hand_check_flag;			//was I hand checking last frame

	int		look_at_ball_ctr;			//set to how long you want plyr to look at ball

	void	(*main_routine)(struct players *);	//main AI generates ctrlr settings
	void	(*top_routine)(struct players *);	//animates top
	void	(*leg_routine)(struct players *);	//moves player

//	void	(*old_main_rou)(struct players *);
//	void	(*old_top_rou)(struct players *);
//	void	(*old_leg_rou)(struct players *);

	int     mr_no;						//nos corresponding to control routines above
	int     top_no;
	int     leg_no;

	int		last_speed;					//how fast was I going last frame 0x1200=TURBO
	int		col_flags;					

	int     cross_ctr;					//counts down since last crossover

	int		kb_ctr;						//counts down to end of knocked_back routine
	int		freeze_ctr;					//counts down to end of freeze routine
	int		ctr2;						//general purpose ctr
	int		blk_release;				//=10 when let go of block button, decremented every frame till=0

	int     turbo;						//current turbo
	int     max_turbo;					//max turbo
	int     energy;						//how much

	UB		base;						//0 or 5. Base of player's team
	UB		team;						//0 or 1. Index into plyr's ai_team[]

	UB		marker;						//0-9	who is marking me
	UB		markee;						//0-9   who I'm marking

	UB		no;							//0-9   my no
	UB		control;					//0-4   0=AI

	UB		no2;			/*jersey no */

	UB		speed;						//how fast am I?

	SI		key_ctr;					//how long have I been in the key
	SI		pitch;						//player lean 0=standing straight up

    SI      top_blend_ctr;				//0 = all current frame, 256 = all last frame
    SI      top_anim;					//index to current animation
	SI		top_frame;					//index into current animation * 256	
	SI		last_top_anim;				//index to current animation
	SI		last_top_frame;				//index into current animation * 256
    SI      top_rate;					//speed of animation
	SW		top_blend_speed;			//how fast to decrement top_blend_ctr, >256 means move last animation as well

    SI      leg_blend_ctr;				//as for tops
    SI      leg_anim;
	SI		leg_frame;
	SI		last_leg_anim;
	SI		last_leg_frame;
    SI      leg_rate;
	SW		leg_blend_speed;			

	SW		next_anim;					//catch animation

	int		shuffle_stage;				//0=start, 1=loop, 2=stop
	bool	shuffle;					//am I in shuffle mode ?
	int		shuffle_target_angle;		//which direction should be facing

	int		force;						//0-15 force from analogue ctrlr
	int		d_angle;					//
	int     ctrlr;						//ctrlr flags
	int		strength;					//how strong am I?

	int		target_x;					//desired position
	int		target_y;
	int		target_dist;				//how far am I from desired position
	int     target_curve;				//+/- 7 what curve should I run at?

	SW		target_angle;				// Desired angle

	int		play_dist;

	SB		pickee;						//player that pick is set for
	SW		pick_angle;					//angle pick is set at
	SW		pick_ctr;					//



// new horrible variables added by steve
	struct players *	bumped_into;			// who I just ran into
	struct players *	bumped_into_me;			// who just ran into me!
	struct players *	bumped_into_2;			// Whor I ran into 2 frames ago
	
	struct players *	fouler;					// Player who fouled me

	SW		bumped_into_me_angle;		// Angle of bumpage
	int		bump_force;					// Force to use during collisions

	int     nearest_op;					//nearest opponent
	int     nearest_dist;				//distance to nearest opponent

	UB		*path_list;					//ball path_list
	int		initial_zvel;				//first bounce of rim zvel
	int		rim_bounce_count;			//how many times ball has bounced on rim

	// added by ben, to make flipped cam/render stuff easier...
	int		flip_xco;
	int		flip_yco;
	int		flip_zco;
	int		flip_angle;

	int		dunk_declare;
	SW		dunk_angle;

	UB		flagrant;					// Has a flagrant foul already been called?

	// 3 Point Contest variables
	SB		State3;
	SB		Rack3;
	SB		Balls3;
	SB		Score3;

} playert;

typedef struct ballt
{
	int		xco,yco,zco;
	int		xvel,yvel,zvel;
	int		type;				// 0: off, 1:normal, 2:special
	int		state;
	void	(*main_routine)(struct players *);	//main AI generates ctrlr settings
	playert	*shooter;

	SW		basket_angle;
	SW		rack;
	SW		ball;
	SW		angle;

	UB		*path_list;
	int		ctr2;
	int		rim_bounce_count;
	int		initial_zvel;

	int		flip_xco;
	int		flip_yco;
	int		flip_zco;

	int		rotx;
	int		roty;
	int		rotz;

	int		spinx;
	int		spiny;
	int		spinz;
} ballt;


//*****************************************************************************
//	Player Flags
//*****************************************************************************
#define	FALLING		2		/*falling */
#define	HIT			8		/*collision react */
#define COLLIDE		16
#define OFF_SCREEN 	1
#define	MOVE_ROOT	32		// Move the root position instead of animating it
#define	HOLD_ROOT	4		// Hold over the move root tracker between animations
#define SHOOT_TURN	128		// Animate turn during jump shot?
#define	SHOOT_PIVOT	256
#define	SHOOT_AIM	512
#define	SHOOT_STOP	1024
#define SHOOT_MASK	(SHOOT_TURN|SHOOT_PIVOT|SHOOT_AIM|SHOOT_STOP)

typedef struct teams
{
//    TeamRomData_T *teamROM;
//    TeamRamData_T *teamRAM;

	playert	*plyr1;
	playert	*main_plyr;

	playert *chaser;
	playert *dt;
	playert *helper;

	int		base;
	int		fouls_left;

	int		controllers[5];
	int		last_controller;

	int		current_set;
	int		last_set_change;

	int		press;
	int		foul;
	int		manual_subs;
	int		set1;
	int		set2;

	// Rebound information
	playert	*reb_plyr;
	int		reb_lt;
	int		reb_t;
	int		reb_to;
	bool	reb_low_flag;

	int		illegalD;

}
teamt;












enum CARD_TYPES
{
	CARD_STEAL,
	CARD_TO,
	CARD_ASSIST,
	CARD_FGS,
	CARD_3PTS,
	CARD_FTS,
	CARD_REB,
	CARD_BLOCK,
	CARD_FOUL
};



#define BLEND(a,b,t,r) { signed long __blendT1,__blendT2; 		\
		       __blendT1=(signed long)(a);			\
		       __blendT2=(signed long)(b);			\
		       __blendT1+=((__blendT2-__blendT1)*(signed long)(t))/256;	\
		       (r)=__blendT1; }

#define BLENDANG(a,b,t,r) { signed short __blendT1,__blendT2,__blendT3; 		\
		            __blendT1=(signed short)(a);			\
		            __blendT2=(signed short)(b);			\
			    __blendT3=__blendT2-__blendT1;			\
		            __blendT1+=(__blendT3*(signed long)(t))/256;	\
		            (r)=__blendT1; }


extern void message(char *fname, int line);

#ifdef N64

 #if DEBUG
  //#define BRK {	message(__FILE__, __LINE__);	\
//				while(1);	 }
	#define	BRK	{ int lp=*((int *)0x1); }
 #else
//  #define BRK FatalError("BRK",__FILE__,__LINE__)//while(1){}
  #ifdef FINAL
   #define BRK
  #else
   #define BRK BreakMessage("BRK",__FILE__,__LINE__)//while(1){}
  #endif
 #endif

#else

 #if DEBUG
  #define BRK {	message(__FILE__, __LINE__);	\
			while(1); }

 #else
  #define BRK message(__FILE__, __LINE__)
 #endif

#endif

//camera modes
#define FREE      0
#define DEMI_GOD  1
#define GOD2      2
#define GOD       3


#define CTRL_PICK		CTRL_C_RIGHT
#define CTRL_TURBO		CTRL_TRIGGER
#define CTRL_SHOOT		CTRL_FIRE_B
#define CTRL_SHUFFLE	CTRL_SHOULDER_R
#define CTRL_STEAL		CTRL_FIRE_A
#define CTRL_SWITCH		CTRL_C_DOWN
#define CTRL_FOUL		CTRL_C_RIGHT

#define CTRL_CROSSOVER	CTRL_C_DOWN
#define CTRL_DRIBBLE	CTRL_C_LEFT
#define CTRL_BOX_OUT	CTRL_C_LEFT

#ifdef N64
 #define CTRL_POST_PASS CTRL_C_UP
 #define CTRL_PASS		CTRL_FIRE_A
#else
 #define CTRL_POST_PASS CTRL_C_UP
 #define CTRL_PASS		CTRL_FIRE_A
#endif


#define CTRL_BACK		CTRL_SHOULDER_L

#define START_VELS(p,x,y) start_vels(p, LFPSqrt((int)(x*x + y*y)), (SW)p->angle+LFPAtn( (int)(y), (int)((p->top_anim>0) ? -(x):x)));

#define MANHATTAN(x,y) ((abs(x)>abs(y)) ? abs(x)+((abs(y)>>8)*0x6a): abs(y)+((abs(x)>>8)*0x6a))
#define MIN_MAX(v,min,max)			(min + ((max-min)*v)/100)
#define MIN_MAX2(v,a,b,min,max)		(min + ((max-min)*(v-a))/(b-a))




#define RIM_VOL    120
#define BOUNCE_VOL 230
#define NET_VOL    255
#define CATCH_VOL  255
#define BOARD_VOL  255
#define STEAL_VOL  120

#define RANDOM(x) ((ReadRnd250()*(x))>>8)


#define UP_UNDER    0
#define UP_FADE     1
#define BABY_HOOK   2
#define SPIN_OFF    3
#define TURN_AROUND 4



//#define NODE_RFINGER 15
//#define NODE_LFINGER 16

typedef struct dunkS
{
	int min_time;
	int max_time;
	int min_dist;
	int max_dist;
	SW min_angle;
	UW angle_range;

	int start_anim;
	int to_factor;
	SW	to_spin;
	SW	target_angle;
	int	to_speed;
	int	ld_speed;
	SW	ld_angle;
	int	end_speed;
	int	time;
	bool switch_flag;
	SB  spin_direction;

	int final_dist;
	SW  final_angle;

	bool hang;

	SB	level;

	UW	id;

	SW  land_twist;
}dunkT;

#endif
