[comp.sources.amiga] iconify part 1 of 1

ain@j.cc.purdue.edu (Patrick White) (12/30/87)

Program Name:	iconify
Submitted By:	well!ewhac@lll-crg.llnl.gov (Leo 'Bols Ewhac' Schwab)
Summary:	This code shows how to iconify a window.
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Tested.

NOTES:
   There is an executable version of the demo posted to comp.binaries.amiga.

	"There are NO bugs in MY code."
   To get it to compile under Manx 3.4a, you *must* add some preceeding
				      ^
semicolons to the comments in the assembly code in the file demo.c.


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

----------------------------------------


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	README
#	iconify.doc
#	Makefile
#	iconify.h
#	iconify.c
#	demo.c
# This archive created: Fri Dec 18 16:14:20 1987
# By:	Leo 'Bols Ewhac' Schwab (Hole Earth 'Lectronic Loss (or words to that effect))
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'
	At last!  I wrote something useful!  This package contains the
iconify() routine, and a demo program that demonstrates it.

MANUFACTURE:
	This program is guaranteed to work with the Manx C compiler (version
3.4b).  However, I did try to keep compiler independence in mind when
writing it, so it is hoped that the iconify() routine will compile cleanly
under Lattice (but I haven't tried it, so no promises).  To create the demo,
you say:

1> make			

SHAMELESS PLEADING:
	Please do read the top comment in the iconify.c and/or iconify.h
file.

	I hope you all like this new goodie.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	ihnp4!ptsfa -\
 \_ -_		Recumbent Bikes:	      dual ---> !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor
SHAR_EOF
fi
if test -f 'iconify.doc'
then
	echo shar: "will not over-write existing file 'iconify.doc'"
else
cat << \SHAR_EOF > 'iconify.doc'
iconify()		Amiga Programmer's Manual		iconify()

NAME
	iconify -- Create an icon on the screen that can be dragged
		   around.

SYNOPSIS
	#include "iconify.h"
	int		success;

	success = 
	 iconify (LeftEdge, TopEdge, Width, Height, Screen, ptr, Type);
	UWORD		*LeftEdge, *TopEdge;
	UWORD		Width, Height;
	struct Screen	*Screen;
	APTR		ptr;
	int		Type;

DESCRIPTION
	Iconify() is a subroutine that creates an icon on the Amiga screen
	that can be subsequently dragged around, and double-clicked on.

	Iconify() creates an icon at screen location (*LeftEdge, *TopEdge)
	and of size (Width, Height), in pixels.  The icon is created on
	the screen specified.  If Screen is NULL, the icon will be created
	on the WorkBench screen.

	The Type variable tells iconify() how to make the icon.  Based on
	the value contained in Type, ptr may be interpreted in one of three
	different ways:

	ICON_IMAGE:
		ptr points to an initialized structure of type Image
		(intuition.h).  The image contained in the structure will
		be used as the icon image.

	ICON_BORDER:
		ptr points to an initialized structure of type Border
		(intuition.h).  The drawing instructions contained in the
		border structure will be used to render the icon.

	ICON_FUNCTION:
		[This is by far the most interesting one.]  ptr points to
		a function that will be called by iconify() N times a
		second (where N is a compile-time constant).  The format
		of the call is:

		(* ((void (*)()) ptr)) (win, val);
		struct Window	*win;
		WORD		val;

		When the icon is first created, your function will be
		called with val equal to one (non-zero).  This should be
		used as a flag to your function to call any initialization
		code it may need (such as caching the icon size, setting
		draw modes, etc.).  On every subsequent call, val will be
		equal to zero.

		win points to the window which is your icon (the icon is in
		fact a window-sized drag gadget).  This may be used for
		rendering purposes (animated icons, for example).

	After the icon is created, iconify() will wait until the icon has
	been double-clicked on.  If the icon is of type ICON_FUNCTION,
	iconify() will also call the supplied function N times a second
	while waiting for the double-click.
	
	When the icon is double-clicked, iconify() will update the values
	pointed to by LeftEdge and TopEdge.  This is so that, in subsequent
	invocations of iconify(), the icon will be where the user last left
	it.  Thus, it is the responsibility of the calling program to
	maintain these values.

	After updating these values, iconify() will remove the icon from
	the screen, and return to the caller with a non-zero value.  If any
	of iconify()'s internal operations fail, a zero value will be
	returned.  It is strongly suggested that this be checked for by
	the calling program.

VIEW TO OUTSIDE PROGRAMS
	Icons created with iconify() will look like small windows (this is
	largely due to the fact that they are small windows).  Outside
	programs may wish to differentiate between 'real' windows, and
	objects created with iconify().
	
	To this end, iconify() writes the 32-bit constant 0x49434f4e
	(which just happens to be the word 'ICON' in ASCII) into the
	window's UserData field.  Outside programs that are manipulating
	windows can check for this so they can avoid touching icons (or so
	that they can specifically find icons if they want).

AUTHOR
	Leo L. Schwab
	61 Martens Blvd.
	San Rafael, CA   94901-5028
	{ihnp4!ptsfa,hplabs}!{well!unicom}!ewhac

SEE ALSO
	Amiga Rom Kernel Manual
	Intuition: The Amiga User Interface

BUGS
	There are NO bugs in MY code.  However, there may be any number
	of undesireable features (but I doubt it).
SHAR_EOF
fi
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
# :ts=8 bk=0
#
# Makefile for iconify tester program.
OBJECTS = demo.o iconify.o

demo: $(OBJECTS)
	ln $(OBJECTS) +cd -lc
SHAR_EOF
fi
if test -f 'iconify.h'
then
	echo shar: "will not over-write existing file 'iconify.h'"
else
cat << \SHAR_EOF > 'iconify.h'
/*  :ts=8 bk=0
 *
 * iconify.h:	Should be used by all programs intending to use iconify.c.
 *
 * Copyright 1987 by Leo L. Schwab.
 * Permission is hereby granted for use in any and all programs, both
 * Public Domain and commercial in nature, provided this Copyright notice
 * is left intact.  Purveyors of programs, at their option, may wish observe
 * the following conditions (in the spirit of hackerdom):
 *	1: You send me a free, registered copy of the program that uses the
 *	   iconify feature,
 *	2: If you're feeling really nice, a mention in the program's
 *	   documentation of my name would be neat.
 *
 *			 		8712.10		(415) 456-3960
 */

#define	ICON_IMAGE	0
#define	ICON_BORDER	1
#define	ICON_FUNCTION	2

/*  Suggested icon size for a standard (640 x 200) WorkBench screen.  */
#define	ICONWIDTH	((UWORD) 50)
#define	ICONHEIGHT	((UWORD) 25)
SHAR_EOF
fi
if test -f 'iconify.c'
then
	echo shar: "will not over-write existing file 'iconify.c'"
else
cat << \SHAR_EOF > 'iconify.c'
/*  :ts=8 bk=0
 *
 * iconify.c:	You asked for it, you got it.
 *
 * Copyright 1987 by Leo L. Schwab.
 * Permission is hereby granted for use in any and all programs, both
 * Public Domain and commercial in nature, provided this Copyright notice
 * is left intact.  Purveyors of programs, at their option, may wish observe
 * the following conditions (in the spirit of hackerdom):
 *	1: You send me a free, registered copy of the program that uses the
 *	   iconify feature,
 *	2: If you're feeling really nice, a mention in the program's
 *	   documentation of my name would be neat.
 *
 *			 		8712.10		(415) 456-3960
 */
#include <exec/types.h>
#include <devices/timer.h>
#include <intuition/intuition.h>
#include "iconify.h"

/*
 * It is recommended that the tick rate not be made too rapid to avoid
 * bogging down the system.
 */
#define	TICKS_PER_SECOND	10

/*
 * Some programmers may not wish to have the added functionality of the
 * ICON_FUNCTION feature.  If you're such a programmer, you may comment out
 * the following #define, which will eliminate the code to handle function
 * calls, and make iconify() even smaller.
 */
#define	USE_FUNCTIONS

/*
 * Jim Mackraz suggested making icons easily identifiable by outside
 * programs, so this constant gets stuffed into the UserData field.
 */
#define	ICON	0x49434f4eL		/*  'ICON'  */


extern void	*OpenWindow(), *GetMsg(), *CreatePort(), *CreateExtIO(),
		*CheckIO();
extern long	OpenDevice(), DoubleClick();


static struct Gadget gadget = {
	NULL,
	0, 0, 0, 0,
	NULL,				/*  Set later  */
	GADGIMMEDIATE,
	WDRAGGING,			/*  Observe the Magic!  */
	NULL,				/*  Set later  */
	NULL, NULL, NULL, NULL,
	0, 0
};

static struct NewWindow windef = {
	0, 0, 0, 0,			/*  Set later  */
	-1, -1,
	GADGETDOWN,
	BORDERLESS | SMART_REFRESH | NOCAREREFRESH,
	&gadget,
	NULL, NULL, NULL, NULL,		/*  Lotsa these  */
	0, 0, 0, 0,
	WBENCHSCREEN
};

static struct Window		*win;

#ifdef USE_FUNCTIONS
static struct timerequest	*tr;
static struct MsgPort		*reply;
#endif


iconify (left, top, width, height, screen, ptr, type)
UWORD *left, *top, width, height;
struct Screen *screen;
APTR ptr;
int type;
{
	register struct IntuiMessage	*msg;
	long				secs = 0, mics = 0,
					cs, cm,
					class,
					sigmask;

	windef.LeftEdge		= *left;
	windef.TopEdge		= *top;
	windef.Width		= width;
	windef.Height		= height;
	windef.Type = (windef.Screen = screen) ? CUSTOMSCREEN : WBENCHSCREEN;

	gadget.Flags		= GADGHCOMP | GRELWIDTH | GRELHEIGHT;

	switch (type & 3) {
	case ICON_IMAGE:
		gadget.Flags		|= GADGIMAGE;
	case ICON_BORDER:
		gadget.GadgetRender	= ptr;
		break;

	case ICON_FUNCTION:
#ifdef USE_FUNCTIONS
		gadget.GadgetRender	= NULL;
#else
		return (0);
#endif
		break;

	default:
		return (0);
	}

	if (!openstuff ())
		return (0);
	sigmask = 1L << win -> UserPort -> mp_SigBit;

#ifdef USE_FUNCTIONS
	if (type == ICON_FUNCTION) {
		sigmask |= 1L << reply -> mp_SigBit;
		tr -> tr_node.io_Command= TR_ADDREQUEST;
		tr -> tr_time.tv_secs	= 0;
		tr -> tr_time.tv_micro	= (1000000L / TICKS_PER_SECOND);
		SendIO (tr);
		/*
		 * Make initialization call to user's function.
		 * Isn't typecasting wonderful?  :-|
		 */
		(* ((void (*)()) ptr)) (win, (WORD) 1);
	}
#endif

	while (1) {
		Wait (sigmask);

#ifdef USE_FUNCTIONS
		if (GetMsg (reply)) {
			/*
			 * Call user's function to do something to the icon.
			 */
			(* ((void (*)()) ptr)) (win, (WORD) 0);
			tr -> tr_time.tv_secs	= 0;
			tr -> tr_time.tv_micro	=
			 (1000000L / TICKS_PER_SECOND);
			SendIO (tr);
		}
#endif

		if (msg = GetMsg (win -> UserPort)) {
			class = msg -> Class;
			cs = msg -> Seconds;
			cm = msg -> Micros;
			ReplyMsg (msg);

			if (class == GADGETDOWN) {
				if (DoubleClick (secs, mics, cs, cm))
					break;
				secs = cs;  mics = cm;
			}
		}
	}

#ifdef USE_FUNCTIONS
	if (type == ICON_FUNCTION) {
		AbortIO (tr);
		WaitIO (tr);
	}
#endif

	*left = win -> LeftEdge;
	*top = win -> TopEdge;
	closestuff ();
	return (1);
}

static
openstuff ()
{
	if (!(win = OpenWindow (&windef)))
		return (0);
	win -> UserData = (BYTE *) ICON;
		
#ifdef USE_FUNCTIONS
	if (!(reply = CreatePort (NULL, NULL)) ||
	    !(tr = CreateExtIO (reply, (long) sizeof (*tr))) ||
	    OpenDevice (TIMERNAME, UNIT_VBLANK, tr, 0L)) {
		closestuff ();
		return (0);
	}
#endif

	return (1);
}

static
closestuff ()
{
#ifdef USE_FUNCTIONS
	if (tr) {
		if (tr -> tr_node.io_Device)
			CloseDevice (tr);
		DeleteExtIO (tr, (long) sizeof (*tr));
	}
	if (reply)		DeletePort (reply);
#endif

	if (win)		CloseWindow (win);
}
SHAR_EOF
fi
if test -f 'demo.c'
then
	echo shar: "will not over-write existing file 'demo.c'"
else
cat << \SHAR_EOF > 'demo.c'
/*  :ts=8 bk=0
 *
 * demo.c:	Demonstrates The Incredible New Iconification Program!!!!!!
 *
 * Leo L. Schwab			8712.10
 */
#include <exec/types.h>
#include <intuition/intuition.h>
#include "iconify.h"

#define	LENGTH		20

extern void	*OpenLibrary(), *OpenWindow(), *GetMsg();
extern long	VBeamPos();


/*  The Boing icon image  */
UWORD icon[] = { 
	0xFFFF,   0xFFFF,   0xFFFF,   0xC000, 
	0x8000,   0x0,   0x0,   0x4000, 
	0x8000,   0x0,   0x0,   0x4000, 
	0x8000,   0x1DF7,   0x0,   0x4000, 
	0x8001,   0xFBEF,   0xB000,   0x4000, 
	0x800D,   0xF7DF,   0x7C00,   0x4000, 
	0x803B,   0xEFBE,   0xFB80,   0x4000, 
	0x8077,   0xDF7D,   0xF7C0,   0x4000, 
	0x80EF,   0xBEFB,   0xEFA0,   0x4000, 
	0x81DF,   0x7DF7,   0xDF70,   0x4000, 
	0x83BE,   0xFBEF,   0xBEF8,   0x4000, 
	0x837D,   0xF7DF,   0x7DF0,   0x4000, 
	0x82FB,   0xEFBE,   0xFBE8,   0x4000, 
	0x81F7,   0xDF7D,   0xF7D8,   0x4000, 
	0x83EF,   0xBEFB,   0xEFB8,   0x4000, 
	0x81DF,   0x7DF7,   0xDF70,   0x4000, 
	0x80BE,   0xFBEF,   0xBEE0,   0x4000, 
	0x807D,   0xF7DF,   0x7DC0,   0x4000, 
	0x803B,   0xEFBE,   0xFB80,   0x4000, 
	0x8007,   0xDF7D,   0xF600,   0x4000, 
	0x8001,   0xBEFB,   0xF000,   0x4000, 
	0x8000,   0x1DF7,   0x0,   0x4000, 
	0x8000,   0x0,   0x0,   0x4000, 
	0x8000,   0x0,   0x0,   0x4000, 
	0xFFFF,   0xFFFF,   0xFFFF,   0xC000,

	0x0,   0x0,   0x0,   0x0, 
	0x0,   0x0,   0x0,   0x0, 
	0x0,   0x0,   0x0,   0x0, 
	0x0,   0x1F0,   0x0,   0x0, 
	0x1,   0xF860,   0x3000,   0x0, 
	0xC,   0x301C,   0x7C00,   0x0, 
	0x18,   0xE3E,   0x1800,   0x0, 
	0x7,   0x1F0C,   0x700,   0x0, 
	0xF,   0x8603,   0x8F80,   0x0, 
	0x1C3,   0x1C7,   0xC300,   0x0, 
	0x180,   0xE3E1,   0x80E0,   0x0, 
	0x71,   0xF0C0,   0x71F0,   0x0, 
	0xF8,   0x6038,   0xF860,   0x0, 
	0x30,   0x1C7C,   0x3018,   0x0, 
	0xE,   0x3E18,   0xE38,   0x0, 
	0x11F,   0xC07,   0x1F00,   0x0, 
	0x86,   0x38F,   0x8600,   0x0, 
	0x1,   0xC7C3,   0x1C0,   0x0, 
	0x3,   0xE180,   0xE380,   0x0, 
	0x0,   0xC071,   0xF000,   0x0, 
	0x0,   0x38F8,   0x7000,   0x0, 
	0x0,   0x1C30,   0x0,   0x0, 
	0x0,   0x0,   0x0,   0x0, 
	0x0,   0x0,   0x0,   0x0, 
	0x0,   0x0,   0x0,   0x0
};

static struct Image iconimg = {		/*  Icon Image  */
 	0, 0,
	50, 25, 2,
	icon,
	0x3, 0,
	NULL
};


static WORD bordbox[] = {	/*  A box with an X in it  */
	0, 0,
	ICONWIDTH-1, 0,
	ICONWIDTH-1, ICONHEIGHT-1,
	0, ICONHEIGHT-1,
	0, 0,
	ICONWIDTH-1, ICONHEIGHT-1,
	ICONWIDTH-1, 0,
	0, ICONHEIGHT-1
};

static struct Border iconbord = {	/*  Icon border  */
 	0, 0,
	1, 0, JAM1,
	8,
	bordbox,
	NULL,
};


/**************************************************************************
* Gadgets for the application's window.
*/

static WORD box[] = {
	-1, -1,
	48, -1,
	48, 10,
	-1, 10,
	-1, -1
};

static struct Border bord = {	/*  Window gadget border  */
 	0, 0,
	1, 0, JAM1,
	5,
	box,
	NULL,
};

static struct IntuiText text[] = {
 {
	1, 0, JAM1,
	4, 1,
	NULL,
	(UBYTE *) "Image",
	NULL,
 }, {
	1, 0, JAM1,
	4, 1,
	NULL,
	(UBYTE *) "Bordr",
	NULL,
 }, {
	1, 0, JAM1,
	4, 1,
	NULL,
	(UBYTE *) "Funct",
	NULL,
 }
};

static struct Gadget gads[] = {
 {			/*  Image  */
	&gads[1],
	0, -10, 48, 10,
	GADGHCOMP | GRELBOTTOM,
	RELVERIFY | BOTTOMBORDER,
	BOOLGADGET,
	(APTR) &bord,
	NULL,
	&text[0],
	NULL, NULL,
	ICON_IMAGE, 0
 }, {			/*  Border  */
	&gads[2],
	48, -10, 48, 10,
	GADGHCOMP | GRELBOTTOM,
	RELVERIFY | BOTTOMBORDER,
	BOOLGADGET,
	(APTR) &bord,
	NULL,
	&text[1],
	NULL, NULL,
	ICON_BORDER, 0
 }, {			/*  Function  */
	NULL,
	96, -10, 48, 10,
	GADGHCOMP | GRELBOTTOM,
	RELVERIFY | BOTTOMBORDER,
	BOOLGADGET,
	(APTR) &bord,
	NULL,
	&text[2],
	NULL, NULL,
	ICON_FUNCTION, 0
 }
};

struct NewWindow windef = {
	0, 0, 400, 100,
	-1, -1,
	CLOSEWINDOW | GADGETUP,
	WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH |
	 NOCAREREFRESH | ACTIVATE,
	gads,
	NULL,
	(UBYTE *) "Click on gadgets below and be amazed!",
	NULL, NULL,
	0, 0, 0, 0,
	WBENCHSCREEN
};

struct Window	*win;
long		xa1[LENGTH], xa2[LENGTH], ya1[LENGTH], ya2[LENGTH];
short		rnd();				/*  Forward reference  */
void		iconfunc();			/*  Forward reference  */
void		*IntuitionBase, *GfxBase;


main ()
{
	register struct IntuiMessage	*msg;
	register struct Gadget		*gad;
	long				class;
	UWORD				x = 0, y = 0;
	int				type;
	void				*ptr;

	openstuff ();
	rnd ((int) -VBeamPos());
	doline (win, 1);

	while (1) {
		if (msg = GetMsg (win -> UserPort)) {
			class = msg -> Class;
			gad = (struct Gadget *) msg -> IAddress;
			ReplyMsg (msg);

			if (class == CLOSEWINDOW)
				break;
			else {
				switch (gad -> GadgetID) {
				case ICON_IMAGE:
					ptr = &iconimg;
					break;

				case ICON_BORDER:
					ptr = &iconbord;
					break;

				case ICON_FUNCTION:
					ptr = (void *) iconfunc;
					break;
				}

				/*
				 * And now!  The moment you've been waiting
				 * for!
				 */
				windef.LeftEdge = win -> LeftEdge;
				windef.TopEdge	= win -> TopEdge;
				CloseWindow (win);  win = NULL;

				iconify (&x, &y, ICONWIDTH, ICONHEIGHT,
					 NULL, ptr, (int) gad -> GadgetID);

				if (!(win = OpenWindow (&windef)))
					die ("Window re-open failed\n");

				doline (win, 1);
			}
		}
		doline (win, 0);
		WaitTOF ();
	}
	closestuff ();
}

doline (win, reset)
struct Window *win;
int reset;
{
	register struct RastPort	*rp = win -> RPort;
	static long			x1, x2, y1, y2, dx1, dx2, dy1, dy2;
	static long			xmin, ymin, xmax, ymax;
	static int			i, flag;

	if (reset) {
		xmin	= win -> BorderLeft;
		ymin	= win -> BorderTop;
		xmax	= win->Width - win->BorderRight - 1;
		ymax	= win->Height - win->BorderBottom - 1;
		x1 = rnd ((int) xmax);  y1 = rnd ((int) ymax);
		x2 = rnd ((int) xmax);  y2 = rnd ((int) ymax);
		setdisp (&dx1, &dy1);
		setdisp (&dx2, &dy2);
		SetDrMd (rp, COMPLEMENT);
		i = flag = 0;
	}

	if (!rnd (20))
		if (rnd (2))
			setdisp (&dx1, &dy1);
		else
			setdisp (&dx2, &dy2);

	x1 += dx1;  y1 += dy1;
	if (x1 > xmax || x1 < xmin) {
		dx1 = -dx1;
		x1 = x1<xmin ? xmin : xmax;
	}
	if (y1 > ymax || y1 < ymin) {
		dy1 = -dy1;
		y1 = y1<ymin ? ymin : ymax;
	}

	x2 += dx2;  y2 += dy2;
	if (x2 > xmax || x2 < xmin) {
		dx2 = -dx2;
		x2 = x2<xmin ? xmin : xmax;
	}
	if (y2 > ymax || y2 < ymin) {
		dy2 = -dy2;
		y2 = y2<ymin ? ymin : ymax;
	}

	Move (rp, x1, y1);
	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;

	if (++i >= LENGTH) {
		i = 0;
		flag = 1;
	}
}

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

void
iconfunc (win, init)
struct Window *win;
WORD init;
{
	if (init) {
		/*  Initialization pass, draw a border in the icon  */
		SetAPen (win -> RPort, 1L);
		Move (win -> RPort, 0L, 0L);
		Draw (win -> RPort, win -> Width - 1L, 0L);
		Draw (win -> RPort, win -> Width - 1L, win -> Height - 1L);
		Draw (win -> RPort, 0L, win -> Height - 1L);
		Draw (win -> RPort, 0L, 0L);
		doline (win, 1);
	}
	doline (win, 0);
}

openstuff ()
{
	if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L)))
		die ("-=RJ=-'s missing.\n");

	if (!(GfxBase = OpenLibrary ("graphics.library", 0L)))
		die ("Dale, where are you?\n");

	if (!(win = OpenWindow (&windef)))
		die ("Window painted shut.\n");
}

closestuff ()
{
	if (win)		CloseWindow (win);
	if (GfxBase)		CloseLibrary (GfxBase);
	if (IntuitionBase)	CloseLibrary (IntuitionBase);
}

die (str)
char *str;
{
	extern long	Output();

	Write (Output (), str, (long) strlen (str));
	closestuff ();
	exit (20);
}

/***********************************************************************/
#asm
*\
*  :ts=8
* Yet Another random number generator.  By Leo Schwab.
* Based on an idea posted on the USENET (Thanks, Sam Dicker!)
* For the Manx assembler.
*
* Calling convention:
*  short rnd (range);
*  short range;
*
* 8606.30
*/

		public    _rnd

_rnd		lea	rndseed,a0	Get address of seed
		move.w	4(sp),d1	Get range argument
		tst.w	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
		divu	d1,d0		Divide by range
		swap	d0		 and get remainder (modulus)
		rts

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

		dseg
rndseed		dc.l	0
		cseg
#endasm
SHAR_EOF
fi
exit 0
#	End of shell archive