home *** CD-ROM | disk | FTP | other *** search
- echo; /* Self-compilation stuff ala John Toebes for Lattice users:
- lc -M bdemon.c bdintui.c bdblit.c bdwin.c
- blink with bdemon.with
- quit
-
- *****************************************************************************
- * BlitDemons by Walter Strickler
- * This program and all its source code are in the public domain and are
- * freely distributable and usable for any purpose, private or commercial.
- *
- * This program is a port of a program by Loren Blaney which runs under
- * Apex, an unknown operating system on the Amiga. It is based on the
- * cellular automaton called 'Demons' described in the August, 1989,
- * issue of Scientific American.
- *
- * It is not my fault that it busy-waits. This is usually inexcusable in
- * an Amiga program, but it is the call to WaitBlit() that causes it. It is
- * really a shame, since this program should require only a small portion of
- * the 68000. As it is, it hogs all of it.
- ****************************************************************************/
-
-
- #include <math.h>
- #include "bdemon.h"
-
-
- int main()
- {
- int IntuiReturn,
- IPRet,
- RetVal;
- struct BDMainStruct BDStuff;
-
- IntuiReturn = InitIntui();
- if (IntuiReturn == INTUI_OK)
- {
- IPRet = InitPlanes(&BDStuff, BDWindow);
- if (IPRet != PLANES_CHOKE)
- {
- BDStuff.BDBlitNodes = InitBlits(&BDStuff);
- if (BDStuff.BDBlitNodes != NULL)
- {
- RetVal = MainLoop(&BDStuff);
- }
- else
- {
- RetVal = INIT_BLIT_CHOKE;
- }
- } /* End BDStuff OK */
- else
- {
- RetVal = PLANES_CHOKE;
- } /* End BDStuff not OK */
- KillPlanes(&BDStuff);
- }
- else /* Single entry, single exit: so there, Guy! */
- {
- RetVal = IntuiReturn;
- }
- CloseIntui();
- ErrorMsgs(RetVal);
- return RetVal;
- } /* End main() */
-
-
- void ErrorMsgs(ErrorNum)
- int ErrorNum;
- {
- switch (ErrorNum)
- {
- case 0:
- break; /* A-OK */
- case NO_INTUI:
- printf("Couldn't open Intuition!\n");
- break;
- case NO_GFX:
- printf("Couldn't open Graphics!\n");
- break;
- case NO_SCREEN:
- printf("Couldn't open the Screen.\n");
- break;
- case NO_WIN:
- printf("Couldn't open the Window.\n");
- break;
- case PLANES_CHOKE:
- printf("Couldn't allocate the temp. bit planes.\n");
- break;
- case ABOUT_CHOKE:
- printf("Couldn't open the about window.\n");
- break;
- case INIT_BLIT_CHOKE:
- printf("Couldn't allocate the blitter nodes.\n");
- break;
- case WBI_CHOKE:
- printf("Couldn't start the blitter interrupt.\n");
- break;
- default:
- printf("Unknown error: %d\n", ErrorNum);
- break;
- }
- }
-
-
- /************************************************************************/
- int MainLoop(BDSchtoff)
- struct BDMainStruct *BDSchtoff;
-
- {
- int RetVal,
- LeavingNow,
- MsgVal,
- MsgControl,
- RandReturn,
- First;
-
- RetVal = ML_OK;
- LeavingNow = FALSE;
- MsgControl = NO_WAIT;
- First = TRUE;
- while (LeavingNow == FALSE)
- {
- if (First)
- {
- First = FALSE; /* Do this once only */
- MsgVal = NEW; /* Hotwire MsgVal on first time through */
- } /* End First */
- else
- {
- if (MsgControl == NO_WAIT) /* If we do WAIT, hurry up and wait! */
- {
- OneGen(BDSchtoff);
- }
- MsgVal = CheckMsg(MsgControl);
- } /* End not First */
-
- switch (MsgVal)
- {
- case CLOSE_WIN:
- case QUIT:
- LeavingNow = TRUE;
- break;
- case NEW:
- RandReturn = Randomize(BDSchtoff, BDWindow);
- switch (RandReturn)
- {
- case RAND_OK:
- OffStart(); /* Set menu items */
- OnStop();
- MsgControl = NO_WAIT;
- break;
- case RAND_QUIT:
- LeavingNow = TRUE;
- break;
- case RAND_ABOUT_CHOKE:
- LeavingNow = TRUE;
- RetVal = ABOUT_CHOKE;
- break;
- }
- break;
- case STOP:
- MsgControl = WAIT;
- OffStop();
- OnStart();
- break;
- case START:
- MsgControl = NO_WAIT;
- OffStart();
- OnStop();
- break;
- case ABOUT:
- if (DisplayAbout() == DA_CHOKE)
- {
- LeavingNow = TRUE;
- RetVal = ABOUT_CHOKE;
- }
- break;
- case NO_MSG:
- /* One more generation. */
- break;
- default:
- assert (FALSE); /* Shouldn't be here */
- break;
- } /* End case CheckMsg() */
- } /* End while not leaving */
- return RetVal;
- } /* End MainLoop() */
-
-
-
- /*******************************************************************************
- InitPlanes() fills in a structure of type BDMainStruct, pointed at by
- Strcut, given the pointer to a window, *Win. Returns PLANES_CHOKE if any
- allocations weren't successful.
- *******************************************************************************/
- int InitPlanes(Struct, Win)
- struct BDMainStruct *Struct;
- struct Window *Win;
-
- {
- int i,
- DispStartOffset,
- RetVal;
-
- RetVal = PLANES_OK;
- /* Find the relative start of the blitfield in words */
- /* Note that BorderTop and BorderBottom are 1 too large */
- DispStartOffset = (((Win -> BorderTop) - 1 ) + Win -> TopEdge)
- * ((Win -> WScreen -> Width) / 16) + (Win -> LeftEdge) / 16;
- for (i=0; i < NUM_PLANES; i++)
- {
- (Struct -> Display)[i] = DispStartOffset +
- (WORD *) Win -> RPort -> BitMap -> Planes[i]; /* Whew! */
- }
- Struct -> XSize = Win -> Width;
- Struct -> YSize = (Win -> Height) - ((Win -> BorderTop) - 1) -
- ((Win -> BorderBottom) - 1); /* Sub. borders */
- Struct -> Mod = (Win -> WScreen -> Width) - (Win -> Width);/* Blit Modulo */
- /* Note that BorderLeft and BorderRight are 2 too large */
- Struct -> LRBorder = max (Win -> BorderLeft - 2, Win -> BorderLeft - 2);
-
- /* Now allocate some bitplanes for temporaries... */
- Struct -> Temp = (WORD *) AllocRaster(Struct -> XSize, Struct -> YSize);
- if (Struct -> Temp == 0)
- {
- RetVal = PLANES_CHOKE;
- } /* End Temp Choke */
- else
- {
- Struct -> Equal = (WORD *)AllocRaster(Struct -> XSize, Struct -> YSize);
- if (Struct -> Equal == 0)
- {
- RetVal = PLANES_CHOKE;
- } /* End Equal choke */
- else
- {
- i = 0;
- while ((RetVal != PLANES_CHOKE) && (i < NUM_PLANES))
- {
- Struct -> Incr[i] = (WORD *) AllocRaster(Struct -> XSize,
- Struct -> YSize);
- if (Struct -> Incr[i] == 0)
- {
- RetVal = PLANES_CHOKE;
- }
- i++;
- } /* End While allocating Incr */
- } /* End Equal OK */
- } /* End Temp OK */
- return RetVal;
- } /* End InitPlanes */
-
-
- /*******************************************************************************
- KillPlanes() deallocates all of the temporary bitplanes allocated
- in InitPlanes.
- *******************************************************************************/
-
- void KillPlanes(Struct)
- struct BDMainStruct *Struct;
-
- {
- int i;
-
- if (Struct -> Temp != 0)
- {
- FreeRaster((PLANEPTR)Struct -> Temp, Struct -> XSize, Struct -> YSize);
- Struct -> Temp = 0;
- }
- if (Struct -> Equal != 0)
- {
- FreeRaster((PLANEPTR)Struct -> Equal, Struct -> XSize, Struct -> YSize);
- Struct -> Equal = 0;
- }
- for (i = 0; i < NUM_PLANES; i++)
- {
- if (Struct -> Incr[i] != 0)
- {
- FreeRaster((PLANEPTR) Struct -> Incr[i], Struct -> XSize,
- Struct -> YSize);
- Struct -> Incr[i] = NULL;
- }
- }
- } /* End KillPlanes() */
-
-
-
- /*******************************************************************************
- Randomize() sets every pixel within the borders of the window pointed
- at by Win.
- *******************************************************************************/
- int Randomize(BDStuff, Win)
- struct BDMainStruct *BDStuff;
- struct Window *Win;
-
- {
- int Left,
- Right,
- Top,
- Bottom,
- XWords,
- YLines,
- i,
- x,
- y,
- Redo,
- MsgControl,
- MsgVal,
- LeavingNow,
- PlaneNum,
- RetVal;
- WORD LRBorder,
- LMask,
- RMask,
- *(Disp[NUM_PLANES]),
- MyWord,
- RandWord;
- long Seed;
- struct DateStamp *Now;
-
- MsgControl = NO_WAIT;
- RetVal = RAND_OK; /* Innocent until proven guilty */
- LeavingNow = FALSE;
- do /* Loop if Redo gets set to TRUE by the NEW menuitem. */
- {
- Redo = FALSE; /* Only one more time unless Redo gets set */
- /* Seed the random number generator with number of TICK's today: */
- Now = (struct DateStamp *) malloc (sizeof (struct DateStamp));
- DateStamp(Now); /* This Lattice compiler warning is not my fault */
- Seed = (Now -> ds_Tick) + ((Now -> ds_Minute) * TICKS_PER_SECOND * 60);
- free(Now);
- srand(Seed);
-
- /* Set the border masks */
- LRBorder = BDStuff -> LRBorder;
- LMask = 0xffff >> LRBorder;
- RMask = 0xffff << LRBorder;
-
- /* Set the plane pointers */
- for (i=0; i < NUM_PLANES; i++)
- {
- Disp[i] = BDStuff -> Display[i];
- }
-
- /* Clear the screen first */
- Left = LRBorder;
- Right = ((BDStuff -> XSize) -1) - LRBorder;
- Top = (BDWindow -> BorderTop) -1; /* Border off by one */
- Bottom = (BDWindow -> Height) - (BDWindow -> BorderBottom);
- SetAPen (BDWindow -> RPort, 0);
- RectFill (BDWindow -> RPort, Left, Top, Right, Bottom);
-
- /* Now set pixels Randomly */
- /* Sweep from top to bottom; bail out if Redo or LeavingNow gets set */
- XWords = (BDStuff -> XSize) / 16;
- YLines = (BDStuff -> YSize);
- y = 0;
- while ((y < YLines) && (!Redo) && (!LeavingNow))
- {
- for (x = 0; x < XWords; x++)
- {
- for (PlaneNum = 0; PlaneNum < NUM_PLANES; PlaneNum++)
- {
- RandWord = (rand() >> 8) & 0xffff; /* Use middle 16 bits */
- /* Set MyWord given LMask and RMask */
- if (x == 0) /* First word */
- {
- MyWord = *(Disp[PlaneNum]) & ~LMask;
- MyWord = MyWord | (RandWord & LMask);
- }
- else if (x == (XWords -1)) /* Last word */
- {
- MyWord = *(Disp[PlaneNum]) & ~RMask;
- MyWord = MyWord | (RandWord & RMask);
- }
- else
- {
- MyWord = RandWord;
- }
- *(Disp[PlaneNum]) = MyWord;
- (Disp[PlaneNum])++;
- } /* End for PlaneNum */
- } /* End for x */
- MsgVal = CheckMsg(MsgControl);
- switch(MsgVal)
- {
- case CLOSE_WIN:
- case QUIT:
- RetVal = RAND_QUIT;
- LeavingNow = TRUE;
- break;
- case STOP:
- MsgControl = WAIT;
- OffStop();
- OnStart();
- break;
- case START:
- MsgControl = NO_WAIT;
- OffStart();
- OnStop();
- break;
- case NEW:
- Redo = TRUE;
- MsgControl = NO_WAIT;
- OffStart();
- OnStop();
- break;
- case ABOUT:
- if (DisplayAbout() == DA_CHOKE)
- {
- LeavingNow = TRUE; /* Let's bomb out now */
- RetVal = RAND_ABOUT_CHOKE;
- }
- break;
- case NO_MSG:
- break;
- default:
- assert (FALSE); /* Shouldn't be here */
- break;
- }
- y++; /* Next line */
- } /* End for y */
- } while (Redo);
- return RetVal;
- } /* End Randomize() */
-