]> 4ch.mooo.com Git - 16.git/blob - 16/ted5/TED5-2.C
ted5 added
[16.git] / 16 / ted5 / TED5-2.C
1 ////////////////////////////////////////////////////
2 ////////////////////////////////////////////////////
3 //
4 // TED5-2 : Menu Item Routines
5 //
6 ////////////////////////////////////////////////////
7 ////////////////////////////////////////////////////
8 #include "ted5.h"
9 #pragma hdrstop
10
11 ////////////////////////////////////////////////////
12 //
13 // Toggle the INFOBAR on and off
14 //
15 ////////////////////////////////////////////////////
16 void Item_ToggleInfo(void)
17 {
18  infobaron^=1;
19  MouseHide();
20  InitDesktop(TED5MenuBar,0);
21  FigureScreenEdges();
22  if (ybase+screenh>mapheight && mapheight>screenh)
23    ybase--;
24  DrawMap();
25  DrawInfoBar();
26  MouseShow();
27 }
28
29
30 ////////////////////////////////////////////////////
31 //
32 // Tile Select
33 //
34 ////////////////////////////////////////////////////
35 btype SelTb[]={{" Tiles ",2,21,1},
36                {" Masked ",11,21,1},
37                {" Icons ",21,21,1},
38                {" Exit ",30,21,2}};
39 DialogDef SelTd={"",38,23,4,&SelTb[0],NULL};
40
41 void SelectTiles(int screen)
42 {
43  int exitok=0,which,i,numrows,numcols,b0,b1,redraw=0;
44
45  //
46  // if parameter passed, change the screen
47  //
48  if (screen)
49    whichscreen=screen-1;
50
51  if (PasteMode || SelectMode)   // RE-BLIT MAP IF WE ARE ENTERING WHILE
52    redraw=1;                    // FLOATING AN IMAGE
53
54  PasteMode=SelectMode=0;
55  SelX1=SelX2=SelY1=SelY2=-1;
56
57  switch(videomode)
58  {
59   case CGA:
60   case EGA1:
61   case VGA:
62          SelTd.height=23;
63     for(i=0;i<4;i++)
64       SelTb[i].yoff=21;
65     break;
66   case EGA2:
67     SelTd.height=58;
68     for(i=0;i<4;i++)
69       SelTb[i].yoff=56;
70  }
71
72  DrawDialog(&SelTd,1);
73  DrawTileSelect(0,&numrows,&numcols);
74  selectcols=numcols;    // VERY IMPORTANT TO PASTE-FROM-TILESELECT MODE
75  DrawCurrentTiles();
76  while(keydown[0x39]);  // WAIT FOR SPACE-UP
77
78  do
79  {
80   which=CheckButtonsRet(&SelTd);
81   b0=MouseButton()&1;
82   b1=(MouseButton()>>1)&1;
83
84   if (which<0)
85     {
86      //
87      // GRAB CURRENT TILE FROM MATRIX
88      //
89      if (b0 || b1)
90        {
91         int mx,my;
92
93         MouseCoords(&mx,&my);
94         mx/=8;
95         if (mx>=left && mx<left+(numcols<<(tsize-1)) &&
96             my>=16 && my<=16+(numrows<<(2+tsize)))
97           {
98            int tile;
99
100            tile=((my-16)>>(tsize+2))*numcols+
101                 ((mx-left)>>(tsize-1));
102
103            if (SelectMode)
104              {
105               int thebase;
106               switch(whichscreen)
107                         {
108                case TILES: thebase=tilebase/numcols; break;
109                case MASKED: thebase=tilembase/numcols;
110               }
111
112               if (b0)
113                 {
114                  sound(1000);
115                  SelY1=((my-16)>>(tsize+2))+thebase;
116                  SelX1=((mx-left)>>(tsize-1));
117                  if (SelX2==-1 && SelY2==-1)
118                    {
119                     SelX2=SelX1;
120                     SelY2=SelY1;
121                    }
122                  DrawTileSelect(0,&numrows,&numcols);
123                  nosound();
124                 }
125               else
126               if (b1)
127                 {
128                  sound(1000);
129                  SelY2=((my-16)>>(tsize+2))+thebase;
130                  SelX2=((mx-left)>>(tsize-1));
131                  if (SelX1==-1 && SelY1==-1)
132                    {
133                     SelX1=SelX2;
134                     SelY1=SelY2;
135                    }
136                  DrawTileSelect(0,&numrows,&numcols);
137                  nosound();
138                 }
139              }
140            else
141              {
142               switch(whichscreen)
143               {
144                case TILES:
145                  if (XMSlookup[tile+tilebase]>=0)
146                    whicht=tile+tilebase;
147                  else
148                    errsound();
149                  break;
150                case MASKED:
151                  whichtm=tile+tilembase+numcols*maxiconrows+tilenum;
152                  if (XMSlookup[whichtm]==-1)
153                    whichtm=tilenum;
154                  break;
155                case ICONS:
156                  if (XMSlookup[tile+tilenum]>=0 || !tile)
157                    whichi=tile+tilenum;
158                  else
159                    errsound();
160                  break;
161               }
162               DrawCurrentTiles();
163              }
164           }
165        }
166
167      if (keydown[0x48])                 // UP
168        DrawTileSelect(-1,&numrows,&numcols);
169      else
170      if (keydown[0x50])                 // DOWN
171        DrawTileSelect(1,&numrows,&numcols);
172      else
173      if (keydown[0x47])                 // HOME
174        {
175         if (whichscreen==TILES)
176           DrawTileSelect(-tilebase/numcols,&numrows,&numcols);
177         else
178         if (whichscreen==MASKED)
179           DrawTileSelect(-tilembase/numcols,&numrows,&numcols);
180        }
181      else
182      if (keydown[0x4f])                 // END
183        {
184         if (whichscreen==TILES)
185           DrawTileSelect(tilenum,&numrows,&numcols);
186         else
187         if (whichscreen==MASKED)
188           DrawTileSelect(tilemnum,&numrows,&numcols);
189        }
190      else
191      if (keydown[0x49])                 // PgUP
192        {
193         DrawTileSelect(-numrows,&numrows,&numcols);
194         if (!keydown[0x1d])     // if not CTRL down, wait for keyup
195           while(keydown[0x49]);
196        }
197           else
198      if (keydown[0x51])                 // PgDN
199        {
200         DrawTileSelect(numrows,&numrows,&numcols);
201         if (!keydown[0x1d])     // if not CTRL down, wait for keyup
202           while(keydown[0x51]);
203        }
204      else
205      if (keydown[0x39])                 // SPACEBAR
206        {
207         RestoreBackground();
208         while(keydown[0x39]);
209         SelectMode=0;
210         if (redraw)
211           DrawMap();
212         DrawInfoBar();
213         return;
214        }
215      else                               // 'C' TO COPY
216      if (keydown[0x2e] && (whichscreen==TILES || whichscreen==MASKED))
217        {
218         char temp[]="COPY MODE";
219
220         sx=screencenterx-strlen(temp)/2;
221         SelectMode=sy=1;
222         print(temp);
223
224         while(keydown[0x2e]);
225        }
226     }
227   else
228     switch(which)
229     {
230      case 0:
231        if (!SelectMode)
232          exitok=1;
233        else
234          {
235           char temp[]="         ";
236
237           sx=screencenterx-strlen(temp)/2;
238           SelectMode=0;
239           SelX1=SelX2=SelY1=SelY2=-1;
240           sy=1;
241           print(temp);
242           DrawTileSelect(0,&numrows,&numcols);
243          }
244        break;
245
246      case 4:
247        if (!SelectMode)
248          exitok=1;
249        //
250        // 'ENTER' TO FINALIZE COPY
251        //
252        else
253          {
254           char temp[]="         ";
255
256           if (MouseButton())    // IF CLICKED ON 'EXIT' WITH MOUSE
257             break;
258
259           sound(500);
260           sx=screencenterx-strlen(temp)/2;
261           PasteOK=sy=1;
262           print(temp);
263
264           TileCopy.x=SelX1;
265           TileCopy.y=SelY1;
266           TileCopy.w=SelX2-SelX1+1;
267           TileCopy.h=SelY2-SelY1+1;
268           TileCopy.MapOrTileSelect=(whichscreen==TILES)+2*(whichscreen==MASKED);
269
270           while(keydown[0x1c]);
271           nosound();
272           SelectMode=0;
273           SelX1=SelX2=SelY1=SelY2=-1;
274           DrawTileSelect(0,&numrows,&numcols);
275          }
276        break;
277      //
278      // NORMAL TILE SELECT
279      //
280      case 1:
281        if (whichscreen!=TILES)
282          {
283           SelX1=SelX2=SelY1=SelY2=-1;
284           SelectMode=0;
285           whichscreen=TILES;
286           DrawDialog(&SelTd,0);
287           DrawCurrentTiles();
288           DrawTileSelect(0,&numrows,&numcols);
289          }
290        else
291          errsound();
292        GetButtonXY(&SelTd,0,&sx,&sy);
293        MouseHide();
294        print(SelTb[0].text);
295        MouseShow();
296        break;
297      //
298      // MASKED TILE SELECT
299      //
300      case 2:
301        if (tilemnum && whichscreen!=MASKED)
302          {
303           SelX1=SelX2=SelY1=SelY2=-1;
304           SelectMode=0;
305           whichscreen=MASKED;
306           DrawDialog(&SelTd,0);
307           DrawCurrentTiles();
308           DrawTileSelect(0,&numrows,&numcols);
309          }
310        else
311          errsound();
312        GetButtonXY(&SelTd,1,&sx,&sy);
313        MouseHide();
314        print(SelTb[1].text);
315        MouseShow();
316        break;
317      //
318      // ICON SELECT
319      //
320      case 3:
321        if (tilemnum && whichscreen!=ICONS)
322          {
323           whichscreen=ICONS;
324           DrawDialog(&SelTd,0);
325           DrawCurrentTiles();
326           DrawTileSelect(0,&numrows,&numcols);
327          }
328        else
329          errsound();
330        GetButtonXY(&SelTd,2,&sx,&sy);
331        MouseHide();
332                  print(SelTb[2].text);
333        MouseShow();
334     }
335
336  } while(!exitok);
337  RestoreBackground();
338  SelectMode=0;
339  SelX1=SelX2=SelY1=SelY2=-1;
340  DrawInfoBar();
341  if (redraw)
342    DrawMap();
343 }
344
345
346 //
347 // DRAW THE CURRENT TILES IN THE TILE-SELECT WINDOW
348 //
349 void DrawCurrentTiles(void)
350 {
351  MouseHide();
352  GetButtonXY(&SelTd,0,&sx,&sy);
353  sy-=1+tsize;
354  CombineTiles(whicht,0,0,tsize);
355  DrawTile(sx,sy*8,tsize);
356  sx+=2;
357  printhex(whicht);
358  sy++;
359  sx-=5;
360  printint(whicht);
361  print("   ");
362
363  if (tilemnum)
364    {
365     GetButtonXY(&SelTd,1,&sx,&sy);
366     sy-=1+tsize;
367     CombineTiles(-BkgndColor,whichtm,0,tsize);
368     DrawTile(sx,sy*8,tsize);
369     sx+=2;
370     (whichtm==tilenum)?print(" No  "):printhex(whichtm-tilenum);
371
372     sy++;
373     sx-=5;
374     (whichtm==tilenum)?print(" Tile "):printint(whichtm-tilenum);
375     print("    ");
376
377          GetButtonXY(&SelTd,2,&sx,&sy);
378     sy-=1+tsize;
379     CombineTiles(-ICONBACK,whichi,0,tsize);
380     DrawTile(sx,sy*8,tsize);
381     sx+=2;
382     (whichi==tilenum)?print(" No  "):printhex(whichi-tilenum);
383     sy++;
384     sx-=5;
385     (whichi==tilenum)?print(" Icon "):printint(whichi-tilenum);
386     print("    ");
387    }
388  MouseShow();
389 }
390
391
392 //
393 // CHECK TILESELECT EDGES
394 //
395 void CheckTSelectEdges(int x,int y,int basey)
396 {
397  int xx,yy,temp;
398
399  xx=left+(x<<(tsize-1));
400  yy=(y<<(tsize-1))+2;
401
402  if (SelX2<SelX1)
403    {
404     temp=SelX1;
405     SelX1=SelX2;
406     SelX2=temp;
407    }
408
409  if (SelY2<SelY1)
410    {
411     temp=SelY1;
412     SelY1=SelY2;
413     SelY2=temp;
414    }
415
416  if (x==SelX1 && y==SelY1-basey)
417    {
418     switch(tsize)
419     {
420      case 1: drawchar(xx,yy,1); return;
421      case 2: drawchar(xx  ,yy,1);
422                   drawchar(xx+1,yy,2);
423              drawchar(xx  ,yy+1,4);
424              break;
425      case 3: drawchar(xx,yy,1);
426
427              drawchar(xx,yy+1,4);
428              drawchar(xx,yy+2,4);
429              drawchar(xx,yy+3,4);
430
431              drawchar(xx+1,yy,2);
432              drawchar(xx+2,yy,2);
433              drawchar(xx+3,yy,2);
434
435              break;
436     }
437    }
438  if (x==SelX2 && y==SelY2-basey)
439    {
440     switch(tsize)
441     {
442      case 1: drawchar(xx,yy,8); return;
443      case 2: drawchar(xx+1,yy+1,8);
444              drawchar(xx+1,yy,5);
445              drawchar(xx,yy+1,7);
446              break;
447      case 3: drawchar(xx+3,yy+3,8);
448
449              drawchar(xx+3,yy  ,5);
450              drawchar(xx+3,yy+1,5);
451              drawchar(xx+3,yy+2,5);
452
453              drawchar(xx  ,yy+3,7);
454              drawchar(xx+1,yy+3,7);
455              drawchar(xx+2,yy+3,7);
456              break;
457     }
458    }
459  if (x==SelX2 && y==SelY1-basey)
460    {
461     switch(tsize)
462     {
463      case 1: drawchar(xx,yy,3); return;
464      case 2: drawchar(xx+1,yy,3);
465              drawchar(xx,yy,2);
466              drawchar(xx+1,yy+1,5);
467                   break;
468      case 3: drawchar(xx+3,yy,3);
469
470              drawchar(xx+2,yy,2);
471              drawchar(xx+1,yy,2);
472              drawchar(xx  ,yy,2);
473
474              drawchar(xx+3,yy+1,5);
475              drawchar(xx+3,yy+2,5);
476              drawchar(xx+3,yy+3,5);
477              break;
478     }
479    }
480  if (x==SelX1 && y==SelY2-basey)
481    {
482     switch(tsize)
483     {
484      case 1: drawchar(xx,yy,6); return;
485      case 2: drawchar(xx,yy+1,6);
486              drawchar(xx+1,yy+1,7);
487              drawchar(xx,yy,4);
488              break;
489      case 3: drawchar(xx,yy+3,6);
490
491              drawchar(xx  ,yy+2,4);
492              drawchar(xx  ,yy+1,4);
493              drawchar(xx  ,yy,4);
494
495              drawchar(xx+1,yy+3,7);
496              drawchar(xx+2,yy+3,7);
497              drawchar(xx+3,yy+3,7);
498              break;
499     }
500    }
501
502  if (x==SelX1 && y>SelY1-basey && y<SelY2-basey)
503    {
504     switch(tsize)
505     {
506      case 3: drawchar(xx,yy+3,4);
507              drawchar(xx,yy+2,4);
508      case 2: drawchar(xx,yy+1,4);
509      case 1: drawchar(xx,yy,4);
510              break;
511     }
512         }
513  else
514  if (y==SelY1-basey && x>SelX1 && x<SelX2)
515    {
516     switch(tsize)
517     {
518      case 3: drawchar(xx+3,yy,2);
519              drawchar(xx+2,yy,2);
520      case 2: drawchar(xx+1,yy,2);
521      case 1: drawchar(xx  ,yy,2);
522              break;
523     }
524    }
525  else
526  if (x==SelX2 && y>SelY1-basey && y<SelY2-basey)
527    {
528     switch(tsize)
529     {
530      case 1: drawchar(xx,yy,5); return;
531      case 2: drawchar(xx+1,yy,5);
532              drawchar(xx+1,yy+1,5);
533              break;
534      case 3: drawchar(xx+3,yy,5);
535              drawchar(xx+3,yy+1,5);
536              drawchar(xx+3,yy+2,5);
537              drawchar(xx+3,yy+3,5);
538              break;
539     }
540    }
541  else
542  if (y==SelY2-basey && x>SelX1 && x<SelX2)
543    {
544     switch(tsize)
545     {
546      case 1: drawchar(xx,yy,7); return;
547      case 2: drawchar(xx  ,yy+1,7);
548              drawchar(xx+1,yy+1,7);
549              break;
550      case 3: drawchar(xx  ,yy+3,7);
551              drawchar(xx+1,yy+3,7);
552              drawchar(xx+2,yy+3,7);
553              drawchar(xx+3,yy+3,7);
554              break;
555     }
556    }
557 }
558
559
560
561 //
562 // FILL THE TILE SELECT SCREEN WITH TILES
563 //
564 void DrawTileSelect(int deltarow,int *retrows,int *retcols)
565 {
566  char tile[32*32];
567  int numcols,numrows,i,j;
568
569  MouseHide();
570  switch(videomode)
571  {
572   case CGA:
573   case EGA1:
574   case VGA:
575     numrows=18-10*(tsize==2)-15*(tsize==3);
576     left=2;
577     break;
578   case EGA2:
579     numrows=49-23*(tsize==2)-34*(tsize==3);
580     left=22;
581  }
582
583  switch(tsize)
584  {
585   case 1: numcols=36; break;
586   case 2: numcols=18; break;
587   case 3: numcols=9;
588  }
589
590  if (whichscreen==TILES && tilebase+numrows*numcols>tilenum)
591    {
592     tilebase=0;
593     numrows=tilenum/numcols;
594    }
595
596  if (whichscreen==MASKED && tilembase+numrows*numcols>tilemnum-maxiconrows*numcols)
597    {
598     tilembase=0;
599     numrows=tilemnum/numcols-maxiconrows;
600    }
601
602  if (whichscreen==ICONS && numrows*numcols>maxiconrows*numcols)
603    {
604     tilembase=0;
605     numrows=maxiconrows;
606    }
607
608  switch((deltarow<0?-1:deltarow>0?1:0))
609  {
610   case -1:
611    switch(whichscreen)
612    {
613     case TILES:
614       tilebase+=deltarow*numcols;
615       if (tilebase<0)
616         tilebase=0;
617       break;
618     case MASKED:
619       tilembase+=deltarow*numcols;
620       if (tilembase<0)
621         tilembase=0;
622    }
623    break;
624   case 1:
625    switch(whichscreen)
626    {
627     case TILES:
628       tilebase+=deltarow*numcols;
629       if (tilebase+numrows*numcols>tilenum)
630         tilebase=tilenum-numcols*numrows;
631       break;
632     case MASKED:
633       tilembase+=deltarow*numcols;
634       if (tilembase+numrows*numcols>tilemnum-maxiconrows*numcols)
635         tilembase=(tilemnum-maxiconrows*numcols)-numcols*numrows;
636    }
637  }
638
639  switch(whichscreen)
640  {
641   case TILES:
642     for(j=0;j<numrows;j++)
643       for(i=0;i<numcols;i++)
644       {
645        CombineTiles(tilebase+j*numcols+i,0,0,tsize);
646        if (GridMode)
647          Overlay(tsize);
648        DrawTile(i*2+left,j*16+16,tsize);
649        CheckTSelectEdges(i,j,tilebase/numcols);
650       }
651     break;
652
653   case MASKED:
654     for(j=0;j<numrows;j++)
655       for(i=0;i<numcols;i++)
656       {
657        CombineTiles(-BkgndColor,tilenum+numcols*maxiconrows+tilembase+j*numcols+i,0,tsize);
658        if (GridMode)
659          Overlay(tsize);
660        DrawTile(i*2+left,j*16+16,tsize);
661        CheckTSelectEdges(i,j,tilembase/numcols);
662       }
663     break;
664
665   default:
666     for(j=0;j<numrows;j++)
667       for(i=0;i<numcols;i++)
668       {
669        CombineTiles(-ICONBACK,tilenum+j*numcols+i,0,tsize);
670        if (GridMode)
671          Overlay(tsize);
672        DrawTile(i*2+left,j*16+16,tsize);
673       }
674  }
675  MouseShow();
676
677  *retrows=numrows;
678  *retcols=numcols;
679 }
680
681
682
683 void errsound(void)
684 {
685  sound(1000);
686  delay(50);
687  nosound();
688 }
689
690
691 ////////////////////////////////////////////////////
692 //
693 // Item - About
694 //
695 ////////////////////////////////////////////////////
696 void Item_About(void)
697 {
698  char dstr[200]=IDSTSTR;
699
700  strcat(dstr,"\n\n   IdWare by John Romero\n");
701  strcat(dstr,"        ");
702  strcat(dstr,__DATE__);
703  strcat(dstr,"\n    (C)1991 Id Software\n\n"
704              " DeluxePaint for Tile Maps! ");
705
706  ErrDialog(dstr," OK ");
707 }
708
709 ////////////////////////////////////////////////////
710 //
711 // Item - Video Mode Switch
712 //
713 ////////////////////////////////////////////////////
714 btype VMS1b[]={{" CGA 320x200 ",5,2,1},
715                {" EGA 320x200 ",5,5,1},
716                          {" EGA 640x350 ",5,8,1},
717                {" VGA 320x200 ",5,11,1}};
718 DialogDef VMS1d={"Select the resolution:",22,14,4,&VMS1b[0],NULL};
719
720 void Item_ModeSwitch(void)
721 {
722  int i,which,rtn;
723
724  for(i=0;i<VMS1d.numbuttons;i++)
725    {
726     VMS1b[i].border=1;
727     if (i==lastvideo)
728       VMS1b[i].border=2;
729    }
730
731 // which=DoDialog(&VMS1d);
732  //
733  // Keep track of last video mode!
734  //
735  if (videomode==EGA1)
736          {
737          which=3;
738          lastvideo=videomode;
739          }
740  else
741          {
742          which=2;
743          lastvideo=videomode;
744          }
745
746  MouseHide();
747  switch(which)
748  {
749   case 0:
750          MouseShow();
751          return;
752   case 1:
753          if (!CgaXMS)
754                 {
755                  rtn=LoadGraphStuff(1,CGA);
756                  if (!rtn)
757          {
758           MouseShow();
759           ErrDialog("There aren't any CGA\n"
760                          "graphics files available!"," OK ");
761           return;
762          }
763                  if (rtn<0)
764          return;
765                  MouseShow();
766                 }
767          else
768                 {
769                  xmshandle=CgaXMS;
770                  XMSlookup=CgaXMSlookup;
771                 }
772          setvideo(CGA);
773          break;
774   case 2:
775          if (!EgaXMS)
776                 {
777                  rtn=LoadGraphStuff(1,EGA1);
778                  if (!rtn)
779          {
780           MouseShow();
781           ErrDialog("There aren't any EGA\n"
782                          "graphics files available!"," OK ");
783           return;
784          }
785                  if (rtn<0)
786          return;
787                  MouseShow();
788                 }
789          else
790       {
791        xmshandle=EgaXMS;
792        XMSlookup=EgaXMSlookup;
793       }
794     setvideo(EGA1);
795     break;
796   case 3:
797     if (!EgaXMS)
798       {
799        rtn=LoadGraphStuff(1,EGA1);
800        if (!rtn)
801          {
802           MouseShow();
803           ErrDialog("There aren't any EGA\n"
804                     "graphics files available!"," OK ");
805           return;
806          }
807        if (rtn<0)
808          return;
809        MouseShow();
810       }
811     else
812       {
813        xmshandle=EgaXMS;
814        XMSlookup=EgaXMSlookup;
815       }
816     setvideo(EGA2);
817     break;
818   case 4:
819     if (!VgaXMS)
820       {
821        rtn=LoadGraphStuff(1,VGA);
822        if (!rtn)
823          {
824           MouseShow();
825           ErrDialog("There aren't any VGA\n"
826                     "graphics files available!"," OK ");
827           return;
828          }
829        if (rtn<0)
830          return;
831        MouseShow();
832                 }
833          else
834       {
835        xmshandle=VgaXMS;
836        XMSlookup=VgaXMSlookup;
837       }
838     setvideo(VGA);
839  }
840
841  InitDesktop(TED5MenuBar,0);
842  DrawInfoBar();
843  FigureScreenEdges();
844
845  if (xbase+screenw>mapwidth)
846    xbase=mapwidth-screenw;
847  if (mapwidth<screenw)
848    xbase=0;
849  if (ybase+screenh>mapheight)
850    ybase=mapheight-screenh;
851  if (mapheight<screenh)
852    ybase=0;
853
854  DrawMap();
855  MouseShow();
856 }
857
858 ////////////////////////////////////////////////////
859 //
860 // Item - Map Stats
861 //
862 ////////////////////////////////////////////////////
863 btype MapStatsb={" OK ",11,11,2};
864 DialogDef MapStatsd={"        MAP STATS\n\n"
865                      "Width   :\n"
866                      "Height  :\n"
867                      "Name    :\n"
868                      "Planes  :",
869                      24,13,1,&MapStatsb,NULL};
870
871 void Item_MapStats(void)
872 {
873  int ox,oy;
874  unsigned i,_seg *unique;
875
876  DrawDialog(&MapStatsd,1);
877  MouseHide();
878  GetDialogXY(&MapStatsd,&sx,&sy);
879  ox=sx+9;
880  oy=sy+2;
881  sx=ox;
882  sy=oy;
883  printint(mapwidth);
884  sx=ox;
885  sy=oy+1;
886  printint(mapheight);
887  sx=ox;
888  sy=oy+2;
889  print(MapHeader.name);
890  sx=ox;
891  sy=oy+3;
892
893  if (MapFileHeader->maptype&BPLANE)
894    print("BACK");
895  if (MapFileHeader->maptype&FPLANE)
896    print(",FORE");
897  if (MapFileHeader->maptype&IPLANE)
898    print(",INFO");
899
900  //
901  // Count amount of unique background tiles
902  //
903  sx=ox-9;
904  sy=oy+4;
905  if (MapFileHeader->maptype&BPLANE)
906    {
907     int amount=0;
908
909     print("Unique Bkgnd Tiles:");
910     MMAllocate((memptr *)&unique,tilenum*2);
911     _fmemset(unique,0,tilenum*2);
912     for (i=0;i<mapwidth*mapheight;i++)
913       unique[MapBkgnd[i]]=1;
914     for (i=0;i<tilenum;i++)
915       amount+=unique[i];
916     MMFreePtr((memptr *)&unique);
917          printint(amount);
918    }
919
920  //
921  // Count amount of unique foreground tiles
922  //
923  sx=ox-9;
924  sy=oy+5;
925  if (MapFileHeader->maptype&FPLANE)
926    {
927     int amount=0;
928
929     print("Unique Frgnd Tiles:");
930     MMAllocate((memptr *)&unique,tilemnum*2);
931     _fmemset(unique,0,tilemnum*2);
932     for (i=0;i<mapwidth*mapheight;i++)
933       if (MapFrgnd[i])
934         unique[MapFrgnd[i]]=1;
935     for (i=0;i<tilemnum;i++)
936       amount+=unique[i];
937     MMFreePtr((memptr *)&unique);
938     printint(amount);
939    }
940
941  //
942  // Count amount of icons
943  //
944  sx=ox-9;
945  sy=oy+6;
946  if (MapFileHeader->maptype&IPLANE)
947    {
948     int amount=0;
949
950     print("Amount of Icons:");
951     for (i=0;i<mapwidth*mapheight;i++)
952       if (MapInfoPl[i])
953         amount++;
954     printint(amount);
955    }
956
957  //
958  // Display amount of memory the map needs
959  //
960  sx=ox-9;
961  sy=oy+7;
962  {
963   long length=0;
964
965   if (MapFileHeader->maptype&BPLANE)
966     length+=2L*mapwidth*mapheight;
967   if (MapFileHeader->maptype&FPLANE)
968          length+=2L*mapwidth*mapheight;
969   if (MapFileHeader->maptype&IPLANE)
970     length+=2L*mapwidth*mapheight;
971   length+=sizeof(MapHeaderStr);
972
973   print("Size of map:");
974   length=(length+1023)/1024;
975   printint(length);
976   print("K");
977  }
978
979  MouseShow();
980  CheckButtons(&MapStatsd);
981  RestoreBackground();
982 }
983
984
985 ////////////////////////////////////////////////////
986 //
987 // Item - Edit New Map
988 //
989 ////////////////////////////////////////////////////
990 btype DOSAVEb[]={{" Yes ",3,3,2},
991                  {" No! ",15,3,1}};
992 DialogDef DOSAVEd={"Your map has changed!\n"
993                    "       Save it?",
994                    21,5,2,&DOSAVEb[0],NULL};
995
996 void Item_EditMap(void)
997 {
998  int which,olddirt;
999
1000  olddirt=DirtyFlag;
1001  if (DirtyFlag)
1002    {
1003     which=DoDialog(&DOSAVEd);
1004     if (!which)
1005       return;
1006     if (which==1)
1007                 Item_SaveMap();
1008     DirtyFlag=0;
1009    }
1010
1011  if ((which=SelectMap(1,CREATED,"TO EDIT"))==-1)
1012    {
1013          DirtyFlag=olddirt;
1014     return;
1015    }
1016
1017  TEDInfo->level=whichmap=which;
1018  LoadMap(whichmap);
1019  MouseHide();
1020  InitDesktop(TED5MenuBar,0);
1021  DrawInfoBar();
1022  FigureScreenEdges();
1023  DrawMap();
1024  MouseShow();
1025 }
1026
1027 ////////////////////////////////////////////////////
1028 //
1029 // Item - Save Map
1030 //
1031 ////////////////////////////////////////////////////
1032 void Item_SaveMap(void)
1033 {
1034  SaveMap(0);
1035  DirtyFlag=0;
1036 }
1037
1038 ////////////////////////////////////////////////////
1039 //
1040 // Item - Create Map
1041 //
1042 ////////////////////////////////////////////////////
1043 void Item_CreateMap(void)
1044 {
1045  if (DirtyFlag)
1046    {
1047     int button;
1048
1049     button=DoDialog(&DoCreated);
1050     if (!button)
1051       return;
1052          if (button==1)
1053       Item_SaveMap();
1054     DirtyFlag=0;
1055    }
1056
1057  CreateMap(1);
1058  MouseHide();
1059  InitDesktop(TED5MenuBar,0);
1060  DrawInfoBar();
1061  FigureScreenEdges();
1062  DrawMap();
1063  MouseShow();
1064 }
1065
1066 ////////////////////////////////////////////////////
1067 //
1068 // Item - Delete Map
1069 //
1070 ////////////////////////////////////////////////////
1071 btype AreSureB[]={{" Yes ",1,4,1},
1072                   {" No ",11,4,2}};
1073 DialogDef AreSureD={"Are you sure you\n"
1074                         "you want to delete",
1075                         18,6,2,&AreSureB[0],NULL};
1076
1077 void Item_DeleteMap(void)
1078 {
1079  MapHeaderStr TempHead;
1080  int whichdel,which,temp;
1081
1082  if ((whichdel=SelectMap(1,CREATED,"TO DELETE"))==-1)
1083    return;
1084
1085  if (whichmap==whichdel)
1086    {
1087         ErrDialog("I'm just not gonna stand for\n"
1088                  "you deleting the map you're\n"
1089                  "currently editing. I'm not\n"
1090                  "gonna doit. Nope."," Gee... ");
1091         return;
1092    }
1093
1094  LoadFile(mapname,(char huge *)&TempHead,
1095         MapFileHeader->dataoffsets[whichdel],sizeof(MapHeaderStr));
1096  MouseHide();
1097  DrawDialog(&AreSureD,1);
1098  GetDialogXY(&AreSureD,&sx,&sy);
1099  sy+=2;
1100  sx=screencenterx-(strlen(TempHead.name)+1)/2;
1101  print(TempHead.name);
1102  print("?");
1103  MouseShow();
1104
1105  which=CheckButtons(&AreSureD);
1106  switch(which)
1107  {
1108   case 1:
1109         temp=whichmap;
1110         whichmap=whichdel;
1111         RestoreBackground();
1112         SaveMap(1);
1113         whichmap=temp;
1114         return;
1115  }
1116  RestoreBackground();
1117 }
1118
1119 ////////////////////////////////////////////////////
1120 //
1121 // Item - Amputate Maps
1122 //
1123 ////////////////////////////////////////////////////
1124 void Item_Amputate(void)
1125 {
1126         char tstr[40];
1127         MapHeaderStr TempHead;
1128         int which1,which2,whichtemp,i,button;
1129         long temp;
1130
1131
1132         if ((which1 = SelectMap(1,CREATED,"TO START AMPUTATE"))==-1)
1133                 return;
1134
1135         LoadFile(mapname,(char huge *)&TempHead,
1136                 MapFileHeader->dataoffsets[which1],sizeof(MapHeaderStr));
1137
1138         if ((which2 = SelectMap(1,ANYLIST,"TO END AMPUTATE"))==-1)
1139                 return;
1140
1141         if (which2 < which1)
1142         {
1143                 whichtemp = which1;
1144                 which1 = which2;
1145                 which2 = whichtemp;
1146         }
1147
1148         if (whichmap >= which1 && whichmap <= which2)
1149         {
1150                 ErrDialog (     "The currently loaded map\n"
1151                                         "is within that range!\n"
1152                                         "NON-AMPUTATENESS!!","Wah!");
1153                 return;
1154         }
1155
1156         DrawDialog(&AreSureD,1);
1157         button = CheckButtons(&AreSureD);
1158         switch (button)
1159         {
1160                 case 1:
1161                         for (i = which1;i <= which2;i++)
1162                         {
1163                                 MapFileHeader->dataoffsets[i] = -1;
1164                                 MapFileHeader->datalengths[i] = 0;
1165                         }
1166
1167                         DirtyFlag = writeH = 1;
1168                         SaveMap(0);
1169         }
1170 }
1171
1172
1173 ////////////////////////////////////////////////////
1174 //
1175 // Item - Switch Maps
1176 //
1177 ////////////////////////////////////////////////////
1178 void Item_SwitchMap(void)
1179 {
1180  char tstr[40];
1181  MapHeaderStr TempHead;
1182  int which1,which2;
1183  long temp;
1184
1185  while(1)
1186  {
1187   if ((which1=SelectMap(1,CREATED,"TO SWAP"))==-1)
1188         return;
1189   LoadFile(mapname,(char huge *)&TempHead,
1190         MapFileHeader->dataoffsets[which1],sizeof(MapHeaderStr));
1191   strcpy(tstr,"TO SWAP WITH '");
1192   strcat(tstr,TempHead.name);
1193   strcat(tstr,"'");
1194   if ((which2=SelectMap(1,ANYLIST,tstr))==-1)
1195         return;
1196
1197   if (which1==whichmap) // MAKE SURE THE CURRENTLY EDITED MAP GETS CHANGED!
1198         whichmap=which2;
1199   else
1200   if (which2==whichmap)
1201         whichmap=which1;
1202
1203   temp=MapFileHeader->dataoffsets[which1];
1204
1205   strcpy(tstr,MapNames[which1]);
1206   strcpy(MapNames[which1],MapNames[which2]);
1207   strcpy(MapNames[which2],tstr);
1208
1209   MapFileHeader->dataoffsets[which1]=MapFileHeader->dataoffsets[which2];
1210   MapFileHeader->dataoffsets[which2]=temp;
1211   writeH=DirtyFlag=1;
1212  }
1213 }
1214
1215 ////////////////////////////////////////////////////
1216 //
1217 // Item - Quit
1218 //
1219 ////////////////////////////////////////////////////
1220 btype Qbuttons[]={{" Yes ",4,2,2},{" No ",12,2,1}},
1221       DoSaveb[]={{" Yes ",7,4,2},{" No ",14,4,1}};
1222 DialogDef Qdialog={"Quit - Are you sure?",20,4,2,&Qbuttons[0],NULL},
1223           DoSaved={"The map has been modified.\n"
1224                    "Do you want to SAVE it\n"
1225                    "before exiting TED5?",26,6,2,&DoSaveb[0],NULL},
1226           DoCreated={"The map has been modified.\n"
1227                      "Do you want to SAVE it\n"
1228                      "before CREATING a new one?",26,6,2,&DoSaveb[0],NULL};
1229
1230 void Item_Quit(void)
1231 {
1232  int button;
1233
1234  button=DoDialog(&Qdialog);
1235
1236  if (button==1)
1237    {
1238          TEDInfo->lastvid=videomode;
1239     TEDInfo->level=whichmap;
1240     TEDInfo->OldCgaXMS=0;
1241     TEDInfo->OldEgaXMS=0;
1242     TEDInfo->OldVgaXMS=0;
1243     TEDInfo->OldCgaXMSsize=0;
1244     TEDInfo->OldEgaXMSsize=0;
1245     TEDInfo->OldVgaXMSsize=0;
1246
1247     TEDInfo->pflags=((planeton&1)<<6)|
1248                     ((planemon&1)<<5)|
1249                     ((planeion&1)<<4)|
1250                     ((viewton&1)<<2)|
1251                     ((viewmon&1)<<1)|
1252                     (viewion&1);
1253
1254     SaveTEDInfo();
1255     if (DirtyFlag)
1256       {
1257        button=DoDialog(&DoSaved);
1258        if (button==1)
1259          Item_SaveMap();
1260        if (!button)
1261          return;        // ESC exits
1262       }
1263     SaveOutputHeader();
1264     Quit("");
1265    }
1266 }
1267
1268 ////////////////////////////////////////////////////
1269 //
1270 // Item - Edit Map Names
1271 //
1272 ////////////////////////////////////////////////////
1273 char EMNstring[16];
1274 btype EMNb[]={{EMNstring,1,4,1},
1275               {"                ",1,8,1},
1276               {" Exit ",7,11,1}};
1277 DialogDef EMNd={"     MAP RENAME\n\nChange...\n\n\n\nTo..."
1278                 ,20,13,3,&EMNb[0],NULL};
1279
1280 void Item_EditMapNames(void)
1281 {
1282  int which,mapnum,redraw=0,omapnum,oxb,oyb;
1283  MapHeaderStr TempHeader;
1284  char temp[16];
1285
1286
1287  CheckForMapSave();
1288  omapnum=whichmap;
1289  oxb=xbase;
1290  oyb=ybase;
1291
1292  if ((mapnum=SelectMap(1,CREATED,"TO RENAME"))<0)
1293    return;
1294
1295  whichmap=mapnum;
1296  LoadMap(whichmap);
1297  strcpy(EMNstring,MapHeader.name);
1298
1299  MouseHide();
1300  DrawDialog(&EMNd,1);
1301  GetDialogXY(&EMNd,&sx,&sy);
1302  MouseShow();
1303  which=2;
1304 #pragma warn -rch
1305  goto badboy;
1306
1307  do
1308  {
1309   which=CheckButtons(&EMNd);
1310
1311 badboy:
1312 #pragma warn +rch
1313   switch(which)
1314   {
1315    case 1:
1316      RestoreBackground();
1317      if ((mapnum=SelectMap(1,CREATED,"TO RENAME"))<0)
1318        {
1319         if (redraw)
1320           DrawInfoBar();
1321
1322         whichmap=omapnum;
1323         LoadMap(whichmap);
1324         xbase=oxb;
1325         ybase=oyb;
1326         return;
1327        }
1328
1329      whichmap=mapnum;
1330      LoadMap(whichmap);
1331      strcpy(EMNstring,MapHeader.name);
1332      MouseHide();
1333      DrawDialog(&EMNd,1);
1334      MouseShow();
1335
1336    case 2:
1337      MouseHide();
1338      GetButtonXY(&EMNd,1,&sx,&sy);
1339      print(EMNb[1].text);
1340      GetButtonXY(&EMNd,1,&sx,&sy);
1341      if (input(temp,15))
1342        {
1343         writeH=1;
1344         strcpy(MapHeader.name,temp);
1345         strcpy(MapNames[mapnum],temp);
1346         DirtyFlag=1;
1347         Item_SaveMap();
1348        }
1349      else
1350        {
1351         GetButtonXY(&EMNd,1,&sx,&sy);
1352         print(EMNb[1].text);
1353        }
1354      MouseShow();
1355      break;
1356
1357    case 3:
1358      which=0;
1359   }
1360  } while(which);
1361
1362  RestoreBackground();
1363  if (redraw)
1364    DrawInfoBar();
1365
1366  whichmap=omapnum;
1367  LoadMap(whichmap);
1368  xbase=oxb;
1369  ybase=oyb;
1370 }
1371
1372 ////////////////////////////////////////////////////
1373 //
1374 // Item - Paste Mode
1375 //
1376 ////////////////////////////////////////////////////
1377 void Item_Paste(void)
1378 {
1379  if (!TileCopy.w)
1380    return;
1381
1382  ZeroModes();
1383  PasteMode=1;
1384  DrawInfoBar();
1385  px=(pixelx>>(tsize+2))+xbase;
1386  py=((pixely-8)>>(tsize+2))+ybase;
1387 }
1388
1389 ////////////////////////////////////////////////////
1390 //
1391 // Item - Copy Mode
1392 //
1393 ////////////////////////////////////////////////////
1394 void Item_Copy(void)
1395 {
1396  ZeroModes();
1397  SelectMode=1;
1398  SelX1=SelY1=SelX2=SelY2=-1;
1399  DrawInfoBar();
1400 }
1401
1402 ////////////////////////////////////////////////////
1403 //
1404 // Item - LastVideo
1405 //
1406 ////////////////////////////////////////////////////
1407 void Item_LastVideo(void)
1408 {
1409  int temp=videomode;
1410
1411
1412  videomode=lastvideo;
1413  lastvideo=temp;
1414  if (temp==EGA1)
1415          videomode=EGA2;
1416  else
1417          videomode=EGA1;
1418
1419  switch(videomode)
1420  {
1421   case CGA:
1422          xmshandle=CgaXMS;
1423          XMSlookup=CgaXMSlookup;
1424          break;
1425   case EGA1:
1426   case EGA2:
1427          xmshandle=EgaXMS;
1428          XMSlookup=EgaXMSlookup;
1429          break;
1430   case VGA:
1431          xmshandle=VgaXMS;
1432          XMSlookup=VgaXMSlookup;
1433  }
1434
1435  MouseHide();
1436  setvideo(videomode);
1437  InitDesktop(TED5MenuBar,0);
1438  DrawInfoBar();
1439  FigureScreenEdges();
1440
1441  if (xbase+screenw>mapwidth)
1442         xbase=mapwidth-screenw;
1443  if (mapwidth<screenw)
1444         xbase=0;
1445  if (ybase+screenh>mapheight)
1446         ybase=mapheight-screenh;
1447  if (mapheight<screenh)
1448         ybase=0;
1449
1450  DrawMap();
1451  MouseShow();
1452 }
1453
1454 ////////////////////////////////////////////////////
1455 //
1456 // Item - Switch to the Last Map
1457 //
1458 ////////////////////////////////////////////////////
1459 void Item_LastMap(void)
1460 {
1461  int temp;
1462
1463  if (!CheckForMapSave())
1464         return;
1465
1466  if (lastmap==-1)
1467         {
1468          int which=SelectMap(1,CREATED,"TO EDIT");
1469     if (which==-1)
1470       return;
1471     lastmap=which;
1472    }
1473
1474  temp=whichmap;
1475  whichmap=lastmap;
1476  lastmap=temp;
1477
1478  LoadMap(whichmap);
1479  InitDesktop(TED5MenuBar,0);
1480  MouseShow();
1481  DrawMap();
1482  DrawInfoBar();
1483 }
1484
1485 ////////////////////////////////////////////////////
1486 //
1487 // Item - Flood Fill!
1488 //
1489 ////////////////////////////////////////////////////
1490 void Item_FloodFill(void)
1491 {
1492  ZeroModes();
1493  FillMode=1;
1494  DrawInfoBar();
1495 }
1496
1497 void DoFloodFill(int x,int y,int whichb)
1498 {
1499 #define NUMSPORES       500
1500
1501  int obx[NUMSPORES],oby[NUMSPORES],i,used,j,width,k,highest,height,
1502      vectx[4]={0,1,0,-1},vecty[4]={-1,0,1,0},orgt,orgm,orgi,Ton,Mon,Ion;
1503  unsigned ptr,newoff,whichplanes=0,ctrl=0;
1504  int nx,ny,newt,newm,newi;
1505
1506
1507  if (keydown[0x1d] || whichb)
1508    ctrl++;
1509
1510  whichplanes=planeton+planemon+planeion;
1511  if (whichplanes>1)
1512    {
1513          ErrDialog("I will only allow Flood Filling\n"
1514               "one plane at a time; you have\n"
1515               "more than one plane selected."," OK ");
1516     return;
1517    }
1518
1519  for (i=0;i<NUMSPORES;i++)
1520    obx[i]=oby[i]=-1;
1521
1522  obx[0]=x;
1523  oby[0]=y;
1524  newoff=ptr=oby[0]*mapwidth+obx[0];
1525  width=MapHeader.width;
1526  height=MapHeader.height;
1527  used=1;
1528  highest=1;
1529  if (obx[0]<0 || oby[0]<0 || obx[0]>width || oby[0]>height)
1530    {
1531     FillMode=0;
1532     DrawInfoBar();
1533     return;
1534    }
1535
1536  Ton=planeton;
1537  Mon=planemon;
1538  Ion=planeion;
1539
1540  orgt=*(MapBkgnd+ptr);
1541  orgm=*(MapFrgnd+ptr);
1542  orgi=*(MapInfoPl+ptr);
1543
1544  if (((Ton?whicht==orgt:0) ||
1545      (Mon?whichtm-tilenum==orgm:0) ||
1546      (Ion?whichi-tilenum==orgi:0)) && !ctrl)
1547    {
1548     FillMode=0;
1549     DrawInfoBar();
1550     return;
1551    }
1552
1553  MouseHide();
1554  CopyUndoRegion();
1555  UndoRegion.x=UndoRegion.y=0;
1556  UndoRegion.w=mapwidth;
1557  UndoRegion.h=mapheight;
1558
1559  if (ctrl)
1560    {
1561     unsigned from=(TileCopy.y+(y%TileCopy.h))*mapwidth+
1562           TileCopy.x+(x%TileCopy.w);
1563
1564     switch(TileCopy.MapOrTileSelect)
1565     {
1566      case 0: // COPY BUFFER
1567        Ton=TileCopy.PlanesCopied&BPLANE;
1568        Mon=TileCopy.PlanesCopied&FPLANE;
1569        Ion=TileCopy.PlanesCopied&IPLANE;
1570
1571        newt=CutBkgnd[from];
1572        newm=CutFrgnd[from];
1573        newi=CutInfoPl[from];
1574
1575        break;
1576      case 1: // TILES
1577        Ton=1;
1578        Mon=Ion=0;
1579
1580        newt=((y%TileCopy.h)+TileCopy.y)*selectcols+
1581             TileCopy.x+(x%TileCopy.w);
1582        if (XMSlookup[newt]<0)
1583          Ton=0;
1584        break;
1585      case 2: // MASKED
1586        Ton=Ion=0;
1587        Mon=1;
1588
1589        newm=((y%TileCopy.h)+TileCopy.y)*selectcols+
1590             TileCopy.x+(x%TileCopy.w)+tilenum+maxiconrows*selectcols;
1591        if (XMSlookup[newm]<0)
1592          Mon=0;
1593        else
1594          newm-=tilenum;
1595     }
1596    }
1597  else
1598    {
1599     newt=whicht;
1600     newm=whichtm-tilenum;
1601     newi=whichi-tilenum;
1602    }
1603
1604  if (Ton)
1605    *(MapBkgnd+newoff)=newt;
1606  if (Mon)
1607    *(MapFrgnd+newoff)=newm;
1608  if (Ion)
1609    *(MapInfoPl+newoff)=newi;
1610
1611  do
1612    {
1613     for (i=0;i<=highest;i++)
1614       //
1615       // SEE IF SPORE EXISTS
1616       //
1617       if (obx[i]!=-1)
1618         {
1619          //
1620          // DRAW TILE AT SPORE IF IT'S ONSCREEN
1621          //
1622          if (oby[i]>=ybase && oby[i]<ybase+screenh &&
1623              obx[i]>=xbase && obx[i]<xbase+screenw)
1624              {
1625               unsigned oldt,oldm,oldi,off;
1626
1627               off=oby[i]*width+obx[i];
1628
1629               oldt=*(MapBkgnd+off);
1630               oldm=*(MapFrgnd+off)+tilenum;
1631               oldi=*(MapInfoPl+off)+tilenum;
1632
1633               CombineTiles(viewton?oldt:-BkgndColor,
1634                            viewmon?oldm:0,
1635                            viewion?oldi:0,
1636                            tsize);
1637               DrawTile((obx[i]-xbase)<<(tsize-1),((oby[i]-ybase)<<(tsize+2))+8,tsize);
1638              }
1639
1640          //
1641          // FREE THIS SPORE
1642          //
1643          x=obx[i];
1644          y=oby[i];
1645          obx[i]=-1;
1646          used--;
1647
1648          //
1649          // SEARCH 4 QUADRANTS FOR A SPORE TO FILL
1650          // (ONLY 4 QUADS SO WE DON'T FILL THRU DIAGONALS)
1651          //
1652          if (!ctrl)
1653          for (j=0;j<4;j++)
1654            {
1655             newoff=(y+vecty[j])*mapwidth+x+vectx[j];
1656
1657             if ((Ton?*(MapBkgnd+newoff)==orgt:1) &&
1658                 (Mon?*(MapFrgnd+newoff)==orgm:1) &&
1659                 (Ion?*(MapInfoPl+newoff)==orgi:1))
1660               {
1661                for (k=0;k<NUMSPORES;k++)
1662                  if (obx[k]==-1)
1663                    {
1664                     obx[k]=x+vectx[j];
1665                     oby[k]=y+vecty[j];
1666                     if (obx[k]<0 || obx[k]>width || oby[k]<0 || oby[k]>height)
1667                       {
1668                        obx[k]=-1;
1669                        break;
1670                       }
1671
1672                     used++;
1673                     if (Ton)
1674                       *(MapBkgnd+newoff)=whicht;
1675                     if (Mon)
1676                       *(MapFrgnd+newoff)=whichtm-tilenum;
1677                     if (Ion)
1678                       *(MapInfoPl+newoff)=whichi-tilenum;
1679                     DirtyFlag=1;
1680                     if (k>highest)
1681                       highest=k;
1682                     break;
1683                    }
1684               }
1685
1686             if (keydown[1])     // ESC OUT
1687               {
1688                while(keydown[1]);
1689                goto done;
1690               }
1691            }
1692          else
1693          for (j=0;j<4;j++)
1694            {
1695             unsigned from;
1696
1697             ny=y+vecty[j];
1698             nx=x+vectx[j];
1699
1700             newoff=ny*mapwidth+nx;
1701
1702             if ((Ton?*(MapBkgnd+newoff)==orgt:1) &&
1703                 (Mon?*(MapFrgnd+newoff)==orgm:1) &&
1704                 (Ion?*(MapInfoPl+newoff)==orgi:1))
1705               {
1706                for (k=0;k<NUMSPORES;k++)
1707                  if (obx[k]==-1)
1708                    {
1709                     obx[k]=nx;
1710                     oby[k]=ny;
1711                     if (obx[k]<0 || obx[k]>width || oby[k]<0 || oby[k]>height)
1712                       {
1713                        obx[k]=-1;
1714                        break;
1715                       }
1716
1717                     from=(TileCopy.y+(ny%TileCopy.h))*mapwidth+
1718                          TileCopy.x+(nx%TileCopy.w);
1719
1720                     switch(TileCopy.MapOrTileSelect)
1721                     {
1722                      case 0: // COPY BUFFER
1723                        Ton=TileCopy.PlanesCopied&BPLANE;
1724                        Mon=TileCopy.PlanesCopied&FPLANE;
1725                        Ion=TileCopy.PlanesCopied&IPLANE;
1726
1727                        newt=CutBkgnd[from];
1728                        newm=CutFrgnd[from];
1729                        newi=CutInfoPl[from];
1730
1731                        break;
1732                      case 1: // TILES
1733                        Ton=1;
1734                        Mon=Ion=0;
1735
1736                        newt=((ny%TileCopy.h)+TileCopy.y)*selectcols+
1737                             TileCopy.x+(nx%TileCopy.w);
1738                                  if (XMSlookup[newt]<0)
1739                          Ton=0;
1740                        break;
1741                      case 2: // MASKED
1742                        Ton=Ion=0;
1743                        Mon=1;
1744
1745                        newm=((ny%TileCopy.h)+TileCopy.y)*selectcols+
1746                             TileCopy.x+(nx%TileCopy.w)+tilenum+maxiconrows*selectcols;
1747                        if (XMSlookup[newm]<0)
1748                          Mon=0;
1749                        else
1750                          newm-=tilenum;
1751                     }
1752
1753                     if (Ton)
1754                       *(MapBkgnd+newoff)=newt;
1755                     if (Mon)
1756                       *(MapFrgnd+newoff)=newm;
1757                     if (Ion)
1758                       *(MapInfoPl+newoff)=newi;
1759                     used++;
1760
1761                     DirtyFlag=1;
1762                     if (k>highest)
1763                       highest=k;
1764                     break;
1765                    }
1766               }
1767
1768             if (keydown[1])     // ESC OUT
1769               {
1770                while(keydown[1]);
1771                goto done;
1772               }
1773            }
1774         }
1775    } while(used);
1776
1777 done:
1778  DrawMap();
1779  MouseShow();
1780  FillMode=0;
1781  DrawInfoBar();
1782 }
1783
1784
1785
1786 ////////////////////////////////////////////////////
1787 //
1788 // If map has been changed, ask user if they want
1789 // to SAVE it before continuing.
1790 //
1791 ////////////////////////////////////////////////////
1792 btype oktosaveB[]={{" Yes ",10,2,2},{" No ",20,2,1}};
1793 DialogDef oktosaveD={"The map has been modified!\n"
1794                      "Save it?",26,4,2,&oktosaveB[0],NULL};
1795
1796 int CheckForMapSave(void)
1797 {
1798  if (DirtyFlag)
1799    {
1800     int which=DoDialog(&oktosaveD);
1801     if (!which)
1802       return 0;
1803     if (which==1)
1804       Item_SaveMap();
1805    }
1806  return 1;
1807 }
1808
1809
1810 ////////////////////////////////////////////////////
1811 //
1812 // Zero all special mode flags
1813 //
1814 ////////////////////////////////////////////////////
1815 void ZeroModes(void)
1816 {
1817  SelX1=SelX2=SelY1=SelY2=-1;
1818  if (BfillMode || SelectMode || PasteMode || FillMode)
1819  {
1820   DrawMap();
1821   DrawInfoBar();
1822  }
1823
1824  BfillMode=SelectMode=PasteMode=FillMode=0;
1825 }
1826
1827
1828 ////////////////////////////////////////////////////
1829 //
1830 // Item - Count Map Tiles
1831 //
1832 ////////////////////////////////////////////////////
1833 btype CMTb[]={
1834               {" Exit ",9,20,2},
1835               {" TILE ",1,20,1},
1836               {" MASKED ",17,20,1},
1837               {" Rebuild ",27,20,1}
1838              };
1839 DialogDef CMTd={"        Count Unused Map Tiles",38,22,4,&CMTb[0],0};
1840 unsigned char _seg *tarray,_seg *tmarray,thesparse;
1841
1842
1843 void Item_CountTiles(void)
1844 {
1845  enum {TILE,TILEM};
1846
1847  unsigned i,j,dx,dy,max,exit=0,numt,numtm,oxbase,oybase,nsize,nmsize,redraw;
1848  int which,dumrow,dumcol;
1849  char pb,pf,pi;
1850
1851
1852  CheckForMapSave();
1853
1854  oxbase=xbase;
1855  oybase=ybase;
1856
1857  //
1858  // COMPUTE SIZE OF EACH TILE
1859  //
1860  switch(videomode)
1861  {
1862   case CGA: nsize=16; nmsize=32; break;
1863   case EGA1:
1864   case EGA2: nsize=32; nmsize=40; break;
1865   case VGA: nsize=64; nmsize=128;
1866  }
1867  nsize=nsize<<((tsize-1)<<1);
1868  nmsize=nmsize<<((tsize-1)<<1);
1869
1870
1871  MouseHide();
1872  DrawDialog(&CMTd,1);
1873  GetDialogXY(&CMTd,&dx,&dy);
1874  sx=dx+4;
1875  sy=dy+2;
1876  print("Counting tiles in map:");
1877  MouseShow();
1878
1879  MMAllocate((memptr *)&tarray,tilenum);
1880  MMAllocate((memptr *)&tmarray,tilemnum);
1881  _fmemset(tarray,0,tilenum);
1882  _fmemset(tmarray,0,tilemnum);
1883
1884  //
1885  // Now, load each map in & count the tiles
1886  //
1887  pb=MapFileHeader->maptype&BPLANE;
1888  pf=MapFileHeader->maptype&FPLANE;
1889  pi=MapFileHeader->maptype&IPLANE;
1890
1891  for (i=0;i<100;i++)
1892    if (MapFileHeader->dataoffsets[i]>=0)
1893      {
1894       sx=dx+26;
1895       sy=dy+2;
1896       printint(i);
1897
1898       LoadMap(i);
1899       max=mapwidth*mapheight;
1900       for (j=0;j<max;j++)
1901         {
1902          if (pb)
1903             tarray[MapBkgnd[j]]=1;
1904          if (pf)
1905             tmarray[MapFrgnd[j]]=1;
1906          if (pi)
1907             tmarray[MapInfoPl[j]]=1;
1908         }
1909      }
1910
1911  //
1912  // Find a SPARSE tile
1913  //
1914  for (i=0;i<tilenum;i++)
1915    if (XMSlookup[i]<0)
1916      {
1917       thesparse=i;
1918       break;
1919      }
1920
1921  //
1922  // Count unused amount
1923  //
1924  numt=0;
1925  for (i=0;i<tilenum;i++)
1926    if (XMSlookup[i]>=0 && !tarray[i])
1927      numt++;
1928
1929  numtm=0;
1930  for (i=0;i<tilemnum;i++)
1931    if (XMSlookup[i+tilenum]>=0 && !tmarray[i])
1932      numtm++;
1933
1934
1935  //
1936  // INPUT FROM DIALOG
1937  //
1938  do
1939  {
1940   MouseHide();
1941   xormask=0;
1942   sx=dx+2;
1943   sy=dy+17;
1944   print("Unused TILES:");
1945   printint(numt);
1946   print(", unused MASKED:");
1947   printint(numtm);
1948   print(" ");
1949   sx=dx+2;
1950   sy=dy+18;
1951   print("TILE Memory:");
1952   printint((1023l+(long)numt*nsize)/1024);
1953   print("K, MASKED Memory:");
1954   printint((1023l+(long)numtm*nmsize)/1024);
1955   print("K ");
1956   MouseShow();
1957   DrawUnused(0);
1958   redraw=0;
1959
1960   do
1961   {
1962    if (!MouseButton())
1963      which=CheckButtonsRet(&CMTd);
1964    MouseCoords(&pixelx,&pixely);
1965    pixelx/=8;
1966    pixely/=8;
1967    if (MouseButton() && pixelx>dx && pixelx<dx+37 && pixely>dy && pixely<dy+18)
1968      {
1969       int tile=((pixelx-dx-1)>>(tsize-1))+((pixely-dy-1)>>(tsize-1))*(9<<(3-tsize));
1970
1971       switch(whichscreen)
1972       {
1973        case TILES:
1974          if (!tarray[tile+tilebase] && XMSlookup[tile+tilebase]>=0)
1975            {
1976             tarray[tile+tilebase]=1;
1977             numt--;
1978             redraw=1;
1979            }
1980          break;
1981        case MASKED:
1982          if (!tmarray[tile+tilembase] && XMSlookup[tilenum+tile+tilembase]>=0)
1983            {
1984             tmarray[tile+tilembase]=1;
1985             numtm--;
1986             redraw=1;
1987            }
1988       }
1989       continue;
1990      }
1991
1992    switch(which)
1993    {
1994     case 0:
1995     case 1:
1996       exit=1;
1997       continue;
1998
1999     case 2:
2000       MouseHide();
2001       GetButtonXY(&CMTd,which-1,&sx,&sy);
2002       print(CMTb[which-1].text);
2003       whichscreen=TILES;
2004       DrawUnused(0);
2005       MouseShow();
2006       continue;
2007
2008     case 3:
2009       MouseHide();
2010       GetButtonXY(&CMTd,which-1,&sx,&sy);
2011       print(CMTb[which-1].text);
2012       whichscreen=MASKED;
2013       DrawUnused(0);
2014       MouseShow();
2015       continue;
2016
2017     //
2018     // REBUILD GRAPHICS FILE & HEADER
2019     //
2020     case 4:
2021       {
2022        char newgfx[13]="NEW?GA.",
2023             newhead[13]="NEW?HEAD.",
2024             newhobj[13]="NEW?HEAD.",
2025             oldhead[13]="?GAHEAD.";
2026
2027        char _seg *gfxhead;
2028
2029
2030        newgfx[3]=format[0];
2031        newhead[3]=format[0];
2032        newhobj[3]=format[0];
2033        oldhead[0]=format[0];
2034
2035
2036        LoadIn(oldhead,(memptr *)&gfxhead);
2037        for (i=0;i<tilenum;i++)
2038        {
2039         if (tarray[i])
2040           *(gfxhead+i*3)=*(gfxhead+i*3);
2041        }
2042
2043
2044       }
2045       continue;
2046    }
2047    //
2048    // KEY CHECKS
2049    //
2050    if (keydown[1])
2051      {
2052       exit=1;
2053       continue;
2054      }
2055    else
2056    if (keydown[0x50])
2057      DrawUnused(1);
2058    else
2059    if (keydown[0x48])
2060      DrawUnused(-1);
2061    else
2062    if (keydown[0x49])
2063      {
2064       DrawUnused(-8);
2065       while(keydown[0x49]);
2066      }
2067    else
2068    if (keydown[0x51])
2069      {
2070       DrawUnused(8);
2071       while(keydown[0x51]);
2072      }
2073
2074   } while(!redraw && !exit);
2075  } while(!exit);
2076
2077  RestoreBackground();
2078  LoadMap(whichmap);
2079  tilebase=tilembase=0;
2080
2081  xbase=oxbase;
2082  ybase=oybase;
2083 }
2084
2085
2086 //
2087 // FILL THE "UNUSED TILES" SCREEN WITH TILES
2088 //
2089 void DrawUnused(int deltarow)
2090 {
2091  char tile[32*32];
2092  int numcols,numrows,i,j,top;
2093
2094  if (whichscreen==ICONS)
2095    whichscreen=TILES;
2096
2097  MouseHide();
2098
2099  numrows=18-10*(tsize==2)-15*(tsize==3);
2100  left=2;
2101  top=2*8;
2102  if (videomode==EGA2)
2103    {
2104     left=22;
2105     top=20*8;
2106    }
2107
2108  switch(tsize)
2109  {
2110   case 1: numcols=36; break;
2111   case 2: numcols=18; break;
2112   case 3: numcols=9;
2113  }
2114
2115  if (whichscreen==TILES && tilebase+numrows*numcols>tilenum)
2116    {
2117     tilebase=0;
2118     numrows=tilenum/numcols;
2119    }
2120
2121  if (whichscreen==MASKED && tilembase+numrows*numcols>tilemnum)
2122    {
2123     tilembase=0;
2124     numrows=tilemnum/numcols;
2125    }
2126
2127  switch((deltarow<0?-1:deltarow>0?1:0))
2128  {
2129   case -1:
2130    switch(whichscreen)
2131    {
2132     case TILES:
2133       tilebase+=deltarow*numcols;
2134       if (tilebase<0)
2135         tilebase=0;
2136       break;
2137     case MASKED:
2138       tilembase+=deltarow*numcols;
2139       if (tilembase<0)
2140         tilembase=0;
2141    }
2142    break;
2143   case 1:
2144    switch(whichscreen)
2145    {
2146     case TILES:
2147       tilebase+=deltarow*numcols;
2148       if (tilebase+numrows*numcols>tilenum)
2149         tilebase=tilenum-numcols*numrows;
2150       break;
2151     case MASKED:
2152       tilembase+=deltarow*numcols;
2153       if (tilembase+numrows*numcols>tilemnum)
2154         tilembase=tilemnum-numcols*numrows;
2155    }
2156  }
2157
2158  switch(whichscreen)
2159  {
2160   case TILES:
2161     for(j=0;j<numrows;j++)
2162       for(i=0;i<numcols;i++)
2163       {
2164        if (!tarray[tilebase+j*numcols+i] && XMSlookup[tilebase+j*numcols+i]>=0)
2165          CombineTiles(tilebase+j*numcols+i,0,0,tsize);
2166        else
2167          CombineTiles(thesparse,0,0,tsize);
2168        DrawTile(i*2+left,j*16+top,tsize);
2169       }
2170     break;
2171
2172   case MASKED:
2173     for(j=0;j<numrows;j++)
2174       for(i=0;i<numcols;i++)
2175       {
2176        if (!tmarray[tilembase+j*numcols+i] && XMSlookup[tilenum+tilembase+j*numcols+i]>=0)
2177          CombineTiles(-BkgndColor,tilenum+tilembase+j*numcols+i,0,tsize);
2178        else
2179          CombineTiles(thesparse,0,0,tsize);
2180        DrawTile(i*2+left,j*16+top,tsize);
2181       }
2182  }
2183  MouseShow();
2184 }