From: Barnard@forge.franken.de (Henning Schmiedehausen)
Newsgroups: comp.sys.amiga.programmer
Subject: Re: Going to the metal
Date: 31 Dec 92 12:04:09 GMT
 <lk1di9INNrsa@exodus.Eng.Sun.COM>
Organization: Barnard's Software Forge (ECG038)
X-Newsreader: Arn V1.00

In article <lk1di9INNrsa@exodus.Eng.Sun.COM>, Chuck McManis writes:

> This is the most powerful motive. Take the most trivial example, finding
> out where an 8 axis joystick is pointed. Do we open the "gameport.device"
> at the begining of the game and look for messages on the input stream
> to tell us where the stick is? Or do we just "mov d1,#port" ?

What's wrong with:

(This  does  go  to  the bare metal but allocates the controllers is a system
friendly way)


/**** JOYSTICK MODULE ****/

/*
 *	NAME
 *		JoyMove
 *
 *	FUNCTION
 *		keeps data for joystick
 *
 */

struct JoyMove
	{
BYTE xOff,			/* x-Position; -1:left, 1:right */
	 yOff,			/* y-Position; -1:up,  1: down */
	 Button;		/* Knopf: 0: pressed */
	};

static struct IOStdReq *joy[2] = { NULL,NULL },
						*InReq = NULL;

static struct MsgPort *jp[2] = { NULL,NULL },
					  *InPort = NULL;

static BOOL sctsucc[2] = { FALSE,FALSE };

#define	JM_UP		-1
#define	JM_DOWN		 1
#define	JM_NO_Y		 0

#define	JM_LEFT		-1
#define	JM_RIGHT	 1
#define	JM_NO_X		 0

#define	JM_BUTTON	 0

/*
 *	NAME
 *		static BOOL set_controller_type(req,type)
 *
 *	FUNCTION
 *		allocates a game port
 *
 *	INPUT
 *		req  -> IORequest
 *		type -> wanted type 
 *
 *	OUTPUT
 *		TRUE  -> Controller allocated
 *		FALSE -> error
 *
 */


static BOOL set_controller_type(req,type)
struct IOStdReq *req;
BYTE type;
{
BOOL success = FALSE;
BYTE controller_type = 0;

	Forbid();
	req->io_Command = GPD_ASKCTYPE;
	req->io_Data	= (APTR)&controller_type;
	req->io_Length  = 1;
	req->io_Flags   = IOF_QUICK;
	DoIO(req);

	if(controller_type == GPCT_NOCONTROLLER)
	{
		req->io_Command = GPD_SETCTYPE;
		req->io_Flags   = IOF_QUICK;
		req->io_Data	= (APTR)&type;
		req->io_Length  = 1L;
		DoIO(req);
		success = TRUE;
	}
	Permit();
	return(success);
}

/*
 *	NAME
 *		void free_gp_unit(req)
 *
 *	FUNCTION
 *		frees a game port
 *
 *	INPUT
 *		req  -> IORequest
 *
 *	OUTPUT
 *		-
 *
 */

static void free_gp_unit(req)
struct	IOStdReq	*req;
{
BYTE type	=	GPCT_NOCONTROLLER;

	req->io_Command = GPD_SETCTYPE;
	req->io_Flags   = IOF_QUICK;
	req->io_Data	= (APTR)&type;
	req->io_Length  = 1;
	DoIO(req);
}

/*
 *	NAME
 *		void JoyOn()
 *
 *	FUNCTION
 *		Allocates the gamesports for joysticks 
 *
 *	INPUT
 *		-
 *
 *	OUTPUT
 *		-
 *
 */


void JoyOn()
{
UBYTE InputMode = GPCT_NOCONTROLLER;

/* remove mouse from input.device */

	InPort =	CreatePort("Input_Port",NULL);
	InReq  =	CreateStdIO(InPort);
	OpenDevice("input.device",0,InReq,0);
	InReq->io_Command = (UWORD)IND_SETMTYPE;
	InReq->io_Data = (APTR)&InputMode;
	InReq->io_Length = 1L;
	DoIO(InReq);

	Delay(2L*TICKS_PER_SECOND);		/* wait for input.device to free mouse */

/* open the Joyports */

	jp[0]  = CreatePort("Joystick_1",NULL);
	joy[0] = CreateStdIO(jp[0]);
	OpenDevice("gameport.device",0,joy[0],0);

	jp[1]  = CreatePort("Joystick_2",NULL);
	joy[1] = CreateStdIO(jp[1]);
	OpenDevice("gameport.device",1,joy[1],0);

	sctsucc[0] = set_controller_type(joy[0],GPCT_ALLOCATED);
	sctsucc[1] = set_controller_type(joy[1],GPCT_ALLOCATED);

	if(!(sctsucc[0] && sctsucc[1]))
	{
		printf("Couldn't allocate game ports!\n");
		JoyOff();
		exit(10);
	}
}

/*
 *	NAME
 *		void JoyOff()
 *
 *	FUNCTION
 *		frees gameports 
 *
 *	INPUT
 *		-
 *
 *	OUTPUT
 *		-
 *
 */

int	JoyOff()
{
UBYTE JoyMode;
UBYTE InputMode;

	if(sctsucc[0])
	{
		joy[0]->io_Command = CMD_CLEAR;
		joy[0]->io_Length  = 0L;
		joy[0]->io_Flags   = IOF_QUICK;
		DoIO(joy[0]);
		free_gp_unit(joy[0]);
	}
	CloseDevice(joy[0]);
	DeletePort(joy[0]->io_Message.mn_ReplyPort);
	DeleteStdIO(joy[0]);

	if(sctsucc[1])
	{
		joy[1]->io_Command = CMD_CLEAR;
		joy[1]->io_Length  = 0L;
		joy[1]->io_Flags   = IOF_QUICK;
		DoIO(joy[1]);
		free_gp_unit(joy[1]);
	}
	CloseDevice(joy[1]);
	DeletePort(joy[1]->io_Message.mn_ReplyPort);
	DeleteStdIO(joy[1]);

/* tell input.device, that there is a mouse */

	InputMode = GPCT_MOUSE;
	InReq->io_Command = (UWORD)IND_SETMTYPE;
	InReq->io_Data = (APTR)&InputMode;
	InReq->io_Length = 1L;
	DoIO(InReq);

	CloseDevice(InReq);
	DeleteStdIO(InReq);
	DeletePort(InPort);
}

/*
 *	NAME
 *		void GetJoyData(port,joy)
 *
 *	FUNCTION
 *		gets joystick-data 
 *
 *	INPUT
 *		port: 0/1 for the game-ports
 *		joy:  pointer to a JoyMove structure
 *
 *	OUTPUT
 *		-
 *
 */

void GetJoyData(port,joy)
BYTE port;
struct JoyMove *joy;
{
register UWORD PortData;
register UWORD a,b;
	if(!port)
	{
		joy->Button = (((UBYTE)ciaa.ciapra) >> CIAB_GAMEPORT0) ^ 1;
		PortData = custom.joy0dat;
	}
	else
	{
		joy->Button = (((UBYTE)ciaa.ciapra) >> CIAB_GAMEPORT1) ^ 1;
		PortData = custom.joy1dat;
	}

	a = PortData >> 1;			/* Bits 1 und 9 nach 0 und 8 */
	b = PortData ^ a;			/* Bit 0: a ^ b, Bit 8: c ^ d */
	joy->xOff	= (a & 1) ? 1 : ( (a & 0x100) ? -1 : 0);
	joy->yOff	= (b & 1) ? 1 : ( (b & 0x100) ? -1 : 0);
}


Flame  me,  if  you  want, this is from a VERY OLD project, in fact one of my
first attempts in C, so if you find bugs, tell me.

Yes,  there  are  *LOTS*  of  error  checkings ( CreatePort(), DoIO() etc.  )
missing.  I'm a lazy typer, you know ;)


	Alloooooooha!
		Henning


-- 
  \\ _ Henning Schmiedehausen - barnard@forge.franken.de _ // Amiga - 
   \X/ --- Home of Barnard's Software Forge - ECG038 --- \X/  Learning to Fly

I'm  stepping  out,  I'm  movin' on, I'm gonna see the world.  Like a rolling
stone.  Stepping out. - E.L.O., Out of the blue.