DEADSOFTWARE

47aaa71eb1a65a2b2997471566b3fa3795f5456d
[flatwaifu.git] / src / files.c
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:Rembo project.
8 Doom2D:Rembo 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:Rembo 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
21 */
23 #include "glob.h"
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <sys/stat.h>
28 #include "files.h"
29 #include "map.h"
30 #include "my.h"
31 #include "game.h"
32 #include "view.h"
33 #include "dots.h"
34 #include "smoke.h"
35 #include "fx.h"
36 #include "items.h"
37 #include "monster.h"
38 #include "player.h"
39 #include "switch.h"
40 #include "weapons.h"
41 #include "error.h"
42 #include "cp866.h"
44 typedef struct {
45 byte n, i, v, d;
46 } dmv;
48 int d_start, d_end;
49 mwad_t wad[MAX_WAD];
50 map_block_t blk;
52 static byte seq[255];
53 static byte seqn;
54 static int inum=0;
55 static dmv *pat=NULL;
56 static unsigned *patp;
57 static void **dmi;
59 static int m_start, m_end;
60 static int s_start, s_end;
61 static int wad_num;
63 static char wads[MAX_WADS][__MAX_PATH];
64 static FILE* wadh[MAX_WADS];
66 static char f_drive[__MAX_DRIVE];
67 static char f_dir[__MAX_DIR];
68 static char f_name[__MAX_FNAME];
69 static char f_ext[__MAX_EXT];
71 void F_startup (void) {
72 logo("F_startup: настройка файловой системы\n");
73 memset(wads,0,sizeof(wads));
74 }
76 void F_addwad (const char *fn) {
77 int i;
79 for(i=0;i<MAX_WADS;++i) if(wads[i][0]==0) {
80 strcpy(wads[i],fn);return;
81 }
82 ERR_failinit("Не могу добавить WAD %s",fn);
83 }
85 static int myfilelength (FILE *h) {
86 int pos = ftell(h);
87 fseek (h, 0, SEEK_END);
88 int len = ftell(h);
89 fseek (h, pos, SEEK_SET);
90 return len;
91 }
93 // build wad directory
94 void F_initwads (void) {
95 int i, j, k, p;
96 FILE *h;
97 char s[4];
98 int n, o;
99 wad_t w;
101 logo("F_initwads: подключение WAD-файлов\n");
102 for (i = 0; i < MAX_WAD; ++i) {
103 wad[i].n[0] = 0;
106 logo(" подключается %s\n", wads[0]);
107 if ((wadh[0] = h = fopen(wads[0], "rb")) == NULL) {
108 ERR_failinit("Не могу открыть файл: %s", wads[0]);
111 s[0] = '\0';
112 myfread(s, 1, 4, h);
113 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
114 ERR_failinit("Нет подписи IWAD или PWAD (1)");
117 p = 0; // wad number
118 n = myfread32(h); // num
119 o = myfread32(h); // offset
120 fseek(h, o, SEEK_SET);
121 for (j = 0; j < n; ++j) {
122 w.o = myfread32(h); // offset
123 w.l = myfread32(h); // len
124 myfread(w.n, 1, 8, h); // name
125 if (p >= MAX_WAD) {
126 ERR_failinit("Слишком много элементов WAD'а");
128 wad[p].o = w.o;
129 wad[p].l = w.l;
130 memcpy(wad[p].n, w.n, 8);
131 wad[p].f = 0;
132 ++p;
135 //fclose(h);
137 for (i = 1; i < MAX_WADS; ++i) {
138 if (wads[i][0] != 0) {
139 logo(" подключается %s\n", wads[i]);
140 if ((wadh[i] = h = fopen(wads[i], "rb")) == NULL) {
141 ERR_failinit("Не могу открыть файл2: %s", wads[i]);
143 mysplitpath(wads[i], f_drive, f_dir, f_name, f_ext);
144 if (cp866_strcasecmp(f_ext, ".lmp") == 0) {
145 for (k = 0; k < MAX_WAD; ++k) {
146 if (cp866_strncasecmp(wad[k].n, f_name, 8) == 0) {
147 wad[k].o = 0;
148 wad[k].l = myfilelength(h);
149 wad[k].f = i;
150 break;
152 if (k >= MAX_WAD) {
153 if (p >= MAX_WAD) {
154 ERR_failinit("Слишком много элементов WAD'а");
156 memset(wad[p].n, 0, 8);
157 strncpy(wad[p].n, f_name, 8);
158 wad[p].o = 0;
159 wad[p].l = myfilelength(h);
160 wad[p].f = i;
161 ++p;
165 s[0] = '\0';
166 myfread(s, 1, 4, h);
167 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
168 ERR_failinit("Нет подписи IWAD или PWAD (2)");
170 n = myfread32(h); // num
171 o = myfread32(h); // offset
172 fseek(h, o, SEEK_SET);
173 for (j = 0; j < n; ++j) {
174 w.o = myfread32(h); // offset
175 w.o = myfread32(h); // len
176 myfread(w.n, 1, 8, h); // name
177 for (k = 0; k < MAX_WAD; ++k) {
178 if (cp866_strncasecmp(wad[k].n, w.n, 8) == 0) {
179 wad[k].o = w.o;
180 wad[k].l = w.l;
181 wad[k].f = i;
182 break;
184 if (k >= MAX_WAD) {
185 if (p >= MAX_WAD) {
186 ERR_failinit("Слишком много элементов WAD'а");
188 memcpy(wad[p].n, w.n, 8);
189 wad[p].o = w.o;
190 wad[p].l = w.l;
191 wad[p].f = i;
192 ++p;
200 wad_num = p;
203 // allocate resources
204 // (called from M_startup)
205 void F_allocres (void) {
206 d_start=F_getresid("D_START");
207 d_end=F_getresid("D_END");
208 m_start=F_getresid("M_START");
209 m_end=F_getresid("M_END");
210 s_start=F_getresid("S_START");
211 s_end=F_getresid("S_END");
214 // load resource
215 void F_loadres (int r, void *p, dword o, dword l) {
217 int oo;
218 FILE *fh;
221 oo=ftell(fh=wadh[wad[r].f]);
223 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
224 ERR_fatal("Ошибка при чтении файла");
226 if((dword)myfreadc(p,1,l,fh)!=l)
227 ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n);
229 fseek(fh,oo,SEEK_SET);
233 /*
234 // unused
235 void F_saveres(int r, void *p, dword o, dword l) {
236 FILE* fh = wadh[wad[r].f];
237 int oo = ftell(fh);
238 if (fseek(fh, wad[r].o + o, SEEK_SET) != 0) {
239 ERR_fatal("Ошибка при чтении файла");
241 myfwrite(p, l, 1, fh);
242 fseek(fh, oo, SEEK_SET);
244 */
246 // get resource id
247 int F_findres (const char n[8]) {
248 int i;
249 for (i = 0; i < wad_num; i++) {
250 if (cp866_strncasecmp(wad[i].n, n, 8) == 0) {
251 return i;
254 return -1;
257 // get resource id
258 int F_getresid (const char n[8]) {
259 int i = F_findres(n);
260 if (i == -1) {
261 ERR_fatal("F_getresid: ресурс %.8s не найден", n);
263 return i;
266 void F_getresname (char n[8], int r) {
267 memcpy(n, wad[r].n, 8);
270 // get sprite id
271 int F_getsprid (const char n[4], int s, int d, char *dir) {
272 int i;
273 byte a, b;
274 s += 'A';
275 d += '0';
276 for (i = s_start + 1; i < s_end; i++) {
277 if (cp866_strncasecmp(wad[i].n, n, 4) == 0 && (wad[i].n[4] == s || wad[i].n[6] == s)) {
278 a = wad[i].n[4] == s ? wad[i].n[5] : 0;
279 b = wad[i].n[6] == s ? wad[i].n[7] : 0;
280 if (a == '0' || b == '0' || a == d || b == d) {
281 if (dir != NULL) {
282 *dir = a != '0' && b == '0' || a != d && b == d;
284 return i;
288 ERR_fatal("F_getsprid: image %.4s%c%c not found", n, s, d);
289 return -1;
292 int F_getreslen (int r) {
293 return wad[r].l;
296 void F_nextmus (char *s) {
297 int i;
298 i=F_findres(s);
299 if(i<=m_start || i>=m_end) i=m_start;
300 for(++i;;++i) {
301 if(i>=m_end) i=m_start+1;
303 if (cp866_strcasecmp(wad[i].n,"MENU") == 0 ||
304 cp866_strcasecmp(wad[i].n,"INTERMUS") == 0 ||
305 cp866_strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0)
306 continue;
308 if(cp866_strncasecmp(wad[i].n,"DMI",3)!=0) break;
310 memcpy(s,wad[i].n,8);
313 void F_randmus (char *s) {
314 int i;
315 int n = myrand(10);
316 for (i = 0; i < n; i++) {
317 F_nextmus(s);
321 // reads bytes from file until CR
322 void F_readstr (FILE* h, char *s, int m) {
323 int i = 0;
324 size_t len = 0;
325 static char c = 0;
326 while (i < m) {
327 c = 13;
328 len = myfreadc(&c, 1, 1, h);
329 if (len == 0 || c == 13 || c == 10) {
330 break;
332 s[i] = c;
333 i++;
335 s[i] = 0;
338 /*
339 // unused
340 // reads bytes from file until NUL
341 void F_readstrz (FILE* h,char *s,int m) {
342 int i = 0;
343 size_t len = 0;
344 static char c = 0;
345 while (i < m) {
346 c = 0;
347 len = myfreadc(&c, 1, 1, h);
348 if (len == 0 || c == 0) {
349 break;
351 s[i] = c;
352 i++;
354 s[i] = 0;
356 */
358 void F_loadmap (char n[8]) {
359 int r, o;
360 FILE *h;
361 map_header_t hdr;
362 W_init();
363 r = F_getresid(n);
364 h = wadh[wad[r].f];
365 fseek(h, wad[r].o, SEEK_SET);
366 myfread(hdr.id, 8, 1, h);
367 hdr.ver = myfread16(h);
368 if (memcmp(hdr.id, "Doom2D\x1A", 8) != 0) {
369 ERR_fatal("%.8s не является уровнем", n);
371 for(;;) {
372 blk.t = myfread16(h);
373 blk.st = myfread16(h);
374 blk.sz = myfread32(h);
375 if(blk.t == MB_END) {
376 break;
378 if(blk.t == MB_COMMENT) {
379 fseek(h, blk.sz, SEEK_CUR);
380 continue;
382 o = ftell(h) + blk.sz;
383 if(!G_load(h)) {
384 if(!W_load(h)) {
385 if(!IT_load(h)) {
386 if(!SW_load(h)) {
387 ERR_fatal("Неизвестный блок %d(%d) в уровне %.8s", blk.t, blk.st, n);
392 fseek(h, o, SEEK_SET);
396 /*void F_freemus(void) {
398 int i;
400 if(!pat) return;
401 S_stopmusic();
402 free(pat);free(patp);
403 for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
404 free(dmi);
405 pat=NULL;
408 */
410 /*void F_loadmus(char n[8]) {
411 int r,i,j;
412 FILE *h;
413 int o;
414 struct{
415 char id[4];
416 byte ver,pat;
417 word psz;
418 }d;
419 struct{byte t;char n[13];word r;}di;
421 if((r=F_findres(n))==-1) return;
422 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
423 myfread(&d,1,sizeof(d),h);
424 if(memcmp(d.id,"DMM",4)!=0) return;
425 if(!(pat=malloc(d.psz<<2))) return;
426 myfread(pat,1,d.psz<<2,h);
427 myfread(&seqn,1,1,h);if(seqn) myfread(seq,1,seqn,h);
428 inum=0;myfread(&inum,1,1,h);
429 if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
430 if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
431 for(i=0;i<inum;++i) {
432 dmi[i]=NULL;
433 myfread(&di,1,16,h);o=ftell(h);
434 for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
435 if((r=F_findres(di.n))==-1) continue;
436 if(!(dmi[i]=malloc(wad[r].l+8))) continue;
437 memset(dmi[i],0,16);
438 F_loadres(r,dmi[i],0,2);
439 F_loadres(r,(int*)dmi[i]+1,2,2);
440 F_loadres(r,(int*)dmi[i]+2,4,2);
441 F_loadres(r,(int*)dmi[i]+3,6,2);
442 F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
443 fseek(h,o,SEEK_SET);
445 for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
446 patp[i]=r<<2;
447 while(pat[r++].v!=0x80);
450 */