]> 4ch.mooo.com Git - 16.git/blobdiff - 16/ted5/TED5-4.C
ted5 added
[16.git] / 16 / ted5 / TED5-4.C
diff --git a/16/ted5/TED5-4.C b/16/ted5/TED5-4.C
new file mode 100755 (executable)
index 0000000..e235257
--- /dev/null
@@ -0,0 +1,2633 @@
+////////////////////////////////////////////////////
+////////////////////////////////////////////////////
+//
+// TED5-4
+//
+////////////////////////////////////////////////////
+////////////////////////////////////////////////////
+#include "ted5.h"
+#pragma hdrstop
+
+
+void SignalSound(void)
+{
+ int i;
+
+ for(i=0;i<10;i++)
+ {
+  sound(500+i*500);
+  delay(5);
+  nosound();
+ }
+}
+
+
+////////////////////////////////////////////////////
+//
+// Create an OBJ linkable file from any type of datafile
+//
+// Exit:
+//  0 = everything's a-ok!
+// -1 = file not found
+// -2 = file >64K
+//
+////////////////////////////////////////////////////
+int MakeOBJ(char *filename,char *destfilename,char *public,segtype whichseg,char *farname)
+{
+ char THEADR[17]={0x80,14,0,12,32,32,32,32,32,32,32,32,32,32,32,32,0},
+      COMENT[18]={0x88,0,0,0,0,'M','a','k','e','O','B','J',' ','v','1','.','1',0},
+      LNAMES[42]={0x96,0,0,
+                 6,'D','G','R','O','U','P',
+                 5,'_','D','A','T','A',
+                 4,'D','A','T','A',
+                 0,
+                 5,'_','T','E','X','T',
+                 4,'C','O','D','E',
+                 8,'F','A','R','_','D','A','T','A'},
+      SEGDEF[9]={0x98,7,0,0x48,0,0,2,3,4},     // for .DATA
+      SEGDEF1[9]={0x98,7,0,0x48,0,0,5,6,4},    // for .CODE
+      SEGDEF2[9]={0x98,7,0,0x60,0,0,8,7,4},    // for .FARDATA
+      GRPDEF[7]={0x9a,4,0,1,0xff,1,0x61},
+      MODEND[5]={0x8a,2,0,0,0x74};
+
+ unsigned i,j,flag,handle;
+ long fsize,offset,loffset,temp,amtleft,amount,offset1;
+ char _seg *dblock,*block;
+
+
+ //
+ // Need to compute the CHECKSUM in the COMENT field
+ // (so if the "MakeOBJ..." string is modified, the CHECKSUM
+ //  will be correct).
+ //
+ COMENT[1]=sizeof(COMENT)-3;
+ for (flag=i=0;i<sizeof(COMENT);i++)
+    flag+=COMENT[i];
+ COMENT[sizeof(COMENT)-1]=(flag^0xff)+1;
+
+ if ((handle=open(filename,O_BINARY))==NULL)
+   return -1;
+
+ fsize=filelength(handle);
+ close(handle);
+ if (fsize>0x10000L)           // BIGGER THAN 1 SEG = ERROR!
+   return -2;
+
+ LoadIn(filename,(memptr *)&block);    // LOAD FILE IN
+ offset=0;
+
+ MMAllocate((memptr *)&dblock,0x10000L);
+
+ ////////////////////////////////////////////////////
+ //
+ // INSERT HEADER RECORD
+ //
+ movedata(_DS,FP_OFF(&THEADR),(unsigned)dblock,offset,sizeof(THEADR));
+ movedata(FP_SEG(filename),FP_OFF(filename),
+         (unsigned)dblock,offset+4,strlen(filename));
+ offset+=sizeof(THEADR);
+
+
+ ////////////////////////////////////////////////////
+ //
+ // INSERT COMMENT RECORD
+ //
+ movedata(_DS,FP_OFF(COMENT),(unsigned)dblock,offset,sizeof(COMENT));
+ offset+=sizeof(COMENT);
+
+
+ ////////////////////////////////////////////////////
+ //
+ // INSERT START OF LIST-OF-NAMES RECORD
+ //
+ loffset=offset;
+ movedata(_DS,FP_OFF(LNAMES),(unsigned)dblock,offset,sizeof(LNAMES));
+ offset+=sizeof(LNAMES);
+
+ // If it's a .FARDATA segment, we need to insert the segment name!
+ if (whichseg==FARDATA)
+   {
+    *(dblock+offset)=strlen(farname);
+    movedata(FP_SEG(farname),FP_OFF(farname),
+       (unsigned)dblock,offset+1,strlen(farname));
+    offset+=strlen(farname)+1;
+   }
+
+ // Now, finish the List-Of-Names record by creating
+ // the CHECKSUM and LENGTH
+ temp=offset;
+ offset=offset-loffset-2;
+ *(int huge *)(dblock+loffset+1)=offset;
+ offset=temp;
+
+ // Now, figure out the CHECKSUM of the record
+ for (flag=i=0;i<(offset-loffset);i++)
+   flag+=*(dblock+i+loffset);
+ *(dblock+offset)=(flag^0xff)+1;
+ offset++;
+
+
+ ////////////////////////////////////////////////////
+ //
+ // CREATE SEGMENT DEFINITION RECORD
+ //
+ loffset=offset;
+ temp=fsize;
+ switch(whichseg)
+ {
+  case DATA:
+    movedata(FP_SEG(&SEGDEF),FP_OFF(&SEGDEF),
+            (unsigned)dblock,offset,sizeof(SEGDEF));
+    *(int huge *)(dblock+offset+4)=temp;
+    offset+=sizeof(SEGDEF);
+    break;
+  case CODE:
+    movedata(FP_SEG(&SEGDEF1),FP_OFF(&SEGDEF1),
+            (unsigned)dblock,offset,sizeof(SEGDEF1));
+    *(int huge *)(dblock+offset+4)=temp;
+    offset+=sizeof(SEGDEF1);
+    break;
+  case FARDATA:
+    movedata(FP_SEG(&SEGDEF2),FP_OFF(&SEGDEF2),
+            (unsigned)dblock,offset,sizeof(SEGDEF2));
+    *(int huge *)(dblock+offset+4)=temp;
+    offset+=sizeof(SEGDEF2);
+    break;
+ }
+
+ // CHECKSUM
+ for (flag=0,i=loffset;i<offset;i++)
+   flag+=*(dblock+i);
+ *(dblock+offset)=(flag^0xff)+1;
+ offset++;
+
+
+ ////////////////////////////////////////////////////
+ //
+ // CREATE GROUP DEFINITION RECORD
+ //
+ switch(whichseg)
+ {
+  case DATA:
+  case CODE:
+    movedata(FP_SEG(&GRPDEF),FP_OFF(&GRPDEF),
+            (unsigned)dblock,offset,sizeof(GRPDEF));
+    offset+=sizeof(GRPDEF);
+ }
+
+
+ ////////////////////////////////////////////////////
+ //
+ // CREATE PUBLIC DEFINITION RECORD
+ //
+ loffset=offset;
+ *(dblock+offset)=0x90;                // PUBDEF ID
+ offset+=3;                    // point to public base, skip length
+ *(dblock+offset)=1;           // group index=1
+ *(dblock+offset+1)=1;         // segment index=1
+ offset+=2;                    // point to public name
+
+ temp=0;
+ movedata(FP_SEG(public),FP_OFF(public),
+         (unsigned)dblock,offset+1,strlen(public));
+ *(dblock+offset)=strlen(public);
+ offset+=strlen(public)+1;
+ *(int huge *)(dblock+offset)=0;       // public offset within segment
+ offset+=2;
+ *(dblock+offset)=0;           // type index
+ offset++;
+
+ // LENGTH
+ temp=offset-loffset-2;
+ *(int huge *)(dblock+loffset+1)=temp;
+ offset++;
+
+ // CHECKSUM
+ for (flag=0,i=loffset;i<offset;i++)
+   flag+=*(dblock+i);
+ *(dblock+offset)=(flag^0xff)+1;
+
+
+ ////////////////////////////////////////////////////
+ //
+ // DATA RECORD(S). YUCK.
+ //
+
+ amtleft=fsize;
+ amount=1024;
+ for (i=0;i<(fsize+1023)/1024;i++)
+   {
+    offset1=offset;
+    if (amtleft<1024)
+      amount=amtleft;
+    //
+    // RECORD HEADER
+    //
+    *(dblock+offset)=0xa0;                     // LEDATA ID
+    *(int huge *)(dblock+offset+1)=amount+4;   // length of record
+    offset+=3;
+    *(dblock+offset)=1;                                // segment index
+    *(int huge *)(dblock+offset+1)=i*1024;     // index into segment
+    offset+=3;
+    //
+    // LOAD DATA IN
+    //
+    LoadFile(filename,(char huge *)dblock+offset,i*1024,amount);
+    offset+=amount;
+    //
+    // CHECKSUM!
+    //
+    for (flag=0,j=offset1;j<offset;j++)
+      flag+=*(dblock+j);
+    *(dblock+offset)=(flag^0xff)+1;
+    offset++;
+
+    amtleft-=1024;
+   }
+
+ ////////////////////////////////////////////////////
+ //
+ // MODULE END! YES!
+ //
+ movedata(FP_SEG(&MODEND),FP_OFF(&MODEND),(unsigned)dblock,offset,sizeof(MODEND));
+ offset+=sizeof(MODEND);
+
+ //
+ // Save the little puppy out!
+ //
+ SaveFile(destfilename,(char huge *)dblock,0,offset);
+ MMFreePtr((memptr *)&dblock);
+ MMFreePtr((memptr *)&block);
+ return 0;
+}
+
+
+////////////////////////////////////////////////////
+//
+// DUMP THE PASTE BUFFER OUT TO EITHER AN
+// "APPLE PREFERRED" OR "ILBM" GRAPHICS FORMAT FILE
+//
+// NOTE: THIS IS ONLY AVAILABLE IN EGA, BECAUSE I
+// DON'T FEEL LIKE WRITING A CGA ILBM PIXEL-SPLICER --
+// AND APPLE PREFERRED ONLY HANDLES 4-BIT COLOR ANYWAY!
+// (YES, I KNOW, I COULD ONLY USE 4 OUT OF 16 COLORS...SHUT UP!)
+//
+////////////////////////////////////////////////////
+btype dumpB[]={{" DeluxePaint II ILBM ",4,2,2},
+              {"   Apple Preferred   ",4,5,1}},
+      fnameB={"         ",4,3,1};
+DialogDef dumpD={" Which format do you require?",30,7,2,&dumpB[0],NULL},
+         fnameD={"Enter filename to\nsave (no suffix)",17,5,1,&fnameB,NULL};
+
+void Item_GraphicDump(void)
+{
+ char filename[14],ext[5],_seg *block,_seg *block1;
+ ApPrefStr PrefHeader;
+ int which,i,j,k,m,n,pwidth,lwidth,dx,dy;
+ long tilelen,fsize=0,bufsize;
+
+ if (!PasteOK)
+   {
+    ErrDialog("You need to use the Copy command\n"
+             "to copy part of the map or tiles\n"
+             "so I know what I need to dump!"," OK ");
+    return;
+   }
+
+ switch(videomode)
+ {
+  case CGA:
+  case VGA:
+    ErrDialog("Sorry, but this function is only\n"
+             "available for EGA mode.  If you\n"
+             "have a REAL NEED for this to work\n"
+             "in CGA or VGA, talk to Id Software!"," OK ");
+    return;
+ }
+
+ if (!(which=DoDialog(&dumpD)))
+   return;
+
+ //
+ // SET TILE LENGTH
+ //
+ switch(tsize)
+ {
+  case 1: tilelen=32L; break;
+  case 2: tilelen=128L; break;
+  case 3: tilelen=512L;
+ }
+
+ //
+ // GET FILENAME TO SAVE UNDER
+ //
+ DrawDialog(&fnameD,1);
+ MouseHide();
+ GetButtonXY(&fnameD,0,&sx,&sy);
+ if (!input(filename,8))
+   {
+    RestoreBackground();
+    MouseShow();
+    return;
+   }
+ for (i=0;i<strlen(filename);i++)
+   if (filename[i]=='.')
+     {
+      filename[i]=0;
+      break;
+     }
+ RestoreBackground();
+ MouseShow();
+
+ //
+ // SETUP FOR EACH TYPE
+ //
+ switch(which)
+ {
+  case 1:      // ILBM
+    {
+     long size;
+     char form[5]="FORM",ilbm[9]="ILBMBMHD",body[5]="BODY";
+
+
+     size=48L;
+     MMAllocate((memptr *)&block,size);
+
+     movedata(FP_SEG(form),FP_OFF(form),(unsigned)block,fsize,4);
+     fsize+=4;
+     size=40L+tilelen*TileCopy.w*TileCopy.h;
+     *(block+fsize)=(size>>24)&0xff;
+     *(block+fsize+1)=(size>>16)&0xff;
+     *(block+fsize+2)=(size>>8)&0xff;
+     *(block+fsize+3)=size&0xff;
+     fsize+=4;
+     movedata(FP_SEG(ilbm),FP_OFF(ilbm),(unsigned)block,fsize,8);
+     fsize+=8;
+     *(block+fsize)=0;
+     *(block+fsize+1)=0;
+     *(block+fsize+2)=0;
+     *(block+fsize+3)=20;
+     fsize+=4;
+     *(block+fsize)=(TileCopy.w<<(tsize+2))/256;   // pixel width
+     *(block+fsize+1)=(TileCopy.w<<(tsize+2))&0xff;
+     *(block+fsize+2)=(TileCopy.h<<(tsize+2))/256; // pixel height
+     *(block+fsize+3)=(TileCopy.h<<(tsize+2))&0xff;
+     *(int huge *)(block+fsize+4)=0;           // Xorg
+     *(int huge *)(block+fsize+6)=0;           // Yorg
+     *(block+fsize+8)=4;                       // planes
+     *(block+fsize+9)=0;                       // mask (stencil!)
+     *(block+fsize+10)=0;                      // compression (none)
+     *(block+fsize+11)=0;                      // pad (?)
+     *(int huge *)(block+fsize+12)=0;          // trans (?)
+     *(int huge *)(block+fsize+14)=0x101;      // aspt (aspect?)
+     *(int huge *)(block+fsize+16)=0x4001;     // page width
+     *(int huge *)(block+fsize+18)=0xc800;     // page height
+     fsize+=20;
+     movedata(FP_SEG(body),FP_OFF(body),(unsigned)block,fsize,4);
+     fsize+=4;
+     size=tilelen*TileCopy.w*TileCopy.h;
+     *(block+fsize)=(size>>24)&0xff;
+     *(block+fsize+1)=(size>>16)&0xff;
+     *(block+fsize+2)=(size>>8)&0xff;
+     *(block+fsize+3)=size&0xff;
+     fsize+=4;
+
+     strcpy(ext,".LBM");
+    }
+    break;
+
+  case 2:      // APPLE PREFERRED
+    {
+     int Ctable[16]={0x0000,0x000a,0x00a0,0x00aa,0x0a00,0x0a0a,0x0a50,0x0aaa,
+                    0x0555,0x055f,0x05f5,0x05ff,0x0f55,0x0f5f,0x0ff5,0x0fff};
+     long size,pixwid;
+
+
+     PrefHeader.length=sizeof(ApPrefStr)+4L*(TileCopy.h<<(tsize+2))+
+       TileCopy.w*TileCopy.h*tilelen+(((TileCopy.w*TileCopy.h*tilelen)+63)/64);
+     strncpy(PrefHeader.Kind,"\x4MAIN",5);
+     PrefHeader.MasterMode=0;
+     PrefHeader.PixelsPerLine=TileCopy.w<<(tsize+2);
+     PrefHeader.NumColorTables=1;
+     for (i=0;i<16;i++)
+       PrefHeader.ColorTable[i]=Ctable[i];
+     PrefHeader.NumScanLines=TileCopy.h<<(tsize+2);
+
+     size=sizeof(ApPrefStr)+4L*(TileCopy.h<<(tsize+2));
+     MMAllocate((memptr *)&block,size);
+     movedata(FP_SEG(&PrefHeader),FP_OFF(&PrefHeader),(unsigned)block,fsize,sizeof(ApPrefStr));
+     fsize+=sizeof(ApPrefStr);
+
+     pixwid=TileCopy.w*(2<<tsize);
+     for (i=0;i<(TileCopy.h<<(tsize+2));i++)
+       {
+       *(int huge *)(block+fsize)=pixwid+(pixwid+63)/64;
+       *(int huge *)(block+fsize+2)=0;
+       fsize+=4;
+       }
+
+     strcpy(ext,".APP");
+     MMAllocate((memptr *)&block1,tilelen*TileCopy.w);
+    }
+ }
+
+ //
+ // SAVE HEADER OUT
+ //
+ strcat(filename,ext);
+ SaveFile(filename,(char huge *)block,0,fsize);
+ MMFreePtr((memptr *)&block);
+
+ //
+ // NOW, WRITE THE DATA OUT! EEEE!
+ //
+ bufsize=tilelen*TileCopy.w;
+ MMAllocate((memptr *)&block,bufsize);
+
+ pwidth=(1<<(tsize-1))*TileCopy.w;
+ lwidth=pwidth*4;
+
+ ErrDialog("One moment. I am busy.\n     Countdown:","");
+ dx=sx;
+ dy=sy;
+
+ for (j=0;j<TileCopy.h;j++)
+   {
+    sx=dx;
+    sy=dy;
+    printint(TileCopy.h-j);
+    print(" ");
+
+    for (i=0;i<TileCopy.w;i++)
+      {
+       unsigned tilet,tilem,tilei,loc;
+
+       //
+       // ESC out?
+       //
+       if (keydown[1])
+        {
+         RestoreBackground();
+         while(keydown[1]);
+         ErrDialog("You aborted out of the\n"
+                   "graphic dump conversion!"," Yes, I know ");
+
+         if (which==2)
+           MMFreePtr((memptr *)&block1);
+         return;
+        }
+       //
+       // GET THE CORRECT TILE MOVED INTO "TDATA"
+       //
+       switch(TileCopy.MapOrTileSelect)
+       {
+       case 0: // MAP COPY
+         loc=(j+TileCopy.y)*mapwidth+TileCopy.x+i;
+         tilet=(TileCopy.PlanesCopied&BPLANE)?CutBkgnd[loc]:-BkgndColor;
+         tilem=(TileCopy.PlanesCopied&FPLANE)?CutFrgnd[loc]+tilenum:0;
+         tilei=(TileCopy.PlanesCopied&IPLANE)?CutInfoPl[loc]+tilenum:0;
+         CombineTiles(tilet,tilem,tilei,tsize);
+         break;
+       case 1: // BKGND TILE COPY
+         loc=(TileCopy.y+j)*selectcols+TileCopy.x+i;
+         CombineTiles(loc,0,0,tsize);
+         break;
+       case 2: // FRGND TILE COPY
+         loc=(TileCopy.y+j)*selectcols+TileCopy.x+i+tilenum;
+         CombineTiles(-BkgndColor,loc,0,tsize);
+       }
+
+       //
+       // NOW, MUNGE "TDATA" INTO BIT-PLANES!
+       //
+       // INTERNAL:            P0      P1      P2      P3
+       //      SCANLINE x      ......  ......  ......  ......
+       //
+       for (k=0;k<8<<(tsize-1);k++)
+        for (m=0;m<4;m++)
+          movedata(FP_SEG(&tdata),FP_OFF(&tdata)+(m*tsize*(8<<(tsize-1)))+k*(1<<(tsize-1)),
+               (unsigned)block,k*lwidth+m*pwidth+i*(1<<(tsize-1)),1<<(tsize-1));
+      }
+    //
+    // ALRIGHT. NOW SAVE THIS CHUNK OUT IN THE CORRECT FORMAT
+    //
+    switch(which)
+    {
+     case 1:   // ILBM
+       SaveFile(filename,MK_FP(block,0),fsize,bufsize);
+       fsize+=bufsize;
+       break;
+     case 2:   // APPLE PREFERRED
+       {
+       int len,clen;
+
+       //
+       // FIRST, I NEED TO CONVERT THE ILBM PLANAR FORMAT
+       // TO SUPER-RES NIBBLES
+       //
+       for (k=0;k<8<<(tsize-1);k++)
+         for (m=0;m<(1<<(tsize-1))*TileCopy.w;m++)
+           {
+            unsigned char src[4],dest[4]={0,0,0,0};
+
+            for (n=0;n<4;n++)
+              src[n]=block[k*lwidth+pwidth*n+m];
+
+            asm        mov     al,[BYTE PTR src+0]
+            asm        mov     ah,[BYTE PTR src+1]
+            asm        mov     bl,[BYTE PTR src+2]
+            asm        mov     bh,[BYTE PTR src+3]
+
+            // dest[0]
+            asm        shl     bh,1
+            asm        rcl     cl,1
+            asm        shl     bl,1
+            asm        rcl     cl,1
+            asm        shl     ah,1
+            asm        rcl     cl,1
+            asm        shl     al,1
+            asm        rcl     cl,1
+
+            asm        shl     bh,1
+            asm        rcl     cl,1
+            asm        shl     bl,1
+            asm        rcl     cl,1
+            asm        shl     ah,1
+            asm        rcl     cl,1
+            asm        shl     al,1
+            asm        rcl     cl,1
+
+            // dest[1]
+            asm        shl     bh,1
+            asm        rcl     ch,1
+            asm        shl     bl,1
+            asm        rcl     ch,1
+            asm        shl     ah,1
+            asm        rcl     ch,1
+            asm        shl     al,1
+            asm        rcl     ch,1
+
+            asm        shl     bh,1
+            asm        rcl     ch,1
+            asm        shl     bl,1
+            asm        rcl     ch,1
+            asm        shl     ah,1
+            asm        rcl     ch,1
+            asm        shl     al,1
+            asm        rcl     ch,1
+
+            // dest[2]
+            asm        shl     bh,1
+            asm        rcl     dl,1
+            asm        shl     bl,1
+            asm        rcl     dl,1
+            asm        shl     ah,1
+            asm        rcl     dl,1
+            asm        shl     al,1
+            asm        rcl     dl,1
+
+            asm        shl     bh,1
+            asm        rcl     dl,1
+            asm        shl     bl,1
+            asm        rcl     dl,1
+            asm        shl     ah,1
+            asm        rcl     dl,1
+            asm        shl     al,1
+            asm        rcl     dl,1
+
+            // dest[3]
+            asm        shl     bh,1
+            asm        rcl     dh,1
+            asm        shl     bl,1
+            asm        rcl     dh,1
+            asm        shl     ah,1
+            asm        rcl     dh,1
+            asm        shl     al,1
+            asm        rcl     dh,1
+
+            asm        shl     bh,1
+            asm        rcl     dh,1
+            asm        shl     bl,1
+            asm        rcl     dh,1
+            asm        shl     ah,1
+            asm        rcl     dh,1
+            asm        shl     al,1
+            asm        rcl     dh,1
+
+            asm        mov     [BYTE PTR dest+0],cl
+            asm        mov     [BYTE PTR dest+1],ch
+            asm        mov     [BYTE PTR dest+2],dl
+            asm        mov     [BYTE PTR dest+3],dh
+
+            movedata(FP_SEG(&dest),FP_OFF(&dest),
+               (unsigned)block1,k*lwidth+m*4,4);
+           }
+
+       //
+       // NOW, TIME TO WRITE THE DATA OUT IN 64-BYTE CHUNKS! YUCK!
+       //
+       for (k=0;k<8<<(tsize-1);k++)
+         {
+          char clen;
+          int off=k*lwidth;;
+
+          len=4*pwidth;
+          while(len>0)
+          {
+           if (len>64)
+             clen=64;
+           else
+             clen=len;
+
+           clen--;
+           SaveFile(filename,(char huge *)&clen,fsize++,1);
+           clen++;
+
+           SaveFile(filename,MK_FP(block1,off),fsize,clen);
+           fsize+=clen;
+           off+=clen;
+           len-=clen;
+          }
+         }
+       }
+    }
+   }
+
+ if (which==2)
+   MMFreePtr((memptr *)&block1);
+
+ MMFreePtr((memptr *)&block);
+ RestoreBackground();
+
+ ErrDialog("Graphic successfully dumped!"," Yeah! ");
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Edit TILEINFO/M values
+//
+////////////////////////////////////////////////////
+btype ETVb[]={{" Tileinfo ",2,21,1},
+             {" TileinfoM ",16,21,1},
+             {" Exit ",30,21,2}};
+DialogDef ETVd={"       Edit TILEINFO/M values",38,23,3,&ETVb[0],NULL};
+int CurTIvalue;
+
+void Item_EditTinfoValues(void)
+{
+ int max,i,which,exitok=0,mx,my,b0,b1,CTRLdown;
+ static int whichtinfo=0;
+
+ //
+ // IS THE "CTRL" KEY DOWN?
+ //
+ CTRLdown=keydown[0x1d];
+ if (CTRLdown)
+   {
+    if (planeton)
+      whichtinfo=0;
+    else
+      whichtinfo=1;
+   }
+
+ switch(whichtinfo)
+ {
+  case 0: max=tilenum; break;
+  case 1: max=tilemnum;
+ }
+
+ switch(videomode)
+ {
+  case CGA:
+  case EGA1:
+  case VGA:
+    ETVd.height=23;
+    for(i=0;i<3;i++)
+      ETVb[i].yoff=21;
+    break;
+  case EGA2:
+    ETVd.height=58;
+    for(i=0;i<3;i++)
+      ETVb[i].yoff=56;
+ }
+
+ //
+ // DRAW THE SCREEN
+ //
+ DrawDialog(&ETVd,1);
+ if (CTRLdown)
+   {
+    DrawTinfoScreen(whichtinfo,0,-max);        // ALIGN TO TOP
+    switch(whichtinfo)
+    {
+     case 0: DrawTinfoScreen(whichtinfo,0,whicht); break;
+     case 1: DrawTinfoScreen(whichtinfo,0,whichtm-tilenum);
+    }
+   }
+ else
+   DrawTinfoScreen(whichtinfo,0,0);
+
+
+ do
+ {
+  which=CheckButtonsRet(&ETVd);
+  if (which>=0)
+    switch(which)
+    {
+     case 0:
+       RestoreBackground();
+       return;
+     case 1:
+       if (whichtinfo)
+        {
+         max=tilenum;
+         whichtinfo=0;
+         DrawDialog(&ETVd,0);
+         DrawTinfoScreen(whichtinfo,0,0);
+        }
+       else
+        {
+         GetButtonXY(&ETVd,0,&sx,&sy);
+         MouseHide();
+         print(ETVb[0].text);
+         MouseShow();
+         errsound();
+        }
+       break;
+     case 2:
+       if (!tilemnum)
+        {
+         GetButtonXY(&ETVd,1,&sx,&sy);
+         MouseHide();
+         print(ETVb[1].text);
+         MouseShow();
+         errsound();
+         break;
+        }
+
+       if (!whichtinfo)
+        {
+         max=tilemnum;
+         whichtinfo=1;
+         DrawDialog(&ETVd,0);
+         DrawTinfoScreen(whichtinfo,0,0);
+        }
+       else
+        {
+         GetButtonXY(&ETVd,1,&sx,&sy);
+         MouseHide();
+         print(ETVb[1].text);
+         MouseShow();
+         errsound();
+        }
+       break;
+
+     case 3:
+       exitok=1;
+    }
+  else
+    {
+     MouseCoords(&mx,&my);
+     mx/=8;
+     my/=8;
+     b0=MouseButton()&1;
+     b1=MouseButton()&2;
+
+     //
+     // CHECK FOR BUTTON PRESSES
+     //
+     if (b0)
+       UseTinfoValue(whichtinfo,mx,my,1);
+     else
+     if (b1)
+       UseTinfoValue(whichtinfo,mx,my,0);
+
+     //
+     // SPACE = ENTER VALUES HORIZONTALLY
+     //
+     if (keydown[0x39])
+     {
+      while(keydown[0x39]);
+      clearkeys();
+      EnterTinfoValue(whichtinfo,mx,my,0);
+     }
+
+     //
+     // CHECK FOR SCROLLING
+     //
+     if (keydown[0x48])                // UP
+       {
+       DrawTinfoScreen(whichtinfo,0,-1);
+       if (keydown[0x1d])
+         while(keydown[0x48]);
+       }
+     else
+     if (keydown[0x50])                // DOWN
+       {
+       DrawTinfoScreen(whichtinfo,0,1);
+       if (keydown[0x1d])
+         while(keydown[0x50]);
+       }
+     else
+     if (keydown[0x49])                // PGUP
+       {
+       DrawTinfoScreen(whichtinfo,0,-8);
+       if (!keydown[0x1d])
+         while(keydown[0x49]);
+       }
+     else
+     if (keydown[0x51])                // PGDN
+       {
+       DrawTinfoScreen(whichtinfo,0,8);
+       if (!keydown[0x1d])
+         while(keydown[0x51]);
+       }
+     else
+     if (keydown[0x47])                // HOME
+       {
+       DrawTinfoScreen(whichtinfo,0,-max);
+       while(keydown[0x47]);
+       }
+     else
+     if (keydown[0x4f])                // END
+       {
+       DrawTinfoScreen(whichtinfo,0,max);
+       while(keydown[0x4f]);
+       }
+     else
+     if (keydown[0x4d])                // RIGHT
+       {
+       DrawTinfoScreen(whichtinfo,1,0);
+       if (!keydown[0x1d])
+         while(keydown[0x4d]);
+       }
+     else
+     if (keydown[0x4b])                // LEFT
+       {
+       DrawTinfoScreen(whichtinfo,-1,0);
+       if (!keydown[0x1d])
+         while(keydown[0x4b]);
+       }
+
+    }
+
+ } while(!exitok);
+
+ RestoreBackground();
+}
+
+
+//
+// PICKUP/DROP TILEINFO VALUE AT CURSOR
+//
+void UseTinfoValue(int whichtinfo,int mx,int my,int PickupOrDrop)
+{
+ int whichx=-1,whichy=-1;
+ unsigned dialogx,dialogy;
+
+
+ GetDialogXY(&ETVd,&dialogx,&dialogy);
+
+ if (mx>=dialogx+10 && mx<=dialogx+45)
+   whichx=(mx-(dialogx+10))/7;
+
+ if (my>=4 && my<=((videomode==EGA2)?55:19))
+   whichy=(my-4)>>(tsize-1);
+
+ switch(whichtinfo)
+ {
+  case 0:
+    if (whichx>=numtplanes)
+      whichx=-1;
+    if (whichy>=tilenum)
+      whichy=-1;
+    break;
+
+  case 1:
+    if (whichx>=numtmplanes)
+      whichx=-1;
+    if (whichy>=tilemnum)
+      whichy=-1;
+ }
+
+ if (whichx>=0 && whichy>=0)
+ {
+  if (!PickupOrDrop)
+    switch(whichtinfo)
+    {
+     case 0:   // TILE
+       CurTIvalue=*(Tinfo[whichx+TIxbase]+whichy+TIybase);
+       break;
+     case 1:   // MASKED
+       CurTIvalue=*(TMinfo[whichx+TIxmbase]+whichy+TIymbase);
+    }
+  else
+    switch(whichtinfo)
+    {
+     case 0:   // TILE
+       *(Tinfo[whichx+TIxbase]+whichy+TIybase)=CurTIvalue;
+       DirtyFlag=1;
+       break;
+     case 1:   // MASKED
+       *(TMinfo[whichx+TIxmbase]+whichy+TIymbase)=CurTIvalue;
+       DirtyFlag=1;
+    }
+
+  DrawTinfoScreen(whichtinfo,0,0);
+ }
+ while(MouseButton());
+}
+
+
+//
+// ENTER TILEINFO/M CELL VALUES
+//
+void EnterTinfoValue(int whichtinfo,int mx,int my,int H_or_V)
+{
+ int whichx=-1,whichy=-1,val,outok=0,tempx,tempy,maxx,maxy;
+ unsigned dialogx,dialogy;
+
+
+ GetDialogXY(&ETVd,&dialogx,&dialogy);
+
+ if (mx>=dialogx+10 && mx<=dialogx+45)
+   whichx=(mx-(dialogx+10))/7;
+
+ if (my>=4 && my<=((videomode==EGA2)?55:19))
+   whichy=(my-4)>>(tsize-1);
+
+ switch(whichtinfo)
+ {
+  case 0:
+    if (whichx>=numtplanes)
+      whichx=-1;
+    if (whichy>=tilenum)
+      whichy=-1;
+    break;
+
+  case 1:
+    if (whichx>=numtmplanes)
+      whichx=-1;
+    if (whichy>=tilemnum)
+      whichy=-1;
+ }
+
+ MouseHide();
+
+ if (whichx>=0 && whichy>=0)
+   do
+   {
+    //
+    // INPUT VALUE
+    //
+    sx=whichx*7+dialogx+10;
+    sy=(whichy<<(tsize-1))+4;
+    print("    ");
+    sx-=4;
+    if ((val=inputint(3))!=(int)ESCOUT)
+      switch(whichtinfo)
+      {
+       case 0: // TILE
+        *(Tinfo[whichx+TIxbase]+whichy+TIybase)=val&0xff;
+        DirtyFlag=1;
+        break;
+       case 1: // MASKED
+        *(TMinfo[whichx+TIxmbase]+whichy+TIymbase)=val&0xff;
+        DirtyFlag=1;
+      }
+    else
+      outok=1;
+
+    //
+    // INPUT INTO THE NEXT FIELD!
+    //
+    if (!outok)
+      {
+       tempx=(whichtinfo?TIxmbase:TIxbase);
+       tempy=(whichtinfo?TIymbase:TIybase);
+       maxx=(whichtinfo?numtmplanes:numtplanes);
+       maxy=(whichtinfo?tilemnum:tilenum);
+
+       switch(H_or_V)
+       {
+       case 0: // HORIZONTAL
+         whichx++;
+         if (tempx+whichx>=maxx)
+           outok=1;
+         else
+         if (whichx>TINFOWIDTH)
+           {
+            whichx=TINFOWIDTH;
+            tempx++;
+            if (tempx>=maxx)
+              outok=1;
+           }
+
+         switch(whichtinfo)
+         {
+          case 0: TIxbase=tempx; break;
+          case 1: TIxmbase=tempx;
+         }
+         break;
+
+       case 1: // VERTICAL
+         whichy++;
+         if (tempy+whichy>=maxy)
+           outok=1;
+         else
+         if (whichy>(videomode==EGA2?TINFOHEIGHTEGA2:TINFOHEIGHT))
+           {
+            whichy=(videomode==EGA2?TINFOHEIGHTEGA2:TINFOHEIGHT);
+            tempy++;
+            if (tempy>=maxy)
+              outok=1;
+           }
+
+         switch(whichtinfo)
+         {
+          case 0: TIybase=tempy; break;
+          case 1: TIymbase=tempy;
+         }
+       }
+      }
+
+    DrawTinfoScreen(whichtinfo,0,0);
+
+   } while (!outok);
+
+ MouseShow();
+}
+
+
+
+//
+// Draw the Tileinfo screen
+//
+void DrawTinfoScreen(int thescreen,int deltax,int deltay)
+{
+ int temp,temp1,i,j,width,height,dialogx;
+ char _seg *Values[10];
+
+
+ MouseHide();
+ switch(videomode)
+ {
+  case CGA:
+  case EGA1:
+  case VGA:
+    dialogx=1;
+    height=16>>(tsize-1); break;
+  case EGA2:
+    dialogx=21;
+    height=52>>(tsize-1);
+ }
+
+ switch(thescreen)
+ {
+  case 0:      // TILEINFO
+    if (height>tilenum)
+      height=tilenum;
+    else
+      {
+       TIybase+=deltay;
+       if (TIybase<0)
+        TIybase=0;
+       else
+       if (TIybase+height>tilenum)
+        TIybase=tilenum-height;
+      }
+    temp=TIybase;
+    break;
+
+  case 1:      // TILEINFOM
+    if (height>tilemnum)
+      height=tilemnum;
+    else
+      {
+       TIymbase+=deltay;
+       if (TIymbase<0)
+        TIymbase=0;
+       else
+       if (TIymbase+height>tilemnum)
+        TIymbase=tilemnum-height;
+      }
+    temp=TIymbase;
+ }
+
+ //
+ // DRAW TILES AND THEIR VALUES
+ //
+ for (i=0;i<height;i++)
+   {
+    sx=dialogx;
+    sy=(i<<(tsize-1))+4;
+    printhex(i+temp);
+    sx=dialogx;
+    sy++;
+    print("    ");
+    sx-=4;
+    printint(i+temp);
+
+    switch(thescreen)
+    {
+     case 0:
+       CombineTiles(temp+i,0,0,tsize);
+       break;
+     case 1:
+       CombineTiles(-BkgndColor,temp+i+tilenum,0,tsize);
+    }
+
+    DrawTile(dialogx+5,(i+2)<<(3+(tsize-1)),tsize);
+   }
+
+ //
+ // DRAW TILEINFO ARRAYS
+ //
+ width=4;
+
+ switch(thescreen)
+ {
+  case 0:
+    if (width>numtplanes)
+      width=numtplanes;
+    else
+      {
+       TIxbase+=deltax;
+       if (TIxbase<0)
+        TIxbase=0;
+       else
+       if (TIxbase+width>numtplanes)
+        TIxbase=numtplanes-width;
+      }
+    temp1=TIxbase;
+    for (i=0;i<10;i++)
+      Values[i]=Tinfo[i];
+
+    break;
+
+  case 1:
+    if (width>numtmplanes)
+      width=numtmplanes;
+    else
+      {
+       TIxmbase+=deltax;
+       if (TIxmbase<0)
+        TIxmbase=0;
+       else
+       if (TIxmbase+width>numtmplanes)
+        TIxmbase=numtmplanes-width;
+      }
+    temp1=TIxmbase;
+    for (i=0;i<10;i++)
+      Values[i]=TMinfo[i];
+ }
+
+ for (j=0;j<width;j++)
+   {
+    sx=(dialogx+10)+j*7;
+    sy=3;
+    switch(thescreen)
+    {
+     case 0:
+       print("       ");
+       sx-=7;
+       fprint(MapFileHeader->tnames[j+TIxbase]);
+       break;
+     case 1:
+       print("       ");
+       sx-=7;
+       fprint(MapFileHeader->tmnames[j+TIxmbase]);
+    }
+    for (i=0;i<height;i++)
+      {
+       sx=(dialogx+10)+j*7;
+       sy=(i<<(tsize-1))+4;
+       print("$");
+       printhexb(Values[j+temp1][i+temp]);
+       sx=(dialogx+10)+j*7;
+       sy++;
+       print("   ");
+       sx-=3;
+       printint(Values[j+temp1][i+temp]&0xff);
+      }
+   }
+ MouseShow();
+}
+
+
+
+////////////////////////////////////////////////////
+//
+// Item - Add or Delete TILEINFO/M planes
+//
+////////////////////////////////////////////////////
+btype AODb[]={{" Add ",1,3,1},
+             {" Delete ",8,3,1},
+             {" Exit ",18,3,2}},
+      TOMb[]={{" Tileinfo  ",1,2,1},
+             {" TileinfoM ",1,5,1}},
+      AreSureB2[]={{" Yes ",1,2,1},
+                  {" No ",8,2,2}},
+      TINb2={" Done ",8,15,1};;
+DialogDef AODd={"       TILEINFO/M\n     Pick a function",25,5,3,&AODb[0],NULL},
+         TOMd={"Add to what?",13,7,2,&TOMb[0],NULL},
+         NId={"Gimme a name!",13,4,0,NULL,NULL},
+         AreSureD2={"Are you sure?",13,4,2,&AreSureB2[0],NULL},
+         TINd2={"   Which to delete?\n"
+               " TILEINFO   TILEINFOM",
+               22,17,1,&TINb2,NULL};
+
+void Item_AddDelTinfo(void)
+{
+ char temp[16];
+ int which,i;
+ unsigned dx,dy;
+
+ while(1)
+ {
+  which=DoDialog(&AODd);
+  switch(which)
+  {
+   case 0:     // ESC or EXIT
+   case 3:
+     return;
+   //
+   // ADD
+   //
+   case 1:
+     which=DoDialog(&TOMd);
+     if (!which)
+       break;
+
+     switch(which)
+     {
+      case 1:
+       if (numtplanes==10)
+         {
+          ErrDialog("You already have 10 TILEINFO\n"
+                    "planes defined!"," OK ");
+          return;
+         }
+       break;
+
+      case 2:
+       if (!tilemnum)
+         {
+          ErrDialog("You crazy shit! You don't\n"
+                    "have any masked tiles!"," Duh! ");
+          return;
+         }
+
+       if (numtmplanes==10)
+         {
+          ErrDialog("You already have 10 TILEINFOM\n"
+                    "planes defined!"," OK ");
+          return;
+         }
+       break;
+     }
+
+     DrawDialog(&NId,1);
+     MouseHide();
+     GetDialogXY(&NId,&dx,&dy);
+     sx=dx+1;
+     sy=dy+1;
+     DrawBorder(sx,sy,9,2,1);
+     sx=dx+2;
+     sy=dy+2;
+     if (!input(temp,7))
+       {
+       RestoreBackground();
+       MouseShow();
+       break;
+       }
+
+     //
+     // MOVE THE NAME AND ALLOCATE THE MEMORY!
+     //
+     switch(which)
+     {
+      case 1:
+       movedata(FP_SEG(temp),FP_OFF(temp),
+                (unsigned)MapFileHeader,FP_OFF(MapFileHeader->tnames[numtplanes]),8);
+       MMAllocate((memptr *)&Tinfo[numtplanes],tilenum);
+       for (i=0;i<tilenum;i++)
+         *(Tinfo[numtplanes]+i)=0;
+       MapFileHeader->numtplanes=++numtplanes;
+       writeH=DirtyFlag=1;
+       break;
+
+      case 2:
+       movedata(FP_SEG(temp),FP_OFF(temp),
+                (unsigned)MapFileHeader,FP_OFF(MapFileHeader->tmnames[numtmplanes]),8);
+       MMAllocate((memptr *)&TMinfo[numtmplanes],tilemnum);
+       for (i=0;i<tilemnum;i++)
+         *(TMinfo[numtmplanes]+i)=0;
+       MapFileHeader->numtmplanes=++numtmplanes;
+       writeH=DirtyFlag=1;
+     }
+
+     RestoreBackground();
+     MouseShow();
+     break;
+
+   //
+   // DELETE
+   //
+   case 2:
+     {
+      unsigned ox,oy,i,oktoexit=0;
+      int which;
+
+      redo:
+
+      MouseHide();
+      DrawDialog(&TINd2,1);
+      GetDialogXY(&TINd2,&sx,&sy);
+      ox=sx;
+      oy=sy;
+      DrawBorder(sx,sy+2,10,11,1);
+      sx=ox;
+      sy=oy;
+      DrawBorder(sx+11,sy+2,10,11,1);
+
+      for (i=0;i<10;i++)
+      {
+       sx=ox+1;
+       sy=oy+i+3;
+       fprint(MapFileHeader->tnames[i]);
+       sx=ox+12;
+       sy=oy+i+3;
+       fprint(MapFileHeader->tmnames[i]);
+      }
+      MouseShow();
+
+      do
+      {
+       if ((which=CheckList(ox+1,oy+3,8,numtplanes,TInfoNon,TInfoNoff,0))>=0)
+        {
+         int reply;
+
+         RestoreBackground();
+         reply=DoDialog(&AreSureD2);
+         switch(reply)
+         {
+          case 0:
+          case 2:
+            goto redo;
+         }
+
+         if (which!=numtplanes-1)
+           {
+            for (i=0;i<8;i++)
+              {
+               MapFileHeader->tnames[which][i]=MapFileHeader->tnames[numtplanes-1][i];
+               MapFileHeader->tnames[numtplanes-1][i]=0;
+              }
+            for (i=0;i<tilenum;i++)
+              *(Tinfo[which]+i)=*(Tinfo[numtplanes-1]+i);
+            MMFreePtr((memptr *)&Tinfo[numtplanes-1]);
+           }
+         else
+           {
+            MMFreePtr((memptr *)&Tinfo[which]);
+            for (i=0;i<8;i++)
+              MapFileHeader->tnames[which][i]=0;
+           }
+         writeH=DirtyFlag=1;
+         MapFileHeader->numtplanes=--numtplanes;
+         goto redo;
+        }
+
+       if ((which=CheckList(ox+12,oy+3,8,numtmplanes,TInfoMNon,TInfoMNoff,0))>=0)
+        {
+         int reply;
+
+         RestoreBackground();
+         reply=DoDialog(&AreSureD2);
+         switch(reply)
+         {
+          case 0:
+          case 2:
+            goto redo;
+         }
+
+         if (which!=numtmplanes-1)
+           {
+            for (i=0;i<8;i++)
+              {
+               MapFileHeader->tmnames[which][i]=MapFileHeader->tmnames[numtplanes-1][i];
+               MapFileHeader->tmnames[numtmplanes-1][i]=0;
+              }
+            for (i=0;i<tilemnum;i++)
+              *(TMinfo[which]+i)=*(TMinfo[numtmplanes-1]+i);
+            MMFreePtr((memptr *)&TMinfo[numtmplanes-1]);
+           }
+         else
+           {
+            MMFreePtr((memptr *)&TMinfo[which]);
+            for (i=0;i<8;i++)
+              MapFileHeader->tmnames[which][i]=0;
+           }
+         writeH=DirtyFlag=1;
+         MapFileHeader->numtmplanes=--numtmplanes;
+         goto redo;
+        }
+
+       GetButtonXY(&TINd2,0,&sx,&sy);
+       if (!CheckList(sx,sy,6,1,TIDoneOn,TIDoneOff,1))
+        oktoexit++;
+
+       if (keydown[1])
+        {
+         while(keydown[1]);
+         oktoexit++;
+        }
+      }while(!oktoexit);
+
+      RestoreBackground();
+     }
+  }
+ }
+}
+
+
+
+////////////////////////////////////////////////////
+//
+// Item - Project Re-Select
+//
+////////////////////////////////////////////////////
+btype NGBb[]={{" Do It! ",1,4,2},
+             {" No! Help! ",16,4,1}};
+DialogDef NGBd={"Are you sure you want to\n"
+               "switch projects? Abort now\n"
+               "or forever hold your peace!",
+               28,6,2,&NGBb[0],NULL};
+
+void Item_ProjectReSelect(void)
+{
+ int i,which;
+
+ //
+ // ARE YOU SURE?!
+ //
+ which=DoDialog(&NGBd);
+ if (!which || which==2)
+   return;
+
+
+ TEDInfo->lastvid=videomode;
+ TEDInfo->level=whichmap;
+ SaveTEDInfo();
+ SaveOutputHeader();
+
+ if (!CheckForMapSave())
+   return;
+
+ //
+ // RELEASE ALL MEMORY
+ //         ---
+ if (MapBkgnd)
+   {
+    MMFreePtr((memptr *)&MapBkgnd);
+    MMFreePtr((memptr *)&CutBkgnd);
+   }
+ if (MapFrgnd)
+   {
+    MMFreePtr((memptr *)&MapFrgnd);
+    MMFreePtr((memptr *)&CutFrgnd);
+   }
+ if (MapInfoPl)
+   {
+    MMFreePtr((memptr *)&MapInfoPl);
+    MMFreePtr((memptr *)&CutInfoPl);
+   }
+
+ MMFreePtr((memptr *)&TEDInfo);
+ MMFreePtr((memptr *)&MapFileHeader);
+
+ if (CgaXMS)
+   {
+    MMFreePtr((memptr *)&CgaXMSlookup);
+    XMSFreeMem(CgaXMS);
+   }
+ if (EgaXMS)
+   {
+    MMFreePtr((memptr *)&EgaXMSlookup);
+    XMSFreeMem(EgaXMS);
+   }
+ if (VgaXMS)
+   {
+    MMFreePtr((memptr *)&VgaXMSlookup);
+    XMSFreeMem(VgaXMS);
+   }
+ if (XMSmaps)
+   XMSFreeMem(XMSmaps);
+
+ XMSmaps=CgaXMS=EgaXMS=VgaXMS=xmshandle=0;
+
+
+ for (i=0;i<numtplanes;i++)
+   if (Tinfo[i])
+     MMFreePtr((memptr *)&Tinfo[i]);
+ for (i=0;i<numtmplanes;i++)
+   if (TMinfo[i])
+     MMFreePtr((memptr *)&TMinfo[i]);
+
+ //
+ // FORCE RE-INIT
+ //
+ writeH=TIxbase=TIxmbase=TIybase=TIymbase=PasteOK=DirtyFlag=ext[0]=0;
+ lastmap=-1;
+
+ FindGraphFile();
+ LoadInfoFile();
+ LoadMapHeader();
+ LoadGraphStuff(0,videomode);
+ MouseHide();
+ RedrawDesktop();
+ MouseShow();
+ DrawInfoBar();
+ DrawMap();
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Toggle GRIDMODE on/off
+//
+////////////////////////////////////////////////////
+void Item_GridMode(void)
+{
+ GridMode^=1;
+
+ if (PasteMode)
+   DrawFloatPaste();
+
+ DrawMap();
+ DrawInfoBar();
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Toggle SNAP-PASTE on/off
+//
+////////////////////////////////////////////////////
+void Item_SnapTog(void)
+{
+ if (!PasteMode)
+   return;
+
+ EraseFloatPaste();
+ SnapMode^=1;
+
+ snapx=(pixelx>>(tsize+2))+xbase;
+ snapy=((pixely-8)>>(tsize+2))+ybase;
+ snapxsize=TileCopy.w;
+ snapysize=TileCopy.h;
+
+ snapx=snapx-(snapx/snapxsize)*snapxsize;
+ snapy=snapy-(snapy/snapysize)*snapysize;
+
+ DrawInfoBar();
+ DrawFloatPaste();
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - View Map & Goto
+//
+////////////////////////////////////////////////////
+void Item_ViewMap(void)
+{
+ Do_ViewMap(0);
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Review Map & Goto
+//
+////////////////////////////////////////////////////
+void Item_ReviewMap(void)
+{
+ Do_ViewMap(1);
+}
+
+
+////////////////////////////////////////////////////
+//
+// Code to actually do the ViewMap (and save it in
+// EGA memory when finished).
+// Entry:
+// 0 = ViewMap, as normal & save when done (but only
+//     if a full map was viewed)
+// 1 = RestoreMap for GOTO
+//
+////////////////////////////////////////////////////
+void Do_ViewMap(int how)
+{
+ int _seg *a_bg,_seg *a_fg,_seg *a_in,CopyArea,bl_width,bl_height,bl_x,bl_y,p_info;
+
+ char huge *EGA=MK_FP(0xa000,0);
+ char _seg *block,_seg *gblock[4];
+ int i,j,k,m,n,pwidth,lwidth,maptype,step,pixnum[4]={0,8,16,32},curpix,
+         maxpack,curline,lybase,t8=8<<(tsize-1),t1=1<<(tsize-1),scrn_h,scrn_w;
+ long tilelen,bufsize;
+ int savevideo;
+
+
+
+ savevideo=videomode;
+ MouseHide();
+ setvideo(EGA1);
+ MouseShow();
+ if (videomode!=EGA1 && videomode!=EGA2)
+ {
+  ErrDialog("This function is currently\n"
+                "only usable in EGA mode!"," OK ");
+  return;
+ }
+
+ //
+ // SCREEN DIMENSIONS
+ //
+ scrn_w=320;
+ scrn_h=200;
+
+
+ bl_x=bl_y=0;
+ bl_width=mapwidth;
+ bl_height=mapheight;
+ a_bg=MapBkgnd;
+ a_fg=MapFrgnd;
+ a_in=MapInfoPl;
+ p_info=MapFileHeader->maptype;
+ CopyArea=0;
+
+ if ((TileCopy.w>screenw || TileCopy.h>screenh) && !how)
+       if (Message("\"Yes\" to display full map,\n"
+                        "\"No\" to display COPY buffer.")==1)
+       {
+        bl_x=TileCopy.x;
+        bl_y=TileCopy.y;
+        bl_width=TileCopy.w;
+        bl_height=TileCopy.h;
+        a_bg=CutBkgnd;
+        a_fg=CutFrgnd;
+        a_in=CutInfoPl;
+        p_info=TileCopy.PlanesCopied;
+        CopyArea=1;
+       }
+
+ //
+ // VALIDATE WIDTH & HEIGHT
+ //
+ if (bl_height<screenh && bl_width<screenw)
+ {
+  ErrDialog("The area fits within the\n"
+                "screen! Forget it!"," Wah! ");
+  return;
+ }
+
+
+ //
+ // FIGURE OUT THE BEST RATIO FOR CONVERSION
+ //
+ if (!how)
+       switch(bl_width>=bl_height)
+       {
+        case 1: // WIDTH > HEIGHT
+               step=(float)(pixnum[tsize]*bl_width)/scrn_w+.5;
+               if (pixnum[tsize]*bl_width/step>scrn_w)
+       step++;
+               if ((float)(pixnum[tsize]*bl_height)/step+.5<scrn_h)
+       break;
+
+        case 0: // HEIGHT > WIDTH
+               step=(float)(pixnum[tsize]*bl_height)/scrn_h+.5;
+               if (pixnum[tsize]*bl_height/step>scrn_h)
+       step++;
+       }
+ else
+       step=VMapData.step;
+
+
+ //
+ // POP LAST MAP ON SCREEN
+ //
+ if (how)
+ {
+  unsigned EGAseg=VMapData.EGAseg;
+
+  if (!VMapData.built_flag)
+  {
+       ErrDialog("You haven't previously\n"
+                 "VIEWed a map!"," OK ");
+       return;
+  }
+
+  //
+  // RESTORE MAP IN MEMORY!
+  //
+  MouseHide();
+  outport(GCindex,GCmode | 0x100);
+  outport(SCindex,SCmapmask | 0xf00);
+  asm  push    ds
+  asm  mov     ax,[EGAseg]
+  asm  mov     ds,ax
+  asm  mov     ax,0xa000
+  asm  mov     es,ax
+  asm  xor     si,si
+  asm  xor     di,di
+  asm  mov     cx,0x2000
+  asm  rep movsb
+  asm  pop     ds
+  step=VMapData.step;
+  maxpack=VMapData.maxpack;
+  MouseShow();
+ }
+ //
+ // BUILD MAP
+ //
+ else
+ {
+  //
+  // CLEAR EGA SCREEN
+  //
+  outport(GCindex,GCmode);
+  outport(SCindex,SCmapmask | 0xf00);
+  _fmemset(MK_FP(0xa000,0),0,0x2000);
+
+  //
+  // SET TILE LENGTH
+  //
+  switch(tsize)
+  {
+       case 1: tilelen=32L; break;
+       case 2: tilelen=128L; break;
+       case 3: tilelen=512L;
+  }
+
+  //
+  // ALLOCATE TEMP BUFFERS & BEGIN!
+  //
+  bufsize=tilelen*bl_width;
+  pwidth=t1*bl_width;
+  lwidth=pwidth*4;
+  MMAllocate((memptr *)&block,bufsize);
+  maxpack=pwidth/step+1;
+  for (i=0;i<4;i++)
+        MMAllocate((memptr *)&gblock[i],maxpack);
+
+  outport(GCindex,GCmode);
+  curline=0;
+  for (j=bl_y;j<bl_y+bl_height;j++)
+  {
+       lybase=j*t8;
+       for (i=bl_x;i<bl_x+bl_width;i++)
+       {
+        unsigned tilet,tilem,tilei,loc;
+
+        //
+        // ESC out?
+        //
+        if (keydown[1])
+        {
+         while(keydown[1]);
+         setvideo(savevideo);
+         RedrawDesktop();
+         DrawMap();
+         DrawInfoBar();
+         return;
+        }
+        //
+        // GET THE CORRECT TILE MOVED INTO "TDATA"
+        //
+        loc=j*mapwidth+i;
+        tilet=viewton?((p_info&BPLANE)?a_bg[loc]:-BkgndColor):-BkgndColor;
+        tilem=viewmon?((p_info&FPLANE)?a_fg[loc]+tilenum:0):0;
+        tilei=viewion?((p_info&IPLANE)?a_in[loc]+tilenum:0):0;
+        CombineTiles(tilet,tilem,tilei,tsize);
+
+        //
+        // NOW, MUNGE "TDATA" INTO BIT-PLANES!
+        //
+        // INTERNAL:           P0      P1      P2      P3
+        //     SCANLINE x      ......  ......  ......  ......
+        //
+        for (k=0;k<t8;k++)
+               if (!((lybase+k)%step))
+       for (m=0;m<4;m++)
+         movedata(FP_SEG(&tdata),FP_OFF(&tdata)+(m*tsize*t8)+k*t1,
+                        (unsigned)block,k*lwidth+m*pwidth+(i-bl_x)*t1,t1);
+       }
+
+       //
+       // CONVERT BIT-PLANE LINES TO COMPRESSED FORM...
+       //
+       for (k=0;k<8<<(tsize-1);k++)
+       {
+        if (!((lybase+k)%step))
+        {
+         int midx=k*lwidth;
+
+
+         curpix=0;
+         _fmemset(gblock[0],0,maxpack);
+         _fmemset(gblock[1],0,maxpack);
+         _fmemset(gblock[2],0,maxpack);
+         _fmemset(gblock[3],0,maxpack);
+         for (m=0;m<pwidth*8;m++)
+         {
+               if (!(m%step))
+               {
+                int temp=curpix/8,
+               temp1=7-(curpix%8),
+               temp2=7-(m%8),
+               idx;
+
+
+                idx=midx+m/8;
+
+                #if 1
+                asm    push    ds
+
+                asm    mov     ds,[block]
+                asm    mov     si,[idx]
+                asm    mov     cl,[BYTE PTR temp2]
+                asm    mov     ch,[BYTE PTR temp1]
+                asm    mov     di,[temp]
+                asm    mov     dx,[pwidth]
+                asm    dec     dx
+
+                asm    mov     es,[WORD PTR gblock]
+
+                asm    lodsb
+                asm    shr     al,cl
+                asm    and     al,1
+                asm    xchg    ch,cl
+                asm    shl     al,cl
+                asm    xchg    ch,cl
+                asm    or      [es:di],al
+
+                asm    add     si,dx
+
+                asm    mov     es,[WORD PTR gblock+2]
+
+                asm    lodsb
+                asm    shr     al,cl
+                asm    and     al,1
+                asm    xchg    ch,cl
+                asm    shl     al,cl
+                asm    xchg    ch,cl
+                asm    or      [es:di],al
+
+                asm    add     si,dx
+
+                asm    mov     es,[WORD PTR gblock+4]
+
+                asm    lodsb
+                asm    shr     al,cl
+                asm    and     al,1
+                asm    xchg    ch,cl
+                asm    shl     al,cl
+                asm    xchg    ch,cl
+                asm    or      [es:di],al
+
+                asm    add     si,dx
+
+                asm    mov     es,[WORD PTR gblock+6]
+
+                asm    lodsb
+                asm    shr     al,cl
+                asm    and     al,1
+                asm    xchg    ch,cl
+                asm    shl     al,cl
+                asm    xchg    ch,cl
+                asm    or      [es:di],al
+
+                asm    add     si,dx
+
+                asm    pop     ds
+
+                #else
+                *(gblock[0]+temp)|=((block[idx]>>temp2)&1)<<temp1;
+                *(gblock[1]+temp)|=((block[idx+pwidth]>>temp2)&1)<<temp1;
+                *(gblock[2]+temp)|=((block[idx+pwidth*2]>>temp2)&1)<<temp1;
+                *(gblock[3]+temp)|=((block[idx+pwidth*3]>>temp2)&1)<<temp1;
+                #endif
+
+                curpix++;
+               }
+         }
+
+         //
+         // BLAST ONTO THE SCREEN
+         //
+
+         MouseHide();
+         for (n=0;n<4;n++)
+         {
+               outport(SCindex,SCmapmask | (0x100<<n));
+               for (m=0;m<maxpack;m++)
+       *(EGA+EGA1lookup[curline]+m)=*(gblock[n]+m);
+     }
+     MouseShow();
+
+     curline++;
+    }
+   }
+  }
+
+  MMFreePtr((memptr *)&block);
+  for(m=0;m<4;m++)
+    MMFreePtr((memptr *)&gblock[m]);
+
+
+  //
+  // SAVE MAP IN MEMORY!
+  //
+  if (!CopyArea)
+  {
+   unsigned EGAseg=0xa800;
+
+
+   MouseHide();
+   outport(GCindex,GCmode | 0x100);
+   outport(SCindex,SCmapmask | 0xf00);
+   asm push    ds
+   asm mov     ax,[EGAseg]
+   asm mov     es,ax
+   asm mov     ax,0xa000
+   asm mov     ds,ax
+   asm xor     si,si
+   asm xor     di,di
+   asm mov     cx,0x2000
+   asm rep movsb
+   asm pop     ds
+   VMapData.step=step;
+   VMapData.built_flag=1;
+   VMapData.EGAseg=EGAseg;
+   VMapData.maxpack=maxpack;
+   MouseShow();
+  }
+ }
+
+
+ //
+ // DONE WITH MAP BUILD-N-DISPLAY
+ //
+ SignalSound();
+ clearkeys();
+
+ //
+ // IF MOUSE BUTTON PRESSED WITHIN REGION, GO THERE!
+ //
+ while(!bioskey(1))
+   if (MouseButton())
+   {
+    int x,y;
+
+    MouseCoords(&x,&y);
+    if (x<maxpack*8 && y<(mapheight*t8/step) && !CopyArea)
+    {
+     xbase=(x*step)/t8-screenw/2;
+     ybase=(y*step)/t8-screenh/2;
+     if (xbase+screenw>mapwidth)
+       xbase=mapwidth-screenw;
+     if (ybase+screenh>mapheight)
+       ybase=mapheight-screenh;
+     if (xbase<0)
+       xbase=0;
+     if (ybase<0)
+       ybase=0;
+    }
+    while(MouseButton());
+    break;
+   }
+
+ clearkeys();
+ MouseHide();
+ setvideo(savevideo);
+ RedrawDesktop();
+ DrawMap();
+ DrawInfoBar();
+ MouseShow();
+}
+
+
+////////////////////////////////////////////////////
+//
+// MAP IMPORTING FUNCTIONS FOLLOW:
+//
+////////////////////////////////////////////////////
+char _seg *oldnames,oldmapname[64],oldmapheadname[64],
+       oldSM_name[64],oldSM_loadname[64];
+
+int IM_swapin(void)
+{
+ int i;
+
+
+ _fstrcpy(mapheadname,TEDInfo->ImportPath);
+ strcat(mapheadname,oldmapheadname);
+ if (access(mapheadname,0))
+   {
+    strcpy(mapheadname,oldmapheadname);
+    return 0;
+   }
+
+ _fstrcpy(mapname,TEDInfo->ImportPath);
+ strcat(mapname,oldmapname);
+
+
+ _fstrcpy(SM_name,TEDInfo->ImportPath);
+ strcat(SM_name,oldSM_name);
+
+ _fstrcpy(SM_loadname,TEDInfo->ImportPath);
+ strcat(SM_loadname,oldSM_loadname);
+
+ MMAllocate((memptr *)&oldnames,100*16);
+ movedata(FP_SEG(MapNames),FP_OFF(MapNames),(unsigned)oldnames,0,100*16);
+
+ MMFreePtr((memptr *)&MapFileHeader);
+
+ LoadIn(mapheadname,(memptr *)&MapFileHeader);
+
+ for (i=0;i<100;i++)
+   if (MapFileHeader->dataoffsets[i]>=0)
+   {
+    MapHeaderStr TempHead;
+
+    LoadFile(mapname,(char huge *)&TempHead,MapFileHeader->dataoffsets[i],sizeof(MapHeaderStr));
+    strcpy(MapNames[i],TempHead.name);
+   }
+ return 1;
+}
+
+
+void IM_swapout(void)
+{
+ if (oldnames)         // GET RID OF MAPNAMES
+ {
+  strcpy(mapname,oldmapname);
+  strcpy(mapheadname,oldmapheadname);
+  strcpy(SM_name,oldSM_name);
+  strcpy(SM_loadname,oldSM_loadname);
+
+  movedata((unsigned)oldnames,0,FP_SEG(MapNames),FP_OFF(MapNames),100*16);
+  MMFreePtr((memptr *)&oldnames);
+  MMFreePtr((memptr *)&MapFileHeader);
+  LoadIn(mapheadname,(memptr *)&MapFileHeader);
+
+ }
+}
+
+void IM_LoadMap(void)
+{
+ unsigned long csize,size=0;
+ memptr block;
+
+ //
+ // DEALLOCATE ALL CURRENT MAP MEMORY
+ //
+ if (MapBkgnd)
+   {
+    MMFreePtr((memptr *)&MapBkgnd);
+    MMFreePtr((memptr *)&CutBkgnd);
+   }
+ if (MapFrgnd)
+   {
+    MMFreePtr((memptr *)&MapFrgnd);
+    MMFreePtr((memptr *)&CutFrgnd);
+   }
+ if (MapInfoPl)
+   {
+    MMFreePtr((memptr *)&MapInfoPl);
+    MMFreePtr((memptr *)&CutInfoPl);
+   }
+
+ //
+ // LOAD MAP HEADER
+ //
+ LoadFile(mapname,(char huge *)&MapHeader,MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
+
+ //
+ // LOAD & DECOMPRESS MAP PLANES
+ //
+ if (MapFileHeader->maptype & BPLANE)
+   {
+    LoadFile(mapname,(char huge *)&size,MapHeader.mapbkgndpl,2);
+
+    MMAllocate((memptr *)&MapBkgnd,size);
+    MMAllocate((memptr *)&CutBkgnd,size);
+    csize=MapHeader.mapbkgndlen-2;
+    MMAllocate(&block,csize);
+
+    LoadFile(mapname,MK_FP(block,0),MapHeader.mapbkgndpl+2,csize);
+
+    RLEWExpand(MK_FP(block,0),MK_FP(MapBkgnd,0),size,MapFileHeader->RLEWtag);
+    MMFreePtr(&block);
+   }
+ if (MapFileHeader->maptype & FPLANE)
+   {
+    LoadFile(mapname,(char huge *)&size,MapHeader.mapfrgndpl,2);
+
+    MMAllocate((memptr *)&MapFrgnd,size);
+    MMAllocate((memptr *)&CutFrgnd,size);
+    csize=MapHeader.mapfrgndlen-2;
+    MMAllocate(&block,csize);
+
+    LoadFile(mapname,MK_FP(block,0),MapHeader.mapfrgndpl+2,csize);
+
+    RLEWExpand(MK_FP(block,0),MK_FP(MapFrgnd,0),size,MapFileHeader->RLEWtag);
+    MMFreePtr(&block);
+   }
+ if (MapFileHeader->maptype & IPLANE)
+   {
+    LoadFile(mapname,(char huge *)&size,MapHeader.mapinfopl,2);
+
+    MMAllocate((memptr *)&MapInfoPl,size);
+    MMAllocate((memptr *)&CutInfoPl,size);
+    csize=MapHeader.mapinfolen-2;
+    MMAllocate(&block,csize);
+
+    LoadFile(mapname,MK_FP(block,0),MapHeader.mapinfopl+2,csize);
+
+    RLEWExpand(MK_FP(block,0),MK_FP(MapInfoPl,0),size,MapFileHeader->RLEWtag);
+    MMFreePtr(&block);
+   }
+}
+
+
+void IM_SaveMap(void)
+{
+ memptr block;
+ long fsize,size,nsize,change;
+ MapHeaderStr TempHeader;
+ int i,XMStemp;
+ char string[100],TEDid[]=IDSTRING;
+
+
+
+ strcpy(string,"Saving Map, '");
+ strcat(string,MapHeader.name);
+
+ strcat(string,"'.");
+ ErrDialog(string,"");
+
+ //
+ // SAVE MAP FILE HEADER
+ //
+ SaveFile(mapheadname,MK_FP(MapFileHeader,0),0,sizeof(MapFileHeaderStr));
+ fsize=sizeof(MapFileHeaderStr);
+
+ //
+ // COMPRESS & SAVE TILEINFOS
+ //
+ for (i=0;i<numtplanes;i++)
+   {
+    MMAllocate(&block,tilenum);
+    MapFileHeader->tileinfooff[i]=fsize;
+    nsize=RLEBCompress(MK_FP(Tinfo[i],0),tilenum,MK_FP(block,0),MapFileHeader->RLEWtag);
+    MapFileHeader->tileinfolen[i]=nsize;
+    SaveFile(mapheadname,MK_FP(block,0),fsize,nsize);
+    fsize+=nsize;
+    MMFreePtr(&block);
+   }
+
+ for (i=0;i<numtmplanes;i++)
+   {
+    MMAllocate(&block,tilemnum);
+    MapFileHeader->tileinfomoff[i]=fsize;
+    nsize=RLEBCompress(MK_FP(TMinfo[i],0),tilemnum,MK_FP(block,0),MapFileHeader->RLEWtag);
+    MapFileHeader->tileinfomlen[i]=nsize;
+    SaveFile(mapheadname,MK_FP(block,0),fsize,nsize);
+    fsize+=nsize;
+    MMFreePtr(&block);
+   }
+
+ MapFileHeader->oldtilenum=tilenum;
+ MapFileHeader->oldtilemnum=tilemnum;
+
+ SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2);
+ //
+ // SAVE ALREADY COMPRESSED MAPS
+ //
+
+ //
+ // NOTE: I AM STORING "TED5" AT THE START OF THE FILE BECAUSE
+ // SAVING THE FILE AT OFFSET 0 WILL TRASH IT (I HAVE TO RE-SAVE THE HEADER!)
+ //
+ SaveFile(SM_name,(char huge *)TEDid,0,strlen(TEDid));
+ fsize=strlen(TEDid);
+
+ for (i=0;i<100;i++)
+ {
+  long oldoff;
+
+  if (MapFileHeader->dataoffsets[i]==-1 || i==whichmap)
+    continue;
+
+  oldoff=MapFileHeader->dataoffsets[i];
+
+  LoadFile(SM_loadname,(char huge *)&TempHeader,oldoff,sizeof(MapHeaderStr));
+
+  strcpy(TempHeader.name,MapNames[i]);
+  MapFileHeader->dataoffsets[i]=fsize;
+  size=TempHeader.mapbkgndlen+TempHeader.mapfrgndlen+TempHeader.mapinfolen;
+  change=TempHeader.mapbkgndpl-fsize-sizeof(MapHeaderStr);
+  TempHeader.mapbkgndpl-=change;
+  TempHeader.mapfrgndpl-=change;
+  TempHeader.mapinfopl-=change;
+
+  SaveFile(SM_name,(char huge *)&TempHeader,fsize,sizeof(MapHeaderStr));
+  fsize+=sizeof(MapHeaderStr);
+
+  MMAllocate(&block,size);
+  LoadFile(SM_loadname,MK_FP(block,0),oldoff+sizeof(MapHeaderStr),size);
+  SaveFile(SM_name,MK_FP(block,0),fsize,size);
+  fsize+=size;
+  SaveFile(SM_name,"!ID!",fsize,4);
+  fsize+=4;
+  MMFreePtr(&block);
+ }
+
+ //
+ // SAVE CURRENT MAP AT END OF FILE
+ //
+ MapFileHeader->dataoffsets[whichmap]=fsize;
+ MapFileHeader->datalengths[whichmap]=sizeof(MapHeaderStr);
+ SaveFile(SM_name,(char huge *)&MapHeader,fsize,sizeof(MapHeaderStr));
+ fsize+=sizeof(MapHeaderStr);
+
+ size=MapHeader.width*MapHeader.height*sizeof(int);
+ MMAllocate(&block,size);
+ if (MapFileHeader->maptype & BPLANE)
+   {
+    MapHeader.mapbkgndpl=fsize;
+    nsize=RLEWCompress(MK_FP(MapBkgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
+    MapHeader.mapbkgndlen=nsize+2;
+
+    SaveFile(SM_name,(char huge *)&size,fsize,2);
+    fsize+=2;
+    SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
+    fsize+=nsize;
+   }
+ else
+   MapHeader.mapbkgndlen=0;
+
+ if (MapFileHeader->maptype & FPLANE)
+   {
+    MapHeader.mapfrgndpl=fsize;
+    nsize=RLEWCompress(MK_FP(MapFrgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
+    MapHeader.mapfrgndlen=nsize+2;
+
+    SaveFile(SM_name,(char huge *)&size,fsize,2);
+    fsize+=2;
+    SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
+    fsize+=nsize;
+   }
+ else
+   MapHeader.mapfrgndlen=0;
+
+ if (MapFileHeader->maptype & IPLANE)
+   {
+    MapHeader.mapinfopl=fsize;
+    nsize=RLEWCompress(MK_FP(MapInfoPl,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
+    MapHeader.mapinfolen=nsize+2;
+
+    SaveFile(SM_name,(char huge *)&size,fsize,2);
+    fsize+=2;
+    SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
+    fsize+=nsize;
+   }
+ else
+   MapHeader.mapinfolen=0;
+
+ SaveFile(SM_name,"!ID!",fsize,4);
+
+ fsize+=4;
+
+ MMFreePtr(&block);
+
+ // RE-SAVE HEADER
+ SaveFile(SM_name,(char huge *)&MapHeader,
+     MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
+
+ //
+ // RE-SAVE FILE HEADER
+ // NOTE: The "2" is so MSDOS doesn't truncate the fucking file!
+ //
+ SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2);
+
+ unlink(SM_loadname);
+ rename(SM_name,SM_loadname);
+
+ RestoreBackground();
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Import Maps
+//
+////////////////////////////////////////////////////
+btype IMPMb[]={{"New Path",3,2,1},
+              {" Import ",3,5,1},
+              {"  Exit  ",3,8,2}};
+DialogDef IMPMd={"Map Importing",13,11,3,&IMPMb[0],NULL};
+btype NPb={"                                    ",1,3,1};
+DialogDef NPd={"Current Path:",38,5,1,&NPb,NULL};
+
+
+void Item_ImportMaps(void)
+{
+ char imfile[64],tempstr[40],impath[64];
+ int oldwhichmap,which,mapnum,i;
+ int oldxb,oldyb;
+
+
+ CheckForMapSave();
+
+ //
+ // THE IMPORT FUNCTION WILL RID THE SYSTEM OF XMSMAPS
+ //
+ if (XMSmaps)
+ {
+  XMSFreeMem(XMSmaps);
+  XMSmaps=0;
+ }
+
+ //
+ // SAVE PATHS
+ //
+ _fstrcpy(impath,TEDInfo->ImportPath);
+
+ strcpy(oldmapname,mapname);
+ strcpy(oldmapheadname,mapheadname);
+ strcpy(oldSM_name,SM_name);
+ strcpy(oldSM_loadname,SM_loadname);
+
+ oldxb=xbase;
+ oldyb=ybase;
+ #pragma warn -sus
+ oldnames=0;
+ #pragma warn +sus
+ oldwhichmap=whichmap;
+
+ DrawDialog(&IMPMd,1);
+ while(1)
+ {
+  which=CheckButtons(&IMPMd);
+  switch(which)
+  {
+   //
+   // NEW PATH
+   //
+   case 1:
+     MouseHide();
+     DrawDialog(&NPd,1);
+     GetDialogXY(&NPd,&sx,&sy);
+     sy++;
+     sx++;
+     if (!impath[0])
+       print("- current dir -");
+     else
+       print(impath);
+     GetButtonXY(&NPd,0,&sx,&sy);
+     if (input(tempstr,36))
+       {
+       strcpy(impath,tempstr);
+       if (impath[strlen(impath)-1]!='\\')
+         strcat(impath,"\\");
+
+       MouseShow();
+       if (access(mapheadname,0))
+       {
+        ErrDialog("Can't find any TED5\n"
+                  "map files at that path."," OK ");
+       }
+       else
+       {
+        RestoreBackground();
+        ErrDialog("Verifying path...","");
+        _fstrcpy(TEDInfo->ImportPath,impath);
+        DirtyFlag=1;
+       }
+
+       MouseHide();
+       }
+     MouseShow();
+     RestoreBackground();
+     break;
+
+   //
+   // IMPORT
+   //
+   case 2:
+     if (!oldnames)
+     {
+      ErrDialog("Loading File Info...","");
+      if (!IM_swapin())
+      {
+       RestoreBackground();
+       ErrDialog("Having problems with your path!"," OK ");
+       break;
+      }
+      RestoreBackground();
+     }
+
+     mapnum=SelectMap(1,CREATED,"TO IMPORT");
+     if (mapnum>=0)
+     {
+      char check[100]="Are you SURE you want to\n"
+                     "Import ";
+
+      strcat(check,MapNames[mapnum]);
+      strcat(check,"?");
+      if (Message(check)<2)
+       break;
+
+      whichmap=mapnum;
+      ErrDialog("Importing. One moment.","");
+      IM_LoadMap();
+      IM_swapout();
+      IM_SaveMap();
+      IM_swapin();
+      RestoreBackground();
+     }
+     break;
+
+   //
+   // EXIT
+   //
+   case 0:
+   case 3:
+     RestoreBackground();
+     whichmap=oldwhichmap;
+     IM_swapout();
+
+     LoadMap(whichmap);
+     xbase=oldxb;
+     ybase=oldyb;
+     DrawMap();
+
+     return;
+  }
+ }
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Visit DOS
+//
+////////////////////////////////////////////////////
+int olddisk;
+char oldpath[64]="\\";
+
+void Item_VisitDOS(void)
+{
+ TempStruct LaunchInfo;
+ char ename[64],temp[40],tiname[14]="TEDINFO.TMP";
+
+ long size;
+
+
+ //
+ // Save the handles for all XMS memory so we don't
+ // have to re-install this shit!
+ //
+ TEDInfo->OldCgaXMS=CgaXMS;
+ TEDInfo->OldEgaXMS=EgaXMS;
+ TEDInfo->OldVgaXMS=VgaXMS;
+
+ TEDInfo->OldCgaXMSsize=CgaXMSsize;
+ TEDInfo->OldEgaXMSsize=EgaXMSsize;
+ TEDInfo->OldVgaXMSsize=VgaXMSsize;
+
+ size=4L*(tilenum+tilemnum);
+ if (CgaXMS)
+   {
+    if (1024L*XMSTotalFree()<size)
+      {
+       XMSFreeMem(CgaXMS);
+       TEDInfo->OldCgaXMS=TEDInfo->OldCgaXMSsize=0;
+      }
+    else
+      {
+       TEDInfo->CgaXMSlook=XMSAllocate(size);
+       XMSmove(0,(long)MK_FP(CgaXMSlookup,0),TEDInfo->CgaXMSlook,0,size);
+      }
+   }
+
+ if (EgaXMS)
+   {
+    if (1024L*XMSTotalFree()<size)
+      {
+       XMSFreeMem(EgaXMS);
+       TEDInfo->OldEgaXMS=TEDInfo->OldEgaXMSsize=0;
+      }
+    else
+      {
+       TEDInfo->EgaXMSlook=XMSAllocate(size);
+       XMSmove(0,(long)MK_FP(EgaXMSlookup,0),TEDInfo->EgaXMSlook,0,size);
+      }
+   }
+
+ if (VgaXMS)
+   {
+    if (1024L*XMSTotalFree()<size)
+      {
+       XMSFreeMem(VgaXMS);
+       TEDInfo->OldVgaXMS=TEDInfo->OldVgaXMSsize=0;
+      }
+    else
+      {
+       TEDInfo->VgaXMSlook=XMSAllocate(size);
+       XMSmove(0,(long)MK_FP(VgaXMSlookup,0),TEDInfo->VgaXMSlook,0,size);
+      }
+   }
+
+ //
+ // SAVE CURRENT VIDEOMODE FOR LAUNCH RETURN
+ //
+ LaunchInfo.lastmode=videomode;
+ strcpy(LaunchInfo.ext,ext);
+ SaveFile(tiname,(char huge *)&LaunchInfo,0,sizeof(TempStruct));
+
+ TEDInfo->oscrx=xbase;
+ TEDInfo->oscry=ybase;
+ _fmemcpy((void far *)TEDInfo->parmstring,(void far *)parmstring,64);
+
+ Item_SaveMap();
+ SaveTEDInfo();
+ SaveOutputHeader();
+
+ if (XMSmaps)
+   XMSFreeMem(XMSmaps);
+
+ strcpy(temp,"Launching ");
+ _fstrcat((char far *)temp,(char far *)TEDInfo->launchname);
+ strcat(temp,"...");
+ ErrDialog(temp,"");
+ clearkeys();
+ nosound();
+ MouseHide();
+
+ _fmemcpy((char far *)ename,(char far *)TEDInfo->launchname,14);
+
+ RemoveUndoBuffers();
+ ShutdownKBD();
+
+ //
+ // ARE WE EXITING WITH A BATCH FILE?
+ //
+
+ setvideo(TEXT);
+ printf("The TED5 DOS shell. Type 'EXIT' to return to TED5.");
+
+ //
+ // SAVE CURRENT DRIVE & PATH
+ //
+ olddisk=getdisk();
+ getcurdir(0,oldpath+1);
+
+ MMShutdown();
+ fcloseall();
+ spawnlp(P_WAIT,"COMMAND",NULL);
+
+ //
+ // RESET OLD PATH
+ //
+ setdisk(olddisk);
+ chdir(oldpath);
+
+ execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL);
+
+ printf("Can't find TED5 for some reason!");
+ exit(1);
+}
+
+
+////////////////////////////////////////////////////
+//
+// Item - Paste Overlay toggle
+//
+////////////////////////////////////////////////////
+void Item_POtog(void)
+{
+ F3_flag^=1;
+
+ if (PasteMode)
+ {
+  EraseFloatPaste();
+  DrawFloatPaste();
+ }
+}