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

 Shuffle 1.0  (Client for BServer)

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

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

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

#include "/include/client.h"

extern ULONG RangeSeed;

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

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *IconBase;
struct DisplayIDInformation *dinfo;

#define IDLE           0
#define SHIFTING_LEFT  1
#define SHIFTING_RIGHT 2
#define SHIFTING_UP    3
#define SHIFTING_DOWN  4

int status = IDLE;
UWORD rectwidth, rectheight, x, y, shift_count, slices = 4;
BOOL correct_state;

void Blank( void )
{
struct Screen *scr;
struct RastPort *rp;

if ( scr = CloneFrontmostScreen( GETBRIGHTNESS(dinfo) ) )
	{
	rp = &scr->RastPort;
	SpritesOff();

	rectwidth = scr->Width >> slices;
	rectheight = scr->Height >> slices;

	for ( x = 0; x < 1 << slices; x++ )
		for ( y = 0; y < 1 << slices; y++ )
			{
			SetAPen( rp, BrightestColorIndex( scr ) );
			Move( rp, x * rectwidth, ( y + 1 ) * rectheight - 1 );
			Draw( rp, x * rectwidth, y * rectheight );
			Draw( rp, ( x + 1 ) * rectwidth - 1, y * rectheight );
			SetAPen( rp, DarkestColorIndex( scr ) );
			Move( rp, ( x + 1 ) * rectwidth - 1, y * rectheight );
			Draw( rp, ( x + 1 ) * rectwidth - 1, ( y + 1 ) * rectheight - 1 );
			Draw( rp, x * rectwidth, ( y + 1 ) * rectheight - 1 );
			}

	x = RangeRand( (1<<slices)-2 ) + 1;
	y = RangeRand( (1<<slices)-2 ) + 1;

	SetAPen( rp, 3 );
	RectFill( rp, x * rectwidth, y * rectheight, ( x + 1 ) * rectwidth - 1, ( y + 1 ) * rectheight - 1 );

	while ( STILL_BLANKING )
		{
		WaitTOF();
		switch( status )
			{
			case IDLE:
				correct_state = FALSE;
				while ( !correct_state )
					{
					status = RangeRand( 4 ) + 1;
					if ( status == SHIFTING_LEFT  && x > 0  ||
					     status == SHIFTING_RIGHT && x < (1<<slices)-1 ||
				    	 status == SHIFTING_UP    && y > 0  ||
					     status == SHIFTING_DOWN  && y < (1<<slices)-1 )
						correct_state = TRUE;
					}
				break;
			case SHIFTING_LEFT:
				BltBitMap( rp->BitMap, (x-1) * rectwidth, y * rectheight, rp->BitMap, x * rectwidth, y * rectheight, rectwidth, rectheight, 0xC0, 0xFF, NULL );
				RectFill( rp, (x-1) * rectwidth, y * rectheight, x * rectwidth - 1, (y+1) * rectheight - 1 );
				x--;
				status = IDLE;
				break;
			case SHIFTING_RIGHT:
				BltBitMap( rp->BitMap, (x+1) * rectwidth, y * rectheight, rp->BitMap, x * rectwidth, y * rectheight, rectwidth, rectheight, 0xC0, 0xFF, NULL );
				RectFill( rp, (x+1) * rectwidth, y * rectheight, (x+2) * rectwidth - 1, (y+1) * rectheight - 1 );
				x++;
				status = IDLE;
				break;
			case SHIFTING_UP:
				BltBitMap( rp->BitMap, x * rectwidth, (y-1) * rectheight, rp->BitMap, x * rectwidth, y * rectheight, rectwidth, rectheight, 0xC0, 0xFF, NULL );
				RectFill( rp, x * rectwidth, (y-1) * rectheight, (x+1) * rectwidth - 1, y * rectheight - 1 );
				y--;
				status = IDLE;
				break;
			case SHIFTING_DOWN:
				BltBitMap( rp->BitMap, x * rectwidth, (y+1) * rectheight, rp->BitMap, x * rectwidth, y * rectheight, rectwidth, rectheight, 0xC0, 0xFF, NULL );
				RectFill( rp, x * rectwidth, (y+1) * rectheight, (x+1) * rectwidth - 1, (y+2) * rectheight - 1 );
				y++;
				status = IDLE;
				break;
			}
		}

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


void __main( void )
{
char buff[10];

if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
		{
		if ( dinfo = OpenCommunication() )
			{
			if ( GetArgString( dinfo->di_Args, "SLICES", buff ) )
				slices = atoi( buff );
			else
				slices = 4;

			if ( slices < 2 || slices > 5 )
				slices = 4;

			CurrentTime( &RangeSeed, &RangeSeed );
			Blank();
			CloseCommunication( dinfo );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
