DEADSOFTWARE

update copyrights
[flatwaifu.git] / src / files.c
1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
18 #include "glob.h"
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <sys/stat.h>
23 #include "files.h"
24 #include "map.h"
25 #include "my.h"
26 #include "game.h"
27 #include "view.h"
28 #include "dots.h"
29 #include "smoke.h"
30 #include "fx.h"
31 #include "items.h"
32 #include "monster.h"
33 #include "player.h"
34 #include "switch.h"
35 #include "weapons.h"
36 #include "error.h"
37 #include "cp866.h"
39 typedef struct {
40 byte n, i, v, d;
41 } dmv;
43 int d_start, d_end;
44 mwad_t wad[MAX_WAD];
45 char wads[MAX_WADS][__MAX_PATH];
46 FILE* wadh[MAX_WADS];
48 static byte seq[255];
49 static byte seqn;
50 static int inum=0;
51 static dmv *pat=NULL;
52 static unsigned *patp;
53 static void **dmi;
55 static int m_start, m_end;
56 static int s_start, s_end;
57 static int wad_num;
59 static char f_drive[__MAX_DRIVE];
60 static char f_dir[__MAX_DIR];
61 static char f_name[__MAX_FNAME];
62 static char f_ext[__MAX_EXT];
64 void F_startup (void) {
65 logo("F_startup: настройка файловой системы\n");
66 memset(wads,0,sizeof(wads));
67 }
69 void F_addwad (const char *fn) {
70 int i;
72 for(i=0;i<MAX_WADS;++i) if(wads[i][0]==0) {
73 strcpy(wads[i],fn);return;
74 }
75 ERR_failinit("Не могу добавить WAD %s",fn);
76 }
78 static int myfilelength (FILE *h) {
79 int pos = ftell(h);
80 fseek (h, 0, SEEK_END);
81 int len = ftell(h);
82 fseek (h, pos, SEEK_SET);
83 return len;
84 }
86 // build wad directory
87 void F_initwads (void) {
88 int i, j, k, p;
89 FILE *h;
90 char s[4];
91 int n, o;
92 wad_t w;
94 logo("F_initwads: подключение WAD-файлов\n");
95 for (i = 0; i < MAX_WAD; ++i) {
96 wad[i].n[0] = 0;
97 }
99 logo(" подключается %s\n", wads[0]);
100 if ((wadh[0] = h = fopen(wads[0], "rb")) == NULL) {
101 ERR_failinit("Не могу открыть файл: %s", wads[0]);
104 s[0] = '\0';
105 myfread(s, 1, 4, h);
106 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
107 ERR_failinit("Нет подписи IWAD или PWAD (1)");
110 p = 0; // wad number
111 n = myfread32(h); // num
112 o = myfread32(h); // offset
113 fseek(h, o, SEEK_SET);
114 for (j = 0; j < n; ++j) {
115 w.o = myfread32(h); // offset
116 w.l = myfread32(h); // len
117 myfread(w.n, 1, 8, h); // name
118 if (p >= MAX_WAD) {
119 ERR_failinit("Слишком много элементов WAD'а");
121 wad[p].o = w.o;
122 wad[p].l = w.l;
123 memcpy(wad[p].n, w.n, 8);
124 wad[p].f = 0;
125 ++p;
128 //fclose(h);
130 for (i = 1; i < MAX_WADS; ++i) {
131 if (wads[i][0] != 0) {
132 logo(" подключается %s\n", wads[i]);
133 if ((wadh[i] = h = fopen(wads[i], "rb")) == NULL) {
134 ERR_failinit("Не могу открыть файл2: %s", wads[i]);
136 mysplitpath(wads[i], f_drive, f_dir, f_name, f_ext);
137 if (cp866_strcasecmp(f_ext, ".lmp") == 0) {
138 for (k = 0; k < MAX_WAD; ++k) {
139 if (cp866_strncasecmp(wad[k].n, f_name, 8) == 0) {
140 wad[k].o = 0;
141 wad[k].l = myfilelength(h);
142 wad[k].f = i;
143 break;
145 if (k >= MAX_WAD) {
146 if (p >= MAX_WAD) {
147 ERR_failinit("Слишком много элементов WAD'а");
149 memset(wad[p].n, 0, 8);
150 strncpy(wad[p].n, f_name, 8);
151 wad[p].o = 0;
152 wad[p].l = myfilelength(h);
153 wad[p].f = i;
154 ++p;
158 s[0] = '\0';
159 myfread(s, 1, 4, h);
160 if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) {
161 ERR_failinit("Нет подписи IWAD или PWAD (2)");
163 n = myfread32(h); // num
164 o = myfread32(h); // offset
165 fseek(h, o, SEEK_SET);
166 for (j = 0; j < n; ++j) {
167 w.o = myfread32(h); // offset
168 w.o = myfread32(h); // len
169 myfread(w.n, 1, 8, h); // name
170 for (k = 0; k < MAX_WAD; ++k) {
171 if (cp866_strncasecmp(wad[k].n, w.n, 8) == 0) {
172 wad[k].o = w.o;
173 wad[k].l = w.l;
174 wad[k].f = i;
175 break;
177 if (k >= MAX_WAD) {
178 if (p >= MAX_WAD) {
179 ERR_failinit("Слишком много элементов WAD'а");
181 memcpy(wad[p].n, w.n, 8);
182 wad[p].o = w.o;
183 wad[p].l = w.l;
184 wad[p].f = i;
185 ++p;
193 wad_num = p;
196 // allocate resources
197 // (called from M_startup)
198 void F_allocres (void) {
199 d_start=F_getresid("D_START");
200 d_end=F_getresid("D_END");
201 m_start=F_getresid("M_START");
202 m_end=F_getresid("M_END");
203 s_start=F_getresid("S_START");
204 s_end=F_getresid("S_END");
207 // load resource
208 void F_loadres (int r, void *p, dword o, dword l) {
210 int oo;
211 FILE *fh;
214 oo=ftell(fh=wadh[wad[r].f]);
216 if(fseek(fh,wad[r].o+o,SEEK_SET)!=0)
217 ERR_fatal("Ошибка при чтении файла");
219 if((dword)myfreadc(p,1,l,fh)!=l)
220 ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n);
222 fseek(fh,oo,SEEK_SET);
226 /*
227 // unused
228 void F_saveres(int r, void *p, dword o, dword l) {
229 FILE* fh = wadh[wad[r].f];
230 int oo = ftell(fh);
231 if (fseek(fh, wad[r].o + o, SEEK_SET) != 0) {
232 ERR_fatal("Ошибка при чтении файла");
234 myfwrite(p, l, 1, fh);
235 fseek(fh, oo, SEEK_SET);
237 */
239 // get resource id
240 int F_findres (const char n[8]) {
241 int i;
242 for (i = 0; i < wad_num; i++) {
243 if (cp866_strncasecmp(wad[i].n, n, 8) == 0) {
244 return i;
247 return -1;
250 // get resource id
251 int F_getresid (const char n[8]) {
252 int i = F_findres(n);
253 if (i == -1) {
254 ERR_fatal("F_getresid: ресурс %.8s не найден", n);
256 return i;
259 void F_getresname (char n[8], int r) {
260 memcpy(n, wad[r].n, 8);
263 // get sprite id
264 int F_getsprid (const char n[4], int s, int d, char *dir) {
265 int i;
266 byte a, b;
267 s += 'A';
268 d += '0';
269 for (i = s_start + 1; i < s_end; i++) {
270 if (cp866_strncasecmp(wad[i].n, n, 4) == 0 && (wad[i].n[4] == s || wad[i].n[6] == s)) {
271 a = wad[i].n[4] == s ? wad[i].n[5] : 0;
272 b = wad[i].n[6] == s ? wad[i].n[7] : 0;
273 if (a == '0' || b == '0' || a == d || b == d) {
274 if (dir != NULL) {
275 *dir = a != '0' && b == '0' || a != d && b == d;
277 return i;
281 ERR_fatal("F_getsprid: image %.4s%c%c not found", n, s, d);
282 return -1;
285 int F_getreslen (int r) {
286 return wad[r].l;
289 void F_nextmus (char *s) {
290 int i;
291 i=F_findres(s);
292 if(i<=m_start || i>=m_end) i=m_start;
293 for(++i;;++i) {
294 if(i>=m_end) i=m_start+1;
296 if (cp866_strcasecmp(wad[i].n,"MENU") == 0 ||
297 cp866_strcasecmp(wad[i].n,"INTERMUS") == 0 ||
298 cp866_strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0)
299 continue;
301 if(cp866_strncasecmp(wad[i].n,"DMI",3)!=0) break;
303 memcpy(s,wad[i].n,8);
306 void F_randmus (char *s) {
307 int i;
308 int n = myrand(10);
309 for (i = 0; i < n; i++) {
310 F_nextmus(s);
314 // reads bytes from file until CR
315 void F_readstr (FILE* h, char *s, int m) {
316 int i = 0;
317 size_t len = 0;
318 static char c = 0;
319 while (i < m) {
320 c = 13;
321 len = myfreadc(&c, 1, 1, h);
322 if (len == 0 || c == 13 || c == 10) {
323 break;
325 s[i] = c;
326 i++;
328 s[i] = 0;
331 /*
332 // unused
333 // reads bytes from file until NUL
334 void F_readstrz (FILE* h,char *s,int m) {
335 int i = 0;
336 size_t len = 0;
337 static char c = 0;
338 while (i < m) {
339 c = 0;
340 len = myfreadc(&c, 1, 1, h);
341 if (len == 0 || c == 0) {
342 break;
344 s[i] = c;
345 i++;
347 s[i] = 0;
349 */
351 /*void F_freemus(void) {
353 int i;
355 if(!pat) return;
356 S_stopmusic();
357 free(pat);free(patp);
358 for(i=0;i<inum;++i) if(dmi[i]!=NULL) free(dmi[i]);
359 free(dmi);
360 pat=NULL;
363 */
365 /*void F_loadmus(char n[8]) {
366 int r,i,j;
367 FILE *h;
368 int o;
369 struct{
370 char id[4];
371 byte ver,pat;
372 word psz;
373 }d;
374 struct{byte t;char n[13];word r;}di;
376 if((r=F_findres(n))==-1) return;
377 fseek(h=wadh[wad[r].f],wad[r].o,SEEK_SET);
378 myfread(&d,1,sizeof(d),h);
379 if(memcmp(d.id,"DMM",4)!=0) return;
380 if(!(pat=malloc(d.psz<<2))) return;
381 myfread(pat,1,d.psz<<2,h);
382 myfread(&seqn,1,1,h);if(seqn) myfread(seq,1,seqn,h);
383 inum=0;myfread(&inum,1,1,h);
384 if(!(dmi=malloc(inum*4))) {free(pat);pat=NULL;return;}
385 if(!(patp=malloc((word)d.pat*32))) {free(pat);free(dmi);pat=NULL;return;}
386 for(i=0;i<inum;++i) {
387 dmi[i]=NULL;
388 myfread(&di,1,16,h);o=ftell(h);
389 for(r=0;r<12;++r) if(di.n[r]=='.') di.n[r]=0;
390 if((r=F_findres(di.n))==-1) continue;
391 if(!(dmi[i]=malloc(wad[r].l+8))) continue;
392 memset(dmi[i],0,16);
393 F_loadres(r,dmi[i],0,2);
394 F_loadres(r,(int*)dmi[i]+1,2,2);
395 F_loadres(r,(int*)dmi[i]+2,4,2);
396 F_loadres(r,(int*)dmi[i]+3,6,2);
397 F_loadres(r,(int*)dmi[i]+4,8,wad[r].l-8);
398 fseek(h,o,SEEK_SET);
400 for(i=r=0,j=(word)d.pat<<3;i<j;++i) {
401 patp[i]=r<<2;
402 while(pat[r++].v!=0x80);
405 */