#include #include #include #include #include #include #include #include #include #include #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 far *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 far * Readiff(char *picname); /**************************************************************************** ** ** ****************************************************************************/ void SoundBeep(void) { sound(440); delay(50); nosound(); } /**************************************************************************** ** ** ****************************************************************************/ void ScreenToBuffer(int x,int y,int wt,int ht,unsigned char *Buffer) { int row; unsigned char *Video; Video = MK_FP(0xA000,(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 = MK_FP(0xA000,(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); } #if 0 handle = open(fName,O_RDWR|O_BINARY); if (handle < 1) return(0); read(handle,size,4); ht = (*(int *)size); wt = (*(int *)&size[2]); len = wt * ht; BackBuffer = malloc(len); BoxBuffer = malloc(len); if (BackBuffer == NULL || BoxBuffer == NULL) { close(handle); return(0); } read(handle,BoxBuffer,len); close(handle); #endif 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 (inkey() == 0x1C0D) break; mouse_read_cursor(&mButton,&my,&mx); if (mButton & 1) { 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 far *Video; Video = MK_FP(0xA000,0); 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 = MK_FP(0xA000,(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 = MK_FP(0xA000,(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 = MK_FP(0xA000,((VidY+3) * 320) + VidX + 1); *Video = 0; } VidX += 10; } VidY += 8; pos += 64; } mouse_show_cursor(); } /**************************************************************************** ** ** ****************************************************************************/ int LoadScreen(char *fName) { int handle,len; #if 0 handle = open(fName,O_RDWR|O_BINARY); if (handle < 1) { printf("Unable to find screen file: %s\n",fName); return(-1); } ScreenBuffer = malloc(64000); if (ScreenBuffer == NULL) { printf("Unable to get screen memory.\n"); close(handle); return(-2); } read(handle,ScreenBuffer,4); /* Skip width and height */ len = read(handle,ScreenBuffer,32000); if (len != 32000) { printf("Invalid screen file: %s\n",fName); close(handle); return(-3); } if (read(handle,&ScreenBuffer[32000],32000) != 32000) { printf("Invalid screen file: %s\n",fName); close(handle); return(-3); } close(handle); #endif 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 (!(stricmp(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 = farmalloc(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|O_BINARY); if (handle < 1) { farfree(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,"rt"); 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 (!stricmp(LineBuf,"WALLS:")) { bType = TYPE_WALL; Mode = 1; continue; } if (!stricmp(LineBuf,"ENDWALLS:")) { if (Mode != 1) { printf("Invalid place for command: %s.\n",LineBuf); result = -1; } Mode = 0; continue; } if (!stricmp(LineBuf,"OBJECTS:")) { bType = TYPE_OBJECT; Mode = 2; continue; } if (!stricmp(LineBuf,"FILES:")) { fMode = 1; continue; } if (!stricmp(LineBuf,"ENDFILES:")) { fMode = 0; continue; } if (!strnicmp(LineBuf,"PALFILE:",8)) { strcpy(PalFile,SkipSpaces(&LineBuf[8])); continue; } if (!strnicmp(LineBuf,"MAPFILE:",8)) { strcpy(GridFile,SkipSpaces(&LineBuf[8])); continue; } if (Mode == 2) { if (!strnicmp(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 (!strnicmp(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|O_BINARY); 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_BINARY|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|O_BINARY); 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 = MK_FP(0xA000,(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(); memmove(Palette,Pal0,9); memmove(&Palette[0x21],Pal11,9); memmove(&Palette[0x2d],Pal15,9); SetPalette(Palette); ShowScreen(); mouse_show_cursor(); GridX = GridY = 0; ShowGrid(); CurrentType = TYPE_WALL; CurrentSquare = 0; ModifiedFlag = 0; done = 0; while (!done) { if (inkey() == 0x11B) { if (ModifiedFlag > 0 && ShowMsgBox(BOX_MODIFIED_WARNING)) continue; done = 1; break; } mouse_read_cursor(&mButton,&my,&mx); if (mButton & 2) { 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 & 1) { 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; } } } textmode(3); }