DEADSOFTWARE

Save-файлы сохраняются в $HOME/.doom2d-rembo
[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 <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/stat.h>
44 char *S_getinfo(void);
46 extern void *snd_drv;
48 typedef struct{
49 byte n,i,v,d;
50 }dmv;
52 byte seq[255],seqn;
53 dmv *pat=NULL;
54 unsigned *patp;
55 void **dmi;
57 static int inum=0;
59 void G_savegame(FILE*);
60 void W_savegame(FILE*);
61 void DOT_savegame(FILE*);
62 void SMK_savegame(FILE*);
63 void FX_savegame(FILE*);
64 void IT_savegame(FILE*);
65 void MN_savegame(FILE*);
66 void PL_savegame(FILE*);
67 void SW_savegame(FILE*);
68 void WP_savegame(FILE*);
70 void G_loadgame(FILE*);
71 void W_loadgame(FILE*);
72 void DOT_loadgame(FILE*);
73 void SMK_loadgame(FILE*);
74 void FX_loadgame(FILE*);
75 void IT_loadgame(FILE*);
76 void MN_loadgame(FILE*);
77 void PL_loadgame(FILE*);
78 void SW_loadgame(FILE*);
79 void WP_loadgame(FILE*);
81 byte savname[7][24],savok[7];
83 int d_start,d_end,m_start,m_end,s_start,s_end,wad_num;
84 mwad_t wad[MAX_WAD];
86 char wads[MAX_WADS][__MAX_PATH];
87 static FILE* wadh[MAX_WADS];
89 char f_drive[__MAX_DRIVE],f_dir[__MAX_DIR],f_name[__MAX_FNAME],f_ext[__MAX_EXT],
90 f_path[__MAX_PATH];
92 void F_startup(void) {
93 logo("F_startup: настройка файловой системы\n");
94 memset(wads,0,sizeof(wads));
95 }
97 char *getsavfpname(int n, int ro)
98 {
99 static char fn[]="savgame0.dat";
100 fn[7]=n+'0';
101 #ifndef WIN32
102 static char p[100];
103 char *e = getenv("HOME");
104 strncpy(p,e,60);
105 strcat(p,"/.doom2d-rembo");
106 if (!ro) mkdir(p, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
107 strcat(p,"/");
108 strcat(p,fn);
109 #else
110 strcpy(p,fn);
111 #endif
112 return p;
115 void F_getsavnames(void) {
117 int i; FILE *h;
118 short ver;
119 char *p;
121 for(i=0;i<7;++i) {
122 p = getsavfpname(i,1);
123 memset(savname[i],0,24);savok[i]=0;
124 if((h=fopen(p,"rb"))==NULL) continue; //if((h=open(n,O_RDONLY|O_BINARY))==-1) continue;
125 myfread(savname[i],1,24,h);ver=-1;myfread(&ver,1,2,h);
126 fclose(h);savname[i][23]=0;savok[i]=(ver==3)?1:0;//savok[i]=(ver==2)?1:0;
130 void F_savegame(int n,char *s) {
132 FILE* h;
133 char *p;
134 p=getsavfpname(n,0);
135 if((h=fopen(p,"wb"))==NULL) return;
136 myfwrite(s,1,24,h);myfwrite("\3\0",1,2,h);//myfwrite("\2\0",1,2,h);
137 G_savegame(h);
138 W_savegame(h);
139 DOT_savegame(h);
140 SMK_savegame(h);
141 FX_savegame(h);
142 IT_savegame(h);
143 MN_savegame(h);
144 PL_savegame(h);
145 SW_savegame(h);
146 WP_savegame(h);
147 fclose(h);
150 void F_loadgame(int n) {
151 FILE* h;
152 short ver;
153 char *p;
154 p=getsavfpname(n,1);
156 if((h=fopen(p,"rb"))==NULL) return;//if((h=open(fn,O_BINARY|O_RDONLY))==-1) return;
157 fseek(h,24,SEEK_SET);myfread(&ver,1,2,h);if(ver!=3) return;//if(ver!=2) return;
158 G_loadgame(h);
159 W_loadgame(h);
160 DOT_loadgame(h);
161 SMK_loadgame(h);
162 FX_loadgame(h);
163 IT_loadgame(h);
164 MN_loadgame(h);
165 PL_loadgame(h);
166 SW_loadgame(h);
167 WP_loadgame(h);
168 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) wad[i].n[0]=0;
202 logo(" подключается %s\n",wads[0]);
203 if((wadh[0]=h=fopen(wads[0],"rb"))==NULL)//if((wadh[0]=h=open(wads[0],O_RDWR|O_BINARY))==-1)
204 ERR_failinit("Не могу открыть файл: %s",wads[0]);//sys_errlist[errno]);
205 *s=0;myfread(s,1,4,h);
206 if(strncmp(s,"IWAD",4)!=0 && strncmp(s,"PWAD",4)!=0)
207 ERR_failinit("Нет подписи IWAD или PWAD");
208 myfread(&n,1,4,h);myfread(&o,1,4,h);fseek(h,o,SEEK_SET);
209 for(j=0,p=0;j<n;++j) {
210 myfread(&w,1,16,h);
211 if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а");
212 memcpy(wad[p].n,w.n,8);
213 wad[p].o=w.o;wad[p].l=w.l;wad[p].f=0;
214 ++p;
216 //fclose(h);
217 for(i=1;i<MAX_WADS;++i) if(wads[i][0]!=0) {
219 logo(" подключается %s\n",wads[i]);
220 if((wadh[i]=h=fopen(wads[i], "rb"))==NULL) //if((wadh[i]=h=open(wads[i],O_RDONLY|O_BINARY))==-1)
221 ERR_failinit("Не могу открыть файл2: %s",wads[i]);//sys_errlist[errno]);
222 mysplitpath(wads[i],f_drive,f_dir,f_name,f_ext);
223 if(strcasecmp(f_ext,".lmp")==0) {
224 for(k=0;k<MAX_WAD;++k) if(strncasecmp(wad[k].n,f_name,8)==0)
225 {wad[k].o=0L;wad[k].l=myfilelength(h);wad[k].f=i;break;}
226 if(k>=MAX_WAD) {
227 if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а");
228 memset(wad[p].n,0,8);
229 strncpy(wad[p].n,f_name,8);
230 wad[p].o=0L;wad[p].l=myfilelength(h);wad[p].f=i;
231 ++p;
233 continue;
235 *s=0;myfread(s,1,4,h);
236 if(strncmp(s,"IWAD",4)!=0 && strncmp(s,"PWAD",4)!=0)
237 ERR_failinit("Нет подписи IWAD или PWAD");
238 myfread(&n,1,4,h);myfread(&o,1,4,h);fseek(h,o,SEEK_SET);
239 for(j=0;j<n;++j) {
240 myfread(&w,1,16,h);
241 for(k=0;k<MAX_WAD;++k) if(strncasecmp(wad[k].n,w.n,8)==0)
242 {wad[k].o=w.o;wad[k].l=w.l;wad[k].f=i;break;}
243 if(k>=MAX_WAD) {
244 if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а");
245 memcpy(wad[p].n,w.n,8);
246 wad[p].o=w.o;wad[p].l=w.l;wad[p].f=i;
247 ++p;
251 wad_num=p;
255 // allocate resources
256 // (called from M_startup)
257 void F_allocres(void) {
258 d_start=F_getresid("D_START");
259 d_end=F_getresid("D_END");
260 m_start=F_getresid("M_START");
261 m_end=F_getresid("M_END");
262 s_start=F_getresid("S_START");
263 s_end=F_getresid("S_END");
266 // load resource
267 void F_loadres(int r,void *p,dword o,dword l) {
269 int oo;
270 FILE *fh;
273 oo=ftell(fh=wadh[wad[r].f]);
275 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
276 ERR_fatal("Ошибка при чтении файла");
278 if((dword)myfreadc(p,1,l,fh)!=l)
279 ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n);
281 fseek(fh,oo,SEEK_SET);
286 void F_saveres(int r,void *p,dword o,dword l) {
288 int oo;
289 FILE* fh;
290 oo=ftell(fh=wadh[wad[r].f]);
291 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
292 ERR_fatal("Ошибка при чтении файла");
293 myfwrite(p,l,1,fh);
294 fseek(fh,oo,SEEK_SET);
298 // get resource id
299 int F_getresid(char *n) {
300 int i;
302 for(i=0;i<wad_num;++i) if(strncasecmp(wad[i].n,n,8)==0) return i;
303 ERR_fatal("F_getresid: ресурс %.8s не найден",n);
304 return -1;
307 // get resource id
308 int F_findres(char *n) {
309 int i;
311 for(i=0;i<wad_num;++i) if(strncasecmp(wad[i].n,n,8)==0) return i;
312 return -1;
315 void F_getresname(char *n,int r) {
316 memcpy(n,wad[r].n,8);
319 // get sprite id
320 int F_getsprid(char n[4],int s,int d) {
321 int i;
322 byte a,b;
324 s+='A';d+='0';
325 for(i=s_start+1;i<s_end;++i)
326 if(strncasecmp(wad[i].n,n,4)==0 && (wad[i].n[4]==s || wad[i].n[6]==s)) {
327 if(wad[i].n[4]==s) a=wad[i].n[5]; else a=0;
328 if(wad[i].n[6]==s) b=wad[i].n[7]; else b=0;
329 if(a=='0') return i;
330 if(b=='0') return(i|0x8000);
331 if(a==d) return i;
332 if(b==d) return(i|0x8000);
334 ERR_fatal("F_getsprid: изображение %.4s%c%c не найдено",n,(byte)s,(byte)d);
335 return -1;
338 int F_getreslen(int r) {
339 return wad[r].l;
342 void F_nextmus(char *s) {
343 int i;
344 i=F_findres(s);
345 if(i<=m_start || i>=m_end) i=m_start;
346 for(++i;;++i) {
347 if(i>=m_end) i=m_start+1;
349 if (strcasecmp(wad[i].n,"MENU") == 0 ||
350 strcasecmp(wad[i].n,"INTERMUS") == 0 ||
351 strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0)
352 continue;
354 if(strncasecmp(wad[i].n,"DMI",3)!=0) break;
356 memcpy(s,wad[i].n,8);
359 void F_randmus(char *s) {
360 int n = myrand(10);
361 int i;
362 for (i=0; i<n; i++) {
363 F_nextmus(s);
367 // reads bytes from file until CR
368 void F_readstr(FILE* h,char *s,int m) {
369 int i;
370 static char c;
372 for(i=0;;) {
373 c=13;
374 myfreadc(&c,1,1,h);
375 if(c==13) break;
376 if(i<m) s[i++]=c;
378 s[i]=0;
381 // reads bytes from file until NUL
382 void F_readstrz(FILE* h,char *s,int m) {
383 int i;
384 static char c;
386 for(i=0;;) {
387 c=0;
388 myfreadc(&c,1,1,h);
389 if(c==0) break;
390 if(i<m) s[i++]=c;
392 s[i]=0;
395 map_block_t blk;
397 void F_loadmap(char n[8]) {
399 int r;
400 FILE *h;
401 map_header_t hdr;
402 int o;
404 W_init();
405 r=F_getresid(n);
406 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
407 myfread(&hdr,1,sizeof(hdr),h);
408 if(memcmp(hdr.id,"Doom2D\x1A",8)!=0)
409 ERR_fatal("%.8s не является уровнем",n);
410 for(;;) {
411 myfread(&blk,1,sizeof(blk),h);
412 if(blk.t==MB_END) break;
413 if(blk.t==MB_COMMENT)
414 {fseek(h,blk.sz,SEEK_CUR);continue;}
415 o=ftell(h)+blk.sz;
416 if(!G_load(h))
417 if(!W_load(h))
418 if(!IT_load(h))
419 if(!SW_load(h))
420 ERR_fatal("Неизвестный блок %d(%d) в уровне %.8s",blk.t,blk.st,n);
421 fseek(h,o,SEEK_SET);
426 /*void F_freemus(void) {
428 int i;
430 if(!pat) return;
431 S_stopmusic();
432 free(pat);free(patp);
433 for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
434 free(dmi);
435 pat=NULL;
438 */
440 /*void F_loadmus(char n[8]) {
441 int r,i,j;
442 FILE *h;
443 int o;
444 struct{
445 char id[4];
446 byte ver,pat;
447 word psz;
448 }d;
449 struct{byte t;char n[13];word r;}di;
451 if((r=F_findres(n))==-1) return;
452 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
453 myfread(&d,1,sizeof(d),h);
454 if(memcmp(d.id,"DMM",4)!=0) return;
455 if(!(pat=malloc(d.psz<<2))) return;
456 myfread(pat,1,d.psz<<2,h);
457 myfread(&seqn,1,1,h);if(seqn) myfread(seq,1,seqn,h);
458 inum=0;myfread(&inum,1,1,h);
459 if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
460 if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
461 for(i=0;i<inum;++i) {
462 dmi[i]=NULL;
463 myfread(&di,1,16,h);o=ftell(h);
464 for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
465 if((r=F_findres(di.n))==-1) continue;
466 if(!(dmi[i]=malloc(wad[r].l+8))) continue;
467 memset(dmi[i],0,16);
468 F_loadres(r,dmi[i],0,2);
469 F_loadres(r,(int*)dmi[i]+1,2,2);
470 F_loadres(r,(int*)dmi[i]+2,4,2);
471 F_loadres(r,(int*)dmi[i]+3,6,2);
472 F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
473 fseek(h,o,SEEK_SET);
475 for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
476 patp[i]=r<<2;
477 while(pat[r++].v!=0x80);
480 */