Subversion Repositories Kolibri OS

Rev

Rev 298 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 serge 1
// Emacs style mode select   -*- C++ -*-
2
//-----------------------------------------------------------------------------
3
//
4
// $Id:$
5
//
6
// Copyright (C) 1993-1996 by id Software, Inc.
7
//
8
// This source is available for distribution and/or modification
9
// only under the terms of the DOOM Source Code License as
10
// published by id Software. All rights reserved.
11
//
12
// The source is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15
// for more details.
16
//
17
// $Log:$
18
//
19
// DESCRIPTION:
20
//	Handles WAD file header, directory, lump I/O.
21
//
22
//-----------------------------------------------------------------------------
23
 
24
 
25
static const char
26
rcsid[] = "$Id: w_wad.c,v 1.5 1997/02/03 16:47:57 b1 Exp $";
27
 
28
 
29
#include 
30
#include 
31
#include 
32
#include 
33
 
34
#include "m_swap.h"
35
#include "doomtype.h"
36
#include "i_system.h"
37
#include "z_zone.h"
38
#include "w_wad.h"
39
 
40
#include 
41
 
42
 
43
//
44
// GLOBALS
45
//
46
 
47
// Location of each lump on disk.
48
lumpinfo_t*		lumpinfo;
49
int			numlumps;
50
 
51
void**			lumpcache;
52
 
53
 
54
int filelength (FILE *handle)
55
{
56
    unsigned long pos, size;
57
 
58
    pos = ftell(handle);
59
    fseek(handle, 0, SEEK_END);
60
    size = ftell(handle);
61
    fseek(handle, pos, SEEK_SET);
62
    return (int)size;
63
}
64
 
65
 
66
void
67
ExtractFileBase
68
( char*		path,
69
  char*		dest )
70
{
71
    char*	src;
72
    int		length;
73
 
74
    src = path + strlen(path) - 1;
75
 
76
    // back up until a \ or the start
77
    while (src != path
78
	   && *(src-1) != '\\'
79
	   && *(src-1) != '/')
80
    {
81
	src--;
82
    }
83
 
84
    // copy up to eight characters
85
    memset (dest,0,8);
86
    length = 0;
87
 
88
    while (*src && *src != '.')
89
    {
90
	if (++length == 9)
91
	    I_Error ("Filename base of %s >8 chars",path);
92
 
93
	*dest++ = toupper((int)*src++);
94
    }
95
}
96
 
97
 
98
 
99
 
100
 
101
//
102
// LUMP BASED ROUTINES.
103
//
104
 
105
//
106
// W_AddFile
107
// All files are optional, but at least one file must be
108
//  found (PWAD, if all required lumps are present).
109
// Files with a .wad extension are wadlink files
110
//  with multiple lumps.
111
// Other files are single lumps with the base filename
112
//  for the lump name.
113
//
114
// If filename starts with a tilde, the file is handled
115
//  specially to allow map reloads.
116
// But: the reload feature is a fragile hack...
117
 
118
#ifdef __BEOS__
119
#ifdef __GNUC__
120
extern void *alloca(int);
121
#else
122
#include 
123
#endif
124
#endif /* __BEOS__ */
125
 
126
int			reloadlump;
127
char*			reloadname;
128
 
129
 
130
void W_AddFile (char *filename)
131
{
132
    wadinfo_t		header;
133
    lumpinfo_t*		lump_p;
134
    unsigned		i;
135
    FILE	       *handle;
136
    int			length;
137
    int			startlump;
138
    filelump_t*		fileinfo;
139
    filelump_t		singleinfo;
140
    int			storehandle;
141
 
142
    // open the file and add to directory
143
 
144
    // handle reload indicator.
145
    if (filename[0] == '~')
146
    {
147
	filename++;
148
	reloadname = filename;
149
	reloadlump = numlumps;
150
    }
151
 
152
    if ( (handle = fopen (filename,"rb")) == NULL)
153
    {
154
      printf (" couldn't open %s\n",filename);
155
	return;
156
    }
157
 
158
    printf (" adding %s\n",filename);
159
    startlump = numlumps;
160
 
161
    if (I_strncasecmp (filename+strlen(filename)-3 , "wad", 3 ) )
162
    {
163
	// single lump file
164
	fileinfo = &singleinfo;
165
	singleinfo.filepos = 0;
166
	singleinfo.size = LONG(filelength(handle));
167
	ExtractFileBase (filename, singleinfo.name);
168
	numlumps++;
169
    }
170
    else
171
    {
172
	 //WAD file
173
	printf("f1 at %x,%u\n",&header,handle);
174
	fread (&header, 1, sizeof(header), handle);
175
    printf("f2\n");
176
	if (strncmp(header.identification,"IWAD",4))
177
	{
178
	    printf("No IWAD id\n");
179
	    // Homebrew levels?
180
	    if (strncmp(header.identification,"PWAD",4))
181
	    {
182
		I_Error ("Wad file %s doesn't have IWAD "
183
			 "or PWAD id\n", filename);
184
	    }
185
//	    printf("WAD magic OK\n");
186
	    // ???modifiedgame = true;
187
	}
188
	printf("after checking hdr\n");
189
	header.numlumps = LONG(header.numlumps);
190
    printf("%u lumps in WAD\n",header.numlumps);
191
	header.infotableofs = LONG(header.infotableofs);
192
    printf("infor table at %x\n",header.infotableofs);
193
	length = header.numlumps*sizeof(filelump_t);
194
    printf("length %u\n",length);
195
	fileinfo = alloca(length);
196
 
197
    printf("seeking to info table\n");
198
	fseek (handle, header.infotableofs, SEEK_SET);
199
    printf("f3\n");
200
	fread (fileinfo, 1, length, handle);
201
    printf("f4\n");
202
	numlumps += header.numlumps;
203
    }
204
 
205
 
206
    // Fill in lumpinfo
207
    lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
208
 
209
    if (!lumpinfo)
210
	I_Error ("Couldn't realloc lumpinfo");
211
 
212
    lump_p = &lumpinfo[startlump];
213
 
214
    storehandle = reloadname ? -1 : (int)handle;
215
 
216
    for (i=startlump ; i
217
    {
218
	lump_p->handle = storehandle;
219
	lump_p->position = LONG(fileinfo->filepos);
220
	lump_p->size = LONG(fileinfo->size);
221
	strncpy (lump_p->name, fileinfo->name, 8);
222
    }
223
 
224
    if (reloadname)
225
	fclose (handle);
226
}
227
 
228
 
229
 
230
 
231
//
232
// W_Reload
233
// Flushes any of the reloadable lumps in memory
234
//  and reloads the directory.
235
//
236
void W_Reload (void)
237
{
238
    wadinfo_t		header;
239
    int			lumpcount;
240
    lumpinfo_t*		lump_p;
241
    unsigned		i;
242
    FILE		*handle;
243
    int			length;
244
    filelump_t*		fileinfo;
245
 
246
    if (!reloadname)
247
	return;
248
 
249
    if ( (handle = fopen (reloadname,"rb")) == NULL)
250
	I_Error ("W_Reload: couldn't open %s",reloadname);
251
 
252
    printf("f5\n");
253
    fread (&header, 1, sizeof(header), handle);
254
    printf("f6\n");
255
    lumpcount = LONG(header.numlumps);
256
    header.infotableofs = LONG(header.infotableofs);
257
    length = lumpcount*sizeof(filelump_t);
258
    fileinfo = malloc (length);
259
    fseek (handle, header.infotableofs, SEEK_SET);
260
    printf("f7\n");
261
    fread (fileinfo, 1, length, handle);
262
    printf("f8\n");
263
 
264
    // Fill in lumpinfo
265
    lump_p = &lumpinfo[reloadlump];
266
 
267
    for (i=reloadlump ;
268
	 i
269
	 i++,lump_p++, fileinfo++)
270
    {
271
	if (lumpcache[i])
272
	    Z_Free (lumpcache[i]);
273
 
274
	lump_p->position = LONG(fileinfo->filepos);
275
	lump_p->size = LONG(fileinfo->size);
276
    }
277
 
278
    fclose (handle);
279
}
280
 
281
 
282
 
283
//
284
// W_InitMultipleFiles
285
// Pass a null terminated list of files to use.
286
// All files are optional, but at least one file
287
//  must be found.
288
// Files with a .wad extension are idlink files
289
//  with multiple lumps.
290
// Other files are single lumps with the base filename
291
//  for the lump name.
292
// Lump names can appear multiple times.
293
// The name searcher looks backwards, so a later file
294
//  does override all earlier ones.
295
//
296
void W_InitMultipleFiles (char** filenames)
297
{
298
    int		size;
299
 
300
    // open all the files, load headers, and count lumps
301
    numlumps = 0;
302
 
303
    // will be realloced as lumps are added
304
    lumpinfo = malloc(1);
305
 
306
    for ( ; *filenames ; filenames++)
307
	W_AddFile (*filenames);
308
 
309
    if (!numlumps)
310
	I_Error ("W_InitFiles: no files found");
311
 
312
    // set up caching
313
    size = numlumps * sizeof(*lumpcache);
314
    lumpcache = malloc (size);
315
 
316
    if (!lumpcache)
317
	I_Error ("Couldn't allocate lumpcache");
318
 
319
    memset (lumpcache,0, size);
320
}
321
 
322
 
323
 
324
 
325
//
326
// W_InitFile
327
// Just initialize from a single file.
328
//
329
void W_InitFile (char* filename)
330
{
331
    char*	names[2];
332
 
333
    names[0] = filename;
334
    names[1] = NULL;
335
    W_InitMultipleFiles (names);
336
}
337
 
338
 
339
 
340
//
341
// W_NumLumps
342
//
343
int W_NumLumps (void)
344
{
345
    return numlumps;
346
}
347
 
348
 
349
 
350
//
351
// W_CheckNumForName
352
// Returns -1 if name not found.
353
//
354
 
355
int W_CheckNumForName (char* name)
356
{
357
    union {
358
	char	s[9];
359
	int	x[2];
360
 
361
    } name8;
362
 
363
    int		v1;
364
    int		v2;
365
    lumpinfo_t*	lump_p;
366
 
367
    // make the name into two integers for easy compares
368
    strncpy (name8.s,name,8);
369
 
370
    // in case the name was a fill 8 chars
371
    name8.s[8] = 0;
372
 
373
    // case insensitive
374
    strupr (name8.s);
375
 
376
    v1 = name8.x[0];
377
    v2 = name8.x[1];
378
 
379
 
380
    // scan backwards so patch lump files take precedence
381
    lump_p = lumpinfo + numlumps;
382
 
383
    while (lump_p-- != lumpinfo)
384
    {
385
	if ( *(int *)lump_p->name == v1
386
	     && *(int *)&lump_p->name[4] == v2)
387
	{
388
	    return lump_p - lumpinfo;
389
	}
390
    }
391
 
392
    // TFB. Not found.
393
    return -1;
394
}
395
 
396
 
397
 
398
 
399
//
400
// W_GetNumForName
401
// Calls W_CheckNumForName, but bombs out if not found.
402
//
403
int W_GetNumForName (char* name)
404
{
405
    int	i;
406
 
407
    i = W_CheckNumForName (name);
408
 
409
    if (i == -1)
410
      I_Error ("W_GetNumForName: %s not found!", name);
411
 
412
    return i;
413
}
414
 
415
 
416
//
417
// W_LumpLength
418
// Returns the buffer size needed to load the given lump.
419
//
420
int W_LumpLength (int lump)
421
{
422
    if (lump >= numlumps)
423
	I_Error ("W_LumpLength: %i >= numlumps",lump);
424
 
425
    return lumpinfo[lump].size;
426
}
427
 
428
 
429
 
430
//
431
// W_ReadLump
432
// Loads the lump into the given buffer,
433
//  which must be >= W_LumpLength().
434
//
435
void
436
W_ReadLump
437
( int		lump,
438
  void*		dest )
439
{
440
    int		c;
441
    lumpinfo_t*	l;
442
    FILE	*handle;
443
 
444
    if (lump >= numlumps)
445
	I_Error ("W_ReadLump: %i >= numlumps",lump);
446
 
447
    l = lumpinfo+lump;
448
 
449
    // ??? I_BeginRead ();
450
 
451
    if (l->handle == -1)
452
    {
453
	// reloadable file, so use open / read / close
454
	if ( (handle = fopen (reloadname,"rb")) == NULL)
455
	    I_Error ("W_ReadLump: couldn't open %s",reloadname);
456
    }
457
    else
458
	handle = (FILE *)l->handle;
459
 
460
    fseek (handle, l->position, SEEK_SET);
461
    c = fread (dest, 1, l->size, handle);
462
    if (c < l->size)
463
	I_Error ("W_ReadLump: only read %i of %i on lump %i",
464
		 c,l->size,lump);
465
 
466
    if (l->handle == -1)
467
	fclose (handle);
468
 
469
    // ??? I_EndRead ();
470
}
471
 
472
 
473
 
474
 
475
//
476
// W_CacheLumpNum
477
//
478
void*
479
W_CacheLumpNum
480
( int		lump,
481
  int		tag )
482
{
483
    byte*	ptr;
484
 
485
    if ((unsigned)lump >= numlumps)
486
	I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
487
 
488
    if (!lumpcache[lump])
489
    {
490
	// read the lump in
491
 
492
	//printf ("cache miss on lump %i\n",lump);
493
	ptr = Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
494
	W_ReadLump (lump, lumpcache[lump]);
495
    }
496
    else
497
    {
498
	//printf ("cache hit on lump %i\n",lump);
499
	Z_ChangeTag (lumpcache[lump],tag);
500
    }
501
 
502
    return lumpcache[lump];
503
}
504
 
505
 
506
 
507
//
508
// W_CacheLumpName
509
//
510
void*
511
W_CacheLumpName
512
( char*		name,
513
  int		tag )
514
{
515
    return W_CacheLumpNum (W_GetNumForName(name), tag);
516
}
517
 
300 serge 518
#if 0
298 serge 519
 
520
//
521
// W_Profile
522
//
523
int		info[2500][10];
524
int		profilecount;
525
 
526
void W_Profile (void)
527
{
528
    int		i;
529
    memblock_t*	block;
530
    void*	ptr;
531
    char	ch;
532
    FILE*	f;
533
    int		j;
534
    char	name[9];
535
 
536
 
537
    for (i=0 ; i
538
    {
539
	ptr = lumpcache[i];
540
	if (!ptr)
541
	{
542
	    ch = ' ';
543
	    continue;
544
	}
545
	else
546
	{
547
	    block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
548
	    if (block->tag < PU_PURGELEVEL)
549
		ch = 'S';
550
	    else
551
		ch = 'P';
552
	}
553
	info[i][profilecount] = ch;
554
    }
555
    profilecount++;
556
 
557
    f = fopen ("waddump.txt","w");
558
    name[8] = 0;
559
 
560
    for (i=0 ; i
561
    {
562
	memcpy (name,lumpinfo[i].name,8);
563
 
564
	for (j=0 ; j<8 ; j++)
565
	    if (!name[j])
566
		break;
567
 
568
	for ( ; j<8 ; j++)
569
	    name[j] = ' ';
570
 
300 serge 571
	printf ("%s ",name);
298 serge 572
 
573
	for (j=0 ; j
574
	    fprintf (f,"    %c",info[i][j]);
575
 
300 serge 576
	printf ("\n");
298 serge 577
    }
578
    fclose (f);
579
}
580
 
300 serge 581
#endif