/**************************************************************** * Polygon drawing demo by John M. Olsen * This demo uses the AreaMove, AreaDraw and AreaEnd Functions. * It uses a hold and modify (HAM) screen, and the polygons can be * any of the possible 4096 colors. This is done by using a patterned * area fill, using separate patterns to modify the red, green, and blue * to get to the correct color as fast as possible. * * My appologies for the sparceness of comments. It is hopefully clear * what I was doing for the most part. * * This is meant to be compiled with the Manx compiler, and has not been * tried under Lettuce. * * This software is in the public domain, and you can do whatever you want * to or with it. * * John M. Olsen * 1547 Jamestown Drive * Salt Lake City, UT 84121 ****************************************************************/ #include #include #include #include #include #include void *OpenLibrary(); struct Window *OpenWindow(), *w, *w2; struct Screen *OpenScreen(), *s; struct IntuiMessage *GetMsg(), *msg; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; BYTE *AllocRaster(); WORD areabuffer[250]; struct TmpRas tmpras; struct AreaInfo myAreaInfo; USHORT a[] = { 0x9429, 0x4294 }; USHORT b[] = { 0x4294, 0x2942 }; /***************************************************************** definition of the 320 X 200 HAM screen. *****************************************************************/ struct NewScreen ss = { /*****************/ 0, /* LeftEdge */ 0, /* TopEdge */ 320, /* Width */ 200, /* Height */ 6, /* Depth */ 0, /* DetailPen */ 1, /* BlockPen */ HAM, /* ViewModes */ CUSTOMSCREEN, /* Type */ NULL, /* *Font */ (UBYTE *) "A Dancing Polygon", /* *DefaultTitle */ NULL, /* *Gadgets */ NULL /* *CustomBitMap */ }; /*****************/ struct NewWindow ww = { /****************/ 0, /* LeftEdge */ 10, /* TopEdge */ 320, /* Width */ 190, /* Height */ -1, /* DetailPen */ -1, /* BlockPen */ CLOSEWINDOW, /* IDCMP */ WINDOWCLOSE | ACTIVATE | NOCAREREFRESH | WINDOWDRAG, NULL, /* *FirstGadget */ NULL, /* *CheckMark */ (UBYTE *)"By John M. Olsen", /* *Title */ NULL, /* Screen */ NULL, /* *Bitmap */ 0,0,0,0, /* Min/Max w,h */ CUSTOMSCREEN /* Type */ }; struct NewWindow ww2 = { /****************/ 0, /* LeftEdge */ 0, /* TopEdge */ 320, /* Width */ 190, /* Height */ -1, /* DetailPen */ -1, /* BlockPen */ NULL, /* IDCMP */ BACKDROP | NOCAREREFRESH, NULL, /* *FirstGadget */ NULL, /* *CheckMark */ (UBYTE *)NULL, /* *Title */ NULL, /* Screen */ NULL, /* *Bitmap */ 0,0,0,0, /* Min/Max w,h */ CUSTOMSCREEN /* Type */ }; main(argc,argv) int argc; char *argv[]; { setup(); drawstuff(); die(0); } setup() { if(!(GfxBase = OpenLibrary("graphics.library",0l))) die(1); if(!(IntuitionBase = OpenLibrary("intuition.library", 0l))) die(2); if(!(s = OpenScreen(&ss))) die(4); ww.Screen = s; ww2.Screen = s; if(!(w = OpenWindow(&ww2))) die(4); if(!(w2 = OpenWindow(&ww))) die(4); /* Set up a buffer for the AreaMove, AreaDraw, and AreaEnd commands */ InitArea(&myAreaInfo, areabuffer, 100l); w->RPort->AreaInfo = &myAreaInfo; tmpras.RasPtr = (BYTE *) AllocRaster(320l, 200l); tmpras.Size = (long) RASSIZE(320l, 200l); w->RPort->TmpRas = &tmpras; } drawstuff() { struct RastPort *r; register long loop; long red, green, blue, x[10], y[10], dx[10], dy[10]; for(loop = 0l; loop < 5l; loop++) { /* init the position */ x[loop] = (long)random(w->Width - w->BorderLeft - w->BorderRight) + w->BorderLeft; y[loop] = (long)random(w->Height - w->BorderTop - w->BorderBottom) + w->BorderTop; dx[loop] = dy[loop] = 0L; } r = w->RPort; msg = GetMsg(w2->UserPort); while(msg->Class != CLOSEWINDOW) { if(msg) ReplyMsg(msg); msg = GetMsg(w2->UserPort); /* draw with 2 colors this time, and just one the next to */ /* get all 3 colors modified. */ SetDrMd(r, JAM2); red += random(3) - 1; green += random(3) - 1; blue += random(3) - 1; if(red < 32L) red = 32L; if(red > 47L) red = 47L; if(green < 48L) green = 48L; if(green > 63L) green = 63L; if(blue < 16L) blue = 16L; if(blue > 31L) blue = 31L; SetAPen(r, (long)red); SetBPen(r, (long)green); /* use 1L as the last parameter if you want to use a 2 word */ /* pattern, which will give sevier jaggies. */ SetAfPt(r, &a, 0L); /* Do a 5 point polygon */ for(loop = 0l; loop < 5l; loop++) { dx[loop] += (long)random(3) - 1L; dy[loop] += (long)random(3) - 1L; if(dy[loop] > 5L) dy[loop] = 5L; if(dx[loop] > 5L) dx[loop] = 5L; if(dy[loop] < -5L) dy[loop] = -5L; if(dx[loop] < -5L) dx[loop] = -5L; if(x[loop] + dx[loop] > w->Width - w->BorderRight || x[loop] + dx[loop] < w->BorderLeft) dx[loop] *= -1; if(y[loop] + dy[loop] > w->Height - w->BorderBottom || y[loop] + dy[loop]< w->BorderTop) dy[loop] *= -1; x[loop] += dx[loop]; y[loop] += dy[loop]; if(x[loop] > w->Width - w->BorderRight) x[loop] = w->Width - w->BorderRight; if(x[loop] < w->BorderLeft) x[loop] = w->BorderLeft; if(y[loop] > w->Height - w->BorderBottom) y[loop] = w->Height - w->BorderBottom; if(y[loop] < w->BorderTop) y[loop] = w->BorderTop; if(loop == 0l) AreaMove(r, x[loop], y[loop]); else AreaDraw(r, x[loop], y[loop]); } AreaEnd(r); SetDrMd(r, JAM1); SetAPen(r, (long)blue); SetAfPt(r, &b, 0L); for(loop = 0l; loop < 5l; loop++) { if(loop == 0l) AreaMove(r, x[loop], y[loop]); else AreaDraw(r, x[loop], y[loop]); } AreaEnd(r); WaitTOF(); ClipBlit(r, 0L, 10L, w2->RPort, 0L, 10L, (long)w->Width, (long)w->Height-10L, 0xc0L); } if(msg) ReplyMsg(msg); } /**************************************************************** * I don't think this random number will set any speed records, but * it is guaranteed to be as random as you can get. ****************************************************************/ random(max) int max; { static ULONG num; ULONG sec, mic; CurrentTime(&sec, &mic); num *= sec; num += mic; while(num > 32000) num = num >> 1; return((int)(num % (ULONG)max)); } die(kind) int kind; { static char *msgs[] = { "", /* err 1 */ "Unable to open graphics library.\n", /* err 2 */ "Unable to open intuition library.\n", /* err 4 */ "Unable to open a window.\n", "\n" }; if(kind) puts(msgs[kind]); if(tmpras.RasPtr) FreeRaster(tmpras.RasPtr,320l,200l); if(w) CloseWindow(w); if(w2) CloseWindow(w2); if(s) CloseScreen(s); if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); exit(kind); }