home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- ** Snake.c - KABjorke 30 March 87 **
- ** © 1987, National Pixel Products **
- ** Released to the Public Domain for Non-Commercial Purposes. **
- ** A variant on the old "bouncing lines" program. **
- ** This version uses multiple vertices and Bezier splines. **
- *****************************************************************/
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <intuition/intuition.h>
- #include <graphics/gfx.h>
- #include <graphics/text.h>
-
- #define MAXVERT 15
-
- #define BGPEN 0
- #define FGPEN 1
- #define LOPEN 2
- #define HIPEN 3
-
- /* Event() return codes */
- #define DUNNO -1
- #define RESIZED 1
-
- #define TRAIL (Trails.Flags&CHECKED)
- #define POLYS (ShoPoly.Flags&CHECKED)
-
- /****************************************************************/
- /******* Built-Ins **********************************************/
- /****************************************************************/
-
- extern LONG GfxBase;
- extern LONG IntuitionBase;
-
- extern struct Window *OpenWindow();
- extern struct IntuiMessage *GetMsg();
-
- /****************************************************************/
- /******* Local IntuiJunk ****************************************/
- /****************************************************************/
-
- struct Window *w;
- struct RastPort *rp;
- struct IntuiMessage *message;
- USHORT class;
-
- struct TextAttr ROMFont8 = {
- "Topaz80",8,0,0 /* Define text font for our screen */
- };
-
- struct IntuiText SText[2] = {
- {LOPEN,BGPEN,JAM1,CHECKWIDTH,0,&ROMFont8,"Trails",NULL},
- {LOPEN,BGPEN,JAM1,CHECKWIDTH,0,&ROMFont8,"Poly", NULL}
- };
-
- struct MenuItem ShoPoly = {
- NULL, /* NextItem */
- 0,9,(CHECKWIDTH+50), 9, /* Corner, Size */
- ITEMTEXT|HIGHCOMP|ISDRAWN|ITEMENABLED|CHECKIT|MENUTOGGLE, /* Flags */
- 0L, /* MutualExclude */
- (APTR)&SText[1], NULL, /* ItemFill, SelectFill */
- '\0', /* Command */
- NULL, NULL /* SubItem, NextSelect */
- };
-
- struct MenuItem Trails = {
- &ShoPoly, /* NextItem */
- 0,0,(CHECKWIDTH+50), 9, /* Corner, Size */
- ITEMTEXT|HIGHCOMP|ISDRAWN|ITEMENABLED|CHECKIT|MENUTOGGLE, /* Flags */
- 0L, /* MutualExclude */
- (APTR)&SText[0], NULL, /* ItemFill, SelectFill */
- '\0', /* Command */
- NULL, NULL /* SubItem, NextSelect */
- };
-
- struct Menu Options = {
- NULL, /* NextMenu */
- 0,0,(CHECKWIDTH+54),9, /* Corner, Size */
- MIDRAWN|MENUENABLED, /* Flags */
- "Snake", /* MenuName */
- &Trails /* FirstItem */
- };
-
- /****************************************************************/
- /******* Window *************************************************/
- /****************************************************************/
-
- struct NewWindow nw = {
- 100,50, /* Starting corner */
- 300,100, /* Width, Height */
- LOPEN,HIPEN, /* DetailPen, BlockPen */
- CLOSEWINDOW|NEWSIZE, /* IDCMPFlags (Don't need MENUPICK!) */
- WINDOWDEPTH|ACTIVATE|WINDOWDRAG|WINDOWCLOSE|
- SMART_REFRESH|WINDOWSIZING, /* Flags */
- NULL, /* FirstGadget */
- NULL, /* Pointer to checkmark */
- "Snake", /* title */
- NULL, /* Screen */
- NULL, /* Bitmap */
- 50,50,640,400, /* Size limits */
- WBENCHSCREEN /* Type */
- };
-
- /****************************************************************/
- /******* Spline Vars ********************************************/
- /****************************************************************/
-
- float coeffs[4][MAXVERT];
- float P[2][4], Pv[2][4], xlf, ylf;
- SHORT xlim, ylim;
- SHORT DispVerts[(2*MAXVERT)];
- SHORT OldVerts[16][(2*MAXVERT)];
- SHORT control[8], oldcont[16][8];
-
- /****************************************************************/
- /****** Function Typing *****************************************/
- /****************************************************************/
-
- extern VOID AmiSetup();
- extern VOID SplineSetup();
- extern VOID CalcSnake();
- extern SHORT Event();
-
- /****************************************************************/
- /******* Execution Begins Here **********************************/
- /****************************************************************/
-
- VOID _main()
- {
- register UWORD i;
- register BOOL k;
- UWORD onward = 0;
- UWORD SnakeColr = FGPEN;
- UWORD PolyColr = HIPEN;
- LONG Iterate = 0L;
-
- AmiSetup();
- SplineSetup();
-
- xlim = w->Width - 3;
- ylim = w->Height - 2;
- xlf = (float)xlim;
- ylf = (float)ylim;
- for(i=0;i<4;++i) {
- P[0][i] = (float)(rand() % (xlim-2) + 1); /* random start */
- P[1][i] = (float)(rand() % (ylim-14) + 13);
- Pv[0][i] = (float)(rand() % 10 + 1); /* and vector */
- Pv[1][i] = (float)(rand() % 10 + 1);
- }
-
- class = NULL;
- do {
- CalcSnake();
- if ((!TRAIL) && (onward)) {
- SetAPen(rp,BGPEN); /* erase old */
- onward = Iterate & 15;
- Move(rp,OldVerts[onward][0],OldVerts[onward][1]);
- PolyDraw(rp,MAXVERT,&OldVerts[onward][0]);
- if (POLYS) {
- Move(rp,oldcont[onward][0],oldcont[onward][1]);
- PolyDraw(rp,4,&oldcont[onward][0]);
- }
- }
-
- SetAPen(rp,SnakeColr); /* Draw new Curve */
- Move(rp,DispVerts[0],DispVerts[1]);
- PolyDraw(rp,MAXVERT,&DispVerts[0]);
-
- if (POLYS) {
- SetAPen(rp,PolyColr);
- Move(rp,control[0],control[1]);
- PolyDraw(rp,4,&control[0]);
- }
- if((rand() & 127) < 2) { /* new color */
- PolyColr = SnakeColr;
- if (++SnakeColr > 3) SnakeColr = 1;
- }
-
- onward = (10 + Iterate++) & 15;
- for (i=0; i<(2*MAXVERT); ++i) /* old curve */
- OldVerts[onward][i] = DispVerts[i];
- for (i=0; i<8; ++i) /* old control points */
- oldcont[onward][i] = control[i];
-
- for(i=0;i<4;++i) { /* update control points */
- P[0][i] += Pv[0][i]; /* new control points */
- P[1][i] += Pv[1][i];
- if(P[0][i] < 2.0) { /* clipping */
- P[0][i] = 2.0; Pv[0][i] = -Pv[0][i];
- } else if(P[0][i] > xlf) {
- P[0][i] = xlf; Pv[0][i] = -Pv[0][i];
- }
- if(P[1][i] < 10.0) {
- P[1][i] = 10.0; Pv[1][i] = -Pv[1][i];
- } else if(P[1][i] > ylf) {
- P[1][i] = ylf; Pv[1][i] = -Pv[1][i];
- }
- if(((rand() >> 5) & 127) < 2) { /* change x speed */
- k = (Pv[0][i] < 0.0);
- Pv[0][i] = (rand() >> 5) & 7;
- if (k) Pv[0][i] = -Pv[0][i];
- }
- if(((rand() >> 5) & 255) < 50) { /* change y speed */
- k = (Pv[1][i] < 0.0);
- Pv[1][i] = (rand() >> 5) & 7;
- if (k) Pv[1][i] = -Pv[1][i];
- }
- }
- onward = 1;
- if(w->UserPort->mp_SigBit) {
- message = GetMsg(w->UserPort);
- if(message != NULL) {
- class = message->Class;
- ReplyMsg(message);
- }
- }
- } while(Event());
-
- ClearMenuStrip(w);
- CloseWindow(w);
- CloseLibrary(IntuitionBase);
- CloseLibrary(GfxBase);
- }
-
- /****************************************************************/
- /****** Analyse IDCMP events ************************************/
- /****************************************************************/
-
- SHORT Event()
- {
- switch(class) {
- case CLOSEWINDOW:
- return(NULL);
- break;
- case NEWSIZE:
- class = NULL;
- xlim = w->Width - 3;
- ylim = w->Height -2;
- xlf = (float)xlim;
- ylf = (float)ylim;
- return(RESIZED);
- break;
- }
- return(DUNNO);
- }
-
- /****************************************************************/
- /****** Set up display & libraries ******************************/
- /****************************************************************/
-
- VOID AmiSetup()
- {
- if ((GfxBase = OpenLibrary("graphics.library",LIBRARY_VERSION))
- == NULL) {
- Exit(20);
- }
- if ((IntuitionBase = OpenLibrary("intuition.library",LIBRARY_VERSION))
- == NULL) {
- CloseLibrary(GfxBase);
- Exit(20);
- }
- if ((w = OpenWindow(&nw)) == NULL) {
- CloseLibrary(IntuitionBase);
- CloseLibrary(GfxBase);
- Exit(20);
- }
- rp = w->RPort;
- SetAPen(rp,HIPEN);
- SetDrMd(rp,JAM1);
- SetMenuStrip(w,&Options);
- }
-
- /****************************************************************/
- /******* Precalculate Spline Coefficients ***********************/
- /****************************************************************/
-
- VOID SplineSetup()
- {
- float t;
- UWORD i;
- for (i=0; i<MAXVERT; ++i) {
- t = (float)i / (float)(MAXVERT-1);
- coeffs[3][i] = 1.0 - t;
- coeffs[2][i] = coeffs[3][i] * coeffs[3][i];
- coeffs[0][i] = t * (coeffs[1][i] = t*t);
- coeffs[1][i] *= (3.0 * coeffs[3][i]);
- coeffs[3][i] *= coeffs[2][i];
- coeffs[2][i] *= (3.0 * t);
- }
- }
-
-
- /****************************************************************/
- /****** Recalculate snake vertices ******************************/
- /****************************************************************/
-
- VOID CalcSnake()
- {
- register i, j;
- float xt, yt;
- short ndx;
- ndx = 0;
- for (i=0; i<MAXVERT; ++i) {
- xt = yt = 0.0;
- for (j=0; j<4; ++j) {
- xt += P[0][j] * coeffs[j][i];
- yt += P[1][j] * coeffs[j][i];
- }
- #ifdef DEBUG
- /* clip is unnessesary because of bounding-poly adherence */
- if (xt<2.0) xt = 2.0;
- if (xt>xlim) xt = xlim;
- if (yt<12.0) yt = 12.0;
- if (yt>ylim) yt = ylim;
- #endif DEBUG
- DispVerts[ndx++] = (SHORT)xt;
- DispVerts[ndx++] = (SHORT)yt;
- }
- ndx = 0;
- for (i=0; i<4; ++i) {
- control[ndx++] = (SHORT)P[0][i];
- control[ndx++] = (SHORT)P[1][i];
- }
- }
-
- /****************************************************************/
- /******************************************************** eof ***/
- /****************************************************************/
-