fix map selector starting the game
[d2d-psx.git] / src / files.c
blob088e9754ad333a269f55fa8a1811706252abeb6e
1 /*
2 * Copyright (C) Prikol Software 1996-1997
3 * Copyright (C) Aleksey Volynskov 1996-1997
4 * Copyright (C) <ARembo@gmail.com> 2011
6 * This file is part of the Doom2D PSX project.
8 * Doom2D PSX is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * Doom2D PSX is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/> or
19 * write to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "glob.h"
24 #include <stdio.h>
25 // #include <conio.h>
26 #include <malloc.h>
27 // #include <dos.h>
28 #include <string.h>
29 #include <stdlib.h>
30 // #include <sys\stat.h>
31 #include "vga.h"
32 #include "error.h"
33 #include "sound.h"
34 // #include "snddrv.h"
35 #include "memory.h"
36 #include "view.h"
37 #include "items.h"
38 #include "switch.h"
39 #include "files.h"
40 #include "map.h"
42 #include <sys/file.h>
43 #include <libapi.h>
45 char * S_getinfo(void);
47 extern void * snd_drv;
49 typedef struct {
50 byte n, i, v, d;
51 } dmv;
53 byte seq[255], seqn;
54 dmv * pat = NULL;
55 unsigned * patp;
56 void ** dmi;
58 static int inum = 0;
60 byte savname[7][24], savok[7];
62 int d_start, d_end, m_start, m_end, s_start, s_end, wad_num;
63 mwad_t wad[MAX_WAD];
65 char wads[MAX_WADS][__MAX_PATH];
66 static CDFILE * wadh[MAX_WADS];
68 char f_drive[__MAX_DRIVE], f_dir[__MAX_DIR], f_name[__MAX_FNAME], f_ext[__MAX_EXT],
69 f_path[__MAX_PATH];
71 void F_startup(void) {
72 logo("F_startup(): setting up filesystem\n");
73 CdInit(); // init cdrom driver
74 memset(wads, 0, sizeof(wads));
77 void F_savegame(int n, char * s) {
81 void F_loadgame(int n) {
85 void F_addwad(char * fn) {
86 int i;
88 for (i = 0; i < MAX_WADS; ++i) {
89 if (wads[i][0] == 0) {
90 strcpy(wads[i], fn);
91 return;
94 ERR_failinit("F_addwad(): can't add WAD %s\n", fn);
97 extern void mysplitpath(const char * path, char * drv, char * dir, char * name, char * ext);
99 // build wad directory
100 void F_initwads(void) {
101 int i, j, k, p;
102 CDFILE * h;
103 char s[4];
104 int n, o;
105 wad_t w;
107 logo("F_initwads(): loading WADs\n");
108 for (i = 0; i < MAX_WAD; ++i)
109 wad[i].n[0] = 0;
110 logo(" loading %s\n", wads[0]);
111 if ((wadh[0] = h = cd_fopen(wads[0])) == NULL) // if((wadh[0]=h=open(wads[0],O_RDWR|O_BINARY))==-1)
112 ERR_failinit("can't open WAD file: %s", wads[0]); // sys_errlist[errno]);
113 *s = 0;
114 cd_freadordie(s, 1, 4, h);
115 if ((strncmp(s, "IWAD", 4) != 0) && (strncmp(s, "PWAD", 4) != 0))
116 ERR_failinit("no WAD signature in file");
117 cd_freadordie(&n, 1, 4, h);
118 cd_freadordie(&o, 1, 4, h);
119 printf("F_initwads(): reading %d lumps from table at %x\n", n, o);
120 cd_fseek(h, o, SEEK_SET);
121 for (j = 0, p = 0; j < n; ++j) {
122 cd_freadordie(&w, 1, 16, h);
123 if (p >= MAX_WAD)
124 ERR_failinit("too many lumps in WAD");
125 memcpy(wad[p].n, w.n, 8);
126 wad[p].o = w.o;
127 wad[p].l = w.l;
128 wad[p].f = 0;
129 ++p;
131 // fclose(h);
132 for (i = 1; i < MAX_WADS; ++i) {
133 if (wads[i][0] != 0) {
134 logo(" loading %s\n", wads[i]);
135 if ((wadh[i] = h = cd_fopen(wads[i])) == NULL) // if((wadh[i]=h=open(wads[i],O_RDONLY|O_BINARY))==-1)
136 ERR_failinit("can't open WAD file: %s", wads[i]); // sys_errlist[errno]);
137 mysplitpath(wads[i], f_drive, f_dir, f_name, f_ext);
138 if (strcasecmp(f_ext, ".lmp") == 0) {
139 for (k = 0; k < MAX_WAD; ++k) {
140 if (strncasecmp(wad[k].n, f_name, 8) == 0) {
141 wad[k].o = 0L;
142 wad[k].l = cd_fsize(h);
143 wad[k].f = i;
144 break;
147 if (k >= MAX_WAD) {
148 if (p >= MAX_WAD)
149 ERR_failinit("too many lumps in WAD");
150 memset(wad[p].n, 0, 8);
151 strncpy(wad[p].n, f_name, 8);
152 wad[p].o = 0L;
153 wad[p].l = cd_fsize(h);
154 wad[p].f = i;
155 ++p;
157 continue;
159 *s = 0;
160 cd_freadordie(s, 1, 4, h);
161 if ((strncmp(s, "IWAD", 4) != 0) && (strncmp(s, "PWAD", 4) != 0))
162 ERR_failinit("no WAD signature in file");
163 cd_freadordie(&n, 1, 4, h);
164 cd_freadordie(&o, 1, 4, h);
165 cd_fseek(h, o, SEEK_SET);
166 for (j = 0; j < n; ++j) {
167 cd_freadordie(&w, 1, 16, h);
168 for (k = 0; k < MAX_WAD; ++k) {
169 if (strncasecmp(wad[k].n, w.n, 8) == 0) {
170 wad[k].o = w.o;
171 wad[k].l = w.l;
172 wad[k].f = i;
173 break;
176 if (k >= MAX_WAD) {
177 if (p >= MAX_WAD)
178 ERR_failinit("too many lumps in WAD");
179 memcpy(wad[p].n, w.n, 8);
180 wad[p].o = w.o;
181 wad[p].l = w.l;
182 wad[p].f = i;
183 ++p;
188 wad_num = p;
189 } /* F_initwads */
191 // allocate resources
192 // (called from M_startup)
193 void F_allocres(void) {
194 #ifdef SORTED_WAD
195 d_start = F_getresid("A_START");
196 d_end = F_getresid("A_END");
197 s_start = F_getresid("A_START");
198 s_end = F_getresid("A_END");
199 #else
200 d_start = F_getresid("D_START");
201 d_end = F_getresid("D_END");
202 s_start = F_getresid("S_START");
203 s_end = F_getresid("S_END");
204 #endif
205 m_start = F_getresid("M_START");
206 m_end = F_getresid("M_END");
209 void F_loadres(int r, void * p, dword o, dword l) {
210 CDFILE * fh;
212 // printf("F_loadres(): loading lump %x (%.8s size %u)\n", r, wad[r].n, l);
214 if (cd_fseek(fh = wadh[wad[r].f], wad[r].o + o, SEEK_SET) != 0)
215 ERR_fatal("F_loadres(): error seeking file");
217 if ((dword) cd_fread(p, 1, l, fh) != l)
218 ERR_fatal("F_loadres(): error loading lump %.8s", wad[r].n);
221 // get resource id
222 int F_getresid(char * n) {
223 int i;
224 for (i = 0; i < wad_num; ++i) {
225 if (strncasecmp(wad[i].n, n, 8) == 0)
226 return i;
228 ERR_fatal("F_getresid(): lump `%.8s` not found\n", n);
229 return -1;
232 // get resource id
233 int F_findres(char * n) {
234 int i;
235 for (i = 0; i < wad_num; ++i) {
236 if (strncasecmp(wad[i].n, n, 8) == 0)
237 return i;
239 return -1;
242 void F_getresname(char * n, int r) {
243 memcpy(n, wad[r].n, 8);
246 // get sprite id
247 int F_getsprid(char n[4], int s, int d) {
248 int i;
249 byte a, b;
251 s += 'A';
252 d += '0';
253 for (i = s_start + 1; i < s_end; ++i) {
254 if ((strncasecmp(wad[i].n, n, 4) == 0) && ((wad[i].n[4] == s) || (wad[i].n[6] == s))) {
255 if (wad[i].n[4] == s)
256 a = wad[i].n[5];
257 else
258 a = 0;
259 if (wad[i].n[6] == s)
260 b = wad[i].n[7];
261 else
262 b = 0;
263 if (a == '0')
264 return i;
266 if (b == '0')
267 return i | 0x8000;
269 if (a == d)
270 return i;
272 if (b == d)
273 return i | 0x8000;
276 ERR_fatal("F_getsprid: image %.4s%c%c not found", n, (byte) s, (byte) d);
277 return -1;
278 } /* F_getsprid */
280 int F_getreslen(int r) {
281 return wad[r].l;
284 void F_nextmus(char * s) {
285 int i;
287 i = F_findres(s);
288 if ((i <= m_start) || (i >= m_end))
289 i = m_start;
290 for (++i;; ++i) {
291 if (i >= m_end)
292 i = m_start + 1;
294 if ((strcasecmp(wad[i].n, "MENU") == 0) ||
295 (strcasecmp(wad[i].n, "INTERMUS") == 0) ||
296 (strcasecmp(wad[i].n, "\x8a\x8e\x8d\x85\x96\x0") == 0))
297 continue;
299 if (strncasecmp(wad[i].n, "DMI", 3) != 0)
300 break;
302 memcpy(s, wad[i].n, 8);
305 void F_randmus(char * s) {
306 int n = myrand(10);
307 int i;
309 for (i = 0; i < n; i++)
310 F_nextmus(s);
313 // reads bytes from file until CR
314 void F_readstr(CDFILE * h, char * s, int m) {
315 int i;
316 static char c;
318 for (i = 0;;) {
319 c = 13;
320 cd_fread(&c, 1, 1, h);
321 if (c == 13)
322 break;
323 if (i < m)
324 s[i++] = c;
326 s[i] = 0;
329 // reads bytes from file until NUL
330 void F_readstrz(CDFILE * h, char * s, int m) {
331 int i;
332 static char c;
334 for (i = 0;;) {
335 c = 0;
336 cd_fread(&c, 1, 1, h);
337 if (c == 0)
338 break;
339 if (i < m)
340 s[i++] = c;
342 s[i] = 0;
345 map_block_t blk;
347 void F_loadmap(char n[8]) {
348 int r;
349 CDFILE * h;
350 map_header_t hdr;
351 int o;
353 W_init();
354 r = F_getresid(n);
355 cd_fseek(h = wadh[wad[r].f], wad[r].o, SEEK_SET);
356 cd_freadordie(&hdr, 1, sizeof(hdr), h);
357 if (memcmp(hdr.id, "Doom2D\x1A", 8) != 0)
358 ERR_fatal("%.8s is not a map", n);
359 for (;;) {
360 cd_freadordie(&blk, 1, sizeof(blk), h);
361 if (blk.t == MB_END)
362 break;
363 if (blk.t == MB_COMMENT) {
364 cd_fseek(h, blk.sz, SEEK_CUR);
365 continue;
367 o = cd_ftell(h) + blk.sz;
368 if (!G_load(h)) {
369 if (!W_load(h)) {
370 if (!IT_load(h)) {
371 if (!SW_load(h))
372 ERR_fatal("unknown block %d(%d) in map %.8s", blk.t, blk.st, n);
376 cd_fseek(h, o, SEEK_SET);
378 } /* F_loadmap */
380 /*void F_freemus(void) {
382 * int i;
384 * if(!pat) return;
385 * S_stopmusic();
386 * free(pat);free(patp);
387 * for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
388 * free(dmi);
389 * pat=NULL;
394 /*void F_loadmus(char n[8]) {
395 * int r,i,j;
396 * CDFILE *h;
397 * int o;
398 * struct{
399 * char id[4];
400 * byte ver,pat;
401 * word psz;
402 * }d;
403 * struct{byte t;char n[13];word r;}di;
405 * if((r=F_findres(n))==-1) return;
406 * cd_fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
407 * cd_freadordie(&d,1,sizeof(d),h);
408 * if(memcmp(d.id,"DMM",4)!=0) return;
409 * if(!(pat=malloc(d.psz<<2))) return;
410 * cd_freadordie(pat,1,d.psz<<2,h);
411 * cd_freadordie(&seqn,1,1,h);if(seqn) cd_freadordie(seq,1,seqn,h);
412 * inum=0;cd_freadordie(&inum,1,1,h);
413 * if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
414 * if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
415 * for(i=0;i<inum;++i) {
416 * dmi[i]=NULL;
417 * cd_freadordie(&di,1,16,h);o=ftell(h);
418 * for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
419 * if((r=F_findres(di.n))==-1) continue;
420 * if(!(dmi[i]=malloc(wad[r].l+8))) continue;
421 * memset(dmi[i],0,16);
422 * F_loadres(r,dmi[i],0,2);
423 * F_loadres(r,(int*)dmi[i]+1,2,2);
424 * F_loadres(r,(int*)dmi[i]+2,4,2);
425 * F_loadres(r,(int*)dmi[i]+3,6,2);
426 * F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
427 * cd_fseek(h,o,SEEK_SET);
429 * for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
430 * patp[i]=r<<2;
431 * while(pat[r++].v!=0x80);