/*  :ts=8 bk=0
 *
 * marketroid.c:	The Killer Demo To End All Killer Demos (we hope).
 *
 * Leo L. Schwab			8710.2		(415) 456-3960
 */
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include "marketroid.h"

#define	ABS(x)		((x) < 0 ? -(x) : (x))
/*  Helpful macro  */
#define	chkabort()	(GetMsg (win -> UserPort))


extern struct obcontrol	*addobject();

extern struct object	ob_hero, ob_RJ, ob_dale, ob_jay, ob_bike;
extern struct object	ob_grunt, ob_hulk, ob_brain, ob_spheroid, ob_tank,
			ob_missile, ob_quark, ob_enforcer, ob_prog;
extern struct object	ob_1K, ob_2K, ob_3K, ob_4K, ob_5K;
extern struct object	ob_bptr1, ob_bptr2, ob_bptr3, ob_bptr4,
			ob_skull, ob_mips;


struct NewScreen scrdef = {
	0, 0, 320, 200, 4,
	0, 1,
	NULL,
	CUSTOMSCREEN,
	NULL, NULL,
	NULL, NULL,
};

struct NewWindow windef = {
	0, 0, 320, 200,
	-1, -1,
	MOUSEBUTTONS,
	ACTIVATE | SIMPLE_REFRESH,
	NULL, NULL,
	(UBYTE *) "               Marketroid",
	NULL,			/*  Filled in later  */
	NULL,
	0, 0, 0, 0,
	CUSTOMSCREEN
};

struct TextAttr robo8 = {
	(STRPTR) "robotron.font",
	8,
	0,
	FPF_DISKFONT
};

struct TextAttr robo6 = {
	(STRPTR) "robotron.font",
	6,
	0,
	FPF_DISKFONT
};


/*  Color maps for background and color cycling  */
UWORD colormap[] = {
	0x000, 0xfff, 0xff0, 0xf80, 0xf00, 0xf0f, 0x0f0, 0x00f,
	0x888, 0xb60, 0xc00, 0x00b, 0xc0c, 0x07f, 0x869, 0x557
};

UWORD bgr[] = { 0x00f, 0x0f0, 0xf00 };

UWORD redpulse[] = { 0xf00, 0xf00, 0xff0 };

UWORD rpbpr[] = {
	0xf00, 0xf04, 0xf08, 0xf0b, 0xf0f, 0xb0f, 0x70f, 0x40f,
	0x00f, 0x40f, 0x80f, 0xb0f, 0xf0f, 0xf0b, 0xf08, 0xf04 
};

UWORD spectrum[] = {
	0xf00, 0xf30, 0xf60, 0xf80, 0xfb0, 0xfe0, 0xdf0, 0xaf0,
	0x7f0, 0x4f0, 0x1f0, 0x0f2, 0x0f5, 0x0f8, 0x0fb, 0x0fe,
	0x0df, 0x0af, 0x07f, 0x04f, 0x01f, 0x20f, 0x50f, 0x80f,
	0xb0f, 0xd0f, 0xf0e, 0xf0b, 0xf08, 0xf05, 0xf03, 0xf01
};

UWORD blackspectrum[] = {
	0xc00, 0x900, 0x600, 0x300, 0x000, 0x004, 0x008, 0x00b,
	0x00f, 0x04f, 0x08f, 0x0cf, 0x0fe, 0x0fa, 0x0f6, 0x0f2,
	0x2f0, 0x6f0, 0xaf0, 0xef0, 0xfc0, 0xf80, 0xf40, 0xf00
};


/*  Border array  */
WORD border[] = {
	0, 10,  319, 10,  319, 199,  0, 199,
	0, 11,  318, 11,  318, 198,  1, 198,
	1, 10
};


/*  Strings for dotext()ing  */
static char inspired[] = "\015INSPIRED BY HIS NEVER-ENDING\033\
QUEST FOR PROGRESS,\033\
IN \0171987\015, MAN PERFECTS THE \017AMIGA:";

static char advanced[] = "\012A COMPUTER SYSTEM SO ADVANCED\033\
THAT ALL OTHER SYSTEMS\033\
ARE INFERIOR.";

static char guided[] = "\014GUIDED BY THEIR CORPORATE GREED,\033\
THE COMPETITION'S \017MARKETROIDS\014\033\
CONCLUDE:";

static char destroyed[] = "\017THE AMIGA IS TOO SOPHISTICATED\033\
FOR US TO COMPETE, AND THEREFORE\033\
MUST BE DESTROYED.";

static char lasthope[] = "\015YOU ARE THE LAST HOPE OF AMIGA, INC.";

static char thanks[] = "\014THANKS TO AN ELECTRONICS ENGINEERING";

static char wizard[] = "WIZARD, YOU POSSESS SUPERCOMPUTING\033\
POWER.";

static char mission[] = "\012YOUR MISSION IS TO\033\
\017STOP THE MARKETROIDS\012 AND\033\
\017SAVE THE LAST REAL HACKERS.";

static char apple[] = "\012THE FORCE OF ANTI-PROGRESS\033\
PATHO-LOGICAL EUTHENIZER\033\
\017(APPLE) MARKETROIDS\012 SEEK TO\033\
DESTROY YOU.";

static char hulk[] = "\015THE HACKED-UP LOSING KLUDGE\033\
\017(HULK) MARKETROIDS\015 SEEK OUT AND\033\
ELIMINATE THE LAST REAL HACKERS.";

static char bogon[] = "\013THE \017BOGONS AND CRUFTIES\013 ARE\033\
TRAINED TO CREATE \017MISINFORMATION AND\033\
VAPORWARE MARKETROIDS.";

static char ibm[] = "\015BEWARE OF THE \017INGENIUS BRAIN\033\
MARKETROIDS (IBM'S)\015 THAT POSSESS THE\033\
ABILITY TO RE-TRAIN THE HACKERS INTO\033\
SINISTER \017MS-DOS PROGRAMMERS.";

static char struggle[] = "\012AS YOU STRUGGLE TO SAVE HACKERDOM,\033\
BE SURE TO AVOID \017BPTRS\012\033\
IN YOUR PATH.";

static char bs[] = "\006NO BULLSHIT, JUST EXCELLENCE.";

static char hype[] = "\006NO HYPE, JUST EXCELLENCE.";

/*  Other stuff  */
struct Screen		*scr;
struct Window		*win;
struct ViewPort		*vp;
struct BitMap		*sbm;
struct TextFont		*bigrobo, *smallrobo;
UWORD			*blankspr;
int			keyx;
char			*keytext;
char			marketroid1987[] = "MARKETROID: 1987";
void			*IntuitionBase, *GfxBase, *DiskfontBase;

main (ac, av)
char **av;
{
	struct RastPort		*rp;

	openstuff ();
	sbm = scr -> ViewPort.RasInfo -> BitMap;
	rp = &scr -> RastPort;
	setbounds (2, 318, 12, 198);
	coverpage ();

	SetFont (rp, bigrobo);
	keytext = hype;
	if (ac > 1)
		if (*av[1] == '-' && av[1][1] == 'o')
			keytext = bs;
	keyx = 160 - TextLength (rp, &keytext[1], strlen (keytext) - 1L) / 2;

	while (1) {
		/*  "Save the last real hackers"  */
		save_em (rp);
		if (chkabort())
			break;

		/*  "MARKETROID:"  */
		market (rp);
		if (chkabort())
			break;

		/*  The Main demo  */
		if (maindemo (rp))
			break;

		/*  Amiga.  No BS, just excellence.  */
		amy (rp);
		if (chkabort())
			break;
	}
	SetSignal (0L, 1L << 12);		/*  Clear ^C signal  */
	closestuff ();
}

maindemo (rp)
register struct RastPort *rp;
{
	extern struct List		guys;		/*  anim.c  */
	register struct obcontrol	*hero, *thing;
	struct obcontrol		*a, *b, *c, *d, *e, *f, *g;
	register int			i, n, k;

	SetRast (rp, 0L);
	openanim ();
	opencycle (vp, colormap, 16);

	standardcycle ();

	/*  Draw border  */
	SetFont (rp, bigrobo);
	standardscreen (rp);

	/*  "Inspired by his never-ending quest for progress..."  */
	dotext (inspired, 10, 50);	waittext ();	Delay (75L);
	if (chkabort())	return (1);
	dotext (advanced, 10, 80);	waittext ();	Delay (75L);
	if (chkabort())	return (1);
	dotext (guided, 10, 110);	waittext ();	Delay (75L);
	if (chkabort())	return (1);
	dotext (destroyed, 10, 140);	waittext ();	Delay (100L);
	if (chkabort())	return (1);

	/*  "You are the last hope of Amiga, Inc..."  */
	cls (rp);
	SetAPen (rp, 1L);
	Move (rp,
	      160 - TextLength (rp,
				marketroid1987,
				(long) strlen (marketroid1987)) / 2,
	      30L);
	Text (rp, marketroid1987, (long) strlen (marketroid1987));

	hero = addobject (&ob_hero, 0, RIGHT, 2, 130);
	dotext (lasthope, 10, 45);
	while (hero->x + ob_hero.width < 160) {
		animate (); WaitTOF ();
	}
	hero -> flags |= FREEZE;
	setdir (hero, DOWN);
	while (!textdone ()) {
		animate (); WaitTOF ();
	}
	Delay (75L);
	if (chkabort())	return (1);

	/*  "Thanks to an electronics engineering"  */
	dotext (thanks, 10, 60);	waittext ();

	/*  "wizard, you possess supercomputing power."  */
	dotext (wizard, 10, 68);
	for (i=0; i<20; i++) {
		if (rnd (2))
			/*  Shoot left  */
			addobject (&ob_mips, 1, LEFT,
				   hero->x - ob_mips.width, 134);
		else
			/*  Shoot right  */
			addobject (&ob_mips, 1, RIGHT,
				   hero->x + ob_hero.width, 134);
		for (n=0; n<10; n++) {
			animate (); WaitTOF ();
		}
	}
	do {
		i = OFFSCREEN;
		animate ();
		WaitTOF ();
		for (thing = (struct obcontrol *) guys.lh_Head;
		     thing -> node.ln_Succ;
		     thing = (struct obcontrol *) thing -> node.ln_Succ) {
			if (thing == hero)
				continue;
			i &= thing -> flags;
		}
	} while (!(i & OFFSCREEN));

	/*  Delete all MIPS objects  */
	deleteallof (&ob_mips);
	waittext ();	Delay (50L);
	if (chkabort())	return (1);

	/*  "Your mission is to stop the marketroids..."  */
	dotext (mission, 10, 90);	waittext ();	Delay (25L);
	if (chkabort())	return (1);

	/*  (-=RJ=-, Dale, Jay)  */
	a = addobject (&ob_RJ, 1, RIGHT, 60, 128);
	SetDrMd (rp, JAM2);
	SetAPen (rp, 12L);
	SetFont (rp, smallrobo);
	Move (rp, 52L, 155L);
	Text (rp, "-=RJ=-", 6L);
	for (i=0; i<100; i++) {
		animate ();  WaitTOF ();
	}
	b = addobject (&ob_dale, 1, RIGHT, 50, 129);
	Move (rp, 46L, 155L);
	Text (rp, "DALE      ", 10L);
	for (i=0; i<100; i++) {
		animate ();  WaitTOF ();
	}
	c = addobject (&ob_jay, 1, RIGHT, 40, 129);
	Move (rp, 40L, 155L);
	Text (rp, "JAY       ", 10L);
	for (i=0; i<100; i++) {
		animate ();  WaitTOF ();
	}

	/*  Hero picks up the hackers for points  */
	hero -> flags &= ~FREEZE;
	setdir (hero, LEFT);
	while (hero -> x > a -> x) {
		animate ();  WaitTOF ();
	}
	removeobject (a);
	a = addobject (&ob_1K, 1, UP, hero->x, hero->y + 4);
	while (hero -> x > b -> x) {
		animate ();  WaitTOF ();
	}
	removeobject (b);
	b = addobject (&ob_2K, 1, UP, hero->x, hero->y + 4);
	while (hero -> x > c -> x) {
		animate ();  WaitTOF ();
	}
	removeobject (c);
	removeobject (a);
	Move (rp, 40L, 155L);
	Text (rp, "   ", 3L);
	c = addobject (&ob_3K, 1, UP, hero->x, hero->y + 4);

	while (hero -> x > 40) {
		animate ();  WaitTOF ();
	}
	removeobject (b);
	setdir (hero, RIGHT);
	while (hero -> x + ob_hero.width < c -> x) {
		animate ();  WaitTOF ();
	}
	removeobject (c);
	if (chkabort())	return (1);


	setbounds (2, 318, 35, 120);
	cls (rp);
	setbounds (2, 318, 12, 198);
	/*  "The force of Anti-Progress Patho-Locigal Euthenizer..."  */
	dotext (apple, 10, 60);
	n = k = 0;
	while (hero -> x + ob_hero.width < 160) {
		if (!(++n % 20)) {
			addobject (&ob_grunt, 2, LEFT, 318, 130+rnd (51)-25);
			k++;
		}
		animate ();
		adjustgrunts ();
		WaitTOF ();
	}
	hero -> flags |= FREEZE;
	a = addobject (&ob_dale, 1, RIGHT, 60, 130);
	i = 0;  c = NULL;
	while (i < 600) {		/*  We'll 'break' out of this  */
		if (++i == 100)
			b = addobject (&ob_RJ, 1, RIGHT, 35, 130);

		if (!(++n % 20))
			if (i < 200) {
				addobject
				 (&ob_grunt, 2, LEFT,
				  318, 130+rnd (51)-25);
				k++;
			} else if (!c && k) {
				c = addobject
				     (&ob_mips, 1, RIGHT,
				      hero->x + ob_hero.width, 134);
				k--;
			}

		if (i == 200)
			setdir (a, DOWN);
		if (i == 600)
			setdir (a, LEFT);

		if (c)
			if (dogruntkill (c)) {
				removeobject (c);  c = NULL;
			}

		animate ();
		adjustgrunts ();
		WaitTOF ();
	}
	waittext ();
	deleteallof (&ob_grunt);
	if (chkabort())	return (1);

	/*  "The Hacked-Up Losing Kludge...."  */
	hero -> flags &= ~FREEZE;
	setbounds (2, 318, 35, 120);
	cls (rp);
	setbounds (2, 318, 12, 198);
	setdir (hero, DOWN);
	c = addobject (&ob_hulk, -1, RIGHT, 0, a->y - 2);
	dotext (hulk, 10, 60);
	while (hero->y < a-> y) {
		animate ();  WaitTOF ();
	}
	setdir (hero, LEFT);
	hero -> flags |= FREEZE;
	while (c->x + ob_hulk.width < a->x + ob_dale.width) {
		animate ();  WaitTOF ();
	}
	removeobject (a);
	a = addobject (&ob_skull, 1, UP, c->x + 8, c->y + 2);
	n = c->x;
	k = c->y + ob_hulk.height + 8;
	SetAPen (rp, 12L);
	Move (rp, (long) n, (long) k);
	Text (rp, "UNEXPANDABLE HULK", 17L);
	for (i=0; i<3; i++) {
		d = addobject (&ob_mips, 2, LEFT,
				   hero->x - ob_hero.width, hero->y + 4);
		while (d->x > c->x + ob_hulk.width) {
			animate ();  WaitTOF ();
		}
		removeobject (d);
	}
	for (i=0; i<75; i++) {
		animate ();  WaitTOF ();
	}
	setdir (c, UP);
	while (c->y > b->y) {		/*  Walk up to RJ's level  */
		animate ();  WaitTOF ();
	}
	SetAPen (rp, 0L);
	Move (rp, (long) n, (long) k);
	Text (rp, "                 ", 17L);
	setdir (hero, DOWN);
	setdir (c, RIGHT);
	removeobject (a);
	while (c->x + ob_hulk.width < b->x + ob_RJ.width) {
		animate ();  WaitTOF ();
	}
	removeobject (b);
	b = addobject (&ob_skull, 1, UP, c->x + 8, c->y + 2);
	while (!(c->flags & OFFSCREEN)) {
		animate ();  WaitTOF ();
	}
	removeobject (b);
	removeobject (c);
	waittext ();
	if (chkabort())	return (1);

	/*  "The Bogons and Crufties...."  */
	setbounds (2, 318, 35, 120);
	cls (rp);
	setbounds (2, 318, 12, 198);
	dotext (bogon, 10, 60);
	a = addobject (&ob_spheroid, 1, LEFT, 280, 130);
	b = addobject (&ob_quark, 1, RIGHT, 20, hero->y + 10);
	for (i=0; i<60; i++) {
		animate ();  WaitTOF ();
	}
	setdir (hero, UP);
	hero -> flags &= ~FREEZE;
	while (hero->y > a->y + 25) {
		animate ();  WaitTOF ();
	}
	c = addobject(&ob_enforcer, 1, LEFT, a->x + ob_spheroid.width, a->y);
	d = addobject(&ob_tank, 1, RIGHT, b->x - ob_tank.width, b->y);
	while (hero->y > c->y) {
		animate ();  WaitTOF ();
	}
	setdir (hero, LEFT);
	hero -> flags |= FREEZE;
	while (!(a -> flags & OFFSCREEN)) {
		animate ();  WaitTOF ();
	}
	e = addobject (&ob_mips, 1, LEFT,
		       hero->x - ob_mips.width, hero->y + 4);
	while (e->x > c->x + ob_enforcer.width) {
		animate ();  WaitTOF ();
	}
	removeobject (e);
	setexplode (c);
	setdir (hero, DOWN);
	hero -> flags &= ~FREEZE;
	while (hero->y < d->y) {
		animate ();  WaitTOF ();
	}
	e = addobject (&ob_mips, 1, RIGHT,
		       hero->x + ob_hero.width, hero->y + 4);
	setdir (hero, RIGHT);
	hero -> flags |= FREEZE;
	while (e->x + ob_mips.width < d->x) {
		animate ();  WaitTOF ();
	}
	removeobject (a);
	removeobject (e);
	setexplode (d);
	a = addobject (&ob_jay, 1, RIGHT, 80, hero->y - 15);
	for (i=0; i<100; i++) {
		animate ();  WaitTOF ();
	}
	removeobject (b);
	removeobject (c);
	removeobject (d);
	setdir (hero, DOWN);
	setdir (a, DOWN);
	for (i=0; i<10; i++) {
		animate ();  WaitTOF ();
	}
	while (!textdone ()) {
		animate ();  WaitTOF ();
	}
	for (i=0; i<150; i++) {
		animate ();  WaitTOF ();
	}
	if (chkabort())	return (1);

	/*  "Beware of the Ingenuis Brain Marketroids..."  */
	setbounds (2, 318, 35, 120);
	cls (rp);
	setbounds (2, 318, 12, 198);
	dotext (ibm, 10, 60);
	b = addobject (&ob_brain, 1, RIGHT, 20, 130);
	setdir (a, UP);
	for (i=0; i<100; i++) {
		animate ();  WaitTOF ();
	}
	setdir (b, DOWN);
	c = addobject (&ob_missile, 1, RIGHT, b->x, b->y);
	setdir (hero, UP);
	hero -> flags &= ~FREEZE;
	while (hero->y + 4 > c->y) {
		animate ();  WaitTOF ();
	}
	setdir (hero, LEFT);
	hero -> flags |= FREEZE;
	d = addobject (&ob_mips, 1, LEFT,
		       hero->x - ob_mips.width, hero->y + 4);
	while (d->x > c->x + ob_missile.width) {
		animate ();  WaitTOF ();
	}
	removeobject (d);
	removeobject (c);
	while (b->y < a->y - 2) {
		animate ();  WaitTOF ();
	}
	setdir (a, LEFT);
	setdir (b, RIGHT);
	while (b->x + ob_brain.width < a->x) {
		animate ();  WaitTOF ();
	}
	BltBitMap (ob_brain.bitmap, (long) b->xoff, (long) b->yoff,
		   sbm, (long) b->x, (long) b->y,
		   (long) ob_brain.width, (long) ob_brain.height,
		   0x30L, 0xffL, NULL);
	setdir (a, RIGHT);
	for (i=0; i<200; i++) {
		n = a->y + rnd (11) - 5L;
		BltBitMap (ob_jay.bitmap, (long) a->xoff, (long) a->yoff,
			   sbm, (long) a->x, (long) n,
			   (long) ob_jay.width, (long) ob_jay.height,
			   0x30L, 0xffL, NULL);
		WaitTOF ();
		BltBitMap (ob_jay.bitmap, 0L, 0L,
			   sbm, (long) a->x, (long) n,
			   (long) ob_jay.width, (long) ob_jay.height,
			   0L, 0xffL, NULL);
	}
	i = a->x;  n = a->y;
	removeobject (a);
	a = addobject (&ob_prog, 1, RIGHT, i, n);
	setdir (hero, DOWN);
	hero -> flags &= ~FREEZE;
	c = d = e = f = g = NULL;
	while (1) {			/*  We'll be 'break'ing out  */
		n++;
		if (hero->y > b->y && !c) {
			setdir (hero, LEFT);
			hero -> flags |= FREEZE;
			c = addobject (&ob_mips, 1, LEFT,
				       hero->x - ob_mips.width, hero->y + 4);
			i = 1;
		}
		if (i && !(b -> flags & EXPLODING))
			if (c->x < b->x + ob_brain.width) {
				removeobject (c);
				setexplode (b);
			}
		if (!d && a->x > 230)
			d = addobject (&ob_bptr1, 1, UP,
				       a->x - ob_bptr1.width, a->y);
		if (!e && a->x > 250)
			e = addobject (&ob_bptr2, 1, UP,
				       a->x - ob_bptr1.width, a->y);
		if (!f && a->x > 270)
			f = addobject (&ob_bptr3, 1, UP,
				       a->x - ob_bptr1.width, a->y);
		if (!g && a->x > 290)
			g = addobject (&ob_bptr4, 1, UP,
				       a->x - ob_bptr1.width, a->y);
		if (a -> flags & OFFSCREEN)
			break;

		animate ();
		WaitTOF ();
	}
	removeobject (a);
	removeobject (b);
	waittext ();
	setdir (hero, DOWN);
	for (i=0; i<10; i++) {
		animate ();  WaitTOF();
	}
	Delay (100L);
	if (chkabort())	return (1);

	/*  "As you struggle to save hackerdom...."  */
	setbounds (2, 318, 35, 120);
	cls (rp);
	setbounds (2, 318, 12, 198);
	dotext (struggle, 10, 60);
	waittext ();
	setdir (hero, RIGHT);
	hero -> flags &= ~FREEZE;
	while (hero->x < 180) {
		animate ();  WaitTOF ();
	}
	c = addobject (&ob_mips, 1, RIGHT, hero->x+ob_hero.width, hero->y+4);
	while (c->x + ob_mips.width < d->x) {
		animate ();  WaitTOF ();
	}
	removeobject (c);
	c = addobject (&ob_mips, 1, RIGHT, hero->x+ob_hero.width, hero->y+4);
	setexplode (d);
	while (c->x + ob_mips.width < e->x) {
		animate ();  WaitTOF ();
	}
	removeobject (c);
	c = addobject (&ob_mips, 1, RIGHT, hero->x+ob_hero.width, hero->y+4);
	setexplode (e);
	while (c->x + ob_mips.width < f->x) {
		animate ();  WaitTOF ();
	}
	removeobject (c);
	setexplode (f);
	while (hero->x < g->x) {
		animate ();  WaitTOF ();
	}
	setexplode (hero);
	for (n=0; n<100; n++) {
		animate ();
		WaitTOF ();
	}

	closeanim ();
	closecycle ();
	return (0);
}

standardscreen (rp)
register struct RastPort *rp;
{
	SetAPen (rp, 4L);
	Move (rp, 80L, 7L);
	Text (rp, "00              00", 18L);
	SetAPen (rp, 14L);
	Move (rp, (long) border[0], (long) border[1]);
	PolyDraw (rp, 9L, border);
}

standardcycle ()
{
	addcycle (CYCLE_THROUGH, redpulse, 3, 10, 0, 6);
	addcycle (CYCLE_THROUGH, bgr, 3, 11, 0, 8);
	addcycle (CYCLE_THROUGH, rpbpr, 16, 12, 0, 4);
	addcycle (CYCLE_THROUGH, spectrum, 32, 13, 0, 4);
	addcycle (CYCLE_THROUGH, blackspectrum, 24, 14, 0, 2);
	addcycle (CYCLE_RANDOM, NULL, 0, 15, 0, 2);
}

adjustgrunts ()
{
	extern struct List		guys;
	register struct obcontrol	*oc;

	for (oc = (struct obcontrol *) guys.lh_Head;
	     oc -> node.ln_Succ;
	     oc = (struct obcontrol *) oc -> node.ln_Succ) {
		/*  Doncha just love all these hard-coded numbers!!??  */
		if (oc -> ob == &ob_grunt)
			if (oc -> y < 130)
				if ((oc->y - 130) + (oc->x - 275) < 0)
					setdir (oc, LEFT);
				else
					setdir (oc, DOWN);
			else
				if ((oc->y - 134) - (oc->x - 275) < 0)
					setdir (oc, LEFT);
				else
					setdir (oc, UP);
	}
}

dogruntkill (mips)
struct obcontrol *mips;
{
	register struct obcontrol	*oc;
	register int			x = mips->x + mips->ob->width;

	for (oc = (struct obcontrol *) guys.lh_Head;
	     oc -> node.ln_Succ;
	     oc = (struct obcontrol *) oc -> node.ln_Succ)
		if (oc -> ob == &ob_grunt && !(oc->flags & EXPLODING))
			if (x > oc -> x) {
				setexplode (oc);
				return (1);
			}
	return (0);
}

openstuff ()
{
	extern long		VBeamPos();

	if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L)))
		die ("-=RJ=- is on vacation.\n");

	if (!(GfxBase = OpenLibrary ("graphics.library", 0L)))
		die ("Dale is not in.\n");

	if (!(DiskfontBase = OpenLibrary ("diskfont.library", 0L)))
		die ("Can't open diskfont.library.\n");

	if (!(scr = OpenScreen (&scrdef)))
		die ("Screen won't open.\n");
	vp = &scr -> ViewPort;
	LoadRGB4 (vp, colormap, 16L);

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

	if (!(blankspr = AllocMem (12L, MEMF_CHIP | MEMF_CLEAR)))
		die ("Pointer sprite memory allocation failed.\n");
	SetPointer (win, blankspr, 1L, 16L, 0L, 0L);

	if (!(bigrobo = OpenDiskFont (&robo8)))
		die ("Failed to open robotron.font.8\n");
	if (!(smallrobo = OpenDiskFont (&robo6)))
		die ("Failed to open robotron.font.6\n");

	rnd ((short) -VBeamPos());
	openanim ();
	opentext (&scr -> RastPort, bigrobo);
}

closestuff ()
{
	closetext ();
	closecycle ();
	closeanim ();

	if (smallrobo)		CloseFont (smallrobo);
	if (bigrobo)		CloseFont (bigrobo);
	if (blankspr)		FreeMem (blankspr, 12L);
	if (win)		CloseWindow (win);
	if (scr)		CloseScreen (scr);
	if (DiskfontBase)	CloseLibrary (DiskfontBase);
	if (GfxBase)		CloseLibrary (GfxBase);
	if (IntuitionBase)	CloseLibrary (IntuitionBase);
}

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

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