
/*
 *  MyBlank.c
 *
 *  DMouse screen blanker for use with DMouse V1.20
 *
 *  Is your computer BORED? If so, then you need...
 *
 *		DStringArt by Larry Phillips
 *		 with all the code for interfacing with DMouse
 *		  flagrantly ripped off from DLineArt
 *		   by Steve 'Raz' Berry
 *		    helped in turn by
 *		     Matt Dillon.
 *
 *  Compile +L w/ sup32.lib.  libs:dres.library no longer required
 */

#include <local/typedefs.h>
#include <local/ipc.h>
#include <local/xmisc.h>

typedef struct IORequest IORequest;

int MAXX, MAXY;

#define DELAY 100
#define BOUNDX MAXX-MINBOUND
#define BOUNDY MAXY-MINBOUND

extern int Enable_Abort;

RP *rp;
VP *vp;
static SCR *Scr;
static WIN *Win;
static TA   Ta = {  (ubyte *)"topaz.font", 11 };
static NS   Ns = {  0, 0, 0, 0, 1, -1, -1, HIRES|LACE, CUSTOMSCREEN|SCREENQUIET, &Ta };
static NW   Nw = { 0, 0, 0, 0, 2, 1, NULL, BORDERLESS|NOCAREREFRESH|BACKDROP,
NULL, NULL,NULL,NULL,NULL,0,0,8000,8000,CUSTOMSCREEN};

char *buf[20] = '\0';

float radians = 180/PI;

double sin(), cos();

#define MAXOBJ 10

struct Object
	{
	LONG	colour;
	int	iter;
	int	x1;
	int	y1;
	int	x2;
	int	y2;
	}	parms[MAXOBJ] = {

		/*	color  iter x1  y1  x2 y2  */

			0xa63, 360, 0, 0,   0, 0,
			0xff0, 213, 0, 200, 0, 300,
			0x00f, 320, 0, 0,   0, 0,
			0x0f0, 360, 0, 0,   0, 0,
			0xf0f, 360, 0, 0,   0, 0,
			0xf00, 300, 0, 0,   0, 0,
			0xfa0, 400, 0, 0,   0, 0,
			0x0ff, 270, 0, 0,   0, 0,
			0xf0f, 360, 0, 0,   0, 0,
			0x0f4, 360, 0, 0,   0, 0
	};

int
	x1 = 0,
	x2 = 0,
	y1 = 0,
	y2 = 0,
	theta = 0,
	count = 0,
	object = 0,
	objcount = 0,
	delaycount = 0;

void
InitScrStructures()
{
	SCR scr;
	if (GetScreenData(&scr, sizeof(scr), WBENCHSCREEN, NULL)) {
		if (scr.ViewPort.Modes & HIRES)
			MAXX = scr.Width;
		else
			MAXX = scr.Width * 2;
		if (scr.ViewPort.Modes & LACE)
			MAXY = scr.Height;
	else
		MAXY = scr.Height * 2;
	}
	else {
		MAXX = 640;
		MAXY = 200;
	}
	Ns.Width  = MAXX;
	Nw.Width  = MAXX;
	Ns.Height = MAXY;
	Nw.Height = MAXY;
}

main()
{
int var;
IORequest AddReq;	/* for dmouse ipc	*/
IORequest RemReq;
PORT    *dmport;
PORT    *ipport;
char    foo;	/*  dummy variable, address used as id	*/
short   notdone = 1;
radians = 3.14159/180;

	Enable_Abort = 0;


	ipport = CreatePort(NULL, 0);   /*  ipc port    */

	if (openlibs(INTUITION_LIB|GRAPHICS_LIB) == 0)
		goto fail;

	InitScrStructures();

	AddReq.io_Message.mn_ReplyPort = ipport;
	AddReq.io_Command = 0x84;
	AddReq.io_Unit = (struct Unit *)&foo;
	AddReq.io_Flags = 0x0C;	/* %1100 (screen blanker, no mouse blanker) */

	RemReq.io_Message.mn_ReplyPort = ipport;
	RemReq.io_Command = 0x85;
	RemReq.io_Unit = (struct Unit *)&foo;

	Forbid();
	if (dmport = FindPort("DMouse.ipc"))
		PutMsg(dmport, &AddReq.io_Message);
	Permit();
	if (dmport == NULL) {
		puts("DMouse not running or <V1.20");
		goto fail;
	}

	while (notdone) {
		long mask = SIGBREAKF_CTRL_C | (1 << ipport->mp_SigBit);
		if (Scr)
			mask = SetSignal(0L, mask);
		else
			mask = Wait(mask);

		if (mask & SIGBREAKF_CTRL_C)
			notdone = 0;
		if (mask & (1 << ipport->mp_SigBit)) {
			IORequest *ior;
			while (ior = (IORequest *)GetMsg(ipport)) {
				if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {
					notdone = 0;
					continue;
				}
			switch(ior->io_Command) {
				case 0x82:
					screenon();
					break;
				case 0x83:
					screenoff();
					break;
				case 0x86:
					notdone = 0;
					break;
			}
			ReplyMsg(&ior->io_Message);
			}
		}
		if (Win) {
			LineArt();
			}
	}
	screenon();

	PutMsg(dmport, &RemReq.io_Message);
		{
		register IORequest *ior = NULL;
		while (ior != &AddReq) {
			WaitPort(ipport);
			ior = (IORequest *)GetMsg(ipport);
			if (ior->io_Message.mn_Node.ln_Type == NT_MESSAGE)
			ReplyMsg(&ior->io_Message);
		}
	}

fail:
		DeletePort(ipport);
		closelibs(-1);
}

screenoff()
{
	if (Scr)
		ScreenToFront(Scr);
	else
	if (Scr = OpenScreen(&Ns)) {
		Nw.Screen = Scr;
		if (Win = OpenWindow(&Nw)){
			vp = &Scr->ViewPort;
			rp = Win->RPort;
			LoadRGB4(vp,&parms[0].colour,2L);
			count = 0;
		}
	ShowTitle(Scr, FALSE);
	}
}

screenon()
{
	if (Win)
		CloseWindow(Win);
	if (Scr)
		CloseScreen(Scr);
	Win = NULL;
	Scr = NULL;
	vp = NULL;
	rp = NULL;
}

LineArt()
{
int i;

	WaitTOF();

	SetAPen(rp, 1L);

	if (count == 0) {
		objcount = parms[object].iter;
		LoadRGB4(vp,&parms[object].colour,2L);
		x1 = parms[object].x1;
		y1 = parms[object].y1;
		x2 = parms[object].x2;
		y2 = parms[object].y2;
		calcobj(object);
		count++;
		}

	if (count == objcount) {
		WaitTOF();
		if (++delaycount == DELAY) {
			count++;
			delaycount = 0;
			return(0);
			}
		else
			return(0);
		}

	if (count > objcount)  {
		count = 0;
		object++;
		if (object == MAXOBJ) object = 0;
		Move(rp, 0, 0);
		ClearScreen(rp);
		delaycount = 0; 
		return(0);
		}


	Move(rp, x1, y1);
	Draw(rp, x2, y2);

	count++;

	calcobj(object);
	return(0);
}

calcobj(object)

int object;
{

	switch (object) {
		case 0:
			x1 = (int)( 320 + (100 * cos( (float)count*radians)) );
			y1 = (int)( 250 + (100 * sin( (float)count*radians)) );
			x2 = (int)( x1 + (100 * cos( (float)x1*radians)) );
			y2 = (int)( y1 + (100 * sin( (float)x1*radians)) );
			break;
		case 1:
			x1 += 3;
			x2 = (int)( 320 + (100 * cos( (float)x1*radians)) );
			y2 = (int)( 200 + (100 * sin( (float)x1*radians)) );
			break;
		case 2:
			if ( y1 != 398 ) {
				x1 += 3;
				y1 += 2;
				}
			x2 = (int)( 200 + (100 * cos( (float)count*radians)) );
			y2 = (int)( 200 + (100 * sin( (float)count*radians)) );
			break;
		case 3:
			x1 = (int)( 201 + (200 * cos( (float)count*radians)) );
			y1 = (int)( 200 + (199 * sin( (float)count*radians)) );
			x2 = (int)( 439 + (200 * sin( (float)count*radians)) );
			y2 = (int)( 200 + (199 * cos( (float)count*radians)) );
			break;
		case 4:
			x1 = (int)( 101 + (100 * cos( (float)(count*2)*radians)) );
			y1 = (int)( 200 + (100 * sin( (float)(count*2)*radians)) );
			x2 = (int)( 439 + (200 * sin( (float)count*radians)) );
			y2 = (int)( 200 + (199 * cos( (float)count*radians)) );
			break;
		case 5:
			x1 = (int)( 201 + (count * cos( (float)count*radians))/2 );
			y1 = (int)( 200 + (count * sin( (float)count*radians))/2 );
			x2 = (int)( 439 + (count * sin( (float)count*radians)) );
			y2 = (int)( 200 + (count * cos( (float)count*radians)) );
			break;
		case 6:
			x1 = (int)( 320 + (300 * cos( (float)(count*3)*radians)) );
			y1 = (int)( 200 + (100 * sin( (float)(count*3)*radians)) );
			x2 = (int)( 320 + (100 * cos( (float)(count*5)*radians)) );
			y2 = (int)( 200 + ( 50 * sin( (float)(count*5)*radians)) );
			break;
		case 7:
			x1 += 2;
			y1 = 200;
			x2 = (int)( x1 + (int)( 100 * cos( (float)x1 * radians)));
			y2 = (int)( 200 + (int)( 50 * sin( (float)x1 * radians)));
			break;
		case 8:
			x1 = (int)( 201 + (200 * cos( (float)count*radians))/3 );
			y1 = (int)( 200 + (199 * sin( (float)count*radians))/3 );
			x2 = (int)( 439 + (200 * cos( (float)count*radians)) );
			y2 = (int)( 200 + (199 * sin( (float)count*radians)) );
			break;
		case 9:
			x1 = (int)( 320 + abs((200 * cos( (float)count*radians))/2) );
			y1 = (int)( 300 + (199 * sin( (float)count*radians))/2 );
			x2 = (int)( 320 + (150 * sin( (float)count*radians)) );
			y2 = (int)( 200 + (150 * cos( (float)count*radians)) );
			break;
		}

/*  Debug stuff here, for checking iterations or whatever. */

/*	sprintf(buf, "%d", count);
 *	Move(rp, 400, 20);
 *	Text(rp, buf, 4);
 */

	return(0);
}
