
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys/stat.h>
#include "ack3d.h"
#include "mapedit.h"

RECT	    HotSpots[] = {
	    1,25,161,153,	/* 0  Main grid */
	    163,23,172,32,	/* 1  Up arrow	*/
	    163,146,172,155,	/* 2  Dn arrow	*/
	    0,155,11,164,	/* 3  Lt arrow	*/
	    152,155,163,164,	/* 4  Rt arrow	*/
	    186,2,196,130,	/* 5  1st wall	*/
	    198,2,208,130,	/* 6  2nd wall	*/
	    210,2,220,130,	/* 7  3rd wall	*/
	    222,2,232,130,	/* 8  4th wall	*/
	    259,2,269,130,	/* 9  1st obj	*/
	    271,2,281,130,	/* 10 2nd obj	*/
	    283,2,293,130,	/* 11 3rd obj	*/
	    295,2,305,130,	/* 12 4th obj	*/
	    4,173,37,185,	/* 13 Load	*/
	    41,173,75,185,	/* 14 Save	*/
	    134,173,163,185,	/* 15 Exit	*/
	    241,22,251,30,	/* 16 blank sq	*/
	    243,2,249,8,	/* 17 Pass box	*/
	    80,173,112,185,	/* 18 New	*/
	    241,41,251,49,	/* 19 Start box */
	    241,62,251,70,	/* 20 Up box	*/
	    241,83,251,91,	/* 21 Dn box	*/
	    241,103,251,111,	/* 22 Goal box	*/
	    -1,-1,-1,-1
};

unsigned char *ScreenBuffer;

unsigned char Grid[4096];

unsigned char *bMaps[256];
unsigned char *oMaps[256];
	 char GridFile[128];
	 char PalFile[128];
unsigned char Palette[768];

int GridX;
int GridY;
int CurrentType;
int CurrentSquare;
int PassFlag;
int ModifiedFlag;
int ErrorCode;

unsigned char *WallSquares[256];
unsigned char *ObjSquares[256];

unsigned char ObjbmNum[256];


RECT	WallCoords[] = {
	    186,2,196,130,	/* 1st wall  */
	    198,2,208,130,	/* 2nd wall  */
	    210,2,220,130,	/* 3rd wall  */
	    222,2,232,130	/* 4th wall  */
};

RECT	ObjCoords[] = {
	    259,2,269,130,	/* 1st obj   */
	    271,2,281,130,	/* 2nd obj   */
	    283,2,293,130,	/* 3rd obj   */
	    295,2,305,130	/* 4th obj   */
};

RECT	SpecialActions[] = {
	    241,41,251,49,	/* Start box */
	    241,62,251,70,	/* Up box    */
	    241,83,251,91,	/* Dn box    */
	    241,103,251,111	/* Goal box  */
};

#define TOTAL_SPECIAL	4


unsigned char Pal0[] = {0,0,0,0,0,0x2A,0,0x2A,0};
unsigned char Pal11[] = {0x15,0x3f,0x3f,0x3f,0x15,0x15,0x3f,0x15,0x3f};
unsigned char Pal15[] = {0x3f,0x3f,0x3f,0x3b,0x3b,0x3b,0x37,0x37,0x37};



BOXES	MsgBox[] = {
	82,48,"mapbox1",1,1,136,81,161,93,0,0,0,0,0,0,0,0,0,0,0,0,
	61,49,"mapbox2",1,2,101,87,132,101,166,87,197,101,0,0,0,0,0,0,0,0,
	61,49,"mapbox3",1,2,101,87,132,101,166,87,197,101,0,0,0,0,0,0,0,0,
	97,54,"mapbox4",0,1,130,88,151,100,0,0,0,0,0,0,0,0,0,0,0,0,
	82,48,"mapbox5",1,1,136,81,161,93,0,0,0,0,0,0,0,0,0,0,0,0,
	82,48,"mapbox6",1,1,136,81,161,93,0,0,0,0,0,0,0,0,0,0,0,0,
};

unsigned char * Readiff(char *picname);

/****************************************************************************
**									   **
****************************************************************************/
void SoundBeep(void)
{
	putchar('\007');
}

/****************************************************************************
**									   **
****************************************************************************/
void ScreenToBuffer(int x,int y,int wt,int ht,unsigned char *Buffer)
{
int	    row;
unsigned char *Video;

	Video = graph_mem + (y * 320) + x;

	for (row = 0; row < ht; row++) {
    		memmove(Buffer,Video,wt);
    		Buffer += wt;
    		Video += 320;
    	}

}

/****************************************************************************
**									   **
****************************************************************************/
void BufferToScreen(int x,int y,int wt,int ht,unsigned char *Buffer)
{
int	    row;
unsigned char *Video;

	Video = graph_mem + (y * 320) + x;

	for (row = 0; row < ht; row++) {
    		memmove(Video,Buffer,wt);
    		Buffer += wt;
    		Video += 320;
    	}

}



/****************************************************************************
**									   **
****************************************************************************/
int ShowMsgBox(int Number)
{
int    i,handle,len,result;
int    mx,my,mButton;
int    x,y,wt,ht;
char   *BackBuffer;
char   *BoxBuffer;
char   size[4];
char   fName[14];

	strcpy(fName,MsgBox[Number].FileName);
	AddExtent(fName,".bbm");

	BoxBuffer = Readiff(fName);

	if (BoxBuffer == NULL)
    		return(0);

	wt = (*(int *)BoxBuffer);
	ht = (*(int *)&BoxBuffer[2]);
	len = wt * ht;

	BackBuffer = malloc(len);
	if (BackBuffer == NULL) {
    		free(BoxBuffer);
    		return(0);
    	}

	x = MsgBox[Number].BoxX;
	y = MsgBox[Number].BoxY;

	mouse_hide_cursor();
	ScreenToBuffer(x,y,wt,ht,BackBuffer);
	BufferToScreen(x,y,wt,ht,&BoxBuffer[4]);
	mouse_show_cursor();

	if (MsgBox[Number].DoBeep)
    		SoundBeep();

	len = 0;

	while (!len) {
    		if (vga_getkey() == '\n')
			break;

    		mouse_read_cursor(&mButton,&my,&mx);

    		if (mButton & MOUSE_LEFTBUTTON) {
			for (i = 0; i < MsgBox[Number].NumButtons; i++) {
	    			if (mx >= MsgBox[Number].ButtonCoords[i].x &&
					mx <= MsgBox[Number].ButtonCoords[i].x1 &&
					my >= MsgBox[Number].ButtonCoords[i].y &&
					my <= MsgBox[Number].ButtonCoords[i].y1) {
					result = i;
					mouse_released();
					len = 1;
					break;
				}
	    		}

		}

    	}

	mouse_hide_cursor();
	BufferToScreen(x,y,wt,ht,BackBuffer);
	mouse_show_cursor();

	free(BackBuffer);
	free(BoxBuffer);

	return(result);
}



/****************************************************************************
**									   **
****************************************************************************/
int GetAction(int mx,int my)
{
int    i = 0;

	while (1) {
    		if (HotSpots[i].x < 0)
			return(-1);

    		if (mx >= HotSpots[i].x &&
			mx <= HotSpots[i].x1 &&
			my >= HotSpots[i].y &&
			my <= HotSpots[i].y1)
			break;

    		i++;
    	}

	return(i);
}

/****************************************************************************
**									   **
****************************************************************************/
void ShowScreen(void)
{
unsigned char *Video;

	Video = graph_mem;
	memmove(Video,ScreenBuffer,64000);

}

/****************************************************************************
**									   **
****************************************************************************/
void GetBufferSquare(int x,int y,unsigned char *buffer)
{
int    row;
unsigned char *src;

	src = ScreenBuffer + ((y * 320) + x);

	for (row = 0; row < 8; row++) {
    		memmove(buffer,src,10);
    		buffer += 10;
    		src += 320;
    	}
}


/****************************************************************************
**									   **
****************************************************************************/
int BuildSquares(void)
{
int i,j,x,y,num;
unsigned char *Square;

	Square = malloc(80);
	if (Square == NULL) {
	    	ErrorCode = ERR_NOMEMORY;
    		return(-1);
    	}

	WallSquares[0] = Square;
	GetBufferSquare(1,25,Square);

	num = 1;
	for (i = 0; i < 4; i++) {
    		x = WallCoords[i].x;
    		y = WallCoords[i].y;

    		for (j = 0; j < 16; j++) {
			Square = malloc(80);
			if (Square == NULL)
	    			return(-1);
			WallSquares[num++] = Square;
			GetBufferSquare(x,y,Square);
			y += 8;
		}

    	}

	num = 1;
	for (i = 0; i < 4; i++) {
    		x = ObjCoords[i].x;
    		y = ObjCoords[i].y;

    		for (j = 0; j < 16; j++) {
			Square = malloc(80);
			if (Square == NULL)
	    			return(-1);
			ObjSquares[num++] = Square;
			GetBufferSquare(x,y,Square);
			y += 8;
		}

    	}

	num = MAP_STARTCODE;
	for (i = 0; i < TOTAL_SPECIAL; i++) {
    		Square = malloc(80);
    		if (Square == NULL) {
			ErrorCode = ERR_NOMEMORY;
			return(-1);
		}
    		WallSquares[num++] = Square;
    		GetBufferSquare(SpecialActions[i].x,SpecialActions[i].y,Square);
    	}

	return(0);
}


/****************************************************************************
**									   **
****************************************************************************/
void PutSquare(int x,int y,unsigned char *buffer)
{
int row;
unsigned char *Video;

Video = graph_mem + (y * 320) + x;

	for (row = 0; row < 8; row++) {
    		memmove(Video,buffer,10);
    		buffer += 10;
    		Video += 320;
    	}
}

/****************************************************************************
**									   **
****************************************************************************/
void ShowPassBox(void)
{
char color;
unsigned char *Video;

	if (PassFlag)
	    color = 0;
	else
	    color = 15;

	mouse_hide_cursor();
	Video = graph_mem + (PASS_Y * 320) + PASS_X;

	*Video = color;
	Video[4] = color;
	Video += 320;
	Video[1] = color;
	Video[3] = color;
	Video += 320;
	Video[2] = color;
	Video += 320;
	Video[1] = color;
	Video[3] = color;
	Video += 320;
	*Video = color;
	Video[4] = color;
	mouse_show_cursor();
}

/****************************************************************************
**									   **
****************************************************************************/
void ShowGrid(void)
{
int    row,col,x,y;
int    VidX,VidY;
int    pos,type,coord;
unsigned char ch;
unsigned char *Video;
unsigned char Square[90];

	pos = (GridY * 64) + GridX;
	VidY = 25;
	mouse_hide_cursor();

	for (row = 0; row < 16; row++) {
    		VidX = 1;
    		for (col = 0; col < 16; col++) {
			ch = Grid[pos + col];

			if (ch < 0x80 || ch >= MAP_STARTCODE)
	    			PutSquare(VidX,VidY,WallSquares[ch]);
			else
	    			PutSquare(VidX,VidY,ObjSquares[ch & 0x3F]);

			if (ch & 0x40 && ch < MAP_STARTCODE) {
	    			Video = graph_mem + ((VidY+3) * 320) + VidX + 1;
	    			*Video = 0;
	    		}

			VidX += 10;
		}

    		VidY += 8;
    		pos += 64;
    	}
	mouse_show_cursor();
}

/****************************************************************************
**									   **
****************************************************************************/
int LoadScreen(char *fName)
{
int handle,len;

	ScreenBuffer = Readiff(fName);
	if (ScreenBuffer == NULL) {
    		printf("Error loading screen file: %s\n",fName);
    		ErrorCode = ERR_NOMEMORY;
    		return(-1);
    	}

	memmove(ScreenBuffer,&ScreenBuffer[4],64000);

	return(0);
}

/****************************************************************************
**									   **
****************************************************************************/
char *GetExtent(char *s)
{
char    *e;

	e = strchr(s,'.');
	if (e == NULL)
    		return(s);
	e++;

	return(e);
}

/****************************************************************************
**									   **
****************************************************************************/
int LoadBitmap(int BitmapNumber,char *BitmapName,int BitmapType)
{
int	    handle;
int	    x,y;
int	    sPos,dPos;
unsigned char ch;
unsigned char *bmp;

	if (!(strcasecmp(GetExtent(BitmapName),"BBM"))) {
    		bmp = Readiff(BitmapName);
    		if (bmp == NULL) {
			ErrorCode = ERR_NOMEMORY;
			return(-1);
		}

    		if (BitmapType == TYPE_WALL)
		bMaps[BitmapNumber] = bmp;

    		if (BitmapType == TYPE_OBJECT)
			oMaps[BitmapNumber] = bmp;

    		memmove(bmp,&bmp[4],4096);
    		return(0);
    	}


	bmp = malloc(4096);
	if (bmp == NULL) {
    		ErrorCode = ERR_NOMEMORY;
    		return(-1);
    	}

	if (BitmapType == TYPE_WALL)
    		bMaps[BitmapNumber] = bmp;

	if (BitmapType == TYPE_OBJECT)
    		oMaps[BitmapNumber] = bmp;


	handle = open(BitmapName,O_RDWR);
	if (handle < 1) {
    		free(bmp);
    		ErrorCode = ERR_BADFILE;
    		return(-1);
    	}

	read(handle,bmp,4);	    /* Skip width and height for now */
	read(handle,bmp,4096);
	close(handle);

	return(0);
}

/****************************************************************************
**									   **
****************************************************************************/
char *StripEndOfLine(char *s)
{
int	    len;
char    ch;

	len = strlen(s);

	while (--len >= 0) {
    		ch = s[len];
    		if (ch != ' ' && ch != ';' && ch != '\t' && ch != 13 && ch != 10)
			break;

    		s[len] = '\0';
    	}

	return(s);
}

/****************************************************************************
**									   **
****************************************************************************/
char *SkipSpaces(char *s)
{

	while (*s == ' ' || *s == '\t' || *s == ',')
    		strcpy(s,&s[1]);

	return(s);
}

/****************************************************************************
**									   **
****************************************************************************/
char *AddExtent(char *s,char *ext)
{
	if (strchr(s,'.') == NULL)
	    	strcat(s,ext);

	return(s);
}

/****************************************************************************
**									   **
****************************************************************************/
char *CopyToComma(char *dest,char *src)
{
char    ch;

	while (*src) {
    		ch = *src++;
    		if (ch == ' ' || ch == '\t' || ch == ',')
			break;

    		*dest++ = ch;
    	}

	*dest = '\0';

	return(src);
}



/****************************************************************************
**									   **
****************************************************************************/
int LoadDescFile(char *fName)
{
FILE    *fp;
int	    Mode,fMode,result;
int	    bType,value,bNum,ObjIndex;
char    LineBuf[128];
char    fBuf[128];
char    *s;

	fp = fopen(fName,"r");
	if (fp == NULL) {
    		printf("Unable to open description file: %s\n",fName);
    		return(-1);
    	}

	ObjIndex = 0;
	Mode = 0;
	result = 0;
	*GridFile = '\0';

	while (1) {
    		if (feof(fp))
			break;

    		*LineBuf = '\0';
    		fgets(LineBuf,127,fp);

    		if (*LineBuf == ';')
			continue;

    		StripEndOfLine(LineBuf);
    		SkipSpaces(LineBuf);

    		if (!strlen(LineBuf))
			continue;

    		if (!strcasecmp(LineBuf,"WALLS:")) {
			bType = TYPE_WALL;
			Mode = 1;
			continue;
		}

    		if (!strcasecmp(LineBuf,"ENDWALLS:")) {
			if (Mode != 1) {
	    			printf("Invalid place for command: %s.\n",LineBuf);
	    			result = -1;
	    		}

			Mode = 0;
			continue;
		}

    		if (!strcasecmp(LineBuf,"OBJECTS:")) {
			bType = TYPE_OBJECT;
			Mode = 2;
			continue;
		}

    		if (!strcasecmp(LineBuf,"FILES:")) {
			fMode = 1;
			continue;
		}

    		if (!strcasecmp(LineBuf,"ENDFILES:")) {
			fMode = 0;
			continue;
		}

    		if (!strncasecmp(LineBuf,"PALFILE:",8)) {
			strcpy(PalFile,SkipSpaces(&LineBuf[8]));
			continue;
		}

    		if (!strncasecmp(LineBuf,"MAPFILE:",8)) {
			strcpy(GridFile,SkipSpaces(&LineBuf[8]));
			continue;
		}

    		if (Mode == 2) {
			if (!strncasecmp(LineBuf,"NUMBER:",7)) {
	    			value = atoi(&LineBuf[7]);

	    			if (value < 1 || value >= 255) {
					printf("Invalid object number:\n%s\n",LineBuf);
					result = -1;
					break;
				}
	    			ObjIndex = value;
	    			continue;
	    		}

			if (!strncasecmp(LineBuf,"BITMAPS:",8)) {
	    			strcpy(LineBuf,SkipSpaces(&LineBuf[8]));
	    			value = 0;
	    			strcpy(LineBuf,CopyToComma(fBuf,LineBuf));
	    			SkipSpaces(fBuf);
	    			bNum = atoi(fBuf);

	    			if (bNum < 1 || bNum > 255) {
					printf("Invalid bitmap number for object: %d\n",ObjIndex);
					result = -1;
					break;
				}

	    			ObjbmNum[ObjIndex] = bNum;
	    			continue;
	    		}
		}

    		if (fMode) {
			value = atoi(LineBuf);
			if (value < 1 || value > 255) {
	    			printf("Invalid number for object: %s.\n",LineBuf);
	    			result = -1;
	    			continue;
	    		}

			s = strpbrk(LineBuf,", \t");
			if (s == NULL) {
	    			printf("Unable to locate bitmap name for object: %s.\n",LineBuf);
	    			result = -1;
	    			continue;
	    		}

			strcpy(fBuf,SkipSpaces(s));
			AddExtent(fBuf,".img");

			if (LoadBitmap(value,fBuf,bType)) {
	    			printf("Error loading bitmap \"%s\".\n",fBuf);
	    			result = -1;
	    		}
			continue;
		}

    	}

	fclose(fp);
	return(result);
}

/****************************************************************************
**									   **
****************************************************************************/
int LoadGrid(void)
{
int	    handle;

	handle = open(GridFile,O_RDWR);
	if (handle < 1) {
    		printf("Unable to open MapFile: %s\n",GridFile);
    		return(-1);
    	}

	if (read(handle,Grid,4096) != 4096) {
    		close(handle);
    		printf("Error reading MapFile: %s\n",GridFile);
    		return(-1);
    	}

	close(handle);
	return(0);
}


/****************************************************************************
**									   **
****************************************************************************/
int SaveGrid(void)
{
int handle;

	handle = open(GridFile,O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
	if (handle < 1) {
    		return(-1);
    	}

	if (write(handle,Grid,4096) != 4096) {
    		close(handle);
    		return(-2);
    	}

	close(handle);
	ShowMsgBox(BOX_SAVED);
	return(0);
}



/****************************************************************************
**									   **
****************************************************************************/
int LoadPalette(char *pName)
{
int handle;

	handle = open(pName,O_RDWR);
	if (handle < 1) {
    		printf("Unable to open PalFile: %s\n",pName);
    		ErrorCode = ERR_BADPALFILE;
    		return(-1);
    	}

	if (read(handle,Palette,768) != 768) {
    		close(handle);
    		printf("Error reading PalFile: %s\n",pName);
    		ErrorCode = ERR_BADPALFILE;
    		return(-1);
    	}

	close(handle);
	return(0);
}

/****************************************************************************
**									   **
****************************************************************************/
void ShowBitmap(int Type,int Number)
{
int y,BegX,BegY;
unsigned char *bmp,*Video;

	BegY = 134;

	if (Type == TYPE_WALL) {
    		BegX = 176;
    		bmp = bMaps[Number];
    	} else {
    		BegX = 250;
    		bmp = oMaps[Number];
    	}

	Video = graph_mem + (BegY * 320) + BegX;

	if (bmp == NULL) {
    		for (y = 0; y < 64; y++) {
			memset(Video,15,64);
			Video += 320;
		}
    		return;
    	}

	for (y = 0; y < 64; y++) {
    		memmove(Video,bmp,64);
    		Video += 320;
    		bmp += 64;
    	}
}

/****************************************************************************
**									   **
****************************************************************************/
void mouse_released(void)
{
int x,y,button;

	button = 1;
	while (button)
    		mouse_read_cursor(&button,&y,&x);

}

/****************************************************************************
**									   **
****************************************************************************/
int CheckDupObjects(unsigned char oNum)
{
int i,result;
unsigned char ch;

	result = 0;

	for (i = 0; i < 4096; i++) {
    		ch = Grid[i];

    		if (!(ch & 0x80))
			continue;

    		if ((ch & 0x3F) == oNum) {
			result = 1;
			ShowMsgBox(BOX_ALREADY_1_OBJECT);
			break;
		}
    	}

	return(result);
}

/****************************************************************************
**									   **
****************************************************************************/
int CountSpecialCodes(unsigned char mCode)
{
int i,count;

	count = 0;
	for (i = 0; i < 4096; i++) {
    		if (Grid[i] == mCode)
			count++;
    	}

	return(count);
}


/****************************************************************************
**									   **
****************************************************************************/
void main(int argc,char *argv[])
{
int done,Action;
int my,mx,mButton;
int pos;

	ErrorCode = 0;

	if (mouse_installed() == -1) {
    		printf("Mouse required\n");
    		exit(1);
    	}

	if (argc < 2) {
    		printf("Syntax: mapedit filename.ext where filename is name of desc. file\n");
    		exit(1);
    	}

	printf("Loading screen\n");
	if (LoadScreen("mapedit.lbm")) {
    		printf("\nErrorCode = %d\n",ErrorCode);
    		exit(1);
    	}

	printf("Loading master file\n");
	if (LoadDescFile(argv[1])) {
    		printf("\nErrorCode = %d\n",ErrorCode);
    		exit(1);
    	}

	printf("Loading map file\n");
	if (LoadGrid()) {
    		printf("\nErrorCode = %d\n",ErrorCode);
    		exit(1);
    	}

	printf("Loading palette file\n");
	if (LoadPalette(PalFile)) {
    		printf("\nErrorCode = %d\n",ErrorCode);
    		exit(1);
    	}

	printf("Building map squares\n");
	if (BuildSquares()) {
    		printf("Not enough memory!\n");
    		exit(1);
    	}

	SetVGAmode();
#if 0
	memmove(Palette,Pal0,9);
	memmove(&Palette[0x21],Pal11,9);
	memmove(&Palette[0x2d],Pal15,9);
#endif
	SetPalette(Palette);

	ShowScreen();
	mouse_show_cursor();
	GridX = GridY = 0;
	ShowGrid();

	CurrentType = TYPE_WALL;
	CurrentSquare = 0;
	ModifiedFlag = 0;
	done = 0;
	while (!done) {
    		if (vga_getkey() == '\033') {
			if (ModifiedFlag > 0 && ShowMsgBox(BOX_MODIFIED_WARNING))
		    		continue;
			done = 1;
			break;
		}

    		mouse_read_cursor(&mButton,&my,&mx);

    		if (mButton & MOUSE_RIGHTBUTTON) {
			if (GetAction(mx,my))
	    			continue;

			my -= 25;
			mx--;
			pos = (((my / 8)+GridY) * 64) + (mx / 10) + GridX;
			Grid[pos] = 0;
			ModifiedFlag = 1;
			ShowGrid();
			continue;
		}

    		if (mButton & MOUSE_LEFTBUTTON) {
			Action = GetAction(mx,my);
			if (Action < 0)
			    	continue;


			switch (Action) {
	    		case 0:	    /* Main grid */
				my -= 25;
				mx--;
				pos = (((my / 8)+GridY) * 64) + (mx / 10) + GridX;
				mx = CurrentSquare;

				if (CurrentType == TYPE_OBJECT) {
		    			if (CheckDupObjects(CurrentSquare))
						break;
		    			mx |= 0x80;
		    		}

				if (CurrentSquare == MAP_UPCODE || CurrentSquare == MAP_DOWNCODE) {
		    			if (CountSpecialCodes(CurrentSquare) > MAX_UPDOWN) {
						ShowMsgBox(BOX_MAX_SPECIAL_CODE);
						break;
					}
		    		}

				if (CurrentSquare == MAP_GOALCODE || CurrentSquare == MAP_STARTCODE) {
		    			if (CountSpecialCodes(CurrentSquare) > 0) {
						ShowMsgBox(BOX_MAX_SPECIAL_CODE);
						break;
					}

		    		}

				if (PassFlag)
		    			mx |= 0x40;

				ModifiedFlag = 1;
				Grid[pos] = mx;
				ShowGrid();
				if (mx & 0x80)
		    			mouse_released();
				break;

	    		case 1:	    /* Up arrow */
				if (GridY) {
			    		GridY--;
			    		ShowGrid();
			    	}
				break;

	    		case 2:	    /* Dn arrow */
				if (GridY < 48) {
			    		GridY++;
			    		ShowGrid();
			    	}
				break;
	
	    		case 3:	    /* Lt arrow */
				if (GridX) {
			    		GridX--;
			    		ShowGrid();
			    	}
				break;

	    		case 4:	    /* Rt arrow */
				if (GridX < 48) {
			    		GridX++;
			    		ShowGrid();
			    	}
				break;

	    		case 14:	    /* Save */
				if (!SaveGrid())
			    		ModifiedFlag = 0;
				break;

	    		case 15:	    /* Exit */
				if (ModifiedFlag > 0 && ShowMsgBox(BOX_MODIFIED_WARNING))
			    		break;
				done = 1;
				break;

	    		case 16:	    /* Blank square */
					CurrentType = TYPE_WALL;
				CurrentSquare = 0;
				mouse_hide_cursor();
				PutSquare(CURRENT_SQUAREX,CURRENT_SQUAREY,WallSquares[0]);
				mouse_show_cursor();
				break;

	   		 case 17:	    /* Pass box */
				PassFlag ^= 1;
				ShowPassBox();
				mouse_released();
				break;

	   		 case 18:	    /* New */
				if (ShowMsgBox(BOX_NEW_WARNING))
				    break;
				memset(Grid,0,4096);
				GridX = GridY = 0;
				ShowGrid();
				ModifiedFlag = 1;
				break;

	   		 default:
				if (Action >= 5 && Action <= 8) {
			    		my -= 2;
			    		my /= 8;
			    		CurrentSquare = ((Action - 5) * 16) + my;
			    		CurrentType = TYPE_WALL;
			    		CurrentSquare++;
			    		mouse_hide_cursor();
			    		ShowBitmap(CurrentType,CurrentSquare);
			    		PutSquare(CURRENT_SQUAREX,CURRENT_SQUAREY,WallSquares[CurrentSquare]);
			    		mouse_show_cursor();
			    	}
	
				if (Action >= 9 && Action <= 12) {
			    		my -= 2;
			    		my /= 8;
			    		CurrentSquare = ((Action - 9) * 16) + my;
			    		CurrentSquare++;
			    		CurrentType = TYPE_OBJECT;
			    		mouse_hide_cursor();
			    		ShowBitmap(CurrentType,ObjbmNum[CurrentSquare]);
			    		PutSquare(CURRENT_SQUAREX,CURRENT_SQUAREY,
					   ObjSquares[CurrentSquare]);
			    		mouse_show_cursor();
			    	}
	
				if (Action > 18) {
			    		CurrentType = TYPE_WALL;
			    		CurrentSquare = MAP_STARTCODE + (Action - 19);
			    		mouse_hide_cursor();
			    		PutSquare(CURRENT_SQUAREX,CURRENT_SQUAREY,
					   WallSquares[CurrentSquare]);
			    		mouse_show_cursor();
			    	}

				break;
	    		}
		}
    	}

	vga_setmode(TEXT);
}

