AMIGA: source to "amiga3d":, file 3 of 4 (1263 lines, 31013 chars)
Barry A. Whitebook
bart at amiga.UUCP
Thu Feb 27 09:24:19 AEST 1986
< eat this line... please! >
/***************************************************************/
displayuniverse.c
/***************************************************************/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <hardware/blit.h>
#include <hardware/custom.h>
#include <graphics/gfx.h>
#include <graphics/clip.h>
#include <graphics/rastport.h>
#include <graphics/view.h>
#include <graphics/text.h>
#include <graphics/gfxmacros.h>
#include <graphics/layers.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include "threed.h"
#define FIXEDILLUMINATION
extern UBYTE title[] ;
extern struct Custom custom;
extern struct TmpRas tmpras;
extern struct BitMap bitmap0;
extern struct BitMap bitmap1;
extern struct RastPort r[2];
extern struct RastPort *rp[2];
extern struct RasInfo ri[2];
extern struct RasInfo *rip[2];
extern struct RasInfo *irip;
extern WORD pcount ;
extern WORD vcount ;
extern UWORD frametoggle ;
extern BPTR objectsegment ;
extern struct Object *Amiga ;
extern long GfxBase;
extern long DosBase;
extern int (*subroutines[])();
/******************************************************************************/
displayuniverse(view,screen,window,cameraobjectinfo,objectinfo)
struct View *view;
struct Screen *screen;
struct Window *window;
struct Objectinfo *cameraobjectinfo;
struct Objectinfo *objectinfo;
{
int argc = 0;
char *argv[MAXNUMARGS];
struct Objectinfo *thisobjectinfo;
/* set up parameter passing information for this display */
argv[0] = &thisobjectinfo;
argv[1] = subroutines;
argc = 2;
/* PROCESS ALL THE OBJECTS IN THE LIST POINTED TO BY OBJECTINFO */
thisobjectinfo = objectinfo;
while(thisobjectinfo)
{
int thisobjecterror = FALSE;
/* process this object */
if(thisobjectinfo->objectprocedure)
{
int (*function)();
/* call the object's procedure */
#ifdef ODEBUG
printf("do3d: object(%lx) procedure = %lx\n",thisobjectinfo,thisobjectinfo->objectprocedure);
#endif
function = (thisobjectinfo->objectprocedure);
thisobjecterror = (*function)(argc,argv);
}
/* begin - rotate the object matrix - temporary */
/* yaw(thisobjectinfo->objectmatrix,SINB,COSB); */
/* pitch(thisobjectinfo->objectmatrix,SINB,COSB); */
/* roll(thisobjectinfo->objectmatrix,SINB,COSB); */
/* end - rotate the object matrix - temporary */
/* this objects's universal reference display matrix is trivial */
*thisobjectinfo->displaymatrix = *thisobjectinfo->objectmatrix;
/* this objects's universal reference position is trivial */
*thisobjectinfo->displayposition = *thisobjectinfo->objectposition;
/* process any subobjects dependent on this object before diplaying it */
{
struct Objectinfo *thisubobjectinfo;
thisubobjectinfo = thisobjectinfo->subobjectinfo;
while(thisubobjectinfo)
{
/* display each subobject */
subdisplayuniverse(view,screen,window,cameraobjectinfo,thisobjectinfo,thisubobjectinfo);
thisubobjectinfo = thisubobjectinfo->nextobjectinfo;
}
}
{
struct Coordinate centerpoint;
/* concatenate this object's matrix with the camera matrix for display through camera viewpoint */
{
struct UV uv;
uv = *thisobjectinfo->objectmatrix; /* copy matrix */
cat(thisobjectinfo->displaymatrix,&uv,cameraobjectinfo->objectmatrix);
}
subvect(cameraobjectinfo->objectposition,thisobjectinfo->displayposition,¢erpoint);
matrix(¢erpoint,¢erpoint,cameraobjectinfo->objectmatrix);
if ( (centerpoint.z > 0)
&&
(( (centerpoint.z) - ( (centerpoint.x < 0) ? -centerpoint.x : centerpoint.x )) > 0)
&&
(( (centerpoint.z) - ( (centerpoint.y < 0) ? -centerpoint.y : centerpoint.y )) > 0) )
{
/* rotate the 3d normals*/
#ifdef DEBUG
printf("do3d: rotate the 3d normals\n");
#endif
rotate(thisobjectinfo->displaymatrix,thisobjectinfo->objectnumnormals,thisobjectinfo->objectnormals,thisobjectinfo->objectbufnormals);
/* rotate, translate, and perspect the 3d points */
dopoints(thisobjectinfo->displaymatrix,¢erpoint,thisobjectinfo->objectnumpoints,thisobjectinfo->objectpoints,thisobjectinfo->objectbufpoints);
}
else
{
/* this object out of 45 degree frustrum */
thisobjectinfo = thisobjectinfo->nextobjectinfo;
/* so process the next object */
continue;
}
}
/* draw the polygons by traversing the polygon list */
{
WORD polycount = 0;
WORD *nextcolor;
struct Coordinate **nextn;
struct Coordinate **nextp;
struct Coordinate *lastn = 0;
WORD endflag = FALSE;
/* intialize buffer pointers */
nextcolor = thisobjectinfo->colorbuf;
nextn = thisobjectinfo->nptrbuf;
nextp = thisobjectinfo->pptrbuf;
for(polycount = 0; polycount < thisobjectinfo->objectnumpolys; polycount++)
{
struct Polygon **np;
WORD vc;
struct Coordinate **v;
struct Coordinate *n;
struct Coordinate *c0;
struct Coordinate *c1;
struct Coordinate *c2;
WORD bright;
WORD firstx, firsty;
#ifdef DEBUG
printf("poly %lx: \n",polycount);
#endif
np = (thisobjectinfo->objectpolys+polycount);
#ifdef DEBUG
printf("np = %lx\n",np);
#endif
#ifdef DEBUG
printf("vertexcount = %lx\n",(*np)->vertexcount);
#endif
#ifdef DRAWDEBUG
printf("poly %lx: color = %lx\n",polycount,*nextcolor);
#endif
/* backface removal */
/* first, simple clip */
if (((*nextn)->z) > 0)
{
nextcolor++;
nextn++;
nextp = (nextp+((*np)->vertexcount));
continue;
}
/* now, test z component of dynamically computed polygon normal */
c0 = (struct Coordinate *)(*(nextp));
c1 = (struct Coordinate *)(*(nextp+1));
c2 = (struct Coordinate *)(*(nextp+2));
/* if polygon's normal faces away from the screen, or is perpendicular, ignore it */
#ifdef DRAWDEBUG
printf("c0->x = %lx c0->y = %lx\n",c0->x,c0->y);
printf("c1->x = %lx c1->y = %lx\n",c1->x,c1->y);
printf("c2->x = %lx c2->y = %lx\n",c2->x,c2->y);
#endif
/* fine clipping */
if (((smuls(((c1->x)-(c0->x)),((c2->y)-(c1->y))))-(smuls(((c2->x)-(c1->x)),((c1->y)-(c0->y))))) >= 0)
{
nextcolor++;
nextn++;
nextp = (nextp+((*np)->vertexcount));
continue;
}
/* illumination */
#ifndef FIXEDILLUMINATION
bright = (((-(((*nextn)->x+(*nextn)->y))>>1)+(0x4000))>>11);
#else
bright = (WORD)*nextcolor;
#endif
/* ceiling */
bright = (bright > 0xF)?0xF:bright;
#ifdef DRAWDEBUG
printf("poly %lx: bright = %lx\n",polycount,bright);
#endif
for(vc = 0; vc < (*np)->vertexcount; vc++)
{
WORD x,y;
#ifdef DRAWDEBUG
printf("vertex %lx : (thisobjectinfo->objectbufpoints+poff) = %lx\n",vc,*nextp);
#endif
#ifdef DRAWDEBUG
printf("(thisobjectinfo->objectbufpoints+poff)->x = %lx\n",(*nextp)->x);
printf("(thisobjectinfo->objectbufpoints+poff)->y = %lx\n",(*nextp)->y);
printf("(thisobjectinfo->objectbufpoints+poff)->z = %lx\n",(*nextp)->z);
#endif
/* draw stuff in */
#ifdef DRAWDEBUG
printf("SetAPen = bright\n");
#endif
SetAPen(rp[frametoggle ^ 0x0001],bright);
if(vc == 0)
{
/* open this polygon */
#ifdef DRAWDEBUG
printf("call areamove...\n");
#endif
x = (((*nextp)->x)+(TMPWIDTH>>1));
y = (((*nextp)->y)+(TMPHEIGHT>>1));
if (x<0) x = 0;
if (y<0) y = 0;
if (x>TMPWIDTH-1) x = TMPWIDTH-1;
if (y>TMPHEIGHT-1) y = TMPHEIGHT-1;
x -= ( ( TMPWIDTH - (window->RPort->BitMap->BytesPerRow<<3) ) >> 1 );
y -= ( ( TMPHEIGHT - (window->RPort->BitMap->Rows) ) >> 1 );
firstx = x;
firsty = y;
/* move into the raster that we're NOT displaying */
#ifndef FIXEDILLUMINATION
if( (lastn != *nextn) && (endflag) )
{
AreaEnd(rp[frametoggle ^ 0x0001]);
endflag = FALSE;
}
#endif
AreaMove(rp[frametoggle ^ 0x0001],x,y);
}
else
{
/* continue this polygon */
#ifdef DRAWDEBUG
printf("call areadraw...\n");
#endif
x = (((*nextp)->x)+(TMPWIDTH>>1));
y = (((*nextp)->y)+(TMPHEIGHT>>1));
if (x<0) x = 0;
if (y<0) y = 0;
if (x>TMPWIDTH-1) x = TMPWIDTH-1;
if (y>TMPHEIGHT-1) y = TMPHEIGHT-1;
x -= ( ( TMPWIDTH - (window->RPort->BitMap->BytesPerRow<<3) ) >> 1 );
y -= ( ( TMPHEIGHT - (window->RPort->BitMap->Rows) ) >> 1 );
/* draw into the raster that we're NOT displaying */
AreaDraw(rp[frametoggle ^ 0x0001],x,y);
}
/* increment the nextp pointer */
nextp++;
}
/* close this polygon */
#ifdef DRAWDEBUG
printf("call areaend...\n");
#endif
/* end raster that we're NOT displaying (or continue collecting polygons) */
/* last polygon displayed is this one */
lastn = *nextn;
#ifndef FIXEDILLUMINATION
if(lastn == *(nextn+1))
{
/* last polygon displayed has same normal as next polygon to be displayed */
#ifdef DRAWDEBUG
printf("last poly displayed has same normal as next polygon to be displayed...draw\n");
#endif
/* draw, but do not terminate this polygon in this sequence */
/* note : need graphics 28.5 or greater to do following trick ! */
AreaDraw(rp[frametoggle ^ 0x0001],firstx,firsty);
endflag = TRUE;
/* if graphics 28.4 or less do this standard thing */
/* AreaEnd(rp[frametoggle ^ 0x0001]); */
/* endflag = FALSE; */
}
else
{
/* last polygon displayed has different normal from next polygon to be displayed */
#ifdef DRAWDEBUG
printf("last poly displayed has deffernt normal from next polygon to be displayed...end\n");
#endif
/* terminate this polygon sequence */
AreaEnd(rp[frametoggle ^ 0x0001]);
endflag = FALSE;
}
#else
{
/* terminate this polygon sequence */
AreaEnd(rp[frametoggle ^ 0x0001]);
endflag = FALSE;
}
#endif
/* increment nextcolor, nextn pointers */
nextcolor++;
nextn++;
}
if(endflag)
{
/* terminate series of "same normal" polygons after polyloop exit */
#ifdef DRAWDEBUG
printf("close last polygon in series...\n");
#endif
AreaEnd(rp[frametoggle ^ 0x0001]);
}
}
thisobjectinfo = thisobjectinfo->nextobjectinfo;
} /* end while (thisobject) */
}
/* END OF PROCESSING ALL THE OBJECTS */
/***************************************************************/
init.c
/***************************************************************/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <hardware/blit.h>
#include <hardware/custom.h>
#include <graphics/gfx.h>
#include <graphics/clip.h>
#include <graphics/rastport.h>
#include <graphics/view.h>
#include <graphics/text.h>
#include <graphics/gfxmacros.h>
#include <graphics/layers.h>
#include <intuition/intuition.h>
#include "threed.h"
/* #define DEBUG */
/* #define ODEBUG */
/* #define DEBUGDRAW */
/* #define TICKDEBUG */
/* #define TICKPRINT */
#define FIXEDILLUMINATION
#define CYCLECOLORS
#ifndef FIXEDILLUMINATION
extern UWORD colorpalette[];
#else
extern UWORD colorpalette[];
#endif
extern UBYTE title[];
extern struct Custom custom;
extern struct TmpRas tmpras;
extern struct BitMap bitmap0;
extern struct BitMap bitmap1;
extern struct RastPort r[];
extern struct RastPort *rp[];
extern struct RasInfo ri[];
extern struct RasInfo *rip[];
extern struct RasInfo *irip;
extern BOOL initobject;
extern WORD pcount;
extern WORD vcount;
extern UWORD frametoggle;
extern long GfxBase;
/******************************************************************************/
positioninit(c)
struct Coordinate *c;
{
c->x = 0;
c->y = 0;
c->z = 0;
}
matrixinit(um)
struct UV *um;
{
um->uv11 = 0x4000;
um->uv12 = 0;
um->uv13 = 0;
um->uv21 = 0;
um->uv22 = 0x4000;
um->uv23 = 0;
um->uv31 = 0;
um->uv32 = 0;
um->uv33 = 0x4000;
}
objectinit(view,screen,window,objectinfo,object)
struct View *view;
struct Screen *screen;
struct Window *window;
struct Objectinfo *objectinfo;
struct Object *object;
{
WORD *nextcolor;
struct Coordinate **nextn;
struct Coordinate **nextp;
int error = FALSE;
/* initialize */
objectinfo->subobjectinfo = NULL;
objectinfo->objectmatrix = object->umatrix;
objectinfo->objectposition = object->position;
objectinfo->objectnumpoints = object->pointcount;
objectinfo->objectpoints = object->pointstart;
objectinfo->objectnumnormals = object->normalcount;
objectinfo->objectnormals = object->normalstart;
objectinfo->objectnumpolys = object->polycount;
objectinfo->objectpolys = object->polystart;
objectinfo->objectprocedure = object->procedure;
if ((objectinfo->displaymatrix= (struct UV *)AllocMem(sizeof(struct UV), MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUG
printf("initobject: can't allocate objectinfo->displaymatrix...\n");
#endif
return(FALSE);
}
if ((objectinfo->displayposition= (struct UV *)AllocMem(sizeof(struct Coordinate), MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUG
printf("initobject: can't allocate objectinfo->displayposition...\n");
#endif
return(FALSE);
}
if (objectinfo->objectnumpoints)
if ((objectinfo->objectbufpoints = (struct Coordinate *)AllocMem(objectinfo->objectnumpoints * sizeof(struct Coordinate), MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUG
printf("initobject: can't allocate objectinfo->objectbufpoints...\n");
#endif
objectinfo->objectbufpointsize = 0;
return(FALSE);
}
else
{
objectinfo->objectbufpointsize = objectinfo->objectnumpoints * sizeof(struct Coordinate);
}
if (objectinfo->objectnumnormals)
if ((objectinfo->objectbufnormals = (struct Coordinate *)AllocMem(objectinfo->objectnumnormals * sizeof(struct Coordinate), MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUG
printf("initobject: can't allocate objectinfo->objectbufnormals ...\n");
#endif
objectinfo->objectbufnormalsize = 0;
return(FALSE);
}
else
{
objectinfo->objectbufnormalsize = objectinfo->objectnumnormals * sizeof(struct Coordinate);
}
/* traverse the polygon list and initialize buffers for color, poff lists */
for(pcount = 0; pcount < objectinfo->objectnumpolys; pcount++)
{
struct Polygon **np;
np = (objectinfo->objectpolys+pcount);
vcount += (*np)->vertexcount;
}
if( (objectinfo->pptrbuf = (APTR)AllocMem((sizeof(APTR)*(vcount+1)),MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUGDRAW
printf("draw: can't allocate objectinfo->pptrbuf...\n");
#endif
objectinfo->pptrbufsize = 0;
return(FALSE);
}
else
{
objectinfo->pptrbufsize = sizeof(APTR)*(vcount+1);
}
if( (objectinfo->nptrbuf = (APTR)AllocMem((sizeof(APTR)*(objectinfo->objectnumpolys+1)),MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUGDRAW
printf("draw: can't allocate objectinfo->nptrbuf...\n");
#endif
objectinfo->nptrbufsize = 0;
return(FALSE);
}
else
{
objectinfo->nptrbufsize = sizeof(APTR)*(objectinfo->objectnumpolys+1);
}
if( (objectinfo->colorbuf = (APTR)AllocMem((sizeof(WORD)*(objectinfo->objectnumpolys+1)),MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
#ifdef DEBUGDRAW
printf("draw: can't allocate objectinfo->colorbuf...\n");
#endif
objectinfo->colorbufsize = 0;
return(FALSE);
}
else
{
objectinfo->colorbufsize = sizeof(WORD)*(objectinfo->objectnumpolys+1);
}
/* intialize buffer pointers */
nextcolor = objectinfo->colorbuf;
nextn = objectinfo->nptrbuf;
nextp = objectinfo->pptrbuf;
for(pcount = 0; pcount < objectinfo->objectnumpolys; pcount++)
{
struct Polygon **np;
WORD vc;
struct Coordinate **v;
struct Coordinate *n;
long noff;
WORD color;
#ifdef DEBUG
printf("poly %lx: \n",pcount);
#endif
np = (objectinfo->objectpolys+pcount);
#ifdef DEBUG
printf("np = %lx\n",np);
#endif
v = (*np)->vertexstart;
n = (*np)->normalvector;
noff = n - (*(objectinfo->objectnormals));
color = (*np)->polycolor;
#ifdef DEBUG
printf("v = %lx\n", v);
printf("vertexcount = %lx\n",(*np)->vertexcount);
printf("n = %lx\n", n);
#endif
*nextcolor++ = color;
*nextn++ = (struct Coordinate *)(objectinfo->objectbufnormals+noff);
#ifdef DEBUGDRAW
printf("poly %lx: color = %lx\n",pcount,color);
#endif
#ifdef DEBUGDRAW
printf("(objectinfo->objectbufnormals+noff)->x = %lx\n",(objectinfo->objectbufnormals+color)->x);
printf("(objectinfo->objectbufnormals+noff)->y = %lx\n",(objectinfo->objectbufnormals+color)->y);
printf("(objectinfo->objectbufnormals+noff)->z = %lx\n",(objectinfo->objectbufnormals+color)->z);
#endif
for(vc = 0; vc < (*np)->vertexcount; vc++)
{
long poff;
#ifdef DEBUG
printf("v = %lx\n", v);
printf("vc = %lx\n",vc);
printf("v+vc = %lx\n",v+vc);
printf("(*(v+vc)) = %lx\n",(*(v+vc)));
#endif
poff = (*(v+vc)) - (*(objectinfo->objectpoints));
/* poff = (long)(*(v+vc)); */
*nextp++ = (struct Coordinate *)(objectinfo->objectbufpoints+poff);
#ifdef DEBUGDRAW
printf("vertex %lx : poff = %lx\n",vc,poff);
#endif
#ifdef DEBUGDRAW
printf("(objectinfo->objectbufpoints+poff)->x = %lx\n",(objectinfo->objectbufpoints+poff)->x);
printf("(objectinfo->objectbufpoints+poff)->y = %lx\n",(objectinfo->objectbufpoints+poff)->y);
printf("(objectinfo->objectbufpoints+poff)->z = %lx\n",(objectinfo->objectbufpoints+poff)->z);
#endif
}
}
/* terminate pointer buffer arrays with a null pointer */
*nextcolor = 0;
*nextn = 0;
*nextp = 0;
/* allocate subobjectinfo structures dependent on this object */
{
struct Object *ob;
/* for all the objects in this objectsegment */
for (ob = object->subobject ; ob; ob = ob->nextobject)
{
struct Objectinfo *thisubobjectinfo;
#ifdef ODEBUG
printf("objectinit: allocate objectinfo for subobject(%lx) ",ob);
#endif
/* allocate an objectinfo structure for the current object */
if ((thisubobjectinfo = (struct Objectinfo *)AllocMem(sizeof(struct Objectinfo),MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
return(error);
}
#ifdef ODEBUG
printf("= %lx\n",thisubobjectinfo);
#endif
/* initialize the buffers for the current 3d subobject */
if(!objectinit(view,screen,window,thisubobjectinfo,ob))
{
return(error);
}
/* make this objectinfo last on the subobjectinfo list */
{
struct Objectinfo **soipp;
soipp = &objectinfo->subobjectinfo;
while (*soipp)
{
soipp = &((*soipp)->nextobjectinfo);
}
*soipp = thisubobjectinfo;
thisubobjectinfo->nextobjectinfo = NULL;
}
}
}
#ifdef ODEBUG
printf("objectinit: &objectinfo->subobjectinfo = %lx\n",&objectinfo->subobjectinfo );
{
struct Objectinfo *soip;
printf(" SUBOBJECTINFO LIST \n");
printf("_________________________\n");
for (soip = objectinfo->subobjectinfo; soip; soip = soip->nextobjectinfo)
printf(" subobjectinfo(%lx)\n",soip);
printf("_________________________\n");
}
#endif
return(TRUE);
}
/***************************************************************/
joystick.c
/***************************************************************/
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <devices/gameport.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include "joystick.h"
/*#define DEBUG*/
/*#define DEBUGSTATE*/
#define MAXNUMEVENTS 2
extern LONG IntuitionBase;
struct IntuiText ErrorText= { /* text for error-requester */
0, 1, JAM1, /* FrontPen, BackPen, DrawMode */
10, 10, /* LeftEdge, TopEdge */
NULL, /* ITextFont */
"3D: Software Error:", /* IText */
NULL /* NextText */
};
struct IntuiText AbortMessage= { /* more text for error-message requester */
0, 1, JAM1, /* FrontPen, BackPen, DrawMode */
11, 45, /* LeftEdge, TopEdge */
NULL, /* ITextFont */
"Select ABORT to exit", /* IText */
NULL /* NextText */
};
struct IntuiText ResumeMessage= { /* more text for error-message requester */
0, 1, JAM1, /* FrontPen, BackPen, DrawMode */
11, 45, /* LeftEdge, TopEdge */
NULL, /* ITextFont */
"Select RESUME to continue", /* IText */
NULL /* NextText */
};
struct IntuiText AbortText= { /* more text for error-requester */
0, 1, JAM1, /* FrontPen, BackPen, DrawMode */
6, 4, /* LeftEdge, TopEdge */
NULL, /* ITextFont */
"ABORT", /* IText */
NULL /* NextText */
};
struct IntuiText ResumeText= { /* more text for error-requester */
0, 1, JAM1, /* FrontPen, BackPen, DrawMode */
6, 4, /* LeftEdge, TopEdge */
NULL, /* ITextFont */
"RESUME", /* IText */
NULL /* NextText */
};
extern struct MsgPort *CreatePort();
extern DeletePort();
extern struct IOStdReq *CreateStdIO();
extern DeleteStdIO();
/******************************************************************************/
ULONG set_flags(joystick_data,flags)
struct InputEvent *joystick_data;
ULONG flags;
{
SHORT xmove, ymove;
xmove = joystick_data->ie_X;
ymove = joystick_data->ie_Y;
switch(ymove)
{
case(-1): flags |= BUTTON_FORWARD;
flags &= ~BUTTON_BACK;
break;
case( 0): flags &= ~BUTTON_FORWARD;
flags &= ~BUTTON_BACK;
break;
case( 1): flags &= ~BUTTON_FORWARD;
flags |= BUTTON_BACK;
break;
default: break;
}
switch(xmove)
{
case(-1): flags |= BUTTON_LEFT;
flags &= ~BUTTON_RIGHT;
break;
case( 0): flags &= ~BUTTON_LEFT;
flags &= ~BUTTON_RIGHT;
break;
case( 1): flags &= ~BUTTON_LEFT;
flags |= BUTTON_RIGHT;
break;
default: break;
}
if(joystick_data->ie_Code != IECODE_NOBUTTON)
{
if(joystick_data->ie_Code == IECODE_LBUTTON)
{
if (!(flags & ACTION))
{
flags |= BUTTON_DOWN;
flags &= ~NO_BUTTON;
}
}
if(joystick_data->ie_Code == (IECODE_LBUTTON + IECODE_UP_PREFIX))
{
if (!(flags & BUTTON_DOWN))
{
flags |= BUTTON_UP;
flags &= ~NO_BUTTON;
}
else
{
if (!(flags & ACTION))
{
flags |= ACTION;
flags |= BUTTON_UP;
flags &= ~NO_BUTTON;
}
else
{
flags |= BUTTON_UP;
flags &= ~NO_BUTTON;
}
}
}
}
else
{
if (!(flags & ACTION))
{
if (!(flags & (BUTTON_DOWN | BUTTON_UP)))
{
flags |= NO_BUTTON;
}
}
}
if (flags & ACTION)
{
UBYTE actioncount;
actioncount = ((flags & 0xFF00) >> 8 );
actioncount += 1;
flags = ( (flags & 0xFFFF00FF) | (actioncount<<8) );
flags &= ~BUTTON_DOWN;
flags &= ~BUTTON_UP;
flags &= ~ACTION;
}
#ifdef DEBUG
switch(ymove)
{
case (-1): switch(xmove)
{
case(-1):
#ifdef DEBUG
printf("NW");
#endif
break;
case( 0):
#ifdef DEBUG
printf("N ");
#endif
break;
case( 1):
#ifdef DEBUG
printf("NE");
#endif
break;
default: break;
}
break;
case ( 0): switch(xmove)
{
case(-1):
#ifdef DEBUG
printf(" W");
#endif
break;
case( 0):
#ifdef DEBUG
printf(" ");
#endif
break;
case( 1):
#ifdef DEBUG
printf(" E");
#endif
break;
default: break;
}
break;
case ( 1): switch(xmove)
{
case(-1):
#ifdef DEBUG
printf("SW");
#endif
break;
case( 0):
#ifdef DEBUG
printf("S ");
#endif
break;
case( 1):
#ifdef DEBUG
printf("SE");
#endif
break;
default: break;
}
break;
default: break;
}
#endif
#ifdef DEBUG
if(joystick_data->ie_Code != IECODE_NOBUTTON)
{
if(joystick_data->ie_Code == IECODE_LBUTTON)
#ifdef DEBUG
printf("!");
#endif
if(joystick_data->ie_Code == (IECODE_LBUTTON + IECODE_UP_PREFIX))
#ifdef DEBUG
printf("#");
#endif
}
else
{
#ifdef DEBUG
/* printf(" "); */
#endif
}
#endif
return(flags);
}
struct IOStdReq *open_joystick()
{
struct MsgPort *joystick_msg_port;
struct IOStdReq *joystick_io_request;
BYTE *joystick_eventbuf;
struct Message *message;
LONG error = FALSE;
#ifdef DEBUG
printf("joystick...entering\n");
#endif
if ( (IntuitionBase = OpenLibrary("intuition.library", 31)) == NULL)
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
exit(0);
}
/* allocate memory for the joystick event buffer */
if ( (joystick_eventbuf = (BYTE *)AllocMem(sizeof(struct InputEvent)*MAXNUMEVENTS,MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
exit(0);
}
/* provide a port for the IO request/response */
joystick_msg_port = CreatePort("joystickport",0);
if(joystick_msg_port == 0)
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
exit(-1);
}
/* make an io request block for communicating with the joystick device */
joystick_io_request = CreateStdIO(joystick_msg_port);
if(joystick_io_request == 0)
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
DeletePort(joystick_msg_port);
exit(-2);
}
/* open the gameport device for access, unit 1 is right port */
if(OpenDevice("gameport.device",1,joystick_io_request,0))
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
FreeMem(joystick_eventbuf,sizeof(struct InputEvent) * MAXNUMEVENTS);
DeleteStdIO(joystick_io_request);
DeletePort(joystick_msg_port);
exit(-4);
}
/* set the device type to absolute joystick */
if (set_controller_type(joystick_io_request,GPCT_ABSJOYSTICK) != 0)
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
FreeMem(joystick_eventbuf,sizeof(struct InputEvent) * MAXNUMEVENTS);
DeleteStdIO(joystick_io_request);
DeletePort(joystick_msg_port);
exit(-4);
}
/* trigger on button-down, button-up, front, back, left, right, center */
if (set_controller_trigger(joystick_io_request,GPTF_UPKEYS+GPTF_DOWNKEYS,1,1,1) != 0)
{
ErrorText.NextText = &AbortMessage;
AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
FreeMem(joystick_eventbuf,sizeof(struct InputEvent) * MAXNUMEVENTS);
DeleteStdIO(joystick_io_request);
DeletePort(joystick_msg_port);
exit(-4);
}
/* SETUP THE IO MESSAGE BLOCK FOR THE ACTUAL DATA READ */
/* gameport.device replies to this task */
joystick_io_request->io_Message.mn_ReplyPort = joystick_msg_port;
/* from now on, just read input events */
joystick_io_request->io_Command = GPD_READEVENT;
/* into the input buffer, one at a time. */
joystick_io_request->io_Data = joystick_eventbuf;
/* read num events each time we go back to the joystickport */
joystick_io_request->io_Length = sizeof(struct InputEvent)* MAXNUMEVENTS;
return(joystick_io_request);
}
ULONG test_joystick(joystick_io_request,state)
struct IOStdReq *joystick_io_request;
ULONG state;
{
ULONG flags;
struct InputEvent *joystick_data;
/* test the joystick */
if (DoIO(joystick_io_request)) return(state);
flags = state;
for (joystick_data = joystick_io_request->io_Data; joystick_data; joystick_data = joystick_data->ie_NextEvent)
{
flags = set_flags(joystick_data,flags);
}
state = flags;
#ifdef DEBUGSTATE
printf("\nstate: %4lx",state);
#endif
return(state);
}
close_joystick(joystick_io_request)
struct IOStdReq *joystick_io_request;
{
/* close up joystick device */
CloseDevice(joystick_io_request);
/* clean up */
FreeMem(joystick_io_request->io_Data,sizeof(struct InputEvent) * MAXNUMEVENTS);
DeletePort(joystick_io_request->io_Message.mn_ReplyPort);
DeleteStdIO(joystick_io_request);
}
int set_controller_type(ior,type)
struct IOStdReq *ior;
BYTE type;
{
ior->io_Command = GPD_SETCTYPE;
ior->io_Length = 1;
/* set type of controller to "type" */
ior->io_Data = &type;
#ifdef DEBUG
printf("joystick:set_controller_type\n");
#endif
return(DoIO(ior));
}
int set_controller_trigger(ior,keys,timeout,xdelta,ydelta)
struct IOStdReq *ior;
UWORD keys,timeout,xdelta,ydelta;
{
struct GamePortTrigger gpt;
ior->io_Command = GPD_SETTRIGGER;
ior->io_Length = sizeof(gpt);
ior->io_Data = &gpt;
gpt.gpt_Keys = keys;
gpt.gpt_Timeout = timeout;
gpt.gpt_XDelta = xdelta;
gpt.gpt_YDelta = ydelta;
#ifdef DEBUG
printf("joystick:set_controller_trigger\n");
#endif
return(DoIO(ior));
}
/*
main()
{
ULONG state = 0;
struct IOStdReq *ior;
if ((ior = open_joystick()) == NULL)
{
exit(-1);
}
else
{
while ( ( (state & 0xFF00) >> 8 ) != 0xF )
{
state = test_joystick(ior,state);
}
close_joystick(ior);
}
exit(0);
}
*/
/***************************************************************/
More information about the Comp.sources.unix
mailing list