;/*
sc Life.c DATA=FAR NMINC STRMERGE NOSTKCHK IGNORE=73 STRUCTUREEQUIVALENCE NOSTDIO
slink from LIB:c.o Life.o to //Clients/Life LIB LIB:sc.lib LIB:amiga.lib /lib/client.lib SC SD NOICONS STRIPDEBUG
delete life.o
quit

 Life 1.2  (Client for BServer)

 Copyright © 1994 by Stefano Reksten of 3AM - The Three Amigos!!!
 All rights reserved.
*/

#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <intuition/intuition.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>
/*#include <stdlib.h>*/
#include <string.h>
#include <time.h>

#include "/include/client.h"
#include "/include/bitmap/bitmap.h"
#include "/include/bitmap/bitmap_pragmas.h"

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *BitMapBase;

struct DisplayIDInformation *dinfo;

struct Screen *scr;
ULONG *ctptable;
struct BitMap *bitmap;

extern ULONG RangeSeed;
extern struct ExecBase *SysBase;

void Life( void )
{
UWORD swidth, sheight, xoffs, yoffs;
struct Rectangle *rect;
UBYTE *table1, *table2, *addr1, *addr2, adj;
BOOL twenty_or_better = SysBase->AttnFlags & AFF_68020;
BOOL success = FALSE;

rect = GETSTANDARDRECT(dinfo);

swidth = RECTANGLEWIDTH(rect);
sheight = RECTANGLEHEIGHT(rect);

if ( scr = OpenScreenTags( NULL,
	SA_DisplayID, DISPLAYID( dinfo ),
	SA_Width, swidth,
	SA_Height, sheight,
	SA_Depth, 1,
	SA_Quiet, TRUE,
	TAG_END ) )
	{
	xoffs = (swidth - 320)/2;
	yoffs = (sheight - 200)/2;
	bitmap = scr->RastPort.BitMap;

	if ( table1 = AllocVec( 64000, MEMF_ANY | MEMF_CLEAR ) )
		{
		if ( table2 = AllocVec( 64000, MEMF_ANY | MEMF_CLEAR ) )
			{
			if ( ctptable = CreateCTPTable( bitmap ) )
				{
				UWORD n;
				struct ViewPort *vp = &(scr->ViewPort);

				success = TRUE;
				SpritesOff();

				SetRGB4( vp, 0, 0, 0, 0 );
				SetRGB4( vp, 1, 6, 6, 6 );

				SetAPen( &scr->RastPort, 1 );

				for ( n = 0; n < 64000; n++ )
					*(table1+n) = RangeRand( 2 );

				while( STILL_BLANKING )
					{
					UWORD rows, columns;
					UBYTE *tmp;

					memset( table2, 0, 64000 );

					addr1 = table1 + 321;
					addr2 = table2 + 321;
					for ( rows = 0; rows < 198; rows++ )
						{
						for ( columns = 0; columns < 318; columns++ )
							{
							adj = *(addr1-321) + *(addr1-320) + *(addr1-319) + *(addr1-1) + *addr1 + *(addr1+1) + *(addr1+319) + *(addr1+320) + *(addr1+321);
							if ( adj == 3 )
								*(addr2) = 1;
							if ( adj == 4 )
								*(addr2) = *(addr1);
							addr1++;
							addr2++;
							if ( !twenty_or_better )
								ChunkyToPlanar( bitmap, xoffs + columns, yoffs + rows, adj == 3, ctptable );
							}
						addr1 += 2;
						addr2 += 2;
						}
					if ( twenty_or_better )
						ChunkyToPlanarArray68020( bitmap, xoffs, yoffs, table2, ctptable, 320, 200, 320 );
					tmp = table1; table1 = table2; table2 = tmp;
					}
				SpritesOn();
				FreeCTPTable( ctptable, bitmap );
				}
			FreeVec( table2 );
			}
		FreeVec( table1 );
		}
	CloseScreen( scr );
	}

if ( !success )
	SendClientMsg( ACTION_FAILED );
}

void __main( char *line )
{
if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
		{
		if ( BitMapBase = OpenLibrary( "bitmap.library", 0L ) )
			{
			if ( dinfo = OpenCommunication() )
				{
				RangeSeed = time( NULL );

				Life();
				CloseCommunication( dinfo );
				}
			CloseLibrary( BitMapBase );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
