DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
wad.c
Go to the documentation of this file.
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20
21
22#include "quakedef.h"
23#include "image.h"
24#include "wad.h"
25
26typedef struct mwad_s
27{
28 qfile_t *file;
31}
32mwad_t;
33
34typedef struct wadstate_s
35{
36 unsigned char *gfx_base;
39}
41
43
44/*
45==================
46W_CleanupName
47
48Lowercases name and pads with spaces and a terminating 0 to the length of
49lumpinfo_t->name.
50Used so lumpname lookups can proceed rapidly by comparing 4 chars at a time
51Space padding is so names can be printed nicely in tables.
52Can safely be performed in place.
53==================
54*/
55static void W_CleanupName (const char *in, char *out)
56{
57 int i;
58 int c;
59
60 for (i=0 ; i<16 ; i++ )
61 {
62 c = in[i];
63 if (!c)
64 break;
65
66 if (c >= 'A' && c <= 'Z')
67 c += ('a' - 'A');
68 out[i] = c;
69 }
70
71 for ( ; i< 16 ; i++ )
72 out[i] = 0;
73}
74
75static void W_SwapLumps(int numlumps, lumpinfo_t *lumps)
76{
77 int i;
78 for (i = 0;i < numlumps;i++)
79 {
80 lumps[i].filepos = LittleLong(lumps[i].filepos);
81 lumps[i].disksize = LittleLong(lumps[i].disksize);
82 lumps[i].size = LittleLong(lumps[i].size);
83 W_CleanupName(lumps[i].name, lumps[i].name);
84 }
85}
86
87void W_UnloadAll(void)
88{
89 unsigned int i;
90 mwad_t *w;
91 // free gfx.wad if it is loaded
92 if (wad.gfx_base)
95 // close all hlwad files and free their lumps data
97 {
99 if (!w)
100 continue;
101 if (w->file)
102 FS_Close(w->file);
103 w->file = NULL;
104 if (w->lumps)
105 Mem_Free(w->lumps);
106 w->lumps = NULL;
107 }
108 // free the hlwads array
110 // clear all state
111 memset(&wad, 0, sizeof(wad));
112}
113
114unsigned char *W_GetLumpName(const char *name, fs_offset_t *returnfilesize)
115{
116 int i;
117 fs_offset_t filesize;
118 lumpinfo_t *lump;
119 char clean[16];
120 wadinfo_t *header;
121 int infotableofs;
122
123 W_CleanupName (name, clean);
124
125 if (!wad.gfx_base)
126 {
127 if ((wad.gfx_base = FS_LoadFile ("gfx.wad", cls.permanentmempool, false, &filesize)))
128 {
129 if (memcmp(wad.gfx_base, "WAD2", 4))
130 {
131 Con_Print("gfx.wad doesn't have WAD2 id\n");
133 wad.gfx_base = NULL;
134 }
135 else
136 {
137 header = (wadinfo_t *)wad.gfx_base;
139 infotableofs = LittleLong(header->infotableofs);
140 wad.gfx.lumps = (lumpinfo_t *)(wad.gfx_base + infotableofs);
141
142 // byteswap the gfx.wad lumps in place
144 }
145 }
146 }
147
148 for (lump = wad.gfx.lumps, i = 0;i < wad.gfx.numlumps;i++, lump++)
149 {
150 if (!strcmp(clean, lump->name))
151 {
152 if (returnfilesize)
153 *returnfilesize = lump->size;
154 return (wad.gfx_base + lump->filepos);
155 }
156 }
157 return NULL;
158}
159
160/*
161====================
162W_LoadTextureWadFile
163====================
164*/
165void W_LoadTextureWadFile (char *filename, int complain)
166{
167 wadinfo_t header;
168 int infotableofs;
169 qfile_t *file;
170 int numlumps;
171 mwad_t *w;
172
173 file = FS_OpenVirtualFile(filename, false);
174 if (!file)
175 {
176 if (complain)
177 Con_Printf(CON_ERROR "W_LoadTextureWadFile: couldn't find %s\n", filename);
178 return;
179 }
180
181 if (FS_Read(file, &header, sizeof(wadinfo_t)) != sizeof(wadinfo_t))
182 {Con_Print(CON_ERROR "W_LoadTextureWadFile: unable to read wad header\n");FS_Close(file);file = NULL;return;}
183
184 if(memcmp(header.identification, "WAD3", 4))
185 {Con_Printf(CON_ERROR "W_LoadTextureWadFile: Wad file %s doesn't have WAD3 id\n",filename);FS_Close(file);file = NULL;return;}
186
187 numlumps = LittleLong(header.numlumps);
188 if (numlumps < 1 || numlumps > 65536)
189 {Con_Printf(CON_ERROR "W_LoadTextureWadFile: invalid number of lumps (%i)\n", numlumps);FS_Close(file);file = NULL;return;}
190 infotableofs = LittleLong(header.infotableofs);
191 if (FS_Seek (file, infotableofs, SEEK_SET))
192 {Con_Print(CON_ERROR "W_LoadTextureWadFile: unable to seek to lump table\n");FS_Close(file);file = NULL;return;}
193
194 if (!wad.hlwads.mempool)
197 w->file = file;
198 w->numlumps = numlumps;
199 w->lumps = (lumpinfo_t *) Mem_Alloc(cls.permanentmempool, w->numlumps * sizeof(lumpinfo_t));
200
201 if (!w->lumps)
202 {
203 Con_Print(CON_ERROR "W_LoadTextureWadFile: unable to allocate temporary memory for lump table\n");
204 FS_Close(w->file);
205 w->file = NULL;
206 w->numlumps = 0;
207 return;
208 }
209
210 if (FS_Read(file, w->lumps, sizeof(lumpinfo_t) * w->numlumps) != (fs_offset_t)sizeof(lumpinfo_t) * numlumps)
211 {
212 Con_Print(CON_ERROR "W_LoadTextureWadFile: unable to read lump table\n");
213 FS_Close(w->file);
214 w->file = NULL;
215 w->numlumps = 0;
216 Mem_Free(w->lumps);
217 w->lumps = NULL;
218 return;
219 }
220
221 W_SwapLumps(w->numlumps, w->lumps);
222
223 // leaves the file open
224}
225
227{
228 unsigned char *in, *data, *out, *pal;
229 int d, p;
230 unsigned char name[16];
231 unsigned int mipoffset[4];
232
234 MSG_ReadBytes(sb, 16, name);
237 mipoffset[0] = MSG_ReadLittleLong(sb);
238 mipoffset[1] = MSG_ReadLittleLong(sb); // should be mipoffset[0] + image_width*image_height
239 mipoffset[2] = MSG_ReadLittleLong(sb); // should be mipoffset[1] + image_width*image_height/4
240 mipoffset[3] = MSG_ReadLittleLong(sb); // should be mipoffset[2] + image_width*image_height/16
241 pal = sb->data + mipoffset[3] + (image_width / 8 * image_height / 8) + 2;
242
243 // bail if any data looks wrong
244 if (image_width < 0
245 || image_width > 4096
246 || image_height < 0
247 || image_height > 4096
248 || mipoffset[0] != 40
249 || mipoffset[1] != mipoffset[0] + image_width * image_height
250 || mipoffset[2] != mipoffset[1] + image_width / 2 * image_height / 2
251 || mipoffset[3] != mipoffset[2] + image_width / 4 * image_height / 4
252 || (unsigned int)sb->cursize < (mipoffset[3] + image_width / 8 * image_height / 8 + 2 + 768))
253 return NULL;
254
255 in = (unsigned char *)sb->data + mipoffset[0];
256 data = out = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
257 if (!data)
258 return NULL;
259 for (d = 0;d < image_width * image_height;d++)
260 {
261 p = *in++;
262 if (name[0] == '{' && p == 255)
263 out[0] = out[1] = out[2] = out[3] = 0;
264 else
265 {
266 p *= 3;
267 out[2] = pal[p];
268 out[1] = pal[p+1];
269 out[0] = pal[p+2];
270 out[3] = 255;
271 }
272 out += 4;
273 }
274 return data;
275}
276
277unsigned char *W_GetTextureBGRA(char *name)
278{
279 unsigned int i, k;
280 sizebuf_t sb;
281 unsigned char *data;
282 mwad_t *w;
283 char texname[17];
284 size_t range;
285
286 texname[16] = 0;
287 W_CleanupName(name, texname);
288 if (!wad.hlwads.mempool)
291 for (k = 0;k < range;k++)
292 {
294 if (!w)
295 continue;
296 for (i = 0;i < (unsigned int)w->numlumps;i++)
297 {
298 if (!strcmp(texname, w->lumps[i].name)) // found it
299 {
300 if (FS_Seek(w->file, w->lumps[i].filepos, SEEK_SET))
301 {Con_Print("W_GetTexture: corrupt WAD3 file\n");return NULL;}
302
303 MSG_InitReadBuffer(&sb, (unsigned char *)Mem_Alloc(tempmempool, w->lumps[i].disksize), w->lumps[i].disksize);
304 if (!sb.data)
305 return NULL;
306 if (FS_Read(w->file, sb.data, w->lumps[i].size) < w->lumps[i].disksize)
307 {Con_Print("W_GetTexture: corrupt WAD3 file\n");return NULL;}
308
310 Mem_Free(sb.data);
311 return data;
312 }
313 }
314 }
316 return NULL;
317}
318
client_static_t cls
Definition cl_main.c:116
void MSG_BeginReading(sizebuf_t *sb)
Definition com_msg.c:257
size_t MSG_ReadBytes(sizebuf_t *sb, size_t numbytes, unsigned char *out)
Definition com_msg.c:364
void MSG_InitReadBuffer(sizebuf_t *buf, unsigned char *data, int size)
Definition com_msg.c:249
int MSG_ReadLittleLong(sizebuf_t *sb)
Definition com_msg.c:285
#define LittleLong(l)
Definition common.h:92
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define CON_ERROR
Definition console.h:102
vector size
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
Definition fs.c:3066
qfile_t * FS_OpenVirtualFile(const char *filepath, qbool quiet)
Definition fs.c:2928
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
int FS_Seek(qfile_t *file, fs_offset_t offset, int whence)
Definition fs.c:3359
static int(ZEXPORT *qz_inflate)(z_stream *strm
int FS_Close(qfile_t *file)
Definition fs.c:2970
int64_t fs_offset_t
Definition fs.h:37
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
GLsizeiptr const GLvoid * data
Definition glquake.h:639
const GLchar * name
Definition glquake.h:601
int image_height
Definition image.c:10
int image_width
Definition image.c:9
int i
#define NULL
Definition qtypes.h:12
mempool_t * permanentmempool
Definition client.h:572
int disksize
Definition wad.h:63
int filepos
Definition wad.h:62
char name[16]
Definition wad.h:68
int size
Definition wad.h:64
mempool_t * mempool
Definition zone.h:137
Definition wad.c:27
lumpinfo_t * lumps
Definition wad.c:30
int numlumps
Definition wad.c:29
qfile_t * file
Definition wad.c:28
unsigned char * data
Definition common.h:52
int cursize
Definition common.h:54
int numlumps
Definition wad.h:56
int infotableofs
Definition wad.h:57
char identification[4]
Definition wad.h:55
memexpandablearray_t hlwads
Definition wad.c:38
mwad_t gfx
Definition wad.c:37
unsigned char * gfx_base
Definition wad.c:36
unsigned char * W_GetLumpName(const char *name, fs_offset_t *returnfilesize)
Definition wad.c:114
static wadstate_t wad
Definition wad.c:42
void W_LoadTextureWadFile(char *filename, int complain)
Definition wad.c:165
unsigned char * W_GetTextureBGRA(char *name)
Definition wad.c:277
static void W_SwapLumps(int numlumps, lumpinfo_t *lumps)
Definition wad.c:75
unsigned char * W_ConvertWAD3TextureBGRA(sizebuf_t *sb)
Definition wad.c:226
static void W_CleanupName(const char *in, char *out)
Definition wad.c:55
void W_UnloadAll(void)
Definition wad.c:87
size_t Mem_ExpandableArray_IndexRange(const memexpandablearray_t *l)
Definition zone.c:763
void Mem_ExpandableArray_NewArray(memexpandablearray_t *l, mempool_t *mempool, size_t recordsize, int numrecordsperarray)
Definition zone.c:675
void * Mem_ExpandableArray_AllocRecord(memexpandablearray_t *l)
Definition zone.c:695
void * Mem_ExpandableArray_RecordAtIndex(const memexpandablearray_t *l, size_t index)
Definition zone.c:780
mempool_t * tempmempool
Definition zone.c:794
void Mem_ExpandableArray_FreeArray(memexpandablearray_t *l)
Definition zone.c:683
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92