home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- /* Garden.c - An "electronic wallpaper" amusement based on finite-state **
- ** automata **
- ** © 1987, Kevin A. Bjorke **
- ** National Pixel Products, Valencia, CA 91355 **
- ** Nov 84, Nov 85, March 86, May 87 **
- *************************************************************************/
-
- /*************************************************
- ** Compile under Lattice 3.10 like so: **
- ** lc -b -r -v -qram: -M Garden **
- ** blink with Garden.With **
- ** Where file Garden.With contains: **
- ** FROM lib:c.o sys:Garden.o **
- ** TO sys:Garden **
- ** LIB lib:amiga.lib lib:lc.lib **
- ** MAP ram:Garden.map **
- ** VERBOSE **
- ** PLAIN **
- ** SMALLCODE **
- ** SMALLDATA **
- ** NODEBUG **
- *************************************************/
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <intuition/intuition.h>
- #include <graphics/text.h>
-
- #define SPAN 320 /* Number of Cell units */
- #define EMPTY 0 /* No cell here (in tube[][]) */
- #define CELL 1 /* Cell here */
- #define MINLINE 1 /* top (vertical) scanline */
- #define MAXLINE 200 /* bottom scanline */
-
- #define SpanClip(a) ((a)<0)?(SPAN+(a)):(((a)>=SPAN)?((a)-SPAN):(a))
- #define SpanClip2(a) ((a)>=SPAN)?((a)-SPAN):(a)
-
- /****************************************************************/
- /****** Misc Externs & IntuiStuff *******************************/
- /****************************************************************/
-
- extern long GfxBase;
- extern long IntuitionBase;
- extern struct InputEvent *Intuition();
- extern struct Window *OpenWindow();
- extern struct Screen *OpenScreen();
-
- /****************/
-
- extern VOID AmiSetup(); /* forward declarations of functions below */
- extern VOID AmiCleanup();
- extern VOID Grow();
- extern VOID CellSetup();
- extern VOID DrawOld();
- extern UWORD Age();
- extern SHORT Event();
-
- /****************************************************************/
- /********* IntuiJunk ********************************************/
- /****************************************************************/
-
- struct TextAttr ROMFont8 = {
- "topaz.font",8,0,0
- };
-
- USHORT class = NULL;
- USHORT code;
- struct Window *wn = NULL;
- struct Screen *sc = NULL;
- struct RastPort *rp;
- struct ViewPort *vp;
- struct IntuiMessage *message;
-
- /****************************************************************/
- /****************************************************************/
- /****************************************************************/
-
- struct IntuiText MenText[3] = {
- {19,1,JAM1,0,0,&ROMFont8,"About",NULL},
- {17,1,JAM1,0,0,&ROMFont8,"Clear",NULL},
- {15,1,JAM1,0,0,&ROMFont8,"Quit", NULL}
- };
-
- struct MenuItem Quits = {
- NULL, 0,18, 50,9, ITEMTEXT|ITEMENABLED|HIGHCOMP,
- 0L,(APTR)&MenText[2], NULL,'\0',NULL,0
- };
-
- struct MenuItem Clear = {
- &Quits, 0,9, 50,9, ITEMTEXT|ITEMENABLED|HIGHCOMP,
- 0L,(APTR)&MenText[1], NULL,'\0',NULL,0
- };
-
- struct MenuItem About = {
- &Clear, 0,0, 50,9, ITEMTEXT|ITEMENABLED|HIGHCOMP,
- 0L,(APTR)&MenText[0], NULL,'\0',NULL,0
- };
-
- struct Menu Garden = {
- NULL, 0,0, (7<<3),9,MENUENABLED|MIDRAWN,
- "Garden",&About
- };
-
- struct IntuiText ReqText[7] = {
- {15,1,JAM2,10, 8,&ROMFont8,"GARDEN by Kevin Bjorke",&ReqText[1]},
- { 6,1,JAM2,10,16,&ROMFont8,"© 1987, National Pixel",&ReqText[2]},
- {19,1,JAM2,18,24,&ROMFont8,"CIS:74756,464", &ReqText[3]},
- {31,1,JAM2,18,32,&ROMFont8,"PLink:OJS637", &ReqText[4]},
- {17,1,JAM2,18,40,&ROMFont8,"BIX:kbjorke", NULL},
- {13,1,JAM2,AUTOLEFTEDGE,AUTOTOPEDGE,&ROMFont8,"Okay",NULL},
- {13,1,JAM2,AUTOLEFTEDGE,AUTOTOPEDGE,&ROMFont8,"Fine",NULL}
- };
-
- UWORD GardenCMap[32] = { /* Colors */
- 0x22D,0xFC2,0x9C0,0x4A0,0x360,0x7C0,0xA4A,0x4A0,
- 0x380,0x190,0x0A0,0x2B8,0x4AD,0x77E,0x2C4,0xB05,
- 0x5B0,0xB72,0x933,0x080,0xFFE,0x183,0x2C6,0x9D0,
- 0x777,0x4A0,0xD92,0xA4A,0xEE0,0x7C0,0xF83,0x77E
- };
-
- /****************************************************************/
- /****** Screen **************************************************/
- /****************************************************************/
-
- struct NewScreen ns = {
- 0,0, /* start pos.*/
- 320,200,5, /* width height depth (2 bit planes) */
- 3,0, /* detail pen, block pen */
- 0, /* ViewModes */
- CUSTOMSCREEN, /* Type */
- &ROMFont8, /* Font */
- NULL, /* Title */
- NULL, NULL /* Gadgets, CustomBitMap */
- };
-
- /****************************************************************/
- /******** Window ************************************************/
- /****************************************************************/
-
- struct NewWindow nw = {
- 0,0,320,200,
- 12,0, /* detail, block pens */
- MENUPICK, /* IDCMPFlags */
- BACKDROP|BORDERLESS|SMART_REFRESH|ACTIVATE, /* Flags */
- NULL, /* FirstGadget */
- NULL, /* CheckMark */
- NULL, /* Title */
- NULL, /* Screen */
- NULL, /* CustomBitMap */
- 0,0,0,0, /* sizing limits */
- CUSTOMSCREEN
- };
-
- /****************************************************************/
- /******* Gardening Variables ************************************/
- /****************************************************************/
-
- UBYTE tube[2][SPAN]; /* cell reproduction happens here */
- UWORD new = 0;
- UWORD old = 1;
- SHORT CellColr = 0;
- SHORT ScanLine = -1;
-
- /****************************************************************/
- /***** Execution Begins *****************************************/
- /****************************************************************/
-
- VOID _main()
- {
- ULONG Seconds, Micros;
- AmiSetup();
- CurrentTime(&Seconds,&Micros);
- srand((unsigned)(Micros & 0xFFFF));
- do {
- if (ScanLine<MINLINE)
- CellSetup();
- else
- Grow();
- if(wn->UserPort->mp_SigBit) {
- message = (struct IntuiMessage *)GetMsg(wn->UserPort);
- if(message != NULL) {
- class = message->Class;
- code = message->Code;
- ReplyMsg(message);
- }
- }
- } while(Event());
- AmiCleanup();
- }
-
- /****************************************************************/
- /****** IDCMP Filtering *****************************************/
- /****************************************************************/
-
- SHORT Event()
- {
- register UWORD u;
- SHORT MNum, INum;
- if (class == MENUPICK) {
- class = NULL;
- MNum = MENUNUM(code);
- INum = ITEMNUM(code);
- if ((MNum == 0)&&(INum == 2)) {
- return(NULL); /* byebye */
- }
- if ((MNum == 0)&&(INum == 1)) {
- /* SetRast(rp,0); */
- for (u=0;u<200;u+=4) {
- ScrollRaster(rp,0,-4,0,0,320,200);
- WaitTOF();
- }
- ScanLine = -1;
- return(2);
- }
- if ((MNum == 0)&&(INum == 0)) {
- AutoRequest(wn,&ReqText[0],&ReqText[5],&ReqText[6],
- NULL,NULL,(36+(22<<3)),85);
- return(3);
- }
- }
- class = NULL;
- return(-1);
- }
-
- /****************************************************************/
- /***** Main Action **********************************************/
- /****************************************************************/
-
- VOID Grow()
- {
- DrawOld();
- if (Age() > 0) {
- old = new;
- new ^= 1;
- --ScanLine;
- } else {
- ScanLine = -1; /* force a CellSetup() */
- }
- }
-
- /****************************************************************/
- /****** Display Most-recent layer *******************************/
- /****************************************************************/
-
- VOID DrawOld()
- {
- UWORD CellCt;
- Move(rp,0,ScanLine);
- for (CellCt = 0; CellCt < SPAN; ++CellCt) {
- if (tube[old][CellCt] == CELL)
- WritePixel(rp,CellCt,ScanLine);
- }
- }
-
- /****************************************************************/
- /***** Make a Random Cell Line **********************************/
- /****************************************************************/
-
- VOID CellSetup()
- {
- register UWORD CellCt, j;
- old = 0;
- new = 1;
- for (CellCt = 0; CellCt < SPAN; ++CellCt) {
- if ((CellCt & 15) == 0)
- j = rand();
- tube[old][CellCt] = (j & 1);
- j >>= 1;
- }
- CellColr = ++CellColr & 31;
- SetAPen(rp,CellColr);
- ScanLine = (MAXLINE-1);
- }
-
- /****************************************************************/
- /***** Generate New Cells ***************************************/
- /****************************************************************/
-
- /*****************************************************************
- ** Algorithm Notes: **
- ** This algorithm is extremely simple, and has little basis in **
- ** real growth mechanisms, except perhaps those of lakeside **
- ** algae. Instead, it's more akin to Conway's LIFE, but is only **
- ** one-dimensional -- by saving the history as successive scan- **
- ** lines, we get plantlike growths. The algorithm is this: scan **
- ** the local pixel and its four closest neighbors. If the the **
- ** sum is 2 or 4, live. If not, die. Simple, eh? **
- *****************************************************************/
-
- UWORD Age()
- {
- register UWORD nCells = 0;
- register UWORD where;
- register SHORT trail, nPals, CellCt;
-
- nPals = tube[old][SPAN-3] + tube[old][SPAN-2] + tube[old][SPAN-1] +
- tube[old][0] + tube[old][1]; /* Solve LAST cell first */
- for(CellCt=0; CellCt<SPAN; ++CellCt) {
- trail = SpanClip(CellCt-3); /* solve incrementally */
- where = SpanClip2(CellCt+2); /* never negative */
- nPals += (tube[old][where]-tube[old][trail]);
- if ((nPals==2)||(nPals==4)) {
- tube[new][CellCt] = CELL;
- ++nCells;
- } else {
- tube[new][CellCt] = EMPTY;
- }
- }
- return(nCells);
- }
-
- /****************************************************************/
- /******* Setup Screen *******************************************/
- /****************************************************************/
-
- VOID AmiSetup()
- {
- if ((GfxBase = OpenLibrary("graphics.library",LIBRARY_VERSION)) == NULL)
- Exit(1);
- if ((IntuitionBase = OpenLibrary("intuition.library",LIBRARY_VERSION)) ==
- NULL) {
- AmiCleanup();
- Exit(1);
- }
- if ((sc = OpenScreen(&ns)) == NULL) {
- AmiCleanup();
- Exit(0);
- }
- nw.Screen = sc;
- if ((wn = OpenWindow(&nw)) == NULL) {
- AmiCleanup();
- Exit(2);
- }
- rp = wn->RPort;
- vp = &wn->WScreen->ViewPort;
- LoadRGB4(vp,GardenCMap,32);
- ShowTitle(sc,FALSE);
- SetAPen(rp,1);
- SetDrMd(rp,JAM1);
- SetMenuStrip(wn,&Garden);
- }
-
- /****************************************************************/
- /****************************************************************/
- /****************************************************************/
-
- VOID AmiCleanup()
- {
- if (wn != NULL) {
- ClearMenuStrip(wn);
- CloseWindow(wn);
- }
- if (sc != NULL)
- CloseScreen(sc);
- if (GfxBase != NULL)
- CloseLibrary(GfxBase);
- if (IntuitionBase != NULL)
- CloseLibrary(IntuitionBase);
- }
-
- /****************************************************************/
- /******************************************************** eof ***/
- /****************************************************************/
-
-