home *** CD-ROM | disk | FTP | other *** search
/ The Best of the Best / _.img / 01041 / wmap.c < prev    next >
C/C++ Source or Header  |  1992-05-26  |  21KB  |  722 lines

  1. /* Program name:  WMAP.C
  2.    Description:   Draws maps for Wolfenstein 3D using ASCII characters
  3.    Author:        P.G.W.Hosken  (<RMCB@DLRVM> or via GAMES-L)
  4.    Version:       3.1
  5.    Compilation:   MSC, compile using "cl wmap.c"
  6.    Notes:         Requires files MAPHEAD.WL1 & MAPTEMP.WL1 .
  7.  
  8.    Changes:  v1.0 - Original version.
  9.              v2.0 - Blue SS guards marked separate to normal guards.
  10.                     Key updated.
  11.                     Code generally improved.
  12.                     Command line parameters included.
  13.              v2.1 - Minor mods.
  14.                     Map interpretation errors corrected.
  15.              v3.0 - Map start address taken from MAPHEAD.WL1 .
  16.                     Map names taken from MAPTEMP.WL1 .
  17.                     /k switch can be used on its own.
  18.                     /h switch included - prints map as hex dump.
  19.              v3.1 - /h switch outputs to LEVELxx.HEX
  20.                     Minor mods.
  21. */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27.  
  28. /* Function declarations */
  29. void  DRAWMAP   (FILE*,int);
  30. void  GETOFFSET (void);
  31. void  HELP      (void);
  32. void  KEY       (FILE*);
  33. void  OUTHEX    (FILE*,int,int);
  34. void  OUTVAL    (FILE*,int,int);
  35. void  OUTVAL2   (FILE*,FILE*,int,int);
  36. int   READC     (FILE*,char*);
  37. FILE* XFOPEN    (char*,char*,int);
  38. void  XFPRINTF  (FILE*,char*,char*,int);
  39.  
  40. /* Offset of start of map data in file */
  41. long OFFSET[10];
  42.  
  43. /* Output filename masks */
  44. char *FIN   = "MAPTEMP.WL1";
  45. char *FHEAD = "MAPHEAD.WL1";
  46. char *FNAME = "LEVEL00.MAP";
  47. char *FTEMP = "WMAP.TMP";
  48.  
  49. /* List of maps to output */
  50. int MAPS[10] = {0,0,0,0,0,0,0,0,0,0};
  51.  
  52. /* Switches */
  53. char KEYON=0;     /* Output key */
  54. char HEX=0;       /* Output in hex format */
  55.  
  56. /* Work buffer */
  57. char BUF[100];
  58.  
  59. /*-------------------------------------------------------------------------*/
  60.  
  61. main(argc,argv)
  62. int argc;
  63. char **argv;
  64. {
  65.   FILE *FP1;     /* File pointer for MAPTEMP.WL1 */
  66.   int   I;       /* 'for' loop counter */
  67.   int   J;       /* 'for' loop counter */
  68.   int   LEV;     /* Map level number */
  69.  
  70.   /* Check command line */
  71.   if (argc<=1) HELP();
  72.   for (I=1;I<argc;I++) {
  73.  
  74.     /* Check for switches */
  75.     if (**(argv+I)=='/' || **(argv+I)=='-') {
  76.       switch (*(*(argv+I)+1)) {
  77.         case 'H':
  78.         case 'h':  /* Output key */
  79.                    HEX=1;
  80.                    break;
  81.         case 'K':
  82.         case 'k':  /* Output key */
  83.                    KEYON=1;
  84.                    break;
  85.         case '?':
  86.         default:   /* Help (and then exit) */
  87.                    HELP();
  88.       }
  89.     }
  90.  
  91.     /* Check map number */
  92.     else {
  93.       if (!strcmp(strupr(*(argv+I)),"ALL")) {
  94.         for (J=0;J<10;J++) MAPS[J]=1;
  95.       }
  96.       else {
  97.         J=atoi(*(argv+I));
  98.         if (J<1 || J>10) HELP();
  99.         MAPS[J-1]=1;
  100.       }
  101.     }
  102.   }
  103.  
  104.   /* Check number of maps specified */
  105.   for (I=J=0;I<10;I++) J+=MAPS[I];
  106.  
  107.   if (J) {
  108.  
  109.     /* Load map addresses */
  110.     GETOFFSET();
  111.  
  112.     /* Open input file */
  113.     FP1=XFOPEN(FIN,"rb",2);
  114.  
  115.     /* Draw maps */
  116.     for (LEV=0;LEV<10;LEV++) if (MAPS[LEV]) DRAWMAP(FP1,LEV);
  117.  
  118.     /* Tidy up */
  119.     fclose(FP1);
  120.   }
  121.   else {
  122.  
  123.     /* Output key */
  124.     if (KEYON) {
  125.       KEY(stdout);
  126.       printf("\n");
  127.     }
  128.   }
  129. }
  130.  
  131. /*-------------------------------------------------------------------------*/
  132.  
  133. void DRAWMAP(FP1,MN)
  134.  
  135. FILE *FP1;  /* Output file pointer */
  136. int   MN;   /* Map number (0-9) */
  137.  
  138. {
  139.   int   C1,C2;      /* Character input */
  140.   int   COUNT;      /* Map byte count */
  141.   FILE *FP2;        /* File pointer for .TMP file */
  142.   FILE *FP3;        /* File pointer for .MAP file */
  143.   int   I;          /* 'for' loop counter */
  144.   long  LI;         /* 'for' loop counter */
  145.   int   LINE;       /* Output map line counter */
  146.   int   N;          /* Repeat count for map data */
  147.   long  OFF;        /* Offset of start of map data in bytes */
  148.   char *TITLE[18];  /* Map title (taken from MAPTEMP.WL1) */
  149.  
  150.  
  151.   printf("Constructing map %d\n",MN+1);
  152.  
  153.   /* Set output file name */
  154.   if (HEX) {
  155.     FNAME[8] ='H';
  156.     FNAME[9] ='E';
  157.     FNAME[10]='X';
  158.   }
  159.   if (MN!=9) {
  160.     FNAME[5]='0';
  161.     FNAME[6]='1'+MN;
  162.   }
  163.   else {
  164.     FNAME[5]='1';
  165.     FNAME[6]='0';
  166.   }
  167.  
  168.   /* Open output file */
  169.   FP3=XFOPEN(FNAME,"wt",2);
  170.  
  171.   /* Open work file */
  172.   if (!HEX) FP2=XFOPEN(FTEMP,"w+b",2);
  173.   else FP2=FP3;
  174.  
  175.   /* Position file pointer at start of data */
  176.   if (fseek(FP1,OFFSET[MN]+0x016,SEEK_SET)) {
  177.     printf("\nERROR: error positioning pointer in %s\n",FIN);
  178.     exit(2);
  179.   }
  180.  
  181.   /* Get title */
  182.   if (fread(TITLE,1,18,FP1)!=18) {
  183.     printf("\nERROR: error reading %s\n",FIN);
  184.     exit(2);
  185.   }
  186.  
  187.   /* Print map title */
  188.   sprintf(BUF,"\nWOLFENSTEIN 3D - %s\n\n",TITLE);
  189.   XFPRINTF(FP3,BUF,FNAME,2);
  190.  
  191.   /* Part 1 - read maze data */
  192.   if (HEX) {
  193.     sprintf(BUF,"Maze data:\n\n");
  194.     XFPRINTF(FP3,BUF,FNAME,2);
  195.   }
  196.   COUNT=LINE=0;
  197.   for (;;) {
  198.  
  199.     /* Read 2 bytes */
  200.     C1=READC(FP1,FIN);
  201.     C2=READC(FP1,FIN);
  202.  
  203.     /* Check for repeated value */
  204.     if (C1==0xCD && C2==0xAB) {
  205.       C1=READC(FP1,FIN);
  206.       C2=READC(FP1,FIN);
  207.       N=C2*256 + C1;       /* Repetition */
  208.       C1=READC(FP1,FIN);
  209.       C2=READC(FP1,FIN);
  210.  
  211.       /* Output values */
  212.       for (I=0;I<N;I++) {
  213.         if (LINE>=64) {
  214.           if (HEX) {
  215.             sprintf(BUF,"\n");
  216.             XFPRINTF(FP3,BUF,FNAME,2);
  217.           }
  218.           LINE=0;
  219.         }
  220.         if (HEX) OUTHEX(FP3,C1,C2);
  221.         else OUTVAL(FP2,C1,C2);
  222.         LINE++;
  223.         COUNT++;
  224.       }
  225.     }
  226.  
  227.     /* Single value */
  228.     else {
  229.       if (LINE>=64) {
  230.         if (HEX) {
  231.           sprintf(BUF,"\n");
  232.           XFPRINTF(FP3,BUF,FNAME,2);
  233.         }
  234.         LINE=0;
  235.       }
  236.       if (HEX) OUTHEX(FP3,C1,C2);
  237.       else OUTVAL(FP2,C1,C2);
  238.       LINE++;
  239.       COUNT++;
  240.     }
  241.     if (COUNT>=4096) goto OUT;
  242.   }
  243. OUT:
  244.  
  245.   /* Rewind output file */
  246.   if (!HEX) rewind(FP2);
  247.  
  248.   /* Skip next 2 bytes */
  249.   C1=READC(FP1,FIN);
  250.   C2=READC(FP1,FIN);
  251.  
  252.   /* Part 2 - read object data */
  253.   if (HEX) {
  254.     sprintf(BUF,"\n\nObject data:\n\n");
  255.     XFPRINTF(FP3,BUF,FNAME,2);
  256.   }
  257.   COUNT=LINE=0;
  258.   for (;;) {
  259.  
  260.     /* Read 2 bytes */
  261.     C1=READC(FP1,FIN);
  262.     C2=READC(FP1,FIN);
  263.  
  264.     /* Check for repeated value */
  265.     if (C1==0xCD && C2==0xAB) {
  266.       C1=READC(FP1,FIN);
  267.       C2=READC(FP1,FIN);
  268.       N=C2*256 + C1;      /* Repetition */
  269.       C1=READC(FP1,FIN);
  270.       C2=READC(FP1,FIN);
  271.  
  272.       /* Output values */
  273.       for (I=0;I<N;I++) {
  274.         if (LINE>=64) {
  275.           sprintf(BUF,"\n");
  276.           XFPRINTF(FP3,BUF,FNAME,2);
  277.           LINE=0;
  278.         }
  279.         if (HEX) OUTHEX(FP3,C1,C2);
  280.         else OUTVAL2(FP2,FP3,C1,C2);
  281.         LINE++;
  282.         COUNT++;
  283.       }
  284.     }
  285.  
  286.     /* Single value */
  287.     else {
  288.  
  289.       /* Check if new line to be started */
  290.       if (LINE>=64) {
  291.         sprintf(BUF,"\n");
  292.         XFPRINTF(FP3,BUF,FNAME,2);
  293.         LINE=0;
  294.       }
  295.  
  296.       /* Output value */
  297.       if (HEX) OUTHEX(FP3,C1,C2);
  298.       else OUTVAL2(FP2,FP3,C1,C2);
  299.       LINE++;
  300.       COUNT++;
  301.     }
  302.     if (COUNT>=4096) goto OUT2;
  303.   }
  304.  
  305. OUT2:
  306.   /* Output key */
  307.   if (KEYON) {
  308.     sprintf(BUF,"\n");
  309.     XFPRINTF(FP3,BUF,FNAME,2);
  310.     KEY(FP3);
  311.   }
  312.   sprintf(BUF,"\f");
  313.   XFPRINTF(FP3,BUF,FNAME,2);
  314.  
  315.   /* Tidy up */
  316.   fclose(FP2);
  317.   fclose(FP3);
  318.  
  319.   /* Delete .TMP file */
  320.   if (!HEX) {
  321.     if (remove(FTEMP)) {
  322.       printf("\nERROR: cannot delete work file %s\n",FTEMP);
  323.       exit(2);
  324.     }
  325.   }
  326. }
  327.  
  328. /*-------------------------------------------------------------------------*/
  329.  
  330. void GETOFFSET()
  331. {
  332.   FILE *FP;    /* File pointer for MAPHEAD.WL1 */
  333.   int   C;     /* Work variable */
  334.  
  335.   /* Open input file */
  336.   FP=XFOPEN(FHEAD,"rb",2);
  337.  
  338.   /* Skip first 2 bytes */
  339.   C=READC(FP,FHEAD);
  340.   C=READC(FP,FHEAD);
  341.  
  342.   /* Read offsets */
  343.   if (fread(OFFSET,4,10,FP)!=10) {
  344.     printf("\nERROR: error reading %s\n",FHEAD);
  345.     exit(2);
  346.   }
  347. }
  348.  
  349. /*-------------------------------------------------------------------------*/
  350.  
  351. void KEY(FP)
  352. FILE *FP;
  353. {
  354.   fprintf(FP,"\nKEY:");
  355.   fprintf(FP,"\n        %c%c  Wall             a   Ammo",177,177);
  356.   fprintf(FP,"\n        %c%c  Wall w/ decor    f   Food",178,178);
  357.   fprintf(FP,"\n        %c%c  Wall-lift        g   Gun-4",219,219);
  358.   fprintf(FP,"\n        %c%c  Exit from maze   k   Key",176,176);
  359.   fprintf(FP,"\n        %c%c  Door             m   Machine gun-3",205,205);
  360.   fprintf(FP,"\n        %c   Door             o   Object",186);
  361.   fprintf(FP,"\n        %c   Lift door        s   Sphere",239);
  362.   fprintf(FP,"\n        %c   Locked door      t   Treasure",240);
  363.   fprintf(FP,"\n        %c   Hidden door      x   Hulk",168);
  364.   fprintf(FP,"\n        %c%c  Cell             ",215,215);
  365.   fprintf(FP,"Dn  Dog: difficulty levels 1-n");
  366.   fprintf(FP,"\n        %c%c  Start of level   ",174,175);
  367.   fprintf(FP,"Gn  Guard: difficulty levels 1-n");
  368.   fprintf(FP,"\n        +   First aid kit    ");
  369.   fprintf(FP,"Bn  Blue guard: difficulty levels 1-n");
  370. }
  371.  
  372. /*-------------------------------------------------------------------------*/
  373.  
  374. void OUTVAL(FP,X1,X2)
  375.  
  376. /* Output maze value */
  377.  
  378. FILE *FP;     /* Output file pointer */
  379. int   X1,X2;  /* 2 input bytes */
  380.  
  381. {
  382.   unsigned char CH,CH2;
  383.  
  384.   if (X2) {
  385.     printf("\nCode > 255 (%X)",X2);
  386.     sprintf(BUF,"!!");
  387.     XFPRINTF(FP,BUF,FTEMP,2);
  388.   }
  389.   else {
  390.     switch (X1) {
  391.       case 0x01: CH=177; break; /* Wall */
  392.       case 0x02: CH=177; break; /* Wall */
  393.       case 0x03: CH=178; break; /* Banner */
  394.       case 0x04: CH=178; break; /* Hitler */
  395.       case 0x05: CH=215; break; /* Cell */
  396.       case 0x06: CH=178; break; /* Swastika w/ eagle */
  397.       case 0x07: CH=215; break; /* Cell w/ skeleton */
  398.       case 0x08: CH=177; break; /* Wall */
  399.       case 0x09: CH=177; break; /* Wall */
  400.       case 0x0A: CH=178; break; /* Eagle */
  401.       case 0x0B: CH=178; break; /* Hitler */
  402.       case 0x0C: CH=177; break; /* Wall */
  403.       case 0x0D: CH=174; break; /* Entrance to level */
  404.       case 0x0F: CH=178; break; /* Steel plates */
  405.       case 0x10: CH=176; break; /* Landscape view */
  406.       case 0x11: CH=177; break; /* Wall */
  407.       case 0x12: CH=178; break; /* Wreath */
  408.       case 0x13: CH=177; break; /* Wall */
  409.       case 0x14: CH=178; break; /* Shield */
  410.       case 0x15: CH=219; break; /* Lift */
  411.       case 0x19: CH=178; break; /* Wall w/ blood */
  412.       case 0x5A: CH=186; break; /* Vert. door */
  413.       case 0x5B: CH=205; break; /* Horiz. door */
  414.       case 0x5C: CH=240; break; /* Locked steel door (needs key) */
  415.       case 0x5D: CH=240; break; /* Locked door (needs key) */
  416.       case 0x64: CH=239; break; /* Lift entrance */
  417.       case 0x6A: CH=' '; break; /* ????? */     
  418.       case 0x6B:
  419.       case 0x6C:
  420.       case 0x6D:
  421.       case 0x6E:
  422.       case 0x6F:
  423.       case 0x70:
  424.       case 0x71:
  425.       case 0x72:
  426.       case 0x73:
  427.       case 0x74:
  428.       case 0x75:
  429.       case 0x76:
  430.       case 0x77:
  431.       case 0x78:
  432.       case 0x79:
  433.       case 0x7A:
  434.       case 0x7B:
  435.       case 0x7C:
  436.       case 0x7D:
  437.       case 0x7E:
  438.       case 0x7F:
  439.       case 0x80:
  440.       case 0x81:
  441.       case 0x82:
  442.       case 0x83:
  443.       case 0x84:
  444.       case 0x85:
  445.       case 0x86:
  446.       case 0x87:
  447.       case 0x88:
  448.       case 0x89:
  449.       case 0x8A:
  450.       case 0x8B:
  451.       case 0x8C:
  452.       case 0x8D:
  453.       case 0x8E:
  454.       case 0x8F: CH=' '; break; /* Floor */
  455.       default:   CH='@';
  456.                  printf("\nPart 1 unknown code (%X)",X1);
  457.     }
  458.     switch (CH) {
  459.       case ' ': CH2=' '; break;
  460.       case 176: CH2=176; break;
  461.       case 177: CH2=177; break;
  462.       case 178: CH2=178; break;
  463.       case 219: CH2=219; break;
  464.       case 215: CH2=215; break;
  465.       case 205: CH2=205; break;
  466.       case 174: CH2=175; break;
  467.       case 240: CH2=240; break;
  468.       default:  CH2=' ';
  469.     }
  470.     sprintf(BUF,"%c%c",CH,CH2);
  471.     XFPRINTF(FP,BUF,FTEMP,2);
  472.   }
  473. }
  474.  
  475. /*-------------------------------------------------------------------------*/
  476.  
  477. void OUTVAL2(FPIN,FPOUT,X1,X2)
  478.  
  479. /* Output maze value */
  480.  
  481. FILE *FPIN;   /* File pointer for .TMP file */
  482. FILE *FPOUT;  /* Output file pointer */
  483. int   X1,X2;  /* 2 input bytes */
  484. {
  485.   unsigned char CH;
  486.   int IN,IN2;
  487.   int GUARD=0;
  488.   int DOG=0;
  489.  
  490.   /* Read maze data for location */
  491.   IN =READC(FPIN,FTEMP);
  492.   IN2=READC(FPIN,FTEMP);
  493.  
  494.   if (X2) {
  495.     printf("\nCode > 255 (%X)",X2);
  496.     sprintf(BUF,"!!");
  497.     XFPRINTF(FPOUT,BUF,FNAME,2);
  498.   }
  499.   else {
  500.     switch (X1) {
  501.       case 0x00: CH=' '; break; /* Nothing */
  502.       case 0x13: CH=' '; break; /* Start position */
  503.       case 0x14: CH=175; break; /* Entrance */
  504.       case 0x15: CH=' '; break; /* ? */
  505.       case 0x17: CH=' '; break; /* Water */
  506.       case 0x18: CH='o'; break; /* Drum */
  507.       case 0x19: CH='o'; break; /* Desk */
  508.       case 0x1A: CH='o'; break; /* Stand lamp */
  509.       case 0x1B: CH=' '; break; /* Chandalier */
  510.       case 0x1C: CH='o'; break; /* Hanging skeleton */
  511.       case 0x1D: CH='f'; break; /* Dog food */
  512.       case 0x1E: CH='o'; break; /* Column */
  513.       case 0x1F: CH='o'; break; /* ? */
  514.       case 0x20: CH='o'; break; /* Skeleton */
  515.       case 0x21: CH='o'; break; /* Sink */
  516.       case 0x22: CH='o'; break; /* Plant */
  517.       case 0x23: CH='o'; break; /* Vase */
  518.       case 0x24: CH='o'; break; /* Table */
  519.       case 0x25: CH=' '; break; /* Lamp */
  520.       case 0x26: CH=' '; break; /* Hanging kitchen utensils */
  521.       case 0x27: CH='o'; break; /* Knight */
  522.       case 0x28: CH='o'; break; /* Empty cage */
  523.       case 0x29: CH='o'; break; /* Cage /w skeleton */
  524.       case 0x2A: CH='o'; break; /* Bones */
  525.       case 0x2B: CH='k'; break; /* Key */
  526.       case 0x2D: CH='o'; break; /* Bed */
  527.       case 0x2E: CH='o'; break; /* Bin */
  528.       case 0x2F: CH='f'; break; /* Food */
  529.       case 0x30: CH='+'; break; /* First aid bed */
  530.       case 0x31: CH='a'; break; /* Ammo */
  531.       case 0x32: CH='m'; break; /* Machine gun (3) */
  532.       case 0x33: CH='g'; break; /* Gun (4) */
  533.       case 0x34: CH='t'; break; /* Cross */
  534.       case 0x35: CH='t'; break; /* Chalace */
  535.       case 0x36: CH='t'; break; /* Jewels */
  536.       case 0x37: CH='t'; break; /* Crown */
  537.       case 0x38: CH='s'; break; /* Sphere */
  538.       case 0x39: CH=' '; break; /* Bones in blood */
  539.       case 0x3A: CH='o'; break; /* Barrel */
  540.       case 0x3B: CH='o'; break; /* Well with water */
  541.       case 0x3C: CH='o'; break; /* Well without water */
  542.       case 0x3D: CH=' '; break; /* Pool of blood */
  543.       case 0x3E: CH='o'; break; /* Flag */
  544.       case 0x49: CH=' '; break; /* ? */
  545.       case 0x5A: CH=' '; break; /* Movement turning point */
  546.       case 0x5B: CH=' '; break; /* Movement turning point */
  547.       case 0x5C: CH=' '; break; /* Movement turning point */
  548.       case 0x5D: CH=' '; break; /* Movement turning point */
  549.       case 0x5E: CH=' '; break; /* Movement turning point */
  550.       case 0x5F: CH=' '; break; /* Movement turning point */
  551.       case 0x60: CH=' '; break; /* Movement turning point */
  552.       case 0x61: CH=' '; break; /* Movement turning point */
  553.       case 0x62: CH=168; break; /* Hidden door */
  554.       case 0x63: CH=' '; break; /* Trigger on floor */
  555.       case 0x6C: CH='1'; GUARD=1; break; /* Guard */
  556.       case 0x6D: CH='1'; GUARD=1; break; /* Guard */
  557.       case 0x6F: CH='1'; GUARD=1; break; /* Guard */
  558.       case 0x6E: CH='1'; GUARD=1; break; /* Guard */
  559.       case 0x70: CH='1'; GUARD=1; break; /* Guard */
  560.       case 0x71: CH='1'; GUARD=1; break; /* Guard */
  561.       case 0x72: CH='1'; GUARD=1; break; /* Guard */
  562.       case 0x73: CH='1'; GUARD=1; break; /* Guard */
  563.       case 0x7C: CH=' '; break; /* Dead guard */
  564.       case 0x7E: CH='1'; GUARD=2; break; /* Blue officer */
  565.       case 0x7F: CH='1'; GUARD=2; break; /* Blue officer */
  566.       case 0x80: CH='1'; GUARD=2; break; /* Blue officer */
  567.       case 0x81: CH='1'; GUARD=2; break; /* Blue officer */
  568.       case 0x83: CH='1'; GUARD=2; break; /* Blue officer */
  569.       case 0x85: CH='1'; GUARD=2; break; /* Blue officer */
  570.       case 0x8A: CH='1'; DOG=1; break; /* Dog */
  571.       case 0x8B: CH='1'; DOG=1; break; /* Dog */
  572.       case 0x8C: CH='1'; DOG=1; break; /* Dog */
  573.       case 0x8D: CH='1'; DOG=1; break; /* Dog */
  574.       case 0x90: CH='3'; GUARD=1; break; /* Guard */
  575.       case 0x91: CH='3'; GUARD=1; break; /* Guard */
  576.       case 0x92: CH='3'; GUARD=1; break; /* Guard */
  577.       case 0x93: CH='3'; GUARD=1; break; /* Guard */
  578.       case 0x94: CH='3'; GUARD=1; break; /* Guard */
  579.       case 0x95: CH='3'; GUARD=1; break; /* Guard */
  580.       case 0x96: CH='3'; GUARD=1; break; /* Guard */
  581.       case 0x97: CH='3'; GUARD=1; break; /* Guard */
  582.       case 0xA2: CH='3'; GUARD=2; break; /* Blue officer */
  583.       case 0xA3: CH='3'; GUARD=2; break; /* Blue officer */
  584.       case 0xA4: CH='3'; GUARD=2; break; /* Blue officer */
  585.       case 0xA5: CH='3'; GUARD=2; break; /* Blue officer */
  586.       case 0xAE: CH='3'; DOG=1; break; /* Dog */
  587.       case 0xAF: CH='3'; DOG=1; break; /* Dog */
  588.       case 0xB0: CH='3'; DOG=1; break; /* Dog */
  589.       case 0xB1: CH='3'; DOG=1; break; /* Dog */
  590.       case 0xB4: CH='4'; GUARD=1; break; /* Guard */
  591.       case 0xB5: CH='4'; GUARD=1; break; /* Guard */
  592.       case 0xB6: CH='4'; GUARD=1; break; /* Guard */
  593.       case 0xB7: CH='4'; GUARD=1; break; /* Guard */
  594.       case 0xB8: CH='4'; GUARD=1; break; /* Guard */
  595.       case 0xB9: CH='4'; GUARD=1; break; /* Guard */
  596.       case 0xBA: CH='4'; GUARD=1; break; /* Guard */
  597.       case 0xBB: CH='4'; GUARD=1; break; /* Guard */
  598.       case 0xC6: CH='4'; GUARD=2; break; /* Blue officer */
  599.       case 0xC7: CH='4'; GUARD=2; break; /* Blue officer */
  600.       case 0xC8: CH='4'; GUARD=2; break; /* Blue officer */
  601.       case 0xC9: CH='4'; GUARD=2; break; /* Blue officer */
  602.       case 0xD2: CH='4'; DOG=1; break; /* Dog */
  603.       case 0xD3: CH='4'; DOG=1; break; /* Dog */
  604.       case 0xD4: CH='4'; DOG=1; break; /* Dog */
  605.       case 0xD5: CH='4'; DOG=1; break; /* Dog */
  606.       case 0xD6: CH='x'; break; /* Hulk */
  607.       default:   CH='@';
  608.                  printf("\nPart 2 unknown code (%X)",X1);
  609.     }
  610.     if (CH==' ') CH=IN2;
  611.     if (GUARD==1) IN='G';
  612.     if (GUARD==2) IN='B';
  613.     if (DOG) IN='D';
  614.     if (IN==' ' &&  CH==175) IN=174;
  615.     sprintf(BUF,"%c%c",IN,CH);
  616.     XFPRINTF(FPOUT,BUF,FNAME,2);
  617.   }
  618. }
  619.  
  620. /*-------------------------------------------------------------------------*/
  621.  
  622. void OUTHEX(FP,X1,X2)
  623.  
  624. FILE *FP;     /* Output file pointer */
  625. int   X1,X2;  /* 2 input bytes */
  626.  
  627. {
  628.   if (X2) {
  629.     printf("\nCode > 255 (%X)",X2);
  630.     sprintf(BUF,"!!");
  631.     XFPRINTF(FP,BUF,FNAME,2);
  632.   }
  633.   else {
  634.     if (X1) {
  635.       sprintf(BUF,"%2.2X",X1);
  636.       XFPRINTF(FP,BUF,FNAME,2);
  637.     }
  638.     else {
  639.       sprintf(BUF,"..",X1);
  640.       XFPRINTF(FP,BUF,FNAME,2);
  641.     }
  642.   }
  643. }
  644.  
  645. /*-------------------------------------------------------------------------*/
  646.  
  647. int READC(FP,NAME)
  648. FILE *FP;
  649. char *NAME;
  650. {
  651.   int CH;
  652.  
  653.   CH=fgetc(FP);
  654.   if (feof(FP) || ferror(FP)) {
  655.     printf("\nERROR: error reading %s\n",NAME);
  656.     exit(2);
  657.   }
  658.   return(CH);
  659. }
  660.  
  661. /*-------------------------------------------------------------------------*/
  662.  
  663. FILE *XFOPEN(NAME,TYPE,STATUS)
  664. char *NAME;    /* File name */
  665. char *TYPE;    /* Type of file access */
  666. int   STATUS;  /* Exit status */
  667. {
  668.   FILE *FP;    /* File handle */
  669.  
  670.   if ((FP=fopen(NAME,TYPE))==NULL) {
  671.     printf("\nERROR: cannot open file %s\n",NAME);
  672.     exit(STATUS);
  673.   }
  674.   return(FP);
  675. }
  676.  
  677. /*-------------------------------------------------------------------------*/
  678.  
  679. void XFPRINTF(FP,BUF,NAME,STATUS)
  680.  
  681. FILE *FP;      /* File handle */
  682. char *BUF;     /* String to print */
  683. char *NAME;    /* File name */
  684. int   STATUS;  /* Exit status */
  685.  
  686. {
  687.   if (!fprintf(FP,BUF)) {
  688.     printf("\nERROR: writing to file %s\n",NAME);
  689.     exit(STATUS);
  690.   }
  691. }
  692.  
  693. /*-------------------------------------------------------------------------*/
  694.  
  695. void HELP()
  696. {
  697.   printf("\nWMAP (v3.1) - constructs maps for Wolfenstein from Apogee");
  698.   printf("\n");
  699.   printf("\n");
  700.   printf("\nCommand line:");
  701.   printf("\n");
  702.   printf("\n   WMAP <sw1> ... <swN> <param.1> ... <param.M>");
  703.   printf("\n");
  704.   printf("\nwhere  <swN> is one of the following switches:");
  705.   printf("\n             /? = display this help message");
  706.   printf("\n             /H = output map as hex dump");
  707.   printf("\n             /K = output key table");
  708.   printf("\n             Note: switches may start with '/' or '-' and be in");
  709.   printf("\n                   upper or lower case.");
  710.   printf("\n       <param.N> is a map number in the range 1-10, or 'ALL'.");
  711.   printf("\n");
  712.   printf("\n");
  713.   printf("\nNotes:");
  714.   printf("\n   The files %s and %s must be in the current",FIN,FHEAD);
  715.   printf("\n   directory. The output is written to files LEVELxx.MAP");
  716.   printf("\n   or LEVELxx.HEX");
  717.   printf("\n");
  718.   exit(1);
  719. }
  720.  
  721. /*-------------------------------------------------------------------------*/
  722.