/******************************************************************************
	INCLUDE:	DMGLOBAL.I
	WRITTEN BY:	Robert Fenske, Jr. (rfenske@swri.edu)
				Southwest Research Institute
				Electromagnetics Division
				6220 Culebra
				San Antonio, Texas 78238-5166
	CREATED:	Mar. 1994
	DESCRIPTION:	This include file contains all the necessary constant,
			macro, syntax, and type definitions as well as all
			external and global variables needed for the various
			DOOM-related utility programs.

			DOOM is a trademark of id Software, Inc.
******************************************************************************/
#if !defined(DM_Globals)

#undef ANSI_C
#if defined(__STDC__) || defined(__OS2__)
#define ANSI_C		1
#endif

#if !defined(__OS2__)
#define _Optlink
#endif

/*===========================================================================*/

#define bcase		break;case		/* for a more reasonabble */
#define bdefault	break;default		/* switch statement       */
#define global					/* global declarations */
#define forward		extern			/* forward references */
#define local		static			/* local declarations */
#define otherwise	break;default		/* alternate default case */
#define repeat		do
#define until(expr)	while (!(expr))		/* for do ... until loops */

/*===========================================================================*/

typedef unsigned short	ushort;
typedef unsigned int	boolean;		/* integer used as boolean */
typedef short		word;			/* 16-bit word */
typedef word		bams;			/* 16-bit bams */

/*===========================================================================*/

#undef PI
#define PI		(double)3.14159265358979323846	/* ubiquitous PI */
#define TWOPI		(double)6.28318530717958647693
#define bams_to_deg	(double)0.00549316406250000000	/* angle conv consts */
#define deg_to_bams   (double)182.04444444444444444444
#define bams_to_rad	(double)0.00009587379924285258
#define rad_to_bams (double)10430.37835047045272494957
#define deg_to_rad	(double)0.01745329251994329577
#define rad_to_deg     (double)57.29577951308232087680
#define BAMS180		((bams)0x8000)		/* BAMS: (-)180 degrees */
#define BAMS090		((bams)0x4000)		/* BAMS: 90 degrees */

#define FALSE		0
#define TRUE		(!FALSE)

/*===========================================================================*/
#if !defined(__OS2__)
#define abs(a)		((a) < 0 ? -(a) : (a))
#define min(a,b)	((a) < (b) ? (a) : (b))
#define max(a,b)	((a) < (b) ? (b) : (a))
#endif
#define numbytes(v)	((unsigned)sizeof(v))
#define numelm(a)	(sizeof a / sizeof a[0])
#define sgn(a)		((0<(a))-((a)<0))

	/* the blockmem() routine must allocate and zero memory */
#if defined(__OS2__)
#include <string.h>
#define blockmem(t,n)	(t *)(0<(n)?calloc((unsigned)(n),sizeof(t)):NULL)
#define blockfree(b)	(free((char *)(b)))
#define blockcopy(bt,bf,n) (void)memcpy((char *)(bt),(char *)(bf),(int)(n))
#elif defined(sun)
#define blockmem(t,n)	(t *)(0<(n)?calloc((unsigned)(n),sizeof(t)):NULL)
#define blockfree(b)	((b)!=NULL?free((char *)(b)):0)
#define blockcopy(bt,bf,n) (void)memcpy((char *)(bt),(char *)(bf),(int)(n))
#else
#define blockmem(t,n)	(t *)(0<(n)?calloc((unsigned)(n),sizeof(t)):NULL)
#define blockfree(b)	((b)!=NULL?free((char *)(b)):(void)0)
#define blockcopy(bt,bf,n) (void)memcpy((char *)(bt),(char *)(bf),(int)(n))
#endif

/*===========================================================================*/

typedef struct DOOM_THING {			/* thing information */
	short x, y;
	short angle;
	short item;
	short flag;
} DOOM_THING;

typedef struct DOOM_LINE {			/* line information */
	short fndx, tndx;
	short flag, action_flag;
	short sect_tag;
	short rsidndx, lsidndx;
} DOOM_LINE;

typedef struct DOOM_SIDE {			/* side information */
	short image_xoff, image_yoff;
	char lwall[8], uwall[8], nwall[8];
	short sectndx;
} DOOM_SIDE;

typedef struct DOOM_VERT {			/* vertex information */
	short x, y;
} DOOM_VERT;

typedef struct DOOM_SEGS {			/* segment information */
	short fndx, tndx;
	bams angle;
	short lndx;
	short sndx;
	short loffset;
} DOOM_SEGS;

typedef struct DOOM_SSECTOR {			/* subsector information */
	short count;
	short sndx;
} DOOM_SSECTOR;

typedef struct DOOM_NODE {			/* node information */
	short x, y;
	short xdel, ydel;
	short rymax, rymin, rxmin, rxmax;
	short lymax, lymin, lxmin, lxmax;
	short nndx[2];
} DOOM_NODE;

typedef struct DOOM_SECTOR {			/* sector information */
	short floor_ht, ceil_ht;
	char floor_desc[8], ceil_desc[8];
	short light_lvl;
	short property;
	short line_tag;
} DOOM_SECTOR;

typedef unsigned char	DOOM_REJECT;		/* reject information */

typedef short		DOOM_BLOCKMAP;		/* block map information */

/*===========================================================================*/

#define MAINS		0
#define THINGS		1
#define LINES		2
#define SIDES		3
#define VERTS		4
#define SEGS		5
#define SSECTS		6
#define NODES		7
#define SECTS		8
#define REJECTS		9
#define BLKMAPS		10
#define ALL		11

typedef struct WAD_HEAD {			/* WAD file header */
	char ident[4];
	long count;
	long offset;
} WAD_HEAD;

typedef struct DIR_ENTRY {			/* WAD file directory entry */
	long offset;
	long nbytes;
	char name[8];
} DIR_ENTRY;

typedef struct WAD_INFO {			/* WAD file information */
	FILE *fp;					/* file pointer */
	int type;					/* (I/P)WAD,patch */
	WAD_HEAD head;					/* file header */
	DIR_ENTRY *origdir,				/* orig directory */
	          *dir;					/* resources dirctry */
	char **data;					/* resources data */
	boolean *changed;				/* rsrce changed flg */
	long *count;					/* resources size */
	int ep, mp;					/* cur episode/map */
	double ver;					/* patch version */
} WAD_INFO;

/*===========================================================================*/

extern void resource_update(
#if defined(ANSI_C)
	register WAD_INFO *winfo,
	int entry,
	void *data,
	long count
#endif
);
extern int resource_count(
#if defined(ANSI_C)
	register DIR_ENTRY *entry
#endif
);
extern boolean patch_read(
#if defined(ANSI_C)
	register WAD_INFO *winfo,
	int entry,
	long resources_needed
#endif
);
extern boolean patch_write(
#if defined(ANSI_C)
	register WAD_INFO *oinfo,
	register WAD_INFO *winfo
#endif
);
extern WAD_INFO *wad_open(
#if defined(ANSI_C)
	char *file,
	boolean input,
	boolean rewrite
#endif
);
extern boolean wad_read(
#if defined(ANSI_C)
	register WAD_INFO *winfo,
	int entry,
	long resources_needed
#endif
);
extern boolean wad_write(
#if defined(ANSI_C)
	register WAD_INFO *oinfo,
	register WAD_INFO *winfo
#endif
);
extern void wad_close(
#if defined(ANSI_C)
	register WAD_INFO *winfo
#endif
);

extern long nodes_make(				/* makes NODES,SSECTORS,SEGS */
#if defined(ANSI_C)
	DOOM_NODE **nodes,
	long *nnodes,
	DOOM_SSECTOR **ssecs,
	long *nssecs,
	DOOM_SEGS **segs,
	long *nsegs,
	DOOM_VERT **verts,
	long *nverts,
	DOOM_LINE **lines,
	long *nlines
#endif
);
extern long blockmap_make(			/* makes the BLOCKMAP */
#if defined(ANSI_C)
	register short **blockmap,
	register DOOM_LINE *lines,
	long nlines,
	DOOM_VERT *verts
#endif
);
extern long reject_make(			/* makes REJECT */
#if defined(ANSI_C)
	DOOM_REJECT **reject,
	boolean zeroflag,
	char *except,
	DOOM_LINE *lines,
	long nlines,
	DOOM_SIDE *sides,
	DOOM_VERT *verts,
	DOOM_BLOCKMAP *blockmap
#endif
);

#define DM_Globals	1			/* now have defined these */
#endif
