/* ---------------------------- S p i n 3 . c ------------------------------ */ /* This is a simple routine that creates some spinning cubes and transforms */ /* them into op-art. It is a good example of how to take total control of */ /* of the screen for graphics and create a double buffered display (with */ /* color tables that can be changed!) */ /* I place it in the public domain so long as no one uses it for profit and */ /* these comments remain with the source code. */ /* Ronald Peterson PeopleLink: OPS448 BIX: rpeterson */ /*---------------------------------------------------------------------------*/ /*--- INCLUDE's ------------------------------------------------------------ */ #include "stdio.h" #include "math.h" #include "limits.h" #include "exec/types.h" #include "graphics/gfx.h" #include "graphics/gfxmacros.h" #include "graphics/copper.h" #include "graphics/view.h" #include "graphics/regions.h" #include "graphics/clip.h" #include "exec/exec.h" #include "graphics/gfxbase.h" #include "graphics/rastport.h" #include "hardware/custom.h" #include "hardware/dmabits.h" /*--- DEFINE's --------------------------------------------------------------*/ #define DEPTH 4 #define COLORS 16 /* COLORS = 2**DEPTH */ #define WIDTH 320 #define HEIGHT 200 #define NOT_ENOUGH_MEMORY -1000 /*--- GLOBAL variable definitions -------------------------------------------*/ struct View v; struct ViewPort vp; struct ColorMap *cm; /* pointer to colormap structure, dynamic alloc */ struct RasInfo ri; struct BitMap b; /* note: Due to the static allocation of a structure * accessed directly by the custom chips, this program * will only work if it resides entirely within the lower * 512k bytes of memory (CHIP memory) */ struct BitMap b2; /* second bitmap for double buffering */ struct cprlist *lof1; /* copper list pointers for double buffer */ struct cprlist *lof2; struct cprlist *shf1; struct cprlist *shf2; struct CopList *Disp1, *Disp2; extern int Enable_Abort; /*--- RastPort variables ----------------- */ PLANEPTR rastpoint, rastpoint2; struct RastPort rp; struct RastPort rp2; WORD areabuffer[250]; struct TmpRas tmpras; struct AreaInfo myAreaInfo; WORD areabuffer2[250]; struct TmpRas tmpras2; struct AreaInfo myAreaInfo2; /*--- My global variables */ extern struct Custom custom; /* so that graphics macros work. OFF_SPRITE */ extern struct ColorMap *GetColorMap(); struct GfxBase *GfxBase; struct View *oldview; /* save pointer to old view so can restore */ USHORT colortable[COLORS] = {0x0000, 0x0222, 0x0444, 0x0555, 0x0666, 0x0777, 0x0888, 0x0999, 0x0AAA, 0x0BBB, 0x0CCC, 0x0DDD, 0x0EEE, 0x0FFF, 0x0005, 0x000A}; /* set colors shades of white, Light blue, Medium blue */ /* 0-13 14 15 */ USHORT j, tmp; UBYTE *displaymem; UWORD *colorpalette; /*--- Start of main routine -------------------------------------------------*/ main() { SHORT bx[30], by[30], bz[30], dx[30], dy[30], dz[30]; SHORT size[30], xminus, xplus, yminus, yplus; SHORT cx, cy, cz, half, nobj; LONG i; SHORT k, icol[30], icol2, xhalf, dxhalf, ncol; static SHORT icl[8] = {256, 16, 1, 4096, -256, -16, -1 ,-4096}; static float scl[7] = {1.0, 1.138, 1.276, 1.414, 1.276, 1.138, 1.0}; /*--- Open graphics and Intuition libraries */ GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0); if(GfxBase == NULL)exit(1); oldview = GfxBase->ActiView; /* Save current view to restore later */ /* Steals screen from Intuition if */ /* started from WorkBench. */ /*--- Initialize graphics structures and create double buffered display. */ OFF_SPRITE; /* turn off pointer (sprites off) */ InitView(&v); /* initialize view */ InitVPort(&vp); /* initialize viewport */ v.ViewPort = &vp; /* link view into viewport */ InitBitMap(&b,DEPTH,WIDTH,HEIGHT); /* Init two bitmaps for double */ InitBitMap(&b2,DEPTH,WIDTH,HEIGHT); /* buffering (for RasInfo & RastPort) */ ri.BitMap = &b; /* Init RasInfo structure */ ri.RxOffset = 0; ri.RyOffset = 0; ri.Next = NULL; vp.DWidth = WIDTH; /* Specify ViewPort characteristics. */ vp.DHeight = HEIGHT; vp.RasInfo = &ri; cm = GetColorMap(COLORS); /* Init color table (16 slots since 4 planes deep */ vp.ColorMap = cm; /* Set ViewPort pointer to my colors */ LoadRGB4(&vp,colortable,COLORS); /* Set viewport colors */ for(i=0; iDspIns; /* To get color map to change properly */ v.LOFCprList = 0; v.SHFCprList = 0; v.ViewPort->DspIns = 0; ri.BitMap = &b2; MakeVPort(&v,&vp); MrgCop(&v); lof2 = v.LOFCprList; /* store pointers to copper lists for bitmap 2 */ shf2 = v.SHFCprList; Disp2 = v.ViewPort->DspIns; LoadView(&v); /* tell copper to use list for display */ InitRastPort(&rp); /* Initialize first RastPort */ rp.BitMap = &b; /* link rastport to bitmap 1 */ SetDrMd(&rp,JAM1); /* set draw mode to JAM1 */ InitArea(&myAreaInfo, areabuffer, 100); /* Vertice buffer for Fill */ rp.AreaInfo = &myAreaInfo; rastpoint = (PLANEPTR)AllocRaster(WIDTH,HEIGHT); InitTmpRas(&tmpras, rastpoint, RASSIZE(WIDTH,HEIGHT)); rp.TmpRas = &tmpras; InitRastPort(&rp2); /* Do same for second RastPort */ rp2.BitMap = &b2; /* link rastport to bitmap */ SetDrMd(&rp2,JAM1); /* set draw mode to JAM1 */ InitArea(&myAreaInfo2, areabuffer2, 100); /* Vertice buffer for Fill */ rp2.AreaInfo = &myAreaInfo2; rastpoint2 = (PLANEPTR)AllocRaster(WIDTH,HEIGHT); InitTmpRas(&tmpras2, rastpoint2, RASSIZE(WIDTH,HEIGHT)); rp2.TmpRas = &tmpras2; /*--- Set outline colors and clear bitmaps. */ SetOPen(&rp,0); /* set outline color */ SetOPen(&rp2,0); /* set outline color */ Enable_Abort = 0; /* disable automatic CTRL-C abort */ SetRast(&rp2,0); /* clear bitmap 2 */ SetRast(&rp,0); /* clear bitmap 1 */ /*--- Set up positions, sizes, and directions for balls. */ for(i=0; i<30; i++) { bx[i] = RangeRand(239) + 40; /* pick an initial location inside */ by[i] = RangeRand(119) + 40; /* the clipping range. */ bz[i] = RangeRand(239) + 40; dx[i] = RangeRand(30) - 15; dy[i] = RangeRand(30) - 15; dz[i] = RangeRand(30) - 15; if(dx[i] == 0)dx[i] = 10; /* zero dx not allowed */ if(dy[i] == 0)dy[i] = 10; if(dz[i] == 0)dz[i] = 10; size[i] = (319-bz[i])/12+ 1; /* ball size is a function of z */ } for(k=0; k<30; k++) /* Initialize cube parameters */ { icol[k] = RangeRand(6) + 7; } /*--- Swap buffers, alternately drawing into each */ ncol = 0; nobj = 3; for(i=0; i<100000; i++) { if(0 != Chk_Abort()) /* check for CTRL-C abort */ { goto dats_all; } v.LOFCprList = lof1; /* set pointers to copper lists and */ v.SHFCprList = shf1; /* set RastPort bitmap pointer */ v.ViewPort->DspIns = Disp1; WaitBOVP(&vp); /* wait till in vertical blank area */ LoadView(&v); /* display bitmap 1 */ if(i < 100)SetRast(&rp2,0); /* clear bitmap 2 */ if(i > 250) { tmp = colortable[0]; /* rotate colors */ for(j=0; j<15; j++) { colortable[j] = colortable[j+1]; } colortable[15] = tmp; } if(i > 200)ncol = RangeRand(15); colortable[ncol] = (colortable[ncol] + icl[RangeRand(8)]) & 0x0FFF; if(i > 150)LoadRGB4(&vp,colortable,COLORS); /* Set viewport colors */ if(i < 200) { SetAPen(&rp2,14); /* Set wall color */ AreaMove(&rp2, 0, 0); AreaDraw(&rp2, 0, 199); AreaDraw(&rp2, 80, 150); AreaDraw(&rp2, 80, 50); AreaEnd(&rp2); SetAPen(&rp2,11); /* Set wall color */ AreaMove(&rp2, 319, 0); AreaDraw(&rp2, 319, 199); AreaDraw(&rp2, 240, 150); AreaDraw(&rp2, 240, 50); AreaEnd(&rp2); SetAPen(&rp2,15); /* Set floor/ceiling color */ AreaMove(&rp2, 0, 0); AreaDraw(&rp2, 80, 50); AreaDraw(&rp2, 240, 50); AreaDraw(&rp2, 319, 0); AreaMove(&rp2, 0, 199); AreaDraw(&rp2, 80, 150); AreaDraw(&rp2, 240, 150); AreaDraw(&rp2, 319, 199); AreaEnd(&rp2); } /* if(i < 150) /* start with one object, then go to three */ nobj = 3; else nobj = 10; */ for(k=0; k 319) /* clip & change direction. */ { bx[k] = 319 - size[k]; dx[k] = RangeRand(10) - 11; /* set negative dx */ } if(by[k]+size[k] > 199) { by[k] = 199 - size[k]; dy[k] = RangeRand(10) - 11; } if(bz[k] > 319) { bz[k] = 319; dz[k] = RangeRand(10) - 11; } if(bx[k]-size[k] < 0) { bx[k] = size[k]; dx[k] = RangeRand(10) + 1; /* set positive dx */ } if(by[k]-size[k] < 0) { by[k] = size[k]; dy[k] = RangeRand(10) + 1; } if(bz[k] < 20) { bz[k] = 20; dz[k] = RangeRand(10) + 1; } cx = bx[k]; cy = by[k]; cz = bz[k]; perspective(&cx, &cy, &cz); /* do perspective xform */ half = size[k]/2; icol[k] = icol[k] - 1; if(icol[k] < 7)icol[k] = 13; icol2 = icol[k] - 7; dxhalf = scl[icol2]*half; xhalf = cx - dxhalf + icol2*dxhalf/3; xminus = cx-dxhalf; xplus = cx+dxhalf; yminus = cy-half; yplus = cy+half; SetAPen(&rp2,icol2); /* Set color to show rotation */ AreaMove(&rp2, xminus, yminus); AreaDraw(&rp2, xhalf, yminus); AreaDraw(&rp2, xhalf, yplus); AreaDraw(&rp2, xminus, yplus); AreaEnd(&rp2); SetAPen(&rp2,icol[k]); /* Set color to show rotation */ AreaMove(&rp2, xhalf, yminus); AreaDraw(&rp2, xplus, yminus); AreaDraw(&rp2, xplus, yplus); AreaDraw(&rp2, xhalf, yplus); AreaEnd(&rp2); } v.LOFCprList = lof2; /* set pointers to copper lists and */ v.SHFCprList = shf2; /* set RastPort bitmap pointer */ v.ViewPort->DspIns = Disp2; WaitBOVP(&vp); /* wait till in vertical blank area */ LoadView(&v); /* display bitmap 2 */ if(i < 100)SetRast(&rp,0); /* clear bitmap 1 */ if(i > 150)LoadRGB4(&vp,colortable,COLORS); /* Set viewport colors */ if(i < 200) { SetAPen(&rp,14); /* Set wall color */ AreaMove(&rp, 0, 0); AreaDraw(&rp, 0, 199); AreaDraw(&rp, 80, 150); AreaDraw(&rp, 80, 50); AreaEnd(&rp); SetAPen(&rp,11); /* Set wall color */ AreaMove(&rp, 319, 0); AreaDraw(&rp, 319, 199); AreaDraw(&rp, 240, 150); AreaDraw(&rp, 240, 50); AreaEnd(&rp); SetAPen(&rp,15); /* Set floor color */ AreaMove(&rp, 0, 0); AreaDraw(&rp, 80, 50); AreaDraw(&rp, 240, 50); AreaDraw(&rp, 319, 0); AreaMove(&rp, 0, 199); AreaDraw(&rp, 80, 150); AreaDraw(&rp, 240, 150); AreaDraw(&rp, 319, 199); AreaEnd(&rp); } for(k=0; k 319) /* clip & change direction. */ { bx[k] = 319 - size[k]; dx[k] = RangeRand(10) - 11; /* set negative dx */ } if(by[k]+size[k] > 199) { by[k] = 199 - size[k]; dy[k] = RangeRand(10) - 11; } if(bz[k] > 319) { bz[k] = 319; dz[k] = RangeRand(10) - 11; } if(bx[k]-size[k] < 0) { bx[k] = size[k]; dx[k] = RangeRand(10) + 1; /* set positive dx */ } if(by[k]-size[k] < 0) { by[k] = size[k]; dy[k] = RangeRand(10) + 1; } if(bz[k] < 20) { bz[k] = 20; dz[k] = RangeRand(10) + 1; } cx = bx[k]; cy = by[k]; cz = bz[k]; perspective(&cx, &cy, &cz); /* do perspective xform */ half = size[k]/2; icol[k] = icol[k] - 1; if(icol[k] < 7)icol[k] = 13; icol2 = icol[k] - 7; dxhalf = scl[icol2]*half; xhalf = cx - dxhalf + icol2*dxhalf/3; xminus = cx-dxhalf; xplus = cx+dxhalf; yminus = cy-half; yplus = cy+half; SetAPen(&rp,icol2); /* Set color to show rotation */ AreaMove(&rp, xminus, yminus); AreaDraw(&rp, xhalf, yminus); AreaDraw(&rp, xhalf, yplus); AreaDraw(&rp, xminus, yplus); AreaEnd(&rp); SetAPen(&rp,icol[k]); /* Set color to show rotation */ AreaMove(&rp, xhalf, yminus); AreaDraw(&rp, xplus, yminus); AreaDraw(&rp, xplus, yplus); AreaDraw(&rp, xhalf, yplus); AreaEnd(&rp); } } dats_all: ON_SPRITE; /* turn on pointer (sprites on) */ LoadView(oldview); /* put back the old view */ FreeMemory(); /* exit gracefully */ CloseLibrary(GfxBase); /* since opened library, close it */ } /* End of main ----------------------------------------------------------*/ /* return user and system-allocated memory to sys manager */ FreeMemory() { int i; FreeRaster(rastpoint,WIDTH,HEIGHT); /* Free drawing areas */ FreeRaster(rastpoint2,WIDTH,HEIGHT); for(i=0; i