1 /*
2 *-----------------------------------------------------------------------------
3 *
4 * $Log: wadread.c,v $
5 *
6 * Revision 2.0 1999/01/24 00:52:12 Andre Wertmann
7 * changed to work with Heretic
8 *
9 * Revision 1.7 1998/06/23 13:23:06 rafaj
10 * findlump() now always returns defined int as result
11 *
12 * Revision 1.6 1998/05/17 00:13:58 chris
13 * removed debug messages; cleaned up
14 *
15 * Revision 1.5 1998/04/24 23:37:36 chris
16 * read_pwads() and support functions - now sounds from PWAD
17 * files are played
18 *
19 * Revision 1.4 1998/04/24 21:09:04 chris
20 * ID's released version
21 *
22 * Revision 1.3 1997/01/30 19:54:23 b1
23 * Final reformatting run. All the remains (ST, W, WI, Z).
24 *
25 * Revision 1.2 1997/01/21 19:00:10 b1
26 * First formatting run:
27 * using Emacs cc-mode.el indentation for C++ now.
28 *
29 * Revision 1.1 1997/01/19 17:22:51 b1
30 * Initial check in DOOM sources as of Jan. 10th, 1997
31 *
32 *
33 * DESCRIPTION:
34 * WAD and Lump I/O, the second.
35 * This time for soundserver only.
36 * Welcome to Department of Redundancy Department. Again :-).
37 *
38 *-----------------------------------------------------------------------------
39 */
40
41
42 #include <stdlib.h>
43 #include <fcntl.h>
44 #include <sys/stat.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #include <ctype.h>
49 #include <unistd.h>
50 #include <assert.h>
51
52 #include "soundsrv.h"
53 #include "wadread.h"
54
55 #ifndef HOMEDIR
56 #define HOMEDIR "/.heretic"
57 #endif /* HOMEDIR */
58
59
60 int* sfxlengths;
61
62 typedef struct wadinfo_struct
63 {
64 char identification[4];
65 int numlumps;
66 int infotableofs;
67 } wadinfo_t;
68
69 typedef struct filelump_struct
70 {
71 int filepos;
72 int size;
73 char name[8];
74 } filelump_t;
75
76 typedef struct lumpinfo_struct
77 {
78 int handle;
79 int filepos;
80 int size;
81 char name[8];
82 } lumpinfo_t;
83
84 lumpinfo_t* lumpinfo;
85 int numlumps;
86
87 void** lumpcache;
88
89
90 #define stricmp strcasecmp
91 #define strnicmp strncasecmp
92
93
94 /*
95 * Something new.
96 * This version of w_wad.c does handle endianess.
97 */
98 #ifdef __BIG_ENDIAN__
99
100 #define SHORT(x) ((short)( \
101 (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) \
102 | \
103 (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
104
105 #define LONG(x) ((int)( \
106 (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) \
107 | \
108 (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) \
109 | \
110 (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) \
111 | \
112 (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
113
114 #else
115 #define LONG(x) (x)
116 #define SHORT(x) (x)
117 #endif
118
119
120 /* Way too many of those... */
derror(char * msg)121 static void derror(char* msg)
122 {
123 fprintf(stderr, "\nwadread error: %s\n", msg);
124 exit(-1);
125 }
126
127
strupr(char * s)128 void strupr (char *s)
129 {
130 while (*s)
131 *s++ = toupper(*s);
132 }
133
filelength(int handle)134 int filelength (int handle)
135 {
136 struct stat fileinfo;
137
138 if (fstat (handle,&fileinfo) == -1)
139 fprintf (stderr, "Error fstating\n");
140
141 return fileinfo.st_size;
142 }
143
accesswad(char * wadname)144 char* accesswad( char* wadname)
145 {
146 char* fn;
147 char* envhome;
148
149 if ((envhome = getenv("HERETICHOME")) != NULL)
150 {
151 fn = (char*) malloc(strlen(envhome)+strlen("/")+strlen(wadname)+1);
152 assert(fn);
153 sprintf(fn, "%s/%s", envhome, wadname);
154 if (!access(fn, R_OK))
155 return fn;
156 else
157 free(fn);
158 }
159 if ((envhome = getenv("HOME")) != NULL)
160 {
161 fn = (char*) malloc(strlen(envhome)+strlen(HOMEDIR"/")
162 +strlen(wadname)+1);
163 assert(fn);
164 sprintf(fn, "%s"HOMEDIR"/%s", envhome, wadname);
165 if (!access(fn, R_OK))
166 return fn;
167 else
168 free(fn);
169 }
170 if ((envhome = getenv("PATH")))
171 {
172 char *path = strdup(envhome), *curentry;
173 assert(path);
174 while (strlen(path))
175 {
176 if (!(curentry = strrchr(path, ':')))
177 curentry = path;
178 else
179 *curentry++ = 0;
180 fn = (char*)malloc(strlen(curentry)+19+strlen(wadname)); /* Add space for /, ../share/heretic/ */
181 assert(fn);
182 sprintf(fn, "%s/%s", curentry, wadname);
183 if (!access(fn, R_OK))
184 {
185 free(path);
186 return fn;
187 }
188 /* check ../share/heretic */
189 sprintf(fn, "%s/../share/heretic/%s", curentry, wadname);
190 if (!access(fn, R_OK))
191 {
192 free(path);
193 return fn;
194 }
195 free(fn);
196 *curentry = 0;
197 }
198 free(path);
199 }
200 if (!access(wadname, R_OK))
201 return wadname;
202
203 fn = (char*) malloc(strlen("./")+strlen(wadname)+1);
204 assert(fn);
205 sprintf(fn,"%s", wadname);
206 if (!access(fn ,R_OK))
207 return fn;
208 else
209 free(fn);
210
211 return NULL;
212 }
213
openwad(char * wadname)214 void openwad(char* wadname)
215 {
216
217 int wadfile;
218 int tableoffset;
219 int tablelength;
220 int tablefilelength;
221 int i;
222 wadinfo_t header;
223 filelump_t* filetable;
224
225 /* open and read the wadfile header */
226 wadfile = open(wadname, O_RDONLY);
227
228 if (wadfile < 0)
229 derror("Could not open wadfile");
230
231 read(wadfile, &header, sizeof header);
232
233 if (strncmp(header.identification, "IWAD", 4))
234 derror("wadfile has weirdo header");
235
236 numlumps = LONG(header.numlumps);
237 tableoffset = LONG(header.infotableofs);
238 tablelength = numlumps * sizeof(lumpinfo_t);
239 tablefilelength = numlumps * sizeof(filelump_t);
240 lumpinfo = (lumpinfo_t *) malloc(tablelength);
241 assert(lumpinfo);
242 filetable = (filelump_t *) ((char*)lumpinfo + tablelength - tablefilelength);
243
244 /* get the lumpinfo table */
245 lseek(wadfile, tableoffset, SEEK_SET);
246 read(wadfile, filetable, tablefilelength);
247
248 /* process the table to make the endianness right and shift it down */
249 for (i=0 ; i<numlumps ; i++)
250 {
251 strncpy(lumpinfo[i].name, filetable[i].name, 8);
252 lumpinfo[i].handle = wadfile;
253 lumpinfo[i].filepos = LONG(filetable[i].filepos);
254 lumpinfo[i].size = LONG(filetable[i].size);
255 /* fprintf(stderr, "lump [%.8s] exists\n", lumpinfo[i].name); */
256 }
257
258 }
259
loadlump(char * lumpname,int * size)260 void* loadlump( char* lumpname, int* size )
261 {
262 int i;
263 void* lump;
264
265 for (i=0 ; i<numlumps ; i++)
266 {
267 if (!strncasecmp(lumpinfo[i].name, lumpname, 8))
268 break;
269 }
270
271 if (i == numlumps)
272 {
273 /*
274 * fprintf(stderr,
275 * "Could not find lumpname [%s]\n", lumpname);
276 */
277 lump = 0;
278 }
279 else
280 {
281 lump = (void *) malloc(lumpinfo[i].size);
282 assert(lump);
283 lseek(lumpinfo[i].handle, lumpinfo[i].filepos, SEEK_SET);
284 read(lumpinfo[i].handle, lump, lumpinfo[i].size);
285 *size = lumpinfo[i].size;
286 }
287 return lump;
288 }
289
getsfx(char * sfxname,int * len)290 void* getsfx( char* sfxname, int* len )
291 {
292 unsigned char* sfx;
293 unsigned char* paddedsfx;
294 int i;
295 int size;
296 int paddedsize;
297 char name[20];
298
299 /* sprintf(name, "ds%s", sfxname); */
300 sprintf(name, "%s", sfxname);
301 #ifdef _DEBUGSOUND
302 fprintf(stderr, "Name: %s ; Sfxname: %s\n", name, sfxname );
303 #endif
304
305 sfx = (unsigned char *) loadlump(name, &size);
306 #ifdef _DEBUGSOUND
307 fprintf(stderr, "Sfxsize: %d\n", size );
308 #endif
309
310 /* pad the sound effect out to the mixing buffer size */
311 paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
312 paddedsfx = (unsigned char *) realloc(sfx, paddedsize+8);
313 for (i=size ; i<paddedsize+8 ; i++)
314 paddedsfx[i] = 128;
315
316 *len = paddedsize;
317 return (void *) (paddedsfx + 8);
318 }
319
findlump(char * lumpname)320 static int findlump(char *lumpname)
321 {
322 int i;
323
324 for (i=0; i<numlumps; i++)
325 if (!strnicmp(lumpname,lumpinfo[i].name,6))
326 return(i);
327 return(-1);
328 }
329
do_pwad(char * wadname)330 static void do_pwad(char* wadname)
331 {
332 int wadfile;
333 int tableoffset;
334 int tablelength;
335 int tablefilelength;
336 int i,j;
337 int _numlumps;
338 lumpinfo_t *_lumpinfo;
339 wadinfo_t header;
340 filelump_t* filetable;
341
342 /* open and read the wadfile header */
343 wadfile = open(wadname, O_RDONLY);
344
345 if (wadfile < 0)
346 derror("Could not open wadfile");
347
348 read(wadfile, &header, sizeof header);
349
350 if (strncmp(header.identification, "PWAD", 4) &&
351 strncmp(header.identification, "IWAD", 4)) /* e.g. tnt.wad is a IWAD */
352 derror("wadfile has weirdo header");
353
354 _numlumps = LONG(header.numlumps);
355 tableoffset = LONG(header.infotableofs);
356 tablelength = numlumps * sizeof(lumpinfo_t);
357 tablefilelength = numlumps * sizeof(filelump_t);
358 _lumpinfo = (lumpinfo_t *) malloc(tablelength);
359 assert(_lumpinfo);
360 filetable = (filelump_t *) ((char*)_lumpinfo + tablelength - tablefilelength);
361
362 /* get the lumpinfo table */
363 lseek(wadfile, tableoffset, SEEK_SET);
364 read(wadfile, filetable, tablefilelength);
365
366 /* process the table to make the endianness right and shift it down */
367 for (i=0 ; i<_numlumps ; i++)
368 {
369 if (strnicmp(filetable[i].name,"DS",2)) continue;
370 j=findlump(filetable[i].name);
371 if (j == -1) {
372 char lname[7];
373 strncpy(lname,filetable[i].name,6);
374 fprintf(stderr,"sndserver: unidentified lump '%s' -- ignored\n",lname);
375 continue;
376 }
377 else {
378 char lname[7],lname2[7];
379 strncpy(lname,filetable[i].name,6);
380 strncpy(lname2,lumpinfo[j].name,6);
381 lname[6]=lname2[6]=0;
382 /* fprintf(stderr,"sndserver: replacing '%s' '%s'\n",lname,lname2); */
383 }
384 lumpinfo[j].handle = wadfile;
385 lumpinfo[j].filepos = LONG(filetable[i].filepos);
386 lumpinfo[j].size = LONG(filetable[i].size);
387 /* fprintf(stderr, "lump [%.8s] exists\n", lumpinfo[i].name); */
388 }
389 free(_lumpinfo);
390 }
391
392 /*
393 * inspired/stolen by/from read_extra_wads() from musserver-1.22
394 * this shouldn't be needed, doom should tell sndserver which
395 * wads to use.
396 */
397
read_pwads(void)398 void read_pwads(void)
399 {
400 pid_t ppid;
401 char filename[100];
402 FILE *fp;
403
404 ppid=getppid(); /* heretic's pid */
405 sprintf(filename,"/proc/%d/cmdline",(int)ppid);
406
407 /* fprintf(stderr,"sndserver: in read_pwads\n"); */
408
409 if ((fp = fopen(filename, "r"))) {
410 char *s;
411 static char buff[256];
412 int len, active = 0;
413 len = fread(buff, 1, 256, fp);
414 fclose(fp);
415 for (s = buff; s < buff+len;) {
416 if (*s == '-')
417 active = 0;
418 if (active)
419 do_pwad(s);
420 else if (!strcmp(s, "-file"))
421 active = 1;
422 s += strlen(s) + 1;
423 }
424 }
425 }
426
427