DEADSOFTWARE

eb6d36e943bbbda1b55d1082d79d7b04c473aade
[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 "error.h"
29 #include "view.h"
30 #include "items.h"
31 #include "switch.h"
32 #include "files.h"
33 #include "map.h"
35 char *S_getinfo(void);
37 extern void *snd_drv;
39 typedef struct{
40 byte n,i,v,d;
41 }dmv;
43 byte seq[255],seqn;
44 dmv *pat=NULL;
45 unsigned *patp;
46 void **dmi;
48 static int inum=0;
50 void G_savegame(FILE*);
51 void W_savegame(FILE*);
52 void DOT_savegame(FILE*);
53 void SMK_savegame(FILE*);
54 void FX_savegame(FILE*);
55 void IT_savegame(FILE*);
56 void MN_savegame(FILE*);
57 void PL_savegame(FILE*);
58 void SW_savegame(FILE*);
59 void WP_savegame(FILE*);
61 void G_loadgame(FILE*);
62 void W_loadgame(FILE*);
63 void DOT_loadgame(FILE*);
64 void SMK_loadgame(FILE*);
65 void FX_loadgame(FILE*);
66 void IT_loadgame(FILE*);
67 void MN_loadgame(FILE*);
68 void PL_loadgame(FILE*);
69 void SW_loadgame(FILE*);
70 void WP_loadgame(FILE*);
72 byte savname[7][24],savok[7];
74 int d_start,d_end,m_start,m_end,s_start,s_end,wad_num;
75 mwad_t wad[MAX_WAD];
77 char wads[MAX_WADS][__MAX_PATH];
78 static FILE* wadh[MAX_WADS];
80 char f_drive[__MAX_DRIVE],f_dir[__MAX_DIR],f_name[__MAX_FNAME],f_ext[__MAX_EXT],
81 f_path[__MAX_PATH];
83 void F_startup(void) {
84 logo("F_startup: настройка файловой системы\n");
85 memset(wads,0,sizeof(wads));
86 }
88 char *getsavfpname(int n, int ro)
89 {
90 static char fn[]="savgame0.dat";
91 fn[7]=n+'0';
92 #ifndef WIN32
93 static char p[100];
94 char *e = getenv("HOME");
95 strncpy(p,e,60);
96 strcat(p,"/.doom2d-rembo");
97 if (!ro) mkdir(p, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
98 strcat(p,"/");
99 strcat(p,fn);
100 #else
101 strcpy(p,fn);
102 #endif
103 return p;
106 void F_getsavnames(void) {
108 int i; FILE *h;
109 short ver;
110 char *p;
112 for(i=0;i<7;++i) {
113 p = getsavfpname(i,1);
114 memset(savname[i],0,24);savok[i]=0;
115 if((h=fopen(p,"rb"))==NULL) continue; //if((h=open(n,O_RDONLY|O_BINARY))==-1) continue;
116 myfread(savname[i],1,24,h);ver=-1;myfread(&ver,1,2,h);
117 fclose(h);savname[i][23]=0;savok[i]=(ver==3)?1:0;//savok[i]=(ver==2)?1:0;
121 void F_savegame(int n,char *s) {
123 FILE* h;
124 char *p;
125 p=getsavfpname(n,0);
126 if((h=fopen(p,"wb"))==NULL) return;
127 myfwrite(s,1,24,h);myfwrite("\3\0",1,2,h);//myfwrite("\2\0",1,2,h);
128 G_savegame(h);
129 W_savegame(h);
130 DOT_savegame(h);
131 SMK_savegame(h);
132 FX_savegame(h);
133 IT_savegame(h);
134 MN_savegame(h);
135 PL_savegame(h);
136 SW_savegame(h);
137 WP_savegame(h);
138 fclose(h);
141 void F_loadgame(int n) {
142 FILE* h;
143 short ver;
144 char *p;
145 p=getsavfpname(n,1);
147 if((h=fopen(p,"rb"))==NULL) return;//if((h=open(fn,O_BINARY|O_RDONLY))==-1) return;
148 fseek(h,24,SEEK_SET);myfread(&ver,1,2,h);if(ver!=3) return;//if(ver!=2) return;
149 G_loadgame(h);
150 W_loadgame(h);
151 DOT_loadgame(h);
152 SMK_loadgame(h);
153 FX_loadgame(h);
154 IT_loadgame(h);
155 MN_loadgame(h);
156 PL_loadgame(h);
157 SW_loadgame(h);
158 WP_loadgame(h);
159 fclose(h);
162 void F_addwad(char *fn) {
163 int i;
165 for(i=0;i<MAX_WADS;++i) if(wads[i][0]==0) {
166 strcpy(wads[i],fn);return;
168 ERR_failinit("Не могу добавить WAD %s",fn);
172 int myfilelength(FILE *h)
174 int pos = ftell(h);
175 fseek (h, 0, SEEK_END);
176 int len = ftell(h);
177 fseek (h, pos, SEEK_SET);
178 return len;
181 extern void mysplitpath(const char* path, char* drv, char* dir, char* name, char* ext);
183 static int myread_int32 (FILE *f) {
184 int x;
185 myfread(&x, 4, 1, f);
186 return int2host(x);
189 // build wad directory
190 void F_initwads (void) {
191 int i, j, k, p;
192 FILE *h;
193 char s[4];
194 int n, o;
195 wad_t w;
197 logo("F_initwads: подключение WAD-файлов\n");
198 for (i = 0; i < MAX_WAD; ++i) {
199 wad[i].n[0] = 0;
202 logo(" подключается %s\n", wads[0]);
203 if ((wadh[0] = h = fopen(wads[0], "rb")) == NULL) {
204 ERR_failinit("Не могу открыть файл: %s", wads[0]);
207 s[0] = '\0';
208 myfread(s, 1, 4, h);
209 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
210 ERR_failinit("Нет подписи IWAD или PWAD (1)");
213 p = 0; // wad number
214 n = myread_int32(h); // num
215 o = myread_int32(h); // offset
216 fseek(h, o, SEEK_SET);
217 for (j = 0; j < n; ++j) {
218 w.o = myread_int32(h); // offset
219 w.l = myread_int32(h); // len
220 myfread(w.n, 1, 8, h); // name
221 if (p >= MAX_WAD) {
222 ERR_failinit("Слишком много элементов WAD'а");
224 wad[p].o = w.o;
225 wad[p].l = w.l;
226 memcpy(wad[p].n, w.n, 8);
227 wad[p].f = 0;
228 ++p;
231 //fclose(h);
233 for (i = 1; i < MAX_WADS; ++i) {
234 if (wads[i][0] != 0) {
235 logo(" подключается %s\n", wads[i]);
236 if ((wadh[i] = h = fopen(wads[i], "rb")) == NULL) {
237 ERR_failinit("Не могу открыть файл2: %s", wads[i]);
239 mysplitpath(wads[i], f_drive, f_dir, f_name, f_ext);
240 if (strcasecmp(f_ext, ".lmp") == 0) {
241 for (k = 0; k < MAX_WAD; ++k) {
242 if (strncasecmp(wad[k].n, f_name, 8) == 0) {
243 wad[k].o = 0;
244 wad[k].l = myfilelength(h);
245 wad[k].f = i;
246 break;
248 if (k >= MAX_WAD) {
249 if (p >= MAX_WAD) {
250 ERR_failinit("Слишком много элементов WAD'а");
252 memset(wad[p].n, 0, 8);
253 strncpy(wad[p].n, f_name, 8);
254 wad[p].o = 0;
255 wad[p].l = myfilelength(h);
256 wad[p].f = i;
257 ++p;
261 s[0] = '\0';
262 myfread(s, 1, 4, h);
263 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
264 ERR_failinit("Нет подписи IWAD или PWAD (2)");
266 n = myread_int32(h); // num
267 o = myread_int32(h); // offset
268 fseek(h, o, SEEK_SET);
269 for (j = 0; j < n; ++j) {
270 w.o = myread_int32(h); // offset
271 w.l = myread_int32(h); // len
272 myfread(w.n, 1, 8, h); // name
273 for (k = 0; k < MAX_WAD; ++k) {
274 if (strncasecmp(wad[k].n, w.n, 8) == 0) {
275 wad[k].o = w.o;
276 wad[k].l = w.l;
277 wad[k].f = i;
278 break;
280 if (k >= MAX_WAD) {
281 if (p >= MAX_WAD) {
282 ERR_failinit("Слишком много элементов WAD'а");
284 memcpy(wad[p].n, w.n, 8);
285 wad[p].o = w.o;
286 wad[p].l = w.l;
287 wad[p].f = i;
288 ++p;
296 wad_num = p;
299 // allocate resources
300 // (called from M_startup)
301 void F_allocres(void) {
302 d_start=F_getresid("D_START");
303 d_end=F_getresid("D_END");
304 m_start=F_getresid("M_START");
305 m_end=F_getresid("M_END");
306 s_start=F_getresid("S_START");
307 s_end=F_getresid("S_END");
310 // load resource
311 void F_loadres(int r,void *p,dword o,dword l) {
313 int oo;
314 FILE *fh;
317 oo=ftell(fh=wadh[wad[r].f]);
319 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
320 ERR_fatal("Ошибка при чтении файла");
322 if((dword)myfreadc(p,1,l,fh)!=l)
323 ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n);
325 fseek(fh,oo,SEEK_SET);
330 void F_saveres(int r,void *p,dword o,dword l) {
332 int oo;
333 FILE* fh;
334 oo=ftell(fh=wadh[wad[r].f]);
335 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
336 ERR_fatal("Ошибка при чтении файла");
337 myfwrite(p,l,1,fh);
338 fseek(fh,oo,SEEK_SET);
342 // get resource id
343 int F_getresid(char *n) {
344 int i;
346 for(i=0;i<wad_num;++i) if(strncasecmp(wad[i].n,n,8)==0) return i;
347 ERR_fatal("F_getresid: ресурс %.8s не найден",n);
348 return -1;
351 // get resource id
352 int F_findres(char *n) {
353 int i;
355 for(i=0;i<wad_num;++i) if(strncasecmp(wad[i].n,n,8)==0) return i;
356 return -1;
359 void F_getresname(char *n,int r) {
360 memcpy(n,wad[r].n,8);
363 // get sprite id
364 int F_getsprid(char n[4],int s,int d) {
365 int i;
366 byte a,b;
368 s+='A';d+='0';
369 for(i=s_start+1;i<s_end;++i)
370 if(strncasecmp(wad[i].n,n,4)==0 && (wad[i].n[4]==s || wad[i].n[6]==s)) {
371 if(wad[i].n[4]==s) a=wad[i].n[5]; else a=0;
372 if(wad[i].n[6]==s) b=wad[i].n[7]; else b=0;
373 if(a=='0') return i;
374 if(b=='0') return(i|0x8000);
375 if(a==d) return i;
376 if(b==d) return(i|0x8000);
378 ERR_fatal("F_getsprid: изображение %.4s%c%c не найдено",n,(byte)s,(byte)d);
379 return -1;
382 int F_getreslen(int r) {
383 return wad[r].l;
386 void F_nextmus(char *s) {
387 int i;
388 i=F_findres(s);
389 if(i<=m_start || i>=m_end) i=m_start;
390 for(++i;;++i) {
391 if(i>=m_end) i=m_start+1;
393 if (strcasecmp(wad[i].n,"MENU") == 0 ||
394 strcasecmp(wad[i].n,"INTERMUS") == 0 ||
395 strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0)
396 continue;
398 if(strncasecmp(wad[i].n,"DMI",3)!=0) break;
400 memcpy(s,wad[i].n,8);
403 void F_randmus(char *s) {
404 int n = myrand(10);
405 int i;
406 for (i=0; i<n; i++) {
407 F_nextmus(s);
411 // reads bytes from file until CR
412 void F_readstr(FILE* h, char *s, int m) {
413 int i = 0;
414 size_t len = 0;
415 static char c = 0;
416 while (i < m) {
417 c = 13;
418 len = myfreadc(&c, 1, 1, h);
419 if (len == 0 || c == 13 || c == 10) {
420 break;
422 s[i] = c;
423 i++;
425 s[i] = 0;
428 // reads bytes from file until NUL
429 void F_readstrz(FILE* h,char *s,int m) {
430 int i = 0;
431 size_t len = 0;
432 static char c = 0;
433 while (i < m) {
434 c = 0;
435 len = myfreadc(&c, 1, 1, h);
436 if (len == 0 || c == 0) {
437 break;
439 s[i] = c;
440 i++;
442 s[i] = 0;
445 map_block_t blk;
447 void F_loadmap(char n[8]) {
449 int r;
450 FILE *h;
451 map_header_t hdr;
452 int o;
454 W_init();
455 r=F_getresid(n);
456 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
457 myfread(&hdr,1,sizeof(hdr),h);
458 hdr.ver = short2host(hdr.ver);
459 if(memcmp(hdr.id,"Doom2D\x1A",8)!=0)
460 ERR_fatal("%.8s не является уровнем",n);
461 for(;;) {
462 myfread(&blk,1,sizeof(blk),h);
463 blk.t = short2host(blk.t);
464 blk.st = short2host(blk.st);
465 blk.sz = int2host(blk.sz);
466 if(blk.t==MB_END) break;
467 if(blk.t==MB_COMMENT)
468 {fseek(h,blk.sz,SEEK_CUR);continue;}
469 o=ftell(h)+blk.sz;
470 if(!G_load(h))
471 if(!W_load(h))
472 if(!IT_load(h))
473 if(!SW_load(h))
474 ERR_fatal("Неизвестный блок %d(%d) в уровне %.8s",blk.t,blk.st,n);
475 fseek(h,o,SEEK_SET);
480 /*void F_freemus(void) {
482 int i;
484 if(!pat) return;
485 S_stopmusic();
486 free(pat);free(patp);
487 for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
488 free(dmi);
489 pat=NULL;
492 */
494 /*void F_loadmus(char n[8]) {
495 int r,i,j;
496 FILE *h;
497 int o;
498 struct{
499 char id[4];
500 byte ver,pat;
501 word psz;
502 }d;
503 struct{byte t;char n[13];word r;}di;
505 if((r=F_findres(n))==-1) return;
506 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
507 myfread(&d,1,sizeof(d),h);
508 if(memcmp(d.id,"DMM",4)!=0) return;
509 if(!(pat=malloc(d.psz<<2))) return;
510 myfread(pat,1,d.psz<<2,h);
511 myfread(&seqn,1,1,h);if(seqn) myfread(seq,1,seqn,h);
512 inum=0;myfread(&inum,1,1,h);
513 if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
514 if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
515 for(i=0;i<inum;++i) {
516 dmi[i]=NULL;
517 myfread(&di,1,16,h);o=ftell(h);
518 for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
519 if((r=F_findres(di.n))==-1) continue;
520 if(!(dmi[i]=malloc(wad[r].l+8))) continue;
521 memset(dmi[i],0,16);
522 F_loadres(r,dmi[i],0,2);
523 F_loadres(r,(int*)dmi[i]+1,2,2);
524 F_loadres(r,(int*)dmi[i]+2,4,2);
525 F_loadres(r,(int*)dmi[i]+3,6,2);
526 F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
527 fseek(h,o,SEEK_SET);
529 for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
530 patp[i]=r<<2;
531 while(pat[r++].v!=0x80);
534 */