home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Doom Magazine 1
/
Doom_magazine_01.bin
/
utils
/
wadinfo
/
wadinfo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-26
|
111KB
|
2,054 lines
/**********************************************************************************************************************************/
/* File : WADINFO.C */
/* Executable : WADINFO.EXE */
/* Doc file : None */
/* Version num : 1.01 */
/* Last changed : 23-08-1994 16:57 */
/* Update count : 4 */
/* OS type : if _AMIGA_ set : AMIGA (Intuition, multitasking) */
/* Compiler : Aztec C Version 5.0a Copyright 1989 by Manx Software Systems Inc. (Jan 9 1990) */
/* Linker : Aztec C68K Linker Version 5.0a Copyright 1989 by Manx Software System Inc. */
/* LN attr : -lm -lc */
/* if _AMIGA_ cleared: PC (DOS, singletasking) */
/* Compiler : Microsoft (R) Quick C Compiler Version 2.00 */
/* Linker : Microsoft (R) QuickC Linker Version 4.06 */
/* QCL attr : /AC /G2 /Ot /Zr */
/* Description : Information extractor for DOOM (TM) WAD files. */
/* Other : None */
/* */
/* By M. van der Heide of ThunderWare Research Center */
/**********************************************************************************************************************************/
/* Uncomment this line if compiling on the AMIGA */
/* #define _AMIGA_ */
#ifdef _AMIGA_
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#else
#include <stdlib.h>
#include <graph.h>
#include <malloc.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#define boolean char
#ifdef _AMIGA_
#define dbyte short /* An 'int' is 4 bytes ('long') in stead of 2 on an Amiga */
#else
#define dbyte int
#define TRUE 1
#define FALSE 0
#endif
#define DBLACK 0 /* Define names for the standard (VGA) palette colors */
#define DBLUE 1
#define DGREEN 2
#define DCYAN 3
#define DRED 4
#define DMAGENTA 5
#define DYELLOW 6
#define DWHITE 7
#define LBLACK 8
#define LBLUE 9
#define LGREEN 10
#define LCYAN 11
#define LRED 12
#define LMAGENTA 13
#define LYELLOW 14
#define LWHITE 15
#define NUMEPISODE 3 /* Define total number of episodes and levels/episode */
#define NUMLEVEL 9
#define MAXCOLORS 2 /* Define number of WAD 'directory' identifiers per type */
#define MAXLEVELS NUMEPISODE * NUMLEVEL
#define MAXSPRITES 77
#define MAXMUSIC 31
#define MAXSOUNDS 122
#define MAXGRAPHS 0
#define MAXINSTRUMENTS 1
#define MAXSTATUSBAR 2
#define MAXMENUS 39
#define NEWCOLORS 0x01 /* Define bit-wise (storage) values for these types */
#define NEWSOUNDS 0x02
#define NEWSPRITES 0x04
#define NEWMUSIC 0x08
#define NEWGRAPHS 0x10
#define NEWINSTRUMENTS 0x20
#define NEWSTATUSBAR 0x40
#define NEWMENUS 0x80
#define THING_PLAYER1 1 /* Define the THINGS to check for : */
#define THING_PLAYER2 2 /* Starting areas */
#define THING_PLAYER3 3
#define THING_PLAYER4 4
#define THING_DEATHMATCH 11
#define THING_CHAINSAW 2005 /* Weapons */
#define THING_SHOTGUN 2001
#define THING_CHAINGUN 2002
#define THING_LAUNCHER 2003
#define THING_PLASMAGUN 2004
#define THING_BFG9000 2006
#define THING_TROOPER 3004 /* Enemies */
#define THING_SARGEANT 9
#define THING_IMP 3001
#define THING_DEMON 3002
#define THING_SPECTRE 58
#define THING_CACODEMON 3005
#define THING_LOSTSOUL 3006
#define THING_BARON 3003
#define THING_CYBERDEMON 16
#define THING_SPIDERBOSS 7
#define TYPE_CHAINSAW 0 /* Define index-values for the THINGS identifiers */
#define TYPE_SHOTGUN 1
#define TYPE_CHAINGUN 2
#define TYPE_LAUNCHER 3
#define TYPE_PLASMAGUN 4
#define TYPE_BFG9000 5
#define TYPE_TROOPER 6
#define TYPE_SARGEANT 7
#define TYPE_IMP 8
#define TYPE_DEMON 9
#define TYPE_SPECTRE 10
#define TYPE_CACODEMON 11
#define TYPE_LOSTSOUL 12
#define TYPE_BARON 13
#define TYPE_CYBERDEMON 14
#define TYPE_SPIDERBOSS 15
#define WHEN_D12 0x0001 /* Define difficulties for when a things appears */
#define WHEN_D3 0x0002
#define WHEN_D45 0x0004
#define WHEN_MULTI 0x0010
struct WadInfo_s /* Group the main info on the WAD file together */
{
char NewStuff; /* Things other than levels patched */
long NewLevels;
dbyte NewDemos;
};
struct WadHeader_s /* The first bytes of a WAD file: the WAD header */
{
char Type[4]; /* Should be "PWAD" or "IWAD" for a (valid) WAD file */
unsigned long DirSize; /* Number of entries in the WAD 'directory' */
unsigned long DirStart; /* Pointer to start of the WAD 'directory' */
};
struct Directory_s /* One entry in the WAD 'directory' */
{
unsigned long Start; /* Pointer to the data of this entry */
unsigned long Size; /* Length of this data in bytes */
char Name[8]; /* Type identifier */
};
struct Thing_s /* One entry of the 'directory' entry type "THINGS" */
{
dbyte Xpos; /* Position on the map */
dbyte Ypos;
dbyte Angle; /* Facing direction: north, east, etc... */
dbyte Type; /* Thing type */
dbyte When; /* Appears when ? */
};
struct Vertex_s
{
dbyte MapX;
dbyte MapY;
};
struct LineDef_s
{
dbyte Start;
dbyte End;
dbyte Flags;
dbyte Type;
dbyte Tag;
dbyte SideDef1;
dbyte SideDef2;
};
struct SideDef_s
{
dbyte OffsetX;
dbyte OffsetY;
char UpperTexture[8];
char LowerTexture[8];
char NormalTexture[8];
};
struct Seg_s
{
dbyte Start;
dbyte End;
dbyte Angle;
dbyte LineDef;
dbyte Flip;
dbyte Distance;
};
struct Sector_s
{
dbyte FloorHeight;
dbyte CeilingHeight;
char FloorTexture[8];
char CeilingTexture[8];
dbyte LightLevel;
dbyte Special;
dbyte Tag;
};
struct SubSector_s
{
dbyte NumberOfSegs;
dbyte FirstSeg;
};
struct Node_s
{
dbyte X;
dbyte Y;
dbyte Dx;
dbyte Dy;
dbyte FirstUpperBoundY;
dbyte FirstLowerBoundY;
dbyte FirstUpperBoundX;
dbyte FirstLowerBoundX;
dbyte SecondUpperBoundY;
dbyte SecondLowerBoundY;
dbyte SecondUpperBoundX;
dbyte SecondLowerBoundX;
dbyte Child1;
dbyte Child2;
};
struct BlockMapHeader_s
{
dbyte OriginX;
dbyte OriginY;
dbyte BlockCntX;
dbyte BlockCntY;
};
struct Remember_s
{
int PlayerStarts[5]; /* 1-4 = startno, 5 = deathmatch start */
int ThingType[16][4]; /* 1 = D12, 2 = D3, 3 = D45, 4 = Multi */
dbyte MinMapX; /* Vertex info */
dbyte MinMapY;
dbyte MaxMapX;
dbyte MaxMapY;
dbyte MapSizeX;
dbyte MapSizeY;
struct Directory_s ThingsLoc;
struct Directory_s VertexLoc;
struct Directory_s LineDefLoc;
struct Directory_s SideDefLoc;
struct Directory_s SegLoc;
struct Directory_s SectorLoc;
struct Directory_s SubSectorLoc;
struct Directory_s NodeLoc;
struct Directory_s RejectDataLoc;
struct Directory_s BlockMapLoc;
boolean ThingsFilled;
boolean StatsFilled;
};
struct Check_s
{
dbyte StartMapX;
dbyte StartMapY;
dbyte EndMapX;
dbyte EndMapY;
};
struct FieldId_s
{
char *IdName;
char *Description;
char Type;
boolean FieldFilled;
};
struct WadHeader_s WadHeader;
struct Directory_s Directory;
struct WadInfo_s WadInfo;
struct Thing_s Thing;
struct Vertex_s Vertex;
struct Remember_s Remember[27];
char *Levels[] = {"E1M1", "E1M2", "E1M3", "E1M4", "E1M5", "E1M6", "E1M7", "E1M8", "E1M9",
"E2M1", "E2M2", "E2M3", "E2M4", "E2M5", "E2M6", "E2M7", "E2M8", "E2M9",
"E3M1", "E3M2", "E3M3", "E3M4", "E3M5", "E3M6", "E3M7", "E3M8", "E3M9"};
char *Colors[] = {"PLAYPAL", "COLORMAP"};
char *StatusBar[] = {"AMMNUM", "ST"};
char *Instruments[] = {"GENMIDI"};
struct FieldId_s Music[] = {{"D_INTER", "Between the levels" },
{"D_INTRO", "Introduction music" },
{"D_VICTOR", "After completing an episode" },
{"D_BUNNY", "While bunny is on the screen" },
{"D_E1M1", "Episode 1 Level 1" },
{"D_E1M2", "Episode 1 Level 2" },
{"D_E1M3", "Episode 1 Level 3" },
{"D_E1M4", "Episode 1 Level 4" },
{"D_E1M5", "Episode 1 Level 5" },
{"D_E1M6", "Episode 1 Level 6" },
{"D_E1M7", "Episode 1 Level 7" },
{"D_E1M8", "Episode 1 Level 8" },
{"D_E1M9", "Episode 1 Level 9" },
{"D_E2M1", "Episode 2 Level 1" },
{"D_E2M2", "Episode 2 Level 2" },
{"D_E2M3", "Episode 2 Level 3" },
{"D_E2M4", "Episode 2 Level 4" },
{"D_E2M5", "Episode 2 Level 5" },
{"D_E2M6", "Episode 2 Level 6" },
{"D_E2M7", "Episode 2 Level 7" },
{"D_E2M8", "Episode 2 Level 8" },
{"D_E2M9", "Episode 2 Level 9" },
{"D_E3M1", "Episode 3 Level 1" },
{"D_E3M2", "Episode 3 Level 2" },
{"D_E3M3", "Episode 3 Level 3" },
{"D_E3M4", "Episode 3 Level 4" },
{"D_E3M5", "Episode 3 Level 5" },
{"D_E3M6", "Episode 3 Level 6" },
{"D_E3M7", "Episode 3 Level 7" },
{"D_E3M8", "Episode 3 Level 8" },
{"D_E3M9", "Episode 3 Level 9" }};
struct FieldId_s Menus[] = {{"M_DOOM", "DOOM", 0},
{"M_NGAME", "New Game", 0},
{"M_OPTION", "Options", 0},
{"M_LOADG", "Load Game", 0},
{"M_SAVEG", "Save Game", 0},
{"M_RDTHIS", "Read This!", 0},
{"M_QUITG", "Quit Game", 0},
{"M_EPISOD", "Which Episode?", 1},
{"M_EPI1", "Knee-Deep in the Dead", 1},
{"M_EPI2", "The Shores of Hell", 1},
{"M_EPI3", "Inferno", 1},
{"M_NEWG", "New Game", 1},
{"M_SKILL", "Choose a Skill Level", 1},
{"M_JKILL", "I'm too young to die", 1},
{"M_ROUGH", "Hey, not too rough", 1},
{"M_HURT", "Hurt me planty", 1},
{"M_ULTRA", "Ultra-Violence!", 1},
{"M_NMARE", "Nightmare", 1},
{"M_SVOL", "Sound Volume", 1},
{"M_SFXVOL", "Sfx Volume", 1},
{"M_MUSVOL", "Music Volume", 1},
{"M_ENDGAM", "End Game", 2},
{"M_PAUSE", "Pause", 2},
{"M_MESSG", "Messages:", 2},
{"M_MSGON", "on", 2},
{"M_MSGOFF", "off", 2},
{"M_OPTTTL", "Options", 2},
{"M_DISP", "Display", 2},
{"M_MSENS", "Mouse Sensitivity", 2},
{"M_GDHIGH", "high", 2},
{"M_GDLOW", "low", 2},
{"M_DETAIL", "Graphic Detail", 2},
{"M_DISOPT", "Display options", 2},
{"M_SCRNSZ", "Screen Size", 2},
{"M_SGTTL", "Save Game", 2},
{"M_LGTTL", "Load Game", 2},
{"M_SKULL", "Selection skull", 3},
{"M_THERM", "Volume slider", 3},
{"M_LS", "Game name field in load/save", 3}};
struct FieldId_s Sprites[] = {{"PLAY", "Player", 0},
{"POSS", "Trooper", 0},
{"SPOS", "Sargeant", 0},
{"TROO", "Imp", 0},
{"SARG", "Demon & Spectre", 0},
{"HEAD", "Caco Demon", 0},
{"SKUL", "Lost Soul", 0},
{"BOSS", "Baron of Hell", 0},
{"CYBR", "Cyber Demon", 0},
{"SPID", "Spider Demon", 0},
{"BKEY", "Blue keycard", 1},
{"YKEY", "Yellow keycard", 1},
{"RKEY", "Red keycard", 1},
{"BSKU", "Blue skullkey", 1},
{"YSKU", "Yellow skullkey", 1},
{"RSKU", "Red skullkey", 1},
{"PUN", "Nothing in hand", 2},
{"SAW", "Chainsaw in hand", 2},
{"PIS", "Pistol in hand", 2},
{"SHT", "Shotgun in hand", 2},
{"CHG", "Chaingun in hand", 2},
{"PLS", "Plasmagun in hand", 2},
{"BFG", "BFG9000 in hand", 2},
{"CSAW", "Chainsaw", 2},
{"SHOT", "Shotgun", 2},
{"MGUN", "Chaingun", 2},
{"LAUN", "Rocket launcher", 2},
{"PLAS", "Plasmagun", 2},
{"BFUG", "BFG9000", 2},
{"CLIP", "Ammoclip", 3},
{"AMMO", "Box of ammo", 3},
{"SHEL", "Shells", 3},
{"SBOX", "Box of shells", 3},
{"ROCK", "Rockets", 3},
{"BROK", "Box of rockets", 3},
{"CELL", "Cells", 3},
{"CELP", "Box of cells", 3},
{"BPAK", "Backpack", 3},
{"BON1", "Healthbonus", 4},
{"BON2", "Armorbonus", 4},
{"STIM", "Stimpack", 4},
{"MEDI", "Medikit", 4},
{"ARM1", "Green armor", 4},
{"ARM2", "Blue armor", 4},
{"SOUL", "Supercharge", 4},
{"PINS", "Invisibility", 4},
{"PINV", "Invulnerability", 4},
{"PSTR", "Berserk", 4},
{"PMAP", "Computer area map", 4},
{"PVIS", "Light amplifier", 4},
{"SUIT", "Radiation suit", 4},
{"BAR", "Barrel", 5},
{"BEXP", "Barrel exploding", 5},
{"POL", "Dead body", 5},
{"GOR", "Hanging body", 5},
{"PBU", NULL, 6},
{"PSH", NULL, 6},
{"BAL", NULL, 6},
{"PUF", NULL, 6},
{"BLU", NULL, 6},
{"MIS", NULL, 6},
{"TFO", NULL, 6},
{"BFS", NULL, 6},
{"BFE", NULL, 6},
{"CAND", NULL, 7},
{"CBRA", NULL, 7},
{"COLU", NULL, 7},
{"ELEC", NULL, 7},
{"TRED", NULL, 7},
{"FSKU", NULL, 7},
{"CEYE", NULL, 7},
{"SMI", NULL, 7},
{"TGRN", NULL, 7},
{"TBLU", NULL, 7},
{"SMRT", NULL, 7},
{"SMBT", NULL, 7},
{"SMGT", NULL, 7}};
struct FieldId_s Sounds[] = {{"DPPISTOL", "Pistol fire " },
{"DSPISTOL", NULL },
{"DPSHOTGN", "Shotgun fire " },
{"DSSHOTGN", NULL },
{"DPSGCOCK", "Shotgun cock " },
{"DSSGCOCK", NULL },
{"DPSAWUP", "Chainsaw startup " },
{"DSSAWUP", NULL },
{"DPSAWIDL", "Chainsaw in rest " },
{"DSSAWIDL", NULL },
{"DPSAWFUL", "Chainsaw active " },
{"DSSAWFUL", NULL },
{"DPSAWHIT", "Chainsaw hitting " },
{"DSSAWHIT", NULL },
{"DPRLAUNC", "Rocket launch " },
{"DSRLAUNC", NULL },
{"DPRXPLOD", "BFG9000 launch " },
{"DSRXPLOD", NULL },
{"DPFIRSHT", "Fireball passing " },
{"DSFIRSHT", NULL },
{"DPFIRXPL", "Fireball hitting " },
{"DSFIRXPL", NULL },
{"DPPSTART", "Lift starting " },
{"DSPSTART", NULL },
{"DPPSTOP", "Lift stopping " },
{"DSPSTOP", NULL },
{"DPDOROPN", "Door opening " },
{"DSDOROPN", NULL },
{"DPDORCLS", "Door closing " },
{"DSDORCLS", NULL },
{"DPSTNMOV", "Floor moving " },
{"DSSTNMOV", NULL },
{"DPSWTCHN", "Switch returning " },
{"DSSWTCHN", NULL },
{"DPSWTCHX", "Switch activated " },
{"DSSWTCHX", NULL },
{"DPPLPAIN", "Player hurt " },
{"DSPLPAIN", NULL },
{"DPDMPAIN", "Trooper hurt " },
{"DSDMPAIN", NULL },
{"DPPOPAIN", "Sargeant hurt " },
{"DSPOPAIN", NULL },
{"DPSLOP", "Total slaying " },
{"DSSLOP", NULL },
{"DPITEMUP", "Item picked up " },
{"DSITEMUP", NULL },
{"DPWPNUP", "Weapon picked up " },
{"DSWPNUP", NULL },
{"DPOOF", "Player jumping " },
{"DSOOF", NULL },
{"DPTELEPT", "Teleporter " },
{"DSTELEPT", NULL },
{"DPPOSIT1", "Trooper spots (1)" },
{"DSPOSIT1", NULL },
{"DPPOSIT2", "Trooper spots (2)" },
{"DSPOSIT2", NULL },
{"DPPOSIT3", "Trooper spots (3)" },
{"DSPOSIT3", NULL },
{"DPBGSIT1", "Imp spots (1) " },
{"DSBGSIT1", NULL },
{"DPBGSIT2", "Imp spots (2) " },
{"DSBGSIT2", NULL },
{"DPSGTSIT", "Spectre spots " },
{"DSSGTSIT", NULL },
{"DPBRSSIT", "Baron spots " },
{"DSBRSSIT", NULL },
{"DPSGTATK", "Spectre attacks " },
{"DSSGTATK", NULL },
{"DPCLAW", "Spectre hits " },
{"DSCLAW", NULL },
{"DPPLDETH", "Player died " },
{"DSPLDETH", NULL },
{"DPPODTH1", "Trooper died (1) " },
{"DSPODTH1", NULL },
{"DPPODTH2", "Trooper died (2) " },
{"DSPODTH2", NULL },
{"DPPODTH3", "Trooper died (3) " },
{"DSPODTH3", NULL },
{"DPBGDTH1", "Imp died (1) " },
{"DSBGDTH1", NULL },
{"DPBGDTH2", "Imp died (2) " },
{"DSBGDTH2", NULL },
{"DPSGTDTH", "Spectre died " },
{"DSSGTDTH", NULL },
{"DPBRSDTH", "Baron died " },
{"DSBRSDTH", NULL },
{"DPPOSACT", "Trooper nearby " },
{"DSPOSACT", NULL },
{"DPBGACT", "Imp nearby " },
{"DSBGACT", NULL },
{"DPDMACT", "Spectre nearby " },
{"DSDMACT", NULL },
{"DPNOWAY", "Pushed on wall " },
{"DSNOWAY", NULL },
{"DPBAREXP", "Barrel exploding " },
{"DSBAREXP", NULL },
{"DPPUNCH", "Player punching " },
{"DSPUNCH", NULL },
{"DPPLASMA", "Plasmagun fire " },
{"DSPLASMA", NULL },
{"DPBFG", "BFG9000 fire " },
{"DSBFG", NULL },
{"DPCACSIT", "Caco Demon spots " },
{"DSCACSIT", NULL },
{"DPCYBSIT", "Cyber Demon spots" },
{"DSCYBSIT", NULL },
{"DPSPISIT", "Spider spots " },
{"DSSPISIT", NULL },
{"DPSKLATK", "Lost Soul attacks" },
{"DSSKLATK", NULL },
{"DPCACDTH", "Caco Demon died " },
{"DSCACDTH", NULL },
{"DPSKLDTH", "Lost Soul died " },
{"DSSKLDTH", NULL },
{"DPCYBDTH", "Cyber Demon died " },
{"DSCYBDTH", NULL },
{"DPSPIDTH", "Spider Demon died" },
{"DSSPIDTH", NULL },
{"DPHOOF", "Cyber Demon walks" },
{"DSHOOF", NULL },
{"DPMETAL", "Metal (?) " },
{"DSMETAL", NULL }};
#ifdef _AMIGA_
struct GfxBase *GfxBase; /* Pointer to graphics library */
struct IntuitionBase *IntuitionBase; /* Pointer to intuition library */
struct Screen *Screen; /* Pointer to current screen */
struct Window *Window; /* Pointer to current window */
struct NewScreen FirstScreen;
struct NewWindow FirstWindow;
struct IntuiMessage *IntuiMessage; /* Message from intuition */
unsigned long MessageClass; /* 'From' ID */
unsigned short Code; /* Value of the message */
#else
unsigned int Key;
#endif
void PrText (short Y0, short X0, unsigned char Color, char *Msg, ...)
/**********************************************************************************************************************************/
/* Pre : 'Y0' and 'X0' hold the coordinates, 'Color' holds the (VGA) color and 'Msg' holds the message to print. */
/* Post : If the coordinates were non-zero, then the message is printed at these coordinates in the given color. In case of the */
/* AMIGA, the coordinates have been converted from pixel- to textcoordinates. */
/* If X0 = 0, then the coordinates are not used; */
/* If X0 = -1, then the text is centered on line Y0. */
/* Import: None. */
/**********************************************************************************************************************************/
{
char Message[80];
va_list Args;
int X1;
int Y1;
va_start (Args, Msg);
vsprintf (Message, Msg, Args); /* Convert the message into one string */
va_end (Args);
#ifdef _AMIGA_
X1 = X0 * 8; /* Fontwidth is 8 pixels */
Y1 = Y0 * 8 + 18; /* Fontheight is 8 pixels, start past the window titlebar */
if (X0 == -1)
X1 = ((80 - strlen (Message)) / 2) * 8;
if (X0 != 0)
Move (&Screen->RastPort, X1, Y1);
SetAPen (&Screen->RastPort, Color);
Text (&Screen->RastPort, Message, strlen (Message));
#else
if (X0 == -1)
_settextposition (Y0, (80 - strlen (Message)) / 2);
if (X0 > 0)
_settextposition (Y0, X0);
_settextcolor (Color);
_outtext (Message);
#endif
}
void ClearScreen (void)
/**********************************************************************************************************************************/
/* Pre : None. */
/* Post : The screen has been cleared. */
/* Import: PrText. */
/**********************************************************************************************************************************/
{
int N;
#ifdef _AMIGA_
for (N = 1 ; N < 30 ; N ++)
PrText (N, 1, DBLACK, " ");
#else
_clearscreen (_GCLEARSCREEN);
#endif
}
#ifdef _AMIGA_
void CloseAllIntuition (void)
/********************************************************************************************************************************/
/* Pre : None. */
/* Post : All windows and screens have been closed, all libraries have been released. */
/* Import: None. */
/********************************************************************************************************************************/
{
if (Window)
CloseWindow (Window);
if (Screen)
CloseScreen (Screen);
if (IntuitionBase)
CloseLibrary (IntuitionBase);
if (GfxBase)
CloseLibrary (GfxBase);
}
void SwapDbyte (dbyte *Number)
/********************************************************************************************************************************/
/* Pre : 'Number' holds a pointer to the dbyte that should be swapped. */
/* Post : The number is converted from Little Endian to Big Endian (or vice versa). */
/* Import: None. */
/********************************************************************************************************************************/
{
unsigned char *Cp;
unsigned char Temp;
Cp = (unsigned char *)Number;
Temp = *Cp;
*Cp = *(Cp + 1);
*(Cp + 1) = Temp;
}
void SwapLong (unsigned long *Number)
/********************************************************************************************************************************/
/* Pre : 'Number' holds a pointer to the long that should be swapped. */
/* Post : The number is converted from Little Endian to Big Endian (or vice versa). */
/* Import: None. */
/********************************************************************************************************************************/
{
unsigned char *Cp;
unsigned char Temp;
Cp = (unsigned char *)Number;
Temp = *Cp; /* Swap bytes 0 and 3 */
*Cp = *(Cp + 3);
*(Cp + 3) = Temp;
Temp = *(Cp + 1); /* Swap bytes 1 and 2 */
*(Cp + 1) = *(Cp + 2);
*(Cp + 2) = Temp;
}
#endif
void Bye (char *Message)
/**********************************************************************************************************************************/
/* Pre : 'Message' holds the errormessage. */
/* Post : 'Message' has been printed, any open file has been closed and the program is aborted. */
/* Import: CloseAllIntuition. */
/**********************************************************************************************************************************/
{
#ifdef _AMIGA_
CloseAllIntuition ();
#else
fcloseall ();
flushall ();
_setvideomode (_DEFAULTMODE);
#endif
fprintf (stderr, "%s\n", Message);
exit (0);
}
#ifdef _AMIGA_
void OpenAllIntuition (void)
/********************************************************************************************************************************/
/* Pre : None. */
/* Post : First the graphics and intuition libraries have been opened. After this a screen has been opened, in a resolution of */
/* 640x256x16, without titlebar. After this has a window been opened with the exact same size, which is layed over the */
/* screen. Finally, the palette has been converted to match the standard VGA colors of the PC. */
/* Import: Bye. */
/********************************************************************************************************************************/
{
FirstScreen.LeftEdge = 0; /* Initialize a screen */
FirstScreen.TopEdge = 0;
FirstScreen.Width = 640;
FirstScreen.Height = 256;
FirstScreen.Depth = 4; /* 16 colors */
FirstScreen.DetailPen = 0;
FirstScreen.BlockPen = 0;
FirstScreen.ViewModes = HIRES;
FirstScreen.Type = CUSTOMSCREEN;
FirstScreen.Font = NULL;
FirstScreen.DefaultTitle = NULL;
FirstScreen.Gadgets = NULL;
FirstScreen.CustomBitMap = NULL;
FirstWindow.LeftEdge = 0; /* Initialize the window */
FirstWindow.TopEdge = 0;
FirstWindow.Width = 640;
FirstWindow.Height = 256;
FirstWindow.DetailPen = DBLACK;
FirstWindow.BlockPen = LCYAN;
FirstWindow.IDCMPFlags = CLOSEWINDOW|VANILLAKEY; /* React to: close-gadget and keyboard (convert keys to ASCII) */
FirstWindow.Flags = WINDOWCLOSE|ACTIVATE|SMART_REFRESH;
FirstWindow.FirstGadget = NULL;
FirstWindow.CheckMark = NULL;
FirstWindow.Title = (unsigned char *)"WADinfo";
FirstWindow.Type = CUSTOMSCREEN;
if (!(GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L))) /* Open the libraries */
Bye ("ERROR - Graphics Library not found\n");
if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L)))
Bye ("ERROR - Intuition Library not found\n");
if (!(Screen = (struct Screen *)OpenScreen (&FirstScreen))) /* Open the screen */
Bye ("ERROR - Cannot open screen\n");
FirstWindow.Screen = Screen; /* Link the window to this screen */
if (!(Window = (struct Window *)OpenWindow (&FirstWindow))) /* Open the window */
Bye ("ERROR - Cannot open window\n");
SetRGB4 (&Screen->ViewPort, DBLACK , 0, 0, 0); /* Convert the palette to standard VGA (PC) */
SetRGB4 (&Screen->ViewPort, DBLUE , 0, 0, 8);
SetRGB4 (&Screen->ViewPort, DGREEN , 0, 8, 0);
SetRGB4 (&Screen->ViewPort, DCYAN , 0, 8, 8);
SetRGB4 (&Screen->ViewPort, DRED , 8, 0, 0);
SetRGB4 (&Screen->ViewPort, DMAGENTA, 8, 0, 8);
SetRGB4 (&Screen->ViewPort, DYELLOW , 8, 8, 0);
SetRGB4 (&Screen->ViewPort, DWHITE , 8, 8, 8);
SetRGB4 (&Screen->ViewPort, LBLACK , 5, 5, 5);
SetRGB4 (&Screen->ViewPort, LBLUE , 0, 0, 15);
SetRGB4 (&Screen->ViewPort, LGREEN , 0, 15, 0);
SetRGB4 (&Screen->ViewPort, LCYAN , 0, 15, 15);
SetRGB4 (&Screen->ViewPort, LRED , 15, 0, 0);
SetRGB4 (&Screen->ViewPort, LMAGENTA, 15, 0, 15);
SetRGB4 (&Screen->ViewPort, LYELLOW , 15, 15, 0);
SetRGB4 (&Screen->ViewPort, LWHITE , 15, 15, 15);
}
#endif
void ListSprites (void)
/**********************************************************************************************************************************/
/* Pre : None. */
/* Post : The new sprites in this WAD file have been listed on a cleared screen. */
/* Import: ClearScreen, PrText. */
/**********************************************************************************************************************************/
{
int Cnt;
int Xco = 1;
int Yco = 3;
boolean Type6Done = FALSE;
boolean Type7Done = FALSE;
boolean AdjustCo;
ClearScreen ();
PrText (1, -1, LBLUE, "NEW SPRITES IN THIS WAD FILE:");
for (Cnt = 0 ; Cnt < MAXSPRITES ; Cnt ++)
if (Sprites[Cnt].FieldFilled)
{
AdjustCo = TRUE;
switch (Sprites[Cnt].Type)
{
case 0 : PrText (Yco, Xco, DCYAN, "ENEMY ");
PrText ( 0, 0, LCYAN, Sprites[Cnt].Description);
break;
case 1 : PrText (Yco, Xco, DCYAN, "CARD ");
PrText ( 0, 0, LCYAN, Sprites[Cnt].Description);
break;
case 2 : PrText (Yco, Xco, DCYAN, "WEAPON ");
PrText ( 0, 0, LCYAN, Sprites[Cnt].Description);
break;
case 3 : PrText (Yco, Xco, DCYAN, "AMMO ");
PrText ( 0, 0, LCYAN, Sprites[Cnt].Description);
break;
case 4 : PrText (Yco, Xco, DCYAN, "BONUS ");
PrText ( 0, 0, LCYAN, Sprites[Cnt].Description);
break;
case 5 : PrText (Yco, Xco, DCYAN, "DECOR ");
PrText ( 0, 0, LCYAN, Sprites[Cnt].Description);
break;
case 6 : if (!Type6Done)
{
PrText (Yco, Xco, LCYAN, "Miscelanious weaponfire");
Type6Done = TRUE;
}
else
AdjustCo = FALSE;
break;
case 7 : if (!Type7Done)
{
PrText (Yco, Xco, LCYAN, "Miscelanious decorations");
Type7Done = TRUE;
}
else
AdjustCo = FALSE;
break;
default: PrText (Yco, Xco, LRED, "Unknown type %d for %s", Sprites[Cnt].Type, Sprites[Cnt].IdName);
}
if (AdjustCo)
if (++ Yco > 26)
{
Yco = 3;
Xco += 26;
}
}
PrText (28, -1, DYELLOW, "Any key to return...");
}
void ListMenus (void)
/**********************************************************************************************************************************/
/* Pre : None. */
/* Post : The new menu items in this WAD file have been listed on a cleared screen. */
/* Import: ClearScreen, PrText. */
/**********************************************************************************************************************************/
{
int Cnt;
int Xco = 1;
int Yco = 3;
ClearScreen ();
PrText (1, -1, LBLUE, "NEW MENU ITEMS IN THIS WAD FILE:");
for (Cnt = 0 ; Cnt < MAXMENUS ; Cnt ++)
if (Menus[Cnt].FieldFilled)
{
switch (Menus[Cnt].Type)
{
case 0 : PrText (Yco, Xco, DCYAN, "MAIN MENU ");
PrText ( 0, 0, LCYAN, "\'%s\'", Menus[Cnt].Description);
break;
case 1 : PrText (Yco, Xco, DCYAN, "SUBMENU ");
PrText ( 0, 0, LCYAN, "\'%s\'", Menus[Cnt].Description);
break;
case 2 : PrText (Yco, Xco, DCYAN, "PLAYING ");
PrText ( 0, 0, LCYAN, "\'%s\'", Menus[Cnt].Description);
break;
case 3 : PrText (Yco, Xco, DCYAN, "MISC ");
PrText ( 0, 0, LCYAN, Menus[Cnt].Description);
}
if (++ Yco > 26)
{
Yco = 3;
Xco += 36;
}
}
PrText (28, -1, DYELLOW, "Any key to return...");
}
void ListMusic (void)
/**********************************************************************************************************************************/
/* Pre : None. */
/* Post : The new music in this WAD file has been listed on a cleared screen. */
/* Import: ClearScreen, PrText. */
/**********************************************************************************************************************************/
{
int Cnt;
int Xco = 1;
int Yco = 3;
ClearScreen ();
PrText (1, -1, LBLUE, "NEW MUSIC IN THIS WAD FILE:");
for (Cnt = 0 ; Cnt < MAXMUSIC ; Cnt ++)
if (Music[Cnt].FieldFilled)
{
PrText (Yco, Xco, LCYAN, Music[Cnt].Description);
if (++ Yco > 26)
{
Yco = 3;
Xco += 36;
}
}
PrText (28, -1, DYELLOW, "Any key to return...");
}
void ListSounds (void)
/**********************************************************************************************************************************/
/* Pre : None. */
/* Post : The new sounds in this WAD file have been listed on a cleared screen. */
/* Import: ClearScreen, PrText. */
/**********************************************************************************************************************************/
{
int Cnt;
int Xco = 1;
int Yco = 4;
ClearScreen ();
PrText (1, -1, LBLUE, "NEW SOUNDS IN THIS WAD FILE:");
PrText (2, -1, LBLUE, "\'Spectre\' means \'Demon & Spectre\', \'spots\' means \'spots player\'");
for (Cnt = 0 ; Cnt < MAXSOUNDS ; Cnt += 2)
if (Sounds[Cnt].FieldFilled || Sounds[Cnt + 1].FieldFilled)
{
PrText (Yco, Xco, DCYAN, "[%2d] ", (Cnt / 2) + 1);
PrText ( 0, 0, LCYAN, Sounds[Cnt].Description);
if (++ Yco > 26)
{
Yco = 4;
Xco += 27;
}
}
PrText (28, -1, DYELLOW, "Any key to return...");
}
void CheckLevel (FILE *Fp, char MemNum)
/**********************************************************************************************************************************/
/* Pre : 'Fp' points to the open WAD file, 'MemNum' holds the ('Remember') level number to check. */
/* Post : The following tests have been made: */
/* - All LINEDEFS have a length of > 0; */
/* - All LINEDEFS use existing SIDEDEF numbers; */
/* - All LINEDEFS use existing VERTEX numbers for Start and End values; */
/* - The BLOCKMAP start is <= lowest VERTEX number; */
/* - The number of blocks in the BLOCKMAP is enough to fit the map; */
/* - All blocks contents in the BLOCKMAP start with a 0x0000 and end with a 0xFFFF; */
/* - All used LINEDEFS in the BLOCKMAP exist; */
/* - All used LINEDEFS in a block of the BLOCKMAP are indeed in the block (starting, ending or crossing); */
/* - The length of the REJECT data is ((number_of_SECTORS ^ 2) / 8), rounded upwards. */
/* - All THINGS have valid coordinates; */
/* - All THINGS have valid angles of appearance; */
/* - All THINGS are of known type; */
/* Import: PrText, SwapDbyte, Bye. */
/**********************************************************************************************************************************/
{
struct BlockMapHeader_s BlockMapHeader;
struct LineDef_s LineDef;
struct Vertex_s *VertexInfo;
struct Check_s *LineInfo;
dbyte *BlockInfo;
dbyte BlockOffset;
dbyte BlockNumber;
dbyte N;
dbyte TestMapX;
dbyte TestMapY;
dbyte TestMapX2;
dbyte TestMapY2;
dbyte NumberOfLineDefs;
dbyte NumberOfSideDefs;
dbyte NumberOfVertexes;
dbyte BlockMinX;
dbyte BlockMinY;
dbyte BlockMaxX;
dbyte BlockMaxY;
dbyte CntX;
dbyte CntY;
dbyte LineDefNumber;
char NextLine;
long Entries;
long BlockMapInfoSize;
boolean More;
for (N = 3 ; N < 29 ; N ++)
PrText (N, 40, DBLACK, " ");
NextLine = 3;
NumberOfLineDefs = Remember[MemNum].LineDefLoc.Size / sizeof (struct LineDef_s);
NumberOfSideDefs = Remember[MemNum].SideDefLoc.Size / sizeof (struct SideDef_s);
NumberOfVertexes = Remember[MemNum].VertexLoc.Size / sizeof (struct Vertex_s);
if ((LineInfo = ((struct Check_s *)malloc ((size_t)(sizeof (struct Check_s) * NumberOfLineDefs)))) == NULL)
Bye ("ERROR - Could not allocate enough memory\n");
if ((VertexInfo = ((struct Vertex_s *)malloc ((size_t)(sizeof (struct Vertex_s) * NumberOfVertexes)))) == NULL)
Bye ("ERROR - Could not allocate enough memory\n");
PrText (1, 68, DWHITE, "Loading...");
if (fseek (Fp, Remember[MemNum].VertexLoc.Start, SEEK_SET))
Bye ("ERROR - File location error\n");
if (fread (VertexInfo, 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s)) /* Read first vertex */
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&VertexInfo->MapX);
SwapDbyte (&VertexInfo->MapY);
#endif
Remember[MemNum].MinMapX = Remember[MemNum].MaxMapX = VertexInfo->MapX;
Remember[MemNum].MinMapY = Remember[MemNum].MaxMapY = VertexInfo->MapY;
N = 1;
Entries = sizeof (struct Vertex_s);
while (Entries < Remember[MemNum].VertexLoc.Size) /* Handle all entries */
{
if (fread ((VertexInfo + N), 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s))
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&(VertexInfo + N)->MapX);
SwapDbyte (&(VertexInfo + N)->MapY);
#endif
if ((VertexInfo + N)->MapX < Remember[MemNum].MinMapX)
Remember[MemNum].MinMapX = (VertexInfo + N)->MapX;
if ((VertexInfo + N)->MapX > Remember[MemNum].MaxMapX)
Remember[MemNum].MaxMapX = (VertexInfo + N)->MapX;
if ((VertexInfo + N)->MapY < Remember[MemNum].MinMapY)
Remember[MemNum].MinMapY = (VertexInfo + N)->MapY;
if ((VertexInfo + N)->MapY > Remember[MemNum].MaxMapY)
Remember[MemNum].MaxMapY = (VertexInfo + N)->MapY;
Entries += sizeof (struct Vertex_s);
N ++;
}
if (Remember[MemNum].MinMapX < 0)
Remember[MemNum].MapSizeX = -Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
else
Remember[MemNum].MapSizeX = Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
if (Remember[MemNum].MinMapY < 0)
Remember[MemNum].MapSizeY = -Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
else
Remember[MemNum].MapSizeY = Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
PrText (NextLine, 40, DMAGENTA, "LINEDEFS consistency check:");
if (fseek (Fp, Remember[MemNum].LineDefLoc.Start, SEEK_SET))
Bye ("ERROR - File location error\n");
Entries = 0;
N = 0;
More = TRUE;
while (Entries < Remember[MemNum].LineDefLoc.Size) /* Handle all entries */
{
if (fread (&LineDef, 1, sizeof (struct LineDef_s), Fp) != sizeof (struct LineDef_s))
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&LineDef.Start);
SwapDbyte (&LineDef.End);
SwapDbyte (&LineDef.SideDef1);
SwapDbyte (&LineDef.SideDef2);
#endif
if (LineDef.Start == LineDef.End) /* A LineDef with zero length */
{
PrText (NextLine + 1, 42, LRED, "LineDef %d has zero length", N);
More = FALSE;
}
else
if (LineDef.SideDef1 >= NumberOfSideDefs || (LineDef.SideDef2 != 0xFFFF && LineDef.SideDef2 >= NumberOfSideDefs))
{ /* Non-existent SideDef ? */
PrText (NextLine + 1, 42, LRED, "LineDef %d has an unknown SideDef", N);
More = FALSE;
}
if (LineDef.Start >= NumberOfVertexes || LineDef.End >= NumberOfVertexes) /* Non-existent Vertex ? */
{
if (More) /* Already an error-message printed ? */
PrText (NextLine + 1, 42, LRED, "LineDef %d has an unknown Vertex", N);
(LineInfo + N)->StartMapX = 0x8000; /* Ensure that the coordinates are off the map */
(LineInfo + N)->StartMapY = 0x8000;
(LineInfo + N)->EndMapX = 0x8000;
(LineInfo + N)->EndMapY = 0x8000;
More = FALSE;
}
else
{
(LineInfo + N)->StartMapX = (VertexInfo + LineDef.Start)->MapX;
(LineInfo + N)->StartMapY = (VertexInfo + LineDef.Start)->MapY;
(LineInfo + N)->EndMapX = (VertexInfo + LineDef.End)->MapX;
(LineInfo + N)->EndMapY = (VertexInfo + LineDef.End)->MapY;
}
N ++;
Entries += sizeof (struct LineDef_s);
}
if (More)
{
PrText (NextLine, 73, LMAGENTA, "Passed");
NextLine += 2;
}
else
{
PrText (NextLine, 73, LRED, "FAILED");
NextLine += 3;
}
free (VertexInfo);
if (fseek (Fp, Remember[MemNum].BlockMapLoc.Start, SEEK_SET))
Bye ("ERROR - File location error\n");
if (fread (&BlockMapHeader, 1, sizeof (struct BlockMapHeader_s), Fp) != sizeof (struct BlockMapHeader_s))
Bye ("ERROR - File read error\n");
BlockMapInfoSize = (size_t)(Remember[MemNum].BlockMapLoc.Size - sizeof (struct BlockMapHeader_s));
if ((BlockInfo = ((dbyte *)malloc (BlockMapInfoSize))) == NULL)
Bye ("ERROR - Could not allocate enough memory\n");
if (fread (BlockInfo, 1, BlockMapInfoSize, Fp) != BlockMapInfoSize)
Bye ("ERROR - File read error\n");
PrText (1, 68, DWHITE, " ");
#ifdef _AMIGA_
for (N = 0 ; N < (BlockMapInfoSize / sizeof (dbyte)) ; N ++)
SwapDbyte (BlockInfo + N);
#endif
PrText (NextLine, 40, DMAGENTA, "BLOCKMAP structure check:");
More = TRUE;
PrText (NextLine + 2, 40, LGREEN, "Origin (bottom-left) : (%5d, %5d) ", BlockMapHeader.OriginX, BlockMapHeader.OriginY);
if (((BlockMapHeader.OriginX <= Remember[MemNum].MinMapX) || (BlockMapHeader.OriginX >= (Remember[MemNum].MinMapX - 0x007F))) &&
((BlockMapHeader.OriginY <= Remember[MemNum].MinMapY) || (BlockMapHeader.OriginY >= (Remember[MemNum].MinMapY - 0x007F))))
PrText (0, 0, LMAGENTA, "+");
else
{
PrText (0, 0, LRED, "X");
More = FALSE;
}
PrText (NextLine + 3, 40, LGREEN, "Number of blocks : %5d x%5d ", BlockMapHeader.BlockCntX, BlockMapHeader.BlockCntY);
TestMapX = Remember[MemNum].MapSizeX / 0x0080 + ((Remember[MemNum].MapSizeX & 0x007F) ? 1 : 0);
TestMapY = Remember[MemNum].MapSizeY / 0x0080 + ((Remember[MemNum].MapSizeY & 0x007F) ? 1 : 0);
if ((BlockMapHeader.BlockCntX >= TestMapX) && (BlockMapHeader.BlockCntY >= TestMapY))
PrText (0, 0, LMAGENTA, "+");
else
{
PrText (0, 0, LRED, "X");
More = FALSE;
}
if (More)
PrText (NextLine, 73, LMAGENTA, "Passed");
else
PrText (NextLine, 73, LRED, "FAILED");
More = TRUE;
NextLine += 5;
PrText (NextLine, 40, DMAGENTA, "BLOCKMAP consistency check:");
BlockMinX = BlockMapHeader.OriginX;
BlockMaxX = BlockMapHeader.OriginX + 0x007F;
BlockMinY = BlockMapHeader.OriginY;
BlockMaxY = BlockMapHeader.OriginY + 0x007F;
for (CntY = 0 ; CntY < BlockMapHeader.BlockCntY && More ; CntY ++)
{
for (CntX = 0 ; CntX < BlockMapHeader.BlockCntX && More ; CntX ++)
{
BlockNumber = CntY * BlockMapHeader.BlockCntX + CntX;
BlockOffset = (*(BlockInfo + BlockNumber) - (sizeof (struct BlockMapHeader_s) / sizeof (dbyte)));
if (*(BlockInfo + BlockOffset) != 0x0000)
{
PrText (NextLine + 1, 42, LRED, "Invalid startmarker in block %d", BlockNumber + 1);
More = FALSE;
}
while (*(BlockInfo + (++ BlockOffset)) != 0xFFFF && More)
{
LineDefNumber = *(BlockInfo + BlockOffset);
if (BlockOffset > BlockMapInfoSize)
{
PrText (NextLine + 1, 42, LRED, "Missing endmarker in block %d", BlockNumber + 1);
More = FALSE;
}
else
if (LineDefNumber > NumberOfLineDefs)
{
PrText (NextLine + 1, 42, LRED, "Unknown LineDef %d in block %d", LineDefNumber, BlockNumber + 1);
More = FALSE;
}
else
{
TestMapX = (LineInfo + LineDefNumber)->StartMapX;
TestMapY = (LineInfo + LineDefNumber)->StartMapY;
TestMapX2 = (LineInfo + LineDefNumber)->EndMapX;
TestMapY2 = (LineInfo + LineDefNumber)->EndMapY;
if (TestMapX < BlockMinX || TestMapX > BlockMaxX) /* Start X is not in this block ? */
{
if (TestMapX2 < BlockMinX || TestMapX2 > BlockMaxX) /* End X also not in this block ? */
More = FALSE; /* Signal: LineDef crosses this block */
else
if (TestMapY2 < BlockMinY || TestMapY2 > BlockMaxY) /* End Y not in the block ? */
More = FALSE; /* Signal: LineDef crosses this block */
}
else
if (TestMapY < BlockMinY || TestMapY > BlockMaxY) /* Start Y not in the block ? */
More = FALSE; /* Signal: LineDef crosses this block */
if (!More) /* Crossing LineDef ? */
{ /* Test if that is possible */
More = TRUE;
if (TestMapX > TestMapX2) /* Line goes from right to left ? */
{ /* Then flip the line */
N = TestMapX;
TestMapX = TestMapX2;
TestMapX2 = N;
N = TestMapY;
TestMapY = TestMapY2;
TestMapY2 = N;
}
if (TestMapX < BlockMinX) /* Start X lies left */
{
if (TestMapX2 < BlockMinX) /* End X also left */
More = FALSE; /* Then the LineDef does NOT cross! */
}
else
if (TestMapX > BlockMinX) /* Start X lies right */
if (TestMapX > BlockMaxX) /* Even after the block */
More = FALSE; /* Then the LineDef does NOT cross! */
if (TestMapY > TestMapY2) /* Line goes from up to down ? */
{ /* Then flip the line */
N = TestMapX;
TestMapX = TestMapX2;
TestMapX2 = N;
N = TestMapY;
TestMapY = TestMapY2;
TestMapY2 = N;
}
if (TestMapY < BlockMinY) /* Start Y lies below */
{
if (TestMapY2 < BlockMinY) /* End Y also below */
More = FALSE; /* Then the LineDef does NOT cross! */
}
else
if (TestMapY > BlockMinY) /* Start Y lies above */
if (TestMapY > BlockMaxY) /* Even after the block */
More = FALSE; /* Then the LineDef does NOT cross! */
if (!More)
PrText (NextLine + 1, 42, LRED, "Invalid LineDef %d in block %d", LineDefNumber, BlockNumber + 1);
}
}
}
BlockMinX += 0x0080;
BlockMaxX += 0x0080;
}
BlockMinY += 0x0080;
BlockMaxY += 0x0080;
BlockMinX = BlockMapHeader.OriginX;
BlockMaxX = BlockMapHeader.OriginX + 0x007F;
}
if (More)
{
PrText (NextLine, 73, LMAGENTA, "Passed");
NextLine += 2;
}
else
{
PrText (NextLine, 73, LRED, "FAILED");
NextLine += 3;
}
free (BlockInfo);
free (LineInfo);
PrText (NextLine, 40, DMAGENTA, "REJECT consistency check:");
if ((long)ceil (pow ((double)(Remember[MemNum].SectorLoc.Size / sizeof (struct Sector_s)), 2) / 8) == Remember[MemNum].RejectDataLoc.Size)
PrText (NextLine, 73, LMAGENTA, "Passed");
else
PrText (NextLine, 73, LRED, "FAILED");
NextLine += 2;
PrText (NextLine, 40, DMAGENTA, "THINGS consistency check:");
PrText (1, 68, DWHITE, "Loading...");
if (fseek (Fp, Remember[MemNum].ThingsLoc.Start, SEEK_SET))
Bye ("ERROR - File location error\n");
More = TRUE;
Entries = 0;
while (Entries < Remember[MemNum].ThingsLoc.Size && More) /* Handle all entries */
{
if (fread (&Thing, 1, sizeof (struct Thing_s), Fp) != sizeof (struct Thing_s))
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&Thing.Xpos);
SwapDbyte (&Thing.Ypos);
SwapDbyte (&Thing.Angle);
SwapDbyte (&Thing.Type);
SwapDbyte (&Thing.When);
#endif
if (Thing.Xpos < BlockMapHeader.OriginX || Thing.Xpos > (BlockMapHeader.OriginX + 0x0080 * BlockMapHeader.BlockCntX - 1) ||
Thing.Ypos < BlockMapHeader.OriginY || Thing.Ypos > (BlockMapHeader.OriginY + 0x0080 * BlockMapHeader.BlockCntY - 1))
{
PrText (NextLine + 1, 40, LRED, "Thing located outside the map");
More = FALSE;
}
else
if (Thing.Angle >= 360)
{
PrText (NextLine + 1, 40, LRED, "Unknown angle %d encountered", Thing.Angle);
More = FALSE;
}
else
if ((Thing.Type > 0x003F && Thing.Type < 0x07D1) ||
Thing.Type == 0x07D9 ||
(Thing.Type > 0x07DF && Thing.Type < 0x07E2) ||
(Thing.Type > 0x07E3 && Thing.Type < 0x07E6) ||
Thing.Type == 0x07EB ||
(Thing.Type > 0x07EC && Thing.Type < 0x07F3) ||
(Thing.Type > 0x07F3 && Thing.Type < 0x07FD) ||
(Thing.Type > 0x0801 && Thing.Type < 0x0BB9) ||
Thing.Type > 0x0BBE)
{
PrText (NextLine + 1, 40, LRED, "Unknown thing %d encountered", Thing.Type);
More = FALSE;
}
Entries += sizeof (struct Thing_s);
}
PrText (1, 68, DWHITE, " ");
if (More)
{
PrText (NextLine, 73, LMAGENTA, "Passed");
NextLine += 2;
}
else
{
PrText (NextLine, 73, LRED, "FAILED");
NextLine += 3;
}
}
dbyte main (int argc, char *argv[])
/**********************************************************************************************************************************/
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN ROUTINE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* Import: Bye, SwapDbyte, SwapLong, OpenAllIntuition, ClearScreen, ListSprites, ListSounds, PrText. */
/**********************************************************************************************************************************/
{
FILE *Fp;
char S[9];
char Last[5];
char ThingMem = -1;
char M;
char N;
char O;
char MemNum;
long Entries;
boolean More;
boolean KeyOk;
boolean KeySprites = FALSE;
boolean KeySounds = FALSE;
boolean KeyMenus = FALSE;
boolean KeyMusic = FALSE;
boolean KeyNext = FALSE;
boolean KeyPrevious = FALSE;
boolean KeyInfo = FALSE;
boolean KeyCheckLevel = FALSE;
boolean Listing = FALSE;
boolean Checked = FALSE;
boolean LevelInfoType = TRUE;
boolean ReprintAll = TRUE;
boolean ReprintLevels = TRUE;
boolean ReprintAny = TRUE;
#ifdef _AMIGA_
OpenAllIntuition ();
#else
_setvideomode (_VRES16COLOR); /* Choose video mode 640x480x16 */
#endif
if (!(Fp = fopen (argv[1], "rb"))) /* Open the WAD file */
Bye ("ERROR - File does not exist\n");
PrText (1, 1, LWHITE, "Analyzing the WAD file...");
PrText (1, 68, DWHITE, "Loading...");
if (fread (&WadHeader, 1, sizeof (struct WadHeader_s), Fp) != sizeof (struct WadHeader_s)) /* Go to the WAD 'directory' */
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapLong (&WadHeader.DirStart);
SwapLong (&WadHeader.DirSize);
#endif
if (fseek (Fp, WadHeader.DirStart, SEEK_SET))
Bye ("ERROR - File location error\n");
for (M = 0 ; M < 27 ; M ++)
{
Remember[M].ThingsFilled = FALSE;
Remember[M].StatsFilled = FALSE;
}
WadInfo.NewStuff = 0x00;
WadInfo.NewLevels = 0x00000000;
WadInfo.NewDemos = 0x0000;
Entries = -1;
while (++ Entries < WadHeader.DirSize) /* Handle all entries in the 'directory' */
{
if (fread (&Directory, 1, sizeof (struct Directory_s), Fp) != sizeof (struct Directory_s)) /* Read an entry */
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapLong (&Directory.Start);
SwapLong (&Directory.Size);
#endif
for (M = 0 ; M < 8 ; M ++)
S[M] = toupper (Directory.Name[M]);
S[8] = '\0';
More = TRUE;
for (M = 0 ; M < MAXCOLORS && More ; M ++)
if (!strncmp (S, Colors[M], strlen (Colors[M])))
{
More = FALSE;
WadInfo.NewStuff |= NEWCOLORS;
}
if (More)
if (!strncmp (S, "DEMO", 4))
{
More = FALSE;
WadInfo.NewDemos |= ((dbyte)1 << (S[4]-'1'));
}
if (More)
for (M = 0 ; M < MAXLEVELS && More ; M ++)
if (!strncmp (S, Levels[M], strlen (Levels[M])))
{
More = FALSE;
WadInfo.NewLevels |= ((long)1 << M);
strncpy (Last, S, 4);
ThingMem ++;
Last[4] = '\0';
}
if (More)
for (M = 0 ; M < MAXSPRITES && More ; M ++)
if (!strncmp (S, Sprites[M].IdName, strlen (Sprites[M].IdName)))
{
More = FALSE;
WadInfo.NewStuff |= NEWSPRITES;
Sprites[M].FieldFilled = TRUE;
}
if (More)
for (M = 0 ; M < MAXMUSIC && More ; M ++)
if (!strncmp (S, Music[M].IdName, strlen (Music[M].IdName)))
{
More = FALSE;
WadInfo.NewStuff |= NEWMUSIC;
Music[M].FieldFilled = TRUE;
}
if (More)
for (M = 0 ; M < MAXINSTRUMENTS && More ; M ++)
if (!strncmp (S, Instruments[M], strlen (Instruments[M])))
{
More = FALSE;
WadInfo.NewStuff |= NEWINSTRUMENTS;
}
if (More)
for (M = 0 ; M < MAXSTATUSBAR && More ; M ++)
if (!strncmp (S, StatusBar[M], strlen (StatusBar[M])))
{
More = FALSE;
WadInfo.NewStuff |= NEWSTATUSBAR;
}
if (More)
for (M = 0 ; M < MAXMENUS && More ; M ++)
if (!strncmp (S, Menus[M].IdName, strlen (Menus[M].IdName)))
{
More = FALSE;
WadInfo.NewStuff |= NEWMENUS;
Menus[M].FieldFilled = TRUE;
}
if (More)
for (M = 0 ; M < MAXSOUNDS && More ; M ++)
if (!strncmp (S, Sounds[M].IdName, strlen (Sounds[M].IdName)))
{
More = FALSE;
WadInfo.NewStuff |= NEWSOUNDS;
Sounds[M].FieldFilled = TRUE;
}
if (More && !strncmp (S, "THINGS", 6))
{
Remember[ThingMem].ThingsLoc.Start = Directory.Start; /* The "THINGS" part of a level is dealt with later */
Remember[ThingMem].ThingsLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].ThingsLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "VERTEXES", 8))
{
Remember[ThingMem].VertexLoc.Start = Directory.Start;
Remember[ThingMem].VertexLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].VertexLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "LINEDEFS", 8))
{
Remember[ThingMem].LineDefLoc.Start = Directory.Start;
Remember[ThingMem].LineDefLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].LineDefLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "SIDEDEFS", 8))
{
Remember[ThingMem].SideDefLoc.Start = Directory.Start;
Remember[ThingMem].SideDefLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].SideDefLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "SEGS", 4))
{
Remember[ThingMem].SegLoc.Start = Directory.Start;
Remember[ThingMem].SegLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].SegLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "SECTORS", 7))
{
Remember[ThingMem].SectorLoc.Start = Directory.Start;
Remember[ThingMem].SectorLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].SectorLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "SSECTORS", 8))
{
Remember[ThingMem].SubSectorLoc.Start = Directory.Start;
Remember[ThingMem].SubSectorLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].SubSectorLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "NODES", 5))
{
Remember[ThingMem].NodeLoc.Start = Directory.Start;
Remember[ThingMem].NodeLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].NodeLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "REJECT", 6))
{
Remember[ThingMem].RejectDataLoc.Start = Directory.Start;
Remember[ThingMem].RejectDataLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].RejectDataLoc.Name, Last);
More = FALSE;
}
if (More && !strncmp (S, "BLOCKMAP", 8))
{
Remember[ThingMem].BlockMapLoc.Start = Directory.Start;
Remember[ThingMem].BlockMapLoc.Size = Directory.Size;
strcpy (Remember[ThingMem].BlockMapLoc.Name, Last);
More = FALSE;
}
if (More && Directory.Start != 0)
WadInfo.NewStuff |= NEWGRAPHS;
}
PrText (1, 1, LWHITE, " ");
PrText (1, 68, DWHITE, " ");
ThingMem ++;
MemNum = 0;
More = TRUE;
while (More)
{
if (ReprintAny)
{
if (ReprintAll)
{
#ifdef _AMIGA_
PrText ( 1, 1, LWHITE, "Filename : %s", argv[1]);
#else
PrText ( 1, 1, LWHITE, "Filename : %s", strupr (argv[1]));
#endif
for (N = 0 ; N < 4 ; N ++) /* Convert the type to a string */
S[N] = WadHeader.Type[N];
S[N] = '\0';
PrText ( 2, 1, LWHITE, "Wadfile type : %s", S); /* Print the WAD 'directory' information */
PrText ( 3, 1, LWHITE, "Directory start: %08lX", WadHeader.DirStart);
PrText ( 4, 1, LWHITE, "Directory size : %08lX", WadHeader.DirSize);
PrText ( 7, 1, LBLUE, "New Colors : %s", WadInfo.NewStuff & NEWCOLORS ? "Yes" : "-");
PrText ( 8, 1, LBLUE, "New Demos :");
if (WadInfo.NewDemos == 0x0000)
PrText (0, 0, LBLUE, " -");
for (N = 0 ; N < 10 ; N ++)
if (WadInfo.NewDemos & ((dbyte)1 << N))
PrText (0, 0, LBLUE, " %d", N + 1);
PrText ( 9, 1, LBLUE, "New Sounds : %s", WadInfo.NewStuff & NEWSOUNDS ? "Yes" : "-");
PrText (10, 1, LBLUE, "New Instruments: %s", WadInfo.NewStuff & NEWINSTRUMENTS ? "Yes" : "-");
PrText (11, 1, LBLUE, "New Music : %s", WadInfo.NewStuff & NEWMUSIC ? "Yes" : "-");
PrText (12, 1, LBLUE, "New Sprites : %s", WadInfo.NewStuff & NEWSPRITES ? "Yes" : "-");
PrText (13, 1, LBLUE, "New Status bar : %s", WadInfo.NewStuff & NEWSTATUSBAR ? "Yes" : "-");
PrText (14, 1, LBLUE, "New Menu items : %s", WadInfo.NewStuff & NEWMENUS ? "Yes" : "-");
PrText (15, 1, LBLUE, "New Graphics : %s", WadInfo.NewStuff & NEWGRAPHS ? "Yes" : "-");
PrText (16, 1, LBLUE, "New Levels :");
if (WadInfo.NewLevels == 0x00000000)
PrText (0, 0, LBLUE, " -");
else
for (N = 0 ; N < NUMEPISODE ; N ++)
if ((WadInfo.NewLevels & ((long)0x1FF << (N * NUMLEVEL))) == ((long)0x1FF << (N * NUMLEVEL)))
PrText (0, 0, LBLUE, " e%d", (dbyte)N + 1);
else
for (O = 0 ; O < NUMLEVEL ; O ++)
if (WadInfo.NewLevels & ((long)1 << (N*NUMLEVEL+O)))
PrText (0, 0, LBLUE, " %d%d", (dbyte)N + 1, (dbyte)O + 1);
ReprintLevels = TRUE;
}
if (ReprintLevels && ThingMem > 0) /* New levels ? */
{
PrText (1, 40, LYELLOW, "INFORMATION ON LEVEL %s:", Remember[MemNum].ThingsLoc.Name);
if (LevelInfoType)
{
if (!Remember[MemNum].ThingsFilled)
{
PrText (1, 68, DWHITE, "Loading...");
for (N = 0 ; N < 4 ; N ++)
{
Remember[MemNum].PlayerStarts[N] = 0;
for (O = 0 ; O < 16 ; O ++)
Remember[MemNum].ThingType[O][N] = 0;
}
Remember[MemNum].PlayerStarts[4] = 0;
if (fseek (Fp, Remember[MemNum].ThingsLoc.Start, SEEK_SET)) /* Go to the start of the data */
Bye ("ERROR - File location error\n");
Entries = 0;
while (Entries < Remember[MemNum].ThingsLoc.Size) /* Handle all entries */
{
if (fread (&Thing, 1, sizeof (struct Thing_s), Fp) != sizeof (struct Thing_s)) /* Read an entry */
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&Thing.Xpos);
SwapDbyte (&Thing.Ypos);
SwapDbyte (&Thing.Angle);
SwapDbyte (&Thing.Type);
SwapDbyte (&Thing.When);
#endif
switch (Thing.Type) /* Find out if the type is interesting */
{
case THING_PLAYER1 : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[0]) ++; break; /* Handle playerstarts */
case THING_PLAYER2 : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[1]) ++; break;
case THING_PLAYER3 : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[2]) ++; break;
case THING_PLAYER4 : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[3]) ++; break;
case THING_DEATHMATCH : Thing.Type = 0xFFFF; (Remember[MemNum].PlayerStarts[4]) ++; break;
case THING_CHAINSAW : Thing.Type = TYPE_CHAINSAW; break; /* Convert type to array index */
case THING_SHOTGUN : Thing.Type = TYPE_SHOTGUN; break;
case THING_CHAINGUN : Thing.Type = TYPE_CHAINGUN; break;
case THING_LAUNCHER : Thing.Type = TYPE_LAUNCHER; break;
case THING_PLASMAGUN : Thing.Type = TYPE_PLASMAGUN; break;
case THING_BFG9000 : Thing.Type = TYPE_BFG9000; break;
case THING_TROOPER : Thing.Type = TYPE_TROOPER; break;
case THING_SARGEANT : Thing.Type = TYPE_SARGEANT; break;
case THING_IMP : Thing.Type = TYPE_IMP; break;
case THING_DEMON : Thing.Type = TYPE_DEMON; break;
case THING_SPECTRE : Thing.Type = TYPE_SPECTRE; break;
case THING_CACODEMON : Thing.Type = TYPE_CACODEMON; break;
case THING_LOSTSOUL : Thing.Type = TYPE_LOSTSOUL; break;
case THING_BARON : Thing.Type = TYPE_BARON; break;
case THING_CYBERDEMON : Thing.Type = TYPE_CYBERDEMON; break;
case THING_SPIDERBOSS : Thing.Type = TYPE_SPIDERBOSS; break;
default : Thing.Type = 0xFFFF;
}
if (Thing.Type != 0xFFFF) /* Unhandled type ? */
{ /* Update array entry, depending on the appearance (difficulty) */
if ((Thing.When & WHEN_MULTI) == WHEN_MULTI) /* If it appears in multi, then the other bits are undefined */
(Remember[MemNum].ThingType[Thing.Type][3]) ++;
else
{
if ((Thing.When & WHEN_D12) == WHEN_D12)
(Remember[MemNum].ThingType[Thing.Type][0]) ++;
if ((Thing.When & WHEN_D3) == WHEN_D3)
(Remember[MemNum].ThingType[Thing.Type][1]) ++;
if ((Thing.When & WHEN_D45) == WHEN_D45)
(Remember[MemNum].ThingType[Thing.Type][2]) ++;
}
}
Entries += sizeof (struct Thing_s);
}
Remember[MemNum].ThingsFilled = TRUE;
PrText (1, 68, DWHITE, " ");
}
if (Remember[MemNum].PlayerStarts[0]) /* Print number of found starting pads */
if (Remember[MemNum].PlayerStarts[1])
if (Remember[MemNum].PlayerStarts[2])
if (Remember[MemNum].PlayerStarts[3])
PrText (3, 40, LGREEN, "Number of player starts : 4 ");
else
PrText (3, 40, LGREEN, "Number of player starts : 3 ");
else
PrText (3, 40, LGREEN, "Number of player starts : 2 ");
else
PrText (3, 40, LGREEN, "Number of player starts : 1 ");
else
PrText (3, 40, LGREEN, "Number of player starts : none ");
if (Remember[MemNum].PlayerStarts[4] == 0)
PrText (4, 40, LGREEN, "Number of deathmatch starts: none ");
else
if (Remember[MemNum].PlayerStarts[4] == 1)
PrText (4, 40, LGREEN, "Number of deathmatch starts: 1 ");
else
PrText (4, 40, LGREEN, "Number of deathmatch starts: %d ", Remember[MemNum].PlayerStarts[4]);
PrText ( 5, 40, DBLACK, " ");
PrText ( 6, 40, DBLACK, " ");
PrText ( 7, 40, DMAGENTA, "Weapons in this level: D12 D3 D45 MUL "); /* Print the other recorded information */
PrText ( 8, 40, DBLACK, " ");
PrText ( 9, 40, LMAGENTA, "(1) Chainsaw %3d %3d %3d %3d ", Remember[MemNum].ThingType[0][0],
Remember[MemNum].ThingType[0][1],
Remember[MemNum].ThingType[0][2],
Remember[MemNum].ThingType[0][3]);
PrText (10, 40, LMAGENTA, "(3) Shotgun %3d %3d %3d %3d ", Remember[MemNum].ThingType[1][0],
Remember[MemNum].ThingType[1][1],
Remember[MemNum].ThingType[1][2],
Remember[MemNum].ThingType[1][3]);
PrText (11, 40, LMAGENTA, "(4) Chaingun %3d %3d %3d %3d ", Remember[MemNum].ThingType[2][0],
Remember[MemNum].ThingType[2][1],
Remember[MemNum].ThingType[2][2],
Remember[MemNum].ThingType[2][3]);
PrText (12, 40, LMAGENTA, "(5) Rocket launcher %3d %3d %3d %3d ", Remember[MemNum].ThingType[3][0],
Remember[MemNum].ThingType[3][1],
Remember[MemNum].ThingType[3][2],
Remember[MemNum].ThingType[3][3]);
PrText (13, 40, LMAGENTA, "(6) Plasmagun %3d %3d %3d %3d ", Remember[MemNum].ThingType[4][0],
Remember[MemNum].ThingType[4][1],
Remember[MemNum].ThingType[4][2],
Remember[MemNum].ThingType[4][3]);
PrText (14, 40, LMAGENTA, "(7) BFG9000 %3d %3d %3d %3d ", Remember[MemNum].ThingType[5][0],
Remember[MemNum].ThingType[5][1],
Remember[MemNum].ThingType[5][2],
Remember[MemNum].ThingType[5][3]);
PrText (15, 40, DBLACK, " ");
PrText (16, 40, DMAGENTA, "Enemies in this level: D12 D3 D45 MUL ");
PrText (17, 40, DBLACK, " ");
PrText (18, 40, LMAGENTA, "Trooper %3d %3d %3d %3d ", Remember[MemNum].ThingType[6][0],
Remember[MemNum].ThingType[6][1],
Remember[MemNum].ThingType[6][2],
Remember[MemNum].ThingType[6][3]);
PrText (19, 40, LMAGENTA, "Sargeant %3d %3d %3d %3d ", Remember[MemNum].ThingType[7][0],
Remember[MemNum].ThingType[7][1],
Remember[MemNum].ThingType[7][2],
Remember[MemNum].ThingType[7][3]);
PrText (20, 40, LMAGENTA, "Imp %3d %3d %3d %3d ", Remember[MemNum].ThingType[8][0],
Remember[MemNum].ThingType[8][1],
Remember[MemNum].ThingType[8][2],
Remember[MemNum].ThingType[8][3]);
PrText (21, 40, LMAGENTA, "Demon %3d %3d %3d %3d ", Remember[MemNum].ThingType[9][0],
Remember[MemNum].ThingType[9][1],
Remember[MemNum].ThingType[9][2],
Remember[MemNum].ThingType[9][3]);
PrText (22, 40, LMAGENTA, "Spectre %3d %3d %3d %3d ", Remember[MemNum].ThingType[10][0],
Remember[MemNum].ThingType[10][1],
Remember[MemNum].ThingType[10][2],
Remember[MemNum].ThingType[10][3]);
PrText (23, 40, LMAGENTA, "Caco Demon %3d %3d %3d %3d ", Remember[MemNum].ThingType[11][0],
Remember[MemNum].ThingType[11][1],
Remember[MemNum].ThingType[11][2],
Remember[MemNum].ThingType[11][3]);
PrText (24, 40, LMAGENTA, "Lost soul %3d %3d %3d %3d ", Remember[MemNum].ThingType[12][0],
Remember[MemNum].ThingType[12][1],
Remember[MemNum].ThingType[12][2],
Remember[MemNum].ThingType[12][3]);
PrText (25, 40, LMAGENTA, "Baron of Hell %3d %3d %3d %3d ", Remember[MemNum].ThingType[13][0],
Remember[MemNum].ThingType[13][1],
Remember[MemNum].ThingType[13][2],
Remember[MemNum].ThingType[13][3]);
PrText (26, 40, LMAGENTA, "Cyber Demon %3d %3d %3d %3d ", Remember[MemNum].ThingType[14][0],
Remember[MemNum].ThingType[14][1],
Remember[MemNum].ThingType[14][2],
Remember[MemNum].ThingType[14][3]);
PrText (27, 40, LMAGENTA, "Spider Demon %3d %3d %3d %3d ", Remember[MemNum].ThingType[15][0],
Remember[MemNum].ThingType[15][1],
Remember[MemNum].ThingType[15][2],
Remember[MemNum].ThingType[15][3]);
PrText (28, 40, DBLACK, " ");
}
else
{
if (!Remember[MemNum].StatsFilled)
{
PrText (1, 68, DWHITE, "Loading...");
if (fseek (Fp, Remember[MemNum].VertexLoc.Start, SEEK_SET))
Bye ("ERROR - File location error\n");
if (fread (&Vertex, 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s)) /* Read an entry */
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&Vertex.MapX);
SwapDbyte (&Vertex.MapY);
#endif
Remember[MemNum].MinMapX = Remember[MemNum].MaxMapX = Vertex.MapX;
Remember[MemNum].MinMapY = Remember[MemNum].MaxMapY = Vertex.MapY;
Entries = sizeof (struct Vertex_s);
while (Entries < Remember[MemNum].VertexLoc.Size) /* Handle all entries */
{
if (fread (&Vertex, 1, sizeof (struct Vertex_s), Fp) != sizeof (struct Vertex_s)) /* Read an entry */
Bye ("ERROR - File read error\n");
#ifdef _AMIGA_
SwapDbyte (&Vertex.MapX);
SwapDbyte (&Vertex.MapY);
#endif
if (Vertex.MapX < Remember[MemNum].MinMapX)
Remember[MemNum].MinMapX = Vertex.MapX;
if (Vertex.MapX > Remember[MemNum].MaxMapX)
Remember[MemNum].MaxMapX = Vertex.MapX;
if (Vertex.MapY < Remember[MemNum].MinMapY)
Remember[MemNum].MinMapY = Vertex.MapY;
if (Vertex.MapY > Remember[MemNum].MaxMapY)
Remember[MemNum].MaxMapY = Vertex.MapY;
Entries += sizeof (struct Vertex_s);
}
if (Remember[MemNum].MinMapX < 0)
Remember[MemNum].MapSizeX = -Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
else
Remember[MemNum].MapSizeX = Remember[MemNum].MinMapX + Remember[MemNum].MaxMapX;
if (Remember[MemNum].MinMapY < 0)
Remember[MemNum].MapSizeY = -Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
else
Remember[MemNum].MapSizeY = Remember[MemNum].MinMapY + Remember[MemNum].MaxMapY;
Remember[MemNum].StatsFilled = TRUE;
PrText (1, 68, DWHITE, " ");
}
PrText ( 3, 40, DGREEN, "THINGS start : %08lX ", Remember[MemNum].ThingsLoc.Start);
PrText ( 4, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].ThingsLoc.Size,
Remember[MemNum].ThingsLoc.Size / sizeof (struct Thing_s));
PrText ( 5, 40, DGREEN, "VERTEXES start : %08lX ", Remember[MemNum].VertexLoc.Start);
PrText ( 6, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].VertexLoc.Size,
Remember[MemNum].VertexLoc.Size / sizeof (struct Vertex_s));
PrText ( 7, 40, DGREEN, "LINEDEFS start : %08lX ", Remember[MemNum].LineDefLoc.Start);
PrText ( 8, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].LineDefLoc.Size,
Remember[MemNum].LineDefLoc.Size / sizeof (struct LineDef_s));
PrText ( 9, 40, DGREEN, "SIDEDEFS start : %08lX ", Remember[MemNum].SideDefLoc.Start);
PrText (10, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].SideDefLoc.Size,
Remember[MemNum].SideDefLoc.Size / sizeof (struct SideDef_s));
PrText (11, 40, DGREEN, "SEGS start : %08lX ", Remember[MemNum].SegLoc.Start);
PrText (12, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].SegLoc.Size,
Remember[MemNum].SegLoc.Size / sizeof (struct Seg_s));
PrText (13, 40, DGREEN, "SECTORS start : %08lX ", Remember[MemNum].SectorLoc.Start);
PrText (14, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].SectorLoc.Size,
Remember[MemNum].SectorLoc.Size / sizeof (struct Sector_s));
PrText (15, 40, DGREEN, "SSECTORS start : %08lX ", Remember[MemNum].SubSectorLoc.Start);
PrText (16, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].SubSectorLoc.Size,
Remember[MemNum].SubSectorLoc.Size / sizeof (struct SubSector_s));
PrText (17, 40, DGREEN, "NODES start : %08lX ", Remember[MemNum].NodeLoc.Start);
PrText (18, 40, DGREEN, " size : %08lX (%4lu) ", Remember[MemNum].NodeLoc.Size,
Remember[MemNum].NodeLoc.Size / sizeof (struct Node_s));
PrText (19, 40, DGREEN, "REJECT start : %08lX ", Remember[MemNum].RejectDataLoc.Start);
PrText (20, 40, DGREEN, " size : %08lX ", Remember[MemNum].RejectDataLoc.Size);
PrText (21, 40, DGREEN, "BLOCKMAP start : %08lX ", Remember[MemNum].BlockMapLoc.Start);
PrText (22, 40, DGREEN, " size : %08lX ", Remember[MemNum].BlockMapLoc.Size);
PrText (23, 40, DBLACK, " ");
PrText (24, 40, LMAGENTA, "Top-left map : (%5d, %5d) ", Remember[MemNum].MinMapX, Remember[MemNum].MinMapY);
PrText (25, 40, LMAGENTA, "Bottom-right map : (%5d, %5d) ", Remember[MemNum].MaxMapX, Remember[MemNum].MaxMapY);
PrText (26, 40, LMAGENTA, "Center of map : (%5d, %5d) ",
Remember[MemNum].MaxMapX - (Remember[MemNum].MapSizeX / 2),
Remember[MemNum].MaxMapY - (Remember[MemNum].MapSizeY / 2));
PrText (27, 40, DBLACK, " ");
PrText (28, 40, LMAGENTA, "Size of map : %5d x %5d ", Remember[MemNum].MapSizeX, Remember[MemNum].MapSizeY);
}
}
PrText (19, 1, DYELLOW, "Press :");
PrText (20, 1, DYELLOW, " [Q] to quit ");
if (ThingMem > 0)
{
PrText (21, 1, DYELLOW, " [I] to toggle level info type ");
KeyInfo = TRUE;
}
else
{
PrText (21, 1, DYELLOW, " ");
KeyInfo = FALSE;
}
if (ThingMem > 0)
{
PrText (22, 1, DYELLOW, " [C] to check this level ");
KeyCheckLevel = TRUE;
}
else
{
PrText (22, 1, DYELLOW, " ");
KeyCheckLevel = FALSE;
}
if ((ThingMem > 0) && (MemNum < ThingMem - 1))
{
PrText (23, 1, DYELLOW, " [N] for next level ");
KeyNext = TRUE;
}
else
{
PrText (23, 1, DYELLOW, " ");
KeyNext = FALSE;
}
if ((ThingMem > 0) && (MemNum > 0))
{
PrText (24, 1, DYELLOW, " [P] for previous level ");
KeyPrevious = TRUE;
}
else
{
PrText (24, 1, DYELLOW, " ");
KeyPrevious = FALSE;
}
if ((WadInfo.NewStuff & NEWSPRITES) == NEWSPRITES)
{
PrText (25, 1, DYELLOW, " [R] to list the sprites ");
KeySprites = TRUE;
}
else
KeySprites = FALSE;
if ((WadInfo.NewStuff & NEWSOUNDS) == NEWSOUNDS)
{
PrText (26, 1, DYELLOW, " [S] to list the sounds ");
KeySounds = TRUE;
}
else
KeySounds = FALSE;
if ((WadInfo.NewStuff & NEWMUSIC) == NEWMUSIC)
{
PrText (27, 1, DYELLOW, " [M] to list the music ");
KeyMusic = TRUE;
}
else
KeyMusic = FALSE;
if ((WadInfo.NewStuff & NEWMENUS) == NEWMENUS)
{
PrText (28, 1, DYELLOW, " [U] to list the menu items ");
KeyMenus = TRUE;
}
else
KeyMenus = FALSE;
KeyOk = FALSE;
ReprintAll = FALSE;
ReprintLevels = FALSE;
ReprintAny = FALSE;
}
while (!KeyOk)
{
KeyOk = TRUE;
#ifdef _AMIGA_
while (KeyOk)
{
if (!(IntuiMessage = (struct IntuiMessage *)GetMsg (Window->UserPort))) /* Wait for a message from intuition */
{
Wait (1L << Window->UserPort->mp_SigBit);
continue;
}
MessageClass = IntuiMessage->Class; /* Determine the source of the message */
Code = IntuiMessage->Code; /* Read the data of the message */
ReplyMsg (IntuiMessage); /* Confirm receipt to the operating system */
switch (MessageClass)
{
case CLOSEWINDOW : KeyOk = FALSE;
Code = 'q'; /* Convert data to key 'quit' */
break;
case VANILLAKEY : KeyOk = FALSE;
}
}
KeyOk = TRUE;
if (Checked)
{
Checked = FALSE;
ReprintLevels = TRUE;
}
else
if (Listing)
{
Listing = FALSE;
ClearScreen ();
ReprintAll = TRUE;
}
else
switch (Code)
#else
Key = getch (); /* Wait for a key */
if (Key == 0x0000 || Key == 0x00E0) /* Non-ASCII keys (cursor, funtion, etc) give 'extended' first */
Key = getch ();
if (Checked)
{
Checked = FALSE;
ReprintLevels = TRUE;
}
else
if (Listing)
{
Listing = FALSE;
ClearScreen ();
ReprintAll = TRUE;
}
else
switch (tolower ((char)(Key & 0x00FF))) /* Keep only the ASCII part */
#endif
{
case 'q' : More = FALSE;
break;
case 'c' : if (KeyCheckLevel)
{
CheckLevel (Fp, MemNum);
KeyOk = FALSE;
Checked = TRUE;
}
else
KeyOk = FALSE;
break;
case 'i' : if (KeyInfo)
{
LevelInfoType = !LevelInfoType;
ReprintLevels = TRUE;
}
else
KeyOk = FALSE;
break;
case 'n' : if (KeyNext)
{
MemNum ++;
ReprintLevels = TRUE;
}
else
KeyOk = FALSE;
break;
case 'p' : if (KeyPrevious)
{
MemNum --;
ReprintLevels = TRUE;
}
else
KeyOk = FALSE;
break;
case 'r' : if (KeySprites)
{
ListSprites ();
Listing = TRUE;
KeyOk = FALSE;
}
else
KeyOk = FALSE;
break;
case 's' : if (KeySounds)
{
ListSounds ();
Listing = TRUE;
KeyOk = FALSE;
}
else
KeyOk = FALSE;
break;
case 'm' : if (KeyMusic)
{
ListMusic ();
Listing = TRUE;
KeyOk = FALSE;
}
else
KeyOk = FALSE;
break;
case 'u' : if (KeyMenus)
{
ListMenus ();
Listing = TRUE;
KeyOk = FALSE;
}
else
KeyOk = FALSE;
break;
default : KeyOk = FALSE;
}
}
ReprintAny = (ReprintAll || ReprintLevels);
}
fclose (Fp);
Bye (""); /* Shutdown */
}