DEADSOFTWARE

fix some warnings
[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"
34 #include "my.h"
36 char *S_getinfo(void);
38 extern void *snd_drv;
40 typedef struct{
41 byte n,i,v,d;
42 }dmv;
44 byte seq[255],seqn;
45 dmv *pat=NULL;
46 unsigned *patp;
47 void **dmi;
49 static int inum=0;
51 void G_savegame(FILE*);
52 void W_savegame(FILE*);
53 void DOT_savegame(FILE*);
54 void SMK_savegame(FILE*);
55 void FX_savegame(FILE*);
56 void IT_savegame(FILE*);
57 void MN_savegame(FILE*);
58 void PL_savegame(FILE*);
59 void SW_savegame(FILE*);
60 void WP_savegame(FILE*);
62 void G_loadgame(FILE*);
63 void W_loadgame(FILE*);
64 void DOT_loadgame(FILE*);
65 void SMK_loadgame(FILE*);
66 void FX_loadgame(FILE*);
67 void IT_loadgame(FILE*);
68 void MN_loadgame(FILE*);
69 void PL_loadgame(FILE*);
70 void SW_loadgame(FILE*);
71 void WP_loadgame(FILE*);
73 byte savname[7][24],savok[7];
75 int d_start,d_end,m_start,m_end,s_start,s_end,wad_num;
76 mwad_t wad[MAX_WAD];
78 char wads[MAX_WADS][__MAX_PATH];
79 static FILE* wadh[MAX_WADS];
81 char f_drive[__MAX_DRIVE],f_dir[__MAX_DIR],f_name[__MAX_FNAME],f_ext[__MAX_EXT],
82 f_path[__MAX_PATH];
84 void F_startup(void) {
85 logo("F_startup: настройка файловой системы\n");
86 memset(wads,0,sizeof(wads));
87 }
89 char *getsavfpname(int n, int ro)
90 {
91 static char fn[]="savgame0.dat";
92 fn[7]=n+'0';
93 #ifndef WIN32
94 static char p[100];
95 char *e = getenv("HOME");
96 strncpy(p,e,60);
97 strcat(p,"/.doom2d-rembo");
98 if (!ro) mkdir(p, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
99 strcat(p,"/");
100 strcat(p,fn);
101 #else
102 strcpy(p,fn);
103 #endif
104 return p;
107 void F_getsavnames (void) {
108 int i;
109 FILE *h;
110 short ver;
111 char *p;
112 for (i = 0; i < 7; ++i) {
113 p = getsavfpname(i, 1);
114 memset(savname[i], 0, 24);
115 savok[i] = 0;
116 h = fopen(p, "rb");
117 if (h != NULL) {
118 ver = -1;
119 myfread(savname[i], 24, 1, h);
120 ver = myfread16(h);
121 savname[i][23] = 0;
122 savok[i] = (ver == 3) ? 1 : 0;
123 fclose(h);
128 void F_savegame (int n, char *s) {
129 char *p = getsavfpname(n, 0);
130 FILE *h = fopen(p, "wb");
131 if (h != NULL) {
132 myfwrite(s, 24, 1, h); // slot name
133 myfwrite16(3, h); // version
134 G_savegame(h);
135 W_savegame(h);
136 DOT_savegame(h);
137 SMK_savegame(h);
138 FX_savegame(h);
139 IT_savegame(h);
140 MN_savegame(h);
141 PL_savegame(h);
142 SW_savegame(h);
143 WP_savegame(h);
144 fclose(h);
148 void F_loadgame (int n) {
149 short ver;
150 char *p = getsavfpname(n, 1);
151 FILE *h = fopen(p, "rb");
152 if (h != NULL) {
153 fseek(h, 24, SEEK_SET); // skip name
154 ver = myfread16(h); // version
155 if (ver == 3) {
156 G_loadgame(h);
157 W_loadgame(h);
158 DOT_loadgame(h);
159 SMK_loadgame(h);
160 FX_loadgame(h);
161 IT_loadgame(h);
162 MN_loadgame(h);
163 PL_loadgame(h);
164 SW_loadgame(h);
165 WP_loadgame(h);
167 fclose(h);
171 void F_addwad(char *fn) {
172 int i;
174 for(i=0;i<MAX_WADS;++i) if(wads[i][0]==0) {
175 strcpy(wads[i],fn);return;
177 ERR_failinit("Не могу добавить WAD %s",fn);
181 int myfilelength(FILE *h)
183 int pos = ftell(h);
184 fseek (h, 0, SEEK_END);
185 int len = ftell(h);
186 fseek (h, pos, SEEK_SET);
187 return len;
190 extern void mysplitpath(const char* path, char* drv, char* dir, char* name, char* ext);
192 // build wad directory
193 void F_initwads (void) {
194 int i, j, k, p;
195 FILE *h;
196 char s[4];
197 int n, o;
198 wad_t w;
200 logo("F_initwads: подключение WAD-файлов\n");
201 for (i = 0; i < MAX_WAD; ++i) {
202 wad[i].n[0] = 0;
205 logo(" подключается %s\n", wads[0]);
206 if ((wadh[0] = h = fopen(wads[0], "rb")) == NULL) {
207 ERR_failinit("Не могу открыть файл: %s", wads[0]);
210 s[0] = '\0';
211 myfread(s, 1, 4, h);
212 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
213 ERR_failinit("Нет подписи IWAD или PWAD (1)");
216 p = 0; // wad number
217 n = myfread32(h); // num
218 o = myfread32(h); // offset
219 fseek(h, o, SEEK_SET);
220 for (j = 0; j < n; ++j) {
221 w.o = myfread32(h); // offset
222 w.l = myfread32(h); // len
223 myfread(w.n, 1, 8, h); // name
224 if (p >= MAX_WAD) {
225 ERR_failinit("Слишком много элементов WAD'а");
227 wad[p].o = w.o;
228 wad[p].l = w.l;
229 memcpy(wad[p].n, w.n, 8);
230 wad[p].f = 0;
231 ++p;
234 //fclose(h);
236 for (i = 1; i < MAX_WADS; ++i) {
237 if (wads[i][0] != 0) {
238 logo(" подключается %s\n", wads[i]);
239 if ((wadh[i] = h = fopen(wads[i], "rb")) == NULL) {
240 ERR_failinit("Не могу открыть файл2: %s", wads[i]);
242 mysplitpath(wads[i], f_drive, f_dir, f_name, f_ext);
243 if (strcasecmp(f_ext, ".lmp") == 0) {
244 for (k = 0; k < MAX_WAD; ++k) {
245 if (strncasecmp(wad[k].n, f_name, 8) == 0) {
246 wad[k].o = 0;
247 wad[k].l = myfilelength(h);
248 wad[k].f = i;
249 break;
251 if (k >= MAX_WAD) {
252 if (p >= MAX_WAD) {
253 ERR_failinit("Слишком много элементов WAD'а");
255 memset(wad[p].n, 0, 8);
256 strncpy(wad[p].n, f_name, 8);
257 wad[p].o = 0;
258 wad[p].l = myfilelength(h);
259 wad[p].f = i;
260 ++p;
264 s[0] = '\0';
265 myfread(s, 1, 4, h);
266 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
267 ERR_failinit("Нет подписи IWAD или PWAD (2)");
269 n = myfread32(h); // num
270 o = myfread32(h); // offset
271 fseek(h, o, SEEK_SET);
272 for (j = 0; j < n; ++j) {
273 w.o = myfread32(h); // offset
274 w.o = myfread32(h); // len
275 myfread(w.n, 1, 8, h); // name
276 for (k = 0; k < MAX_WAD; ++k) {
277 if (strncasecmp(wad[k].n, w.n, 8) == 0) {
278 wad[k].o = w.o;
279 wad[k].l = w.l;
280 wad[k].f = i;
281 break;
283 if (k >= MAX_WAD) {
284 if (p >= MAX_WAD) {
285 ERR_failinit("Слишком много элементов WAD'а");
287 memcpy(wad[p].n, w.n, 8);
288 wad[p].o = w.o;
289 wad[p].l = w.l;
290 wad[p].f = i;
291 ++p;
299 wad_num = p;
302 // allocate resources
303 // (called from M_startup)
304 void F_allocres(void) {
305 d_start=F_getresid("D_START");
306 d_end=F_getresid("D_END");
307 m_start=F_getresid("M_START");
308 m_end=F_getresid("M_END");
309 s_start=F_getresid("S_START");
310 s_end=F_getresid("S_END");
313 // load resource
314 void F_loadres(int r,void *p,dword o,dword l) {
316 int oo;
317 FILE *fh;
320 oo=ftell(fh=wadh[wad[r].f]);
322 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
323 ERR_fatal("Ошибка при чтении файла");
325 if((dword)myfreadc(p,1,l,fh)!=l)
326 ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n);
328 fseek(fh,oo,SEEK_SET);
333 void F_saveres(int r,void *p,dword o,dword l) {
335 int oo;
336 FILE* fh;
337 oo=ftell(fh=wadh[wad[r].f]);
338 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
339 ERR_fatal("Ошибка при чтении файла");
340 myfwrite(p,l,1,fh);
341 fseek(fh,oo,SEEK_SET);
345 // get resource id
346 int F_getresid(char *n) {
347 int i;
349 for(i=0;i<wad_num;++i) if(strncasecmp(wad[i].n,n,8)==0) return i;
350 ERR_fatal("F_getresid: ресурс %.8s не найден",n);
351 return -1;
354 // get resource id
355 int F_findres(char *n) {
356 int i;
358 for(i=0;i<wad_num;++i) if(strncasecmp(wad[i].n,n,8)==0) return i;
359 return -1;
362 void F_getresname(char *n,int r) {
363 memcpy(n,wad[r].n,8);
366 // get sprite id
367 int F_getsprid(char n[4],int s,int d) {
368 int i;
369 byte a,b;
371 s+='A';d+='0';
372 for(i=s_start+1;i<s_end;++i)
373 if(strncasecmp(wad[i].n,n,4)==0 && (wad[i].n[4]==s || wad[i].n[6]==s)) {
374 if(wad[i].n[4]==s) a=wad[i].n[5]; else a=0;
375 if(wad[i].n[6]==s) b=wad[i].n[7]; else b=0;
376 if(a=='0') return i;
377 if(b=='0') return(i|0x8000);
378 if(a==d) return i;
379 if(b==d) return(i|0x8000);
381 ERR_fatal("F_getsprid: изображение %.4s%c%c не найдено",n,(byte)s,(byte)d);
382 return -1;
385 int F_getreslen(int r) {
386 return wad[r].l;
389 void F_nextmus(char *s) {
390 int i;
391 i=F_findres(s);
392 if(i<=m_start || i>=m_end) i=m_start;
393 for(++i;;++i) {
394 if(i>=m_end) i=m_start+1;
396 if (strcasecmp(wad[i].n,"MENU") == 0 ||
397 strcasecmp(wad[i].n,"INTERMUS") == 0 ||
398 strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0)
399 continue;
401 if(strncasecmp(wad[i].n,"DMI",3)!=0) break;
403 memcpy(s,wad[i].n,8);
406 void F_randmus(char *s) {
407 int n = myrand(10);
408 int i;
409 for (i=0; i<n; i++) {
410 F_nextmus(s);
414 // reads bytes from file until CR
415 void F_readstr(FILE* h, char *s, int m) {
416 int i = 0;
417 size_t len = 0;
418 static char c = 0;
419 while (i < m) {
420 c = 13;
421 len = myfreadc(&c, 1, 1, h);
422 if (len == 0 || c == 13 || c == 10) {
423 break;
425 s[i] = c;
426 i++;
428 s[i] = 0;
431 // reads bytes from file until NUL
432 void F_readstrz(FILE* h,char *s,int m) {
433 int i = 0;
434 size_t len = 0;
435 static char c = 0;
436 while (i < m) {
437 c = 0;
438 len = myfreadc(&c, 1, 1, h);
439 if (len == 0 || c == 0) {
440 break;
442 s[i] = c;
443 i++;
445 s[i] = 0;
448 map_block_t blk;
450 void F_loadmap(char n[8]) {
451 int r, o;
452 FILE *h;
453 map_header_t hdr;
454 W_init();
455 r = F_getresid(n);
456 h = wadh[wad[r].f];
457 fseek(h, wad[r].o, SEEK_SET);
458 myfread(hdr.id, 8, 1, h);
459 hdr.ver = myfread16(h);
460 if (memcmp(hdr.id, "Doom2D\x1A", 8) != 0) {
461 ERR_fatal("%.8s не является уровнем", n);
463 for(;;) {
464 blk.t = myfread16(h);
465 blk.st = myfread16(h);
466 blk.sz = myfread32(h);
467 if(blk.t == MB_END) {
468 break;
470 if(blk.t == MB_COMMENT) {
471 fseek(h, blk.sz, SEEK_CUR);
472 continue;
474 o = ftell(h) + blk.sz;
475 if(!G_load(h)) {
476 if(!W_load(h)) {
477 if(!IT_load(h)) {
478 if(!SW_load(h)) {
479 ERR_fatal("Неизвестный блок %d(%d) в уровне %.8s", blk.t, blk.st, n);
484 fseek(h, o, SEEK_SET);
488 /*void F_freemus(void) {
490 int i;
492 if(!pat) return;
493 S_stopmusic();
494 free(pat);free(patp);
495 for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
496 free(dmi);
497 pat=NULL;
500 */
502 /*void F_loadmus(char n[8]) {
503 int r,i,j;
504 FILE *h;
505 int o;
506 struct{
507 char id[4];
508 byte ver,pat;
509 word psz;
510 }d;
511 struct{byte t;char n[13];word r;}di;
513 if((r=F_findres(n))==-1) return;
514 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
515 myfread(&d,1,sizeof(d),h);
516 if(memcmp(d.id,"DMM",4)!=0) return;
517 if(!(pat=malloc(d.psz<<2))) return;
518 myfread(pat,1,d.psz<<2,h);
519 myfread(&seqn,1,1,h);if(seqn) myfread(seq,1,seqn,h);
520 inum=0;myfread(&inum,1,1,h);
521 if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
522 if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
523 for(i=0;i<inum;++i) {
524 dmi[i]=NULL;
525 myfread(&di,1,16,h);o=ftell(h);
526 for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
527 if((r=F_findres(di.n))==-1) continue;
528 if(!(dmi[i]=malloc(wad[r].l+8))) continue;
529 memset(dmi[i],0,16);
530 F_loadres(r,dmi[i],0,2);
531 F_loadres(r,(int*)dmi[i]+1,2,2);
532 F_loadres(r,(int*)dmi[i]+2,4,2);
533 F_loadres(r,(int*)dmi[i]+3,6,2);
534 F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
535 fseek(h,o,SEEK_SET);
537 for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
538 patp[i]=r<<2;
539 while(pat[r++].v!=0x80);
542 */