AMIGA: source to "amiga3d":, file 4 of 4 (873 lines, 19845 chars)
bart at amiga.UUCP
bart at amiga.UUCP
Thu Feb 27 09:28:51 AEST 1986
< eat this line... please! >
/***************************************************************/
objectallocate.c
/***************************************************************/
#include <exec/types.h>
#include <exec/memory.h>
#include "threed.h"
allocateobjectinfolist(view,screen,window,firstobjectinfo,firstobject)
struct View *view;
struct Screen *screen;
struct Window *window;
struct Objectinfo **firstobjectinfo;
struct Object *firstobject;
{
struct Object *ob;
int error = FALSE;
/* allocate objectinfo structures */
/* for all the objects in this objectsegment */
for (ob = firstobject; ob; ob = ob->nextobject)
{
struct Objectinfo *thisobjectinfo;
#ifdef CAMERADEBUG
printf("test3d: allocate objectinfo for object(%lx) ",ob);
#endif
/* allocate an objectinfo structure for the current object */
if ((thisobjectinfo = (struct Objectinfo *)AllocMem(sizeof(struct Objectinfo),MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{
error = TRUE;
return(error);
}
#ifdef CAMERADEBUG
printf("= %lx\n",thisobjectinfo);
#endif
/* initialize the buffers for the current 3d object */
if(!objectinit(view,screen,window,thisobjectinfo,ob))
{
error = TRUE;
return(error);
}
/* make this objectinfo last on the objectinfo list */
{
struct Objectinfo **oipp;
oipp = firstobjectinfo;
while (*oipp)
{
oipp = &((*oipp)->nextobjectinfo);
}
*oipp = thisobjectinfo;
thisobjectinfo->nextobjectinfo = NULL;
}
}
}
deallocateobjectinfolist(view,screen,window,firstobjectinfo)
struct View *view;
struct Screen *screen;
struct Window *window;
struct Objectinfo **firstobjectinfo;
{
/* deallocate objectinfo structures */
#ifdef ODEBUG
printf("test3d: deallocate the active objectinfo structures...\n");
#endif
while( (*firstobjectinfo) )
{
struct Objectinfo *oip;
/* delink the first objectinfo from the objectinfo list */
oip = *firstobjectinfo;
(*firstobjectinfo) = (*firstobjectinfo)->nextobjectinfo;
/* deallocate the buffers dependent on the current objectinfo */
#ifdef ODEBUG
printf(" deallocate objectinfo(%lx)\n",oip);
#endif
objectdeallocate(view,screen,window,oip);
/* deallocate this objectinfo structure itself */
FreeMem(oip,sizeof(struct Objectinfo));
}
}
/***************************************************************/
startgfxdos.c
/***************************************************************/
#define MAXPOINTS 64
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.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 <exec/memory.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/interrupts.h>
#include <graphics/copper.h>
#include <hardware/dmabits.h>
#include <hardware/custom.h>
#include <graphics/gfxmacros.h>
#include <devices/timer.h>
#include "threed.h"
#define IS_PAL (((struct GfxBase *)GfxBase)->DisplayFlags & PAL)
long TimerBase;
struct timerequest *timerio;
extern struct Custom custom;
/* #define DEBUG */
/* #define TICKDEBUG */
long GfxBase = 0;
long LayersBase = 0;
long IntuitionBase = 0;
long DosBase = 0;
struct AreaInfo areainfo;
UWORD areafill[(MAXPOINTS/2)*5];
int gettime()
{
int ticks;
DoIO(timerio);
ticks = timerio->tr_time.tv_secs*60;
ticks += (timerio->tr_time.tv_micro*60)/1000000;
return(ticks);
}
inittimer(usrproc,view,screen, window)
int (*usrproc)();
struct View *view;
struct Screen *screen;
struct Window *window;
{
int error = FALSE;
/* allocate a timerequest structure */
timerio = (APTR)AllocMem(sizeof(struct timerequest),MEMF_CLEAR);
/* open the timer device */
TimerBase = OpenDevice("timer.device",UNIT_VBLANK,timerio,0);
/* initialize stuff to read timer value back */
timerio->tr_node.io_Command = TR_GETSYSTIME;
error = (*usrproc)(view,screen,window);
/* close timer device */
CloseDevice(timerio);
/* clean up */
FreeMem(timerio,sizeof(struct timerequest));
return(error);
}
timeproc(usrproc,view,screen, window)
int (*usrproc)();
struct View *view;
struct Screen *screen;
struct Window *window;
{
int error = FALSE;
int starttime;
starttime = gettime();
error = (*usrproc)(view,screen,window);
if (!error)
{
return(gettime() - starttime);
}
else
{
return(error);
}
}
startgfxdos(x,y,height,width,n_bit_planes,usrproc,s,flags,tmpras,sbitmap)
WORD x,y;
UWORD height, width, n_bit_planes;
int (*usrproc)();
UBYTE *s;
ULONG flags;
struct TmpRas *tmpras;
struct BitMap *sbitmap;
{
struct Screen *screen;
struct Window *window;
struct RastPort *w;
struct View *view;
short idcmp;
struct NewWindow nw;
struct NewScreen ns;
int error = FALSE;
#ifdef DEBUG
printf("startgfxdos: opening graphics lib...\n");
#endif
if ( (!GfxBase) && ( (GfxBase = OpenLibrary("graphics.library",0) ) == NULL) )
{
#ifdef DEBUG
printf("startgfxdos: can't open graphics lib...\n");
#endif
return((int)-1);
}
#ifdef DEBUG
printf("startgfxdos: opening layers lib...\n");
#endif
if ( (LayersBase = OpenLibrary("layers.library",0)) == NULL)
{
#ifdef DEBUG
printf("startgfxdos: can't open layers lib...\n");
#endif
return((int)-1);
}
#ifdef DEBUG
printf("startgfxdos: opening intuition lib...\n");
#endif
if ( (IntuitionBase = OpenLibrary("intuition.library",0)) == NULL)
{
#ifdef DEBUG
printf("startgfxdos: can't open intuition lib...\n");
#endif
return((int)-1);
}
ns.LeftEdge = x;
ns.TopEdge = 0;
ns.Width = width;
ns.Height = ((height>(IS_PAL?PAL_MAXHINOLACE:NTSC_MAXHINOLACE))?(IS_PAL?PAL_MAXHILACE:NTSC_MAXHILACE):(IS_PAL?PAL_MAXHINOLACE:NTSC_MAXHINOLACE));
ns.Depth = n_bit_planes;
ns.DetailPen = -1;
ns.BlockPen = -1;
ns.ViewModes = ( 0 | ((width > 320)?HIRES:0) | ((height>(IS_PAL?PAL_MAXHINOLACE:NTSC_MAXHINOLACE))?LACE:0) );
ns.Type = CUSTOMSCREEN;
ns.Font = NULL;
ns.DefaultTitle = NULL;
ns.Gadgets = NULL;
#ifdef DEBUG
printf("startgfxdos: opening a custom screen...\n");
#endif
if ( (screen = (struct Screen *)OpenScreen(&ns)) == NULL)
{
#ifdef DEBUG
printf("startgfxdos: can't open a custom screen...\n");
#endif
return((int)-1);
}
screen->ViewPort.DxOffset = x;
#ifdef DEBUG
printf("startgfxdos: calling makescreen, rethinkdisplay...\n");
#endif
MakeScreen(screen);
RethinkDisplay();
ShowTitle(screen,FALSE); /* let backdrop window title bars show */
idcmp = CLOSEWINDOW;
nw.LeftEdge = 0;
nw.TopEdge = y;
nw.Width = width;
nw.Height = height;
nw.DetailPen = -1;
nw.BlockPen = -1;
nw.IDCMPFlags = idcmp;
nw.Flags = WINDOWCLOSE|flags;
nw.FirstGadget = NULL;
nw.CheckMark = NULL;
nw.Title = s;
nw.Screen = screen;
nw.BitMap = sbitmap;
nw.MinWidth = width;
nw.MinHeight = height;
nw.MaxWidth = width;
nw.MaxHeight = height;
nw.Type = CUSTOMSCREEN;
#ifdef DEBUG
printf("startgfxdos: opening a window in the custom screen...\n");
#endif
if ( (window = (struct Window *)OpenWindow(&nw)) == NULL )
{
#ifdef DEBUG
printf("startgfxdos: can't open a new window...\n");
#endif
return((int)-1);
}
if(window->RPort)
{
#ifdef DEBUG
printf("startgfxdos: initialize and link areainfo to this window's rastport...\n");
#endif
InitArea(&areainfo,areafill,MAXPOINTS);
window->RPort->AreaInfo = &areainfo;
}
else
{
#ifdef DEBUG
printf("startgfxdos: null window rastport pointer...\n");
#endif
return((int)-1);
}
#ifdef DEBUG
printf("startgfxdos: trying to find the view adress...\n");
#endif
if ( (view = (struct View *)ViewAddress()) == NULL)
{
#ifdef DEBUG
printf("startgfxdos: can't get view address...\n");
#endif
return((int)-1);
}
window->RPort->TmpRas = tmpras;
#ifdef DEBUG
printf("startgfxdos: calling the usrproc routine ...\n");
#endif
#ifdef TICKDEBUG
#ifdef DEBUG
printf("though the inittimer routine ...\n");
#endif
error = inittimer(usrproc,view,window->WScreen,window);
#else
error = (*usrproc)(view,window->WScreen,window);
#endif
#ifdef DEBUG
printf("startgfxdos: returnted from the usrproc with error = %lx...\n",error);
#endif
#ifdef DEBUG
printf("startgfxdos: close the window...\n");
#endif
CloseWindow(window);
#ifdef DEBUG
printf("startgfxdos: close the screen...\n");
#endif
CloseScreen(screen);
return(error);
}
/***************************************************************/
subdisplay.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[])();
/******************************************************************************/
subdisplayuniverse(view,screen,window,cameraobjectinfo,objectinfo,subobjectinfo)
struct View *view;
struct Screen *screen;
struct Window *window;
struct Objectinfo *cameraobjectinfo;
struct Objectinfo *objectinfo;
struct Objectinfo *subobjectinfo;
{
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 = subobjectinfo;
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);
}
/* concatenate this submatrix with the next higher level display matrix */
{
struct UV uv;
uv = *thisobjectinfo->objectmatrix;
transpose(&uv);
cat(thisobjectinfo->displaymatrix,&uv,objectinfo->displaymatrix);
transpose(thisobjectinfo->displaymatrix);
}
/* convert this object's position to the next higher lever display frame-of-reference */
matrix(thisobjectinfo->displayposition,thisobjectinfo->objectposition,
objectinfo->displaymatrix);
/* then determine this subobjects's universal reference position */
addvect(thisobjectinfo->displayposition,objectinfo->displayposition,
thisobjectinfo->displayposition);
/* process any subobjects dependent on this object before displaying it */
{
struct Objectinfo *nextsubobjectinfo;
nextsubobjectinfo = thisobjectinfo->subobjectinfo;
while(nextsubobjectinfo)
{
/* subdisplay each next subobject */
subdisplayuniverse(view,screen,window,cameraobjectinfo,thisobjectinfo,nextsubobjectinfo);
nextsubobjectinfo = nextsubobjectinfo->nextobjectinfo;
}
}
{
struct Coordinate centerpoint;
/* concatenate this object's matrix with the camera matrix for display through camera viewpoint */
{
struct UV uv1, uv2;
subvect(cameraobjectinfo->objectposition,thisobjectinfo->displayposition,¢erpoint);
uv1 = *thisobjectinfo->displaymatrix;
uv2 = *cameraobjectinfo->objectmatrix;
transpose(&uv1);
/*transpose(&uv2);*/
cat(thisobjectinfo->displaymatrix,&uv2,&uv1);
/*transpose(thisobjectinfo->displaymatrix);*/
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 subdisplaying */
#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 subdisplaying */
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 subdisplaying (or continue collecting polygons) */
/* last polygon subdisplayed is this one */
lastn = *nextn;
#ifndef FIXEDILLUMINATION
if(lastn == *(nextn+1))
{
/* last polygon subdisplayed has same normal as next polygon to be subdisplayed */
#ifdef DRAWDEBUG
printf("last poly subdisplayed has same normal as next polygon to be subdisplayed...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 subdisplayed has different normal from next polygon to be subdisplayed */
#ifdef DRAWDEBUG
printf("last poly subdisplayed has deffernt normal from next polygon to be subdisplayed...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 */
/***************************************************************/
More information about the Comp.sources.unix
mailing list