bart@amiga.UUCP (Barry A. Whitebook) (02/27/86)
< 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); } */ /***************************************************************/