home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the DOOM Programming Gurus / Tricks_of_the_Doom_Programming_Gurus.iso / bonus / utils / wadinfo / wadinfo.c next >
Encoding:
C/C++ Source or Header  |  1995-03-12  |  119.4 KB  |  2,303 lines

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