/*
 * PACMAN  - written by Dave Nixon, AGS Computers Inc., July, 1981.
 *
 * Terminal handling for video games taken from aliens
 *      the original version  of aliens is from 
 *      Fall 1979                      Cambridge               Jude Miller
 *
 * Score keeping modified and general terminal handling (termcap routines
 * from UCB's ex) added by Rob Coben, BTL, June, 1980.
 *
 * Adapted for BDS C by Jeff Martin	Naperville, Il		February 1982
 *	As distributed, this program is set up for the H19 terminal.
 *	All that should be necessary to modify it for another terminal
 *	type is to make the appropriate changes to the initPOS and POS
 *	functions, located at the very end of PACUTIL.C.  These functions
 *	define the cursor-addressing sequence.
 *
 *	Also, as with most keyboard game programs with BDS C, this program
 *	must be linked with CIO.CRL, to get sufficiently raw terminal i/o.
 *	This means that there's little point in distributing a .COM file.
 *
 *	To compile:
 *		CC1 PACMAN.C
 *		CC1 PACMONST.C
 *		CC1 PACUTIL.C
 *
 *	To link:
 *		CLINK PACMAN PACMONST PACUTIL DEFF CIO
 *	or,
 *		L2 PACMAN PACMONST PACUTIL -L DEFF CIO
 */
#include <a:bdscio.h>
#include	"pacdefs.h"

main()
{
	register int tmp;		/* temp variables */
	register int pac_cnt;
	register int monstcnt;	/* monster number */
	struct pactyp *mptr;
	char gcnt[10];

	init();		/* global init */
	for (pac_cnt = MAXPAC; pac_cnt > 0; pac_cnt--)
	{
redraw:
		clr();
		SPLOT(0, 45, "SCORE: ");
		SPLOT(21, 45, "gold left = ");
		sprintf(gcnt, "%6d", goldcnt);
		SPLOT(21, 57, gcnt);
		if (potion == TRUE)
		{
			SPLOT(3, 45, "COUNTDOWN: ");
		};
		pacsymb = PACMAN;
		killflg = FALSE;
		sprintf(message, "delay = %6d", delay);
		SPLOT(22, 45, message);
		/*
		 * PLOT maze
		 */
		for (tmp = 0; tmp < BRDY; tmp++)
		{
			SPLOT(tmp, 0, &(display[tmp][0]));
		};
		/* initialize a pacman */
		pac.xpos = PSTARTX;
		pac.ypos = PSTARTY;
		pac.dirn = DNULL;
		pac.speed = SLOW;
		pac.danger = FALSE;
		PLOT(pacptr->ypos, pacptr->xpos, pacsymb);
		/* display remaining pacmen */
		for (tmp = 0; tmp < pac_cnt - 1; tmp++)
		{
			PLOT(23, (MAXPAC * tmp), PACMAN);
		};
		/*
		 * Init. monsters
	 	 */
		for (mptr = &monst[0], monstcnt = 0; monstcnt < MAXMONSTER; mptr++, monstcnt++)
		{
			mptr->xpos = MSTARTX + (2 * monstcnt);
			mptr->ypos = MSTARTY;
			mptr->speed = SLOW;
			mptr->dirn = DNULL;
			mptr->danger = FALSE;
			mptr->stat = START;
			PLOT(mptr->ypos, mptr->xpos, MONSTER);
		};
		rounds = 0;	/* timing mechanism */

		/* main game loop */
		do
		{
			if (rounds++ % MSTARTINTVL == 0)
			{
				startmonst();
			};
			pacman();
			if (killflg == TURKEY)
				break;
			for (monstcnt = 0; monstcnt < (MAXMONSTER / 2); monstcnt++)
			{
				monster(monstcnt);	/* next monster */
			};
			if (killflg == TURKEY)
				break;
			if (pacptr->speed == FAST)
			{
				pacman();
				if (killflg == TURKEY)
					break;
			};
			for (monstcnt = (MAXMONSTER / 2); monstcnt < MAXMONSTER; monstcnt++)
			{
				monster(monstcnt);	/* next monster */
			};
			if (killflg == TURKEY)
				break;
			if (potion == TRUE)
			{
				sprintf(message, "%2d%c", potioncnt,
					((potioncnt == 10) ? BEEP : ' '));
				SPLOT(3, 60, message);
				if (--potioncnt <= 0)
				{
					SPLOT(3, 45, "                        ");
					potion = FALSE;
					pacptr->speed = SLOW;
					pacptr->danger = FALSE;
					for (monstcnt = 0; monstcnt < MAXMONSTER; monstcnt++)
					{
						monst[monstcnt].danger = TRUE;
					};
				};
			};
			update();	/* score display etc */
			if (goldcnt <= 0)
			{
				reinit();
				goto redraw;
			};
		} while (killflg != TURKEY);
		SPLOT(5, 45, "YOU ARE BEING EATEN");
		SPLOT(6, 45, "THIS TAKES ABOUT 2 SECONDS");
		sleep(20);
	};
	SPLOT(8, 45, "THE MONSTERS ALWAYS TRIUMPH");
	SPLOT(9, 45, "IN THE END!");
	over();
}

pacman()
{
	register int sqtype;
	register int mcnt;
	register int tmpx, tmpy;
	int deltat;
	struct pactyp *mptr;

	/* pause; wait for the player to hit a key */
	for (deltat = delay; deltat > 0; deltat--);

	/* get instructions from player, but don't wait */
	poll(0);

	/* remember current pacman position */
	tmpx = pacptr->xpos;
	tmpy = pacptr->ypos;

	/* "eat" any gold */
	/* update display array to reflect what is on terminal */
	display[tmpy][tmpx] = VACANT;

	/* what next? */
	switch (pacptr->dirn)
	{
	case DUP:
		pacsymb = PUP;
		switch (sqtype = display[tmpy + UPINT][tmpx])
		{
		case GOLD:
		case VACANT:
		case CHOICE:
		case POTION:
		case TREASURE:

			/* erase where the pacman went */
			PLOT(tmpy, tmpx, VACANT);
			pacptr->ypos += UPINT;
			break;

		default:
			pacptr->dirn = DNULL;
			break;
		};
		break;
	case DDOWN:
		pacsymb = PDOWN;
		switch (sqtype = display[tmpy + DOWNINT][tmpx])
		{
		case GOLD:
		case VACANT:
		case CHOICE:
		case POTION:
		case TREASURE:

			/* erase where the pacman went */
			PLOT(tmpy, tmpx, VACANT);
			pacptr->ypos += DOWNINT;
			break;

		default:
			pacptr->dirn = DNULL;
			break;
		};
		break;
	case DLEFT:
		if(tmpx == 0)
		{
			/* erase where the pacman went */
			PLOT(tmpy, tmpx, VACANT);
			pacptr->xpos = XWRAP;
			sqtype = VACANT;
			break;
		};
		pacsymb = PLEFT;
		switch (sqtype = display[tmpy][tmpx + LEFTINT])
		{
		case GOLD:
		case VACANT:
		case CHOICE:
		case POTION:
		case TREASURE:

			/* erase where the pacman went */
			PLOT(tmpy, tmpx, VACANT);
			pacptr->xpos += LEFTINT;
			break;
		
		default:
			pacptr->dirn = DNULL;
			break;
		};
		break;
	case DRIGHT:
		if(tmpx == XWRAP)
		{
			/* erase where the pacman went */
			PLOT(tmpy, tmpx, VACANT);
			pacptr->xpos = 0;
			sqtype = VACANT;
			break;
		};
		pacsymb = PRIGHT;
		switch (sqtype = display[tmpy][tmpx + RIGHTINT])
		{
		case GOLD:
		case VACANT:
		case CHOICE:
		case POTION:
		case TREASURE:

			/* erase where the pacman went */
			PLOT(tmpy, tmpx, VACANT);
			pacptr->xpos += RIGHTINT;
			break;

		default:
			pacptr->dirn = DNULL;
			break;
		};
		break;
	};

	/* did the pacman get any points or eat a potion? */
	switch (sqtype)
	{
	case CHOICE:
	case GOLD:
		pscore++;
		goldcnt--;
		break;

	case TREASURE:
		pscore += TREASVAL;
		break;

	case POTION:
		SPLOT(3, 45, "COUNTDOWN: ");
		potion = TRUE;
		potioncnt = POTINTVL;
		pacptr->speed = FAST;
		pacptr->danger = TRUE;

		/* slow down monsters and make them harmless */
		mptr = &monst[0];
		for (mcnt = 0; mcnt < MAXMONSTER; mcnt++)
		{
			if (mptr->stat == RUN)
			{
				mptr->speed = SLOW;
				mptr->danger = FALSE;
			};
			mptr++;
		};
		break;
	};

	/* did the pacman run into a monster? */
	for (mptr = &monst[0], mcnt = 0; mcnt < MAXMONSTER; mptr++, mcnt++)
	{
		if ((mptr->xpos == pacptr->xpos) &&
			(mptr->ypos == pacptr->ypos))
		{

			killflg = dokill(mcnt);
		}
		else
		{
			killflg = FALSE;
		};
	};
	if (killflg != TURKEY)
	{
		PLOT(pacptr->ypos, pacptr->xpos, pacsymb);
	};
}




efault:
			