X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fcommon%2Fwadres.c;h=356f591f2267be52967cfed126d433fefa21623b;hb=1d587e933326d5d8c90b965cc02a25224b2942a8;hp=88583b78ece81075a003012b3c704177ced50cba;hpb=65130d9f6581e4bd39ceae50d820c9774e4972a9;p=flatwaifu.git diff --git a/src/common/wadres.c b/src/common/wadres.c index 88583b7..356f591 100644 --- a/src/common/wadres.c +++ b/src/common/wadres.c @@ -1,9 +1,10 @@ #include #include +#include #include -#include "common/wadres.h" -#include "common/streams.h" +#include "wadres.h" +#include "streams.h" #include "cp866.h" typedef struct Entry { @@ -12,10 +13,17 @@ typedef struct Entry { int f; } Entry; +typedef struct Block { + int id; + int ref; + char data[]; +} Block; + static int n_wads; static int n_resources; static Stream *wads[MAX_WADS]; static Entry resources[MAX_RESOURCES]; +static Block *blocks[MAX_RESOURCES]; static int check_header (Stream *r) { assert(r != NULL); @@ -52,7 +60,8 @@ static int WADRES_addresource (const Entry *e) { return -1; } -static int WADRES_read (Stream *r) { +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); @@ -62,6 +71,7 @@ static int WADRES_read (Stream *r) { 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; } @@ -71,7 +81,7 @@ static int WADRES_read (Stream *r) { 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; } } @@ -118,3 +128,50 @@ void WADRES_getdata (int id, void *data) { stream_read(data, resources[id].size, 1, r); 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); +}