;/*
sc RESOPT IGNORE=73 DATA=NEAR MATH=FFP NMINC UCHAR CONSTLIB STREQ STRMERGE NOSTKCHK NOSTDIO OPTIMIZE OPTSIZE Hopalong.c
Slink from LIB:catch.o Hopalong.o to //Clients/Hopalong LIB LIB:scmffp.lib LIB:sc.lib LIB:amiga.lib /lib/client.lib SC SD NOICONS STRIPDEBUG
delete Hopalong.o
quit

 Hopalong 1.0  (Client for BServer)

 Copyright © 1995 by
 Stefano Reksten and Luca Viola of 3AM - The Three Amigos!!!
 All rights reserved.

*/

#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/layers.h>
#include <clib/alib_protos.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#include "/include/client.h"

char *ver = "$VER: Hopalong 1.0 "__AMIGADATE__;

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *LayersBase;

struct DisplayIDInformation *dinfo;

struct Screen *scr;

#define SCRDEPTH	5
#define NUMCOLORS	32

UBYTE scrdepth = 5, numcolors = 32;

extern ULONG RangeSeed;
UWORD swidth, sheight, maxw, maxh;
UBYTE brightness;

UBYTE colors[96] =
{
	0,0,0, 0,5,0, 0,8,0, 0,10,0, 0,13,0, 2,13,4, 3,15,7, 5,15,10,
	7,15,13, 9,15,15, 0,15,15, 0,10,14, 0,6,12, 0,3,11, 0,0,15, 4,0,14,
	6,0,12, 9,0,11, 11,0,10, 12,0,7, 13,0,3, 13,1,0, 13,5,0, 13,10,0,
	15,15,0, 14,14,3, 13,13,5, 12,12,7, 11,11,9, 10,10,10, 6,6,7, 4,4,4
};

#define MAXITER 	50000
#define SCALE		50
#define CHANGES		5
#define XIN			0
#define YIN 		0


double sgn( double x )
{
	return ((x>=0.0)?(1.0):(-1.0));
}

void Blank( void )
{
ULONG displayID;
struct Rectangle *rect;

register int i,px,py;
double sqrt(),log(),sin();
double (*ptfun[3]) ( double );

double a,b,c,x,y,x_1,y_1;
long scale,changes,func;

ptfun[0]=sqrt;
ptfun[1]=log;
ptfun[2]=sin;

rect = GETTXTOSCANRECT(dinfo);

swidth = RECTANGLEWIDTH(rect);
sheight = RECTANGLEHEIGHT(rect);
displayID = DISPLAYID(dinfo);
brightness = GETBRIGHTNESS(dinfo);

if ( !CheckAA() )
	{
	if ( displayID & SUPERHIRES )
		{
		displayID &= ~SUPERHIRES;
		displayID |= HIRES;
		}
	scrdepth = 4;
	numcolors = 16;
	}

if ( (scr = OpenScreenTags( NULL,
		SA_Width, swidth,
		SA_Height, sheight,
		SA_Depth, scrdepth,
		SA_Type, CUSTOMSCREEN,
		SA_Quiet, TRUE,
		SA_DisplayID, displayID,
		SA_Overscan, OSCAN_TEXT,
		TAG_END ) ) )
	{
	SpritesOff();
	for ( i = 0; i < numcolors; i+=3 )
		SetRGB4( &scr->ViewPort, i, colors[i]*brightness/100, colors[i+1]*brightness/100, colors[i+2]*brightness/100 );

	while( STILL_BLANKING )
		{
		x=XIN; y=YIN;
		SetRast( &scr->RastPort,0 );
		func = RangeRand( 3 );
		scale = RangeRand( 30 ) + 40;
		changes = RangeRand( 5 ) + 5;
		a = drand48()*2-1;
		b = drand48()*2-1;
		c = drand48()*2-1;

		for( i=0; i<=MAXITER; i++ )
			{
			x_1=y-sgn( x )*(ptfun[func])( abs( b*x-c ) );
			y_1=a-x;
			px=(int)((x_1*swidth)/scale)+(swidth>>1);
			py=(sheight>>1)-(int)((y_1*sheight)/scale);
			SetAPen( &scr->RastPort,1+(int)(numcolors*changes*i/MAXITER) );
			if ( px >= 0 && px < swidth && py >= 0 && py < sheight )
				WritePixel( &scr->RastPort,px,py );
			x=x_1; y=y_1;
			if ( !STILL_BLANKING )
				goto exit;
			}
		}
exit:
	SpritesOn();
	CloseScreen( scr );
	}
else
	SendClientMsg( ACTION_FAILED );
}


void __main( char *line )
{
if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
		{
		if ( LayersBase = OpenLibrary( "layers.library", 37L ) )
			{
			if ( dinfo = OpenCommunication() )
				{
				RangeSeed = time( NULL );
				srand48( time( NULL ) );
				Blank();
				CloseCommunication( dinfo );
				}
			CloseLibrary( LayersBase );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
