home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d131
/
life
/
life.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-03-13
|
11KB
|
406 lines
/*
* What fun! A new LIFE program by Tomas Rokicki. Commented rather
* erratically; hell, this is all just one big hack.
*/
int modulo ;
int wmodulo ;
int vsize ;
#define RASTSIZE (wmodulo * (long)(vsize+1))
#include "structures.h"
#include "blit.h"
short *a, *b, *c, *d, *e, *t1=NULL, *t2=NULL, *t3=NULL, *t4=NULL ;
short noplanes ;
short torus ;
short orify ;
struct GfxBase *GfxBase = NULL ; /* the GfxBase */
struct IntuitionBase *IntuitionBase = NULL ; /* the IntuitionBase */
struct Screen *myscreen = NULL ;
struct Window *mywindow = NULL ;
struct TextAttr myfont = {(STRPTR)"topaz.font", TOPAZ_EIGHTY, 0, 0 };
struct NewScreen mynewscreen = {0, 0, 0, 0, 0, 1, 2, 0,
CUSTOMSCREEN, &myfont, (UBYTE *)"AmigaLIFE -- Radical Eye Software"} ;
/*
* Let's use a borderless window too, so we can get vanilla
* keys. This gives us a nicer way to exit and adjust the
* speed of the program. But we still play with the screen
* bitmaps.
*/
static struct NewWindow mynewwindow = { 0, 0, 0, 0, 0, 1,
VANILLAKEY, SIMPLE_REFRESH | ACTIVATE | NOCAREREFRESH | BORDERLESS | BACKDROP,
NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, CUSTOMSCREEN } ;
/*
* 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() {
long color ;
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() ;
}
mynewwindow.Screen = myscreen ;
if ((mywindow = OpenWindow(&mynewwindow))==NULL) {
printf("Couldn't open window.\n") ;
cleanup() ;
}
a = ((short *)(myscreen->BitMap.Planes[0])) + 10 * wmodulo ;
b = ((short *)(myscreen->BitMap.Planes[1])) + 10 * wmodulo ;
c = ((short *)(myscreen->BitMap.Planes[2])) + 10 * wmodulo ;
d = ((short *)(myscreen->BitMap.Planes[3])) + 10 * wmodulo ;
e = ((short *)(myscreen->BitMap.Planes[4])) + 10 * wmodulo ;
t1 = myalloc() ;
t2 = myalloc() ;
t3 = myalloc() ;
t4 = myalloc() ;
if (orify) {
color = GetRGB4(myscreen->ViewPort.ColorMap, 0L) ;
if (color & 0xf00)
color -= 256 ;
if (color & 0xf0)
color -= 16 ;
if (color & 0xf)
color -= 1 ;
SetRGB4(&(myscreen->ViewPort), 1L << (noplanes - 1), (color >> 8) & 15,
(color >> 4) & 15, color & 15) ;
}
}
/*
* Exit routine.
*/
cleanup() {
if (mywindow != NULL)
CloseWindow(mywindow) ;
if (myscreen != NULL)
CloseScreen(myscreen) ;
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) ;
exit(0) ;
}
#define PARITY (0x96)
#define CARRY (0xe8)
#define SPEC1 (0x6a)
#define SPEC2 (0xbe)
#define SPEC3 (0x40)
#define COPY (0xf0)
#define ORIFY (0xfc)
#define ORAC (0xfa)
/*
* This routine does the necessary four blits to wrap the LIFE image.
* Please make sure that you own the blitter when you call it!
*/
struct blitparam blitparam ;
fixit() {
register struct blitparam *p = &blitparam ;
p->bltsize = BLTSIZE(1, vsize) ;
p->asource = a ;
p->csource = a + wmodulo - 1 ;
p->dsource = a + wmodulo - 1 ;
p->amod = 2 * (wmodulo - 1) ;
p->bmod = 0 ;
p->cmod = 2 * (wmodulo - 1) ;
p->dmod = 2 * (wmodulo - 1) ;
p->fwm = 0x4000 ;
p->lwm = 0xffff ;
p->con0 = SHIFTSHIFT(14) + USEA + USEC + USED + ORAC ;
p->con1 = 0 ;
blit(p) ;
p->asource = a + 2 * wmodulo - 1 ;
p->csource = a ;
p->dsource = a ;
p->fwm = 0x0002 ;
p->con0 = SHIFTSHIFT(2) + USEA + USEC + USED + ORAC ;
blit(p) ;
p->bltsize = BLTSIZE(wmodulo, 1) ;
p->asource = a + wmodulo ;
p->dsource = a + wmodulo * (long)(vsize - 1) ;
p->amod = 0 ;
p->cmod = 0 ;
p->dmod = 0 ;
p->fwm = 0xffff ;
p->lwm = 0xffff ;
p->con0 = USEA + USED + COPY ;
blit(p) ;
p->asource = a + wmodulo * (long)(vsize - 2) ;
p->dsource = a ;
blit(p) ;
}
/*
* Does one LIFE generation. Fancy algorithm uses only 9 blits. If
* anyone can improve this, please let me know.
*/
dogeneration() {
register struct blitparam *p = &blitparam ;
/*
* Initialize the parameters we are not going to change.
*/
p->fwm = 0xffff ;
p->lwm = 0xffff ;
p->amod = 0 ;
p->bmod = 0 ;
p->cmod = 0 ;
p->dmod = 0 ;
p->asource = a - wmodulo ;
p->bsource = a - wmodulo + 1 ;
p->csource = a - wmodulo ;
p->dsource = t1 ;
p->bltsize = BLTSIZE(wmodulo, vsize+1) ;
p->con0 = SHIFTSHIFT(1) + USEA + USEB + USEC + USED + PARITY ;
p->con1 = SHIFTSHIFT(15) ;
OwnBlitter() ;
blit(p) ;
p->dsource = t2 ;
p->con0 = SHIFTSHIFT(1) + USEA + USEB + USEC + USED + CARRY ;
blit(p) ;
p->csource = t1 + wmodulo ;
p->dsource = t3 ;
p->con0 = SHIFTSHIFT(1) + USEA + USEB + USEC + USED + CARRY ;
blit(p) ;
p->bltsize = BLTSIZE(wmodulo, vsize) ;
p->asource = t2 ;
p->bsource = t2 + 2 * wmodulo ;
p->csource = t3 + wmodulo ;
p->dsource = t4 ;
p->con1 = 0 ;
p->con0 = USEA + USEB + USEC + USED + CARRY ;
blit(p) ;
p->dsource = t3 ;
p->con0 = USEA + USEB + USEC + USED + PARITY ;
blit(p) ;
p->bltsize = BLTSIZE(wmodulo, vsize+1) ;
p->asource = a - wmodulo ;
p->bsource = a - wmodulo + 1 ;
p->csource = t1 + wmodulo ;
p->dsource = t2 ;
p->con0 = SHIFTSHIFT(1) + USEA + USEB + USEC + USED + PARITY ;
p->con1 = SHIFTSHIFT(15) ;
blit(p) ;
p->bltsize = BLTSIZE(wmodulo, vsize) ;
p->asource = t1 ;
p->bsource = t2 + wmodulo ;
p->csource = t3 ;
p->dsource = t3 ;
p->con0 = USEA + USEB + USEC + USED + SPEC1 ;
p->con1 = 0 ;
blit(p) ;
p->csource = a ;
p->dsource = t1 ;
p->con0 = USEA + USEB + USEC + USED + SPEC2 ;
blit(p) ;
/*
* Before we do the final write, we copy bits down one generation.
*/
if (orify) {
a = ((short *)(myscreen->BitMap.Planes[0])) + 10 * wmodulo ;
p->asource =
((short *)(myscreen->BitMap.Planes[noplanes-1])) + 10 * wmodulo ;
p->bsource =
((short *)(myscreen->BitMap.Planes[noplanes-2])) + 10 * wmodulo ;
p->dsource = p->asource ;
p->con0 = USEA + USEB + USED + ORIFY ;
blit(p) ;
}
p->con0 = USEA + USED + COPY ;
switch (noplanes - orify) {
case 5:
p->asource = d ;
p->dsource = e ;
blit(p) ;
case 4:
p->asource = c ;
p->dsource = d ;
blit(p) ;
case 3:
p->asource = b ;
p->dsource = c ;
blit(p) ;
case 2:
p->asource = a ;
p->dsource = b ;
blit(p) ;
default: ;
}
p->bltsize = BLTSIZE(wmodulo, vsize-2) ;
p->asource = t1 + wmodulo ;
p->bsource = t3 + wmodulo ;
p->csource = t4 + wmodulo ;
p->dsource = a + wmodulo ;
p->fwm = 0x7fff ;
p->lwm = 0xfffe ;
p->con0 = USEA + USEB + USEC + USED + SPEC3 ;
blit(p) ;
/*
* Wrap, if necessary
*/
if (torus)
fixit() ;
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.
*/
char buffer[200] ;
main (argc, argv)
int argc ;
char *argv[] ;
{
register int x, y ;
int hires = 320 ;
int randoms = 0 ;
int ir ;
int dvsize = 0 ;
struct IntuiMessage *message ;
int code ;
long delayval = 0 ;
noplanes = 1 ;
while (argc > 1 && argv[1][0]=='-') {
argc-- ;
argv++ ;
if (argv[0][1]=='h' || argv[0][1]=='H') {
if (sscanf(argv[0]+2, "%d", &hires)!=1)
hires = 640 ;
} else if (argv[0][1]=='r' || argv[0][1]=='R') {
if (sscanf(argv[0]+2, "%d", &randoms)!=1)
randoms = 1 ;
} else if (argv[0][1]=='p' || argv[0][1]=='P') {
noplanes = argv[0][2] - '0' ;
if (noplanes < 1 || noplanes > 6)
noplanes = 1 ;
} else if (argv[0][1]=='o' || argv[0][1]=='O') {
orify = 1 ;
} else if (argv[0][1]=='t' || argv[0][1]=='T') {
torus = 1 ;
} else if (argv[0][1]=='v' || argv[0][1]=='V') {
if (sscanf(argv[0]+2, "%d", &dvsize)!=1)
dvsize = 0 ;
} else if (argv[0][1]=='s' || argv[0][1]=='S') {
delayval = -1 ;
}
}
if (noplanes == 1)
orify = 0 ;
if (argc > 1) {
if (argv[1][0]=='?' && argv[1][1]==0) {
printf(
"Usage: life [-h[n]] [-r[n]] [-p[n]] [-o] [-t] [-v[n]] [-s] [infile]\n") ;
cleanup() ;
}
if (freopen(argv[1], "r", stdin)==NULL) {
printf("Couldn't open %s\n", argv[1]) ;
cleanup() ;
}
}
if (hires > 400) {
vsize = 390 ;
mynewscreen.ViewModes |= HIRES ;
} else {
vsize = 190 ;
}
modulo = hires & ~15 ;
ir = randoms ;
if (dvsize >= 10 && dvsize <= 600)
vsize = dvsize ;
wmodulo = modulo / 16 ;
mynewscreen.Depth = noplanes ;
mynewscreen.Width = modulo ;
mynewscreen.Height = vsize + 10 ;
mynewwindow.Width = modulo ;
mynewwindow.Height = vsize + 10 ;
if (vsize > 300)
mynewscreen.ViewModes |= LACE ;
initialize() ;
readin(a) ;
if (torus) {
OwnBlitter() ;
fixit() ;
DisownBlitter() ;
}
while (1) {
if (message = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
code = message->Code ;
ReplyMsg(message) ;
switch(code) {
case 27 : case 3 : case 'q' : case 'Q' : case 'x' : case 'X' :
cleanup() ;
case '0' : case 'g' : case 'G' :
delayval = 0 ;
break ;
case '1' : case '2' : case '3' : case '4' :
case '5' : case '6' : case '7' : case '8' : case '9' :
delayval = 1L << (code - '0') ;
break ;
case ' ' :
delayval = -1 ;
goto doone ;
case 'S' : case 's' :
delayval = -1 ;
default :
break ;
}
}
if (delayval) {
if (delayval == -1)
continue ;
Delay(delayval) ;
}
doone:
if (randoms) {
if (ir-- == 0) {
x = rnd(modulo-2) + 1 ;
y = rnd(vsize-2) + 1 ;
a[y * (long)wmodulo + (x >> 4)] |= 1 << (15 - (15 & x)) ;
ir = randoms ;
}
}
dogeneration() ;
}
cleanup() ;
}