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

 FadeScreen 1.4  (Client for BServer)

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

#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>

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

#include "/include/client.h"

char *ver = "$VER: FadeScreen 1.4 "__AMIGADATE__;

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

struct Screen *scr;
int scrdepth, delay, darkness_percent;

struct DisplayIDInformation *dinfo;
ULONG command;


void FadeOut( void )
{
UWORD n, yoffs, ticks = 0;
ULONG color;
BOOL blanking;
ULONG *current, *colors, *copy_of_colors, *faded, colorsize = (257 * 3 + 1) * sizeof(ULONG);
BOOL result = FALSE;
UBYTE fadecount = 0;
UBYTE actual_percent = 100;

scr = IntuitionBase->FirstScreen;
scrdepth = scr->RastPort.BitMap->Depth;

if ( colors = AllocVec( colorsize, MEMF_ANY|MEMF_CLEAR ) )
	{
	if ( faded = AllocVec( colorsize, MEMF_ANY|MEMF_CLEAR ) )
		{
		if ( CheckAA() )
			{
			*colors = (1L<<scrdepth)<<16;
			current = colors;
			current++;
			GetRGB32( scr->ViewPort.ColorMap, 0, 1<<scrdepth, current );
			CopyMem( colors, faded, colorsize );
			}
		else
			{
			current = colors;
			current++;
			for ( n = 0; n < 1<<scrdepth; n++ )
				{
				color = GetRGB4( scr->ViewPort.ColorMap, n );
				*current++ = color >> 8;
				*current++ = (color & 0xF0) >> 4;
				*current++ = color & 0xF;
				CopyMem( colors, faded, colorsize );
				}
			}

		result = TRUE;
		SpritesOff();

		yoffs = scr->TopEdge;
		MoveScreen( scr, 0, - yoffs );

		blanking = TRUE;

		while( blanking )
			{
			WaitTOF();
			if ( actual_percent > darkness_percent )
				command = GetServerCommand();
			else
				command = WaitServerCommand();

			if ( command == COMMAND_QUIT )
				blanking = FALSE;
			else
			if ( (actual_percent > darkness_percent) && (++ticks > delay) )
				{
				ticks = 0;
				actual_percent--;
				current = faded;
				current++;
				copy_of_colors = colors;
				copy_of_colors++;

				if ( CheckAA() )
					{
					for ( n = 0; n < (1<<scrdepth) * 3; n++ )
						*current++ = ( (*copy_of_colors++>>24)*actual_percent/100 )<<24;

					WaitTOF();
					LoadRGB32( &scr->ViewPort, faded );
					}
				else
					{
					WaitTOF();
					if ( ++fadecount == 16 )
						{
						fadecount = 0;
						for ( n = 0; n < 1<<scrdepth; n++ )
							SetRGB4( &scr->ViewPort, n, (*copy_of_colors++)*actual_percent/100, (*copy_of_colors++)*actual_percent/100, (*copy_of_colors++)*actual_percent/100 );
						}
					}
				}
			}

		MoveScreen( scr, 0, yoffs );
		SpritesOn();

		if ( CheckAA() )
			LoadRGB32( &scr->ViewPort, colors );
		else
			{
			current = colors;
			current++;
			for ( n = 0; n < 1<<scrdepth; n++ )
				SetRGB4( &scr->ViewPort, n, *current++, *current++, *current++ );
			}

		FreeVec( faded );
		}
	FreeVec( colors );
	}

if ( !result )
	SendClientMsg( ACTION_FAILED );
}


void __main( void )
{
if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 36L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library",0L ) )
		{
		if ( dinfo = OpenCommunication() )
			{
			if ( !GetArgInt( dinfo->di_Args, "BRIGHTNESS", &darkness_percent ) )
				darkness_percent = 25;

			if ( darkness_percent < 0 )
				darkness_percent = 0;
			if ( darkness_percent > 100 )
				darkness_percent = 100;

			if ( !GetArgInt( dinfo->di_Args, "DELAY", &delay ) )
				delay = 20;

			if ( delay < 0 )
				delay = 0;
			if ( delay > 100 )
				delay = 100;

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