


/************************************************************************************
	ACTION MAN PS	(c) 1998-9 ISL

	pad.h:		Controller pad routines

   (ctrller.h in Glover - additional code for dead-zone handling)
************************************************************************************/

#ifndef _PAD_H_
#define _PAD_H_


//extern	volatile UBYTE gameon;

//extern SHORT nleftx[2];
//extern SHORT nlefty[2];
//extern SHORT nrightx[2];
//extern SHORT nrighty[2];

// deadzone needs to be 40% of full travel of stick!
// SONY strikes again!!!
#define DEADZONE 50
#define DEADMULT 53


enum {									// Supported pad types
	PADTYPE_NONE,
	PADTYPE_DIGITAL,
	PADTYPE_ANALOG,
	PADTYPE_DUALSHOCK,
};


#define PAD_LEFT		(1<<7)			// Pad digital buttons
#define PAD_RIGHT		(1<<5)
#define PAD_UP			(1<<4)
#define PAD_DOWN		(1<<6)
#define PAD_CROSS		(1<<14)
#define PAD_CIRCLE		(1<<13)
#define PAD_TRIANGLE	(1<<12)
#define PAD_SQUARE		(1<<15)
#define PAD_L1			(1<<10)
#define PAD_L2			(1<<8)
#define PAD_L3			(1<<1)
#define PAD_R1			(1<<11)
#define PAD_R2			(1<<9)
#define PAD_R3			(1<<2)
#define PAD_SELECT		(1<<0)
#define PAD_START		(1<<3)



typedef struct _PadDataType {
	uchar	present[8];					// Controllers present
	uchar	numPads[2];					// Number of pads in port
	ushort	digital[8];					// Current d-pad reading
	ushort	analogX[8];					// Current left analog X reading
	ushort	analogY[8];					// Current left analog Y reading
	ushort	analogX2[8];				// Current right analog X reading
	ushort	analogY2[8];				// Current right analog Y reading
	uchar	buffer[2][34];				// HW packet buffers
	int		state[8];					// Port HW state
	uchar	motor[8][2];				// Dual shock motor values
	int		shock[8];					// 2nd shock dest values
	int		currShock[8];				// 2nd shock current values
	int		shockDiv[8];				// 2nd shock inertia divisor
	int		buzzTime[8];				// Countdown time for 1st shock
	int		newShock[8];
} PadDataType;



extern PadDataType	padData;
extern UBYTE		analog[8];			// Older vars for compatibility
extern USHORT		pad[8], debounce[8];
extern USHORT		leftx[8], lefty[8];
extern USHORT		rightx[8], righty[8];
extern USHORT		bothdebounces, bothpads;

// glover normalised versions
extern SHORT nleftx[8];
extern SHORT nlefty[8];
extern SHORT nrightx[8];
extern SHORT nrighty[8];

extern UBYTE dualShockOn;

// Stop dual shock vibration
#define SHOCK_STOP(p)		if(dualShockOn){ \
							padData.motor[(p)][0] = padData.motor[(p)][1] = 0; \
							padData.shock[(p)] = 0; \
							padData.buzzTime[(p)] = 0;}

// Start 1st shock motor
							
#define SHOCK_BUZZ(p)		if(dualShockOn) \
							padData.buzzTime[(p)] = INT_LARGEST;

// Stop 1st shock motor
#define SHOCK_NOBUZZ(p)		if(dualShockOn) \
							padData.buzzTime[(p)] = 0;

// Start 1st shock motor for given time
#define SHOCK_BUZZTIME(p,t)	if(dualShockOn) \
							padData.buzzTime[(p)] = (t);

// Set 2nd shock motor value
#define SHOCK_SET(p,v)		if(dualShockOn){ \
							padData.motor[(p)][1] = (v); \
							padData.currShock[(p)] = padData.shock[(p)] = (v)<<16;}

// Slide 2nd shock motor to value
#define SHOCK_SLIDE(p,v,d)	if(dualShockOn){ \
							padData.shock[(p)] = (v)<<16; \
							padData.shockDiv[(p)] = (d);}


#define SHOCK_FISTSLAM		{SHOCK_SET(0,127); SHOCK_SLIDE(0,0,4);}
#define SHOCK_SMASHPLATFORM	{SHOCK_BUZZTIME(0,4); SHOCK_SET(0,127); SHOCK_SLIDE(0,0,8);}
#define SHOCK_BOUNCEBALL	{SHOCK_SET(0,127); SHOCK_SLIDE(0,0,4);}
#define SHOCK_WHACKBALL


int padGetWhenLastUsed(void);
void padResetWhenLastUsed(void);

/**************************************************************************
	FUNCTION:	padInitialise()
	PURPOSE:	Initialise pads
	PARAMETERS:	
	RETURNS:	
**************************************************************************/

void padInitialise();


/**************************************************************************
	FUNCTION:	padHandler()
	PURPOSE:	Handle pad reading/connection etc.
	PARAMETERS:	
	RETURNS:	
**************************************************************************/

void padHandler();


#endif



