DEADSOFTWARE

files: add F_getsprid description
[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 <assert.h>
23 #include "files.h"
24 #include "error.h"
26 #include "map.h" // MAP_load
27 #include "save.h" // SAVE_getname
29 #ifdef UNIX
30 # include <sys/stat.h>
31 #endif
33 #include "common/streams.h"
34 #include "common/files.h"
35 #include "common/wadres.h"
36 #include "common/cp866.h"
38 int d_start, d_end;
40 char savname[SAVE_MAX][SAVE_MAXLEN];
41 char savok[SAVE_MAX];
43 static int m_start, m_end;
44 static int s_start, s_end;
46 void F_addwad (const char *fn) {
47 static int i = 0;
48 static FILE_Stream wadh[MAX_WADS];
49 if (i < MAX_WADS) {
50 if (FILE_Open(&wadh[i], fn, "rb")) {
51 if (WADRES_addwad(&wadh[i].base)) {
52 i += 1;
53 } else {
54 ERR_failinit("Invalid WAD %s", fn);
55 }
56 } else {
57 ERR_failinit("Unable to add WAD %s", fn);
58 }
59 } else {
60 ERR_failinit("Too many wads");
61 }
62 }
64 void F_initwads (void) {
65 if (!WADRES_rehash()) {
66 ERR_failinit("F_initwads: failed rehash");
67 }
68 d_start = F_getresid("D_START");
69 d_end = F_getresid("D_END");
70 m_start = F_getresid("M_START");
71 m_end = F_getresid("M_END");
72 s_start = F_getresid("S_START");
73 s_end = F_getresid("S_END");
74 }
76 int F_findres (const char n[8]) {
77 return WADRES_find(n);
78 }
80 int F_getresid (const char n[8]) {
81 int i = F_findres(n);
82 if (i == -1) {
83 ERR_fatal("F_getresid: resource %.8s not found", n);
84 }
85 return i;
86 }
88 void F_getresname (char n[8], int r) {
89 WADRES_getname(r, n);
90 }
92 // Get sprite resource id.
93 // Sprite name has following format:
94 // (nnnn)('A'+s)('0'+d)[('A'+s)('0'+d)]
95 // Letter means animation frame
96 // A for first, B for second...
97 // Number means direction
98 // 0 = front
99 // 1 = left
100 // 2 = right
101 // Optional part means that this file can be used for differnt frame/direction.
102 // Note that if found FRONT direction for this frame than it UNCONDITIONALLY used.
103 // Note that search performed between markers S_START and S_END in order as paced in wad.
104 // int n[4] -- sprite name
105 // int s -- sprite frame
106 // int d -- sprite direction
107 // char *dir -- out flag "alternative used" (
108 int F_getsprid (const char n[4], int s, int d, char *dir) {
109 s += 'A';
110 d += '0';
111 for (int i = s_start + 1; i < s_end; i++) {
112 char wn[8];
113 byte a, b;
114 WADRES_getname(i, wn);
115 if (cp866_strncasecmp(wn, n, 4) == 0 && (wn[4] == s || wn[6] == s)) {
116 a = wn[4] == s ? wn[5] : 0;
117 b = wn[6] == s ? wn[7] : 0;
118 if (a == '0' || b == '0' || a == d || b == d) {
119 if (dir != NULL) {
120 *dir = (a != '0' && b == '0') || (a != d && b == d);
122 return i;
126 ERR_fatal("F_getsprid: image %.4s%c%c not found", n, s, d);
127 return -1;
130 int F_getreslen (int r) {
131 return WADRES_getsize(r);
134 /*
135 void F_nextmus (char *s) {
136 int i = F_findres(s);
137 if (i <= m_start || i >= m_end) {
138 i = m_start;
140 for (++i; ; ++i) {
141 if (i >= m_end) {
142 i = m_start + 1;
144 WADRES_getname(i, s);
145 if (cp866_strcasecmp(s, "MENU") == 0 ||
146 cp866_strcasecmp(s, "INTERMUS") == 0 ||
147 cp866_strcasecmp(s, "\x8a\x8e\x8d\x85\x96\x0") == 0) {
148 continue;
150 if (cp866_strncasecmp(s, "DMI", 3) != 0) {
151 break;
156 void F_randmus (char *s) {
157 int i;
158 int n = myrand(10);
159 for (i = 0; i < n; i++) {
160 F_nextmus(s);
163 */
165 void F_loadmap (char n[8]) {
166 int id = F_getresid(n);
167 if (id != -1) {
168 Stream *r = WADRES_getbasereader(id);
169 long offset = WADRES_getoffset(id);
170 stream_setpos(r, offset);
171 if (!MAP_load(r)) {
172 ERR_fatal("Failed to load map");
174 } else {
175 ERR_fatal("Failed to load map: resource %.8s not found", n);
179 static char *getsavfpname (int n, int ro) {
180 static char fn[] = "savgame0.dat";
181 static char p[100];
182 fn[7] = n + '0';
183 #ifdef UNIX
184 char *e = getenv("HOME");
185 strncpy(p, e, 60);
186 strcat(p, "/.flatwaifu");
187 if (!ro) {
188 mkdir(p, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
190 strcat(p, "/");
191 strcat(p, fn);
192 #else
193 strcpy(p, fn);
194 #endif
195 return p;
198 void F_getsavnames (void) {
199 FILE_Stream rd;
200 for (int i = 0; i < SAVE_MAX; ++i) {
201 savok[i] = 0;
202 char *p = getsavfpname(i, 1);
203 if (FILE_Open(&rd, p, "rb")) {
204 savok[i] = SAVE_getname(&rd.base, savname[i]);
205 FILE_Close(&rd);
207 if (!savok[i]) {
208 memset(savname[i], 0, 24);
209 } else {
210 savname[i][23] = 0;
215 void F_loadgame (int n) {
216 FILE_Stream rd;
217 char *p = getsavfpname(n, 1);
218 if (FILE_Open(&rd, p, "rb")) {
219 SAVE_load(&rd.base);
220 FILE_Close(&rd);
224 void F_savegame (int n, char *s) {
225 FILE_Stream wr;
226 char *p = getsavfpname(n, 0);
227 if (FILE_Open(&wr, p, "wb")) {
228 SAVE_save(&wr.base, s);
229 FILE_Close(&wr);