~samiam/ObHack

1dd634c371bd84b66531d862b1b25a80de76af87 — Sam Trenholme 4 years ago 03cc02f
Add wad2map tool
A wad2map/2dclip.cpp => wad2map/2dclip.cpp +360 -0
@@ 0,0 1,360 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	2dclip.cpp

	Ted Mielczarek
	12/10/1999

	This file contains the 2d clipping routines for forming ssectors.
*/

#include <StdAfx.h>
#include <math.h>
#include "types.h"
#include "2dclip.h"

// find out which side of a line a point is on
side PointLocation(point_t *p, line_t *l)
{
	coord lofq;
	point_t v;

	// get a vector from line to point
	v.x = p->x - l->p.x;
	v.y = p->y - l->p.y;

	lofq = DOT_PROD(v,l->n);

	if(lofq < 0)
		return(left_side);

	if(lofq > 0)
		return(right_side);
	
	return(on_line);
}

/*
	PointInPoly

	Determine if the point p lies within the poly s
*/
bool PointInPoly(point_t *p, poly_t *s)
{
	line_t l;
	int i;

	for(i=0;i<s->num_verts-1;i++) {
		LineFromPoints(&l,s->p+i);
		if(PointLocation(p,&l) == left_side)
			return(false);
	}

	return(true);
}

bool IntersectPoint(line_t *l, point_t l2[2], point_t *result)
{
	point_t d;
	double t;

	// get direction vector for l2 (the line segment
	d.x = l2[1].x - l2[0].x;
	d.y = l2[1].y - l2[0].y;

	// are the lines parallel?
	if(DOT_PROD(l->n,d) == 0)
		return(false);

	t = double(DOT_PROD(l->n,l->p) - DOT_PROD(l->n,l2[0])) / double(DOT_PROD(l->n,d));

	if(t < 0 || t > 1) {
		// outside the line segment
		return(false);
	}

	// get intersect point
#ifdef USE_FLOATING_POINT
	result->x = l2[0].x + t*d.x;
 	result->y = l2[0].y + t*d.y;
#else
	// if using int, round correctly
	result->x = int(floor(l2[0].x + t*d.x + 0.5));
 	result->y = int(floor(l2[0].y + t*d.y + 0.5));
#endif

	return(true);
}

void LineFromPoints(line_t *l, point_t p[2])
{
	// copy point A p[0]
	memcpy(&l->p,&p[0],sizeof(point_t));

	// calc normal vector:
	// use negative inverse slope of direction vector
	l->n.x = p[1].y - p[0].y;
	l->n.y = -1*(p[1].x - p[0].x);
}

bool ClipPolyToLine(poly_t *poly, line_t *l, side keep)
{
	int i;
	poly_t newpoly;
	point_t pt, tmp[2];
	side from,to,drop;

	memset(&newpoly,0,sizeof(newpoly));
	drop = OppositeSide(keep);

	// check first point
	if(PointLocation(&poly->p[0],l) != drop)
		memcpy(&newpoly.p[newpoly.num_verts++],&poly->p[0],sizeof(point_t));

	// cycle thru poly points
	for(i=0;i<poly->num_verts-1;i++) {
		from = PointLocation(&poly->p[i],l);
		to = PointLocation(&poly->p[i+1],l);
		if(from != drop) {
			if(to != drop)
				// crosses in to in
				memcpy(&newpoly.p[newpoly.num_verts++],&poly->p[i+1],sizeof(point_t));
			else {
				// check for points on line...
				if(from != on_line) {
					// crosses in to out, save crossing
					if(IntersectPoint(l,&poly->p[i],&pt))
						memcpy(&newpoly.p[newpoly.num_verts++],&pt,sizeof(point_t));
				}
			}
		}
		else {
			if(to != drop) {
				if(to != on_line) {
					// crosses out to in, save intersect point and "to" point
					if(IntersectPoint(l,&poly->p[i],&pt))
						memcpy(&newpoly.p[newpoly.num_verts++],&pt,sizeof(point_t));
				}
				// out to in, or out to on line, save 'to'
				memcpy(&newpoly.p[newpoly.num_verts++],&poly->p[i+1],sizeof(point_t));
			}
			// out to out, save nothing
		}
	}

	// check last point to first point
	from = PointLocation(&poly->p[poly->num_verts-1],l);
	to = PointLocation(&poly->p[0],l);
	memcpy(tmp,&poly->p[poly->num_verts-1],sizeof(point_t)*2);
	memcpy(&tmp[1],&poly->p[0],sizeof(point_t)*2);
	if(from != drop) {
		if(to == drop) {
			// check for points on line...
			if(from != on_line) {
				// crosses in to out, save crossing
				if(IntersectPoint(l,tmp,&pt))
					memcpy(&newpoly.p[newpoly.num_verts++],&pt,sizeof(point_t));
			}
		}
	}
	else {
		if(to != drop) {
			if(to != on_line) {
				// crosses out to in, save intersect point
				if(IntersectPoint(l,tmp,&pt))
					memcpy(&newpoly.p[newpoly.num_verts++],&pt,sizeof(point_t));
			}
		}
		// out to out, save nothing
	}

	// check to see if all that's left is points on the line.  this could screw stuff up.
	from = on_line;
	for(i=0;i<newpoly.num_verts;i++) {
		to = PointLocation(&newpoly.p[i],l);
		if(to != on_line) {
			from = to;
			break;
		}
	}

	memset(poly,0,sizeof(poly_t));

	// if all points are on the line, don't copy it
	if(from != on_line)
		memcpy(poly,&newpoly,sizeof(newpoly));

	return(poly->num_verts > 2);
}

side OppositeSide(side s)
{
	if(s == right_side)
		return(left_side);
	
	if(s == left_side)
		return(right_side);

	return(s);
}

/*
	CheckPolys

	Check all polys for duplicate vertices.

	Parameters:
	p: Array of polys to check
	n: Number of polys in array
*/
void CheckPolys(poly_t *p, int n)
{
	int i,j,k;

	for(i=0;i<n;i++) {
		// degenerate poly...
		if(p[i].num_verts < 3) {
			memset(&p[i],0,sizeof(poly_t));
			continue;
		}
		for(j=0;j<p[i].num_verts-1;j++) {
			for(k=j;k<p[i].num_verts;k++) {
				if(j==k)
					continue;
				if(PointsEqual(&p[i].p[j], &p[i].p[k])) {
					// degenerate poly!
					if(p[i].num_verts <= 3) {
						memset(&p[i],0,sizeof(poly_t));
						break;
					}
					RemovePoint(&p[i],k);
				}
			}
		}
	}
}

/*
	CheckPoly

	Check a single poly for degeneracy. (Duplicate verts, < 3 verts, all verts colinear)
*/
bool CheckPoly(poly_t *p)
{
	int j,k;
	line_t l;
	bool isOk;

	// degenerate poly...
	if(p->num_verts < 3) {
		memset(p,0,sizeof(poly_t));
		return(false);
	}

	for(j=0;j<p->num_verts-1;j++) {
		for(k=j;k<p->num_verts;k++) {
			if(j==k)
				continue;
			if(PointsEqual(&p->p[j], &p->p[k])) {
				// degenerate poly!
				if(p->num_verts <= 3) {
					memset(p,0,sizeof(poly_t));
					return(false);
				}
				RemovePoint(p,k);
			}
		}
	}

	// check to see if all points are colinear
	LineFromPoints(&l,p->p);
	isOk = false;
	for(j=2;j<p->num_verts;j++) {
		if(PointLocation(p->p+j,&l) != on_line) {
			isOk = true;
			break;
		}
	}	

	return(isOk);
}

bool PointsEqual(point_t *p1, point_t *p2)
{
#ifdef USE_FLOATING_POINT
	if((fabs(p1->x - p2->x) < 0.1) && (fabs(p1->y - p2->y) < 0.1))
#else
	if(abs(p1->x - p2->x) < 3 && abs(p1->y - p2->y) < 3)
#endif
	//if(p1->x == p2->x && p1->y == p2->y)
		return(true);

	return(false);
}

void RemovePoint(poly_t *p, int n)
{
	int i,j;

	// number of verts after this
	i = p->num_verts - n - 1;
	
	// if any, move points back
	if(i > 0)
		for(j=0;j<i;j++)
			memcpy(&p->p[j+n],&p->p[j+n+1],sizeof(point_t));
	
	// zero out last vertex
	p->p[p->num_verts - 1].x = 0;
	p->p[p->num_verts - 1].y = 0;

	// one less point
	p->num_verts--;
}

/*
	printpoint

	Print a point to a string as (x, y)
*/
void printpoint(char *s, point_t *p)
{
	sprintf(s,"("CSPEC", "CSPEC")",p->x,p->y);
}

/*
	DumpPoly

	Dump all points in a poly to a file.
*/
void DumpPoly(FILE *f, poly_t *p)
{
	int i;
	char szTmp[256];

	for(i=0;i<p->num_verts;i++) {
		printpoint(szTmp,p->p+i);
		fprintf(f,szTmp);
		fprintf(f,", ");
	}
	fprintf(f,"\n");
}

A wad2map/2dclip.h => wad2map/2dclip.h +55 -0
@@ 0,0 1,55 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	2dclip.h

	Ted Mielczarek
	12/10/1999

	This file contains prototypes for the functions in 2dclip.cpp, which
	are 2d clipping routines.
*/
#ifndef __2DCLIP_H_
#define __2DCLIP_H_

typedef enum {
	on_line,
	left_side,
	right_side
} side;

// dot product macro
#define DOT_PROD(a,b) ((a.x) * (b.x) + (a.y) * (b.y))

side PointLocation(point_t *p, line_t *l);
bool PointInPoly(point_t *p, poly_t *s);
bool IntersectPoint(line_t *l, point_t l2[2], point_t *result);
void LineFromPoints(line_t *l, point_t p[2]);
bool ClipPolyToLine(poly_t *poly, line_t *l, side keep);
void CheckPolys(poly_t *p, int n);
bool CheckPoly(poly_t *p);
bool PointsEqual(point_t *p1, point_t *p2);
void RemovePoint(poly_t *p, int n);
void printpoint(char *s, point_t *p);
void DumpPoly(FILE *f, poly_t *p);
side OppositeSide(side s);

#endif /* __2DCLIP_H_ */

A wad2map/FUNK.WAD => wad2map/FUNK.WAD +0 -0
A wad2map/StdAfx.cpp => wad2map/StdAfx.cpp +28 -0
@@ 0,0 1,28 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
// stdafx.cpp : source file that includes just the standard includes
//	ssectors.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

A wad2map/StdAfx.h => wad2map/StdAfx.h +41 -0
@@ 0,0 1,41 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__05681BA2_ADAE_11D3_910E_0000E82F44A6__INCLUDED_)
#define AFX_STDAFX_H__05681BA2_ADAE_11D3_910E_0000E82F44A6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#endif // !defined(AFX_STDAFX_H__05681BA2_ADAE_11D3_910E_0000E82F44A6__INCLUDED_)

A wad2map/WadFile.cpp => wad2map/WadFile.cpp +290 -0
@@ 0,0 1,290 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
// WadFile.cpp: implementation of the CWadFile class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "WadFile.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CWadFile::CWadFile()
{
	isOpen = false;
	wadfile = NULL;
	ZeroMemory(&header,sizeof(header));
	directory = NULL;
	theWadType = NO_WAD;
	currentEntry = -1;
}

CWadFile::~CWadFile()
{
	if(isOpen)
		Close();
}

// Constructor with filename parameter
CWadFile::CWadFile(char *szFile)
{
	Open(szFile);
}

//------------------------------
// Open
//		Open a wad file with
//	the specified path/filename.
//  Return true for success, false
//	for failure.
//------------------------------
bool CWadFile::Open(char *szFile)
{
	if(isOpen)
		Close();

	ZeroMemory(&header,sizeof(header));

	wadfile = fopen(szFile,"rb");

	if(wadfile == NULL)
		return(false);

	if(fread(&header,sizeof(wadheader_t),1,wadfile) != 1) {
		fclose(wadfile);
		return(false);
	}

	// Check wad type
	if(!strncmp(header.id,IWAD_ID,4))
		// IWAD
		theWadType = IWAD;
	else if(!strncmp(header.id,PWAD_ID,4))
		// PWAD
		theWadType = PWAD;
	else {
		// not a valid wadfile
		fclose(wadfile);
		return(false);
	}

	if(header.numlumps <= 0) {
		// empty wad
		theWadType = NO_WAD;
		fclose(wadfile);
		return(false);
	}

	if(fseek(wadfile,header.dirpos,SEEK_SET) != 0) {
		// couldn't find directory
		theWadType = NO_WAD;
		fclose(wadfile);
		return(false);
	}

	// allocate memory for wad directory
	directory = new waddirentry_t[header.numlumps];

	if(directory == NULL) { // uh oh
		theWadType = NO_WAD;
		fclose(wadfile);
		return(false);
	}

	// attempt to read in directory
	if(fread(directory,sizeof(waddirentry_t),header.numlumps,wadfile)
		!= unsigned(header.numlumps)) {
		delete[] directory;
		theWadType = NO_WAD;
		fclose(wadfile);
		return(false);
	}

	// start at first entry
	currentEntry = 0;
	if(fseek(wadfile,directory[0].offset,SEEK_SET) != 0) {
		delete[] directory;
		theWadType = NO_WAD;
		fclose(wadfile);
		return(false);
	}

	// wadfile is open
	isOpen = true;

	return(true);
}

//------------------------------
// IsOpen
//		Return true if a wadfile
//	is open, false if not.
//------------------------------
bool CWadFile::IsOpen(void)
{
	return(isOpen);
}

//------------------------------
// SeekTo
//		Find the first entry in
//	the wadfile with this name.
//	Return true if found, false
//	if not.
//------------------------------
bool CWadFile::SeekTo(char *szEntry)
{
	int i;

	if(szEntry == NULL || szEntry[0] == '\0')
		return(false);

	for(i=0;i<header.numlumps;i++) {
		if(!strncmp(directory[i].name,szEntry,8)) {
			currentEntry = i;
			return(true);
		}
	}

	return(false);
}

//------------------------------
// SeekNext
//		Seek to the next entry
//	in the wadfile.  If szEntry
//	is not NULL, copy the entry
//	name into it.
//------------------------------
bool CWadFile::SeekNext(char *szEntry)
{
	// are we already at the end
	if(currentEntry + 1 == header.numlumps)
		return(false);

	currentEntry++;

	if(szEntry != NULL) {
		strncpy(szEntry,directory[currentEntry].name,8);
		szEntry[8] = '\0';
	}

	return(true);
}

//------------------------------
// SeekPrevious
//		Seek to the previous entry
//	in the wadfile.  If szEntry
//	is not NULL, copy the entry
//	name into it.
//------------------------------
bool CWadFile::SeekPrevious(char *szEntry)
{
	// are we already at the beginning
	if(currentEntry == 0)
		return(false);

	currentEntry--;

	if(szEntry != NULL) {
		strncpy(szEntry,directory[currentEntry].name,8);
		szEntry[8] = '\0';
	}

	return(true);
}

//------------------------------
// GetEntryData
//		Get the data associated
//	with the current entry and
//	store it in pData.  Returns
//	true on success, false on
//	failure.
//------------------------------
bool CWadFile::GetEntryData(void *pData)
{
	if(pData == NULL)
		return(false);

	// seek to entry
	if(fseek(wadfile,directory[currentEntry].offset,SEEK_SET) != 0)
		return(false);

	// read entry
	if(fread(pData,directory[currentEntry].size,1,wadfile) != 1)
		return(false);
	
	return(true);
}

//------------------------------
// GetEntrySize
//		Get the size of the current
//	entry, in bytes.
//------------------------------
long CWadFile::GetEntrySize(void)
{
	if(!isOpen)
		return(0);

	return(directory[currentEntry].size);
}

//------------------------------
// Close
//		Close the current wadfile.
//------------------------------
void CWadFile::Close()
{
	if(!isOpen)
		return;

	delete[] directory;
	directory = NULL;
	fclose(wadfile);
	wadfile = NULL;
	isOpen = false;
	theWadType = NO_WAD;
	currentEntry = -1;
	ZeroMemory(&header,sizeof(header));
}

wadtypes CWadFile::WadType()
{
	return(theWadType);
}

bool CWadFile::SeekFirst(char *szEntry)
{
	if(header.numlumps == 0)
		return(false);

	currentEntry = 0;
	if(szEntry != NULL) {
		strncpy(szEntry,directory[currentEntry].name,8);
		szEntry[8] = '\0';
	}
	return(true);
}

A wad2map/WadFile.h => wad2map/WadFile.h +89 -0
@@ 0,0 1,89 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
// WadFile.h: interface for the CWadFile class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_WADFILE_H__852EB12B_ACEE_11D3_910E_0000E82F44A6__INCLUDED_)
#define AFX_WADFILE_H__852EB12B_ACEE_11D3_910E_0000E82F44A6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// This is defined for windows
#ifndef ZeroMemory
#define ZeroMemory(x,y) memset(x,0,y)
#endif

// Wad Header struct
typedef struct s_wadheader
{
	char id[4];		// wad id, either IWAD or PWAD
	long numlumps;	// number of entries
	long dirpos;	// offset to start of directory
} wadheader_t;

// Wad Directory Entry struct
typedef struct s_waddirentry
{
	long offset;	// offset from start of wad, in bytes
	long size;		// size, in bytes
	char name[8];	// name, padded with zeroes
} waddirentry_t;

// wad types
#define IWAD_ID "IWAD"
#define PWAD_ID "PWAD"

enum wadtypes {
	NO_WAD,
	IWAD,
	PWAD
};

class CWadFile  
{
public:
	bool SeekFirst(char *szEntry);
	wadtypes WadType(void);
	void Close(void);
	long GetEntrySize();
	bool GetEntryData(void *pData);
	bool SeekPrevious(char *szEntry);
	bool SeekNext(char *szEntry);
	bool SeekTo(char *szEntry);
	bool IsOpen();
	bool Open(char *szFile);
	CWadFile(char *szFile);
	CWadFile();
	virtual ~CWadFile();

private:
	bool isOpen;
	FILE *wadfile;
	wadheader_t header;
	waddirentry_t *directory;
	wadtypes theWadType;
	long currentEntry;
};

#endif // !defined(AFX_WADFILE_H__852EB12B_ACEE_11D3_910E_0000E82F44A6__INCLUDED_)

A wad2map/clip_ssectors.cpp => wad2map/clip_ssectors.cpp +212 -0
@@ 0,0 1,212 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	clip_ssectors.cpp

	Ted Mielczarek
	12-13-1999

	This file clips the ssectors using each node division line traversing the node tree until
	a ssector is hit, and then clips the ssector to the bounding segs of the ssector.
*/
#include <StdAfx.h>
#include "defs.h"
#include "types.h"
#include "2dclip.h"
#include "doomlevel.h"
#include "WadFile.h"
#include "wadentries.h"
#include "clip_ssectors.h"
#include "progress.h"

int ssDone;

/*
	ClipSectors

	Take a doom level, and generate polygons of the ssectors.

	Parameters:
	level: Level data for the doom map.
	polys: An array of pointers to polys to fill.
*/
bool ClipSsectors(level_t *level, poly_t *polys)
{
	poly_t thePoly;

	MakeWorldPoly(&thePoly,level);

	printf("Creating ssectors: ");
	// draw a progress bar to be nice
	InitProgress(20,'*',true);
	//DrawProgress(level->n_ssectors,0);
	ssDone = 0;
	// walk bsp tree
	RecurseNodes(level->nodes + (level->n_nodes - 1),&thePoly,level,polys);

	printf("\n");
	// check all ssectors
	for(int i=0;i<level->n_ssectors;i++) {
		CheckPoly(polys+i);
		if(polys[i].num_verts < 3)
			OutputDebugString("Bad ssector\n");
	}

	return(true);
}

void MakeWorldPoly(poly_t *thePoly, level_t *level)
{
	// init thePoly to be a rectangle encompassing the entire level, with a 16 unit border
	memset(thePoly,0,sizeof(poly_t));
	thePoly->num_verts = 4;
	thePoly->p[0].x = level->x_center - level->l_width / 2 - 16;
	thePoly->p[0].y = level->y_center - level->l_height / 2 - 16;
	thePoly->p[1].x = level->x_center - level->l_width / 2 - 16;
	thePoly->p[1].y = level->y_center + level->l_height / 2 + 16;
	thePoly->p[2].x = level->x_center + level->l_width / 2 + 16;
	thePoly->p[2].y = level->y_center + level->l_height / 2 + 16;
	thePoly->p[3].x = level->x_center + level->l_width / 2 + 16;
	thePoly->p[3].y = level->y_center - level->l_height / 2 - 16;
}

/*
	RecurseNodes

	Traverse the bsp tree, using node division lines to clip away at a polygon until
	it hits a ssector, then use the segs bounding that ssector to clip the rest of it.

	Parameters:
	node: The current node of the bsp tree.
	thePoly: The current polygon being clipped.
	level: The doom level data.
	polys: The full set of polys being created for this level.
*/
bool RecurseNodes(node_t *node, poly_t *thePoly, level_t *level, poly_t *polys)
{
	poly_t newPoly;
	point_t p[2];
	line_t l;
	segment_t *s;
	int i;
	short ssnum;

	//***********
	// Left Child
	//***********
	// copy poly
	memcpy(&newPoly,thePoly,sizeof(poly_t));
	// clip it to the node split line and
	p[0].x = node->x;
	p[0].y = node->y;
	p[1].x = node->x + node->dx;
	p[1].y = node->y + node->dy;
	LineFromPoints(&l,p);
	ClipPolyToLine(&newPoly,&l,left_side);
	// is left node a ssector?
	if(node->left_child & 0x8000) {
		// clip it to the segs
		ssnum = node->left_child & 0x7FFF;
		for(i=0, s = &level->segs[level->ssectors[ssnum].startseg];
			i<level->ssectors[ssnum].numsegs; i++,s++) {
			// make clip line from seg
			p[0].x = level->vertices[s->from_vertex].x;
			p[0].y = level->vertices[s->from_vertex].y;
			p[1].x = level->vertices[s->to_vertex].x;
			p[1].y = level->vertices[s->to_vertex].y;
			LineFromPoints(&l,p);
			ClipPolyToLine(&newPoly,&l,right_side);
		}
		// set which sector this is part of
		if(level->ssectors[ssnum].numsegs > 0) {
			short segnum,linenum,sidenum;

			// could do this in one line, but it's ugly
			segnum = level->ssectors[ssnum].startseg;
			linenum = level->segs[segnum].linedef;
			sidenum = level->linedefs[linenum].sidedefs[level->segs[segnum].side];
			newPoly.sector = level->sidedefs[sidenum].sector;
		}
		else
			newPoly.sector = -1;
		// now add it to the list of polys
		memcpy(&polys[ssnum],&newPoly,sizeof(poly_t));
		ssDone++;
		// draw progress meter
		DrawProgress(level->n_ssectors,ssDone);
	}
	else {
		// otherwise, recurse
		RecurseNodes(&level->nodes[node->left_child],&newPoly,level,polys);
	}


	//***********
	// Right Child
	//***********
	// copy poly
	memcpy(&newPoly,thePoly,sizeof(poly_t));
	// clip it to the node split line
	p[0].x = node->x;
	p[0].y = node->y;
	p[1].x = node->x + node->dx;
	p[1].y = node->y + node->dy;
	LineFromPoints(&l,p);
	ClipPolyToLine(&newPoly,&l,right_side);
	// is left node a ssector?
	if(node->right_child & 0x8000) {
		// clip it to the segs
		ssnum = node->right_child & 0x7FFF;
		for(i=0, s = &level->segs[level->ssectors[ssnum].startseg];
			i<level->ssectors[ssnum].numsegs; i++,s++) {
			// make clip line from seg
			p[0].x = level->vertices[s->from_vertex].x;
			p[0].y = level->vertices[s->from_vertex].y;
			p[1].x = level->vertices[s->to_vertex].x;
			p[1].y = level->vertices[s->to_vertex].y;
			LineFromPoints(&l,p);
			ClipPolyToLine(&newPoly,&l,right_side);
		}
		// set which sector this is part of
		if(level->ssectors[ssnum].numsegs > 0) {
			short segnum,linenum,sidenum;

			// could do this in one line, but it's ugly
			segnum = level->ssectors[ssnum].startseg;
			linenum = level->segs[segnum].linedef;
			sidenum = level->linedefs[linenum].sidedefs[level->segs[segnum].side];
			newPoly.sector = level->sidedefs[sidenum].sector;
		}
		else
			newPoly.sector = -1;
		// now add it to the list of polys
		memcpy(&polys[ssnum],&newPoly,sizeof(poly_t));
		ssDone++;
		// draw progress meter
		DrawProgress(level->n_ssectors,ssDone);
	}
	else {
		// recurse
		RecurseNodes(&level->nodes[node->right_child],&newPoly,level,polys);
	}

	return(true);
}

A wad2map/clip_ssectors.h => wad2map/clip_ssectors.h +36 -0
@@ 0,0 1,36 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	clip_ssectors.h

	Ted Mielczarek
	12-13-1999

	This file contains the prototypes for the ssector clipping code.
*/
#ifndef __CLIP_SSECTORS_H_
#define __CLIP_SSECTORS_H_

bool ClipSsectors(level_t *level, poly_t *polys);
void MakeWorldPoly(poly_t *thePoly, level_t *level);
bool RecurseNodes(node_t *node, poly_t *thePoly, level_t *level, poly_t *polys);

#endif /* __CLIP_SSECTORS_H_ */

A wad2map/convert.cpp => wad2map/convert.cpp +136 -0
@@ 0,0 1,136 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	convert.cpp

	Ted Mielczarek
	1-13-2000

	This file contains the main routines for running through the conversion process.
*/

#include "StdAfx.h"
#include "defs.h"
#include "WadFile.h"
#include "convert.h"
#include "types.h"
#include "doomlevel.h"
#include "wadentries.h"
#include "clip_ssectors.h"
#include "subtract_ssectors.h"
#include "dumpmap.h"
#include "globals.h"

void strupper(char *s);

bool DoConversion(CWadFile &wadFile)
{
	levelentries le = W_NOT_LEVEL_ENTRY;
	char szEntry[256];
	bool outOfEntries = false;
	// level data
	level_t level;
	poly_t *polys;
	poly_t *world;
	int nWorld;

	// no mapname specified, get first map
	if(mapname[0] == '\0') {
		wadFile.SeekFirst(szEntry);
		le = LookupLevelEntry(szEntry);
		while(le != W_D1LEVEL && le != W_D2LEVEL) {
			if(!wadFile.SeekNext(szEntry))
				break;
			le = LookupLevelEntry(szEntry);
		}
		if(le != W_D1LEVEL && le != W_D2LEVEL) {
			fprintf(stderr,"No level entries found.\n");
			return(false);
		}
		strcpy(mapname,szEntry);
	}
	else {
		strupper(mapname);
		if(!wadFile.SeekTo(mapname)) {
			fprintf(stderr,"Level %s not found.\n",mapname);
			return(false);
		}
	}


	// Conversion loop
	do {
		printf("\nConverting %s\n",mapname);

		if(!LoadLevelData(wadFile,&level,mapname)) {
			fprintf(stderr,"Could not load level data!");
			return(false);
		}

		LevelExtents(&level);

		polys = new poly_t[level.n_ssectors];
		// clip ssectors to node clipping lines
		ClipSsectors(&level,polys);
		// get world polys
		poly_t tmp;
		MakeWorldPoly(&tmp,&level);
		ClipWorldToPolys(&tmp,polys,level.n_ssectors,&world,nWorld);
		if(world == NULL)
			fprintf(stderr,"ClipWorldToPolys failed!\n");

		// output a .map
		DumpMap(mapname,&level,polys,world,nWorld);

		// clean up memory
		CleanupLevel(&level);
		if(polys != NULL) {
			delete[] polys;
			polys = NULL;
		}
		if(world != NULL) {
			delete[] world;
			world = NULL;
			nWorld = 0;
		}

		// find next level, if using "convert all"
		if(convert_all) {
			wadFile.SeekTo(mapname);
			do {
				if(!wadFile.SeekNext(szEntry)) {
					outOfEntries = true;
					break;
				}
				le = LookupLevelEntry(szEntry);
			} while(le != W_D1LEVEL && le != W_D2LEVEL);
			strcpy(mapname,szEntry);
		}

	} while((le == W_D1LEVEL || le == W_D2LEVEL) && convert_all && !outOfEntries);
	return(true);
}

void strupper(char *s)
{
	while(*s)
		*s++ = toupper(*s);
}

A wad2map/convert.h => wad2map/convert.h +32 -0
@@ 0,0 1,32 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	convert.h

	Ted Mielczarek
	1-13-2000
*/
#ifndef __CONVERT_H_
#define __CONVERT_H_

bool DoConversion(CWadFile &wadFile);

#endif /* __CONVERT_H_ */

A wad2map/defs.h => wad2map/defs.h +54 -0
@@ 0,0 1,54 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	defs.h

	Ted Mielczarek
	1-13-2000

	Definitions of random stuff
*/
#ifndef __DEFS_H_
#define __DEFS_H_

#define MAJORVERSION 1
#define MINORVERSION 0

#ifndef max
#define max(x,y) ((x > y)?(x):(y))
#define min(x,y) ((x < y)?(x):(y))
#endif

#ifndef MAX_PATH
#define MAX_PATH 1024
#endif

#define WHITESPACECHARS " \t\r\n"

#ifndef OutputDebugString
#if DEBUG
#define OutputDebugString(x) fprintf(stderr,x)
#else
#define OutputDebugString
#endif /* DEBUG */
#endif /* OutputDebugString */

#endif /* __DEFS_H_ */

A wad2map/doomlevel.h => wad2map/doomlevel.h +137 -0
@@ 0,0 1,137 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	doomlevel.h

  Ted Mielczarek
  12/07/1999

  Contains struct definitions for doom level data.
*/
#ifndef __DOOMLEVEL_H_
#define __DOOMLEVEL_H_

typedef struct linedef_s {
	short int from_vertex;
	short int to_vertex;
	short int attributes;
	short int type;
	short int sector_trigger;
	short int sidedefs[2];
} linedef_t;

typedef struct sidedef_s {
	short int	u_offset;	
	short int	v_offset;
	char	uppertxt[8];
	char	lowertxt[8];
	char	walltxt[8];
	short int	sector;
} sidedef_t;

typedef struct vertex_s {
	short int x;
	short int y;
} vertex_t;

typedef struct segment_s {
	short int from_vertex;
	short int to_vertex;
	short int angle;
	short int linedef;
	short int side;
	short int distance;
} segment_t;

typedef struct ssector_s {
	short int numsegs;
	short int startseg;
} ssector_t;

typedef struct node_s {
	short int x;
	short int y;
	short int dx;
	short int dy;

	short int left_y_upper;
	short int left_y_lower;
	short int left_x_upper;
	short int left_x_lower;

	short int right_y_upper;
	short int right_y_lower;
	short int right_x_upper;
	short int right_x_lower;

	unsigned short int right_child;
	unsigned short int left_child;
} node_t;

typedef struct sector_s {
	short int floor_alt;
	short int ceiling_alt;
	char floortxt[8];
	char ceiltxt[8];
	short int brightness;
	short int special;
	short int trigger;
} sector_t;

typedef struct thing_s {
	short x;
	short y;
	short angle;
	short thingnum;
	short options;
} thing_t;

// This is just to contain all the level data nicely
typedef struct level_s {
	linedef_t *linedefs;
	long n_linedefs;

	sidedef_t *sidedefs;
	long n_sidedefs;

	vertex_t *vertices;
	long n_vertices;

	segment_t *segs;
	long n_segs;

	ssector_t *ssectors;
	long n_ssectors;

	node_t *nodes;
	long n_nodes;

	sector_t *sectors;
	long n_sectors;

	thing_t *things;
	long n_things;

	short l_width, l_height, x_center, y_center;

} level_t;

#endif /* __DOOMLEVEL_H_ */

A wad2map/dumpmap.cpp => wad2map/dumpmap.cpp +444 -0
@@ 0,0 1,444 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	dumpmap.cpp

	Ted Mielczarek
	1-11-2000

	This file contains routines for exporting a .map file from all the polys
	generated from the doom level.
*/

#include "StdAfx.h"
#include "defs.h"
#include "types.h"
#include "doomlevel.h"
#include "things.h"
#include "dumpmap.h"
#include "progress.h"

#define LAMETEX "base_floor/diamond2c"

void DumpMap(char *mapname, level_t *l, poly_t *ss, poly_t *world, int nWorld)
{
	char filename[MAX_PATH],tex[9],shader[256];
	FILE *f;
	int i,j,c;
	short z_ceil,z_floor,z_max,z_min;
	point3d_t p[3];
	sector_t *sec;
	int nBrushes;

	// create filename, open file
	strcpy(filename,mapname);
	strcat(filename,".map");
	f = fopen(filename,"w");
	if(f == NULL)
		return;

	printf("Writing brushes to mapfile: ");
	// init progress meter
	InitProgress(20,'*',true);
	// 2 brushes for each ssector (floor/ceiling)
	nBrushes = 2 * l->n_ssectors + nWorld;

	// put out some kinda comment
	fprintf(f,"// This map generated by Wad2Map v%d.%d\n",MAJORVERSION,MINORVERSION);

	// find max/min ceiling/floor
	z_max = short(0x8000);
	z_min = short(0x7FFF);
	for(i=0;i<l->n_sectors;i++) {
		z_max = max(z_max,l->sectors[i].ceiling_alt);
		z_min = min(z_min,l->sectors[i].floor_alt);
	}
	// make sure floors/ceilings are at least 16 thick
	z_max += 16;
	z_min -= 16;

	// output brushes
	c = 0;
	// worldspawn ent
	fprintf(f,"{\n\"classname\"  \"worldspawn\"\n\"message\"  \"%s\"\n",mapname);
//------------------------------------------------------
//   Ssector Polys
//------------------------------------------------------
	for(i=0;i<l->n_ssectors;i++) {
		// degenerate/erased polys
		if(ss[i].num_verts < 3)
			continue;

		// get floor/ceiling height
		if(ss[i].sector != -1) {
			sec = &l->sectors[ss[i].sector];
			z_ceil = sec->ceiling_alt;
			z_floor = sec->floor_alt;
		}
		else {
			z_ceil = z_max - 16;;
			z_floor = z_min + 16;;
		}

		// output to map
		//** START FLOOR **
		fprintf(f,"// brush %d\n",c++);
		fprintf(f,"{\n");
		// output floor planes
		// clockwise plane for top floor plane
		p[0].x = 0;
		p[0].y = 0;
		p[1].x = 0;
		p[1].y = 1;
		p[2].x = 1;
		p[2].y = 1;
		p[0].z = p[1].z = p[2].z = z_floor;
		OutputPlane(f,p,LAMETEX);
		// counterclockwise plane for bottom floor plane
		p[0].x = 0;
		p[0].y = 0;
		p[1].x = 1;
		p[1].y = 0;
		p[2].x = 1;
		p[2].y = 1;
		p[0].z = p[1].z = p[2].z = z_min;
		OutputPlane(f,p,LAMETEX);
		// output sides
		for(j=0;j<ss[i].num_verts-1;j++) {
			p[0].x = ss[i].p[j+1].x;
			p[0].y = ss[i].p[j+1].y;
			p[0].z = 1;
			p[1].x = ss[i].p[j].x;
			p[1].y = ss[i].p[j].y;
			p[1].z = 1;
			p[2].x = ss[i].p[j].x;
			p[2].y = ss[i].p[j].y;
			p[2].z = 0;
			OutputPlane(f,p,LAMETEX);
		}
		// side from last to first
		p[0].x = ss[i].p[0].x;
		p[0].y = ss[i].p[0].y;
		p[0].z = 1;
		p[1].x = ss[i].p[ss[i].num_verts-1].x;
		p[1].y = ss[i].p[ss[i].num_verts-1].y;
		p[1].z = 1;
		p[2].x = p[1].x;
		p[2].y = p[1].y;
		p[2].z = 0;
		OutputPlane(f,p,LAMETEX);
		// close brush (floor)
		fprintf(f,"}\n");
		DrawProgress(nBrushes,c);
		//** END FLOOR **

		//** START CEILING **
		// start next brush (ceiling)
		fprintf(f,"// brush %d\n",c++);
		fprintf(f,"{\n");
		// output ceiling planes
		// clockwise plane for top ceiling plane
		p[0].x = 0;
		p[0].y = 0;
		p[1].x = 0;
		p[1].y = 1;
		p[2].x = 1;
		p[2].y = 1;
		p[0].z = p[1].z = p[2].z = z_max;
		OutputPlane(f,p,LAMETEX);
		// counterclockwise plane for bottom ceiling plane
		p[0].x = 0;
		p[0].y = 0;
		p[1].x = 1;
		p[1].y = 0;
		p[2].x = 1;
		p[2].y = 1;
		p[0].z = p[1].z = p[2].z = z_ceil;
		OutputPlane(f,p,LAMETEX);
		// output sides
		for(j=0;j<ss[i].num_verts-1;j++) {
			p[0].x = ss[i].p[j+1].x;
			p[0].y = ss[i].p[j+1].y;
			p[0].z = 1;
			p[1].x = ss[i].p[j].x;
			p[1].y = ss[i].p[j].y;
			p[1].z = 1;
			p[2].x = ss[i].p[j].x;
			p[2].y = ss[i].p[j].y;
			p[2].z = 0;
			OutputPlane(f,p,LAMETEX);
		}
		// side from last to first
		p[0].x = ss[i].p[0].x;
		p[0].y = ss[i].p[0].y;
		p[0].z = 1;
		p[1].x = ss[i].p[ss[i].num_verts-1].x;
		p[1].y = ss[i].p[ss[i].num_verts-1].y;
		p[1].z = 1;
		p[2].x = p[1].x;
		p[2].y = p[1].y;
		p[2].z = 0;
		OutputPlane(f,p,LAMETEX);

		// close ceiling brush
		fprintf(f,"}\n");
		DrawProgress(nBrushes,c);
		//** END CEILING **
	}

//------------------------------------------------------
//     World Polys
//------------------------------------------------------
	// Output world brushes
	for(i=0;i<nWorld;i++) {
		fprintf(f,"// brush %d\n",c++);
		fprintf(f,"{\n");
		// output top and bottom planes
		// clockwise plane for top
		p[0].x = 0;
		p[0].y = 0;
		p[1].x = 0;
		p[1].y = 1;
		p[2].x = 1;
		p[2].y = 1;
		p[0].z = p[1].z = p[2].z = z_max;
		OutputPlane(f,p,LAMETEX);
		// counterclockwise plane for bottom
		p[0].x = 0;
		p[0].y = 0;
		p[1].x = 1;
		p[1].y = 0;
		p[2].x = 1;
		p[2].y = 1;
		p[0].z = p[1].z = p[2].z = z_min;
		OutputPlane(f,p,LAMETEX);
		// output sides
		for(j=0;j<world[i].num_verts-1;j++) {
			p[0].x = world[i].p[j+1].x;
			p[0].y = world[i].p[j+1].y;
			p[0].z = 1;
			p[1].x = world[i].p[j].x;
			p[1].y = world[i].p[j].y;
			p[1].z = 1;
			p[2].x = world[i].p[j].x;
			p[2].y = world[i].p[j].y;
			p[2].z = 0;
			OutputPlane(f,p,LAMETEX);
		}
		// side from last to first
		p[0].x = world[i].p[0].x;
		p[0].y = world[i].p[0].y;
		p[0].z = 1;
		p[1].x = world[i].p[world[i].num_verts-1].x;
		p[1].y = world[i].p[world[i].num_verts-1].y;
		p[1].z = 1;
		p[2].x = p[1].x;
		p[2].y = p[1].y;
		p[2].z = 0;
		OutputPlane(f,p,LAMETEX);
		// close brush
		fprintf(f,"}\n");
		DrawProgress(nBrushes,c);
	}

//------------------------------------------------------
//    Closure Brushes (seal up the level)
//------------------------------------------------------
	OutputSealBrushes(f,l,z_max,z_min);

	fprintf(f,"}\n"); // close up worldspawn
	fprintf(f,"\n");

	printf("\n");
//------------------------------------------------------
//    Things
//------------------------------------------------------
	ConvertThings(f,l,ss);

	// End!
	printf("Finished writing mapfile\n");
	fclose(f);
}

void OutputSealBrushes(FILE *f, level_t *l, int z_max, int z_min)
{
	short xmax,ymax,xmin,ymin;

	// get dimensions
	xmax = l->x_center + l->l_width / 2;
	xmin = l->x_center - l->l_width / 2;
	ymax = l->y_center + l->l_height / 2;
	ymin = l->y_center - l->l_height / 2;

	fprintf(f,"// Seal brushes\n");
	// Top brush
	fprintf(f,"{\n");
	// clockwise plane for top
	WriteZPlane(f,z_max,true);
	// counterclockwise plane for bottom
	WriteZPlane(f,z_max-16,false);
	// right side
	WriteXPlane(f,xmax+16,true);
	// left side
	WriteXPlane(f,xmin-16,false);
	// front side
	WriteYPlane(f,ymax+16,true);
	// back side
	WriteYPlane(f,ymin-16,false);
	fprintf(f,"}\n");

	// Bottom brush
	fprintf(f,"{\n");
	// clockwise plane for top
	WriteZPlane(f,z_min,true);
	// counterclockwise plane for bottom
	WriteZPlane(f,z_min-16,false);
	// right side
	WriteXPlane(f,xmax+16,true);
	// left side
	WriteXPlane(f,xmin-16,false);
	// front side
	WriteYPlane(f,ymax+16,true);
	// back side
	WriteYPlane(f,ymin-16,false);
	fprintf(f,"}\n");

	// Right side brush
	fprintf(f,"{\n");
	// clockwise plane for top
	WriteZPlane(f,z_max-16,true);
	// counterclockwise plane for bottom
	WriteZPlane(f,z_min,false);
	// right side
	WriteXPlane(f,xmax+16,true);
	// left side
	WriteXPlane(f,xmax,false);
	// front side
	WriteYPlane(f,ymax+16,true);
	// back side
	WriteYPlane(f,ymin-16,false);
	fprintf(f,"}\n");
	
	// Left side brush
	fprintf(f,"{\n");
	// clockwise plane for top
	WriteZPlane(f,z_max-16,true);
	// counterclockwise plane for bottom
	WriteZPlane(f,z_min,false);
	// right side
	WriteXPlane(f,xmin,true);
	// left side
	WriteXPlane(f,xmin-16,false);
	// front side
	WriteYPlane(f,ymax+16,true);
	// back side
	WriteYPlane(f,ymin-16,false);
	fprintf(f,"}\n");

	// Front brush
	fprintf(f,"{\n");
	// clockwise plane for top
	WriteZPlane(f,z_max-16,true);
	// counterclockwise plane for bottom
	WriteZPlane(f,z_min,false);
	// right side
	WriteXPlane(f,xmax,true);
	// left side
	WriteXPlane(f,xmin,false);
	// front side
	WriteYPlane(f,ymax+16,true);
	// back side
	WriteYPlane(f,ymax,false);
	fprintf(f,"}\n");

	// Back brush
	fprintf(f,"{\n");
	// clockwise plane for top
	WriteZPlane(f,z_max-16,true);
	// counterclockwise plane for bottom
	WriteZPlane(f,z_min,false);
	// right side
	WriteXPlane(f,xmax,true);
	// left side
	WriteXPlane(f,xmin,false);
	// front side
	WriteYPlane(f,ymin,true);
	// back side
	WriteYPlane(f,ymin-16,false);
	fprintf(f,"}\n");
}

void WriteZPlane(FILE *f, int z, bool dir)
{
	point3d_t p[3];

	p[0].x = 0;
	p[0].y = 0;
	p[1].x = (dir)? 0 : 1;
	p[1].y = (dir)? 1 : 0;
	p[2].x = 1;
	p[2].y = 1;
	p[0].z = p[1].z = p[2].z = z;
	OutputPlane(f,p,LAMETEX);
}

void WriteXPlane(FILE *f, int x, bool dir)
{
	point3d_t p[3];

	p[0].x = x;
	p[0].y = 0;
	p[0].z = 0;
	p[1].x = x;
	p[1].y = (dir) ? 0 : 1;
	p[1].z = (dir) ? 1 : 0;
	p[2].x = x;
	p[2].y = 1;
	p[2].z = 1;
	OutputPlane(f,p,LAMETEX);
}

void WriteYPlane(FILE *f, int y, bool dir)
{
	point3d_t p[3];

	p[0].x = 0;
	p[0].y = y;
	p[0].z = 0;
	p[1].x = (dir) ? 1 : 0;
	p[1].y = y;
	p[1].z = (dir) ? 0 : 1;
	p[2].x = 1;
	p[2].y = y;
	p[2].z = 1;
	OutputPlane(f,p,LAMETEX);
}

void OutputPlane(FILE *f,point3d_t p[], char *tex)
{
	// output points
	fprintf(f,"( "CSPEC" "CSPEC" "CSPEC" ) ( "CSPEC" "CSPEC" "CSPEC" ) ( "CSPEC" "CSPEC" "CSPEC" ) ",
		p[0].x,p[0].y,p[0].z,p[1].x,p[1].y,p[1].z,p[2].x,p[2].y,p[2].z);
	// output texture
	fprintf(f,"%s ",tex);
	// output other data (x/y offset, rotation, x/y scale, ? ? ?
	fprintf(f,"%d %d %d %8.6f %8.6f %d %d %d\n",0,0,0,1.0,1.0,0,0,0);
}

A wad2map/dumpmap.h => wad2map/dumpmap.h +39 -0
@@ 0,0 1,39 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	dumpmap.h

	Ted Mielczarek
	1-11-2000

	This file contains prototypes for dumpmap.cpp, for outputting
	to a .map file.
*/
#ifndef __DUMPMAP_H_
#define __DUMPMAP_H_

void DumpMap(char *mapname, level_t *l, poly_t *ss, poly_t *world, int nWorld);
void OutputPlane(FILE *f,point3d_t p[], char *tex);
void OutputSealBrushes(FILE *f, level_t *l, int z_max, int z_min);
void WriteZPlane(FILE *f, int z, bool dir);
void WriteXPlane(FILE *f, int x, bool dir);
void WriteYPlane(FILE *f, int y, bool dir);
#endif /* __DUMPMAP_H_ */

A wad2map/entities.list => wad2map/entities.list +49 -0
@@ 0,0 1,49 @@
; Wad2Map thing conversion options.
; Comments start with a semicolon.

; contents of a line:
; Doom thing number		Quake entity name
; 1 					info_player_start

; Also, to use a misc_model, preface the model path with a *
; Doom thing number		Model path
; 15					*models/mapobjects/corpse/corpse.md3

; Probably don't want to change these
   1 info_player_start		; Player start
  11 info_player_deathmatch	; Deathmatch start
  14 misc_teleporter_dest	; Teleport landing
  
; Weapons/Ammo
2001 weapon_shotgun			; Shotgun
  82 weapon_shotgun			; Double-barreled shotgun
2002 weapon_railgun			; Chaingun
2003 weapon_rocketlauncher	; Rocket launcher
2004 weapon_plasmagun		; Plasma gun
2006 weapon_bfg				; Bfg9000
2007 ammo_bullets			; Ammo clip
2008 ammo_shells			; Shotgun shells
2010 ammo_rockets			; A rocket
2047 ammo_cells				; Cell charge
2048 ammo_bullets			; Box of Ammo
2049 ammo_shells			; Box of Shells
2046 ammo_rockets			; Box of Rockets
  17 ammo_cells				; Cell charge pack

; Health/Armor
2011 item_health			; Stimpak
2012 item_health_large		; Medikit
2014 item_health_small		; Health Potion
2015 item_armor_shard		; Spirit Armor
2018 item_armor_body		; Green armor
2019 item_armor_combat		; Blue armor
  83 item_regen				; Megasphere (nothing else to replace it with)
2013 item_health_mega		; Soulsphere
2022 item_enviro			; Invulnerability
2023 item_quad				; Berserk
2024 item_invis				; Invisibility
2025 item_enviro			; Radiation suit

; More Dead people
  15  *models/mapobjects/corpse/corpse.md3 ; dead player


A wad2map/entities.list.template => wad2map/entities.list.template +157 -0
@@ 0,0 1,157 @@
; Wad2Map thing conversion options.
; This is only a template!  It will work, but you do not need to include
; lines for things that are ignored.  They are included here just to have
; a complete reference.

; Comments start with a semicolon.

; contents of a line:
; Doom thing number		Quake entity name
; 1 					info_player_start

; Also, to use a misc_model, preface the model path with a *
; Doom thing number		Model path
; 15					*models/mapobjects/corpse/corpse.md3

; Probably don't want to change these
   1 info_player_start		; Player start
   2						; Player 2 start
   3						; Player 3 start
   4						; Player 4 start
  11 info_player_deathmatch	; Deathmatch start
  14 misc_teleporter_dest	; Teleport landing
  
; Monsters are ignored, but you could change this
3004 	; FORMER HUMAN
  84 	; WOLFENSTEIN SS
   9 	; FORMER HUMAN SERGEANT
  65 	; HEAVY WEAPON DUDE
3001 	; IMP
3002 	; DEMON
  58 	; SPECTRE
3006 	; LOST SOUL
3005 	; CACODEMON
  69 	; HELL KNIGHT
3003 	; BARON OF HELL
  68 	; ARACHNOTRON
  71 	; PAIN ELEMENTAL
  66 	; REVENANT
  67 	; MANCUBUS
  64 	; ARCH-VILE
   7 	; SPIDER MASTERMIND
  16 	; CYBER-DEMON
  88 	; BOSS BRAIN (romero's head)
  89 	; Boss Shooter
  87 	; Spawn Spot

; Weapons/Ammo
2005 						; Chainsaw
2001 weapon_shotgun			; Shotgun
  82 weapon_shotgun			; Double-barreled shotgun
2002 weapon_railgun			; Chaingun
2003 weapon_rocketlauncher	; Rocket launcher
2004 weapon_plasmagun		; Plasma gun
2006 weapon_bfg				; Bfg9000
2007 ammo_bullets			; Ammo clip
2008 ammo_shells			; Shotgun shells
2010 ammo_rockets			; A rocket
2047 ammo_cells				; Cell charge
2048 ammo_bullets			; Box of Ammo
2049 ammo_shells			; Box of Shells
2046 ammo_rockets			; Box of Rockets
  17 ammo_cells				; Cell charge pack
   8 						; Backpack

; Health/Armor
2011 item_health			; Stimpak
2012 item_health_large		; Medikit
2014 item_health_small		; Health Potion
2015 item_armor_shard		; Spirit Armor
2018 item_armor_body		; Green armor
2019 item_armor_combat		; Blue armor
  83 item_regen				; Megasphere (nothing else to replace it with)
2013 item_health_mega		; Soulsphere
2022 item_enviro			; Invulnerability
2023 item_quad				; Berserk
2024 item_invis				; Invisibility
2025 item_enviro			; Radiation suit
2026 						; Computer map
2045 						; Lite Amplification goggles

; Keys are ignored
   5 ; Blue keycard
  40 ; Blue skullkey
  13 ; Red keycard
  38 ; Red skullkey
   6 ; Yellow keycard
  39 ; Yellow skullkey

; Misc stuff
2035 ; Barrel
  72 ; Commander Keen
  48 ; Tall, techno pillar
  30 ; Tall green pillar
  32 ; Tall red pillar
  31 ; Short green pillar
  36 ; Short green pillar with beating heart
  33 ; Short red pillar
  37 ; Short red pillar with skull
  47 ; Stalagmite: small brown pointy stump
  43 ; Burnt tree: gray tree
  54 ; Large brown tree

; Lights (will do something with these)
2028 ; Floor lamp
  85 ; Tall techno floor lamp
  86 ; Short techno floor lamp
  34 ; Candle
  35 ; Candelabra
  44 ; Tall blue firestick
  45 ; Tall green firestick
  46 ; Tall red firestick
  55 ; Short blue firestick
  56 ; Short green firestick
  57 ; Short red firestick
  70 ; Burning barrel

; More random stuff
  41 ; Evil Eye: floating eye in symbol, over candle
  42 ; Floating Skull: flaming skull-rock

; Dead people (hanging)
  49 ; Hanging victim, twitching
  63 ; Hanging victim, twitching
  50 ; Hanging victim, arms out
  59 ; Hanging victim, arms out
  52 ; Hanging pair of legs
  60 ; Hanging pair of legs
  51 ; Hanging victim, 1-legged
  61 ; Hanging victim, 1-legged
  53 ; Hanging leg
  62 ; Hanging leg
  73 ; Hanging victim, guts removed
  74 ; Hanging victim, guts and brain removed
  75 ; Hanging torso, looking down
  76 ; Hanging torso, open skull
  77 ; Hanging torso, looking up
  78 ; Hanging torso, brain removed

; More Dead people
  25 ; Impaled human
  26 ; Twitching impaled human
  27 ; Skull on a pole
  28 ; 5 skulls shish kebob
  29 ; Pile of skulls and candles
  10 ; Bloody mess (an exploded player)
  12 ; Bloody mess, this thing is exactly the same as 10
  24 ; Pool of blood and flesh
  79 ; Pool of blood
  80 ; Pool of blood
  81 ; Pool of brains
  15 ; Dead player
  18 ; Dead former human
  19 ; Dead former sergeant
  20 ; Dead imp
  21 ; Dead demon
  22 ; Dead cacodemon
  23 ; Dead lost soul (nothing)

A wad2map/globals.h => wad2map/globals.h +45 -0
@@ 0,0 1,45 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	globals.h

	Ted Mielczarek
	1-13-2000

	This file contains extern definitions for the global variables
	in wad2map.cpp
*/
#ifndef __GLOBALS_H_
#define __GLOBALS_H_

extern char wadfilename[MAX_PATH];

extern char entityoptfilename[MAX_PATH];
#define DEFAULTENTITYFILE "entities.list"

extern char textureoptfilename[MAX_PATH];
#define DEFAULTTEXTUREFILE "textures.list"

extern char mapname[9];
extern bool convert_all;
extern bool do_textures;

#endif /* __GLOBALS_H_ */

A wad2map/gpl.txt => wad2map/gpl.txt +561 -0
@@ 0,0 1,561 @@
		    GNU GENERAL PUBLIC LICENSE

		       Version 2, June 1991



 Copyright (C) 1989, 1991 Free Software Foundation, Inc.

                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 Everyone is permitted to copy and distribute verbatim copies

 of this license document, but changing it is not allowed.



			    Preamble



  The licenses for most software are designed to take away your

freedom to share and change it.  By contrast, the GNU General Public

License is intended to guarantee your freedom to share and change free

software--to make sure the software is free for all its users.  This

General Public License applies to most of the Free Software

Foundation's software and to any other program whose authors commit to

using it.  (Some other Free Software Foundation software is covered by

the GNU Library General Public License instead.)  You can apply it to

your programs, too.



  When we speak of free software, we are referring to freedom, not

price.  Our General Public Licenses are designed to make sure that you

have the freedom to distribute copies of free software (and charge for

this service if you wish), that you receive source code or can get it

if you want it, that you can change the software or use pieces of it

in new free programs; and that you know you can do these things.



  To protect your rights, we need to make restrictions that forbid

anyone to deny you these rights or to ask you to surrender the rights.

These restrictions translate to certain responsibilities for you if you

distribute copies of the software, or if you modify it.



  For example, if you distribute copies of such a program, whether

gratis or for a fee, you must give the recipients all the rights that

you have.  You must make sure that they, too, receive or can get the

source code.  And you must show them these terms so they know their

rights.



  We protect your rights with two steps: (1) copyright the software, and

(2) offer you this license which gives you legal permission to copy,

distribute and/or modify the software.



  Also, for each author's protection and ours, we want to make certain

that everyone understands that there is no warranty for this free

software.  If the software is modified by someone else and passed on, we

want its recipients to know that what they have is not the original, so

that any problems introduced by others will not reflect on the original

authors' reputations.



  Finally, any free program is threatened constantly by software

patents.  We wish to avoid the danger that redistributors of a free

program will individually obtain patent licenses, in effect making the

program proprietary.  To prevent this, we have made it clear that any

patent must be licensed for everyone's free use or not licensed at all.



  The precise terms and conditions for copying, distribution and

modification follow.



		    GNU GENERAL PUBLIC LICENSE

   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION



  0. This License applies to any program or other work which contains

a notice placed by the copyright holder saying it may be distributed

under the terms of this General Public License.  The "Program", below,

refers to any such program or work, and a "work based on the Program"

means either the Program or any derivative work under copyright law:

that is to say, a work containing the Program or a portion of it,

either verbatim or with modifications and/or translated into another

language.  (Hereinafter, translation is included without limitation in

the term "modification".)  Each licensee is addressed as "you".



Activities other than copying, distribution and modification are not

covered by this License; they are outside its scope.  The act of

running the Program is not restricted, and the output from the Program

is covered only if its contents constitute a work based on the

Program (independent of having been made by running the Program).

Whether that is true depends on what the Program does.



  1. You may copy and distribute verbatim copies of the Program's

source code as you receive it, in any medium, provided that you

conspicuously and appropriately publish on each copy an appropriate

copyright notice and disclaimer of warranty; keep intact all the

notices that refer to this License and to the absence of any warranty;

and give any other recipients of the Program a copy of this License

along with the Program.



You may charge a fee for the physical act of transferring a copy, and

you may at your option offer warranty protection in exchange for a fee.



  2. You may modify your copy or copies of the Program or any portion

of it, thus forming a work based on the Program, and copy and

distribute such modifications or work under the terms of Section 1

above, provided that you also meet all of these conditions:



    a) You must cause the modified files to carry prominent notices

    stating that you changed the files and the date of any change.



    b) You must cause any work that you distribute or publish, that in

    whole or in part contains or is derived from the Program or any

    part thereof, to be licensed as a whole at no charge to all third

    parties under the terms of this License.



    c) If the modified program normally reads commands interactively

    when run, you must cause it, when started running for such

    interactive use in the most ordinary way, to print or display an

    announcement including an appropriate copyright notice and a

    notice that there is no warranty (or else, saying that you provide

    a warranty) and that users may redistribute the program under

    these conditions, and telling the user how to view a copy of this

    License.  (Exception: if the Program itself is interactive but

    does not normally print such an announcement, your work based on

    the Program is not required to print an announcement.)



These requirements apply to the modified work as a whole.  If

identifiable sections of that work are not derived from the Program,

and can be reasonably considered independent and separate works in

themselves, then this License, and its terms, do not apply to those

sections when you distribute them as separate works.  But when you

distribute the same sections as part of a whole which is a work based

on the Program, the distribution of the whole must be on the terms of

this License, whose permissions for other licensees extend to the

entire whole, and thus to each and every part regardless of who wrote it.



Thus, it is not the intent of this section to claim rights or contest

your rights to work written entirely by you; rather, the intent is to

exercise the right to control the distribution of derivative or

collective works based on the Program.



In addition, mere aggregation of another work not based on the Program

with the Program (or with a work based on the Program) on a volume of

a storage or distribution medium does not bring the other work under

the scope of this License.



  3. You may copy and distribute the Program (or a work based on it,

under Section 2) in object code or executable form under the terms of

Sections 1 and 2 above provided that you also do one of the following:



    a) Accompany it with the complete corresponding machine-readable

    source code, which must be distributed under the terms of Sections

    1 and 2 above on a medium customarily used for software interchange; or,



    b) Accompany it with a written offer, valid for at least three

    years, to give any third party, for a charge no more than your

    cost of physically performing source distribution, a complete

    machine-readable copy of the corresponding source code, to be

    distributed under the terms of Sections 1 and 2 above on a medium

    customarily used for software interchange; or,



    c) Accompany it with the information you received as to the offer

    to distribute corresponding source code.  (This alternative is

    allowed only for noncommercial distribution and only if you

    received the program in object code or executable form with such

    an offer, in accord with Subsection b above.)



The source code for a work means the preferred form of the work for

making modifications to it.  For an executable work, complete source

code means all the source code for all modules it contains, plus any

associated interface definition files, plus the scripts used to

control compilation and installation of the executable.  However, as a

special exception, the source code distributed need not include

anything that is normally distributed (in either source or binary

form) with the major components (compiler, kernel, and so on) of the

operating system on which the executable runs, unless that component

itself accompanies the executable.



If distribution of executable or object code is made by offering

access to copy from a designated place, then offering equivalent

access to copy the source code from the same place counts as

distribution of the source code, even though third parties are not

compelled to copy the source along with the object code.



  4. You may not copy, modify, sublicense, or distribute the Program

except as expressly provided under this License.  Any attempt

otherwise to copy, modify, sublicense or distribute the Program is

void, and will automatically terminate your rights under this License.

However, parties who have received copies, or rights, from you under

this License will not have their licenses terminated so long as such

parties remain in full compliance.



  5. You are not required to accept this License, since you have not

signed it.  However, nothing else grants you permission to modify or

distribute the Program or its derivative works.  These actions are

prohibited by law if you do not accept this License.  Therefore, by

modifying or distributing the Program (or any work based on the

Program), you indicate your acceptance of this License to do so, and

all its terms and conditions for copying, distributing or modifying

the Program or works based on it.



  6. Each time you redistribute the Program (or any work based on the

Program), the recipient automatically receives a license from the

original licensor to copy, distribute or modify the Program subject to

these terms and conditions.  You may not impose any further

restrictions on the recipients' exercise of the rights granted herein.

You are not responsible for enforcing compliance by third parties to

this License.



  7. If, as a consequence of a court judgment or allegation of patent

infringement or for any other reason (not limited to patent issues),

conditions are imposed on you (whether by court order, agreement or

otherwise) that contradict the conditions of this License, they do not

excuse you from the conditions of this License.  If you cannot

distribute so as to satisfy simultaneously your obligations under this

License and any other pertinent obligations, then as a consequence you

may not distribute the Program at all.  For example, if a patent

license would not permit royalty-free redistribution of the Program by

all those who receive copies directly or indirectly through you, then

the only way you could satisfy both it and this License would be to

refrain entirely from distribution of the Program.



If any portion of this section is held invalid or unenforceable under

any particular circumstance, the balance of the section is intended to

apply and the section as a whole is intended to apply in other

circumstances.



It is not the purpose of this section to induce you to infringe any

patents or other property right claims or to contest validity of any

such claims; this section has the sole purpose of protecting the

integrity of the free software distribution system, which is

implemented by public license practices.  Many people have made

generous contributions to the wide range of software distributed

through that system in reliance on consistent application of that

system; it is up to the author/donor to decide if he or she is willing

to distribute software through any other system and a licensee cannot

impose that choice.



This section is intended to make thoroughly clear what is believed to

be a consequence of the rest of this License.



  8. If the distribution and/or use of the Program is restricted in

certain countries either by patents or by copyrighted interfaces, the

original copyright holder who places the Program under this License

may add an explicit geographical distribution limitation excluding

those countries, so that distribution is permitted only in or among

countries not thus excluded.  In such case, this License incorporates

the limitation as if written in the body of this License.



  9. The Free Software Foundation may publish revised and/or new versions

of the General Public License from time to time.  Such new versions will

be similar in spirit to the present version, but may differ in detail to

address new problems or concerns.



Each version is given a distinguishing version number.  If the Program

specifies a version number of this License which applies to it and "any

later version", you have the option of following the terms and conditions

either of that version or of any later version published by the Free

Software Foundation.  If the Program does not specify a version number of

this License, you may choose any version ever published by the Free Software

Foundation.



  10. If you wish to incorporate parts of the Program into other free

programs whose distribution conditions are different, write to the author

to ask for permission.  For software which is copyrighted by the Free

Software Foundation, write to the Free Software Foundation; we sometimes

make exceptions for this.  Our decision will be guided by the two goals

of preserving the free status of all derivatives of our free software and

of promoting the sharing and reuse of software generally.



			    NO WARRANTY



  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY

FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN

OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES

PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED

OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS

TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE

PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,

REPAIR OR CORRECTION.



  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING

WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR

REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,

INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING

OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED

TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY

YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER

PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE

POSSIBILITY OF SUCH DAMAGES.



		     END OF TERMS AND CONDITIONS



A wad2map/progress.cpp => wad2map/progress.cpp +85 -0
@@ 0,0 1,85 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	progress.cpp

	Ted Mielczarek
	1-13-2000

	Defines routines for drawing an ascii progress bar.
*/

#include "StdAfx.h"
#include "progress.h"

int progLen = 10;
char fillChar = '*';
char clearBuf[256] = "\0";
bool doPercent = false;

void InitProgress(int len, char fill, bool drawPercent)
{
	int i,c;

	if(len > 255)
		len = 255;

	progLen = len;
	fillChar = fill;
	doPercent = drawPercent;

	clearBuf[0] = '\0';
	c = progLen+1;
	if(doPercent)
		c += 5;

	for(i=0;i<c;i++)
		strcat(clearBuf,"\b");

	// print empty progress bar
	printf("[");
	for(i=0;i<len;i++)
		printf(" ");
	printf("]   0%%");
}

void DrawProgress(long total, long count)
{
	int i, c;
	double d;

	d = double(count) / double(total);
	c = int(progLen * d);

	// clear last progress bar
	printf(clearBuf);

	// print progress bar
	for(i=0;i<progLen;i++)
		(i<c) ?
		printf("*") :
		printf(" ");

	if(doPercent)
		printf("] %3d%%",int(d*100));
	else
		printf("]");
}

A wad2map/progress.h => wad2map/progress.h +33 -0
@@ 0,0 1,33 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	progress.h

	Ted Mielczarek
	1-13-2000
*/
#ifndef __PROGRESS_H_
#define __PROGRESS_H_

void InitProgress(int len, char fill, bool drawPercent);
void DrawProgress(long total, long count);

#endif /* __PROGRESS_H_ */

A wad2map/subtract_ssectors.cpp => wad2map/subtract_ssectors.cpp +265 -0
@@ 0,0 1,265 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	subtract_ssectors.cpp

	Ted Mielczarek
	12-21-1999

	This file contains routines to subtract the ssector polygons from the
	world polygon, creating the "wall" brushes.
*/
#include "StdAfx.h"
#include "defs.h"
#include "types.h"
#include "2dclip.h"
#include "subtract_ssectors.h"
#include "progress.h"

// Globals
poly_t *polyList[MAX_POLYS_IN_LIST];
int polyCount;

/*
	ClipWorldToPolys

	Parameters:
	world: Poly surrounding entire level
	ss:    List of polys to subtract from world
	n:     Count of polys in ss
	out:   Pointer to allocate list into to store returned polys
	count: Number of polys returned in out

	This function subtracts each poly in ss from world, and stores the results in
	out, and the number of polys created in count.
*/
bool ClipWorldToPolys(poly_t *world, poly_t ss[], int n, poly_t **out, int &count)
{
	int i,c;

	// MUST DO THIS FIRST!!
	InitList();

	// start out with world poly
	AddToList(world);

	printf("Subtracting ssectors from world: ");
	// init progress meter
	InitProgress(20,'*',true);
	//DrawProgress(n,0);

	// iterate through polys to subtract
	for(i=0;i<n;i++) {
		if(ss[i].num_verts > 2)
			// subtract this poly from every poly in the world list
			Subtract(&ss[i]);
		// draw progress meter
		DrawProgress(n,i);
	}
	DrawProgress(n,i);
	printf("\n");

	// make sure we didn't screw up
	if(polyCount > 0) {
		*out = new poly_t[polyCount];
		count = polyCount;
		c = 0;
		for(i=0;i < MAX_POLYS_IN_LIST && c < polyCount; i++)
			if(polyList[i] != NULL)
				memcpy(&(*out)[c++],polyList[i],sizeof(poly_t));
	}
	else // eek
		return(false);

	ClearList();

	// check all polys
	for(i=0;i<count;i++)
		if((*out)[i].num_verts < 3)
			OutputDebugString("Bad world brush\n");

	return(true);
}

bool Subtract(poly_t *sub)
{
	poly_t inter;
	int i;

	for(i=0;i<MAX_POLYS_IN_LIST; i++) {
		if(polyList[i] == NULL)
			continue;

		// do they intersect
		if(PolyIntersect(polyList[i],sub,&inter)) {
			if(CheckPoly(&inter)) {
				// cut intersection out of poly
				CSGSubtract(polyList[i],&inter);
				// remove old poly from list
				RemByIndex(i);
			}
		}
	}
			
	return(true);
}

bool CSGSubtract(poly_t *a, poly_t *inter)
{
	int i;
	poly_t save,tmp;
	line_t l;
	point_t p[2];

	memcpy(&tmp,a,sizeof(poly_t));
	for(i=0;i<inter->num_verts-1;i++) {
		LineFromPoints(&l,inter->p+i);
		memcpy(&save,&tmp,sizeof(poly_t));
		if(ClipPolyToLine(&save,&l,left_side)) {
			if(CheckPoly(&save))
				AddToList(&save);
			else
				OutputDebugString("Bad world brush\n");

			ClipPolyToLine(&tmp,&l,right_side);
		}
	}

	// do last vert->first vert
	memcpy(p,inter->p+inter->num_verts-1,sizeof(point_t));
	memcpy(p+1,inter->p,sizeof(point_t));
	LineFromPoints(&l,p);
	memcpy(&save,&tmp,sizeof(poly_t));
	if(ClipPolyToLine(&save,&l,left_side))
		if(CheckPoly(&save))
			AddToList(&save);
		else
			OutputDebugString("Bad world brush\n");

	return(true);
}

bool PolyIntersect(poly_t *a, poly_t *b, poly_t *inter)
{
	line_t l;
	int i;
	point_t p[2];

	memcpy(inter,a,sizeof(poly_t));
	// clip intersection poly (starts out as a) to each line in b
	for(i=0;i<b->num_verts-1;i++) {
		LineFromPoints(&l,b->p+i);
		ClipPolyToLine(inter,&l,right_side);
	}
		
	// get line from last vert to first vert
	memcpy(p,b->p+b->num_verts-1,sizeof(point_t));
	memcpy(p+1,b->p,sizeof(point_t));
	LineFromPoints(&l,p);
	ClipPolyToLine(inter,&l,right_side);

	if(inter->num_verts > 2)
		return(true);

	return(false);
}

void InitList(void)
{
	int i;

	for(i=0;i<MAX_POLYS_IN_LIST;i++)
		polyList[i] = NULL;

	polyCount = 0;
}

bool AddToList(poly_t *p)
{
	int i;

	// list is full, oops
	if(polyCount == MAX_POLYS_IN_LIST)
		return(false);

	for(i=0;i<MAX_POLYS_IN_LIST;i++) {
		if(polyList[i] == NULL) {
			polyList[i] = new poly_t;
			if(polyList[i] == NULL)
				// out of memory
				return(false);
			// just in case!
			p->sector = -1;
			memcpy(polyList[i],p,sizeof(poly_t));
			polyCount++;
			return(true);
		}
	}
	// no slots free, this shouldn't happen
	return(false);
}

void ClearList(void)
{
	int i;

	for(i=0;i<MAX_POLYS_IN_LIST;i++) {
		if(polyList[i] != NULL)
			delete polyList[i];
		polyList[i] = NULL;
	}
	polyCount = 0;
}

bool RemFromList(poly_t *p)
{
	int i;

	// list empty
	if(polyCount == 0)
		return(false);

	for(i=0;i<MAX_POLYS_IN_LIST;i++) {
		if(polyList[i] == p) {
			delete(polyList[i]);
			polyList[i] = NULL;
			polyCount--;
			return(true);
		}
	}

	return(false);
}

bool RemByIndex(int i)
{
	// list empty
	if(polyCount == 0)
		return(false);

	if(polyList[i] == NULL)
		return(false);

	delete(polyList[i]);
	polyList[i] = NULL;
	polyCount--;
	return(true);
}

A wad2map/subtract_ssectors.h => wad2map/subtract_ssectors.h +45 -0
@@ 0,0 1,45 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	subtract_ssectors.h

	Ted Mielczarek
	12-21-1999

	This file contains prototypes for subtract_ssectors.cpp
*/
#ifndef __SUBTRACT_SSECTORS_H_
#define __SUBTRACT_SSECTORS_H_

// max polys we can have created for the world.  not enough?
#define MAX_POLYS_IN_LIST 1024

bool ClipWorldToPolys(poly_t *world, poly_t ss[], int n, poly_t **out, int &count);
bool Subtract(poly_t *sub);
bool CSGSubtract(poly_t *a, poly_t *inter);
bool PolyIntersect(poly_t *a, poly_t *b, poly_t *inter);
void InitList(void);
bool AddToList(poly_t *p);
void ClearList(void);
bool RemFromList(poly_t *p);
bool RemByIndex(int i);

#endif /* __SUBTRACT_SSECTORS_H_ */

A wad2map/things.cpp => wad2map/things.cpp +216 -0
@@ 0,0 1,216 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	things.cpp

	Ted Mielczarek
	1-11-2000

	This file contains routines for converting things from a wadfile
	to a .map file.
*/

#include "StdAfx.h"
#include <errno.h>
#include "defs.h"
#include "types.h"
#include "doomlevel.h"
#include "2dclip.h"
#include "things.h"
#include "progress.h"

// Globals
thingconvert_t things[MAX_DOOM_THINGS];
int numthings = 0;
specialthing_t specialthings[] = {
	{'*', MiscModel}
};
int numspecialthings = sizeof(specialthings) / sizeof(specialthing_t);

// This function is only used if the thing convert file cannot be loaded
void SetThingConvertDefaults(void)
{
	memset(things,0,sizeof(things));
	// just initialize this one for quick testing
	things[0].d_thing = 1;
	strcpy(things[0].q_entity,"info_player_start");
	numthings++;
}

void LoadThingConvertFile(char *szFile)
{
	FILE *f;
	char strIn[1024], qThing[256],*s,*ptr;
	long dThing;
	int i;

	f = fopen(szFile,"r");
	if(f == NULL) {
		fprintf(stderr,"Could not open thing convert list %s, using defaults.\n",szFile);
		SetThingConvertDefaults();
		return;
	}

	printf("Loading thing conversion options from %s\n",szFile);

	// initialize numthings
	numthings = 0;
	i = 0;

	while(!feof(f)) {
		fgets(strIn,1024,f);
		if(feof(f))
			break;

		i++;
		// look for thing number
		s = strtok(strIn,WHITESPACECHARS);
		// nothing on line
		if(s == NULL)
			continue;

		// just a comment
		if(*s == ';')
			continue;

		dThing = strtol(s,&ptr,0);
		if(*ptr != '\0' || errno == ERANGE) {
			fprintf(stderr,"LoadThingConvertFile: Bad thing number on line %d\n",i);
			continue;
		}

		// look for entity name
		s = strtok(NULL,WHITESPACECHARS);

		// skip things with nothing to convert to
		// blank line
		if(s == NULL)
			continue;
		// just a comment
		else if(*s == ';')
			continue;

		strcpy(qThing,s);

		// set values
		things[numthings].d_thing = short(dThing);
		strcpy(things[numthings].q_entity,qThing);
		numthings++;
	}

	fclose(f);
}

bool ConvertThings(FILE *f, level_t *l, poly_t *ss)
{
	int i,c,z,st;
	thing_t *t = l->things;
	char szName[256];

	printf("Converting things: ");
	InitProgress(20,'*',true);
	DrawProgress(l->n_things,0);

	c = 0;
	for(i=0; i<l->n_things; i++, t++) {
		if(LookupThing(t->thingnum,szName)) {
			// get  z coordinate
			z = GetThingZ(l,t,ss);
			// see if it's a "special thing"
			st = LookupSpecialThing(szName[0]);
			// output thing
			fprintf(f,"// entity %d\n",c++);
			fprintf(f,"{\n");
			// handle "special things"
			if(st != -1)
				specialthings[st].stp(f,szName+1,t,z);
			else {
				fprintf(f,"\"classname\" \"%s\"\n",szName);
				fprintf(f,"\"origin\" \"%d %d %d\"\n",t->x,t->y,z);
				fprintf(f,"\"angle\" \"%d\"\n",t->angle);
			}
			fprintf(f,"}\n\n");
		}
		DrawProgress(l->n_things,i);
	}
	DrawProgress(l->n_things,i);
	printf("\n");

	return(true);
}

bool LookupThing(short d_thing, char *q_entity)
{
	int i;

	// lookup d_thing number in things list
	for(i=0;i<numthings;i++) {
		if(d_thing == things[i].d_thing) {
			// found
			strcpy(q_entity,things[i].q_entity);
			return(true);
		}
	}
	// not found
	return(false);
}

int LookupSpecialThing(char c)
{
	int i;

	for(i=0;i<numspecialthings;i++)
		if(specialthings[i].c == c)
			return(i);

	return(-1);
}

int GetThingZ(level_t *l, thing_t *t, poly_t *ss)
{
	int i;
	point_t p;

	// coords of thing
	p.x = t->x;
	p.y = t->y;

	for(i=0; i<l->n_ssectors; i++) {
		if(PointInPoly(&p,&ss[i]))
			return(l->sectors[ss[i].sector].floor_alt + 8);
	}

	return(0);
}

//--------------------------------------------------
// "Special Things" procedures
//--------------------------------------------------
bool MiscModel(FILE *f, char *szModel, thing_t *t, int z)
{
	if(*szModel == '\0')
		return(false);

	fprintf(f,"\"classname\" \"misc_model\"\n");
	fprintf(f,"\"model\" \"%s\"\n",szModel);
	fprintf(f,"\"origin\" \"%d %d %d\"\n",t->x,t->y,z);
	return(true);
}

A wad2map/things.h => wad2map/things.h +63 -0
@@ 0,0 1,63 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	things.h

	Ted Mielczarek
	1-11-2000

	This file contains definitions for things.cpp
*/
#ifndef __THINGS_H_
#define __THINGS_H_

// thing conversion list
typedef struct thingconvert_s
{
	short d_thing;
	char q_entity[256];
} thingconvert_t;

typedef bool (*SPECIALTHINGPROC)(FILE *,char *, thing_t *, int);
typedef struct specialthing_s
{
	char c;
	SPECIALTHINGPROC stp;
} specialthing_t;

// number of unique things present in Doom
#define MAX_DOOM_THINGS 123

#define THING_SKILL_EASY	1
#define THING_SKILL_MED		(1<<1)
#define THING_SKILL_HARD	(1<<2)
#define THING_DEAF				(1<<3)
#define THING_MULTI_ONLY	(1<<4)

void SetThingConvertDefaults(void);
void LoadThingConvertFile(char *szFile);
bool ConvertThings(FILE *f, level_t *l, poly_t *ss);
bool LookupThing(short d_thing, char *q_entity);
int LookupSpecialThing(char c);
int GetThingZ(level_t *l, thing_t *t, poly_t *ss);
// Special Thing procs
bool MiscModel(FILE *f, char *szModel, thing_t *t, int z);
#endif /* __THINGS_H_ */

A wad2map/types.h => wad2map/types.h +71 -0
@@ 0,0 1,71 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	types.h

	Ted Mielczarek
	12/10/1999

	This file contains data types for the program.
*/
#ifndef __TYPES_H_
#define __TYPES_H_

// we can use double or int
#ifdef USE_FLOATING_POINT
typedef double coord;
#define CSPEC "%lf"
#else
typedef int coord;
#define CSPEC "%d"
#endif

typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;

// point
typedef struct point_s {
	coord x,y;
} point_t;

// 3d point (used for dumping maps)
typedef struct point3d_s {
	coord x,y,z;
} point3d_t;

// point-normal form of a line
typedef struct line_s {
	point_t n;	// normal vector
	point_t p;	// point
} line_t;

// is this enough?
#define MAX_POLY_VERTS 256

typedef struct poly_s {
	point_t p[MAX_POLY_VERTS];			// poly vertices
	int num_verts;									// vertex count
	short sidedef[MAX_POLY_VERTS];	// to keep track of sidedefs/lines
	short sector;										// sector this is a part of (-1 for none)
} poly_t;

#endif /* __TYPES_H_ */

A wad2map/wad2map-todo.txt => wad2map/wad2map-todo.txt +32 -0
@@ 0,0 1,32 @@
Wad2Map to-do list
1-16-2000

Things to do immediately:
* texture support
* door/plat/etc support

Things that need to be worked on:
* Fix CSG Code - Still Producing some bad world brushes

Things to do as a whole:
+ doom level structs
+ wad class
+ polygon clipping code
+ Ssector clipping from node division lines/segs
+ 2d CSG subtract ssector polys from world poly
+ Output brushes to map file
* Combine brushes to reduce count
+ Convert things / config file format
* Parse thing convert file
* Assign textures - sector # for ssectors, sidedef # for world brushes (lower/upper for ssectors)
* Handle doors/plats/etc
* Handle water/lava
* Handle skies
* Convert pillars, other misc entities to brushes or misc models
* Handle lighting (textures, entities, points?)
+ Texture converter
* Have texture converter output shaders
* Level scaling / shifting (is it needed?)
* Texture replacing / config file format
* Sky textures
* Handmade shaders for doom textures (for best results)
\ No newline at end of file

A wad2map/wad2map.cpp => wad2map/wad2map.cpp +158 -0
@@ 0,0 1,158 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	wad2map.cpp

	Main entry point
*/
#include "StdAfx.h"
#include "defs.h"
#include "types.h"
#include "doomlevel.h"
#include "WadFile.h"
#include "convert.h"
#include "globals.h"
#include "things.h"

// Local function prototypes
int GetCommandlineOptions(int argc, char **argv);
void usage(void);
void License(void);

// Global variables
char wadfilename[MAX_PATH] = "\0",
		entityoptfilename[MAX_PATH] = DEFAULTENTITYFILE,
		textureoptfilename[MAX_PATH] = DEFAULTTEXTUREFILE;
char mapname[9] = "\0";
bool convert_all = false,
		do_textures = false;

// Function definitions
int main(int argc, char **argv)
{
	CWadFile theWad;
	int i;

	License();

	if(argc < 2)
		usage();

	// Check commandline options
	i = GetCommandlineOptions(argc,argv);

	// open wadfile and proceed
	if(!theWad.Open(argv[i])) {
		printf("Could not open %s for input!\n",argv[i]);
		exit(1);
	}

	// get thing/texture conversion data
	LoadThingConvertFile(entityoptfilename);

	// do all conversion
	DoConversion(theWad);
	// close up
	theWad.Close();

	printf("Exiting...\n");

	return(0);
}

int GetCommandlineOptions(int argc, char **argv)
{
	int i;

		// check commandline options
	for(i=1;i<argc;i++) {
		// check for "convert all" option
		if(!strcmp(argv[i],"-a")) {
			convert_all = true;
		}
		// check for "do textures" option
		else if(!strcmp(argv[i],"-dt")) {
			do_textures = true;
		}
		// check for map name
		else if(!strcmp(argv[i],"-m")) {
			i++;
			if(i == argc)
				usage();
			strcpy(mapname,argv[i]);
		}
		// check for entity conversion options file
		else if(!strcmp(argv[i],"-e")) {
			i++;
			if(i == argc)
				usage();
			strcpy(entityoptfilename,argv[i]);
		}
		// check for texture conversion options files
		else if(!strcmp(argv[i],"-t")) {
			i++;
			if(i == argc)
				usage();
			strcpy(textureoptfilename,argv[i]);
		}
		else // unknown option
			if(i < argc-1)
				usage();
	}

	if(i == (argc + 1))
		usage();

	return(i - 1);
}

void usage(void)
{
	printf("Usage: wad2map [options] wadfile\n");
	printf("options:\n\n");
	printf("-m mapname\n");
	printf("Convert this map.  If used with -a,\n");
	printf("starts with this map and converts all\n");
	printf("maps following it.  If not specified,\n");
	printf("converts the first map found.\n\n");
	printf("-a\n");
	printf("Convert all maps in the wad.\n\n");
	printf("-e file\n");
	printf("Read entity conversion data from this\n");
	printf("file.  Default is %s\n\n",DEFAULTENTITYFILE);
	printf("-t file\n");
	printf("Read texture conversion data from this\n");
	printf("file.  Default is %s (not functional)\n\n",DEFAULTTEXTUREFILE);
	printf("-dt\n");
	printf("Replace textures with Quake textures.\n");
	printf("Do not use this option if you intend to\n");
	printf("use converted doom textures. (not functional)\n\n");

	exit(1);
}

void License(void)
{
	printf("Wad2Map version 1.0, Copyright (C) 2000 Ted Mielczarek\n"
		"Wad2Map comes with ABSOLUTELY NO WARRANTY; for details see GPL.txt\n"
		"This is free software, and you are welcome to redistribute it\n"
		"under certain conditions; see GPL.txt for details.\n\n");
}
\ No newline at end of file

A wad2map/wad2map.dsp => wad2map/wad2map.dsp +223 -0
@@ 0,0 1,223 @@
# Microsoft Developer Studio Project File - Name="wad2map" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=wad2map - Win32 Not Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "wad2map.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "wad2map.mak" CFG="wad2map - Win32 Not Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "wad2map - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "wad2map - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "wad2map - Win32 Not Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "wad2map - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /W4 /GX /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"stdafx.h" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386

!ELSEIF  "$(CFG)" == "wad2map - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept

!ELSEIF  "$(CFG)" == "wad2map - Win32 Not Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "wad2map___Win32_Not_Debug"
# PROP BASE Intermediate_Dir "wad2map___Win32_Not_Debug"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Not_Debug"
# PROP Intermediate_Dir "Not_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /ML /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /pdbtype:sept
# SUBTRACT LINK32 /debug

!ENDIF 

# Begin Target

# Name "wad2map - Win32 Release"
# Name "wad2map - Win32 Debug"
# Name "wad2map - Win32 Not Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\2dclip.cpp
# End Source File
# Begin Source File

SOURCE=.\clip_ssectors.cpp
# End Source File
# Begin Source File

SOURCE=.\convert.cpp
# End Source File
# Begin Source File

SOURCE=.\dumpmap.cpp
# End Source File
# Begin Source File

SOURCE=.\progress.cpp
# End Source File
# Begin Source File

SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# Begin Source File

SOURCE=.\subtract_ssectors.cpp
# End Source File
# Begin Source File

SOURCE=.\things.cpp
# End Source File
# Begin Source File

SOURCE=.\wad2map.cpp
# End Source File
# Begin Source File

SOURCE=.\wadentries.cpp
# End Source File
# Begin Source File

SOURCE=.\WadFile.cpp
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=.\2dclip.h
# End Source File
# Begin Source File

SOURCE=.\clip_ssectors.h
# End Source File
# Begin Source File

SOURCE=.\convert.h
# End Source File
# Begin Source File

SOURCE=.\defs.h
# End Source File
# Begin Source File

SOURCE=.\doomlevel.h
# End Source File
# Begin Source File

SOURCE=.\dumpmap.h
# End Source File
# Begin Source File

SOURCE=.\globals.h
# End Source File
# Begin Source File

SOURCE=.\progress.h
# End Source File
# Begin Source File

SOURCE=.\StdAfx.h
# End Source File
# Begin Source File

SOURCE=.\subtract_ssectors.h
# End Source File
# Begin Source File

SOURCE=.\things.h
# End Source File
# Begin Source File

SOURCE=.\types.h
# End Source File
# Begin Source File

SOURCE=.\wadentries.h
# End Source File
# Begin Source File

SOURCE=.\WadFile.h
# End Source File
# End Group
# End Target
# End Project

A wad2map/wad2map.dsw => wad2map/wad2map.dsw +29 -0
@@ 0,0 1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!

###############################################################################

Project: "wad2map"=.\wad2map.dsp - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Global:

Package=<5>
{{{
}}}

Package=<3>
{{{
}}}

###############################################################################


A wad2map/wad2map.opt => wad2map/wad2map.opt +0 -0
A wad2map/wad2map.txt => wad2map/wad2map.txt +58 -0
@@ 0,0 1,58 @@
Wad2Map
A Doom to Quake3 level converter
by Ted Mielczarek

Wad2Map is just what its name states: A Doom wad to Quake map converter.  Yes,
now you can (more or less) play your favorite doom maps as Quake maps.  I know,
I know, there have been other converters, and they produce mostly crap.  I'm not
saying that Wad2Map is perfect, but it's a heck of a lot better than those. (In
my opinion, anyway).

Wad2Map is released under the GNU Public Lisence.  See GPL.txt for details.

Usage
----
You can simply run "wad2map somewad.wad" and Wad2Map will convert the first level
it finds in that wad into a quake map.  Or, you can take matters into your
own hands and use some of the following commandline switches:

-a
Convert all levels in the wad.  Fairly obvious as to the functionality.

-m mapname
Convert this map.  If used with -a, also converts all maps after this in the wad.

-e file
Read the entity conversion list from this file.  The default is entities.list.  See
that file for a description of the format.

How exactly does it work?
----
Wad2Map determines the ssectors by using the node clipping lines to clip a world-size
polygon down to size.  Once it has created all the ssectors, it csg subtracts these
polygons from a world-size polygon to get the rest of the world geometry (what you
see as the walls).  Fairly simple.  Mostly.  Unfortunately, it's not quite that simple,
so it's not perfect.  You will still get some bad brushes occasionally.  Hopefully this
will be fixed eventually.

Credits
----
Wad2Map would not have been possible without the help of the following:

Trey Harrison, who schooled me in some aspects of computational geometry.
Stephen Crowley, who had the original idea.
Matt Fell's Doom Specs - The Ultimate Doom Resource.
Niklata's Quake Map Specs - An excellent guide to the .map format.
The denizens of EFnet #QuakeEd, for being generally unhelpful.

Etc.
----
The Wad2Map homepage is http://www.lehigh.edu/~tam4/wad2map
The author, Ted Mielczarek, can be contacted via email at tam4@lehigh.edu.  Please
include Wad2Map in the subject line, or your mail is likely to be tossed aside.  And
don't complain about what's not implemented, unless you have an actual idea of how
to do so.  Praise (and money) are accepted.


-Ted
2-11-2000

A wad2map/wadentries.cpp => wad2map/wadentries.cpp +262 -0
@@ 0,0 1,262 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	wadentries.cpp

	Ted Mielczarek
	12/09/1999

	This file contains an index of doom level wad entries and
	a function to look them up into the enum defined in wadentries.h
*/

#include "StdAfx.h"
#include "defs.h"
#include "WadFile.h"
#include "doomlevel.h"
#include "wadentries.h"

// table of level entries
const char WAD_ENTRY_NAMES[10][9] =
{
	"THINGS",
	"LINEDEFS",
	"SIDEDEFS",
	"VERTEXES",
	"SEGS",
	"SSECTORS",
	"NODES",
	"SECTORS",
	"REJECT",
	"BLOCKMAP"
};

levelentries LookupLevelEntry(char *s)
{
	int i;

	if(strlen(s) == 4)
		if(s[0]=='E' && isdigit(s[1]) && s[2]=='M' && isdigit(s[3]))
			return(W_D1LEVEL);

	if(strlen(s) == 5)
		if(!strncmp(s,"MAP",3) && isdigit(s[3]) && isdigit(s[4]))
			return(W_D2LEVEL);

	for(i=0;i<NUM_LEVEL_ENTRIES;i++)
		if(!strncmp(s,WAD_ENTRY_NAMES[i],8))
			return(levelentries(i));

	return(W_NOT_LEVEL_ENTRY);
}

bool LoadLevelData(CWadFile &wadFile, level_t *level, char *szMap)
{
	char szTmp[9];
	levelentries le;
	int c = 0;

	if(!wadFile.SeekTo(szMap))
		return(false);

	do {
		if(!wadFile.SeekNext(szTmp))
			return(false);

		le = LookupLevelEntry(szTmp);
		switch(le) {
		case W_VERTEXES:
			level->n_vertices = wadFile.GetEntrySize() / sizeof(vertex_t);
			level->vertices = new vertex_t[level->n_vertices];
			wadFile.GetEntryData(level->vertices);
			c++;
			break;
		case W_LINEDEFS:
			level->n_linedefs = wadFile.GetEntrySize() / sizeof(linedef_t);
			level->linedefs = new linedef_t[level->n_linedefs];
			wadFile.GetEntryData(level->linedefs);
			c++;
			break;
		case W_SIDEDEFS:
			level->n_sidedefs = wadFile.GetEntrySize() / sizeof(sidedef_t);
			level->sidedefs = new sidedef_t[level->n_sidedefs];
			wadFile.GetEntryData(level->sidedefs);
			c++;
			break;
		case W_SECTORS:
			level->n_sectors = wadFile.GetEntrySize() / sizeof(sector_t);
			level->sectors = new sector_t[level->n_sectors];
			wadFile.GetEntryData(level->sectors);
			c++;
			break;
		case W_SEGS:
			level->n_segs = wadFile.GetEntrySize() / sizeof(segment_t);
			level->segs = new segment_t[level->n_segs];
			wadFile.GetEntryData(level->segs);
			c++;
			break;
		case W_SSECTORS:
			level->n_ssectors = wadFile.GetEntrySize() / sizeof(ssector_t);
			level->ssectors = new ssector_t[level->n_ssectors];
			wadFile.GetEntryData(level->ssectors);
			c++;
			break;
		case W_NODES:
			level->n_nodes = wadFile.GetEntrySize() / sizeof(node_t);
			level->nodes = new node_t[level->n_nodes];
			wadFile.GetEntryData(level->nodes);
			c++;
			break;
		case W_THINGS:
			level->n_things = wadFile.GetEntrySize() / sizeof(thing_t);
			level->things = new thing_t[level->n_things];
			wadFile.GetEntryData(level->things);
			c++;
			break;
		default:
			break;
		}
	} while(c < 8);

	return(true);
}

void LevelExtents(level_t *level)
{
	int i;
	short xmin = short(0x7FFF);
	short xmax = short(0x8000);
	short ymin = short(0x7FFF);
	short ymax = short(0x8000);

	// get max/min x/y
	for(i=0;i<level->n_vertices;i++) {
		xmin = min(xmin,level->vertices[i].x);
		xmax = max(xmax,level->vertices[i].x);
		ymin = min(ymin,level->vertices[i].y);
		ymax = max(ymax,level->vertices[i].y);
	}

	// calc height, width, x/y center
	level->l_width = xmax - xmin;
	level->l_height = ymax - ymin;
	level->x_center = xmin + level->l_width / 2;
	level->y_center = ymin + level->l_height / 2;
}

void InitLevel(level_t *l)
{
	memset(l,0,sizeof(level_t));
}

void CleanupLevel(level_t *l)
{
	if(l->linedefs != NULL)
		delete[] l->linedefs;
	if(l->nodes != NULL)
		delete[] l->nodes;
	if(l->sectors != NULL)
		delete[] l->sectors;
	if(l->segs != NULL)
		delete[] l->segs;
	if(l->sidedefs != NULL)
		delete[] l->sidedefs;
	if(l->ssectors != NULL)
		delete[] l->ssectors;
	if(l->vertices != NULL)
		delete[] l->vertices;
	if(l->things != NULL)
		delete[] l->things;

	memset(l,0,sizeof(level_t));
}

void DumpLevel(char *filename, level_t *l)
{
	FILE *f = fopen(filename,"w");
	int i;

	if(f == NULL)
		return;

	fprintf(f,"Level Dump\n----------\n");

	fprintf(f,"NODES\n-----\n");
	for(i=0;i<l->n_nodes;i++) {
		fprintf(f,"Node %d:\n",i);
		fprintf(f,"x = %d\n"
		"y = %d\n"
		"dx = %d\n"
		"dy = %d\n"
		"left_y_upper = %d\n"
		"left_y_lower = %d\n"
		"left_x_upper = %d\n"
		"left_x_lower = %d\n"
		"right_y_upper = %d\n"
		"right_y_lower = %d\n"
		"right_x_upper = %d\n"
		"right_x_lower = %d\n"
		"left_child = %d\n"
		"right_child = %d\n\n",
		l->nodes[i].x,l->nodes[i].y,
		l->nodes[i].dx,l->nodes[i].dy,
		l->nodes[i].left_y_upper,
		l->nodes[i].left_y_lower,
		l->nodes[i].left_x_upper,
		l->nodes[i].left_x_lower,
		l->nodes[i].right_y_upper,
		l->nodes[i].right_y_lower,
		l->nodes[i].right_x_upper,
		l->nodes[i].right_x_lower,
		l->nodes[i].left_child,
		l->nodes[i].right_child);
	}

	fprintf(f,"SSECTORS\n--------\n");
	for(i=0;i<l->n_ssectors;i++) {
		fprintf(f,"SSector %d:\n",i);
		fprintf(f,
			"numsegs = %d\n"
			"startseg = %d\n\n",
			l->ssectors[i].numsegs,
			l->ssectors[i].startseg);
	}

	fprintf(f,"SEGS\n----\n");
	for(i=0;i<l->n_segs;i++) {
		fprintf(f,"Seg %d:\n",i);
		fprintf(f,
			"from_vertex = %d\n"
			"to_vertex = %d\n"
			"angle = %d\n"
			"linedef = %d\n"
			"side = %d\n"
			"distance = %d\n",
			l->segs[i].from_vertex,
			l->segs[i].to_vertex,
			l->segs[i].angle,
			l->segs[i].linedef,
			l->segs[i].side,
			l->segs[i].distance);
	}

	fclose(f);
}

A wad2map/wadentries.h => wad2map/wadentries.h +60 -0
@@ 0,0 1,60 @@
/*
	Wad2Map v1.0
	(c) 2000 Ted Mielczarek
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    You can contact the author of this program at tam4@lehigh.edu
*/
/*
	wadentries.h

	Ted Mielczarek
	12/07/1999

  This file contains an enumeration of the different wad entry types.
 */

#ifndef __WADENTRIES_H_
#define __WADENTRIES_H_

typedef enum {
	W_THINGS		= 0,
	W_LINEDEFS	= 1,
	W_SIDEDEFS	= 2,
	W_VERTEXES	= 3,
	W_SEGS			= 4,
	W_SSECTORS	= 5,
	W_NODES			= 6,
	W_SECTORS		= 7,
	W_REJECT		= 8,
	W_BLOCKMAP	= 9,
	W_D1LEVEL,
	W_D2LEVEL,
	W_NOT_LEVEL_ENTRY
} levelentries;

extern const char WAD_ENTRY_NAMES[10][9];
#define NUM_LEVEL_ENTRIES 10

// lookup function
levelentries LookupLevelEntry(char *s);
bool LoadLevelData(CWadFile &wadFile, level_t *level, char *szMap);
void LevelExtents(level_t *level);
void InitLevel(level_t *l);
void CleanupLevel(level_t *l);
void DumpLevel(char *filename, level_t *l);

#endif /* __WADENTRIES_H_ */