[docs] Replace cyrillic 'с' with latin 'c' in register names
[kolibrios.git] / contrib / other / sdldoom-1.10 / w_wad.c
blob768a927cfc28d9bfbb5c1249a03a350407e6859c
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.
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.
17 // $Log:$
19 // DESCRIPTION:
20 // Handles WAD file header, directory, lump I/O.
22 //-----------------------------------------------------------------------------
25 static const char
26 rcsid[] = "$Id: w_wad.c,v 1.5 1997/02/03 16:47:57 b1 Exp $";
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <ctype.h>
34 #include "m_swap.h"
35 #include "doomtype.h"
36 #include "i_system.h"
37 #include "z_zone.h"
39 #ifdef __GNUG__
40 #pragma implementation "w_wad.h"
41 #endif
42 #include "w_wad.h"
50 // GLOBALS
53 // Location of each lump on disk.
54 lumpinfo_t* lumpinfo;
55 int numlumps;
57 void** lumpcache;
60 #if defined(linux) || defined(__BEOS__) || defined(__SVR4)
61 void strupr (char* s)
63 while (*s) { *s = toupper(*s); s++; }
65 #endif
67 int filelength (FILE *handle)
69 unsigned long pos, size;
71 pos = ftell(handle);
72 printf("Position was %lu\n", pos);
73 fseek(handle, 0, SEEK_END);
74 size = ftell(handle);
75 fseek(handle, pos, SEEK_SET);
76 printf("Size is %lu\n", size);
78 return (int)size;
82 void
83 ExtractFileBase
84 ( char* path,
85 char* dest )
87 char* src;
88 int length;
90 src = path + strlen(path) - 1;
92 // back up until a \ or the start
93 while (src != path
94 && *(src-1) != '\\'
95 && *(src-1) != '/')
97 src--;
100 // copy up to eight characters
101 memset (dest,0,8);
102 length = 0;
104 while (*src && *src != '.')
106 if (++length == 9)
107 I_Error ("Filename base of %s >8 chars",path);
109 *dest++ = toupper((int)*src++);
118 // LUMP BASED ROUTINES.
122 // W_AddFile
123 // All files are optional, but at least one file must be
124 // found (PWAD, if all required lumps are present).
125 // Files with a .wad extension are wadlink files
126 // with multiple lumps.
127 // Other files are single lumps with the base filename
128 // for the lump name.
130 // If filename starts with a tilde, the file is handled
131 // specially to allow map reloads.
132 // But: the reload feature is a fragile hack...
134 #ifdef __BEOS__
135 #ifdef __GNUC__
136 extern void *alloca(int);
137 #else
138 #include <alloca.h>
139 #endif
140 #endif /* __BEOS__ */
142 int reloadlump;
143 char* reloadname;
146 void W_AddFile (char *filename)
148 wadinfo_t header;
149 lumpinfo_t* lump_p;
150 unsigned i;
151 FILE *handle;
152 int length;
153 int startlump;
154 filelump_t* fileinfo;
155 filelump_t singleinfo;
156 int storehandle;
158 // open the file and add to directory
160 // handle reload indicator.
161 if (filename[0] == '~')
163 filename++;
164 reloadname = filename;
165 reloadlump = numlumps;
168 if ( (handle = fopen (filename,"rb")) == NULL)
170 printf (" couldn't open %s\n",filename);
171 return;
174 printf (" adding %s\n",filename);
175 startlump = numlumps;
177 if (I_strncasecmp (filename+strlen(filename)-3 , "wad", 3 ) )
179 // single lump file
180 fileinfo = &singleinfo;
181 singleinfo.filepos = 0;
182 singleinfo.size = LONG(filelength(handle));
183 ExtractFileBase (filename, singleinfo.name);
184 numlumps++;
186 else
188 // WAD file
189 fread (&header, 1, sizeof(header), handle);
190 if (strncmp(header.identification,"IWAD",4))
192 // Homebrew levels?
193 if (strncmp(header.identification,"PWAD",4))
195 I_Error ("Wad file %s doesn't have IWAD "
196 "or PWAD id\n", filename);
199 // ???modifiedgame = true;
201 header.numlumps = LONG(header.numlumps);
202 header.infotableofs = LONG(header.infotableofs);
203 length = header.numlumps*sizeof(filelump_t);
204 fileinfo = alloca (length);
205 fseek (handle, header.infotableofs, SEEK_SET);
206 fread (fileinfo, 1, length, handle);
207 numlumps += header.numlumps;
211 // Fill in lumpinfo
212 lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
214 if (!lumpinfo)
215 I_Error ("Couldn't realloc lumpinfo");
217 lump_p = &lumpinfo[startlump];
219 storehandle = reloadname ? -1 : (int)handle;
221 for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
223 lump_p->handle = storehandle;
224 lump_p->position = LONG(fileinfo->filepos);
225 lump_p->size = LONG(fileinfo->size);
226 strncpy (lump_p->name, fileinfo->name, 8);
229 if (reloadname)
230 fclose (handle);
237 // W_Reload
238 // Flushes any of the reloadable lumps in memory
239 // and reloads the directory.
241 void W_Reload (void)
243 wadinfo_t header;
244 int lumpcount;
245 lumpinfo_t* lump_p;
246 unsigned i;
247 FILE *handle;
248 int length;
249 filelump_t* fileinfo;
251 if (!reloadname)
252 return;
254 if ( (handle = fopen (reloadname,"rb")) == NULL)
255 I_Error ("W_Reload: couldn't open %s",reloadname);
257 fread (&header, 1, sizeof(header), handle);
258 lumpcount = LONG(header.numlumps);
259 header.infotableofs = LONG(header.infotableofs);
260 length = lumpcount*sizeof(filelump_t);
261 fileinfo = alloca (length);
262 fseek (handle, header.infotableofs, SEEK_SET);
263 fread (fileinfo, 1, length, handle);
265 // Fill in lumpinfo
266 lump_p = &lumpinfo[reloadlump];
268 for (i=reloadlump ;
269 i<reloadlump+lumpcount ;
270 i++,lump_p++, fileinfo++)
272 if (lumpcache[i])
273 Z_Free (lumpcache[i]);
275 lump_p->position = LONG(fileinfo->filepos);
276 lump_p->size = LONG(fileinfo->size);
279 fclose (handle);
285 // W_InitMultipleFiles
286 // Pass a null terminated list of files to use.
287 // All files are optional, but at least one file
288 // must be found.
289 // Files with a .wad extension are idlink files
290 // with multiple lumps.
291 // Other files are single lumps with the base filename
292 // for the lump name.
293 // Lump names can appear multiple times.
294 // The name searcher looks backwards, so a later file
295 // does override all earlier ones.
297 void W_InitMultipleFiles (char** filenames)
299 int size;
301 // open all the files, load headers, and count lumps
302 numlumps = 0;
304 // will be realloced as lumps are added
305 lumpinfo = malloc(1);
307 for ( ; *filenames ; filenames++)
308 W_AddFile (*filenames);
310 if (!numlumps)
311 I_Error ("W_InitFiles: no files found");
313 // set up caching
314 size = numlumps * sizeof(*lumpcache);
315 lumpcache = malloc (size);
317 if (!lumpcache)
318 I_Error ("Couldn't allocate lumpcache");
320 memset (lumpcache,0, size);
327 // W_InitFile
328 // Just initialize from a single file.
330 void W_InitFile (char* filename)
332 char* names[2];
334 names[0] = filename;
335 names[1] = NULL;
336 W_InitMultipleFiles (names);
342 // W_NumLumps
344 int W_NumLumps (void)
346 return numlumps;
352 // W_CheckNumForName
353 // Returns -1 if name not found.
356 int W_CheckNumForName (char* name)
358 union {
359 char s[9];
360 int x[2];
362 } name8;
364 int v1;
365 int v2;
366 lumpinfo_t* lump_p;
368 // make the name into two integers for easy compares
369 strncpy (name8.s,name,8);
371 // in case the name was a fill 8 chars
372 name8.s[8] = 0;
374 // case insensitive
375 strupr (name8.s);
377 v1 = name8.x[0];
378 v2 = name8.x[1];
381 // scan backwards so patch lump files take precedence
382 lump_p = lumpinfo + numlumps;
384 while (lump_p-- != lumpinfo)
386 if ( *(int *)lump_p->name == v1
387 && *(int *)&lump_p->name[4] == v2)
389 return lump_p - lumpinfo;
393 // TFB. Not found.
394 return -1;
401 // W_GetNumForName
402 // Calls W_CheckNumForName, but bombs out if not found.
404 int W_GetNumForName (char* name)
406 int i;
408 i = W_CheckNumForName (name);
410 if (i == -1)
411 I_Error ("W_GetNumForName: %s not found!", name);
413 return i;
418 // W_LumpLength
419 // Returns the buffer size needed to load the given lump.
421 int W_LumpLength (int lump)
423 if (lump >= numlumps)
424 I_Error ("W_LumpLength: %i >= numlumps",lump);
426 return lumpinfo[lump].size;
432 // W_ReadLump
433 // Loads the lump into the given buffer,
434 // which must be >= W_LumpLength().
436 void
437 W_ReadLump
438 ( int lump,
439 void* dest )
441 int c;
442 lumpinfo_t* l;
443 FILE *handle;
445 if (lump >= numlumps)
446 I_Error ("W_ReadLump: %i >= numlumps",lump);
448 l = lumpinfo+lump;
450 // ??? I_BeginRead ();
452 if (l->handle == -1)
454 // reloadable file, so use open / read / close
455 if ( (handle = fopen (reloadname,"rb")) == NULL)
456 I_Error ("W_ReadLump: couldn't open %s",reloadname);
458 else
459 handle = (FILE *)l->handle;
461 fseek (handle, l->position, SEEK_SET);
462 c = fread (dest, 1, l->size, handle);
464 if (c < l->size)
465 I_Error ("W_ReadLump: only read %i of %i on lump %i",
466 c,l->size,lump);
468 if (l->handle == -1)
469 fclose (handle);
471 // ??? I_EndRead ();
478 // W_CacheLumpNum
480 void*
481 W_CacheLumpNum
482 ( int lump,
483 int tag )
485 byte* ptr;
487 if ((unsigned)lump >= numlumps)
488 I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
490 if (!lumpcache[lump])
492 // read the lump in
494 //printf ("cache miss on lump %i\n",lump);
495 ptr = Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
496 W_ReadLump (lump, lumpcache[lump]);
498 else
500 //printf ("cache hit on lump %i\n",lump);
501 Z_ChangeTag (lumpcache[lump],tag);
504 return lumpcache[lump];
510 // W_CacheLumpName
512 void*
513 W_CacheLumpName
514 ( char* name,
515 int tag )
517 return W_CacheLumpNum (W_GetNumForName(name), tag);
522 // W_Profile
524 int info[2500][10];
525 int profilecount;
527 void W_Profile (void)
529 int i;
530 memblock_t* block;
531 void* ptr;
532 char ch;
533 FILE* f;
534 int j;
535 char name[9];
538 for (i=0 ; i<numlumps ; i++)
540 ptr = lumpcache[i];
541 if (!ptr)
543 ch = ' ';
544 continue;
546 else
548 block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
549 if (block->tag < PU_PURGELEVEL)
550 ch = 'S';
551 else
552 ch = 'P';
554 info[i][profilecount] = ch;
556 profilecount++;
558 f = fopen ("waddump.txt","w");
559 name[8] = 0;
561 for (i=0 ; i<numlumps ; i++)
563 memcpy (name,lumpinfo[i].name,8);
565 for (j=0 ; j<8 ; j++)
566 if (!name[j])
567 break;
569 for ( ; j<8 ; j++)
570 name[j] = ' ';
572 fprintf (f,"%s ",name);
574 for (j=0 ; j<profilecount ; j++)
575 fprintf (f," %c",info[i][j]);
577 fprintf (f,"\n");
579 fclose (f);