/* * Here is a simple LIFE program which tests the blitter operations. * It does not extensively test the shifts or anything, but it makes * sure that the basic interface is correct. */ #define HSIZE (320) #define MODULO ((HSIZE + 15)/16)*16 #define VSIZE (190) #define RASTSIZE (MODULO / 16 * VSIZE) #include "structures.h" short *a, *b, *c, *d, *e, *t1=NULL, *t2=NULL, *t3=NULL, *t4=NULL, *t5=NULL ; short noplanes ; struct GfxBase *GfxBase = NULL ; /* the GfxBase */ struct IntuitionBase *IntuitionBase = NULL ; /* the IntuitionBase */ struct Screen *myscreen = NULL ; struct NewScreen mynewscreen = { 0, /* left edge */ 0, /* top edge */ 320, /* width */ 200, /* height */ 2, /* depth (change for color?)*/ 1, /* detail pen */ 2, /* block pen */ 0, /* screen mode */ CUSTOMSCREEN, /* type */ NULL, /* use default font */ (UBYTE *)"LIFE by Tomas Rokicki", /* title */ NULL, /* initialize this gadget field */ NULL } ; /* no bitmap supplied */ /* * This routine gets a raster for temporary storage. */ short *myalloc() { void *AllocMem() ; void *p ; if ((p=AllocMem(2L*RASTSIZE, MEMF_CHIP | MEMF_CLEAR))==NULL) { printf("Could not allocate raster data\n") ; cleanup() ; } return(p) ; } /* * Here we set things up. */ initialize() { initblitdata() ; if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library",0L))==NULL || (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L)) ==NULL) { printf("Couldn't open libraries.\n") ; cleanup() ; } if ((myscreen = OpenScreen(&mynewscreen))==NULL) { printf("Couldn't open screen.\n") ; cleanup() ; } a = ((short *)(myscreen->BitMap.Planes[0])) + 200 ; b = ((short *)(myscreen->BitMap.Planes[1])) + 200 ; c = ((short *)(myscreen->BitMap.Planes[2])) + 200 ; d = ((short *)(myscreen->BitMap.Planes[3])) + 200 ; e = ((short *)(myscreen->BitMap.Planes[4])) + 200 ; t1 = myalloc() ; t2 = myalloc() ; t3 = myalloc() ; t4 = myalloc() ; t5 = myalloc() ; } /* * Exit routine. */ cleanup() { if (myscreen != NULL) CloseScreen(myscreen) ; myscreen = NULL ; if (IntuitionBase) CloseLibrary(IntuitionBase) ; IntuitionBase = NULL ; if (GfxBase) CloseLibrary(GfxBase) ; GfxBase = NULL ; if (t1) FreeMem(t1, 2L*RASTSIZE) ; if (t2) FreeMem(t2, 2L*RASTSIZE) ; if (t3) FreeMem(t3, 2L*RASTSIZE) ; if (t4) FreeMem(t4, 2L*RASTSIZE) ; if (t5) FreeMem(t5, 2L*RASTSIZE) ; exit(0) ; } #define PARITY (0x96) #define CARRY (0xe8) #define PARITY2 (0x3c) #define CARRY2 (0xc0) #define SPECIAL1 (0x12) #define SPECIAL2 (0xe0) #define COPY (0xf0) /* * Does one LIFE generation. Fancy algorithm uses only 10 blits. If * anyone can improve this, please let me know. */ dogeneration() { OwnBlitter() ; /* * Take horizontal sums. */ blit(a, 0, 1, a, 2, 1, a, 1, 1, t1, 1, 1, MODULO, HSIZE-2, VSIZE-2, PARITY) ; blit(a, 0, 1, a, 2, 1, a, 1, 1, t2, 1, 1, MODULO, HSIZE-2, VSIZE-2, CARRY) ; /* * Take sums for middle row. */ blit(a, 0, 1, a, 2, 1, a, 1, 1, t3, 1, 1, MODULO, HSIZE-2, VSIZE-2, PARITY2) ; blit(a, 0, 1, a, 2, 1, a, 1, 1, t4, 1, 1, MODULO, HSIZE-2, VSIZE-2, CARRY2) ; /* * Now, sum each of the three columns. */ blit(t1, 1, 0, t1, 1, 2, t3, 1, 1, t5, 1, 1, MODULO, HSIZE-2, VSIZE-2, PARITY) ; blit(t1, 1, 0, t1, 1, 2, t3, 1, 1, t3, 1, 1, MODULO, HSIZE-2, VSIZE-2, CARRY) ; blit(t2, 1, 0, t2, 1, 2, t4, 1, 1, t1, 1, 1, MODULO, HSIZE-2, VSIZE-2, PARITY) ; blit(t2, 1, 0, t2, 1, 2, t4, 1, 1, t4, 1, 1, MODULO, HSIZE-2, VSIZE-2, CARRY) ; /* * Now, check high two order bits, then combine with original and * low order bit. */ blit(t1, 1, 1, t4, 1, 1, t3, 1, 1, t2, 1, 1, MODULO, HSIZE-2, VSIZE-2, SPECIAL1) ; /* * Before we do the final write, we copy bits down one generation. */ switch (noplanes) { case 5: blit(d, 1, 1, d, 1, 1, d, 1, 1, e, 1, 1, MODULO, HSIZE-2, VSIZE-2, COPY) ; case 4: blit(c, 1, 1, c, 1, 1, c, 1, 1, d, 1, 1, MODULO, HSIZE-2, VSIZE-2, COPY) ; case 3: blit(b, 1, 1, b, 1, 1, b, 1, 1, c, 1, 1, MODULO, HSIZE-2, VSIZE-2, COPY) ; case 2: blit(a, 1, 1, a, 1, 1, a, 1, 1, b, 1, 1, MODULO, HSIZE-2, VSIZE-2, COPY) ; default: ; } blit(t2, 1, 1, t5, 1, 1, a, 1, 1, a, 1, 1, MODULO, HSIZE-2, VSIZE-2, SPECIAL2) ; DisownBlitter() ; } /* * Random number generator; probably not a very good one. */ int rnd(i) int i ; { static long seed = 323214521 ; long rval ; seed = seed * 123213 + 121 ; rval = (seed >> 5) & 65535 ; return ((i * rval) >> 16) ; } /* * Main routine. If called with no arguments, makes 1 bit plane screen. * Otherwise, first argument is used as the number of bit planes. */ main (argc, argv) int argc ; char *argv[] ; { register int i ; register int x, y ; long t1[3], t2[3] ; if (argc < 2 || sscanf(argv[1], "%d", &noplanes) < 1 || noplanes < 1 || noplanes > 5) noplanes = 1 ; mynewscreen.Depth = noplanes ; initialize() ; for (i=0; i>4)] |= 1 << (15 - (x & 15)) ; dogeneration() ; i++ ; x = myscreen->MouseX ; y = myscreen->MouseY ; } DateStamp(t2) ; printf("%ld ticks %d generations\n", t2[2]-t1[2] + (t2[1]-t1[1]) * 3000L + (t2[0]-t1[0]) * 4320000L, i) ; printf("Done.\n") ; cleanup() ; }