;/*
sc RESOPT IGNORE=73 DATA=NEAR NMINC UCHAR CONSTLIB STREQ STRMERGE NOSTKCHK NOSTDIO OPTIMIZE OPTTIME Hopalong.c
Slink from LIB:c.o Hopalong.o to //Clients/Hopalong LIB LIB:scm.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/mathieeesingbas.h>
#include <proto/mathieeesingtrans.h>
#include <clib/alib_protos.h>

#include <stdlib.h>
#include <math.h>

#include "/include/client.h"

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

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *MathIeeeSingBasBase, *MathIeeeSingTransBase;

struct DisplayIDInformation *dinfo;

struct Screen *scr;

UBYTE scrdepth = 5, numcolors = 32;

extern ULONG RangeSeed;
UWORD swidth, sheight, hswidth, hsheight, maxw, maxh;
float fswidth, fsheight;
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

#define Mul IEEESPMul
#define Add IEEESPAdd
#define Div IEEESPDiv
#define Sub IEEESPSub
#define Cmp IEEESPCmp
#define Flt IEEESPFlt
#define Fix IEEESPFix
#define Tst IEEESPTst

float rndnum( void )
{
return( Sub( Mul( (float)drand48(), 2.0F ), 1.0F ) );
}

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

register int i, px, py;
float (*ptfun[3]) ( float );

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

ptfun[0]=IEEESPSqrt;
ptfun[1]=IEEESPLog;
ptfun[2]=IEEESPSin;

rect = GETTXTOSCANRECT(dinfo);

swidth = RECTANGLEWIDTH(rect);
sheight = RECTANGLEHEIGHT(rect);
hswidth = swidth >> 1;
hsheight = sheight >> 1;
fswidth = Div( Flt(swidth), Flt(RangeRand( 30 ) + 40) );
fsheight = Div( Flt(sheight), Flt(RangeRand( 30 ) + 40) );
displayID = DISPLAYID(dinfo);
brightness = GETBRIGHTNESS(dinfo);

if ( !CheckAA() )
	{
	if ( displayID & SUPERHIRES )
		{
		displayID &= ~SUPERHIRES;
		displayID |= HIRES;
		swidth >>= 1;
		}
	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 );
		changes = RangeRand( 5 ) + 5;
		a = rndnum();
		b = rndnum();
		c = rndnum();

		for( i = 0; i <= MAXITER; i++ )
			{
			if ( Tst(x) >= 0 )
				x_1 = Sub( y, (ptfun[func])( IEEESPAbs( Sub( Mul( b, x ), c ) ) ) );
			else
				x_1 = Add( y, (ptfun[func])( IEEESPAbs( Sub( Mul( b, x ), c ) ) ) );
			y_1 = Sub( a, x );
			px = hswidth + Fix( Mul( x_1, fswidth ) );
			py = hsheight - Fix( Mul( y_1, fsheight ) );
			x = x_1; y = y_1;

			if ( px >= 0 && py >= 0 && px < swidth && py < sheight )
				{
				SetAPen( &scr->RastPort,1 + numcolors * changes * i / MAXITER );
				WritePixel( &scr->RastPort, px, py );
				}

			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 ( MathIeeeSingBasBase = OpenLibrary( "mathieeesingbas.library", 37L ) )
			{
			if ( MathIeeeSingTransBase = OpenLibrary( "mathieeesingtrans.library", 37L ) )
				{
				if ( dinfo = OpenCommunication() )
					{
					CurrentTime( &RangeSeed, &RangeSeed );
					srand48( RangeSeed );
					Blank();
					CloseCommunication( dinfo );
					}
				CloseLibrary( MathIeeeSingTransBase );
				}
			CloseLibrary( MathIeeeSingBasBase );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
