]> 4ch.mooo.com Git - 16.git/blob - 16/ted5/TED5-1.C
ted5 added
[16.git] / 16 / ted5 / TED5-1.C
1 ////////////////////////////////////////////////////
2 ////////////////////////////////////////////////////
3 //
4 // TED5-1
5 //
6 ////////////////////////////////////////////////////
7 ////////////////////////////////////////////////////
8 #include "ted5.h"
9 #pragma hdrstop
10
11 void InputMap(char *lvlname,unsigned *levelw,unsigned *levelh,int exitok);
12 void MNameOn(int x,int y,int i);
13 void MNameOff(int x,int y,int i);
14 void DnarOn(int x,int y);
15 void DnarOff(int x,int y);
16 void UparOn(int x,int y);
17 void UparOff(int x,int y);
18 void ExitOn(int x,int y);
19 void ExitOff(int x,int y);
20 void TInfoNon(int x,int y,int b);
21 void TInfoNoff(int x,int y,int b);
22 void TInfoMNon(int x,int y,int b);
23 void TInfoMNoff(int x,int y,int b);
24 void TIDoneOn(int x,int y);
25 void TIDoneOff(int x,int y);
26
27
28 ////////////////////////////////////////////////////
29 //
30 // SAVE the current map
31 //
32 ////////////////////////////////////////////////////
33 void SaveMap(int delmap)
34 {
35  memptr block;
36  long fsize,size,nsize,change;
37  MapHeaderStr TempHeader;
38  int i,XMStemp;
39  char string[100],TEDid[]=IDSTRING;
40
41
42
43  RemoveUndoBuffers();
44  if (delmap)
45    {
46         LoadFile(mapname,(char huge *)&TempHeader,
47         MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
48         strcpy(string,"Deleting Map, '");
49         strcat(string,TempHeader.name);
50    }
51  else
52    {
53         strcpy(string,"Saving Map, '");
54         strcat(string,MapHeader.name);
55    }
56
57  strcat(string,"'.");
58  ErrDialog(string,"");
59
60
61  BackupFile(mapheadname);
62  BackupFile(SM_loadname);
63
64
65  if (delmap || DirtyFlag)
66    {
67         //
68         // SAVE MAP FILE HEADER
69         //
70         if (delmap)
71           MapFileHeader->dataoffsets[whichmap]=-1;
72
73         SaveFile(mapheadname,MK_FP(MapFileHeader,0),0,sizeof(MapFileHeaderStr));
74         fsize=sizeof(MapFileHeaderStr);
75
76         //
77         // COMPRESS & SAVE TILEINFOS
78         //
79         MMAllocate(&block,tilenum);
80         for (i=0;i<numtplanes;i++)
81           {
82            MapFileHeader->tileinfooff[i]=fsize;
83            nsize=RLEBCompress(MK_FP(Tinfo[i],0),tilenum,MK_FP(block,0),MapFileHeader->RLEWtag);
84            MapFileHeader->tileinfolen[i]=nsize;
85            SaveFile(mapheadname,MK_FP(block,0),fsize,nsize);
86            fsize+=nsize;
87           }
88         MMFreePtr(&block);
89
90         MMAllocate(&block,tilemnum);
91         for (i=0;i<numtmplanes;i++)
92           {
93            MapFileHeader->tileinfomoff[i]=fsize;
94            nsize=RLEBCompress(MK_FP(TMinfo[i],0),tilemnum,MK_FP(block,0),MapFileHeader->RLEWtag);
95            MapFileHeader->tileinfomlen[i]=nsize;
96            SaveFile(mapheadname,MK_FP(block,0),fsize,nsize);
97            fsize+=nsize;
98           }
99         MMFreePtr(&block);
100
101         MapFileHeader->oldtilenum=tilenum;
102         MapFileHeader->oldtilemnum=tilemnum;
103
104         SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2);
105         //
106         // SAVE ALREADY COMPRESSED MAPS
107         //
108
109         //
110         // IF MAPS ARE IN XMS ALREADY, ALLOCATE A NEW BUFFER
111         // TO SHUFFLE ALREADY-COMPRESSED MAPS INTO
112         //
113         if (XMSmaps)
114           {
115            int planes;
116            long len=filelen(SM_loadname);
117
118
119            planes=(MapFileHeader->maptype&BPLANE>0)+
120                   (MapFileHeader->maptype&FPLANE>0)+
121                   (MapFileHeader->maptype&IPLANE>0);
122            len+=2L*mapwidth*mapheight*planes;
123
124            if (1024L*XMSTotalFree()<len)
125          {
126           XMSFreeMem(XMSmaps);
127           XMSmaps=0;
128          }
129            else
130          XMStemp=XMSAllocate(len);
131           }
132
133         //
134         // NOTE: I AM STORING "TED5" AT THE START OF THE FILE BECAUSE
135         // SAVING THE FILE AT OFFSET 0 WILL TRASH IT (I HAVE TO RE-SAVE THE HEADER!)
136         //
137         if (XMSmaps)
138           XMSmove(0,(long)&TEDid,XMStemp,0,strlen(TEDid));
139         else
140           SaveFile(SM_name,(char huge *)TEDid,0,strlen(TEDid));
141         fsize=strlen(TEDid);
142
143         for (i=0;i<100;i++)
144     {
145      long oldoff;
146
147      if (MapFileHeader->dataoffsets[i]==-1 || i==whichmap)
148        continue;
149
150      oldoff=MapFileHeader->dataoffsets[i];
151
152      if (XMSmaps)
153            XMSmove(XMSmaps,oldoff,0,(long)&TempHeader,sizeof(MapHeaderStr));
154      else
155        LoadFile(SM_loadname,(char huge *)&TempHeader,oldoff,sizeof(MapHeaderStr));
156
157      strcpy(TempHeader.name,MapNames[i]);
158      MapFileHeader->dataoffsets[i]=fsize;
159      size=TempHeader.mapbkgndlen+TempHeader.mapfrgndlen+TempHeader.mapinfolen;
160      change=TempHeader.mapbkgndpl-fsize-sizeof(MapHeaderStr);
161      TempHeader.mapbkgndpl-=change;
162      TempHeader.mapfrgndpl-=change;
163      TempHeader.mapinfopl-=change;
164
165      if (XMSmaps)
166        XMSmove(0,(long)&TempHeader,XMStemp,fsize,sizeof(MapHeaderStr));
167      else
168        SaveFile(SM_name,(char huge *)&TempHeader,fsize,sizeof(MapHeaderStr));
169      fsize+=sizeof(MapHeaderStr);
170
171      if (XMSmaps)
172        {
173         XMSmove(XMSmaps,oldoff+sizeof(MapHeaderStr),XMStemp,fsize,size);
174         fsize+=size;
175         XMSmove(0,(long)"!ID!",XMStemp,fsize,4);
176         fsize+=4;
177        }
178      else
179        {
180         MMAllocate(&block,size);
181         LoadFile(SM_loadname,MK_FP(block,0),oldoff+sizeof(MapHeaderStr),size);
182         SaveFile(SM_name,MK_FP(block,0),fsize,size);
183         fsize+=size;
184         SaveFile(SM_name,"!ID!",fsize,4);
185         fsize+=4;
186         MMFreePtr(&block);
187        }
188     }
189
190     //
191     // SAVE CURRENT MAP AT END OF FILE
192     //
193     if (!delmap)
194       {
195        MapFileHeader->dataoffsets[whichmap]=fsize;
196        MapFileHeader->datalengths[whichmap]=sizeof(MapHeaderStr);
197        if (XMSmaps)
198          XMSmove(0,(long)&MapHeader,XMStemp,fsize,sizeof(MapHeaderStr));
199        else
200          SaveFile(SM_name,(char huge *)&MapHeader,fsize,sizeof(MapHeaderStr));
201        fsize+=sizeof(MapHeaderStr);
202
203        size=MapHeader.width*MapHeader.height*sizeof(int);
204        MMAllocate(&block,size);
205        if (MapFileHeader->maptype & BPLANE)
206          {
207           MapHeader.mapbkgndpl=fsize;
208           nsize=RLEWCompress(MK_FP(MapBkgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
209
210           MapHeader.mapbkgndlen=nsize+2;
211
212           if (XMSmaps)
213             XMSmove(0,(long)&size,XMStemp,fsize,2);
214           else
215             SaveFile(SM_name,(char huge *)&size,fsize,2);
216
217           fsize+=2;
218
219           if (XMSmaps)
220             XMSmove(0,(long)MK_FP(block,0),XMStemp,fsize,nsize);
221           else
222             SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
223
224           fsize+=nsize;
225          }
226        else
227          MapHeader.mapbkgndlen=0;
228
229        if (MapFileHeader->maptype & FPLANE)
230          {
231           MapHeader.mapfrgndpl=fsize;
232           nsize=RLEWCompress(MK_FP(MapFrgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
233
234           MapHeader.mapfrgndlen=nsize+2;
235
236           if (XMSmaps)
237             XMSmove(0,(long)&size,XMStemp,fsize,2);
238           else
239             SaveFile(SM_name,(char huge *)&size,fsize,2);
240
241           fsize+=2;
242
243           if (XMSmaps)
244             XMSmove(0,(long)MK_FP(block,0),XMStemp,fsize,nsize);
245           else
246             SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
247
248           fsize+=nsize;
249          }
250        else
251          MapHeader.mapfrgndlen=0;
252
253        if (MapFileHeader->maptype & IPLANE)
254          {
255           MapHeader.mapinfopl=fsize;
256           nsize=RLEWCompress(MK_FP(MapInfoPl,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
257
258           MapHeader.mapinfolen=nsize+2;
259
260           if (XMSmaps)
261             XMSmove(0,(long)&size,XMStemp,fsize,2);
262           else
263             SaveFile(SM_name,(char huge *)&size,fsize,2);
264
265           fsize+=2;
266
267           if (XMSmaps)
268             XMSmove(0,(long)MK_FP(block,0),XMStemp,fsize,nsize);
269           else
270             SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
271
272           fsize+=nsize;
273          }
274        else
275          MapHeader.mapinfolen=0;
276
277        if (XMSmaps)
278          XMSmove(0,(long)"!ID!",XMStemp,fsize,4);
279        else
280          SaveFile(SM_name,"!ID!",fsize,4);
281
282        fsize+=4;
283
284        MMFreePtr(&block);
285
286        // RE-SAVE HEADER
287        if (XMSmaps)
288                         XMSmove(0,(long)&MapHeader,XMStemp,
289                                 MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
290            else
291                         SaveFile(SM_name,(char huge *)&MapHeader,
292                                 MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
293
294        //
295        // RE-SAVE FILE HEADER
296            // NOTE: The "2" is so SaveFile doesn't truncate the fucking file!
297        //
298        SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2);
299           }
300
301     if (XMSmaps)
302       {
303        #define BCSIZE   0x4000
304        long size=fsize,clen,coff;
305
306        //
307        // SAVE ENTIRE MAPFILE IN XMS TO DISK!
308        //
309        XMSFreeMem(XMSmaps);
310        XMSmaps=XMStemp;
311
312        MMAllocate(&block,BCSIZE);
313        coff=0;
314        do
315        {
316                 clen=BCSIZE;
317                 if (size<BCSIZE)
318                         clen=size;
319
320                 XMSmove(XMSmaps,coff,0,(long)MK_FP(block,0),clen);
321                 SaveFile(SM_loadname,MK_FP(block,0),coff,clen);
322                 size-=BCSIZE;
323                 coff+=clen;
324
325            } while(size>0);
326
327        MMFreePtr(&block);
328       }
329     else
330       {
331        unlink(SM_loadname);
332        rename(SM_name,SM_loadname);
333       }
334    }
335
336  AllocateUndoBuffers();
337  UndoRegion.x=-1;
338  SaveUndo(0,0,mapwidth,mapheight);
339  RestoreBackground();
340 }
341
342
343
344
345
346
347 ////////////////////////////////////////////////////
348 //
349 // BACKUP FILES!
350 //
351 ////////////////////////////////////////////////////
352 void BackupFile(char *filename)
353 {
354  #define BUFSIZE        0x8000
355  memptr block;
356  long size,clen,coff;
357  int i;
358  char backupname[14];
359
360
361  size = filelen(filename);
362  if (!size)
363    return;
364
365  strcpy(backupname,filename);
366  for (i=strlen(backupname);i;i--)
367    if (backupname[i] == '.')
368          backupname[i+1] = 0;
369  strcat(backupname,"BAK");
370
371  MMAllocate(&block,BUFSIZE);
372  coff=0;
373  do
374  {
375   clen=BUFSIZE;
376   if (size<BUFSIZE)
377           clen=size;
378
379   LoadFile(filename,(char far *)block,coff,clen);
380   SaveFile(backupname,MK_FP(block,0),coff,clen);
381   size-=BUFSIZE;
382   coff+=clen;
383
384  } while(size>0);
385
386  MMFreePtr(&block);
387 }
388
389
390 ////////////////////////////////////////////////////
391 //
392 // SAVE OUT TEDINFO FILE
393 //
394 ////////////////////////////////////////////////////
395 void SaveTEDInfo(void)
396 {
397  BackupFile(infoname);
398
399  TEDInfo->oscrx=xbase;
400  TEDInfo->oscry=ybase;
401  _fstrcpy(TEDInfo->launchname,(char far *)launchname);
402  SaveFile(infoname,MK_FP(TEDInfo,0),0,sizeof(InfoStruct));
403 }
404
405
406 ////////////////////////////////////////////////////
407 //
408 // WRITE OUT THE OUTPUT HEADER FILE
409 //
410 ////////////////////////////////////////////////////
411 char * _nfstrcpy(char *dest,char far *source)
412 {
413  int i;
414
415  for (i=0;i<_fstrlen(source);i++)
416    *(dest+i)=*(source+i);
417
418  return dest;
419 }
420
421
422 void SaveOutputHeader(void)
423 {
424  char outhead[14]="MAPHEAD.",dot_h[14]="MAPS",t[15],tm[15],temp[40],temp1[40];
425  FILE *fp;
426  OutputHeadStr OutHead;
427  int i,Thelast;
428  long fsize;
429
430
431  ErrDialog("Saving header...","");
432
433  strcat(outhead,ext);
434
435  BackupFile(outhead);
436
437  memset(&OutHead,0,sizeof(OutputHeadStr));
438
439  OutHead.RLEWtag=MapFileHeader->RLEWtag;
440
441  for (i=0;i<100;i++)
442    OutHead.dataoffsets[i]=MapFileHeader->dataoffsets[i];
443
444  fsize=sizeof(OutputHeadStr);
445  SaveFile(outhead,(char huge *)&OutHead,0,fsize);
446  for (i=0;i<numtplanes;i++)
447    {
448     SaveFile(outhead,MK_FP(Tinfo[i],0),fsize,tilenum);
449     fsize+=tilenum;
450    }
451  for (i=0;i<numtmplanes;i++)
452    {
453     SaveFile(outhead,MK_FP(TMinfo[i],0),fsize,tilemnum);
454     fsize+=tilemnum;
455    }
456
457  RestoreBackground();
458
459  //
460  // DUMP OUT A MAPSext.H HEADER FILE
461  //
462  if (writeH)
463    {
464     ErrDialog("Saving .h file...","");
465
466     strcat(dot_h,ext);
467     strcat(dot_h,".H");
468     unlink(dot_h);
469
470     if ((fp=fopen(dot_h,"wt"))==NULL)
471       return;
472
473     fprintf(fp,"///////////////////////////////////////\n");
474     fprintf(fp,"//\n");
475     fprintf(fp,"// TED5 Map Header for %s\n",ext);
476     fprintf(fp,"//\n");
477     fprintf(fp,"///////////////////////////////////////\n");
478
479     Thelast=99;
480         for (i=99;i>=0;i--)
481       if (MapFileHeader->dataoffsets[i]>=0)
482       {
483        Thelast=i;
484        break;
485       }
486
487
488     fprintf(fp,"\n");
489     fprintf(fp,"//\n");
490     fprintf(fp,"// Map Names\n");
491     fprintf(fp,"//\n");
492
493     fprintf(fp,"typedef enum {\n");
494     for (i=0;i<100;i++)
495       if (MapFileHeader->dataoffsets[i]>=0)
496         {
497          char temp[28];
498          int j;
499
500
501          strcpy(temp,&MapNames[i][0]);
502          strcat(temp,"_MAP");
503
504          for (j=0;j<strlen(temp);j++)
505            if (temp[j]==' ')
506              temp[j]='_';
507
508          strcat(temp,",");
509          while(strlen(temp)<25)
510            strcat(temp," ");
511
512          fprintf(fp,"\t\t%s// %d\n",strupr(temp),i);
513         }
514       else
515         if (i<Thelast)
516           fprintf(fp,"\t\tEMPTYMAP%d,\n",i);
517
518     fprintf(fp,"\t\tLASTMAP\n\t     } mapnames;\n");
519
520     switch(tsize)
521     {
522      case 1:
523        strcpy(t,"NUMTILE8");
524        strcpy(tm,"NUMTILE8M");
525            break;
526      case 2:
527        strcpy(t,"NUMTILE16");
528        strcpy(tm,"NUMTILE16M");
529        break;
530      case 3:
531        strcpy(t,"NUMTILE32");
532        strcpy(tm,"NUMTILE32M");
533     }
534
535
536     if (numtplanes)
537     {
538      fprintf(fp,"\n");
539      fprintf(fp,"//\n");
540      fprintf(fp,"// TILEINFO offsets\n");
541      fprintf(fp,"//\n");
542
543      memset(temp,0,sizeof(temp));
544      memset(temp1,0,sizeof(temp1));
545      fprintf(fp,"#define %s\x9\x9%d\n",
546        strupr(_nfstrcpy(temp,MapFileHeader->tnames[0])),
547        sizeof(OutputHeadStr));
548      for (i=1;i<numtplanes;i++)
549        {
550         memset(temp,0,sizeof(temp));
551         memset(temp1,0,sizeof(temp1));
552
553         fprintf(fp,"#define %s\x9\x9(%s+%s)\n",
554           strupr(_nfstrcpy(temp,MapFileHeader->tnames[i])),
555           strupr(_nfstrcpy(temp1,MapFileHeader->tnames[i-1])),
556           t);
557        }
558     }
559
560     if (numtmplanes)
561     {
562      fprintf(fp,"\n");
563      fprintf(fp,"//\n");
564      fprintf(fp,"// TILEINFOM offsets\n");
565      fprintf(fp,"//\n");
566
567      memset(temp,0,sizeof(temp));
568      memset(temp1,0,sizeof(temp1));
569      fprintf(fp,"#define %s\x9\x9(%s+%s)\n",
570        strupr(_nfstrcpy(temp,MapFileHeader->tmnames[0])),
571        strupr(_nfstrcpy(temp1,MapFileHeader->tnames[numtplanes-1])),
572        t);
573      for (i=1;i<numtmplanes;i++)
574        {
575         memset(temp,0,sizeof(temp));
576         memset(temp1,0,sizeof(temp1));
577
578         fprintf(fp,"#define %s\x9\x9(%s+%s)\n",
579           strupr(_nfstrcpy(temp,MapFileHeader->tmnames[i])),
580           strupr(_nfstrcpy(temp1,MapFileHeader->tmnames[i-1])),
581           tm);
582        }
583     }
584
585     fclose(fp);
586     writeH=0;
587     RestoreBackground();
588    }
589
590 }
591
592
593 ////////////////////////////////////////////////////
594 //
595 // Initialize the TILEINFO/M arrays
596 //
597 ////////////////////////////////////////////////////
598 btype TIb[]={{"                  ",1,2,1},
599              {"                  ",1,6,1},
600              {" Done ",12,9,2}};
601 DialogDef TId={" How many TILEINFO planes?\n\n\n\n"
602                " How many TILEINFOM planes?",
603                27,11,3,&TIb[0],NULL};
604
605 void InitTileinfo(void)
606 {
607  unsigned temp,which,oktoexit=0,ox,oy,i,j;
608  long fsize;
609
610  numtplanes=numtmplanes=0;
611  DrawDialog(&TId,1);
612  GetButtonXY(&TId,0,&sx,&sy);
613  printint(numtplanes);
614  if (MapFileHeader->maptype&FPLANE)
615    {
616     GetButtonXY(&TId,1,&sx,&sy);
617     printint(numtmplanes);
618    }
619  do
620  {
621   which=CheckButtons(&TId);
622   switch(which)
623   {
624    case 1:
625      MouseHide();
626      GetButtonXY(&TId,0,&sx,&sy);
627      ox=sx;
628      oy=sy;
629      print(TIb[0].text);
630      sx=ox;
631      sy=oy;
632      if ((temp=inputint(9))!=ESCOUT && temp<11 && temp)
633        numtplanes=temp;
634      sx=ox;
635      sy=oy;
636      print(TIb[0].text);
637      sx=ox;
638      sy=oy;
639      printint(numtplanes);
640      MouseShow();
641
642    case 2:
643      MouseHide();
644      GetButtonXY(&TId,1,&sx,&sy);
645      ox=sx;
646      oy=sy;
647      print(TIb[1].text);
648      sx=ox;
649      sy=oy;
650      if (MapFileHeader->maptype&FPLANE)
651        {
652         if ((temp=inputint(9))!=ESCOUT && temp<11 && temp)
653           numtmplanes=temp;
654         sx=ox;
655         sy=oy;
656         print(TIb[1].text);
657         sx=ox;
658         sy=oy;
659         printint(numtmplanes);
660        }
661      MouseShow();
662      break;
663
664    case 3:
665      MouseHide();
666      oktoexit=1;
667      GetButtonXY(&TId,2,&sx,&sy);
668      print(TIb[2].text);
669      MouseShow();
670   }
671
672  } while(!oktoexit);
673
674  RestoreBackground();
675
676  //
677  // allocate arrays
678  //
679  fsize=sizeof(MapFileHeaderStr);
680
681  for (i=0;i<numtplanes;i++)
682    {
683     MMAllocate((memptr *)&Tinfo[i],tilenum);
684     MapFileHeader->tileinfooff[i]=fsize;        // THIS DOESN'T REALLY MATTER
685     fsize+=tilenum;                             // ....YET!
686     for(j=0;j<tilenum;j++)
687       *(Tinfo[i]+j)=0;
688    }
689
690  for (i=0;i<numtmplanes;i++)
691    {
692     MMAllocate((memptr *)&TMinfo[i],tilemnum);
693     MapFileHeader->tileinfomoff[i]=fsize;
694     fsize+=tilemnum;
695     for(j=0;j<tilemnum;j++)
696       *(TMinfo[i]+j)=0;
697    }
698
699  MapFileHeader->numtplanes=numtplanes;
700  MapFileHeader->numtmplanes=numtmplanes;
701
702  MapFileHeader->oldtilenum=tilenum;
703  MapFileHeader->oldtilemnum=tilemnum;
704  writeH=1;
705 }
706
707
708 ////////////////////////////////////////////////////
709 //
710 // Item - Edit the TILEINFO names
711 //
712 ////////////////////////////////////////////////////
713 btype TINb={" Done ",8,15,1};
714 DialogDef TINd={"  Enter plane names:\n"
715                 " TILEINFO   TILEINFOM",
716                 22,17,1,&TINb,NULL};
717
718 void Item_EditTinfoNames(void)
719 {
720  unsigned ox,oy,i,oktoexit=0;
721  int which;
722
723  MouseHide();
724  DrawDialog(&TINd,1);
725  GetDialogXY(&TINd,&sx,&sy);
726  ox=sx;
727  oy=sy;
728  DrawBorder(sx,sy+2,10,11,1);
729  sx=ox;
730  sy=oy;
731  DrawBorder(sx+11,sy+2,10,11,1);
732
733  for (i=0;i<10;i++)
734  {
735   sx=ox+1;
736   sy=oy+i+3;
737   fprint(MapFileHeader->tnames[i]);
738   sx=ox+12;
739   sy=oy+i+3;
740   fprint(MapFileHeader->tmnames[i]);
741  }
742  MouseShow();
743
744  do
745  {
746   if ((which=CheckList(ox+1,oy+3,8,numtplanes,TInfoNon,TInfoNoff,0))>=0)
747     {
748      char temp[8];
749
750      MouseHide();
751 redo:
752      sx=ox+1;
753      sy=oy+which+3;
754      print("         ");
755      sx=ox+1;
756      sy=oy+which+3;
757      if (input(temp,7))
758        {
759         for(i=0;i<8;i++)
760           MapFileHeader->tnames[which][i]=temp[i];
761         which++;
762         writeH=DirtyFlag=1;
763         if (which<numtplanes)
764           goto redo;
765        }
766      else
767        TInfoNoff(ox+1,oy+3+which,which);
768     MouseShow();
769     }
770
771   if ((which=CheckList(ox+12,oy+3,8,numtmplanes,TInfoMNon,TInfoMNoff,0))>=0)
772     {
773      char temp[8];
774
775      MouseHide();
776 redo1:
777      sx=ox+12;
778      sy=oy+which+3;
779      print("         ");
780      sx=ox+12;
781      sy=oy+which+3;
782      if (input(temp,7))
783        {
784         for(i=0;i<8;i++)
785           MapFileHeader->tmnames[which][i]=temp[i];
786         which++;
787         writeH=DirtyFlag=1;
788         if (which<numtmplanes)
789           goto redo1;
790        }
791      else
792        TInfoMNoff(ox+12,oy+3+which,which);
793     MouseShow();
794     }
795
796   GetButtonXY(&TINd,0,&sx,&sy);
797   if (!CheckList(sx,sy,6,1,TIDoneOn,TIDoneOff,1))
798     oktoexit++;
799
800   if (keydown[1])
801     {
802      while(keydown[1]);
803      oktoexit++;
804     }
805  }while(!oktoexit);
806
807  RestoreBackground();
808 }
809
810 void TInfoNon(int x,int y,int b)
811 {
812  xormask=1;
813  sx=x;
814  sy=y;
815  if (!MapFileHeader->tnames[b][0])
816    print("         ");
817  else
818    fprint(MapFileHeader->tnames[b]);
819  xormask=0;
820 }
821 void TInfoNoff(int x,int y,int b)
822 {
823  sx=x;
824  sy=y;
825  if (!MapFileHeader->tnames[b][0])
826    print("         ");
827  else
828    fprint(MapFileHeader->tnames[b]);
829 }
830 void TInfoMNon(int x,int y,int b)
831 {
832  xormask=1;
833  sx=x;
834  sy=y;
835  if (!MapFileHeader->tmnames[b][0])
836    print("         ");
837  else
838    fprint(MapFileHeader->tmnames[b]);
839  xormask=0;
840 }
841 void TInfoMNoff(int x,int y,int b)
842 {
843  sx=x;
844  sy=y;
845  if (!MapFileHeader->tmnames[b][0])
846    print("         ");
847  else
848    fprint(MapFileHeader->tmnames[b]);
849 }
850 void TIDoneOn(int x,int y)
851 {
852  xormask=1;
853  sx=x;
854  sy=y;
855  print(" Done ");
856  xormask=0;
857 }
858 void TIDoneOff(int x,int y)
859 {
860  sx=x;
861  sy=y;
862  print(" Done ");
863 }
864
865 ////////////////////////////////////////////////////
866 //
867 // Create a new map!
868 //
869 ////////////////////////////////////////////////////
870 void CreateMap(int exitok)
871 {
872  unsigned lwidth,lheight,i;
873  int mapnum;
874  long size;
875  char lname[16];
876
877  if ((mapnum=SelectMap(exitok,NOTCREATED,"TO CREATE"))==-1)
878    return;
879
880  InputMap(lname,&lwidth,&lheight,exitok);
881  if (!lname[0])
882    return;
883
884  RemoveUndoBuffers();
885  SaveCutBuffers();
886
887  if (MapBkgnd)
888    {
889     MMFreePtr((memptr *)&MapBkgnd);
890     MMFreePtr((memptr *)&CutBkgnd);
891    }
892  if (MapFrgnd)
893    {
894     MMFreePtr((memptr *)&MapFrgnd);
895     MMFreePtr((memptr *)&CutFrgnd);
896    }
897  if (MapInfoPl)
898    {
899     MMFreePtr((memptr *)&MapInfoPl);
900     MMFreePtr((memptr *)&CutInfoPl);
901    }
902
903  size=2L*(lwidth*lheight);
904
905  if (MapFileHeader->maptype&BPLANE)
906    {
907     MMAllocate((memptr *)&MapBkgnd,size);
908     MMAllocate((memptr *)&CutBkgnd,size);
909     for(i=0;i<lwidth*lheight;i++)
910       *(MapBkgnd+i)=*(CutBkgnd+i)=0;
911    }
912  if (MapFileHeader->maptype&FPLANE)
913    {
914     MMAllocate((memptr *)&MapFrgnd,size);
915     MMAllocate((memptr *)&CutFrgnd,size);
916     for(i=0;i<lwidth*lheight;i++)
917       *(MapFrgnd+i)=*(CutFrgnd+i)=0;
918    }
919  if (MapFileHeader->maptype&IPLANE)
920    {
921     MMAllocate((memptr *)&MapInfoPl,size);
922     MMAllocate((memptr *)&CutInfoPl,size);
923     for(i=0;i<lwidth*lheight;i++)
924       *(MapInfoPl+i)=*(CutInfoPl+i)=0;
925    }
926
927  whichmap=mapnum;
928  strcpy(MapHeader.name,lname);
929  MapHeader.width=mapwidth=lwidth;
930  MapHeader.height=mapheight=lheight;
931  strcpy(MapNames[mapnum],MapHeader.name);
932  AllocateUndoBuffers();
933  DirtyFlag=1;
934  SaveMap(0);
935  DirtyFlag=0;
936  RestoreCutBuffers();
937  SelectMode=PasteMode=xbase=ybase=0;
938  SelX1=SelX2=SelY1=SelY2=-1;
939  writeH=1;
940 }
941
942
943 ////////////////////////////////////////////////////
944 //
945 // Load a map
946 //
947 ////////////////////////////////////////////////////
948 void LoadMap(int mapnum)
949 {
950  unsigned long csize,size=0;
951  memptr block;
952
953  SaveCutBuffers();
954  //
955  // DEALLOCATE ALL CURRENT MAP MEMORY
956  //
957  RemoveUndoBuffers();
958
959  if (MapBkgnd)
960    {
961     MMFreePtr((memptr *)&MapBkgnd);
962     MMFreePtr((memptr *)&CutBkgnd);
963    }
964  if (MapFrgnd)
965    {
966     MMFreePtr((memptr *)&MapFrgnd);
967     MMFreePtr((memptr *)&CutFrgnd);
968    }
969  if (MapInfoPl)
970    {
971     MMFreePtr((memptr *)&MapInfoPl);
972     MMFreePtr((memptr *)&CutInfoPl);
973    }
974
975  //
976  // LOAD MAP HEADER
977  //
978  if (XMSmaps)
979    XMSmove(XMSmaps,MapFileHeader->dataoffsets[mapnum],0,(long)&MapHeader,sizeof(MapHeaderStr));
980  else
981    LoadFile(mapname,(char huge *)&MapHeader,MapFileHeader->dataoffsets[mapnum],sizeof(MapHeaderStr));
982
983  //
984  // LOAD & DECOMPRESS MAP PLANES
985  //
986  if (MapFileHeader->maptype & BPLANE)
987    {
988     if (XMSmaps)
989       XMSmove(XMSmaps,MapHeader.mapbkgndpl,0,(long)&size,2);
990     else
991       LoadFile(mapname,(char huge *)&size,MapHeader.mapbkgndpl,2);
992
993     MMAllocate((memptr *)&MapBkgnd,size);
994     MMAllocate((memptr *)&CutBkgnd,size);
995     csize=MapHeader.mapbkgndlen-2;
996     MMAllocate(&block,csize);
997
998     if (XMSmaps)
999       XMSmove(XMSmaps,MapHeader.mapbkgndpl+2,0,(long)MK_FP(block,0),csize);
1000     else
1001       LoadFile(mapname,MK_FP(block,0),MapHeader.mapbkgndpl+2,csize);
1002
1003     RLEWExpand(MK_FP(block,0),MK_FP(MapBkgnd,0),size,MapFileHeader->RLEWtag);
1004     MMFreePtr(&block);
1005    }
1006  if (MapFileHeader->maptype & FPLANE)
1007    {
1008     if (XMSmaps)
1009       XMSmove(XMSmaps,MapHeader.mapfrgndpl,0,(long)&size,2);
1010     else
1011       LoadFile(mapname,(char huge *)&size,MapHeader.mapfrgndpl,2);
1012
1013     MMAllocate((memptr *)&MapFrgnd,size);
1014     MMAllocate((memptr *)&CutFrgnd,size);
1015     csize=MapHeader.mapfrgndlen-2;
1016     MMAllocate(&block,csize);
1017
1018     if (XMSmaps)
1019       XMSmove(XMSmaps,MapHeader.mapfrgndpl+2,0,(long)MK_FP(block,0),csize);
1020     else
1021       LoadFile(mapname,MK_FP(block,0),MapHeader.mapfrgndpl+2,csize);
1022
1023     RLEWExpand(MK_FP(block,0),MK_FP(MapFrgnd,0),size,MapFileHeader->RLEWtag);
1024     MMFreePtr(&block);
1025    }
1026  if (MapFileHeader->maptype & IPLANE)
1027    {
1028     if (XMSmaps)
1029       XMSmove(XMSmaps,MapHeader.mapinfopl,0,(long)&size,2);
1030     else
1031       LoadFile(mapname,(char huge *)&size,MapHeader.mapinfopl,2);
1032
1033     MMAllocate((memptr *)&MapInfoPl,size);
1034     MMAllocate((memptr *)&CutInfoPl,size);
1035     csize=MapHeader.mapinfolen-2;
1036     MMAllocate(&block,csize);
1037
1038     if (XMSmaps)
1039       XMSmove(XMSmaps,MapHeader.mapinfopl+2,0,(long)MK_FP(block,0),csize);
1040     else
1041       LoadFile(mapname,MK_FP(block,0),MapHeader.mapinfopl+2,csize);
1042
1043     RLEWExpand(MK_FP(block,0),MK_FP(MapInfoPl,0),size,MapFileHeader->RLEWtag);
1044     MMFreePtr(&block);
1045    }
1046
1047  mapwidth=MapHeader.width;
1048  mapheight=MapHeader.height;
1049  strcpy(MapNames[mapnum],MapHeader.name);
1050
1051  AllocateUndoBuffers();
1052  UndoRegion.x=-1;
1053  SaveUndo(0,0,mapwidth,mapheight);
1054  RestoreCutBuffers();
1055
1056  SelectMode=PasteMode=xbase=ybase=0;
1057  SelX1=SelX2=SelY1=SelY2=-1;
1058 }
1059
1060
1061 ////////////////////////////////////////////////////
1062 //
1063 // Select a new map!
1064 //
1065 ////////////////////////////////////////////////////
1066 btype ClvlB[]={{"\xb",28,5,1},
1067                {"\xc",28,14,1},
1068                {" Exit ",12,17,1}};
1069 DialogDef ClvlD={"          SELECT MAP",
1070                  30,19,2,&ClvlB[0],NULL};
1071 int smbase=0;
1072
1073 int SelectMap(int exitok,int createflg,char *title)
1074 {
1075  MapHeaderStr TempMapHeader;
1076  unsigned ox,oy,i,dx,dy;
1077  int select=-1,redraw;
1078
1079  if (exitok)
1080    {
1081     ClvlD.numbuttons=3;
1082     ClvlD.height=19;
1083    }
1084  else
1085    {
1086     ClvlD.numbuttons=2;
1087     ClvlD.height=16;
1088    }
1089
1090  DrawDialog(&ClvlD,1);
1091  GetDialogXY(&ClvlD,&dx,&dy);
1092  sy=dy+1;
1093  sx=screencenterx-strlen(title)/2;
1094  print(title);
1095
1096  dx+=3;
1097  dy+=5;
1098
1099  MouseHide();
1100  GetButtonXY(&ClvlD,0,&sx,&sy);
1101  sx-=27;
1102  sy-=2;
1103  print("Map   Name\n");
1104  ox=sx+1;
1105  oy=sy+1;
1106  DrawBorder(sx,sy,26,11,2);
1107  MouseShow();
1108
1109
1110  do
1111  {
1112   int mx,my;
1113
1114   //
1115   // DRAW MAP NAMES
1116   //
1117   MouseHide();
1118   for (i=0;i<10;i++)
1119   {
1120    sy=oy+i;
1121    sx=ox;
1122    if (i+smbase==whichmap)
1123      print("*");
1124    else
1125      print(" ");
1126
1127    printint(i+smbase);
1128    print(" ");
1129    sx=ox+5;
1130    MNameOff(sx,sy,i);
1131   }
1132   MouseShow();
1133   redraw=0;
1134
1135   do
1136   {
1137    GetButtonXY(&ClvlD,0,&(unsigned)mx,&(unsigned)my);
1138    if (!CheckList(mx,my,1,1,UparOn,UparOff,0) || keydown[0x48])
1139      {
1140       MouseHide();
1141       GetButtonXY(&ClvlD,0,&sx,&sy);
1142       print(ClvlB[0].text);
1143
1144       smbase-=10;
1145       if (smbase<0)
1146         smbase=0;
1147       redraw=1;
1148       MouseShow();
1149       while(keydown[0x48]);
1150       continue;
1151      }
1152
1153    GetButtonXY(&ClvlD,1,&(unsigned)mx,&(unsigned)my);
1154    if (!CheckList(mx,my,1,1,DnarOn,DnarOff,0) || keydown[0x50])
1155      {
1156       MouseHide();
1157       GetButtonXY(&ClvlD,1,&sx,&sy);
1158       print(ClvlB[1].text);
1159
1160       smbase+=10;
1161       if (smbase>90)
1162         smbase=90;
1163       redraw=1;
1164       MouseShow();
1165       while(keydown[0x50]);
1166       continue;
1167      }
1168
1169    if (exitok)
1170      {
1171       GetButtonXY(&ClvlD,2,&(unsigned)mx,&(unsigned)my);
1172       if (!CheckList(mx,my,6,1,ExitOn,ExitOff,0))
1173         {
1174          RestoreBackground();
1175          return -1;
1176         }
1177      }
1178
1179    if (exitok && keydown[1])
1180      {
1181       RestoreBackground();
1182       return -1;
1183      }
1184
1185    select=CheckList(ox+5,oy,20,10,MNameOn,MNameOff,0);
1186    if (select>=0)
1187      {
1188       MouseHide();
1189       sy=select+oy;
1190       sx=ox+5;
1191       MNameOff(sx,sy,select);
1192       MouseShow();
1193       if ((MapFileHeader->dataoffsets[select+smbase]!=-1 && createflg==NOTCREATED)||
1194           (MapFileHeader->dataoffsets[select+smbase]==-1 && createflg==CREATED))
1195         select=-1;
1196      }
1197
1198   } while(!redraw && select<0);
1199  } while(select<0);
1200
1201  RestoreBackground();
1202  return select+smbase;
1203 }
1204
1205 //
1206 // Print arrows
1207 //
1208 void DnarOn(int x,int y)
1209 {
1210  sx=x;
1211  sy=y;
1212  xormask=1;
1213  drawchar(sx,sy,0xc);
1214  xormask=0;
1215 }
1216 void DnarOff(int x,int y)
1217 {
1218  sx=x;
1219  sy=y;
1220  drawchar(sx,sy,0xc);
1221 }
1222 void UparOn(int x,int y)
1223 {
1224  sx=x;
1225  sy=y;
1226  xormask=1;
1227  drawchar(sx,sy,0xb);
1228  xormask=0;
1229 }
1230 void UparOff(int x,int y)
1231 {
1232  sx=x;
1233  sy=y;
1234  drawchar(sx,sy,0xb);
1235 }
1236 void ExitOn(int x,int y)
1237 {
1238  sx=x;
1239  sy=y;
1240  xormask=1;
1241  print(" Exit ");
1242  xormask=0;
1243 }
1244 void ExitOff(int x,int y)
1245 {
1246  sx=x;
1247  sy=y;
1248  print(" Exit ");
1249 }
1250
1251 //
1252 // Highlight Map Name
1253 //
1254 void MNameOn(int x,int y,int i)
1255 {
1256  xormask=1;
1257  MNameOff(x,y,i);
1258  xormask=0;
1259 }
1260
1261 //
1262 // De-Highlight Map Name
1263 //
1264 void MNameOff(int x,int y,int i)
1265 {
1266  MapHeaderStr TempMapHeader;
1267
1268  sx=x;
1269  sy=y;
1270  if (MapFileHeader->dataoffsets[i+smbase]!=-1)
1271    {
1272     print("                   ");
1273     sx=x;
1274     print(MapNames[i+smbase]);
1275    }
1276  else
1277    print("--not created yet--");
1278 }
1279
1280
1281
1282 ////////////////////////////////////////////////////
1283 //
1284 // Pick more planes for the map set
1285 //
1286 ////////////////////////////////////////////////////
1287 btype PickPlaneb[]={{"X",1,3,1},
1288                     {"X",1,6,1},
1289                     {" Done ",1,9,2}};
1290 DialogDef PickPlaneD={"Which other planes\n"
1291                      "to enable?\n\n"
1292                      "    Foreground\n\n\n"
1293                      "    Information"
1294                      ,18,11,3,&PickPlaneb[0],NULL};
1295
1296 int PickMorePlanes(void)
1297 {
1298  int which;
1299  char planes=7; // 1=bkgnd/2=frgnd/4=info
1300
1301  DrawDialog(&PickPlaneD,1);
1302  do
1303  {
1304   which=CheckButtons(&PickPlaneD);
1305   switch(which)
1306   {
1307    case 0:
1308      RestoreBackground();
1309      return 1;
1310    case 1:
1311      GetButtonXY(&PickPlaneD,0,&sx,&sy);
1312      planes^=2;
1313      MouseHide();
1314      if (planes&2)
1315        print("X");
1316      else
1317        print(" ");
1318      MouseShow();
1319      break;
1320    case 2:
1321      GetButtonXY(&PickPlaneD,1,&sx,&sy);
1322      planes^=4;
1323      MouseHide();
1324      if (planes&4)
1325        print("X");
1326      else
1327        print(" ");
1328      MouseShow();
1329   }
1330  } while(which!=3);
1331
1332  RestoreBackground();
1333  MapFileHeader->maptype=planes;
1334  return 0;
1335 }
1336
1337 ////////////////////////////////////////////////////
1338 //
1339 // Get map dimensions
1340 //
1341 ////////////////////////////////////////////////////
1342 btype LvlSpecb[]={{"                  ",1,3,1},
1343                   {"                  ",1,7,1},
1344                   {"                  ",1,11,1},
1345                   {" Done ",7,14,2}};
1346 DialogDef LvlSpec={"   MAP DIMENSIONS\n"
1347                    " Map Name:\n\n\n\n"
1348                    " Map Width:\n\n\n\n"
1349                    " Map Height:\n",
1350                    20,16,4,&LvlSpecb[0],NULL};
1351
1352 void InputMap(char *lvlname,unsigned *levelw,unsigned *levelh,int exitok)
1353 {
1354  unsigned butn,ok=0,nameok=0,widok=0,heightok=0,
1355      ox,oy,width=0,height=0,oldwidth=0,oldheight=0;
1356  char oldname[16]="",name[16]="";
1357
1358  MouseHide();
1359  DrawDialog(&LvlSpec,1);
1360  GetButtonXY(&LvlSpec,1,&sx,&sy);
1361  printint(width);
1362  GetButtonXY(&LvlSpec,2,&sx,&sy);
1363  printint(height);
1364  MouseShow();
1365
1366  //
1367  // START INPUT IMMEDIATELY
1368  //
1369  butn=1;
1370  goto firsttime;
1371
1372 #pragma warn -rch
1373  while (!ok)
1374 #pragma warn +rch
1375  {
1376   butn=CheckButtons(&LvlSpec);
1377   if (!butn)
1378      if (exitok)
1379       {
1380        RestoreBackground();
1381        lvlname[0]=0;
1382        return;
1383       }
1384      else
1385       continue;
1386
1387 firsttime:
1388
1389   xormask=0;
1390   GetButtonXY(&LvlSpec,butn-1,&sx,&sy);
1391   MouseHide();
1392   ox=sx;
1393   oy=sy;
1394   print(LvlSpecb[butn-1].text);
1395   sx=ox;
1396   sy=oy;
1397   switch(butn)
1398   {
1399    case 1:
1400      name[0]=0;
1401      if (!input(name,15))
1402        {
1403         strcpy(name,oldname);
1404         sx=ox;
1405         sy=oy;
1406         print(LvlSpecb[butn-1].text);
1407        }
1408      strcpy(oldname,name);
1409      sx=ox;
1410      sy=oy;
1411      if (name[0])
1412                  {
1413         print(name);
1414         nameok=1;
1415        }
1416      else
1417        nameok=0;
1418
1419      if (nameok)
1420        {
1421         butn=2;
1422         GetButtonXY(&LvlSpec,butn-1,&sx,&sy);
1423         ox=sx;
1424         oy=sy;
1425         print(LvlSpecb[butn-1].text);
1426         sx=ox;
1427         sy=oy;
1428        }
1429      else
1430      break;
1431
1432    case 2:
1433      width=0;
1434      if ((width=inputint(9))==ESCOUT)
1435        {
1436         widok=0;
1437         width=oldwidth;
1438        }
1439      if (width)
1440        widok=1;
1441
1442      oldwidth=width;
1443      sx=ox;
1444      sy=oy;
1445      print(LvlSpecb[butn-1].text);
1446           sx=ox;
1447      sy=oy;
1448      printint(width);
1449      if (widok)
1450        {
1451         butn=3;
1452         GetButtonXY(&LvlSpec,butn-1,&sx,&sy);
1453         ox=sx;
1454         oy=sy;
1455         print(LvlSpecb[butn-1].text);
1456         sx=ox;
1457         sy=oy;
1458        }
1459      else
1460      break;
1461
1462    case 3:
1463      height=0;
1464      if ((height=inputint(9))==ESCOUT)
1465        {
1466         heightok=0;
1467         height=oldheight;
1468        }
1469      if (height)
1470        heightok=1;
1471
1472      oldheight=height;
1473      sx=ox;
1474      sy=oy;
1475      print(LvlSpecb[butn-1].text);
1476      sx=ox;
1477      sy=oy;
1478      printint(height);
1479      break;
1480
1481    case 4:
1482      if (2L*height*width>0x10000)       // TOO BIG! TRIM IT!
1483        {
1484         errsound();
1485         errsound();
1486         widok=heightok=0;
1487         break;
1488        }
1489      if (nameok && widok && heightok)
1490        ok=1;
1491   }
1492
1493   MouseShow();
1494  }
1495
1496  RestoreBackground();
1497
1498  *levelw=width;
1499  *levelh=height;
1500  strcpy(lvlname,name);
1501 }
1502
1503 ////////////////////////////////////////////////////
1504 //
1505 // Item - Input INFOPLANE value
1506 //
1507 ////////////////////////////////////////////////////
1508 btype EnterIVb={"          ",1,3,1};
1509 DialogDef EnterIV={"Enter a value for\nthe INFO plane:\n\n\n",18,5,1,&EnterIVb,NULL};
1510
1511 void Item_InputInfoplane(void)
1512 {
1513  unsigned val;
1514
1515
1516  if (TsearchMode || BfillMode || FillMode || PasteMode || SelectMode)
1517    return;
1518
1519  clearkeys();
1520  DrawDialog(&EnterIV,1);
1521  MouseHide();
1522  GetButtonXY(&EnterIV,0,&sx,&sy);
1523  if ((val=inputint(9))!=ESCOUT)
1524    whichi=val+tilenum;
1525  RestoreBackground();
1526  DrawInfoBar();
1527  MouseShow();
1528 }
1529
1530 ////////////////////////////////////////////////////
1531 //
1532 // Item - Select Tile
1533 //
1534 ////////////////////////////////////////////////////
1535 void Item_SelectTile(void)
1536 {
1537  SelectTiles(0);
1538 }
1539
1540 ////////////////////////////////////////////////////
1541 //
1542 // Item - Block Fill
1543 //
1544 ////////////////////////////////////////////////////
1545 void Item_BlockFill(void)
1546 {
1547  ZeroModes();
1548  BfillMode=1;
1549  DrawInfoBar();
1550 }
1551
1552 //
1553 // DO THE ACTUAL BLOCK FILL
1554 //
1555 void DoBlockFill(void)
1556 {
1557  unsigned loc,i,j,ctrl=0,newt,newm,newi,tton,tmon,tion,from;
1558
1559  if (keydown[0x1d])
1560    ctrl++;
1561
1562  MouseHide();
1563
1564  CopyUndoRegion();
1565  UndoRegion.x=SelX1;
1566  UndoRegion.y=SelY1;
1567  UndoRegion.w=SelX2-SelX1+1;
1568  UndoRegion.h=SelY2-SelY1+1;
1569
1570  if (ctrl)
1571    {
1572     for (j=SelY1;j<=SelY2;j++)
1573       for (i=SelX1;i<=SelX2;i++)
1574         {
1575          loc=j*mapwidth+i;
1576          from=(TileCopy.y+((j-SelY1)%TileCopy.h))*mapwidth+
1577               TileCopy.x+((i-SelX1)%TileCopy.w);
1578
1579          switch(TileCopy.MapOrTileSelect)
1580          {
1581           case 0: // COPY BUFFER
1582                  tton=TileCopy.PlanesCopied&BPLANE;
1583             tmon=TileCopy.PlanesCopied&FPLANE;
1584             tion=TileCopy.PlanesCopied&IPLANE;
1585
1586             newt=CutBkgnd[from];
1587             newm=CutFrgnd[from];
1588             newi=CutInfoPl[from];
1589
1590             break;
1591           case 1: // TILES
1592             tton=1;
1593             tmon=tion=0;
1594
1595             newt=((j%TileCopy.h)+TileCopy.y)*selectcols+
1596                  TileCopy.x+(i%TileCopy.w);
1597             if (XMSlookup[newt]<0)
1598               tton=0;
1599             break;
1600           case 2: // MASKED
1601             tton=tion=0;
1602             tmon=1;
1603
1604             newm=((j%TileCopy.h)+TileCopy.y)*selectcols+
1605                  TileCopy.x+(i%TileCopy.w)+tilenum+maxiconrows*selectcols;
1606             if (XMSlookup[newm]<0)
1607               tmon=0;
1608             else
1609               newm-=tilenum;
1610          }
1611
1612          if (tton)
1613            *(MapBkgnd+loc)=newt;
1614          if (tmon)
1615            *(MapFrgnd+loc)=newm;
1616          if (tion)
1617            *(MapInfoPl+loc)=newi;
1618
1619          if (j>=ybase && j<ybase+screenh &&
1620              i>=xbase && i<xbase+screenw)
1621            {
1622             int tempt,tempm,tempi;
1623
1624             tempt=*(MapBkgnd+loc);
1625             tempm=*(MapFrgnd+loc)+tilenum;
1626             tempi=*(MapInfoPl+loc)+tilenum;
1627
1628             CombineTiles(viewton?tempt:-BkgndColor,viewmon*tempm,viewion*tempi,tsize);
1629             if (GridMode)
1630               Overlay(tsize);
1631             DrawTile((i-xbase)<<(tsize-1),((j-ybase)<<(tsize+2))+8,tsize);
1632            }
1633         }
1634    }
1635  else
1636    for (j=SelY1;j<=SelY2;j++)
1637      for (i=SelX1;i<=SelX2;i++)
1638        {
1639         loc=j*mapwidth+i;
1640
1641         if (planeton)
1642           *(MapBkgnd+loc)=whicht;
1643         if (planemon)
1644           *(MapFrgnd+loc)=whichtm-tilenum;
1645         if (planeion)
1646           *(MapInfoPl+loc)=whichi-tilenum;
1647
1648         if (j>=ybase && j<ybase+screenh &&
1649             i>=xbase && i<xbase+screenw)
1650           {
1651            int tempt,tempm,tempi;
1652
1653            tempt=*(MapBkgnd+loc);
1654            tempm=*(MapFrgnd+loc)+tilenum;
1655            tempi=*(MapInfoPl+loc)+tilenum;
1656
1657            CombineTiles(viewton?tempt:-BkgndColor,viewmon*tempm,viewion*tempi,tsize);
1658            if (GridMode)
1659              Overlay(tsize);
1660            DrawTile((i-xbase)<<(tsize-1),((j-ybase)<<(tsize+2))+8,tsize);
1661           }
1662        }
1663
1664  DirtyFlag=1;
1665  MouseShow();
1666 }
1667
1668
1669 ////////////////////////////////////////////////////
1670 //
1671 // Remove the XMS undo buffers
1672 //
1673 ////////////////////////////////////////////////////
1674 void RemoveUndoBuffers(void)
1675 {
1676  if (XMSundoB)
1677    XMSFreeMem(XMSundoB);
1678  if (XMSundoF)
1679    XMSFreeMem(XMSundoF);
1680  if (XMSundoI)
1681    XMSFreeMem(XMSundoI);
1682
1683  XMSundoB=XMSundoF=XMSundoI=0;
1684 }
1685
1686
1687 ////////////////////////////////////////////////////
1688 //
1689 // Allocate XMS undo buffers
1690 // NOTE: uses "mapwidth" & "mapheight"
1691 //
1692 ////////////////////////////////////////////////////
1693 void AllocateUndoBuffers(void)
1694 {
1695  long size=2L*mapwidth*mapheight;
1696
1697  if (MapFileHeader->maptype&BPLANE)
1698    XMSundoB=XMSAllocate(size);
1699  if (MapFileHeader->maptype&FPLANE)
1700    XMSundoF=XMSAllocate(size);
1701  if (MapFileHeader->maptype&IPLANE)
1702    XMSundoI=XMSAllocate(size);
1703 }
1704
1705
1706 ////////////////////////////////////////////////////
1707 //
1708 // Save Undo buffers
1709 //
1710 ////////////////////////////////////////////////////
1711 void SaveUndo(int x,int y,int w,int h)
1712 {
1713  unsigned hsize=w*2,j;
1714
1715  for (j=y;j<y+h;j++)
1716    {
1717     unsigned off=2*(j*mapwidth+x);
1718
1719     if (MapFileHeader->maptype&BPLANE)
1720       XMSmove(0,(long)MK_FP(MapBkgnd,off),XMSundoB,off,hsize);
1721     if (MapFileHeader->maptype&FPLANE)
1722       XMSmove(0,(long)MK_FP(MapFrgnd,off),XMSundoF,off,hsize);
1723     if (MapFileHeader->maptype&IPLANE)
1724       XMSmove(0,(long)MK_FP(MapInfoPl,off),XMSundoI,off,hsize);
1725    }
1726 }
1727
1728
1729 ////////////////////////////////////////////////////
1730 //
1731 // Restore Undo buffers
1732 //
1733 ////////////////////////////////////////////////////
1734 void RestoreUndo(void)
1735 {
1736  long size=2L*UndoRegion.w;
1737  unsigned j;
1738
1739  sound(2000);
1740  for (j=UndoRegion.y;j<UndoRegion.y+UndoRegion.h;j++)
1741    {
1742     unsigned loc=2*(j*mapwidth+UndoRegion.x);
1743
1744     if (MapFileHeader->maptype&BPLANE)
1745       XMSmove(XMSundoB,loc,0,(long)MK_FP(MapBkgnd,loc),size);
1746     if (MapFileHeader->maptype&FPLANE)
1747       XMSmove(XMSundoF,loc,0,(long)MK_FP(MapFrgnd,loc),size);
1748     if (MapFileHeader->maptype&IPLANE)
1749       XMSmove(XMSundoI,loc,0,(long)MK_FP(MapInfoPl,loc),size);
1750    }
1751
1752  nosound();
1753 }
1754
1755
1756 ////////////////////////////////////////////////////
1757 //
1758 // Copy the current UNDO region to the undo buffers
1759 //
1760 ////////////////////////////////////////////////////
1761 void CopyUndoRegion(void)
1762 {
1763  if (UndoRegion.x==-1)
1764         return;
1765
1766  SaveUndo(UndoRegion.x,UndoRegion.y,UndoRegion.w,UndoRegion.h);
1767 }
1768
1769
1770 ////////////////////////////////////////////////////
1771 //
1772 // Item - Undo
1773 //
1774 ////////////////////////////////////////////////////
1775 void Item_Undo(void)
1776 {
1777  if (UndoRegion.x==-1)
1778         {
1779          ErrDialog("You don't have anything to UNDO!"," Oh, yeah. ");
1780          return;
1781         }
1782
1783  RestoreUndo();
1784  DrawMap();
1785 }
1786
1787
1788 ////////////////////////////////////////////////////
1789 //
1790 // Item - Tile Search!
1791 //
1792 ////////////////////////////////////////////////////
1793 void Item_TileSearch(void)
1794 {
1795  int num=planeton+planemon+planeion;
1796
1797  ZeroModes();
1798  if (num>1)
1799         {
1800          ErrDialog("TILE SEARCH will only work\n"
1801                         "with ONE active plane! Make\n"
1802                         "sure that the tile you're\n"
1803                         "searching for is selected!"," OK ");
1804          return;
1805         }
1806
1807  TsearchMode=1;
1808  DrawInfoBar();
1809  DrawMap();
1810 }
1811
1812 ////////////////////////////////////////////////////
1813 //
1814 // Item - Launch
1815 //
1816 ////////////////////////////////////////////////////
1817 char tempparm[40];
1818
1819 void Item_Launch(void)
1820 {
1821  TempStruct LaunchInfo;
1822  char ename[64],*envstr[15],temp[40],temp1[40],temp2[40],tiname[14]="TEDINFO.TMP",i,j;
1823  long size;
1824  int  rottlaunch;
1825  int  startp;
1826  unsigned mx,my;
1827
1828
1829  rottlaunch=0;
1830  if (!TEDInfo->launchname[0])
1831         {
1832          ErrDialog("You didn't specify a launching\n"
1833                         "name on the command line? What\n"
1834                         "do I launch, Einstein? Geez!"," What a goober. ");
1835          return;
1836         }
1837
1838  //
1839  // Save the handles for all XMS memory so we don't
1840  // have to re-install this shit!
1841  //
1842  TEDInfo->OldCgaXMS=CgaXMS;
1843  TEDInfo->OldEgaXMS=EgaXMS;
1844  TEDInfo->OldVgaXMS=VgaXMS;
1845
1846  TEDInfo->OldCgaXMSsize=CgaXMSsize;
1847  TEDInfo->OldEgaXMSsize=EgaXMSsize;
1848  TEDInfo->OldVgaXMSsize=VgaXMSsize;
1849
1850  size=4L*(tilenum+tilemnum);
1851  if (CgaXMS)
1852         {
1853          if (1024L*XMSTotalFree()<size)
1854                 {
1855                  XMSFreeMem(CgaXMS);
1856                  TEDInfo->OldCgaXMS=TEDInfo->OldCgaXMSsize=0;
1857                 }
1858          else
1859                 {
1860                  TEDInfo->CgaXMSlook=XMSAllocate(size);
1861                  XMSmove(0,(long)MK_FP(CgaXMSlookup,0),TEDInfo->CgaXMSlook,0,size);
1862                 }
1863         }
1864
1865  if (EgaXMS)
1866         {
1867          if (1024L*XMSTotalFree()<size)
1868                 {
1869                  XMSFreeMem(EgaXMS);
1870                  TEDInfo->OldEgaXMS=TEDInfo->OldEgaXMSsize=0;
1871                 }
1872          else
1873                 {
1874                  TEDInfo->EgaXMSlook=XMSAllocate(size);
1875                  XMSmove(0,(long)MK_FP(EgaXMSlookup,0),TEDInfo->EgaXMSlook,0,size);
1876                 }
1877         }
1878
1879  if (VgaXMS)
1880         {
1881          if (1024L*XMSTotalFree()<size)
1882                 {
1883                  XMSFreeMem(VgaXMS);
1884                  TEDInfo->OldVgaXMS=TEDInfo->OldVgaXMSsize=0;
1885                 }
1886          else
1887                 {
1888                  TEDInfo->VgaXMSlook=XMSAllocate(size);
1889                  XMSmove(0,(long)MK_FP(VgaXMSlookup,0),TEDInfo->VgaXMSlook,0,size);
1890                 }
1891         }
1892
1893  //
1894  // SAVE CURRENT VIDEOMODE FOR LAUNCH RETURN
1895  //
1896  LaunchInfo.lastmode=videomode;
1897  strcpy(LaunchInfo.ext,ext);
1898  SaveFile(tiname,(char huge *)&LaunchInfo,0,sizeof(TempStruct));
1899
1900  //
1901  // ICON CHANGE ON LAUNCH?
1902  //
1903  if (keydown[0x2A])
1904          {
1905          rottlaunch=1;
1906          startp=5;
1907          mx=xbase+(pixelx>>(tsize+2));
1908          my=ybase+((pixely-8)>>(tsize+2));
1909          }
1910  else
1911          startp=3;
1912  if (pixely>=8 && pixely<infoy*8 && TEDInfo->permicon
1913           && MapFileHeader->maptype&IPLANE && !usingbat && keydown[0x1d])
1914         {
1915          unsigned i,j;
1916
1917          mx=xbase+(pixelx>>(tsize+2));
1918          my=ybase+((pixely-8)>>(tsize+2));
1919
1920          for (j=0;j<mapheight;j++)
1921                 for (i=0;i<mapwidth;i++)
1922         if (MapInfoPl[j*mapwidth+i]==TEDInfo->permicon)
1923           {
1924                 MapInfoPl[j*mapwidth+i]=0;
1925                 TEDInfo->lastx=i;
1926                 TEDInfo->lasty=j;
1927                 break;
1928           }
1929
1930          MapInfoPl[my*mapwidth+mx]=TEDInfo->permicon;
1931          DrawMap();
1932          DirtyFlag=1;
1933         }
1934
1935  TEDInfo->oscrx=xbase;
1936  TEDInfo->oscry=ybase;
1937  TEDInfo->pflags=((planeton&1)<<6)|
1938                  ((planemon&1)<<5)|
1939                  ((planeion&1)<<4)|
1940                  ((viewton&1)<<2)|
1941                  ((viewmon&1)<<1)|
1942                  (viewion&1);
1943
1944  _fmemcpy((void far *)TEDInfo->parmstring,(void far *)parmstring,64);
1945
1946  Item_SaveMap();
1947  SaveTEDInfo();
1948  SaveOutputHeader();
1949
1950  if (XMSmaps)
1951         XMSFreeMem(XMSmaps);
1952
1953  strcpy(temp,"Launching ");
1954  _fstrcat((char far *)temp,(char far *)TEDInfo->launchname);
1955  strcat(temp,"...");
1956  ErrDialog(temp,"");
1957  clearkeys();
1958  nosound();
1959  MouseHide();
1960
1961  _fmemcpy((char far *)ename,(char far *)TEDInfo->launchname,14);
1962
1963  envstr[0] = ename;
1964  envstr[1] = "/TEDLEVEL";
1965  itoa(whichmap,temp,10);
1966  envstr[2] = temp;
1967  if (rottlaunch)
1968          {
1969          itoa(mx,temp1,10);
1970          envstr[3] = temp1;
1971          itoa(my,temp2,10);
1972          envstr[4] = temp2;
1973          }
1974  //
1975  // CHOP UP THE PARMSTRING FOR 'EXECV'
1976  //
1977  strcpy(tempparm,parmstring);
1978  envstr[startp]=&tempparm[0];
1979  for(j=startp+1,i=0;i<strlen(tempparm);i++)
1980         if (tempparm[i]==' ')
1981         {
1982          envstr[j]=&tempparm[i+1];
1983          tempparm[i]=0;
1984          j++;
1985         }
1986  envstr[j]=0;
1987
1988  RemoveUndoBuffers();
1989  ShutdownKBD();
1990
1991  //
1992  // ARE WE EXITING WITH A BATCH FILE?
1993  //
1994
1995  if (usingbat)
1996         {
1997          setvideo(TEXT);
1998          exit(whichmap+2);
1999    }
2000
2001  fcloseall();
2002  MMShutdown();
2003  execv(ename,envstr);
2004
2005  SetupKBD();
2006  RestoreBackground();
2007  MouseShow();
2008  ErrDialog("LAUNCHing failed. TED5 will\n"
2009            "now restart."," I have gubs ");
2010  ShutdownKBD();
2011  execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL);
2012
2013  printf("Couldn't find TED5 for some reason!");
2014  exit(1);
2015 }
2016
2017
2018 ////////////////////////////////////////////////////
2019 //
2020 // Item - TILEINFO Copy
2021 //
2022 ////////////////////////////////////////////////////
2023 DialogDef TICd=
2024 {"TILEINFOM Copy Kludge\n\n"
2025  "From:\n"
2026  "  To:\n"
2027  "Rows:",22,6};
2028
2029
2030 void Item_TINFOCopy(void)
2031 {
2032  unsigned dx,dy,i,from,to,amt;
2033  memptr block;
2034
2035
2036  MouseHide();
2037  DrawDialog(&TICd,1);
2038  GetDialogXY(&TICd,&dx,&dy);
2039
2040
2041  sx=dx+5;
2042  sy=dy+2;
2043  from=inputint(9);
2044  if (from==ESCOUT)
2045  {
2046   RestoreBackground();
2047   MouseShow();
2048   return;
2049  }
2050
2051
2052  sx=dx+5;
2053  sy=dy+3;
2054  to=inputint(9);
2055  if (to==ESCOUT)
2056  {
2057   RestoreBackground();
2058   MouseShow();
2059   return;
2060  }
2061
2062
2063  sx=dx+5;
2064  sy=dy+4;
2065  amt=inputint(9);
2066  if (amt==ESCOUT)
2067  {
2068   RestoreBackground();
2069   MouseShow();
2070   return;
2071  }
2072  amt*=18;
2073
2074
2075  MMAllocate(&block,amt);
2076
2077  for (i=0;i<numtmplanes;i++)
2078  {
2079   movedata((unsigned)TMinfo[i],from,(unsigned)block,0,amt);
2080   movedata((unsigned)block,0,(unsigned)TMinfo[i],to,amt);
2081  }
2082
2083  MMFreePtr(&block);
2084  RestoreBackground();
2085  DirtyFlag=writeH=1;
2086
2087
2088  MouseShow();
2089 }