install: add install sources and resources
[doom2d-restoration.git] / GAME / FILES.C
blobeee21052dfd0d50a71ef5f376a96078b30dbe8c7
1 #include "glob.h"
2 #include <stdio.h>
3 #include <conio.h>
4 #include <malloc.h>
5 #include <dos.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <sys\stat.h>
9 #include "vga.h"
10 #include "error.h"
11 #include "sound.h"
12 #include "snddrv.h"
13 #include "memory.h"
14 #include "view.h"
15 #include "items.h"
16 #include "switch.h"
17 #include "files.h"
18 #include "map.h"
20 char *S_getinfo(void);
22 extern void *snd_drv;
24 typedef struct{
25   byte n,i,v,d;
26 }dmv;
28 byte seq[255],seqn;
29 dmv *pat=NULL;
30 unsigned *patp;
31 void **dmi;
33 static int inum=0;
35 void G_savegame(int);
36 void W_savegame(int);
37 void DOT_savegame(int);
38 void SMK_savegame(int);
39 void FX_savegame(int);
40 void IT_savegame(int);
41 void MN_savegame(int);
42 void PL_savegame(int);
43 void SW_savegame(int);
44 void WP_savegame(int);
46 void G_loadgame(int);
47 void W_loadgame(int);
48 void DOT_loadgame(int);
49 void SMK_loadgame(int);
50 void FX_loadgame(int);
51 void IT_loadgame(int);
52 void MN_loadgame(int);
53 void PL_loadgame(int);
54 void SW_loadgame(int);
55 void WP_loadgame(int);
57 byte savname[7][24],savok[7];
59 int d_start,d_end,m_start,m_end,s_start,s_end,wad_num;
60 mwad_t wad[MAX_WAD];
62 static char wads[MAX_WADS][_MAX_PATH];
63 static int wadh[MAX_WADS];
65 char f_drive[_MAX_DRIVE],f_dir[_MAX_DIR],f_name[_MAX_FNAME],f_ext[_MAX_EXT],
66   f_path[_MAX_PATH];
68 void F_startup(void) {
69   logo("F_startup: настройка файловой системы\n");
70   memset(wads,0,sizeof(wads));
73 void F_getsavnames(void) {
74   int i,h;
75   static char n[]="SAVGAME0.DAT";
76   short ver;
78   for(i=0;i<7;++i) {
79     n[7]=i+'0';memset(savname[i],0,24);savok[i]=0;
80     if((h=open(n,O_RDONLY|O_BINARY))==-1) continue;
81     read(h,savname[i],24);ver=-1;read(h,&ver,2);
82     close(h);savname[i][23]=0;savok[i]=(ver==2)?1:0;
83   }
86 void F_savegame(int n,char *s) {
87   int h;
88   static char fn[]="SAVGAME0.DAT";
90   fn[7]=n+'0';
91   if((h=open(fn,O_BINARY|O_CREAT|O_RDWR|O_TRUNC,S_IREAD|S_IWRITE))==-1) return;
92   write(h,s,24);write(h,"\2\0",2);
93   G_savegame(h);
94   W_savegame(h);
95   DOT_savegame(h);
96   SMK_savegame(h);
97   FX_savegame(h);
98   IT_savegame(h);
99   MN_savegame(h);
100   PL_savegame(h);
101   SW_savegame(h);
102   WP_savegame(h);
103   close(h);
106 void F_loadgame(int n) {
107   int h;
108   static char fn[]="SAVGAME0.DAT";
109   short ver;
111   fn[7]=n+'0';
112   if((h=open(fn,O_BINARY|O_RDONLY))==-1) return;
113   lseek(h,24,SEEK_SET);read(h,&ver,2);if(ver!=2) return;
114   G_loadgame(h);
115   W_loadgame(h);
116   DOT_loadgame(h);
117   SMK_loadgame(h);
118   FX_loadgame(h);
119   IT_loadgame(h);
120   MN_loadgame(h);
121   PL_loadgame(h);
122   SW_loadgame(h);
123   WP_loadgame(h);
124   close(h);
127 void F_set_snddrv(void) {
128   snd_card=(snd_card>=SDRV__END)?0:snd_card;
129   logo("F_set_snddrv: звуковая карта #%d\n",snd_card);
130   snd_drv=snd_drv_tab[snd_card];
131   logo("  %s ",S_getinfo());
132   if(snd_card) logo("(%dГц)\n",(dword)sfreq);
133     else logo("\n");
136 void F_addwad(char *fn) {
137   int i;
139   for(i=0;i<MAX_WADS;++i) if(wads[i][0]==0) {
140     strcpy(wads[i],fn);return;
141   }
142   ERR_failinit("Не могу добавить WAD %s",fn);
145 // build wad directory
146 void F_initwads(void) {
147   int i,j,k,h,p;
148   char s[4];
149   long n,o;
150   wad_t w;
152   logo("F_initwads: подключение WAD-файлов\n");
153   for(i=0;i<MAX_WAD;++i) wad[i].n[0]=0;
154   logo("  подключается %s\n",wads[0]);
155   if((wadh[0]=h=open(wads[0],O_RDWR|O_BINARY))==-1)
156         ERR_failinit("Не могу открыть файл: %s",sys_errlist[errno]);
157   *s=0;read(h,s,4);
158   if(strncmp(s,"IWAD",4)!=0 && strncmp(s,"PWAD",4)!=0)
159         ERR_failinit("Нет подписи IWAD или PWAD");
160   read(h,&n,4);read(h,&o,4);lseek(h,o,SEEK_SET);
161   for(j=0,p=0;j<n;++j) {
162         read(h,&w,16);
163         if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а");
164         memcpy(wad[p].n,w.n,8);
165         wad[p].o=w.o;wad[p].l=w.l;wad[p].f=0;
166         ++p;
167   }
168   for(i=1;i<MAX_WADS;++i) if(wads[i][0]!=0) {
169         logo("  подключается %s\n",wads[i]);
170         if((wadh[i]=h=open(wads[i],O_RDONLY|O_BINARY))==-1)
171           ERR_failinit("Не могу открыть файл: %s",sys_errlist[errno]);
172         _splitpath(wads[i],f_drive,f_dir,f_name,f_ext);
173         if(stricmp(f_ext,".lmp")==0) {
174           for(k=0;k<MAX_WAD;++k) if(strnicmp(wad[k].n,f_name,8)==0)
175                 {wad[k].o=0L;wad[k].l=filelength(h);wad[k].f=i;break;}
176           if(k>=MAX_WAD) {
177                 if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а");
178                 memset(wad[p].n,0,8);
179                 strncpy(wad[p].n,f_name,8);
180                 wad[p].o=0L;wad[p].l=filelength(h);wad[p].f=i;
181                 ++p;
182           }
183           continue;
184         }
185         *s=0;read(h,s,4);
186         if(strncmp(s,"IWAD",4)!=0 && strncmp(s,"PWAD",4)!=0)
187           ERR_failinit("Нет подписи IWAD или PWAD");
188     read(h,&n,4);read(h,&o,4);lseek(h,o,SEEK_SET);
189     for(j=0;j<n;++j) {
190           read(h,&w,16);
191           for(k=0;k<MAX_WAD;++k) if(strnicmp(wad[k].n,w.n,8)==0)
192                 {wad[k].o=w.o;wad[k].l=w.l;wad[k].f=i;break;}
193           if(k>=MAX_WAD) {
194                 if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а");
195                 memcpy(wad[p].n,w.n,8);
196                 wad[p].o=w.o;wad[p].l=w.l;wad[p].f=i;
197                 ++p;
198       }
199     }
200   }
201   wad_num=p;
204 // allocate resources
205 // (called from M_startup)
206 void F_allocres(void) {
207 //  int i;
209   d_start=F_getresid("D_START");
210   d_end=F_getresid("D_END");
211   m_start=F_getresid("M_START");
212   m_end=F_getresid("M_END");
213   s_start=F_getresid("S_START");
214   s_end=F_getresid("S_END");
215 //  if(d_end<d_start) ERR_failinit("D_END is before D_START");
216 //  if(m_end<m_start) ERR_failinit("M_END is before M_START");
217 /*  for(i=0;i<wad_num;++i) {
218     restab[i].l=0;
219     if(!wad[i].l) continue;
220         if(memicmp(wad[i].n,"PLAYPAL",8)==0) continue;
221         if(memicmp(wad[i].n,"COLORMAP",8)==0) continue;
222         if(memicmp(wad[i].n,"MAP",3)==0) continue;
223         if(!w_horiz && memicmp(wad[i].n,"RSKY",4)==0) continue;
224         if(i>m_start && i<m_end) continue;
225         if(i>d_start && i<d_end)
226       if(snd_type==-1) continue;
227           else if((snd_type==0 || snd_type==1) && wad[i].n[1]!='S') continue;
228         restab[i].l=wad[i].l;
229   }*/
233 // preload blocks
234 void F_preload(void) {
235   int i,c;
237   logo("F_preload: preload WAD resources\n");
238   logo("  loading ");
239   for(i=0;i<res_size && i<ems_size;++i) {
240         logo_gas(i+1,res_size);
241         if(kbhit()) if((c=getch())==27) ERR_failinit("\nUser break");
242         else if(c==0) getch();
243         M_loadblock(i);
244   }
245   logo("\n");
249 // load resource
250 void F_loadres(int r,void *p,dword o,dword l) {
251   int fh,oo;
253   oo=tell(fh=wadh[wad[r].f]);
254   if(lseek(fh,wad[r].o+o,SEEK_SET)==-1L)
255     ERR_fatal("Ошибка при чтении файла");
256   if((dword)read(fh,p,l)!=l)
257     ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n);
258   lseek(fh,oo,SEEK_SET);
261 void F_saveres(int r,void *p,dword o,dword l) {
262   int fh,oo;
264   oo=tell(fh=wadh[wad[r].f]);
265   if(lseek(fh,wad[r].o+o,SEEK_SET)==-1L)
266     ERR_fatal("Ошибка при чтении файла");
267   write(fh,p,l);
268   lseek(fh,oo,SEEK_SET);
271 // get resource id
272 int F_getresid(char *n) {
273   int i;
275   for(i=0;i<wad_num;++i) if(strnicmp(wad[i].n,n,8)==0) return i;
276   ERR_fatal("F_getresid: ресурс %.8s не найден",n);
277   return -1;
280 // get resource id
281 int F_findres(char *n) {
282   int i;
284   for(i=0;i<wad_num;++i) if(strnicmp(wad[i].n,n,8)==0) return i;
285   return -1;
288 void F_getresname(char *n,int r) {
289   memcpy(n,wad[r].n,8);
292 // get sprite id
293 int F_getsprid(char n[4],int s,int d) {
294   int i;
295   byte a,b;
297   s+='A';d+='0';
298   for(i=s_start+1;i<s_end;++i)
299     if(memicmp(wad[i].n,n,4)==0 && (wad[i].n[4]==s || wad[i].n[6]==s)) {
300       if(wad[i].n[4]==s) a=wad[i].n[5]; else a=0;
301       if(wad[i].n[6]==s) b=wad[i].n[7]; else b=0;
302       if(a=='0') return i;
303       if(b=='0') return(i|0x8000);
304       if(a==d) return i;
305       if(b==d) return(i|0x8000);
306     }
307   ERR_fatal("F_getsprid: изображение %.4s%c%c не найдено",n,(byte)s,(byte)d);
308   return -1;
311 int F_getreslen(int r) {
312   return wad[r].l;
315 void F_nextmus(char *s) {
316   int i;
318   i=F_findres(s);
319   if(i<=m_start || i>=m_end) i=m_start;
320   for(++i;;++i) {
321     if(i>=m_end) i=m_start+1;
322     if(memicmp(wad[i].n,"DMI",3)!=0) break;
323   }
324   memcpy(s,wad[i].n,8);
327 // reads bytes from file until CR
328 void F_readstr(int h,char *s,int m) {
329   int i;
330   static char c;
332   for(i=0;;) {
333     c=13;
334     read(h,&c,1);
335     if(c==13) break;
336     if(i<m) s[i++]=c;
337   }
338   s[i]=0;
341 // reads bytes from file until NUL
342 void F_readstrz(int h,char *s,int m) {
343   int i;
344   static char c;
346   for(i=0;;) {
347     c=0;
348     read(h,&c,1);
349     if(c==0) break;
350     if(i<m) s[i++]=c;
351   }
352   s[i]=0;
355 map_block_t blk;
357 void F_loadmap(char n[8]) {
358   int r,h;
359   map_header_t hdr;
360   int o;
362   W_init();
363   r=F_getresid(n);
364   lseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
365   read(h,&hdr,sizeof(hdr));
366   if(memcmp(hdr.id,"Doom2D\x1A",8)!=0)
367         ERR_fatal("%.8s не является уровнем",n);
368   for(;;) {
369         read(h,&blk,sizeof(blk));
370         if(blk.t==MB_END) break;
371         if(blk.t==MB_COMMENT)
372           {lseek(h,blk.sz,SEEK_CUR);continue;}
373         o=tell(h)+blk.sz;
374         if(!G_load(h))
375         if(!W_load(h))
376         if(!IT_load(h))
377         if(!SW_load(h))
378           ERR_fatal("Неизвестный блок %d(%d) в уровне %.8s",blk.t,blk.st,n);
379         lseek(h,o,SEEK_SET);
380   }
383 void F_freemus(void) {
384   int i;
386   if(!pat) return;
387   S_stopmusic();
388   free(pat);free(patp);
389   for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
390   free(dmi);
391   pat=NULL;
394 void F_loadmus(char n[8]) {
395   int r,h,i,j;
396   int o;
397   struct{
398         char id[4];
399         byte ver,pat;
400         word psz;
401   }d;
402   struct{byte t;char n[13];word r;}di;
404   if((r=F_findres(n))==-1) return;
405   lseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
406   read(h,&d,sizeof(d));
407   if(memcmp(d.id,"DMM",4)!=0) return;
408   if(!(pat=malloc(d.psz<<2))) return;
409   read(h,pat,d.psz<<2);
410   read(h,&seqn,1);if(seqn) read(h,seq,seqn);
411   inum=0;read(h,&inum,1);
412   if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
413   if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
414   for(i=0;i<inum;++i) {
415         dmi[i]=NULL;
416         read(h,&di,16);o=tell(h);
417         for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
418         if((r=F_findres(di.n))==-1) continue;
419         if(!(dmi[i]=malloc(wad[r].l+8))) continue;
420         memset(dmi[i],0,16);
421         F_loadres(r,dmi[i],0,2);
422         F_loadres(r,(int*)dmi[i]+1,2,2);
423         F_loadres(r,(int*)dmi[i]+2,4,2);
424         F_loadres(r,(int*)dmi[i]+3,6,2);
425         F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
426         lseek(h,o,SEEK_SET);
427   }
428   for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
429         patp[i]=r<<2;
430         while(pat[r++].v!=0x80);
431   }