#if 0
	How to make this beastie:

Assumptions: source is in current directory, MetaComCo assembler is in df1:,
	Alink is in your C: directory.

1> df1:c/assem rnd.s -o rnd.o
1> df1:c/assem rotate.s -i df1:include -o rotate.o

At this point, put your Lattice compiler in df1:

1> df1:c/lc1 -idf1:include/ nart
1> df1:c/lc2 -v nart		; -v really isn't necessary
1> alink df1:lib/astartup.obj+nart.o+rnd.o+rotate.o library df1:lib/amiga.lib+df1:lib/lc.lib to nart faster

SYNOPSIS
	nart

DESCRIPTION
	NART is the New Art program (if you have the Manx compiler with an
examples directory, you have the old art program).  It's a display hack that
I finally got around to making "flow."  May actually hold your interest for
a few seconds.  May give some people headaches.

--------

	I originally tried to write this under Manx, but it became
non-trivial, so I didn't bother.  Getting what I wanted to happen under
Lattice was no picnic either.  If you manage to coerce this to work under
Manx, let me know.

	Yes, including lc.lib is necessary, but by trickery and deceit at
the linking stage, I have managed to keep the code size down.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 ________                ___
           \            /___--__                Leo L. Schwab
  ___  ___ /\               ---##\              ihnp4!ptsfa!well!ewhac
      /   X  \_____    |  __ _---))                      ..or..
     /   /_\--    -----+==____\ // \  _         well ---\
___ (   o---+------------------O/   \/ \        dual ----> !unicom!ewhac
     \     /                ___ \_  (`o )       hplabs -/       ("AE-wack")
 ____ \___/                          \_/
              Recumbent Bikes:                  "Work FOR?  I don't work FOR
            The _O_n_l_y Way To Fly!                anybody!  I'm just having fun."
#endif

/*  :ts=8 bk=0
 * In the tradition of stupid programs, Leo Schwab presents (yet again)
 * The Art Program.
 *
 * Modofied to do even neater things.
 * 8607.1
 */

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

#define XSIZE           319L
#define YSIZE           199L

extern long rnd();

void *OpenLibrary();
struct IntuitionBase    *IntuitionBase;
struct GfxBase          *GfxBase;
struct Screen   *scr, *OpenScreen();
struct Window   *win, *OpenWindow();
struct ViewPort *vp;

struct NewScreen scrdef = {
        0, 0, XSIZE+1, YSIZE+1,
        4,              /*  16 colors  */
        0, 1,           /*  detail/block pens  */
                        /*  "Automatically" set up screen format  */
        ((XSIZE>320) ? HIRES : 0) | ((YSIZE>200) ? LACE : 0),
        CUSTOMSCREEN,
        NULL, NULL, NULL, NULL  /* no special font, title, gadg, or bitmap */
};

struct NewWindow windef = {
        0, 0, XSIZE+1, YSIZE+1,
        0, 1,
        CLOSEWINDOW,
        WINDOWCLOSE | BACKDROP | BORDERLESS,
        NULL, NULL, NULL,       /* no special gadget, checkmark or title */
        NULL,                   /* screen pointer; will get set later */
        NULL,                   /* no custom bitmap */
        0, 0, 0, 0,             /* ignored */
        CUSTOMSCREEN
};

main ()
{
        register struct RastPort *rp;
        long i, dx1, dy1, dx2, dy2, pen = 16, flag = 0;
        static long xa1[150], ya1[150], xa2[150], ya2[150];
        register long x1, y1, x2, y2;

        openstuff ();
        rnd (-87634L);
/*	rp = win -> RPort;    <-- This is slower because of layers    */
        rp = & (scr -> RastPort);
        SetDrMd (rp, COMPLEMENT);
        ShowTitle (scr, FALSE);
        SetRast (rp, 0L);
        x1 = rnd (XSIZE+1);  y1 = rnd (YSIZE+1);
        x2 = rnd (XSIZE+1);  y2 = rnd (YSIZE+1);
        setdisp (&dx1, &dy1);
        setdisp (&dx2, &dy2);

       while (1) {
        for (i=0; i<150; i++) {
		rotate ();
                if (GetMsg (win -> UserPort)) {
                        closestuff ();
                        exit (TRUE);
                }
                if (rnd (12L) == 3)
                        if (rnd (2L))
                                setdisp (&dx1, &dy1);
                        else
                                setdisp (&dx2, &dy2);

                x1 += dx1;  y1 += dy1;
                if (x1 > XSIZE || x1 < 0) {
                        dx1 = -dx1;
                        x1 = x1<0 ? 0 : XSIZE;
                }
                if (y1 > YSIZE || y1 < 0) {
                        dy1 = -dy1;
                        y1 = y1<0 ? 0 : YSIZE;
                }
                x2 += dx2;  y2 += dy2;
                if (x2 > XSIZE || x2 < 0) {
                        dx2 = -dx2;
                        x2 = x2<0 ? 0 : XSIZE;
                }
                if (y2 > YSIZE || y2 < 0) {
                        dy2 = -dy2;
                        y2 = y2<0 ? 0 : YSIZE;
                }

                if (!--pen)
                        pen = 15;
                rp -> Mask = pen;       /* kludge; COMPLEMENT does not  */
                Move (rp, x1, y1);      /* perform as advertised  */
                Draw (rp, x2, y2);
                if (flag) {
                        Move (rp, xa1[i], ya1[i]);
                        Draw (rp, xa2[i], ya2[i]);
                }
                xa1[i] = x1;  ya1[i] = y1;
                xa2[i] = x2;  ya2[i] = y2;
        }
       flag = 1;
       }        /* End of the while */
}

openstuff ()
{
        if (!(IntuitionBase = (struct IntuitionBase *)
            OpenLibrary ("intuition.library", 1L))) {
                printf ("Awright, where's Intuition?\n");
                exit (FALSE);
        }

        if (!(GfxBase = (struct GfxBase *)
            OpenLibrary ("graphics.library", 1L))) {
                printf ("Graphics?  Heeeere graphics....\n");
                exit (FALSE);
        }

	if (!(scr = OpenScreen (&scrdef))) {
                printf ("Can't open your screen.\n");
                exit (FALSE);
        }

        windef.Screen = scr;
        if (!(win = OpenWindow (&windef))) {
                printf ("Window painted shut.\n");
                exit (FALSE);
        }
	vp = &(scr -> ViewPort);
	setcolors ();
}

closestuff ()
{
        CloseWindow (win);
        CloseScreen (scr);
        CloseLibrary (GfxBase);
        CloseLibrary (IntuitionBase);
}

setdisp (x, y)
register long *x, *y;
{
        *x = rnd (9L) - 4;
        *y = rnd (9L) - 4;
}

/*  What I really wanted was the HSL color wheel.  Oh well....  */
setcolors ()
{
	long r, g, b, i;

	for (i=1; i<16; i++) {
		if (i <= 5) {
			r = (6-i) * 15 / 5;
			g = (i-1) * 15 / 5;
			b = 0;
		} else if (i > 5 && i <= 10) {
			r = 0;
			g = (11-i) * 15 / 5;
			b = (i-5) * 15 / 5;
		} else if (i > 10) {
			r = (i-10) * 15 / 5;
			g = 0;
			b = (16-i) * 15 / 5;
		}
		SetRGB4 (vp, i, r, g, b);
	}
	SetRGB4 (vp, 0L, 0L, 0L, 0L);
}

#asm
*\
*  :ts=8 bk=0
* Yet Another random number generator.  By Leo Schwab.
* Based on an idea posted on the USENET (Thanks, Sam Dicker!)
* For the MetaComCo assembler
*
* Calling convention:
*  long rnd (range);
*  long range;
*
* Assembling:
*  df1:c/assem rnd.s -o rnd.o
* 
* 8606.30
*/

		blanks off
		section code
		xdef	_rnd

_rnd		lea	rndseed,a0	;Get address of seed
		move.l	4(sp),d1	;Get range argument
		tst.l	d1
		ble.s	setseed		;Go reset seed


		move.l	(a0),d0		;Get seed
		ADD.L   D0,D0
		BHI.S   over
		EORI.L  #$1D872B41,D0
over
		move.l	d0,(a0)		;Save new seed
		andi.l	#$ffff,d0	;Coerce into word
		andi.l	#$ffff,d1
		divu	d1,d0		;Divide by range
		swap	d0		 ;and get remainder (modulus)
		ext.l	d0
		rts

setseed		neg.l	d1		;Probably don't need this
		move.l	d1,(a0)
		rts

		section data
rndseed		dc.l	0
		section code

*\  :ts=8 bk=0
* The color rotater for the New Art program.
* This was written in machine code for speed (Lattice has this odd habit
* of pessimizing code).
*
* Calling convention:
*  rotate ();
*
* Assembling:
*  df1:c/assem rotate.s -i df1:include -o rotate.o
*
* 8607.1
*/

		include	"exec/types.i"
		include	"exec/libraries.i"
		include "graphics/view.i"

xlib		macro
		xref	_LVO\1
		endm

callsys		macro
		CALLLIB	_LVO\1
		endm

		xdef	_rotate

		xref	_GfxBase
		xref	_vp

		xlib	LoadRGB4

;		rorg	0


_rotate		movem.l	a2-a3/a6,-(sp)

		movea.l	_vp,a0
		movea.l a0,a1
		movea.l vp_ColorMap(a1),a1
		movea.l cm_ColorTable(a1),a1
		movea.l a1,a2
		adda.w	#1*2,a2		;Point at the colors we want
		movea.l	a2,a3
		addq.w	#2,a3
		moveq	#13,d0
		move.w	(a2),d1
loop		move.w	(a3)+,(a2)+
		dbra	d0,loop
		move.w	d1,(a2)

		movea.l	_GfxBase,a6
		moveq	#32,d0
		callsys	LoadRGB4

		movem.l	(sp)+,a2-a3/a6
		rts

#endasm
