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