356f591f2267be52967cfed126d433fefa21623b
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 check_header (Stream
*r
) {
31 stream_setpos(r
, 0); // !!!
32 stream_read(ident
, 4, 1, r
);
33 return (memcmp(ident
, "IWAD", 4) == 0) || (memcmp(ident
, "PWAD", 4) == 0);
36 int WADRES_addwad (Stream
*r
) {
38 if (n_wads
< MAX_WADS
&& check_header(r
)) {
47 static int WADRES_addresource (const Entry
*e
) {
49 for (int i
= 0; i
< n_resources
; ++i
) {
50 if (cp866_strncasecmp(resources
[i
].name
, e
->name
, 8) == 0) {
51 memcpy(&resources
[i
], e
, sizeof(Entry
));
55 if (n_resources
< MAX_RESOURCES
) {
56 memcpy(&resources
[n_resources
], e
, sizeof(Entry
));
58 return n_resources
- 1;
63 static int WADRES_read (int f
) {
65 stream_setpos(r
, 4); // skip magic
66 int32_t n
= stream_read32(r
);
67 int32_t dir
= stream_read32(r
);
68 stream_setpos(r
, dir
);
70 for (int32_t i
= 0; ok
&& i
< n
; ++i
) {
72 e
.offset
= stream_read32(r
);
73 e
.size
= stream_read32(r
);
75 stream_read(e
.name
, 8, 1, r
);
76 ok
= WADRES_addresource(&e
) != -1;
81 int WADRES_rehash (void) {
83 for (int i
= 0; i
< n_wads
; ++i
) {
84 if (!WADRES_read(i
)) {
91 int WADRES_find (const char name
[8]) {
92 int i
= n_resources
- 1;
93 while (i
>= 0 && cp866_strncasecmp(name
, resources
[i
].name
, 8) != 0) {
99 int WADRES_maxids (void) {
103 Stream
*WADRES_getbasereader (int id
) {
104 assert(id
>= 0 && id
< n_resources
);
105 return wads
[resources
[id
].f
];
108 long WADRES_getoffset (int id
) {
109 assert(id
>= 0 && id
< n_resources
);
110 return resources
[id
].offset
;
113 long WADRES_getsize (int id
) {
114 assert(id
>= 0 && id
< n_resources
);
115 return resources
[id
].size
;
118 void WADRES_getname (int id
, char *name
) {
119 assert(id
>= 0 && id
< n_resources
);
120 strncpy(name
, resources
[id
].name
, 8);
123 void WADRES_getdata (int id
, void *data
) {
124 assert(id
>= 0 && id
< n_resources
);
125 Stream
*r
= wads
[resources
[id
].f
];
126 long pos
= stream_getpos(r
);
127 stream_setpos(r
, resources
[id
].offset
);
128 stream_read(data
, resources
[id
].size
, 1, r
);
129 stream_setpos(r
, pos
);
132 void *WADRES_lock (int id
) {
133 assert(id
>= -1 && id
< MAX_RESOURCES
);
135 Block
*x
= blocks
[id
];
140 x
= malloc(sizeof(Block
) + WADRES_getsize(id
));
144 WADRES_getdata(id
, x
->data
);
153 void WADRES_unlock (void *data
) {
155 Block
*x
= data
- sizeof(Block
);
157 assert(id
>= 0 && id
< MAX_RESOURCES
);
169 int WADRES_locked (int id
) {
170 assert(id
>= -1 && id
< MAX_RESOURCES
);
171 return (id
>= 0) && (blocks
[id
] != NULL
) && (blocks
[id
]->ref
>= 1);
174 int WADRES_was_locked (int id
) {
175 assert(id
>= -1 && id
< MAX_RESOURCES
);
176 return (id
>= 0) && (blocks
[id
] != NULL
) && (blocks
[id
]->ref
>= 0);