DEADSOFTWARE

5861fe5f41c093247088eb343fc9ef7f408cb024
[flatwaifu.git] / src / common / wadres.c
1 #include <stdint.h>
2 #include <string.h>
3 #include <assert.h>
5 #include "wadres.h"
6 #include "streams.h"
7 #include "cp866.h"
9 typedef struct Entry {
10 long offset, size;
11 char name[8];
12 int f;
13 } Entry;
15 static int n_wads;
16 static int n_resources;
17 static Stream *wads[MAX_WADS];
18 static Entry resources[MAX_RESOURCES];
20 static int check_header (Stream *r) {
21 assert(r != NULL);
22 char ident[4];
23 stream_setpos(r, 0); // !!!
24 stream_read(ident, 4, 1, r);
25 return (memcmp(ident, "IWAD", 4) == 0) || (memcmp(ident, "PWAD", 4) == 0);
26 }
28 int WADRES_addwad (Stream *r) {
29 assert(r != NULL);
30 if (n_wads < MAX_WADS && check_header(r)) {
31 wads[n_wads] = r;
32 n_wads += 1;
33 return 1;
34 } else {
35 return 0;
36 }
37 }
39 static int WADRES_addresource (const Entry *e) {
40 assert(e != NULL);
41 for (int i = 0; i < n_resources; ++i) {
42 if (cp866_strncasecmp(resources[i].name, e->name, 8) == 0) {
43 memcpy(&resources[i], e, sizeof(Entry));
44 return i;
45 }
46 }
47 if (n_resources < MAX_RESOURCES) {
48 memcpy(&resources[n_resources], e, sizeof(Entry));
49 n_resources += 1;
50 return n_resources - 1;
51 }
52 return -1;
53 }
55 static int WADRES_read (Stream *r) {
56 stream_setpos(r, 4); // skip magic
57 int32_t n = stream_read32(r);
58 int32_t dir = stream_read32(r);
59 stream_setpos(r, dir);
60 int ok = 1;
61 for (int32_t i = 0; ok && i < n; ++i) {
62 Entry e;
63 e.offset = stream_read32(r);
64 e.size = stream_read32(r);
65 stream_read(e.name, 8, 1, r);
66 ok = WADRES_addresource(&e) != -1;
67 }
68 return ok;
69 }
71 int WADRES_rehash (void) {
72 int ok = 1;
73 for (int i = 0; i < n_wads; ++i) {
74 if (!WADRES_read(wads[i])) {
75 ok = 0;
76 }
77 }
78 return ok;
79 }
81 int WADRES_find (const char name[8]) {
82 int i = n_resources - 1;
83 while (i >= 0 && cp866_strncasecmp(name, resources[i].name, 8) != 0) {
84 i -= 1;
85 }
86 return i;
87 }
89 int WADRES_maxids (void) {
90 return n_resources;
91 }
93 Stream *WADRES_getbasereader (int id) {
94 assert(id >= 0 && id < n_resources);
95 return wads[resources[id].f];
96 }
98 long WADRES_getoffset (int id) {
99 assert(id >= 0 && id < n_resources);
100 return resources[id].offset;
103 long WADRES_getsize (int id) {
104 assert(id >= 0 && id < n_resources);
105 return resources[id].size;
108 void WADRES_getname (int id, char *name) {
109 assert(id >= 0 && id < n_resources);
110 strncpy(name, resources[id].name, 8);
113 void WADRES_getdata (int id, void *data) {
114 assert(id >= 0 && id < n_resources);
115 Stream *r = wads[resources[id].f];
116 long pos = stream_getpos(r);
117 stream_setpos(r, resources[id].offset);
118 stream_read(data, resources[id].size, 1, r);
119 stream_setpos(r, pos);