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

 Lightning 1.0  (Client for BServer)

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

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

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <clib/alib_protos.h>

#include "/include/client.h"

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

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct DisplayIDInformation *dinfo;

extern ULONG RangeSeed;

UWORD FromX, FromY, ToX, ToY;

UWORD lines[2000], linecnt = 0;

UWORD swidth, sheight;
struct Screen *scr;
struct RastPort *rp;

void SetCoords( void )
{
FromX = RangeRand( swidth>>1 );
FromY = RangeRand( (sheight - 50)>>1 );
ToX = RangeRand( FromX ) - (FromX>>1);
ToY = RangeRand( sheight - FromY - 100 ) + FromY + 100;
}


void RemoveLightning( void )
{
register UWORD n;

SetAPen( rp, 0 );
for ( n = 0; n < linecnt; )
	{
	Move( rp, lines[n++], lines[n++] );
	Draw( rp, lines[n++], lines[n++] );
	}
linecnt = 0;
}


void DrawLightning( UWORD fx, UWORD fy, UWORD tx, UWORD ty )
{
register UWORD rx, ry;
register WORD gap;

if ( tx >= swidth ) tx = swidth - 1;
if ( ty >= sheight ) ty = sheight - 1;

Move( rp, fx, fy );

rx = tx > fx ? fx + (( tx - fx ) >> 2) : fx - (( fx - tx ) >> 2);
ry = (( ty - fy ) >> 2) + fy;

gap = rx > tx ? rx - tx : tx - rx;
gap /= 4;
if ( gap )
	{
	gap = RangeRand( gap ) - ( gap >> 1 );
	rx += gap;
	}

if ( gap = ( ty - ry ) / 4 )
	{
	gap = RangeRand( gap ) - ( gap >> 1 );
	if ( ry + gap < ty )
		ry += gap;
	}

if ( rx != fx && ry != fy )
	{
	Draw( rp, rx, ry );
	lines[linecnt++] = fx;
	lines[linecnt++] = fy;
	lines[linecnt++] = rx;
	lines[linecnt++] = ry;
	DrawLightning( rx, ry, tx, ty );
	if ( rx != tx && ry != ty )
		{
		gap =  rx > tx ? rx - tx : tx - rx;
		DrawLightning( rx, ry, rx + RangeRand( gap ) - (gap>>1), ry + RangeRand( ty - ry ) );
		}
	}
}

#define IDLE    0
#define LIGHTN  1

void Blank( void )
{
struct Rectangle *rect;
UBYTE brightness;
int status = IDLE;
int ticks = 0;

rect = GETTXTOSCANRECT(dinfo);

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

if ( scr = OpenScreenTags( NULL,
	SA_DisplayID, DISPLAYID( dinfo ),
	SA_Width, swidth,
	SA_Height, sheight,
	SA_Depth, 1,
	SA_Quiet, TRUE,
	TAG_END ) )
	{
	register struct ViewPort *vp = &(scr->ViewPort);
	rp = &(scr->RastPort);

	SpritesOff();

	SetRGB4( vp, 0, 0, 0, 0 );
	SetRGB4( vp, 1, 15*brightness/100, 15*brightness/100, 15*brightness/100 );
	SetCoords();

	while( STILL_BLANKING )
		{
		WaitTOF();
		if ( ++ticks > 100 )
			status = LIGHTN;
		if ( status == LIGHTN )
			{
			RemoveLightning();
			SetAPen( rp, 1 );
			DrawLightning( FromX, FromY, ToX, ToY );
			if ( ticks > 130 && !RangeRand( 5 ) )
				{
				WaitTOF();
				RemoveLightning();
				SetCoords();
				ticks = 0;
				status = IDLE;
				}
			}
		}

	CloseScreen( scr );
	SpritesOn();
	}
else
	SendClientMsg( ACTION_FAILED );
}


void __main( void )
{
if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
		{
		if ( dinfo = OpenCommunication() )
			{
			CurrentTime( &RangeSeed, &RangeSeed );
			Blank();
			CloseCommunication( dinfo );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
