6 #include "common/wadres.h"
7 #include "common/streams.h"
8 #include "common/cp866.h"
10 typedef struct Entry
{
16 typedef struct Block
{
23 static int n_resources
;
24 static Stream
*wads
[MAX_WADS
];
25 static Entry resources
[MAX_RESOURCES
];
26 static Block
*blocks
[MAX_RESOURCES
];
28 static int s_start
, s_end
;
30 static int check_header (Stream
*r
) {
33 stream_setpos(r
, 0); // !!!
34 stream_read(ident
, 4, 1, r
);
35 return (memcmp(ident
, "IWAD", 4) == 0) || (memcmp(ident
, "PWAD", 4) == 0);
38 int WADRES_addwad (Stream
*r
) {
40 if (n_wads
< MAX_WADS
&& check_header(r
)) {
49 static int WADRES_addresource (const Entry
*e
) {
52 for (i
= 0; i
< n_resources
; ++i
) {
53 if (cp866_strncasecmp(resources
[i
].name
, e
->name
, 8) == 0) {
54 memcpy(&resources
[i
], e
, sizeof(Entry
));
58 if (n_resources
< MAX_RESOURCES
) {
59 memcpy(&resources
[n_resources
], e
, sizeof(Entry
));
61 return n_resources
- 1;
66 static int WADRES_read (int f
) {
70 stream_setpos(r
, 4); // skip magic
72 dir
= stream_read32(r
);
73 stream_setpos(r
, dir
);
74 for (i
= 0; ok
&& i
< n
; ++i
) {
76 e
.offset
= stream_read32(r
);
77 e
.size
= stream_read32(r
);
79 stream_read(e
.name
, 8, 1, r
);
80 ok
= WADRES_addresource(&e
) != -1;
85 int WADRES_rehash (void) {
88 for (i
= 0; i
< n_wads
; ++i
) {
89 if (!WADRES_read(i
)) {
93 s_start
= WADRES_find("S_START");
94 s_end
= WADRES_find("S_END");
98 int WADRES_find (const char name
[8]) {
99 int i
= n_resources
- 1;
100 while (i
>= 0 && cp866_strncasecmp(name
, resources
[i
].name
, 8) != 0) {
106 int WADRES_maxids (void) {
110 int WADRES_findsprite (const char n
[4], int s
, int d
, char *dir
) {
114 for (i
= s_start
+ 1; i
< s_end
; i
++) {
116 char *wn
= resources
[i
].name
;
117 if (cp866_strncasecmp(wn
, n
, 4) == 0 && (wn
[4] == s
|| wn
[6] == s
)) {
118 a
= wn
[4] == s
? wn
[5] : 0;
119 b
= wn
[6] == s
? wn
[7] : 0;
120 if (a
== '0' || b
== '0' || a
== d
|| b
== d
) {
122 *dir
= (a
!= '0' && b
== '0') || (a
!= d
&& b
== d
);
131 Stream
*WADRES_getbasereader (int id
) {
132 assert(id
>= 0 && id
< n_resources
);
133 return wads
[resources
[id
].f
];
136 long WADRES_getoffset (int id
) {
137 assert(id
>= 0 && id
< n_resources
);
138 return resources
[id
].offset
;
141 long WADRES_getsize (int id
) {
142 assert(id
>= 0 && id
< n_resources
);
143 return resources
[id
].size
;
146 void WADRES_getname (int id
, char *name
) {
147 assert(id
>= 0 && id
< n_resources
);
148 strncpy(name
, resources
[id
].name
, 8);
151 void WADRES_getdata (int id
, void *data
) {
154 assert(id
>= 0 && id
< n_resources
);
155 r
= wads
[resources
[id
].f
];
156 pos
= stream_getpos(r
);
157 stream_setpos(r
, resources
[id
].offset
);
158 stream_read(data
, resources
[id
].size
, 1, r
);
159 stream_setpos(r
, pos
);
162 void *WADRES_lock (int id
) {
163 assert(id
>= -1 && id
< MAX_RESOURCES
);
165 Block
*x
= blocks
[id
];
170 x
= malloc(sizeof(Block
) + WADRES_getsize(id
));
174 WADRES_getdata(id
, x
->data
);
183 void WADRES_unlock (void *data
) {
187 x
= (Block
*)((uintptr_t)data
- sizeof(Block
));
189 assert(id
>= 0 && id
< MAX_RESOURCES
);
201 int WADRES_locked (int id
) {
202 assert(id
>= -1 && id
< MAX_RESOURCES
);
203 return (id
>= 0) && (blocks
[id
] != NULL
) && (blocks
[id
]->ref
>= 1);
206 int WADRES_was_locked (int id
) {
207 assert(id
>= -1 && id
< MAX_RESOURCES
);
208 return (id
>= 0) && (blocks
[id
] != NULL
) && (blocks
[id
]->ref
>= 0);