diff --git a/src/common/wadres.c b/src/common/wadres.c
index 99524cc1ed81ff2725e05221799f6151f6cf1a46..356f591f2267be52967cfed126d433fefa21623b 100644 (file)
--- a/src/common/wadres.c
+++ b/src/common/wadres.c
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <string.h>
+#include <stdlib.h>
#include <assert.h>
#include <assert.h>
-#include "common/wadres.h"
-#include "common/streams.h"
+#include "wadres.h"
+#include "streams.h"
#include "cp866.h"
typedef struct Entry {
#include "cp866.h"
typedef struct Entry {
int f;
} Entry;
int f;
} Entry;
+typedef struct Block {
+ int id;
+ int ref;
+ char data[];
+} Block;
+
static int n_wads;
static int n_resources;
static int n_wads;
static int n_resources;
-static Reader *wads[MAX_WADS];
+static Stream *wads[MAX_WADS];
static Entry resources[MAX_RESOURCES];
static Entry resources[MAX_RESOURCES];
+static Block *blocks[MAX_RESOURCES];
-static int check_header (Reader *r) {
+static int check_header (Stream *r) {
assert(r != NULL);
char ident[4];
assert(r != NULL);
char ident[4];
- r->setpos(r, 0);
+ stream_setpos(r, 0); // !!!
stream_read(ident, 4, 1, r);
return (memcmp(ident, "IWAD", 4) == 0) || (memcmp(ident, "PWAD", 4) == 0);
}
stream_read(ident, 4, 1, r);
return (memcmp(ident, "IWAD", 4) == 0) || (memcmp(ident, "PWAD", 4) == 0);
}
-int WADRES_addwad (Reader *r) {
+int WADRES_addwad (Stream *r) {
assert(r != NULL);
if (n_wads < MAX_WADS && check_header(r)) {
wads[n_wads] = r;
assert(r != NULL);
if (n_wads < MAX_WADS && check_header(r)) {
wads[n_wads] = r;
return -1;
}
return -1;
}
-static int WADRES_read (Reader *r) {
- r->setpos(r, 4); // skip magic
+static int WADRES_read (int f) {
+ Stream *r = wads[f];
+ stream_setpos(r, 4); // skip magic
int32_t n = stream_read32(r);
int32_t dir = stream_read32(r);
int32_t n = stream_read32(r);
int32_t dir = stream_read32(r);
- r->setpos(r, dir);
+ stream_setpos(r, dir);
int ok = 1;
for (int32_t i = 0; ok && i < n; ++i) {
Entry e;
e.offset = stream_read32(r);
e.size = stream_read32(r);
int ok = 1;
for (int32_t i = 0; ok && i < n; ++i) {
Entry e;
e.offset = stream_read32(r);
e.size = stream_read32(r);
+ e.f = f;
stream_read(e.name, 8, 1, r);
ok = WADRES_addresource(&e) != -1;
}
stream_read(e.name, 8, 1, r);
ok = WADRES_addresource(&e) != -1;
}
int WADRES_rehash (void) {
int ok = 1;
for (int i = 0; i < n_wads; ++i) {
int WADRES_rehash (void) {
int ok = 1;
for (int i = 0; i < n_wads; ++i) {
- if (!WADRES_read(wads[i])) {
+ if (!WADRES_read(i)) {
ok = 0;
}
}
ok = 0;
}
}
return n_resources;
}
return n_resources;
}
-Reader *WADRES_getbasereader (int id) {
+Stream *WADRES_getbasereader (int id) {
assert(id >= 0 && id < n_resources);
return wads[resources[id].f];
}
assert(id >= 0 && id < n_resources);
return wads[resources[id].f];
}
void WADRES_getdata (int id, void *data) {
assert(id >= 0 && id < n_resources);
void WADRES_getdata (int id, void *data) {
assert(id >= 0 && id < n_resources);
- Reader *r = wads[resources[id].f];
- long pos = r->getpos(r);
- r->setpos(r, resources[id].offset);
+ Stream *r = wads[resources[id].f];
+ long pos = stream_getpos(r);
+ stream_setpos(r, resources[id].offset);
stream_read(data, resources[id].size, 1, r);
stream_read(data, resources[id].size, 1, r);
- r->setpos(r, pos);
+ stream_setpos(r, pos);
+}
+
+void *WADRES_lock (int id) {
+ assert(id >= -1 && id < MAX_RESOURCES);
+ if (id >= 0) {
+ Block *x = blocks[id];
+ if (x) {
+ x->ref += 1;
+ return x->data;
+ } else {
+ x = malloc(sizeof(Block) + WADRES_getsize(id));
+ if (x) {
+ x->id = id;
+ x->ref = 1;
+ WADRES_getdata(id, x->data);
+ blocks[id] = x;
+ return x->data;
+ }
+ }
+ }
+ return NULL;
+}
+
+void WADRES_unlock (void *data) {
+ if (data) {
+ Block *x = data - sizeof(Block);
+ int id = x->id;
+ assert(id >= 0 && id < MAX_RESOURCES);
+ x->ref -= 1;
+ assert(x->ref >= 0);
+#if 0
+ if (x->ref == 0) {
+ blocks[id] = NULL;
+ free(x);
+ }
+#endif
+ }
+}
+
+int WADRES_locked (int id) {
+ assert(id >= -1 && id < MAX_RESOURCES);
+ return (id >= 0) && (blocks[id] != NULL) && (blocks[id]->ref >= 1);
+}
+
+int WADRES_was_locked (int id) {
+ assert(id >= -1 && id < MAX_RESOURCES);
+ return (id >= 0) && (blocks[id] != NULL) && (blocks[id]->ref >= 0);
}
}