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

 Spotlight 1.1  (Client for BServer)

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

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

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

#include <stdio.h>

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


UWORD s_imgdata[147] = {
 0x4254, 0x4F43, 0x0, 0x1F8,
 0xFFDD, 0xFFFF, 0x0, 0x3FF8,
 0xFFE2, 0x1, 0xFF02, 0xFFE2,
 0xF, 0xFF02, 0xE0FF, 0xE100,
 0x3FFF, 0x2F8, 0xFFE1, 0x7F,
 0xFF02, 0xFCFF, 0xE000, 0x1FF,
 0x4FF, 0xE000, 0x3FF, 0x480,
 0x0, 0x7FF, 0x4C0, 0x0,
 0xFFF, 0x4E0, 0x0, 0x1FFF,
 0x4F0, 0x0, 0x3FFF, 0x4F8,
 0x0, 0x7FFF, 0x4FC, 0x0,
 0x7FFF, 0x4FC, 0x0, 0xFF05,
 0xFE00, 0x1FF, 0x600, 0x1FF,
 0x600, 0x3FF, 0x680, 0x3FF,
 0x680, 0x3FF, 0x680, 0x7FF,
 0x6C0, 0x7FF, 0x6C0, 0x7FF,
 0x6C0, 0xFFF, 0x6E0, 0xFFF,
 0x6E0, 0xFFF, 0x6E0, 0xFFF,
 0x6E0, 0xFFF, 0x6E0, 0xFFF,
 0x6E0, 0xFFF, 0x6E0, 0xFFF,
 0x6E0, 0xFFF, 0x6E0, 0xFFF,
 0x6E0, 0xFFF, 0x6E0, 0x7FF,
 0x6C0, 0x7FF, 0x6C0, 0x7FF,
 0x6C0, 0x3FF, 0x680, 0x3FF,
 0x680, 0x3FF, 0x680, 0x1FF,
 0x600, 0x1FF, 0x600, 0xFF,
 0x5FE, 0x0, 0x7FFF, 0x4FC,
 0x0, 0x7FFF, 0x4FC, 0x0,
 0x3FFF, 0x4F8, 0x0, 0x1FFF,
 0x4F0, 0x0, 0xFFF, 0x4E0,
 0x0, 0x7FF, 0x4C0, 0x0,
 0x3FF, 0x480, 0x0, 0x1FF,
 0x4FF, 0xE100, 0x7FFF, 0x2FC,
 0xFFE1, 0x3F, 0xFF02, 0xF8FF,
 0xE100, 0xFFF, 0x2E0, 0xFFE1,
 0x1, 0xFF02, 0xFFE3, 0x3F,
 0xF8FF, 0xFF00, 0x0 };

#define IMGW 63
#define IMGH 63

struct Image img = { 0, 0, IMGW, IMGH, 1, NULL, 0xFF, 0xFF, NULL };

#define BITPLSIZE ((((IMGW+15)>>4)<<1)*IMGH)

char *ver = "$VER: Spotlight 1.1 "__AMIGADATE__;

UBYTE *mem_ptr;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *BitMapBase;
struct DisplayIDInformation *dinfo;
BOOL blanking = TRUE;

extern ULONG RangeSeed;
struct Screen *scr;
struct BitMap *Spotlightsbm, *shadowbm, *scalebm;
WORD x, y, dirx, diry,
     blitx, blity, sizex, sizey;
UBYTE scaleX = 0, scaleY = 0;
struct BitMapScaleInfo bsi;
UBYTE depth;


void MoveSpotlight( void )
{
x += dirx * 1<<scaleX;
if ( x < -(IMGW<<scaleX)+1 )
	{
	x = -(IMGW<<scaleX)+1;
	dirx = RangeRand( 3 ) + 1;
	bsi.bsi_Flags = BSIF_INVERTHOR;
	}
if ( x >= scr->Width - 2 )
	{
	x = scr->Width - 2;
	dirx = - RangeRand( 3 ) - 1;
	bsi.bsi_Flags = 0L;
	}

y += diry * 1<<scaleY;
if ( y < -(IMGH<<scaleY)+1 )
	{
	y = -(IMGH<<scaleY)+1;
	diry = RangeRand( 3 ) + 1;
	}
if ( y >= scr->Height - 2 )
	{
	y = scr->Height - 2;
	diry = - RangeRand( 3 ) - 1;
	}
}


BOOL CreateFrames( void )
{
BOOL success = FALSE;

if ( Spotlightsbm = AllocVec( sizeof(struct BitMap), MEMF_ANY|MEMF_CLEAR ) )
	{
	InitBitMap( Spotlightsbm, 1, IMGW, IMGH );
	Spotlightsbm->Planes[0] = mem_ptr;
	Decrunch30( mem_ptr, s_imgdata );

	if ( shadowbm = AllocVec( sizeof(struct BitMap), MEMF_ANY|MEMF_CLEAR ) )
		{
		shadowbm->BytesPerRow = scr->RastPort.BitMap->BytesPerRow;
		shadowbm->Rows        = scr->RastPort.BitMap->Rows;
		shadowbm->Flags       = scr->RastPort.BitMap->Flags;
		shadowbm->Depth       = 1;
		shadowbm->Planes[0]   = scr->RastPort.BitMap->Planes[depth-1];

		if ( scalebm = CreateBitMap( IMGW << scaleX, IMGH << scaleY, 1 ) )
			{
			bsi.bsi_SrcLeftEdge = 0;
			bsi.bsi_SrcTopEdge = 0;
			bsi.bsi_DestTopEdge = 0;
			bsi.bsi_DestLeftEdge = 0;
			bsi.bsi_HorDen = 1;
			bsi.bsi_VertDen = 1;
			bsi.bsi_TempBitMap = NULL;
			bsi.bsi_HorNum = 1 << scaleX;
			bsi.bsi_VertNum = 1 << scaleY;
			bsi.bsi_Flags = NULL;
			bsi.bsi_SrcBitMap = Spotlightsbm;
			bsi.bsi_DestBitMap = scalebm;
			bsi.bsi_Width = IMGW;
			bsi.bsi_Height = IMGH;

			ScaleBitMap( &bsi );

			success = TRUE;
			}
		if ( !success ) DisposeBitMap( shadowbm );
		}
	if ( !success ) FreeVec( Spotlightsbm );
	}

return success;
}


void GetDirection( void )
{
dirx = diry = 0;

while ( ( dirx == 0 ) && ( diry == 0 ) )
	{
	dirx = RangeRand( 7 ) - 3;
	diry = RangeRand( 9 ) - 4;
	}
if ( dirx < 0 )
	bsi.bsi_Flags = 0L;
else
	bsi.bsi_Flags = BSIF_INVERTHOR;
}


void Blank( void )
{
ULONG mode;
BOOL success = FALSE;
UBYTE brightness = GETBRIGHTNESS(dinfo), fmdepth;
ULONG *RGBTriplets, *copy_of_RGBTriplets;
struct Screen *fm = IntuitionBase->FirstScreen;
fmdepth = fm->RastPort.BitMap->Depth;

if ( scr = GetDeeperFrontmostScreen( brightness, 1 ) )
	{
	UWORD *ptr;
	ULONG n;

	depth = scr->RastPort.BitMap->Depth;
	ptr = (UWORD *)scr->RastPort.BitMap->Planes[depth-1];
	n = scr->RastPort.BitMap->BytesPerRow * scr->RastPort.BitMap->Rows >> 1;
	while ( n-- )
		*ptr++ = 0;

	if ( RGBTriplets = AllocVec( 3088, MEMF_ANY|MEMF_CLEAR ) )
		{
		copy_of_RGBTriplets = (ULONG *)((ULONG)RGBTriplets + 4);
		*RGBTriplets = ( 1 << fmdepth ) << 16;

		GetRGB32( fm->ViewPort.ColorMap, 0, 1 << fmdepth, copy_of_RGBTriplets );
		for ( n = 0; n < 3 << fmdepth; n++ )
			{
			*copy_of_RGBTriplets = (((*copy_of_RGBTriplets) >> 24) * (brightness >> 2) / 100 ) << 24;
			copy_of_RGBTriplets++;
			}
		LoadRGB32( &scr->ViewPort, RGBTriplets );

		mode = scr->ViewPort.Modes;
		if ( mode & SUPERHIRES )
			{
			if ( mode & LACE )
				{ scaleX = 2; scaleY = 1; }
			else
				{ scaleX = 2; scaleY = 0; }
			}
		else if ( mode & HIRES )
			{
			if ( mode & LACE )
				{ scaleX = 1; scaleY = 1; }
			else
				{ scaleX = 1; scaleY = 0; }
			}
		else if ( mode & LACE )
			{ scaleX = 0; scaleY = 1; }

		if ( CreateFrames() )
			{
			success = TRUE;

			SpritesOff();

			x = RangeRand( scr->Width - 1 - (IMGW << scaleX) );
			y = RangeRand( scr->Height - 1 - (IMGH << scaleY) );

			do { dirx = RangeRand( 7 ) - 3; } while ( !dirx );
			do { diry = RangeRand( 7 ) - 3; } while ( !diry );

			while( STILL_BLANKING )
				{
				MoveSpotlight();

				if ( x < 0 )
					{ blitx = -x; sizex = (IMGW<<scaleX) + x; }
				else if ( x >= scr->Width - 1 - (IMGW<<scaleX) )
					{ blitx = 0; sizex = scr->Width - x - 1; }
				else
					{ blitx = 0; sizex = IMGW<<scaleX; }

				if ( y < 0 )
					{ blity = -y; sizey = (IMGH<<scaleY) + y; }
				else if ( y >= scr->Height - 1 - (IMGH<<scaleY) )
					{ blity = 0; sizey = scr->Height - y - 1; }
				else
					{ blity = 0; sizey = IMGH<<scaleY; }

				WaitTOF();

				BltBitMap( scalebm, blitx, blity,
					shadowbm, x < 0 ? 0 : ( x >= scr->Width ? scr->Width - 1 - x : x ), y < 0 ? 0 : ( y >= scr->Height ? scr->Height - 1 - y : y ),
					sizex, sizey, 0xC0, 0xFF, NULL );
				}

			SpritesOn();

			DisposeBitMap( scalebm );
			FreeVec( shadowbm );
			FreeVec( Spotlightsbm );
			}
		FreeVec( RGBTriplets );
		}
	CloseScreen( scr );
	}

if ( !success )
	SendClientMsg( ACTION_FAILED );
}


void __main( void )
{
if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
		{
		if ( BitMapBase = OpenLibrary( "bitmap.library", 0L ) )
			{
			if ( mem_ptr = AllocVec( BITPLSIZE, MEMF_CHIP ) )
				{
				img.ImageData = mem_ptr;

				if ( dinfo = OpenCommunication() )
					{
					CurrentTime( &RangeSeed, &RangeSeed );
					Blank();
					CloseCommunication( dinfo );
					}
				FreeVec( mem_ptr );
				}
			CloseLibrary( BitMapBase );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
