1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: wadlib.cpp 4219 2010-04-19 22:11:41Z firebrand_kh $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 
26 // HEADER FILES ------------------------------------------------------------
27 
28 #include "cmdlib.h"
29 #include "wadlib.h"
30 
31 namespace VavoomUtils {
32 
33 #include "fwaddefs.h"
34 
35 // MACROS ------------------------------------------------------------------
36 
37 // TYPES -------------------------------------------------------------------
38 
39 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
40 
41 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
42 
43 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
44 
45 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
46 
47 // PUBLIC DATA DEFINITIONS -------------------------------------------------
48 
49 // PRIVATE DATA DEFINITIONS ------------------------------------------------
50 
51 // CODE --------------------------------------------------------------------
52 
53 //==========================================================================
54 //
55 //	TIWadFile::Open
56 //
57 //==========================================================================
58 
Open(const char * filename)59 void TIWadFile::Open(const char* filename)
60 {
61 	wadinfo_t		header;
62 	lumpinfo_t*		lump_p;
63 	int				i;
64 	filelump_t*		fileinfo;
65 	filelump_t*		fi_p;
66 
67 	handle = fopen(filename, "rb");
68 	if (!handle)
69 	{
70 		throw WadLibError(va("couldn't open %s", filename));
71 	}
72 
73 	fread(&header, 1, sizeof(header), handle);
74 	if (strncmp(header.identification, "IWAD", 4))
75 	{
76 		// Homebrew levels?
77 		if (strncmp(header.identification, "PWAD", 4))
78 		{
79 			throw WadLibError(va("Wad file %s doesn't have IWAD or PWAD id",
80 				filename));
81 		}
82 	}
83 	strcpy(wadid, header.identification);
84 
85 	numlumps = LittleLong(header.numlumps);
86 	lumpinfo = new lumpinfo_t[numlumps];
87 	fileinfo = new filelump_t[numlumps];
88 	fseek(handle, LittleLong(header.infotableofs), SEEK_SET);
89 	fread(fileinfo, 1, numlumps * sizeof(filelump_t), handle);
90 
91 	// Fill in lumpinfo
92 	lump_p = lumpinfo;
93 	fi_p = fileinfo;
94 	for (i = 0; i < numlumps; i++, lump_p++, fi_p++)
95 	{
96 		CleanupName(fi_p->name, lump_p->name);
97 		lump_p->position = LittleLong(fi_p->filepos);
98 		lump_p->size = LittleLong(fi_p->size);
99 	}
100 
101 	delete fileinfo;
102 	fileinfo = NULL;
103 }
104 
105 //==========================================================================
106 //
107 //	TIWadFile::LumpNumForName
108 //
109 //==========================================================================
110 
LumpNumForName(const char * name)111 int TIWadFile::LumpNumForName(const char* name)
112 {
113 	int			i;
114 	char		buf[12];
115 
116 	CleanupName(name, buf);
117 	for (i = numlumps - 1; i >= 0; i--)
118 	{
119 		if (!strcmp(buf, lumpinfo[i].name))
120 			return i;
121 	}
122 	throw WadLibError(va("W_GetNumForName: %s not found!", name));
123 }
124 
125 //==========================================================================
126 //
127 //	TIWadFile::GetLump
128 //
129 //==========================================================================
130 
GetLump(int lump)131 void* TIWadFile::GetLump(int lump)
132 {
133 	void*		ptr;
134 	lumpinfo_t*	l;
135 
136 	l = lumpinfo + lump;
137 
138 	ptr = Z_Malloc(l->size);
139 	fseek(handle, l->position, SEEK_SET);
140 	fread(ptr, 1, l->size, handle);
141 	return ptr;
142 }
143 
144 //==========================================================================
145 //
146 //	TIWadFile::Close
147 //
148 //==========================================================================
149 
Close()150 void TIWadFile::Close()
151 {
152 	fclose(handle);
153 	handle = NULL;
154 	delete lumpinfo;
155 	lumpinfo = NULL;
156 }
157 
158 //==========================================================================
159 //
160 //	TOWadFile::Open
161 //
162 //==========================================================================
163 
Open(const char * filename,const char * Awadid)164 void TOWadFile::Open(const char *filename, const char *Awadid)
165 {
166 	handle = fopen(filename, "wb");
167 	wadinfo_t	header;
168 	memset(&header, 0, sizeof(header));
169 	fwrite(&header, 1, sizeof(header), handle);
170 	lumpinfo = new lumpinfo_t[8 * 1024];
171 	strncpy(wadid, Awadid, 4);
172 	numlumps = 0;
173 }
174 
175 //==========================================================================
176 //
177 //	TOWadFile::AddLump
178 //
179 //==========================================================================
180 
AddLump(const char * name,const void * data,int size)181 void TOWadFile::AddLump(const char *name, const void *data, int size)
182 {
183 	CleanupName(name, lumpinfo[numlumps].name);
184 	lumpinfo[numlumps].size = size;
185 	lumpinfo[numlumps].position = ftell(handle);
186 	if (size)
187 	{
188 		fwrite(data, 1, size, handle);
189 	}
190 	numlumps++;
191 }
192 
193 //==========================================================================
194 //
195 //	TOWadFile::Close
196 //
197 //==========================================================================
198 
Close()199 void TOWadFile::Close()
200 {
201 	wadinfo_t	header;
202 	strcpy(header.identification, wadid);
203 	header.numlumps = LittleLong(numlumps);
204 	header.infotableofs = LittleLong(ftell(handle));
205 	for (int i = 0; i < numlumps; i++)
206 	{
207 		filelump_t	fileinfo;
208 		strncpy(fileinfo.name, lumpinfo[i].name, 8);
209 		fileinfo.size = LittleLong(lumpinfo[i].size);
210 		fileinfo.filepos = LittleLong(lumpinfo[i].position);
211 		fwrite(&fileinfo, 1, sizeof(fileinfo), handle);
212 	}
213 	fseek(handle, 0, SEEK_SET);
214 	fwrite(&header, 1, sizeof(header), handle);
215 	fclose(handle);
216 	handle = NULL;
217 	delete lumpinfo;
218 	lumpinfo = NULL;
219 }
220 
221 } // namespace VavoomUtils
222