home *** CD-ROM | disk | FTP | other *** search
/ Doom Magazine 1 / Doom_magazine_01.bin / utils / wadinfo / wadinfo.c < prev    next >
C/C++ Source or Header  |  1994-08-26  |  111KB  |  2,054 lines

  1. /**********************************************************************************************************************************/
  2. /* File         : WADINFO.C                                                                                                       */
  3. /* Executable   : WADINFO.EXE                                                                                                     */
  4. /* Doc file     : None                                                                                                            */
  5. /* Version num  : 1.01                                                                                                            */
  6. /* Last changed : 23-08-1994  16:57                                                                                               */
  7. /* Update count : 4                                                                                                               */
  8. /* OS type      : if _AMIGA_ set    : AMIGA (Intuition, multitasking)                                                             */
  9. /*                                    Compiler : Aztec C Version 5.0a  Copyright 1989 by Manx Software Systems Inc. (Jan 9 1990)  */
  10. /*                                    Linker   : Aztec C68K Linker Version 5.0a  Copyright 1989 by Manx Software System Inc.      */
  11. /*                                    LN attr  : -lm -lc                                                                          */
  12. /*                if _AMIGA_ cleared: PC (DOS, singletasking)                                                                     */
  13. /*                                    Compiler : Microsoft (R) Quick C Compiler Version 2.00                                      */
  14. /*                                    Linker   : Microsoft (R) QuickC Linker Version 4.06                                         */
  15. /*                                    QCL attr : /AC /G2 /Ot /Zr                                                                  */
  16. /* Description  : Information extractor for DOOM (TM) WAD files.                                                                  */
  17. /* Other        : None                                                                                                            */
  18. /*                                                                                                                                */
  19. /*                                   By M. van der Heide of ThunderWare Research Center                                           */
  20. /**********************************************************************************************************************************/
  21.  
  22. /* Uncomment this line if compiling on the AMIGA */
  23. /* #define _AMIGA_ */
  24.  
  25.  
  26. #ifdef _AMIGA_
  27.   #include <intuition/intuition.h>
  28.   #include <graphics/gfxbase.h>
  29. #else
  30.   #include <stdlib.h>
  31.   #include <graph.h>
  32.   #include <malloc.h>
  33. #endif
  34.  
  35. #include   <stdio.h>
  36. #include   <ctype.h>
  37. #include   <stdarg.h>
  38. #include   <string.h>
  39. #include   <math.h>
  40.  
  41. #define    boolean            char
  42.  
  43. #ifdef _AMIGA_
  44.   #define  dbyte              short                                     /* An 'int' is 4 bytes ('long') in stead of 2 on an Amiga */
  45. #else
  46.   #define  dbyte              int
  47.   #define  TRUE               1
  48.   #define  FALSE              0
  49. #endif
  50.  
  51. #define    DBLACK             0                                             /* Define names for the standard (VGA) palette colors */
  52. #define    DBLUE              1
  53. #define    DGREEN             2
  54. #define    DCYAN              3
  55. #define    DRED               4
  56. #define    DMAGENTA           5
  57. #define    DYELLOW            6
  58. #define    DWHITE             7
  59. #define    LBLACK             8
  60. #define    LBLUE              9
  61. #define    LGREEN             10
  62. #define    LCYAN              11
  63. #define    LRED               12
  64. #define    LMAGENTA           13
  65. #define    LYELLOW            14
  66. #define    LWHITE             15
  67.  
  68. #define    NUMEPISODE         3                                             /* Define total number of episodes and levels/episode */
  69. #define    NUMLEVEL           9
  70.  
  71. #define    MAXCOLORS          2                                          /* Define number of WAD 'directory' identifiers per type */
  72. #define    MAXLEVELS          NUMEPISODE * NUMLEVEL
  73. #define    MAXSPRITES         77
  74. #define    MAXMUSIC           31
  75. #define    MAXSOUNDS          122
  76. #define    MAXGRAPHS          0
  77. #define    MAXINSTRUMENTS     1
  78. #define    MAXSTATUSBAR       2
  79. #define    MAXMENUS           39
  80.  
  81. #define    NEWCOLORS          0x01                                            /* Define bit-wise (storage) values for these types */
  82. #define    NEWSOUNDS          0x02
  83. #define    NEWSPRITES         0x04
  84. #define    NEWMUSIC           0x08
  85. #define    NEWGRAPHS          0x10
  86. #define    NEWINSTRUMENTS     0x20
  87. #define    NEWSTATUSBAR       0x40
  88. #define    NEWMENUS           0x80
  89.  
  90. #define    THING_PLAYER1      1                                                               /* Define the THINGS to check for : */
  91. #define    THING_PLAYER2      2                                                                                 /* Starting areas */
  92. #define    THING_PLAYER3      3
  93. #define    THING_PLAYER4      4
  94. #define    THING_DEATHMATCH   11
  95.  
  96. #define    THING_CHAINSAW     2005                                                                                     /* Weapons */
  97. #define    THING_SHOTGUN      2001
  98. #define    THING_CHAINGUN     2002
  99. #define    THING_LAUNCHER     2003
  100. #define    THING_PLASMAGUN    2004
  101. #define    THING_BFG9000      2006
  102.  
  103. #define    THING_TROOPER      3004                                                                                     /* Enemies */
  104. #define    THING_SARGEANT     9
  105. #define    THING_IMP          3001
  106. #define    THING_DEMON        3002
  107. #define    THING_SPECTRE      58
  108. #define    THING_CACODEMON    3005
  109. #define    THING_LOSTSOUL     3006
  110. #define    THING_BARON        3003
  111. #define    THING_CYBERDEMON   16
  112. #define    THING_SPIDERBOSS   7
  113.  
  114. #define    TYPE_CHAINSAW      0                                                 /* Define index-values for the THINGS identifiers */
  115. #define    TYPE_SHOTGUN       1
  116. #define    TYPE_CHAINGUN      2
  117. #define    TYPE_LAUNCHER      3
  118. #define    TYPE_PLASMAGUN     4
  119. #define    TYPE_BFG9000       5
  120. #define    TYPE_TROOPER       6
  121. #define    TYPE_SARGEANT      7
  122. #define    TYPE_IMP           8
  123. #define    TYPE_DEMON         9
  124. #define    TYPE_SPECTRE       10
  125. #define    TYPE_CACODEMON     11
  126. #define    TYPE_LOSTSOUL      12
  127. #define    TYPE_BARON         13
  128. #define    TYPE_CYBERDEMON    14
  129. #define    TYPE_SPIDERBOSS    15
  130.  
  131. #define    WHEN_D12           0x0001                                             /* Define difficulties for when a things appears */
  132. #define    WHEN_D3            0x0002
  133. #define    WHEN_D45           0x0004
  134. #define    WHEN_MULTI         0x0010
  135.  
  136. struct     WadInfo_s                                                              /* Group the main info on the WAD file together */
  137. {
  138.   char     NewStuff;                                                                          /* Things other than levels patched */
  139.   long     NewLevels;
  140.   dbyte    NewDemos;
  141. };
  142.  
  143. struct     WadHeader_s                                                           /* The first bytes of a WAD file: the WAD header */
  144. {
  145.   char     Type[4];                                                          /* Should be "PWAD" or "IWAD" for a (valid) WAD file */
  146.   unsigned long DirSize;                                                              /* Number of entries in the WAD 'directory' */
  147.   unsigned long DirStart;                                                              /* Pointer to start of the WAD 'directory' */
  148. };
  149.  
  150. struct     Directory_s                                                                        /* One entry in the WAD 'directory' */
  151. {
  152.   unsigned long Start;                                                                       /* Pointer to the data of this entry */
  153.   unsigned long Size;                                                                             /* Length of this data in bytes */
  154.   char     Name[8];                                                                                            /* Type identifier */
  155. };
  156.  
  157. struct     Thing_s                                                            /* One entry of the 'directory' entry type "THINGS" */
  158. {
  159.   dbyte    Xpos;                                                                                           /* Position on the map */
  160.   dbyte    Ypos;
  161.   dbyte    Angle;                                                                        /* Facing direction: north, east, etc... */
  162.   dbyte    Type;                                                                                                    /* Thing type */
  163.   dbyte    When;                                                                                                /* Appears when ? */
  164. };
  165.  
  166. struct     Vertex_s
  167. {
  168.   dbyte    MapX;
  169.   dbyte    MapY;
  170. };
  171.  
  172. struct     LineDef_s
  173. {
  174.   dbyte    Start;
  175.   dbyte    End;
  176.   dbyte    Flags;
  177.   dbyte    Type;
  178.   dbyte    Tag;
  179.   dbyte    SideDef1;
  180.   dbyte    SideDef2;
  181. };
  182.  
  183. struct     SideDef_s
  184. {
  185.   dbyte    OffsetX;
  186.   dbyte    OffsetY;
  187.   char     UpperTexture[8];
  188.   char     LowerTexture[8];
  189.   char     NormalTexture[8];
  190. };
  191.  
  192. struct     Seg_s
  193. {
  194.   dbyte    Start;
  195.   dbyte    End;
  196.   dbyte    Angle;
  197.   dbyte    LineDef;
  198.   dbyte    Flip;
  199.   dbyte    Distance;
  200. };
  201.  
  202. struct     Sector_s
  203. {
  204.   dbyte    FloorHeight;
  205.   dbyte    CeilingHeight;
  206.   char     FloorTexture[8];
  207.   char     CeilingTexture[8];
  208.   dbyte    LightLevel;
  209.   dbyte    Special;
  210.   dbyte    Tag;
  211. };
  212.  
  213. struct     SubSector_s
  214. {
  215.   dbyte    NumberOfSegs;
  216.   dbyte    FirstSeg;
  217. };
  218.  
  219. struct     Node_s
  220. {
  221.   dbyte    X;
  222.   dbyte    Y;
  223.   dbyte    Dx;
  224.   dbyte    Dy;
  225.   dbyte    FirstUpperBoundY;
  226.   dbyte    FirstLowerBoundY;
  227.   dbyte    FirstUpperBoundX;
  228.   dbyte    FirstLowerBoundX;
  229.   dbyte    SecondUpperBoundY;
  230.   dbyte    SecondLowerBoundY;
  231.   dbyte    SecondUpperBoundX;
  232.   dbyte    SecondLowerBoundX;
  233.   dbyte    Child1;
  234.   dbyte    Child2;
  235. };
  236.  
  237. struct     BlockMapHeader_s
  238. {
  239.   dbyte    OriginX;
  240.   dbyte    OriginY;
  241.   dbyte    BlockCntX;
  242.   dbyte    BlockCntY;
  243. };
  244.  
  245. struct     Remember_s
  246. {
  247.   int      PlayerStarts[5];                                                                /* 1-4 = startno, 5 = deathmatch start */
  248.   int      ThingType[16][4];                                                               /* 1 = D12, 2 = D3, 3 = D45, 4 = Multi */
  249.   dbyte    MinMapX;                                                                                                /* Vertex info */
  250.   dbyte    MinMapY;
  251.   dbyte    MaxMapX;
  252.   dbyte    MaxMapY;
  253.   dbyte    MapSizeX;
  254.   dbyte    MapSizeY;
  255.   struct   Directory_s ThingsLoc;
  256.   struct   Directory_s VertexLoc;
  257.   struct   Directory_s LineDefLoc;
  258.   struct   Directory_s SideDefLoc;
  259.   struct   Directory_s SegLoc;
  260.   struct   Directory_s SectorLoc;
  261.   struct   Directory_s SubSectorLoc;
  262.   struct   Directory_s NodeLoc;
  263.   struct   Directory_s RejectDataLoc;
  264.   struct   Directory_s BlockMapLoc;
  265.   boolean  ThingsFilled;
  266.   boolean  StatsFilled;
  267. };
  268.  
  269. struct     Check_s
  270. {
  271.   dbyte    StartMapX;
  272.   dbyte    StartMapY;
  273.   dbyte    EndMapX;
  274.   dbyte    EndMapY;
  275. };
  276.  
  277. struct     FieldId_s
  278. {
  279.   char    *IdName;
  280.   char    *Description;
  281.   char     Type;
  282.   boolean  FieldFilled;
  283. };
  284.  
  285. struct     WadHeader_s WadHeader;
  286. struct     Directory_s Directory;
  287. struct     WadInfo_s   WadInfo;
  288. struct     Thing_s     Thing;
  289. struct     Vertex_s    Vertex;
  290. struct     Remember_s  Remember[27];
  291.  
  292. char      *Levels[]            = {"E1M1", "E1M2", "E1M3", "E1M4", "E1M5", "E1M6", "E1M7", "E1M8", "E1M9",
  293.                                   "E2M1", "E2M2", "E2M3", "E2M4", "E2M5", "E2M6", "E2M7", "E2M8", "E2M9",
  294.                                   "E3M1", "E3M2", "E3M3", "E3M4", "E3M5", "E3M6", "E3M7", "E3M8", "E3M9"};
  295. char      *Colors[]            = {"PLAYPAL", "COLORMAP"};
  296. char      *StatusBar[]         = {"AMMNUM", "ST"};
  297. char      *Instruments[]       = {"GENMIDI"};
  298. struct     FieldId_s Music[]   = {{"D_INTER",  "Between the levels"             },
  299.                                   {"D_INTRO",  "Introduction music"             },
  300.                                   {"D_VICTOR", "After completing an episode"    },
  301.                                   {"D_BUNNY",  "While bunny is on the screen"   },
  302.                                   {"D_E1M1",   "Episode 1 Level 1"              },
  303.                                   {"D_E1M2",   "Episode 1 Level 2"              },
  304.                                   {"D_E1M3",   "Episode 1 Level 3"              },
  305.                                   {"D_E1M4",   "Episode 1 Level 4"              },
  306.                                   {"D_E1M5",   "Episode 1 Level 5"              },
  307.                                   {"D_E1M6",   "Episode 1 Level 6"              },
  308.                                   {"D_E1M7",   "Episode 1 Level 7"              },
  309.                                   {"D_E1M8",   "Episode 1 Level 8"              },
  310.                                   {"D_E1M9",   "Episode 1 Level 9"              },
  311.                                   {"D_E2M1",   "Episode 2 Level 1"              },
  312.                                   {"D_E2M2",   "Episode 2 Level 2"              },
  313.                                   {"D_E2M3",   "Episode 2 Level 3"              },
  314.                                   {"D_E2M4",   "Episode 2 Level 4"              },
  315.                                   {"D_E2M5",   "Episode 2 Level 5"              },
  316.                                   {"D_E2M6",   "Episode 2 Level 6"              },
  317.                                   {"D_E2M7",   "Episode 2 Level 7"              },
  318.                                   {"D_E2M8",   "Episode 2 Level 8"              },
  319.                                   {"D_E2M9",   "Episode 2 Level 9"              },
  320.                                   {"D_E3M1",   "Episode 3 Level 1"              },
  321.                                   {"D_E3M2",   "Episode 3 Level 2"              },
  322.                                   {"D_E3M3",   "Episode 3 Level 3"              },
  323.                                   {"D_E3M4",   "Episode 3 Level 4"              },
  324.                                   {"D_E3M5",   "Episode 3 Level 5"              },
  325.                                   {"D_E3M6",   "Episode 3 Level 6"              },
  326.                                   {"D_E3M7",   "Episode 3 Level 7"              },
  327.                                   {"D_E3M8",   "Episode 3 Level 8"              },
  328.                                   {"D_E3M9",   "Episode 3 Level 9"              }};
  329. struct     FieldId_s Menus[]   = {{"M_DOOM",   "DOOM",                         0},
  330.                                   {"M_NGAME",  "New Game",                     0},
  331.                                   {"M_OPTION", "Options",                      0},
  332.                                   {"M_LOADG",  "Load Game",                    0},
  333.                                   {"M_SAVEG",  "Save Game",                    0},
  334.                                   {"M_RDTHIS", "Read This!",                   0},
  335.                                   {"M_QUITG",  "Quit Game",                    0},
  336.                                   {"M_EPISOD", "Which Episode?",               1},
  337.                                   {"M_EPI1",   "Knee-Deep in the Dead",        1},
  338.                                   {"M_EPI2",   "The Shores of Hell",           1},
  339.                                   {"M_EPI3",   "Inferno",                      1},
  340.                                   {"M_NEWG",   "New Game",                     1},
  341.                                   {"M_SKILL",  "Choose a Skill Level",         1},
  342.                                   {"M_JKILL",  "I'm too young to die",         1},
  343.                                   {"M_ROUGH",  "Hey, not too rough",           1},
  344.                                   {"M_HURT",   "Hurt me planty",               1},
  345.                                   {"M_ULTRA",  "Ultra-Violence!",              1},
  346.                                   {"M_NMARE",  "Nightmare",                    1},
  347.                                   {"M_SVOL",   "Sound Volume",                 1},
  348.                                   {"M_SFXVOL", "Sfx Volume",                   1},
  349.                                   {"M_MUSVOL", "Music Volume",                 1},
  350.                                   {"M_ENDGAM", "End Game",                     2},
  351.                                   {"M_PAUSE",  "Pause",                        2},
  352.                                   {"M_MESSG",  "Messages:",                    2},
  353.                                   {"M_MSGON",  "on",                           2},
  354.                                   {"M_MSGOFF", "off",                          2},
  355.                                   {"M_OPTTTL", "Options",                      2},
  356.                                   {"M_DISP",   "Display",                      2},
  357.                                   {"M_MSENS",  "Mouse Sensitivity",            2},
  358.                                   {"M_GDHIGH", "high",                         2},
  359.                                   {"M_GDLOW",  "low",                          2},
  360.                                   {"M_DETAIL", "Graphic Detail",               2},
  361.                                   {"M_DISOPT", "Display options",              2},
  362.                                   {"M_SCRNSZ", "Screen Size",                  2},
  363.                                   {"M_SGTTL",  "Save Game",                    2},
  364.                                   {"M_LGTTL",  "Load Game",                    2},
  365.                                   {"M_SKULL",  "Selection skull",              3},
  366.                                   {"M_THERM",  "Volume slider",                3},
  367.                                   {"M_LS",     "Game name field in load/save", 3}};
  368. struct     FieldId_s Sprites[] = {{"PLAY",     "Player",                       0},
  369.                                   {"POSS",     "Trooper",                      0},
  370.                                   {"SPOS",     "Sargeant",                     0},
  371.                                   {"TROO",     "Imp",                          0},
  372.                                   {"SARG",     "Demon & Spectre",              0},
  373.                                   {"HEAD",     "Caco Demon",                   0},
  374.                                   {"SKUL",     "Lost Soul",                    0},
  375.                                   {"BOSS",     "Baron of Hell",                0},
  376.                                   {"CYBR",     "Cyber Demon",                  0},
  377.                                   {"SPID",     "Spider Demon",                 0},
  378.                                   {"BKEY",     "Blue keycard",                 1},
  379.                                   {"YKEY",     "Yellow keycard",               1},
  380.                                   {"RKEY",     "Red keycard",                  1},
  381.                                   {"BSKU",     "Blue skullkey",                1},
  382.                                   {"YSKU",     "Yellow skullkey",              1},
  383.                                   {"RSKU",     "Red skullkey",                 1},
  384.                                   {"PUN",      "Nothing in hand",              2},
  385.                                   {"SAW",      "Chainsaw in hand",             2},
  386.                                   {"PIS",      "Pistol in hand",               2},
  387.                                   {"SHT",      "Shotgun in hand",              2},
  388.                                   {"CHG",      "Chaingun in hand",             2},
  389.                                   {"PLS",      "Plasmagun in hand",            2},
  390.                                   {"BFG",      "BFG9000 in hand",              2},
  391.                                   {"CSAW",     "Chainsaw",                     2},
  392.                                   {"SHOT",     "Shotgun",                      2},
  393.                                   {"MGUN",     "Chaingun",                     2},
  394.                                   {"LAUN",     "Rocket launcher",              2},
  395.                                   {"PLAS",     "Plasmagun",                    2},
  396.                                   {"BFUG",     "BFG9000",                      2},
  397.                                   {"CLIP",     "Ammoclip",                     3},
  398.                                   {"AMMO",     "Box of ammo",                  3},
  399.                                   {"SHEL",     "Shells",                       3},
  400.                                   {"SBOX",     "Box of shells",                3},
  401.                                   {"ROCK",     "Rockets",                      3},
  402.                                   {"BROK",     "Box of rockets",               3},
  403.                                   {"CELL",     "Cells",                        3},
  404.                                   {"CELP",     "Box of cells",                 3},
  405.                                   {"BPAK",     "Backpack",                     3},
  406.                                   {"BON1",     "Healthbonus",                  4},
  407.                                   {"BON2",     "Armorbonus",                   4},
  408.                                   {"STIM",     "Stimpack",                     4},
  409.                                   {"MEDI",     "Medikit",                      4},
  410.                                   {"ARM1",     "Green armor",                  4},
  411.                                   {"ARM2",     "Blue armor",                   4},
  412.                                   {"SOUL",     "Supercharge",                  4},
  413.                                   {"PINS",     "Invisibility",                 4},
  414.                                   {"PINV",     "Invulnerability",              4},
  415.                                   {"PSTR",     "Berserk",                      4},
  416.                                   {"PMAP",     "Computer area map",            4},
  417.                                   {"PVIS",     "Light amplifier",              4},
  418.                                   {"SUIT",     "Radiation suit",               4},
  419.                                   {"BAR",      "Barrel",                       5},
  420.                                   {"BEXP",     "Barrel exploding",             5},
  421.                                   {"POL",      "Dead body",                    5},
  422.                                   {"GOR",      "Hanging body",                 5},
  423.                                   {"PBU",      NULL,                           6},
  424.                                   {"PSH",      NULL,                           6},
  425.                                   {"BAL",      NULL,                           6},
  426.                                   {"PUF",      NULL,                           6},
  427.                                   {"BLU",      NULL,                           6},
  428.                                   {"MIS",      NULL,                           6},
  429.                                   {"TFO",      NULL,                           6},
  430.                                   {"BFS",      NULL,                           6},
  431.                                   {"BFE",      NULL,                           6},
  432.                                   {"CAND",     NULL,                           7},
  433.                                   {"CBRA",     NULL,                           7},
  434.                                   {"COLU",     NULL,                           7},
  435.                                   {"ELEC",     NULL,                           7},
  436.                                   {"TRED",     NULL,                           7},
  437.                                   {"FSKU",     NULL,                           7},
  438.                                   {"CEYE",     NULL,                           7},
  439.                                   {"SMI",      NULL,                           7},
  440.                                   {"TGRN",     NULL,                           7},
  441.                                   {"TBLU",     NULL,                           7},
  442.                                   {"SMRT",     NULL,                           7},
  443.                                   {"SMBT",     NULL,                           7},
  444.                                   {"SMGT",     NULL,                           7}};
  445. struct     FieldId_s Sounds[]  = {{"DPPISTOL", "Pistol fire      "              },
  446.                                   {"DSPISTOL", NULL                             },
  447.                                   {"DPSHOTGN", "Shotgun fire     "              },
  448.                                   {"DSSHOTGN", NULL                             },
  449.                                   {"DPSGCOCK", "Shotgun cock     "              },
  450.                                   {"DSSGCOCK", NULL                             },
  451.                                   {"DPSAWUP",  "Chainsaw startup "              },
  452.                                   {"DSSAWUP",  NULL                             },
  453.                                   {"DPSAWIDL", "Chainsaw in rest "              },
  454.                                   {"DSSAWIDL", NULL                             },
  455.                                   {"DPSAWFUL", "Chainsaw active  "              },
  456.                                   {"DSSAWFUL", NULL                             },
  457.                                   {"DPSAWHIT", "Chainsaw hitting "              },
  458.                                   {"DSSAWHIT", NULL                             },
  459.                                   {"DPRLAUNC", "Rocket launch    "              },
  460.                                   {"DSRLAUNC", NULL                             },
  461.                                   {"DPRXPLOD", "BFG9000 launch   "              },
  462.                                   {"DSRXPLOD", NULL                             },
  463.                                   {"DPFIRSHT", "Fireball passing "              },
  464.                                   {"DSFIRSHT", NULL                             },
  465.                                   {"DPFIRXPL", "Fireball hitting "              },
  466.                                   {"DSFIRXPL", NULL                             },
  467.                                   {"DPPSTART", "Lift starting    "              },
  468.                                   {"DSPSTART", NULL                             },
  469.                                   {"DPPSTOP",  "Lift stopping    "              },
  470.                                   {"DSPSTOP",  NULL                             },
  471.                                   {"DPDOROPN", "Door opening     "              },
  472.                                   {"DSDOROPN", NULL                             },
  473.                                   {"DPDORCLS", "Door closing     "              },
  474.                                   {"DSDORCLS", NULL                             },
  475.                                   {"DPSTNMOV", "Floor moving     "              },
  476.                                   {"DSSTNMOV", NULL                             },
  477.                                   {"DPSWTCHN", "Switch returning "              },
  478.                                   {"DSSWTCHN", NULL                             },
  479.                                   {"DPSWTCHX", "Switch activated "              },
  480.                                   {"DSSWTCHX", NULL                             },
  481.                                   {"DPPLPAIN", "Player hurt      "              },
  482.                                   {"DSPLPAIN", NULL                             },
  483.                                   {"DPDMPAIN", "Trooper hurt     "              },
  484.                                   {"DSDMPAIN", NULL                             },
  485.                                   {"DPPOPAIN", "Sargeant hurt    "              },
  486.                                   {"DSPOPAIN", NULL                             },
  487.                                   {"DPSLOP",   "Total slaying    "              },
  488.                                   {"DSSLOP",   NULL                             },
  489.                                   {"DPITEMUP", "Item picked up   "              },
  490.                                   {"DSITEMUP", NULL                             },
  491.                                   {"DPWPNUP",  "Weapon picked up "              },
  492.                                   {"DSWPNUP",  NULL                             },
  493.                                   {"DPOOF",    "Player jumping   "              },
  494.                                   {"DSOOF",    NULL                             },
  495.                                   {"DPTELEPT", "Teleporter       "              },
  496.                                   {"DSTELEPT", NULL                             },
  497.                                   {"DPPOSIT1", "Trooper spots (1)"              },
  498.                                   {"DSPOSIT1", NULL                             },
  499.                                   {"DPPOSIT2", "Trooper spots (2)"              },
  500.                                   {"DSPOSIT2", NULL                             },
  501.                                   {"DPPOSIT3", "Trooper spots (3)"              },
  502.                                   {"DSPOSIT3", NULL                             },
  503.                                   {"DPBGSIT1", "Imp spots (1)    "              },
  504.                                   {"DSBGSIT1", NULL                             },
  505.                                   {"DPBGSIT2", "Imp spots (2)    "              },
  506.                                   {"DSBGSIT2", NULL                             },
  507.                                   {"DPSGTSIT", "Spectre spots    "              },
  508.                                   {"DSSGTSIT", NULL                             },
  509.                                   {"DPBRSSIT", "Baron spots      "              },
  510.                                   {"DSBRSSIT", NULL                             },
  511.                                   {"DPSGTATK", "Spectre attacks  "              },
  512.                                   {"DSSGTATK", NULL                             },
  513.                                   {"DPCLAW",   "Spectre hits     "              },
  514.                                   {"DSCLAW",   NULL                             },
  515.                                   {"DPPLDETH", "Player died      "              },
  516.                                   {"DSPLDETH", NULL                             },
  517.                                   {"DPPODTH1", "Trooper died (1) "              },
  518.                                   {"DSPODTH1", NULL                             },
  519.                                   {"DPPODTH2", "Trooper died (2) "              },
  520.                                   {"DSPODTH2", NULL                             },
  521.                                   {"DPPODTH3", "Trooper died (3) "              },
  522.                                   {"DSPODTH3", NULL                             },
  523.                                   {"DPBGDTH1", "Imp died (1)     "              },
  524.                                   {"DSBGDTH1", NULL                             },
  525.                                   {"DPBGDTH2", "Imp died (2)     "              },
  526.                                   {"DSBGDTH2", NULL                             },
  527.                                   {"DPSGTDTH", "Spectre died     "              },
  528.                                   {"DSSGTDTH", NULL                             },
  529.                                   {"DPBRSDTH", "Baron died       "              },
  530.                                   {"DSBRSDTH", NULL                             },
  531.                                   {"DPPOSACT", "Trooper nearby   "              },
  532.                                   {"DSPOSACT", NULL                             },
  533.                                   {"DPBGACT",  "Imp nearby       "              },
  534.                                   {"DSBGACT",  NULL                             },
  535.                                   {"DPDMACT",  "Spectre nearby   "              },
  536.                                   {"DSDMACT",  NULL                             },
  537.                                   {"DPNOWAY",  "Pushed on wall   "              },
  538.                                   {"DSNOWAY",  NULL                             },
  539.                                   {"DPBAREXP", "Barrel exploding "              },
  540.                                   {"DSBAREXP", NULL                             },
  541.                                   {"DPPUNCH",  "Player punching  "              },
  542.                                   {"DSPUNCH",  NULL                             },
  543.                                   {"DPPLASMA", "Plasmagun fire   "              },
  544.                                   {"DSPLASMA", NULL                             },
  545.                                   {"DPBFG",    "BFG9000 fire     "              },
  546.                                   {"DSBFG",    NULL                             },
  547.                                   {"DPCACSIT", "Caco Demon spots "              },
  548.                                   {"DSCACSIT", NULL                             },
  549.                                   {"DPCYBSIT", "Cyber Demon spots"              },
  550.                                   {"DSCYBSIT", NULL                             },
  551.                                   {"DPSPISIT", "Spider spots     "              },
  552.                                   {"DSSPISIT", NULL                             },
  553.                                   {"DPSKLATK", "Lost Soul attacks"              },
  554.                                   {"DSSKLATK", NULL                             },
  555.                                   {"DPCACDTH", "Caco Demon died  "              },
  556.                                   {"DSCACDTH", NULL                             },
  557.                                   {"DPSKLDTH", "Lost Soul died   "              },
  558.                                   {"DSSKLDTH", NULL                             },
  559.                                   {"DPCYBDTH", "Cyber Demon died "              },
  560.                                   {"DSCYBDTH", NULL                             },
  561.                                   {"DPSPIDTH", "Spider Demon died"              },
  562.                                   {"DSSPIDTH", NULL                             },
  563.                                   {"DPHOOF",   "Cyber Demon walks"              },
  564.                                   {"DSHOOF",   NULL                             },
  565.                                   {"DPMETAL",  "Metal (?)        "              },
  566.                                   {"DSMETAL",  NULL                             }};
  567. #ifdef _AMIGA_
  568. struct GfxBase       *GfxBase;                                                                     /* Pointer to graphics library */
  569. struct IntuitionBase *IntuitionBase;                                                              /* Pointer to intuition library */
  570. struct Screen        *Screen;                                                                        /* Pointer to current screen */
  571. struct Window        *Window;                                                                        /* Pointer to current window */
  572. struct NewScreen      FirstScreen;
  573. struct NewWindow      FirstWindow;
  574. struct IntuiMessage  *IntuiMessage;                                                                     /* Message from intuition */
  575. unsigned long         MessageClass;                                                                                  /* 'From' ID */
  576. unsigned short        Code;                                                                               /* Value of the message */
  577. #else
  578. unsigned int          Key;
  579. #endif
  580.  
  581. void PrText (short Y0, short X0, unsigned char Color, char *Msg, ...)
  582.  
  583. /**********************************************************************************************************************************/
  584. /* Pre   : 'Y0' and 'X0' hold the coordinates, 'Color' holds the (VGA) color and 'Msg' holds the message to print.                */
  585. /* Post  : If the coordinates were non-zero, then the message is printed at these coordinates in the given color. In case of the  */
  586. /*         AMIGA, the coordinates have been converted from pixel- to textcoordinates.                                             */
  587. /*         If X0 = 0, then the coordinates are not used;                                                                          */
  588. /*         If X0 = -1, then the text is centered on line Y0.                                                                      */
  589. /* Import: None.                                                                                                                  */
  590. /**********************************************************************************************************************************/
  591.  
  592. {
  593.   char     Message[80];
  594.   va_list  Args;
  595.   int      X1;
  596.   int      Y1;
  597.  
  598.   va_start (Args, Msg);
  599.   vsprintf (Message, Msg, Args);                                                           /* Convert the message into one string */
  600.   va_end (Args);
  601. #ifdef _AMIGA_
  602.   X1 = X0 * 8;                                                                                           /* Fontwidth is 8 pixels */
  603.   Y1 = Y0 * 8 + 18;                                                     /* Fontheight is 8 pixels, start past the window titlebar */
  604.   if (X0 == -1)
  605.     X1 = ((80 - strlen (Message)) / 2) * 8;
  606.   if (X0 != 0)
  607.     Move (&Screen->RastPort, X1, Y1);
  608.   SetAPen (&Screen->RastPort, Color);
  609.   Text (&Screen->RastPort, Message, strlen (Message));
  610. #else
  611.   if (X0 == -1)
  612.     _settextposition (Y0, (80 - strlen (Message)) / 2);
  613.   if (X0 > 0)
  614.     _settextposition (Y0, X0);
  615.   _settextcolor (Color);
  616.   _outtext (Message);
  617. #endif
  618. }
  619.  
  620. void ClearScreen (void)
  621.  
  622. /**********************************************************************************************************************************/
  623. /* Pre   : None.                                                                                                                  */
  624. /* Post  : The screen has been cleared.                                                                                           */
  625. /* Import: PrText.                                                                                                                */
  626. /**********************************************************************************************************************************/
  627.  
  628. {
  629.   int N;
  630.  
  631. #ifdef _AMIGA_
  632.   for (N = 1 ; N < 30 ; N ++)
  633.     PrText (N, 1, DBLACK, "                                                                              ");
  634. #else
  635.   _clearscreen (_GCLEARSCREEN);
  636. #endif
  637. }
  638.  
  639. #ifdef _AMIGA_
  640.  
  641.   void CloseAllIntuition (void)
  642.  
  643.   /********************************************************************************************************************************/
  644.   /* Pre   : None.                                                                                                                */
  645.   /* Post  : All windows and screens have been closed, all libraries have been released.                                          */
  646.   /* Import: None.                                                                                                                */
  647.   /********************************************************************************************************************************/
  648.  
  649.   {
  650.     if (Window)
  651.       CloseWindow (Window);
  652.     if (Screen)
  653.       CloseScreen (Screen);
  654.     if (IntuitionBase)
  655.       CloseLibrary (IntuitionBase);
  656.     if (GfxBase)
  657.       CloseLibrary (GfxBase);
  658.   }
  659.  
  660.   void SwapDbyte (dbyte *Number)
  661.  
  662.   /********************************************************************************************************************************/
  663.   /* Pre   : 'Number' holds a pointer to the dbyte that should be swapped.                                                        */
  664.   /* Post  : The number is converted from Little Endian to Big Endian (or vice versa).                                            */
  665.   /* Import: None.                                                                                                                */
  666.   /********************************************************************************************************************************/
  667.  
  668.   {
  669.     unsigned char *Cp;
  670.     unsigned char  Temp;
  671.   
  672.     Cp = (unsigned char *)Number;
  673.     Temp = *Cp;
  674.     *Cp = *(Cp + 1);
  675.     *(Cp + 1) = Temp;
  676.   }
  677.  
  678.   void SwapLong (unsigned long *Number)
  679.  
  680.   /********************************************************************************************************************************/
  681.   /* Pre   : 'Number' holds a pointer to the long that should be swapped.                                                         */
  682.   /* Post  : The number is converted from Little Endian to Big Endian (or vice versa).                                            */
  683.   /* Import: None.                                                                                                                */
  684.   /********************************************************************************************************************************/
  685.  
  686.   {
  687.     unsigned char *Cp;
  688.     unsigned char  Temp;
  689.   
  690.     Cp = (unsigned char *)Number;
  691.     Temp = *Cp;                                                                                             /* Swap bytes 0 and 3 */
  692.     *Cp = *(Cp + 3);
  693.     *(Cp + 3) = Temp;
  694.     Temp = *(Cp + 1);                                                                                       /* Swap bytes 1 and 2 */
  695.     *(Cp + 1) = *(Cp + 2);
  696.     *(Cp + 2) = Temp;
  697.   }
  698.  
  699. #endif
  700.  
  701. void Bye (char *Message)
  702.  
  703. /**********************************************************************************************************************************/
  704. /* Pre   : 'Message' holds the errormessage.                                                                                      */
  705. /* Post  : 'Message' has been printed, any open file has been closed and the program is aborted.                                  */
  706. /* Import: CloseAllIntuition.                                                                                                     */
  707. /**********************************************************************************************************************************/
  708.  
  709. {
  710.   #ifdef _AMIGA_
  711.     CloseAllIntuition ();
  712.   #else
  713.     fcloseall ();
  714.     flushall ();
  715.     _setvideomode (_DEFAULTMODE);
  716.   #endif
  717.   fprintf (stderr, "%s\n", Message);
  718.   exit (0);
  719. }
  720.  
  721. #ifdef _AMIGA_
  722.  
  723.   void OpenAllIntuition (void)
  724.  
  725.   /********************************************************************************************************************************/
  726.   /* Pre   : None.                                                                                                                */
  727.   /* Post  : First the graphics and intuition libraries have been opened. After this a screen has been opened, in a resolution of */
  728.   /*         640x256x16, without titlebar. After this has a window been opened with the exact same size, which is layed over the  */
  729.   /*         screen. Finally, the palette has been converted to match the standard VGA colors of the PC.                          */
  730.   /* Import: Bye.                                                                                                                 */
  731.   /********************************************************************************************************************************/
  732.  
  733.   {
  734.     FirstScreen.LeftEdge     = 0;                                                                          /* Initialize a screen */
  735.     FirstScreen.TopEdge      = 0;
  736.     FirstScreen.Width        = 640;
  737.     FirstScreen.Height       = 256;
  738.     FirstScreen.Depth        = 4;                                                                                    /* 16 colors */
  739.     FirstScreen.DetailPen    = 0;
  740.     FirstScreen.BlockPen     = 0;
  741.     FirstScreen.ViewModes    = HIRES;
  742.     FirstScreen.Type         = CUSTOMSCREEN;
  743.     FirstScreen.Font         = NULL;
  744.     FirstScreen.DefaultTitle = NULL;
  745.     FirstScreen.Gadgets      = NULL;
  746.     FirstScreen.CustomBitMap = NULL;
  747.     
  748.     FirstWindow.LeftEdge     = 0;                                                                        /* Initialize the window */
  749.     FirstWindow.TopEdge      = 0;
  750.     FirstWindow.Width        = 640;
  751.     FirstWindow.Height       = 256;
  752.     FirstWindow.DetailPen    = DBLACK;
  753.     FirstWindow.BlockPen     = LCYAN;
  754.     FirstWindow.IDCMPFlags   = CLOSEWINDOW|VANILLAKEY;             /* React to: close-gadget and keyboard (convert keys to ASCII) */
  755.     FirstWindow.Flags        = WINDOWCLOSE|ACTIVATE|SMART_REFRESH;
  756.     FirstWindow.FirstGadget  = NULL;
  757.     FirstWindow.CheckMark    = NULL;
  758.     FirstWindow.Title        = (unsigned char *)"WADinfo";
  759.     FirstWindow.Type         = CUSTOMSCREEN;
  760.  
  761.     if (!(GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L)))                                /* Open the libraries */
  762.       Bye ("ERROR - Graphics Library not found\n");
  763.     if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L)))
  764.       Bye ("ERROR - Intuition Library not found\n");
  765.     if (!(Screen = (struct Screen *)OpenScreen (&FirstScreen)))                                                /* Open the screen */
  766.       Bye ("ERROR - Cannot open screen\n");
  767.     FirstWindow.Screen = Screen;                                                                /* Link the window to this screen */
  768.     if (!(Window = (struct Window *)OpenWindow (&FirstWindow)))                                                /* Open the window */
  769.       Bye ("ERROR - Cannot open window\n");
  770.  
  771.     SetRGB4 (&Screen->ViewPort, DBLACK  ,  0,  0,  0);                                /* Convert the palette to standard VGA (PC) */
  772.     SetRGB4 (&Screen->ViewPort, DBLUE   ,  0,  0,  8);
  773.     SetRGB4 (&Screen->ViewPort, DGREEN  ,  0,  8,  0);
  774.     SetRGB4 (&Screen->ViewPort, DCYAN   ,  0,  8,  8);
  775.     SetRGB4 (&Screen->ViewPort, DRED    ,  8,  0,  0);
  776.     SetRGB4 (&Screen->ViewPort, DMAGENTA,  8,  0,  8);
  777.     SetRGB4 (&Screen->ViewPort, DYELLOW ,  8,  8,  0);
  778.     SetRGB4 (&Screen->ViewPort, DWHITE  ,  8,  8,  8);
  779.     SetRGB4 (&Screen->ViewPort, LBLACK  ,  5,  5,  5);
  780.     SetRGB4 (&Screen->ViewPort, LBLUE   ,  0,  0, 15);
  781.     SetRGB4 (&Screen->ViewPort, LGREEN  ,  0, 15,  0);
  782.     SetRGB4 (&Screen->ViewPort, LCYAN   ,  0, 15, 15);
  783.     SetRGB4 (&Screen->ViewPort, LRED    , 15,  0,  0);
  784.     SetRGB4 (&Screen->ViewPort, LMAGENTA, 15,  0, 15);
  785.     SetRGB4 (&Screen->ViewPort, LYELLOW , 15, 15,  0);
  786.     SetRGB4 (&Screen->ViewPort, LWHITE  , 15, 15, 15);
  787.   }
  788.  
  789. #endif
  790.  
  791. void ListSprites (void)
  792.  
  793. /**********************************************************************************************************************************/
  794. /* Pre   : None.                                                                                                                  */
  795. /* Post  : The new sprites in this WAD file have been listed on a cleared screen.                                                 */
  796. /* Import: ClearScreen, PrText.                                                                                                   */
  797. /**********************************************************************************************************************************/
  798.  
  799. {
  800.   int     Cnt;
  801.   int     Xco       = 1;
  802.   int     Yco       = 3;
  803.   boolean Type6Done = FALSE;
  804.   boolean Type7Done = FALSE;
  805.   boolean AdjustCo;
  806.  
  807.   ClearScreen ();
  808.   PrText (1, -1, LBLUE, "NEW SPRITES IN THIS WAD FILE:");
  809.   for (Cnt = 0 ; Cnt < MAXSPRITES ; Cnt ++)
  810.     if (Sprites[Cnt].FieldFilled)
  811.     {
  812.       AdjustCo = TRUE;
  813.       switch (Sprites[Cnt].Type)
  814.       {
  815.         case 0 : PrText (Yco, Xco, DCYAN, "ENEMY  ");
  816.                  PrText (  0,   0, LCYAN, Sprites[Cnt].Description);
  817.                  break;
  818.         case 1 : PrText (Yco, Xco, DCYAN, "CARD   ");
  819.                  PrText (  0,   0, LCYAN, Sprites[Cnt].Description);
  820.                  break;
  821.         case 2 : PrText (Yco, Xco, DCYAN, "WEAPON ");
  822.                  PrText (  0,   0, LCYAN, Sprites[Cnt].Description);
  823.                  break;
  824.         case 3 : PrText (Yco, Xco, DCYAN, "AMMO   ");
  825.                  PrText (  0,   0, LCYAN, Sprites[Cnt].Description);
  826.                  break;
  827.         case 4 : PrText (Yco, Xco, DCYAN, "BONUS  ");
  828.                  PrText (  0,   0, LCYAN, Sprites[Cnt].Description);
  829.                  break;
  830.         case 5 : PrText (Yco, Xco, DCYAN, "DECOR  ");
  831.                  PrText (  0,   0, LCYAN, Sprites[Cnt].Description);
  832.                  break;
  833.         case 6 : if (!Type6Done)
  834.                  {
  835.                    PrText (Yco, Xco, LCYAN, "Miscelanious weaponfire");
  836.                    Type6Done = TRUE;
  837.                  }
  838.                  else
  839.                    AdjustCo = FALSE;
  840.                  break;
  841.         case 7 : if (!Type7Done)
  842.                  {
  843.                    PrText (Yco, Xco, LCYAN, "Miscelanious decorations");
  844.                    Type7Done = TRUE;
  845.                  }
  846.                  else
  847.                    AdjustCo = FALSE;
  848.                  break;
  849.         default: PrText (Yco, Xco, LRED, "Unknown type %d for %s", Sprites[Cnt].Type, Sprites[Cnt].IdName);
  850.       }
  851.       if (AdjustCo)
  852.         if (++ Yco > 26)
  853.         {
  854.           Yco = 3;
  855.           Xco += 26;
  856.         }
  857.     }
  858.   PrText (28, -1, DYELLOW, "Any key to return...");
  859. }
  860.       
  861. void ListMenus (void)
  862.  
  863. /**********************************************************************************************************************************/
  864. /* Pre   : None.                                                                                                                  */
  865. /* Post  : The new menu items in this WAD file have been listed on a cleared screen.                                              */
  866. /* Import: ClearScreen, PrText.                                                                                                   */
  867. /**********************************************************************************************************************************/
  868.  
  869. {
  870.   int Cnt;
  871.   int Xco = 1;
  872.   int Yco = 3;
  873.  
  874.   ClearScreen ();
  875.   PrText (1, -1, LBLUE, "NEW MENU ITEMS IN THIS WAD FILE:");
  876.   for (Cnt = 0 ; Cnt < MAXMENUS ; Cnt ++)
  877.     if (Menus[Cnt].FieldFilled)
  878.     {
  879.       switch (Menus[Cnt].Type)
  880.       {
  881.         case 0 : PrText (Yco, Xco, DCYAN, "MAIN MENU ");
  882.                  PrText (  0,   0, LCYAN, "\'%s\'", Menus[Cnt].Description);
  883.                  break;
  884.         case 1 : PrText (Yco, Xco, DCYAN, "SUBMENU   ");
  885.                  PrText (  0,   0, LCYAN, "\'%s\'", Menus[Cnt].Description);
  886.                  break;
  887.         case 2 : PrText (Yco, Xco, DCYAN, "PLAYING   ");
  888.                  PrText (  0,   0, LCYAN, "\'%s\'", Menus[Cnt].Description);
  889.                  break;
  890.         case 3 : PrText (Yco, Xco, DCYAN, "MISC      ");
  891.                  PrText (  0,   0, LCYAN, Menus[Cnt].Description);
  892.       }
  893.       if (++ Yco > 26)
  894.       {
  895.         Yco = 3;
  896.         Xco += 36;
  897.       }
  898.     }
  899.   PrText (28, -1, DYELLOW, "Any key to return...");
  900. }
  901.       
  902. void ListMusic (void)
  903.  
  904. /**********************************************************************************************************************************/
  905. /* Pre   : None.                                                                                                                  */
  906. /* Post  : The new music in this WAD file has been listed on a cleared screen.                                                    */
  907. /* Import: ClearScreen, PrText.                                                                                                   */
  908. /**********************************************************************************************************************************/
  909.  
  910. {
  911.   int Cnt;
  912.   int Xco  = 1;
  913.   int Yco  = 3;
  914.  
  915.   ClearScreen ();
  916.   PrText (1, -1, LBLUE, "NEW MUSIC IN THIS WAD FILE:");
  917.   for (Cnt = 0 ; Cnt < MAXMUSIC ; Cnt ++)
  918.     if (Music[Cnt].FieldFilled)
  919.     {
  920.       PrText (Yco, Xco, LCYAN, Music[Cnt].Description);
  921.       if (++ Yco > 26)
  922.       {
  923.         Yco = 3;
  924.         Xco += 36;
  925.       }
  926.     }
  927.   PrText (28, -1, DYELLOW, "Any key to return...");
  928. }
  929.       
  930. void ListSounds (void)
  931.  
  932. /**********************************************************************************************************************************/
  933. /* Pre   : None.                                                                                                                  */
  934. /* Post  : The new sounds in this WAD file have been listed on a cleared screen.                                                  */
  935. /* Import: ClearScreen, PrText.                                                                                                   */
  936. /**********************************************************************************************************************************/
  937.  
  938. {
  939.   int Cnt;
  940.   int Xco  = 1;
  941.   int Yco  = 4;
  942.  
  943.   ClearScreen ();
  944.   PrText (1, -1, LBLUE, "NEW SOUNDS IN THIS WAD FILE:");
  945.   PrText (2, -1, LBLUE, "\'Spectre\' means \'Demon & Spectre\', \'spots\' means \'spots player\'");
  946.   for (Cnt = 0 ; Cnt < MAXSOUNDS ; Cnt += 2)
  947.     if (Sounds[Cnt].FieldFilled || Sounds[Cnt + 1].FieldFilled)
  948.     {
  949.       PrText (Yco, Xco, DCYAN, "[%2d] ", (Cnt / 2) + 1);
  950.       PrText (  0,   0, LCYAN, Sounds[Cnt].Description);
  951.       if (++ Yco > 26)
  952.       {
  953.         Yco = 4;
  954.         Xco += 27;
  955.       }
  956.     }
  957.   PrText (28, -1, DYELLOW, "Any key to return...");
  958. }
  959.       
  960. void CheckLevel (FILE *Fp, char MemNum)
  961.  
  962. /**********************************************************************************************************************************/
  963. /* Pre   : 'Fp' points to the open WAD file, 'MemNum' holds the ('Remember') level number to check.                               */
  964. /* Post  : The following tests have been made:                                                                                    */
  965. /*         - All LINEDEFS have a length of > 0;                                                                                   */
  966. /*         - All LINEDEFS use existing SIDEDEF numbers;                                                                           */
  967. /*         - All LINEDEFS use existing VERTEX numbers for Start and End values;                                                   */
  968. /*         - The BLOCKMAP start is <= lowest VERTEX number;                                                                       */
  969. /*         - The number of blocks in the BLOCKMAP is enough to fit the map;                                                       */
  970. /*         - All blocks contents in the BLOCKMAP start with a 0x0000 and end with a 0xFFFF;                                       */
  971. /*         - All used LINEDEFS in the BLOCKMAP exist;                                                                             */
  972. /*         - All used LINEDEFS in a block of the BLOCKMAP are indeed in the block (starting, ending or crossing);                 */
  973. /*         - The length of the REJECT data is ((number_of_SECTORS ^ 2) / 8), rounded upwards.                                     */
  974. /*         - All THINGS have valid coordinates;                                                                                   */
  975. /*         - All THINGS have valid angles of appearance;                                                                          */
  976. /*         - All THINGS are of known type;                                                                                        */
  977. /* Import: PrText, SwapDbyte, Bye.                                                                                                */
  978. /**********************************************************************************************************************************/
  979.  
  980. {
  981.   struct BlockMapHeader_s BlockMapHeader;
  982.   struct LineDef_s        LineDef;
  983.   struct Vertex_s        *VertexInfo;
  984.   struct Check_s         *LineInfo;
  985.   dbyte                  *BlockInfo;
  986.   dbyte                   BlockOffset;
  987.   dbyte                   BlockNumber;
  988.   dbyte                   N;
  989.   dbyte                   TestMapX;
  990.   dbyte                   TestMapY;
  991.   dbyte                   TestMapX2;
  992.   dbyte                   TestMapY2;
  993.   dbyte                   NumberOfLineDefs;
  994.   dbyte                   NumberOfSideDefs;
  995.   dbyte                   NumberOfVertexes;
  996.   dbyte                   BlockMinX;
  997.   dbyte                   BlockMinY;
  998.   dbyte                   BlockMaxX;
  999.   dbyte                   BlockMaxY;
  1000.   dbyte                   CntX;
  1001.   dbyte                   CntY;
  1002.   dbyte                   LineDefNumber;
  1003.   char                    NextLine;
  1004.   long                    Entries;
  1005.   long                    BlockMapInfoSize;
  1006.   boolean                 More;
  1007.  
  1008.   for (N = 3 ; N < 29 ; N ++)
  1009.     PrText (N, 40, DBLACK, "                                       ");
  1010.   NextLine = 3;
  1011.   NumberOfLineDefs = Remember[MemNum].LineDefLoc.Size / sizeof (struct LineDef_s);
  1012.   NumberOfSideDefs = Remember[MemNum].SideDefLoc.Size / sizeof (struct SideDef_s);
  1013.   NumberOfVertexes = Remember[MemNum].VertexLoc.Size / sizeof (struct Vertex_s);
  1014.   if ((LineInfo = ((struct Check_s *)malloc ((size_t)(sizeof (struct Check_s) * NumberOfLineDefs)))) == NULL)
  1015.     Bye ("ERROR - Could not allocate enough memory\n");
  1016.   if ((VertexInfo = ((struct Vertex_s *)malloc ((size_t)(sizeof (struct Vertex_s) * NumberOfVertexes)))) == NULL)
  1017.     Bye ("ERROR - Could not allocate enough memory\n");
  1018.   PrText (1, 68, DWHITE, "Loading...");
  1019.   if (fseek (Fp, Remember[MemNum].VertexLoc.Start, SEEK_SET))
  1020.     Bye ("ERROR - File location error\n");
  1021.   if (fread (VertexInfo, 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s))                       /* Read first vertex */
  1022.     Bye ("ERROR - File read error\n");
  1023. #ifdef _AMIGA_
  1024.   SwapDbyte (&VertexInfo->MapX);
  1025.   SwapDbyte (&VertexInfo->MapY);
  1026. #endif
  1027.   Remember[MemNum].MinMapX = Remember[MemNum].MaxMapX = VertexInfo->MapX;
  1028.   Remember[MemNum].MinMapY = Remember[MemNum].MaxMapY = VertexInfo->MapY;
  1029.   N = 1;
  1030.   Entries = sizeof (struct Vertex_s);
  1031.   while (Entries < Remember[MemNum].VertexLoc.Size)                                                         /* Handle all entries */
  1032.   {
  1033.     if (fread ((VertexInfo + N), 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s))
  1034.       Bye ("ERROR - File read error\n");
  1035. #ifdef _AMIGA_
  1036.     SwapDbyte (&(VertexInfo + N)->MapX);
  1037.     SwapDbyte (&(VertexInfo + N)->MapY);
  1038. #endif
  1039.     if ((VertexInfo + N)->MapX < Remember[MemNum].MinMapX)
  1040.       Remember[MemNum].MinMapX = (VertexInfo + N)->MapX;
  1041.     if ((VertexInfo + N)->MapX > Remember[MemNum].MaxMapX)
  1042.       Remember[MemNum].MaxMapX = (VertexInfo + N)->MapX;
  1043.     if ((VertexInfo + N)->MapY < Remember[MemNum].MinMapY)
  1044.       Remember[MemNum].MinMapY = (VertexInfo + N)->MapY;
  1045.     if ((VertexInfo + N)->MapY > Remember[MemNum].MaxMapY)
  1046.       Remember[MemNum].MaxMapY = (VertexInfo + N)->MapY;
  1047.     Entries += sizeof (struct Vertex_s);
  1048.     N ++;
  1049.   }
  1050.   if (Remember[MemNum].MinMapX < 0)
  1051.     Remember[MemNum].MapSizeX = -Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
  1052.   else
  1053.     Remember[MemNum].MapSizeX = Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
  1054.   if (Remember[MemNum].MinMapY < 0)
  1055.     Remember[MemNum].MapSizeY = -Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
  1056.   else
  1057.     Remember[MemNum].MapSizeY = Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
  1058.   PrText (NextLine, 40, DMAGENTA, "LINEDEFS consistency check:");
  1059.   if (fseek (Fp, Remember[MemNum].LineDefLoc.Start, SEEK_SET))
  1060.     Bye ("ERROR - File location error\n");
  1061.   Entries = 0;
  1062.   N = 0;
  1063.   More = TRUE;
  1064.   while (Entries < Remember[MemNum].LineDefLoc.Size)                                                        /* Handle all entries */
  1065.   {
  1066.     if (fread (&LineDef, 1, sizeof (struct LineDef_s), Fp) != sizeof (struct LineDef_s))
  1067.       Bye ("ERROR - File read error\n");
  1068. #ifdef _AMIGA_
  1069.     SwapDbyte (&LineDef.Start);
  1070.     SwapDbyte (&LineDef.End);
  1071.     SwapDbyte (&LineDef.SideDef1);
  1072.     SwapDbyte (&LineDef.SideDef2);
  1073. #endif
  1074.     if (LineDef.Start == LineDef.End)                                                               /* A LineDef with zero length */
  1075.     {
  1076.       PrText (NextLine + 1, 42, LRED, "LineDef %d has zero length", N);
  1077.       More = FALSE;
  1078.     }
  1079.     else
  1080.       if (LineDef.SideDef1 >= NumberOfSideDefs || (LineDef.SideDef2 != 0xFFFF && LineDef.SideDef2 >= NumberOfSideDefs))
  1081.       {                                                                                                 /* Non-existent SideDef ? */
  1082.         PrText (NextLine + 1, 42, LRED, "LineDef %d has an unknown SideDef", N);
  1083.         More = FALSE;
  1084.       }
  1085.     if (LineDef.Start >= NumberOfVertexes || LineDef.End >= NumberOfVertexes)                            /* Non-existent Vertex ? */
  1086.     {
  1087.       if (More)                                                                             /* Already an error-message printed ? */
  1088.         PrText (NextLine + 1, 42, LRED, "LineDef %d has an unknown Vertex", N);
  1089.       (LineInfo + N)->StartMapX = 0x8000;                                          /* Ensure that the coordinates are off the map */
  1090.       (LineInfo + N)->StartMapY = 0x8000;
  1091.       (LineInfo + N)->EndMapX = 0x8000;
  1092.       (LineInfo + N)->EndMapY = 0x8000;
  1093.       More = FALSE;
  1094.     }
  1095.     else
  1096.     {
  1097.       (LineInfo + N)->StartMapX = (VertexInfo + LineDef.Start)->MapX;
  1098.       (LineInfo + N)->StartMapY = (VertexInfo + LineDef.Start)->MapY;
  1099.       (LineInfo + N)->EndMapX = (VertexInfo + LineDef.End)->MapX;
  1100.       (LineInfo + N)->EndMapY = (VertexInfo + LineDef.End)->MapY;
  1101.     }
  1102.     N ++;
  1103.     Entries += sizeof (struct LineDef_s);
  1104.   }
  1105.   if (More)
  1106.   {
  1107.     PrText (NextLine, 73, LMAGENTA, "Passed");
  1108.     NextLine += 2;
  1109.   }
  1110.   else
  1111.   {
  1112.     PrText (NextLine, 73, LRED, "FAILED");
  1113.     NextLine += 3;
  1114.   }
  1115.   free (VertexInfo);
  1116.   if (fseek (Fp, Remember[MemNum].BlockMapLoc.Start, SEEK_SET))
  1117.     Bye ("ERROR - File location error\n");
  1118.   if (fread (&BlockMapHeader, 1, sizeof (struct BlockMapHeader_s), Fp) != sizeof (struct BlockMapHeader_s))
  1119.     Bye ("ERROR - File read error\n");
  1120.   BlockMapInfoSize = (size_t)(Remember[MemNum].BlockMapLoc.Size - sizeof (struct BlockMapHeader_s));
  1121.   if ((BlockInfo = ((dbyte *)malloc (BlockMapInfoSize))) == NULL)
  1122.     Bye ("ERROR - Could not allocate enough memory\n");
  1123.   if (fread (BlockInfo, 1, BlockMapInfoSize, Fp) != BlockMapInfoSize)
  1124.     Bye ("ERROR - File read error\n");
  1125.   PrText (1, 68, DWHITE, "          ");
  1126. #ifdef _AMIGA_
  1127.   for (N = 0 ; N < (BlockMapInfoSize / sizeof (dbyte)) ; N ++)
  1128.     SwapDbyte (BlockInfo + N);
  1129. #endif
  1130.   PrText (NextLine, 40, DMAGENTA, "BLOCKMAP   structure check:");
  1131.   More = TRUE;
  1132.   PrText (NextLine + 2, 40, LGREEN, "Origin (bottom-left) : (%5d, %5d) ", BlockMapHeader.OriginX, BlockMapHeader.OriginY);
  1133.   if (((BlockMapHeader.OriginX <= Remember[MemNum].MinMapX) || (BlockMapHeader.OriginX >= (Remember[MemNum].MinMapX - 0x007F))) &&
  1134.       ((BlockMapHeader.OriginY <= Remember[MemNum].MinMapY) || (BlockMapHeader.OriginY >= (Remember[MemNum].MinMapY - 0x007F))))
  1135.     PrText (0, 0, LMAGENTA, "+");
  1136.   else
  1137.   {
  1138.     PrText (0, 0, LRED, "X");
  1139.     More = FALSE;
  1140.   }
  1141.   PrText (NextLine + 3, 40, LGREEN, "Number of blocks     :  %5d x%5d  ", BlockMapHeader.BlockCntX, BlockMapHeader.BlockCntY);
  1142.   TestMapX = Remember[MemNum].MapSizeX / 0x0080 + ((Remember[MemNum].MapSizeX & 0x007F) ? 1 : 0);
  1143.   TestMapY = Remember[MemNum].MapSizeY / 0x0080 + ((Remember[MemNum].MapSizeY & 0x007F) ? 1 : 0);
  1144.   if ((BlockMapHeader.BlockCntX >= TestMapX) && (BlockMapHeader.BlockCntY >= TestMapY))
  1145.     PrText (0, 0, LMAGENTA, "+");
  1146.   else
  1147.   {
  1148.     PrText (0, 0, LRED, "X");
  1149.     More = FALSE;
  1150.   }
  1151.   if (More)
  1152.     PrText (NextLine, 73, LMAGENTA, "Passed");
  1153.   else
  1154.     PrText (NextLine, 73, LRED, "FAILED");
  1155.   More = TRUE;
  1156.   NextLine += 5;
  1157.   PrText (NextLine, 40, DMAGENTA, "BLOCKMAP consistency check:");
  1158.   BlockMinX = BlockMapHeader.OriginX;
  1159.   BlockMaxX = BlockMapHeader.OriginX + 0x007F;
  1160.   BlockMinY = BlockMapHeader.OriginY;
  1161.   BlockMaxY = BlockMapHeader.OriginY + 0x007F;
  1162.   for (CntY = 0 ; CntY < BlockMapHeader.BlockCntY && More ; CntY ++)
  1163.   {
  1164.     for (CntX = 0 ; CntX < BlockMapHeader.BlockCntX && More ; CntX ++)
  1165.     {
  1166.       BlockNumber = CntY * BlockMapHeader.BlockCntX + CntX;
  1167.       BlockOffset = (*(BlockInfo + BlockNumber) - (sizeof (struct BlockMapHeader_s) / sizeof (dbyte)));
  1168.       if (*(BlockInfo + BlockOffset) != 0x0000)
  1169.       {
  1170.         PrText (NextLine + 1, 42, LRED, "Invalid startmarker in block %d", BlockNumber + 1);
  1171.         More = FALSE;
  1172.       }
  1173.       while (*(BlockInfo + (++ BlockOffset)) != 0xFFFF && More)
  1174.       {
  1175.         LineDefNumber = *(BlockInfo + BlockOffset);
  1176.         if (BlockOffset > BlockMapInfoSize)
  1177.         {
  1178.           PrText (NextLine + 1, 42, LRED, "Missing endmarker in block %d", BlockNumber + 1);
  1179.           More = FALSE;
  1180.         }
  1181.         else
  1182.           if (LineDefNumber > NumberOfLineDefs)
  1183.           {
  1184.             PrText (NextLine + 1, 42, LRED, "Unknown LineDef %d in block %d", LineDefNumber, BlockNumber + 1);
  1185.             More = FALSE;
  1186.           }
  1187.           else
  1188.           {
  1189.             TestMapX = (LineInfo + LineDefNumber)->StartMapX;
  1190.             TestMapY = (LineInfo + LineDefNumber)->StartMapY;
  1191.             TestMapX2 = (LineInfo + LineDefNumber)->EndMapX;
  1192.             TestMapY2 = (LineInfo + LineDefNumber)->EndMapY;
  1193.             if (TestMapX < BlockMinX || TestMapX > BlockMaxX)                                   /* Start X is not in this block ? */
  1194.             {
  1195.               if (TestMapX2 < BlockMinX || TestMapX2 > BlockMaxX)                               /* End X also not in this block ? */
  1196.                 More = FALSE;                                                               /* Signal: LineDef crosses this block */
  1197.               else
  1198.                 if (TestMapY2 < BlockMinY || TestMapY2 > BlockMaxY)                                   /* End Y not in the block ? */
  1199.                   More = FALSE;                                                             /* Signal: LineDef crosses this block */
  1200.             }
  1201.             else
  1202.               if (TestMapY < BlockMinY || TestMapY > BlockMaxY)                                     /* Start Y not in the block ? */
  1203.                 More = FALSE;                                                               /* Signal: LineDef crosses this block */
  1204.             if (!More)                                                                                      /* Crossing LineDef ? */
  1205.             {                                                                                         /* Test if that is possible */
  1206.               More = TRUE;
  1207.               if (TestMapX > TestMapX2)                                                         /* Line goes from right to left ? */
  1208.               {                                                                                             /* Then flip the line */
  1209.                 N = TestMapX;
  1210.                 TestMapX = TestMapX2;
  1211.                 TestMapX2 = N;
  1212.                 N = TestMapY;
  1213.                 TestMapY = TestMapY2;
  1214.                 TestMapY2 = N;
  1215.               }
  1216.               if (TestMapX < BlockMinX)                                                                      /* Start X lies left */
  1217.               {
  1218.                 if (TestMapX2 < BlockMinX)                                                                     /* End X also left */
  1219.                   More = FALSE;                                                               /* Then the LineDef does NOT cross! */
  1220.               }
  1221.               else
  1222.                 if (TestMapX > BlockMinX)                                                                   /* Start X lies right */
  1223.                   if (TestMapX > BlockMaxX)                                                               /* Even after the block */
  1224.                     More = FALSE;                                                             /* Then the LineDef does NOT cross! */
  1225.               if (TestMapY > TestMapY2)                                                            /* Line goes from up to down ? */
  1226.               {                                                                                             /* Then flip the line */
  1227.                 N = TestMapX;
  1228.                 TestMapX = TestMapX2;
  1229.                 TestMapX2 = N;
  1230.                 N = TestMapY;
  1231.                 TestMapY = TestMapY2;
  1232.                 TestMapY2 = N;
  1233.               }
  1234.               if (TestMapY < BlockMinY)                                                                     /* Start Y lies below */
  1235.               {
  1236.                 if (TestMapY2 < BlockMinY)                                                                    /* End Y also below */
  1237.                   More = FALSE;                                                               /* Then the LineDef does NOT cross! */
  1238.               }
  1239.               else
  1240.                 if (TestMapY > BlockMinY)                                                                   /* Start Y lies above */
  1241.                   if (TestMapY > BlockMaxY)                                                               /* Even after the block */
  1242.                     More = FALSE;                                                             /* Then the LineDef does NOT cross! */
  1243.               if (!More)
  1244.                 PrText (NextLine + 1, 42, LRED, "Invalid LineDef %d in block %d", LineDefNumber, BlockNumber + 1);
  1245.             }
  1246.           }
  1247.       }
  1248.       BlockMinX += 0x0080;
  1249.       BlockMaxX += 0x0080;
  1250.     }
  1251.     BlockMinY += 0x0080;
  1252.     BlockMaxY += 0x0080;
  1253.     BlockMinX = BlockMapHeader.OriginX;
  1254.     BlockMaxX = BlockMapHeader.OriginX + 0x007F;
  1255.   }
  1256.   if (More)
  1257.   {
  1258.     PrText (NextLine, 73, LMAGENTA, "Passed");
  1259.     NextLine += 2;
  1260.   }
  1261.   else
  1262.   {
  1263.     PrText (NextLine, 73, LRED, "FAILED");
  1264.     NextLine += 3;
  1265.   }
  1266.   free (BlockInfo);
  1267.   free (LineInfo);
  1268.   PrText (NextLine, 40, DMAGENTA, "REJECT   consistency check:");
  1269.   if ((long)ceil (pow ((double)(Remember[MemNum].SectorLoc.Size / sizeof (struct Sector_s)), 2) / 8) == Remember[MemNum].RejectDataLoc.Size)
  1270.     PrText (NextLine, 73, LMAGENTA, "Passed");
  1271.   else
  1272.     PrText (NextLine, 73, LRED, "FAILED");
  1273.   NextLine += 2;
  1274.   PrText (NextLine, 40, DMAGENTA, "THINGS   consistency check:");
  1275.   PrText (1, 68, DWHITE, "Loading...");
  1276.   if (fseek (Fp, Remember[MemNum].ThingsLoc.Start, SEEK_SET))
  1277.     Bye ("ERROR - File location error\n");
  1278.   More = TRUE;
  1279.   Entries = 0;
  1280.   while (Entries < Remember[MemNum].ThingsLoc.Size && More)                                                 /* Handle all entries */
  1281.   {
  1282.     if (fread (&Thing, 1, sizeof (struct Thing_s), Fp) != sizeof (struct Thing_s))
  1283.       Bye ("ERROR - File read error\n");
  1284. #ifdef _AMIGA_
  1285.     SwapDbyte (&Thing.Xpos);
  1286.     SwapDbyte (&Thing.Ypos);
  1287.     SwapDbyte (&Thing.Angle);
  1288.     SwapDbyte (&Thing.Type);
  1289.     SwapDbyte (&Thing.When);
  1290. #endif
  1291.     if (Thing.Xpos < BlockMapHeader.OriginX || Thing.Xpos > (BlockMapHeader.OriginX + 0x0080 * BlockMapHeader.BlockCntX - 1) ||
  1292.         Thing.Ypos < BlockMapHeader.OriginY || Thing.Ypos > (BlockMapHeader.OriginY + 0x0080 * BlockMapHeader.BlockCntY - 1))
  1293.     {
  1294.       PrText (NextLine + 1, 40, LRED, "Thing located outside the map");
  1295.       More = FALSE;
  1296.     }
  1297.     else
  1298.       if (Thing.Angle >= 360)
  1299.       {
  1300.         PrText (NextLine + 1, 40, LRED, "Unknown angle %d encountered", Thing.Angle);
  1301.         More = FALSE;
  1302.       }
  1303.       else
  1304.         if ((Thing.Type > 0x003F && Thing.Type < 0x07D1) ||
  1305.              Thing.Type == 0x07D9  ||
  1306.             (Thing.Type > 0x07DF && Thing.Type < 0x07E2) ||
  1307.             (Thing.Type > 0x07E3 && Thing.Type < 0x07E6) ||
  1308.              Thing.Type == 0x07EB  ||
  1309.             (Thing.Type > 0x07EC && Thing.Type < 0x07F3) ||
  1310.             (Thing.Type > 0x07F3 && Thing.Type < 0x07FD) ||
  1311.             (Thing.Type > 0x0801 && Thing.Type < 0x0BB9) ||
  1312.              Thing.Type > 0x0BBE)
  1313.         {
  1314.           PrText (NextLine + 1, 40, LRED, "Unknown thing %d encountered", Thing.Type);
  1315.           More = FALSE;
  1316.         }
  1317.     Entries += sizeof (struct Thing_s);
  1318.   }
  1319.   PrText (1, 68, DWHITE, "          ");
  1320.   if (More)
  1321.   {
  1322.     PrText (NextLine, 73, LMAGENTA, "Passed");
  1323.     NextLine += 2;
  1324.   }
  1325.   else
  1326.   {
  1327.     PrText (NextLine, 73, LRED, "FAILED");
  1328.     NextLine += 3;
  1329.   }
  1330. }
  1331.  
  1332. dbyte main (int argc, char *argv[])
  1333.  
  1334. /**********************************************************************************************************************************/
  1335. /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN ROUTINE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
  1336. /* Import: Bye, SwapDbyte, SwapLong, OpenAllIntuition, ClearScreen, ListSprites, ListSounds, PrText.                              */
  1337. /**********************************************************************************************************************************/
  1338.  
  1339. {
  1340.   FILE    *Fp;
  1341.   char     S[9];
  1342.   char     Last[5];
  1343.   char     ThingMem       = -1;
  1344.   char     M;
  1345.   char     N;
  1346.   char     O;
  1347.   char     MemNum;
  1348.   long     Entries;
  1349.   boolean  More;
  1350.   boolean  KeyOk;
  1351.   boolean  KeySprites     = FALSE;
  1352.   boolean  KeySounds      = FALSE;
  1353.   boolean  KeyMenus       = FALSE;
  1354.   boolean  KeyMusic       = FALSE;
  1355.   boolean  KeyNext        = FALSE;
  1356.   boolean  KeyPrevious    = FALSE;
  1357.   boolean  KeyInfo        = FALSE;
  1358.   boolean  KeyCheckLevel  = FALSE;
  1359.   boolean  Listing        = FALSE;
  1360.   boolean  Checked        = FALSE;
  1361.   boolean  LevelInfoType  = TRUE;
  1362.   boolean  ReprintAll     = TRUE;
  1363.   boolean  ReprintLevels  = TRUE;    
  1364.   boolean  ReprintAny     = TRUE;    
  1365.  
  1366. #ifdef _AMIGA_
  1367.   OpenAllIntuition ();
  1368. #else
  1369.   _setvideomode (_VRES16COLOR);                                                                   /* Choose video mode 640x480x16 */
  1370. #endif
  1371.   if (!(Fp = fopen (argv[1], "rb")))                                                                         /* Open the WAD file */
  1372.     Bye ("ERROR - File does not exist\n");
  1373.   PrText (1, 1, LWHITE, "Analyzing the WAD file...");
  1374.   PrText (1, 68, DWHITE, "Loading...");
  1375.   if (fread (&WadHeader, 1, sizeof (struct WadHeader_s), Fp) != sizeof (struct WadHeader_s))         /* Go to the WAD 'directory' */
  1376.     Bye ("ERROR - File read error\n");
  1377. #ifdef _AMIGA_
  1378.   SwapLong (&WadHeader.DirStart);
  1379.   SwapLong (&WadHeader.DirSize);
  1380. #endif
  1381.   if (fseek (Fp, WadHeader.DirStart, SEEK_SET))
  1382.     Bye ("ERROR - File location error\n");
  1383.   for (M = 0 ; M < 27 ; M ++)
  1384.   {
  1385.     Remember[M].ThingsFilled = FALSE;
  1386.     Remember[M].StatsFilled = FALSE;
  1387.   }
  1388.   WadInfo.NewStuff = 0x00;
  1389.   WadInfo.NewLevels = 0x00000000;
  1390.   WadInfo.NewDemos = 0x0000;
  1391.   Entries = -1;
  1392.   while (++ Entries < WadHeader.DirSize)                                                 /* Handle all entries in the 'directory' */
  1393.   {
  1394.     if (fread (&Directory, 1, sizeof (struct Directory_s), Fp) != sizeof (struct Directory_s))                   /* Read an entry */
  1395.       Bye ("ERROR - File read error\n");
  1396. #ifdef _AMIGA_
  1397.     SwapLong (&Directory.Start);
  1398.     SwapLong (&Directory.Size);
  1399. #endif
  1400.     for (M = 0 ; M < 8 ; M ++)
  1401.       S[M] = toupper (Directory.Name[M]);
  1402.     S[8] = '\0';
  1403.     More = TRUE;
  1404.     for (M = 0 ; M < MAXCOLORS && More ; M ++)
  1405.       if (!strncmp (S, Colors[M], strlen (Colors[M])))
  1406.       {
  1407.         More = FALSE;
  1408.         WadInfo.NewStuff |= NEWCOLORS;
  1409.       }
  1410.     if (More)
  1411.       if (!strncmp (S, "DEMO", 4))
  1412.         {
  1413.           More = FALSE;
  1414.           WadInfo.NewDemos |= ((dbyte)1 << (S[4]-'1'));
  1415.         }
  1416.     if (More)
  1417.       for (M = 0 ; M < MAXLEVELS && More ; M ++)
  1418.         if (!strncmp (S, Levels[M], strlen (Levels[M])))
  1419.         {
  1420.           More = FALSE;
  1421.           WadInfo.NewLevels |= ((long)1 << M);
  1422.           strncpy (Last, S, 4);
  1423.           ThingMem ++;
  1424.           Last[4] = '\0';
  1425.         }
  1426.     if (More)
  1427.       for (M = 0 ; M < MAXSPRITES && More ; M ++)
  1428.         if (!strncmp (S, Sprites[M].IdName, strlen (Sprites[M].IdName)))
  1429.         {
  1430.           More = FALSE;
  1431.           WadInfo.NewStuff |= NEWSPRITES;
  1432.           Sprites[M].FieldFilled = TRUE;
  1433.         }
  1434.     if (More)
  1435.       for (M = 0 ; M < MAXMUSIC && More ; M ++)
  1436.         if (!strncmp (S, Music[M].IdName, strlen (Music[M].IdName)))
  1437.         {
  1438.           More = FALSE;
  1439.           WadInfo.NewStuff |= NEWMUSIC;
  1440.           Music[M].FieldFilled = TRUE;
  1441.         }
  1442.     if (More)
  1443.       for (M = 0 ; M < MAXINSTRUMENTS && More ; M ++)
  1444.         if (!strncmp (S, Instruments[M], strlen (Instruments[M])))
  1445.         {
  1446.           More = FALSE;
  1447.           WadInfo.NewStuff |= NEWINSTRUMENTS;
  1448.         }
  1449.     if (More)
  1450.       for (M = 0 ; M < MAXSTATUSBAR && More ; M ++)
  1451.         if (!strncmp (S, StatusBar[M], strlen (StatusBar[M])))
  1452.         {
  1453.           More = FALSE;
  1454.           WadInfo.NewStuff |= NEWSTATUSBAR;
  1455.         }
  1456.     if (More)
  1457.       for (M = 0 ; M < MAXMENUS && More ; M ++)
  1458.         if (!strncmp (S, Menus[M].IdName, strlen (Menus[M].IdName)))
  1459.         {
  1460.           More = FALSE;
  1461.           WadInfo.NewStuff |= NEWMENUS;
  1462.           Menus[M].FieldFilled = TRUE;
  1463.         }
  1464.     if (More)
  1465.       for (M = 0 ; M < MAXSOUNDS && More ; M ++)
  1466.         if (!strncmp (S, Sounds[M].IdName, strlen (Sounds[M].IdName)))
  1467.         {
  1468.           More = FALSE;
  1469.           WadInfo.NewStuff |= NEWSOUNDS;
  1470.           Sounds[M].FieldFilled = TRUE;
  1471.         }
  1472.     if (More && !strncmp (S, "THINGS", 6))
  1473.     {
  1474.       Remember[ThingMem].ThingsLoc.Start = Directory.Start;                   /* The "THINGS" part of a level is dealt with later */
  1475.       Remember[ThingMem].ThingsLoc.Size = Directory.Size;
  1476.       strcpy (Remember[ThingMem].ThingsLoc.Name, Last);
  1477.       More = FALSE;
  1478.     }
  1479.     if (More && !strncmp (S, "VERTEXES", 8))
  1480.     {
  1481.       Remember[ThingMem].VertexLoc.Start = Directory.Start;
  1482.       Remember[ThingMem].VertexLoc.Size = Directory.Size;
  1483.       strcpy (Remember[ThingMem].VertexLoc.Name, Last);
  1484.       More = FALSE;
  1485.     }
  1486.     if (More && !strncmp (S, "LINEDEFS", 8))
  1487.     {
  1488.       Remember[ThingMem].LineDefLoc.Start = Directory.Start;
  1489.       Remember[ThingMem].LineDefLoc.Size = Directory.Size;
  1490.       strcpy (Remember[ThingMem].LineDefLoc.Name, Last);
  1491.       More = FALSE;
  1492.     }
  1493.     if (More && !strncmp (S, "SIDEDEFS", 8))
  1494.     {
  1495.       Remember[ThingMem].SideDefLoc.Start = Directory.Start;
  1496.       Remember[ThingMem].SideDefLoc.Size = Directory.Size;
  1497.       strcpy (Remember[ThingMem].SideDefLoc.Name, Last);
  1498.       More = FALSE;
  1499.     }
  1500.     if (More && !strncmp (S, "SEGS", 4))
  1501.     {
  1502.       Remember[ThingMem].SegLoc.Start = Directory.Start;
  1503.       Remember[ThingMem].SegLoc.Size = Directory.Size;
  1504.       strcpy (Remember[ThingMem].SegLoc.Name, Last);
  1505.       More = FALSE;
  1506.     }
  1507.     if (More && !strncmp (S, "SECTORS", 7))
  1508.     {
  1509.       Remember[ThingMem].SectorLoc.Start = Directory.Start;
  1510.       Remember[ThingMem].SectorLoc.Size = Directory.Size;
  1511.       strcpy (Remember[ThingMem].SectorLoc.Name, Last);
  1512.       More = FALSE;
  1513.     }
  1514.     if (More && !strncmp (S, "SSECTORS", 8))
  1515.     {
  1516.       Remember[ThingMem].SubSectorLoc.Start = Directory.Start;
  1517.       Remember[ThingMem].SubSectorLoc.Size = Directory.Size;
  1518.       strcpy (Remember[ThingMem].SubSectorLoc.Name, Last);
  1519.       More = FALSE;
  1520.     }
  1521.     if (More && !strncmp (S, "NODES", 5))
  1522.     {
  1523.       Remember[ThingMem].NodeLoc.Start = Directory.Start;
  1524.       Remember[ThingMem].NodeLoc.Size = Directory.Size;
  1525.       strcpy (Remember[ThingMem].NodeLoc.Name, Last);
  1526.       More = FALSE;
  1527.     }
  1528.     if (More && !strncmp (S, "REJECT", 6))
  1529.     {
  1530.       Remember[ThingMem].RejectDataLoc.Start = Directory.Start;
  1531.       Remember[ThingMem].RejectDataLoc.Size = Directory.Size;
  1532.       strcpy (Remember[ThingMem].RejectDataLoc.Name, Last);
  1533.       More = FALSE;
  1534.     }
  1535.     if (More && !strncmp (S, "BLOCKMAP", 8))
  1536.     {
  1537.       Remember[ThingMem].BlockMapLoc.Start = Directory.Start;
  1538.       Remember[ThingMem].BlockMapLoc.Size = Directory.Size;
  1539.       strcpy (Remember[ThingMem].BlockMapLoc.Name, Last);
  1540.       More = FALSE;
  1541.     }
  1542.     if (More && Directory.Start != 0)
  1543.       WadInfo.NewStuff |= NEWGRAPHS;
  1544.   }
  1545.   PrText (1, 1, LWHITE, "                         ");
  1546.   PrText (1, 68, DWHITE, "          ");
  1547.   ThingMem ++;
  1548.   MemNum = 0;
  1549.   More = TRUE;
  1550.   while (More)
  1551.   {
  1552.     if (ReprintAny)
  1553.     {
  1554.       if (ReprintAll)
  1555.       {
  1556. #ifdef _AMIGA_
  1557.         PrText ( 1, 1, LWHITE, "Filename       : %s", argv[1]);
  1558. #else
  1559.         PrText ( 1, 1, LWHITE, "Filename       : %s", strupr (argv[1]));
  1560. #endif
  1561.         for (N = 0 ; N < 4 ; N ++)                                                                /* Convert the type to a string */
  1562.           S[N] = WadHeader.Type[N];
  1563.         S[N] = '\0';
  1564.         PrText ( 2, 1, LWHITE, "Wadfile type   : %s", S);                                /* Print the WAD 'directory' information */
  1565.         PrText ( 3, 1, LWHITE, "Directory start: %08lX", WadHeader.DirStart);
  1566.         PrText ( 4, 1, LWHITE, "Directory size : %08lX", WadHeader.DirSize);
  1567.         PrText ( 7, 1, LBLUE,  "New Colors     : %s", WadInfo.NewStuff & NEWCOLORS ? "Yes" : "-");
  1568.         PrText ( 8, 1, LBLUE,  "New Demos      :");
  1569.         if (WadInfo.NewDemos == 0x0000)
  1570.           PrText (0, 0, LBLUE, " -");
  1571.         for (N = 0 ; N < 10 ; N ++)
  1572.           if (WadInfo.NewDemos & ((dbyte)1 << N))
  1573.             PrText (0, 0, LBLUE, " %d", N + 1);
  1574.         PrText ( 9, 1, LBLUE,  "New Sounds     : %s", WadInfo.NewStuff & NEWSOUNDS ? "Yes" : "-");
  1575.         PrText (10, 1, LBLUE,  "New Instruments: %s", WadInfo.NewStuff & NEWINSTRUMENTS ? "Yes" : "-");
  1576.         PrText (11, 1, LBLUE,  "New Music      : %s", WadInfo.NewStuff & NEWMUSIC ? "Yes" : "-");
  1577.         PrText (12, 1, LBLUE,  "New Sprites    : %s", WadInfo.NewStuff & NEWSPRITES ? "Yes" : "-");
  1578.         PrText (13, 1, LBLUE,  "New Status bar : %s", WadInfo.NewStuff & NEWSTATUSBAR ? "Yes" : "-");
  1579.         PrText (14, 1, LBLUE,  "New Menu items : %s", WadInfo.NewStuff & NEWMENUS ? "Yes" : "-");
  1580.         PrText (15, 1, LBLUE,  "New Graphics   : %s", WadInfo.NewStuff & NEWGRAPHS ? "Yes" : "-");
  1581.         PrText (16, 1, LBLUE,  "New Levels     :");
  1582.         if (WadInfo.NewLevels == 0x00000000)
  1583.           PrText (0, 0, LBLUE, " -");
  1584.         else
  1585.           for (N = 0 ; N < NUMEPISODE ; N ++)
  1586.             if ((WadInfo.NewLevels & ((long)0x1FF << (N * NUMLEVEL))) == ((long)0x1FF << (N * NUMLEVEL)))
  1587.               PrText (0, 0, LBLUE, " e%d", (dbyte)N + 1);
  1588.             else
  1589.               for (O = 0 ; O < NUMLEVEL ; O ++)
  1590.                 if (WadInfo.NewLevels & ((long)1 << (N*NUMLEVEL+O)))
  1591.                   PrText (0, 0, LBLUE, " %d%d", (dbyte)N + 1, (dbyte)O + 1);
  1592.         ReprintLevels = TRUE;
  1593.       }
  1594.       if (ReprintLevels && ThingMem > 0)                                                                          /* New levels ? */
  1595.       {
  1596.         PrText (1, 40, LYELLOW, "INFORMATION ON LEVEL %s:", Remember[MemNum].ThingsLoc.Name);
  1597.         if (LevelInfoType)
  1598.         {
  1599.           if (!Remember[MemNum].ThingsFilled)
  1600.           {
  1601.             PrText (1, 68, DWHITE, "Loading...");
  1602.             for (N = 0 ; N < 4 ; N ++)
  1603.             {
  1604.               Remember[MemNum].PlayerStarts[N] = 0;
  1605.               for (O = 0 ; O < 16 ; O ++)
  1606.                 Remember[MemNum].ThingType[O][N] = 0;
  1607.             }
  1608.             Remember[MemNum].PlayerStarts[4] = 0;
  1609.             if (fseek (Fp, Remember[MemNum].ThingsLoc.Start, SEEK_SET))                            /* Go to the start of the data */
  1610.               Bye ("ERROR - File location error\n");
  1611.             Entries = 0;
  1612.             while (Entries < Remember[MemNum].ThingsLoc.Size)                                               /* Handle all entries */
  1613.             {
  1614.               if (fread (&Thing, 1, sizeof (struct Thing_s), Fp) != sizeof (struct Thing_s))                     /* Read an entry */
  1615.                 Bye ("ERROR - File read error\n");
  1616. #ifdef _AMIGA_
  1617.               SwapDbyte (&Thing.Xpos);
  1618.               SwapDbyte (&Thing.Ypos);
  1619.               SwapDbyte (&Thing.Angle);
  1620.               SwapDbyte (&Thing.Type);
  1621.               SwapDbyte (&Thing.When);
  1622. #endif
  1623.               switch (Thing.Type)                                                          /* Find out if the type is interesting */
  1624.               {
  1625.                 case THING_PLAYER1    : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[0]) ++; break; /* Handle playerstarts */
  1626.                 case THING_PLAYER2    : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[1]) ++; break;
  1627.                 case THING_PLAYER3    : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[2]) ++; break;
  1628.                 case THING_PLAYER4    : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[3]) ++; break;
  1629.                 case THING_DEATHMATCH : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[4]) ++; break;
  1630.                 case THING_CHAINSAW   : Thing.Type = TYPE_CHAINSAW; break;                         /* Convert type to array index */
  1631.                 case THING_SHOTGUN    : Thing.Type = TYPE_SHOTGUN; break;
  1632.                 case THING_CHAINGUN   : Thing.Type = TYPE_CHAINGUN; break;
  1633.                 case THING_LAUNCHER   : Thing.Type = TYPE_LAUNCHER; break;
  1634.                 case THING_PLASMAGUN  : Thing.Type = TYPE_PLASMAGUN; break;
  1635.                 case THING_BFG9000    : Thing.Type = TYPE_BFG9000; break;
  1636.                 case THING_TROOPER    : Thing.Type = TYPE_TROOPER; break;
  1637.                 case THING_SARGEANT   : Thing.Type = TYPE_SARGEANT; break;
  1638.                 case THING_IMP        : Thing.Type = TYPE_IMP; break;
  1639.                 case THING_DEMON      : Thing.Type = TYPE_DEMON; break;
  1640.                 case THING_SPECTRE    : Thing.Type = TYPE_SPECTRE; break;
  1641.                 case THING_CACODEMON  : Thing.Type = TYPE_CACODEMON; break;
  1642.                 case THING_LOSTSOUL   : Thing.Type = TYPE_LOSTSOUL; break;
  1643.                 case THING_BARON      : Thing.Type = TYPE_BARON; break;
  1644.                 case THING_CYBERDEMON : Thing.Type = TYPE_CYBERDEMON; break;
  1645.                 case THING_SPIDERBOSS : Thing.Type = TYPE_SPIDERBOSS; break;
  1646.                 default               : Thing.Type = 0xFFFF;
  1647.               }
  1648.               if (Thing.Type != 0xFFFF)                                                                       /* Unhandled type ? */
  1649.               {                                                   /* Update array entry, depending on the appearance (difficulty) */
  1650.                 if ((Thing.When & WHEN_MULTI) == WHEN_MULTI)         /* If it appears in multi, then the other bits are undefined */
  1651.                   (Remember[MemNum].ThingType[Thing.Type][3]) ++;
  1652.                 else
  1653.                 {
  1654.                   if ((Thing.When & WHEN_D12) == WHEN_D12)
  1655.                     (Remember[MemNum].ThingType[Thing.Type][0]) ++;
  1656.                   if ((Thing.When & WHEN_D3) == WHEN_D3)
  1657.                     (Remember[MemNum].ThingType[Thing.Type][1]) ++;
  1658.                   if ((Thing.When & WHEN_D45) == WHEN_D45)
  1659.                     (Remember[MemNum].ThingType[Thing.Type][2]) ++;
  1660.                 }
  1661.               }
  1662.               Entries += sizeof (struct Thing_s);
  1663.             }
  1664.             Remember[MemNum].ThingsFilled = TRUE;
  1665.             PrText (1, 68, DWHITE, "          ");
  1666.           }
  1667.           if (Remember[MemNum].PlayerStarts[0])                                            /* Print number of found starting pads */
  1668.             if (Remember[MemNum].PlayerStarts[1])
  1669.               if (Remember[MemNum].PlayerStarts[2])
  1670.                 if (Remember[MemNum].PlayerStarts[3])
  1671.                   PrText (3, 40, LGREEN, "Number of player starts    : 4         ");
  1672.                 else
  1673.                   PrText (3, 40, LGREEN, "Number of player starts    : 3         ");
  1674.               else
  1675.                 PrText (3, 40, LGREEN, "Number of player starts    : 2         ");
  1676.             else
  1677.               PrText (3, 40, LGREEN, "Number of player starts    : 1         ");
  1678.           else
  1679.             PrText (3, 40, LGREEN, "Number of player starts    : none     ");
  1680.           if (Remember[MemNum].PlayerStarts[4] == 0)
  1681.             PrText (4, 40, LGREEN, "Number of deathmatch starts: none     ");
  1682.           else
  1683.             if (Remember[MemNum].PlayerStarts[4] == 1)
  1684.               PrText (4, 40, LGREEN, "Number of deathmatch starts: 1         ");
  1685.             else
  1686.               PrText (4, 40, LGREEN, "Number of deathmatch starts: %d        ", Remember[MemNum].PlayerStarts[4]);
  1687.           PrText ( 5, 40, DBLACK, "                                       ");
  1688.           PrText ( 6, 40, DBLACK, "                                       ");
  1689.           PrText ( 7, 40, DMAGENTA, "Weapons in this level: D12  D3 D45 MUL ");           /* Print the other recorded information */
  1690.           PrText ( 8, 40, DBLACK, "                                       ");
  1691.           PrText ( 9, 40, LMAGENTA, "(1) Chainsaw           %3d %3d %3d %3d ", Remember[MemNum].ThingType[0][0],
  1692.                                                                                Remember[MemNum].ThingType[0][1],
  1693.                                                                                Remember[MemNum].ThingType[0][2],
  1694.                                                                                Remember[MemNum].ThingType[0][3]);
  1695.           PrText (10, 40, LMAGENTA, "(3) Shotgun            %3d %3d %3d %3d ", Remember[MemNum].ThingType[1][0],
  1696.                                                                                Remember[MemNum].ThingType[1][1],
  1697.                                                                                Remember[MemNum].ThingType[1][2],
  1698.                                                                                Remember[MemNum].ThingType[1][3]);
  1699.           PrText (11, 40, LMAGENTA, "(4) Chaingun           %3d %3d %3d %3d ", Remember[MemNum].ThingType[2][0],
  1700.                                                                                Remember[MemNum].ThingType[2][1],
  1701.                                                                                Remember[MemNum].ThingType[2][2],
  1702.                                                                                Remember[MemNum].ThingType[2][3]);
  1703.           PrText (12, 40, LMAGENTA, "(5) Rocket launcher    %3d %3d %3d %3d ", Remember[MemNum].ThingType[3][0],
  1704.                                                                                Remember[MemNum].ThingType[3][1],
  1705.                                                                                Remember[MemNum].ThingType[3][2],
  1706.                                                                                Remember[MemNum].ThingType[3][3]);
  1707.           PrText (13, 40, LMAGENTA, "(6) Plasmagun          %3d %3d %3d %3d ", Remember[MemNum].ThingType[4][0],
  1708.                                                                                Remember[MemNum].ThingType[4][1],
  1709.                                                                                Remember[MemNum].ThingType[4][2],
  1710.                                                                                Remember[MemNum].ThingType[4][3]);
  1711.           PrText (14, 40, LMAGENTA, "(7) BFG9000            %3d %3d %3d %3d ", Remember[MemNum].ThingType[5][0],
  1712.                                                                                Remember[MemNum].ThingType[5][1],
  1713.                                                                                Remember[MemNum].ThingType[5][2],
  1714.                                                                                Remember[MemNum].ThingType[5][3]);
  1715.           PrText (15, 40, DBLACK, "                                       ");
  1716.           PrText (16, 40, DMAGENTA, "Enemies in this level: D12  D3 D45 MUL ");
  1717.           PrText (17, 40, DBLACK, "                                       ");
  1718.           PrText (18, 40, LMAGENTA, "Trooper                %3d %3d %3d %3d ", Remember[MemNum].ThingType[6][0],
  1719.                                                                                Remember[MemNum].ThingType[6][1],
  1720.                                                                                Remember[MemNum].ThingType[6][2],
  1721.                                                                                Remember[MemNum].ThingType[6][3]);
  1722.           PrText (19, 40, LMAGENTA, "Sargeant               %3d %3d %3d %3d ", Remember[MemNum].ThingType[7][0],
  1723.                                                                                Remember[MemNum].ThingType[7][1],
  1724.                                                                                Remember[MemNum].ThingType[7][2],
  1725.                                                                                Remember[MemNum].ThingType[7][3]);
  1726.           PrText (20, 40, LMAGENTA, "Imp                    %3d %3d %3d %3d ", Remember[MemNum].ThingType[8][0],
  1727.                                                                                Remember[MemNum].ThingType[8][1],
  1728.                                                                                Remember[MemNum].ThingType[8][2],
  1729.                                                                                Remember[MemNum].ThingType[8][3]);
  1730.           PrText (21, 40, LMAGENTA, "Demon                  %3d %3d %3d %3d ", Remember[MemNum].ThingType[9][0],
  1731.                                                                                Remember[MemNum].ThingType[9][1],
  1732.                                                                                Remember[MemNum].ThingType[9][2],
  1733.                                                                                Remember[MemNum].ThingType[9][3]);
  1734.           PrText (22, 40, LMAGENTA, "Spectre                %3d %3d %3d %3d ", Remember[MemNum].ThingType[10][0],
  1735.                                                                                Remember[MemNum].ThingType[10][1],
  1736.                                                                                Remember[MemNum].ThingType[10][2],
  1737.                                                                                Remember[MemNum].ThingType[10][3]);
  1738.           PrText (23, 40, LMAGENTA, "Caco Demon             %3d %3d %3d %3d ", Remember[MemNum].ThingType[11][0],
  1739.                                                                                Remember[MemNum].ThingType[11][1],
  1740.                                                                                Remember[MemNum].ThingType[11][2],
  1741.                                                                                Remember[MemNum].ThingType[11][3]);
  1742.           PrText (24, 40, LMAGENTA, "Lost soul              %3d %3d %3d %3d ", Remember[MemNum].ThingType[12][0],
  1743.                                                                                Remember[MemNum].ThingType[12][1],
  1744.                                                                                Remember[MemNum].ThingType[12][2],
  1745.                                                                                Remember[MemNum].ThingType[12][3]);
  1746.           PrText (25, 40, LMAGENTA, "Baron of Hell          %3d %3d %3d %3d ", Remember[MemNum].ThingType[13][0],
  1747.                                                                                Remember[MemNum].ThingType[13][1],
  1748.                                                                                Remember[MemNum].ThingType[13][2],
  1749.                                                                                Remember[MemNum].ThingType[13][3]);
  1750.           PrText (26, 40, LMAGENTA, "Cyber Demon            %3d %3d %3d %3d ", Remember[MemNum].ThingType[14][0],
  1751.                                                                                Remember[MemNum].ThingType[14][1],
  1752.                                                                                Remember[MemNum].ThingType[14][2],
  1753.                                                                                Remember[MemNum].ThingType[14][3]);
  1754.           PrText (27, 40, LMAGENTA, "Spider Demon           %3d %3d %3d %3d ", Remember[MemNum].ThingType[15][0],
  1755.                                                                                Remember[MemNum].ThingType[15][1],
  1756.                                                                                Remember[MemNum].ThingType[15][2],
  1757.                                                                                Remember[MemNum].ThingType[15][3]);
  1758.           PrText (28, 40, DBLACK, "                                       ");
  1759.         }
  1760.         else
  1761.         {
  1762.           if (!Remember[MemNum].StatsFilled)
  1763.           {
  1764.             PrText (1, 68, DWHITE, "Loading...");
  1765.             if (fseek (Fp, Remember[MemNum].VertexLoc.Start, SEEK_SET))
  1766.               Bye ("ERROR - File location error\n");
  1767.             if (fread (&Vertex, 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s))                    /* Read an entry */
  1768.               Bye ("ERROR - File read error\n");
  1769. #ifdef _AMIGA_
  1770.             SwapDbyte (&Vertex.MapX);
  1771.             SwapDbyte (&Vertex.MapY);
  1772. #endif
  1773.             Remember[MemNum].MinMapX = Remember[MemNum].MaxMapX = Vertex.MapX;
  1774.             Remember[MemNum].MinMapY = Remember[MemNum].MaxMapY = Vertex.MapY;
  1775.             Entries = sizeof (struct Vertex_s);
  1776.             while (Entries < Remember[MemNum].VertexLoc.Size)                                               /* Handle all entries */
  1777.             {
  1778.               if (fread (&Vertex, 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s))                  /* Read an entry */
  1779.                 Bye ("ERROR - File read error\n");
  1780. #ifdef _AMIGA_
  1781.               SwapDbyte (&Vertex.MapX);
  1782.               SwapDbyte (&Vertex.MapY);
  1783. #endif
  1784.               if (Vertex.MapX < Remember[MemNum].MinMapX)
  1785.                 Remember[MemNum].MinMapX = Vertex.MapX;
  1786.               if (Vertex.MapX > Remember[MemNum].MaxMapX)
  1787.                 Remember[MemNum].MaxMapX = Vertex.MapX;
  1788.               if (Vertex.MapY < Remember[MemNum].MinMapY)
  1789.                 Remember[MemNum].MinMapY = Vertex.MapY;
  1790.               if (Vertex.MapY > Remember[MemNum].MaxMapY)
  1791.                 Remember[MemNum].MaxMapY = Vertex.MapY;
  1792.               Entries += sizeof (struct Vertex_s);
  1793.             }
  1794.             if (Remember[MemNum].MinMapX < 0)
  1795.               Remember[MemNum].MapSizeX = -Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
  1796.             else
  1797.               Remember[MemNum].MapSizeX = Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
  1798.             if (Remember[MemNum].MinMapY < 0)
  1799.               Remember[MemNum].MapSizeY = -Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
  1800.             else
  1801.               Remember[MemNum].MapSizeY = Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
  1802.             Remember[MemNum].StatsFilled = TRUE;
  1803.             PrText (1, 68, DWHITE, "          ");
  1804.           }
  1805.           PrText ( 3, 40, DGREEN, "THINGS   start : %08lX              ", Remember[MemNum].ThingsLoc.Start);
  1806.           PrText ( 4, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].ThingsLoc.Size,
  1807.                                                                           Remember[MemNum].ThingsLoc.Size / sizeof (struct Thing_s));
  1808.           PrText ( 5, 40, DGREEN, "VERTEXES start : %08lX              ", Remember[MemNum].VertexLoc.Start);
  1809.           PrText ( 6, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].VertexLoc.Size,
  1810.                                                                           Remember[MemNum].VertexLoc.Size / sizeof (struct Vertex_s));
  1811.           PrText ( 7, 40, DGREEN, "LINEDEFS start : %08lX              ", Remember[MemNum].LineDefLoc.Start);
  1812.           PrText ( 8, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].LineDefLoc.Size,
  1813.                                                                           Remember[MemNum].LineDefLoc.Size / sizeof (struct LineDef_s));
  1814.           PrText ( 9, 40, DGREEN, "SIDEDEFS start : %08lX              ", Remember[MemNum].SideDefLoc.Start);
  1815.           PrText (10, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].SideDefLoc.Size,
  1816.                                                                           Remember[MemNum].SideDefLoc.Size / sizeof (struct SideDef_s));
  1817.           PrText (11, 40, DGREEN, "SEGS     start : %08lX              ", Remember[MemNum].SegLoc.Start);
  1818.           PrText (12, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].SegLoc.Size,
  1819.                                                                           Remember[MemNum].SegLoc.Size / sizeof (struct Seg_s));
  1820.           PrText (13, 40, DGREEN, "SECTORS  start : %08lX              ", Remember[MemNum].SectorLoc.Start);
  1821.           PrText (14, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].SectorLoc.Size,
  1822.                                                                           Remember[MemNum].SectorLoc.Size / sizeof (struct Sector_s));
  1823.           PrText (15, 40, DGREEN, "SSECTORS start : %08lX              ", Remember[MemNum].SubSectorLoc.Start);
  1824.           PrText (16, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].SubSectorLoc.Size,
  1825.                                                                           Remember[MemNum].SubSectorLoc.Size / sizeof (struct SubSector_s));
  1826.           PrText (17, 40, DGREEN, "NODES    start : %08lX              ", Remember[MemNum].NodeLoc.Start);
  1827.           PrText (18, 40, DGREEN, "         size  : %08lX (%4lu)       ", Remember[MemNum].NodeLoc.Size,
  1828.                                                                           Remember[MemNum].NodeLoc.Size / sizeof (struct Node_s));
  1829.           PrText (19, 40, DGREEN, "REJECT   start : %08lX              ", Remember[MemNum].RejectDataLoc.Start);
  1830.           PrText (20, 40, DGREEN, "         size  : %08lX              ", Remember[MemNum].RejectDataLoc.Size);
  1831.           PrText (21, 40, DGREEN, "BLOCKMAP start : %08lX              ", Remember[MemNum].BlockMapLoc.Start);
  1832.           PrText (22, 40, DGREEN, "         size  : %08lX              ", Remember[MemNum].BlockMapLoc.Size);
  1833.           PrText (23, 40, DBLACK, "                                       ");
  1834.           PrText (24, 40, LMAGENTA, "Top-left map       : (%5d, %5d)    ", Remember[MemNum].MinMapX, Remember[MemNum].MinMapY);
  1835.           PrText (25, 40, LMAGENTA, "Bottom-right map   : (%5d, %5d)    ", Remember[MemNum].MaxMapX, Remember[MemNum].MaxMapY);
  1836.           PrText (26, 40, LMAGENTA, "Center of map      : (%5d, %5d)    ",
  1837.                           Remember[MemNum].MaxMapX - (Remember[MemNum].MapSizeX / 2),
  1838.                           Remember[MemNum].MaxMapY - (Remember[MemNum].MapSizeY / 2));
  1839.           PrText (27, 40, DBLACK, "                                       ");
  1840.           PrText (28, 40, LMAGENTA, "Size of map        : %5d x %5d     ", Remember[MemNum].MapSizeX, Remember[MemNum].MapSizeY);
  1841.         }
  1842.       }
  1843.       PrText (19, 1, DYELLOW, "Press :");
  1844.       PrText (20, 1, DYELLOW, "  [Q] to quit                      ");
  1845.       if (ThingMem > 0)
  1846.       {
  1847.         PrText (21, 1, DYELLOW, "  [I] to toggle level info type    ");
  1848.         KeyInfo = TRUE;
  1849.       }
  1850.       else
  1851.       {
  1852.         PrText (21, 1, DYELLOW, "                                   ");
  1853.         KeyInfo = FALSE;
  1854.       }
  1855.       if (ThingMem > 0)
  1856.       {
  1857.         PrText (22, 1, DYELLOW, "  [C] to check this level          ");
  1858.         KeyCheckLevel = TRUE;
  1859.       }
  1860.       else
  1861.       {
  1862.         PrText (22, 1, DYELLOW, "                                   ");
  1863.         KeyCheckLevel = FALSE;
  1864.       }
  1865.       if ((ThingMem > 0) && (MemNum < ThingMem - 1))
  1866.       {
  1867.         PrText (23, 1, DYELLOW, "  [N] for next level               ");
  1868.         KeyNext = TRUE;
  1869.       }
  1870.       else
  1871.       {
  1872.         PrText (23, 1, DYELLOW, "                                   ");
  1873.         KeyNext = FALSE;
  1874.       }
  1875.       if ((ThingMem > 0) && (MemNum > 0))
  1876.       {
  1877.         PrText (24, 1, DYELLOW, "  [P] for previous level           ");
  1878.         KeyPrevious = TRUE;
  1879.       }
  1880.       else
  1881.       {
  1882.         PrText (24, 1, DYELLOW, "                                   ");
  1883.         KeyPrevious = FALSE;
  1884.       }
  1885.       if ((WadInfo.NewStuff & NEWSPRITES) == NEWSPRITES)
  1886.       {
  1887.         PrText (25, 1, DYELLOW, "  [R] to list the sprites          ");
  1888.         KeySprites = TRUE;
  1889.       }
  1890.       else
  1891.         KeySprites = FALSE;
  1892.       if ((WadInfo.NewStuff & NEWSOUNDS) == NEWSOUNDS)
  1893.       {
  1894.         PrText (26, 1, DYELLOW, "  [S] to list the sounds           ");
  1895.         KeySounds = TRUE;
  1896.       }
  1897.       else
  1898.         KeySounds = FALSE;
  1899.       if ((WadInfo.NewStuff & NEWMUSIC) == NEWMUSIC)
  1900.       {
  1901.         PrText (27, 1, DYELLOW, "  [M] to list the music            ");
  1902.         KeyMusic = TRUE;
  1903.       }
  1904.       else
  1905.         KeyMusic = FALSE;
  1906.       if ((WadInfo.NewStuff & NEWMENUS) == NEWMENUS)
  1907.       {
  1908.         PrText (28, 1, DYELLOW, "  [U] to list the menu items       ");
  1909.         KeyMenus = TRUE;
  1910.       }
  1911.       else
  1912.         KeyMenus = FALSE;
  1913.       KeyOk = FALSE;
  1914.       ReprintAll = FALSE;
  1915.       ReprintLevels = FALSE;
  1916.       ReprintAny = FALSE;
  1917.     }
  1918.     while (!KeyOk)
  1919.     {
  1920.       KeyOk = TRUE;
  1921. #ifdef _AMIGA_
  1922.       while (KeyOk)
  1923.       {
  1924.         if (!(IntuiMessage = (struct IntuiMessage *)GetMsg (Window->UserPort)))              /* Wait for a message from intuition */
  1925.         {
  1926.           Wait (1L << Window->UserPort->mp_SigBit);
  1927.           continue;
  1928.         }
  1929.         MessageClass = IntuiMessage->Class;                                                /* Determine the source of the message */
  1930.         Code = IntuiMessage->Code;                                                                /* Read the data of the message */
  1931.         ReplyMsg (IntuiMessage);                                                       /* Confirm receipt to the operating system */
  1932.         switch (MessageClass)
  1933.         {
  1934.           case CLOSEWINDOW : KeyOk = FALSE;
  1935.                              Code = 'q';                                                            /* Convert data to key 'quit' */
  1936.                              break;
  1937.           case VANILLAKEY  : KeyOk = FALSE;
  1938.         }
  1939.       }
  1940.       KeyOk = TRUE;
  1941.       if (Checked)
  1942.       {
  1943.         Checked = FALSE;
  1944.         ReprintLevels = TRUE;
  1945.       }
  1946.       else
  1947.       if (Listing)
  1948.       {
  1949.         Listing = FALSE;
  1950.         ClearScreen ();
  1951.         ReprintAll = TRUE;
  1952.       }
  1953.       else
  1954.         switch (Code)
  1955. #else
  1956.       Key = getch ();                                                                                           /* Wait for a key */
  1957.       if (Key == 0x0000 || Key == 0x00E0)                          /* Non-ASCII keys (cursor, funtion, etc) give 'extended' first */
  1958.         Key = getch ();
  1959.       if (Checked)
  1960.       {
  1961.         Checked = FALSE;
  1962.         ReprintLevels = TRUE;
  1963.       }
  1964.       else
  1965.       if (Listing)
  1966.       {
  1967.         Listing = FALSE;
  1968.         ClearScreen ();
  1969.         ReprintAll = TRUE;
  1970.       }
  1971.       else
  1972.         switch (tolower ((char)(Key & 0x00FF)))                                                       /* Keep only the ASCII part */
  1973. #endif
  1974.         {
  1975.           case 'q' : More = FALSE;
  1976.                      break;
  1977.           case 'c' : if (KeyCheckLevel)
  1978.                      {
  1979.                        CheckLevel (Fp, MemNum);
  1980.                        KeyOk = FALSE;
  1981.                        Checked = TRUE;
  1982.                      }
  1983.                      else
  1984.                        KeyOk = FALSE;
  1985.                      break;
  1986.           case 'i' : if (KeyInfo)
  1987.                      {
  1988.                        LevelInfoType = !LevelInfoType;
  1989.                        ReprintLevels = TRUE;
  1990.                      }
  1991.                      else
  1992.                        KeyOk = FALSE;
  1993.                      break;
  1994.           case 'n' : if (KeyNext)
  1995.                      {
  1996.                        MemNum ++;
  1997.                        ReprintLevels = TRUE;
  1998.                      }
  1999.                      else
  2000.                        KeyOk = FALSE;
  2001.                      break;
  2002.           case 'p' : if (KeyPrevious)
  2003.                      {
  2004.                        MemNum --;
  2005.                        ReprintLevels = TRUE;
  2006.                      }
  2007.                      else
  2008.                        KeyOk = FALSE;
  2009.                      break;
  2010.           case 'r' : if (KeySprites)
  2011.                      {
  2012.                        ListSprites ();
  2013.                        Listing = TRUE;
  2014.                        KeyOk = FALSE;
  2015.                      }
  2016.                      else
  2017.                        KeyOk = FALSE;
  2018.                      break;
  2019.           case 's' : if (KeySounds)
  2020.                      {
  2021.                        ListSounds ();
  2022.                        Listing = TRUE;
  2023.                        KeyOk = FALSE;
  2024.                      }
  2025.                      else
  2026.                        KeyOk = FALSE;
  2027.                      break;
  2028.           case 'm' : if (KeyMusic)
  2029.                      {
  2030.                        ListMusic ();
  2031.                        Listing = TRUE;
  2032.                        KeyOk = FALSE;
  2033.                      }
  2034.                      else
  2035.                        KeyOk = FALSE;
  2036.                      break;
  2037.           case 'u' : if (KeyMenus)
  2038.                      {
  2039.                        ListMenus ();
  2040.                        Listing = TRUE;
  2041.                        KeyOk = FALSE;
  2042.                      }
  2043.                      else
  2044.                        KeyOk = FALSE;
  2045.                      break;
  2046.           default  : KeyOk = FALSE;
  2047.         }
  2048.       }
  2049.       ReprintAny = (ReprintAll || ReprintLevels);
  2050.   }
  2051.   fclose (Fp);
  2052.   Bye ("");                                                                                                           /* Shutdown */
  2053. }
  2054.