From 9df860ab2839447c7143bbe705a573df152d7734 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Wed, 7 Apr 2021 08:57:00 +0300 Subject: [PATCH] files: move wad reader to separete implementation --- src/common/streams.h | 1 + src/common/wadres.c | 120 +++++++++++++++ src/common/wadres.h | 21 +++ src/files.c | 349 ++++++++----------------------------------- src/files.h | 23 +-- src/map.c | 15 +- src/map.h | 1 - src/memory.c | 98 ++++++------ src/sdl/main.c | 4 +- 9 files changed, 265 insertions(+), 367 deletions(-) create mode 100644 src/common/wadres.c create mode 100644 src/common/wadres.h diff --git a/src/common/streams.h b/src/common/streams.h index 8952e24..d82b51a 100644 --- a/src/common/streams.h +++ b/src/common/streams.h @@ -6,6 +6,7 @@ typedef struct Reader Reader; typedef struct Writer Writer; +typedef struct Handle Handle; struct Reader { long (*getpos)(Reader *r); diff --git a/src/common/wadres.c b/src/common/wadres.c new file mode 100644 index 0000000..99524cc --- /dev/null +++ b/src/common/wadres.c @@ -0,0 +1,120 @@ +#include +#include +#include + +#include "common/wadres.h" +#include "common/streams.h" +#include "cp866.h" + +typedef struct Entry { + long offset, size; + char name[8]; + int f; +} Entry; + +static int n_wads; +static int n_resources; +static Reader *wads[MAX_WADS]; +static Entry resources[MAX_RESOURCES]; + +static int check_header (Reader *r) { + assert(r != NULL); + char ident[4]; + r->setpos(r, 0); + stream_read(ident, 4, 1, r); + return (memcmp(ident, "IWAD", 4) == 0) || (memcmp(ident, "PWAD", 4) == 0); +} + +int WADRES_addwad (Reader *r) { + assert(r != NULL); + if (n_wads < MAX_WADS && check_header(r)) { + wads[n_wads] = r; + n_wads += 1; + return 1; + } else { + return 0; + } +} + +static int WADRES_addresource (const Entry *e) { + assert(e != NULL); + for (int i = 0; i < n_resources; ++i) { + if (cp866_strncasecmp(resources[i].name, e->name, 8) == 0) { + memcpy(&resources[i], e, sizeof(Entry)); + return i; + } + } + if (n_resources < MAX_RESOURCES) { + memcpy(&resources[n_resources], e, sizeof(Entry)); + n_resources += 1; + return n_resources - 1; + } + return -1; +} + +static int WADRES_read (Reader *r) { + r->setpos(r, 4); // skip magic + int32_t n = stream_read32(r); + int32_t dir = stream_read32(r); + r->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); + stream_read(e.name, 8, 1, r); + ok = WADRES_addresource(&e) != -1; + } + return ok; +} + +int WADRES_rehash (void) { + int ok = 1; + for (int i = 0; i < n_wads; ++i) { + if (!WADRES_read(wads[i])) { + ok = 0; + } + } + return ok; +} + +int WADRES_find (const char name[8]) { + int i = n_resources - 1; + while (i >= 0 && cp866_strncasecmp(name, resources[i].name, 8) != 0) { + i -= 1; + } + return i; +} + +int WADRES_maxids (void) { + return n_resources; +} + +Reader *WADRES_getbasereader (int id) { + assert(id >= 0 && id < n_resources); + return wads[resources[id].f]; +} + +long WADRES_getoffset (int id) { + assert(id >= 0 && id < n_resources); + return resources[id].offset; +} + +long WADRES_getsize (int id) { + assert(id >= 0 && id < n_resources); + return resources[id].size; +} + +void WADRES_getname (int id, char *name) { + assert(id >= 0 && id < n_resources); + strncpy(name, resources[id].name, 8); +} + +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_read(data, resources[id].size, 1, r); + r->setpos(r, pos); +} diff --git a/src/common/wadres.h b/src/common/wadres.h new file mode 100644 index 0000000..30ee85b --- /dev/null +++ b/src/common/wadres.h @@ -0,0 +1,21 @@ +#ifndef COMMON_WADRES_H_INCLUDED +#define COMMON_WADRES_H_INCLUDED + +#include "common/streams.h" + +#define MAX_WADS 20 +#define MAX_RESOURCES 2000 + +int WADRES_addwad (Reader *r); +int WADRES_rehash (void); + +int WADRES_find (const char name[8]); +int WADRES_maxids (void); + +Reader *WADRES_getbasereader (int id); +long WADRES_getoffset (int id); +long WADRES_getsize (int id); +void WADRES_getname (int id, char *name); +void WADRES_getdata (int id, void *data); + +#endif /* COMMON_WADRES_H_INCLUDED */ \ No newline at end of file diff --git a/src/files.c b/src/files.c index e470830..704ca27 100644 --- a/src/files.c +++ b/src/files.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef UNIX # include #endif @@ -38,218 +39,59 @@ #include "error.h" #include "cp866.h" -typedef struct { - byte n, i, v, d; -} dmv; +#include "common/streams.h" +#include "common/files.h" +#include "common/wadres.h" int d_start, d_end; -mwad_t wad[MAX_WAD]; -char wads[MAX_WADS][__MAX_PATH]; -FILE* wadh[MAX_WADS]; - -static byte seq[255]; -static byte seqn; -static int inum=0; -static dmv *pat=NULL; -static unsigned *patp; -static void **dmi; - static int m_start, m_end; static int s_start, s_end; -static int wad_num; - -static char f_drive[__MAX_DRIVE]; -static char f_dir[__MAX_DIR]; -static char f_name[__MAX_FNAME]; -static char f_ext[__MAX_EXT]; void F_startup (void) { logo("F_startup: setup file system\n"); - memset(wads,0,sizeof(wads)); } void F_addwad (const char *fn) { - int i; - - for(i=0;i= MAX_WAD) { - ERR_failinit("Too many entries in the WAD"); - } - wad[p].o = w.o; - wad[p].l = w.l; - memcpy(wad[p].n, w.n, 8); - wad[p].f = 0; - ++p; + if (!WADRES_rehash()) { + ERR_failinit("F_initwads: failed rehash"); } - - //fclose(h); - - for (i = 1; i < MAX_WADS; ++i) { - if (wads[i][0] != 0) { - logo(" add %s\n", wads[i]); - if ((wadh[i] = h = fopen(wads[i], "rb")) == NULL) { - ERR_failinit("Unable to open file (2): %s", wads[i]); - } - mysplitpath(wads[i], f_drive, f_dir, f_name, f_ext); - if (cp866_strcasecmp(f_ext, ".lmp") == 0) { - for (k = 0; k < MAX_WAD; ++k) { - if (cp866_strncasecmp(wad[k].n, f_name, 8) == 0) { - wad[k].o = 0; - wad[k].l = myfilelength(h); - wad[k].f = i; - break; - } - if (k >= MAX_WAD) { - if (p >= MAX_WAD) { - ERR_failinit("Too many entries in the WAD"); - } - memset(wad[p].n, 0, 8); - strncpy(wad[p].n, f_name, 8); - wad[p].o = 0; - wad[p].l = myfilelength(h); - wad[p].f = i; - ++p; - } - } - - s[0] = '\0'; - myfread(s, 1, 4, h); - if (strncmp(s, "IWAD", 4) != 0 && strncmp(s, "PWAD", 4) != 0) { - ERR_failinit("Not IWAD or PWAD (2)"); - } - n = myfread32(h); // num - o = myfread32(h); // offset - fseek(h, o, SEEK_SET); - for (j = 0; j < n; ++j) { - w.o = myfread32(h); // offset - w.o = myfread32(h); // len - myfread(w.n, 1, 8, h); // name - for (k = 0; k < MAX_WAD; ++k) { - if (cp866_strncasecmp(wad[k].n, w.n, 8) == 0) { - wad[k].o = w.o; - wad[k].l = w.l; - wad[k].f = i; - break; - } - if (k >= MAX_WAD) { - if (p >= MAX_WAD) { - ERR_failinit("Too many entries in the WAD"); - } - memcpy(wad[p].n, w.n, 8); - wad[p].o = w.o; - wad[p].l = w.l; - wad[p].f = i; - ++p; - } - } - } - } - } - } - - wad_num = p; } -// allocate resources -// (called from M_startup) void F_allocres (void) { - d_start=F_getresid("D_START"); - d_end=F_getresid("D_END"); - m_start=F_getresid("M_START"); - m_end=F_getresid("M_END"); - s_start=F_getresid("S_START"); - s_end=F_getresid("S_END"); -} - -// load resource -void F_loadres (int r, void *p, dword o, dword l) { - - int oo; - FILE *fh; - - - oo=ftell(fh=wadh[wad[r].f]); - - if(fseek(fh,wad[r].o+o,SEEK_SET)!=0) - ERR_fatal("Error while file reading"); - - if((dword)myfreadc(p,1,l,fh)!=l) - ERR_fatal("Error while loading resource %.8s", wad[r].n); - - fseek(fh,oo,SEEK_SET); - + d_start = F_getresid("D_START"); + d_end = F_getresid("D_END"); + m_start = F_getresid("M_START"); + m_end = F_getresid("M_END"); + s_start = F_getresid("S_START"); + s_end = F_getresid("S_END"); } -/* -// unused -void F_saveres(int r, void *p, dword o, dword l) { - FILE* fh = wadh[wad[r].f]; - int oo = ftell(fh); - if (fseek(fh, wad[r].o + o, SEEK_SET) != 0) { - ERR_fatal("Error while reading file"); - } - myfwrite(p, l, 1, fh); - fseek(fh, oo, SEEK_SET); +void F_loadres (int r, void *p) { + WADRES_getdata(r, p); } -*/ -// get resource id int F_findres (const char n[8]) { - int i; - for (i = 0; i < wad_num; i++) { - if (cp866_strncasecmp(wad[i].n, n, 8) == 0) { - return i; - } - } - return -1; + return WADRES_find(n); } -// get resource id int F_getresid (const char n[8]) { int i = F_findres(n); if (i == -1) { @@ -259,22 +101,22 @@ int F_getresid (const char n[8]) { } void F_getresname (char n[8], int r) { - memcpy(n, wad[r].n, 8); + WADRES_getname(r, n); } -// get sprite id int F_getsprid (const char n[4], int s, int d, char *dir) { - int i; - byte a, b; s += 'A'; d += '0'; - for (i = s_start + 1; i < s_end; i++) { - if (cp866_strncasecmp(wad[i].n, n, 4) == 0 && (wad[i].n[4] == s || wad[i].n[6] == s)) { - a = wad[i].n[4] == s ? wad[i].n[5] : 0; - b = wad[i].n[6] == s ? wad[i].n[7] : 0; + for (int i = s_start + 1; i < s_end; i++) { + char wn[8]; + byte a, b; + WADRES_getname(i, wn); + if (cp866_strncasecmp(wn, n, 4) == 0 && (wn[4] == s || wn[6] == s)) { + a = wn[4] == s ? wn[5] : 0; + b = wn[6] == s ? wn[7] : 0; if (a == '0' || b == '0' || a == d || b == d) { if (dir != NULL) { - *dir = a != '0' && b == '0' || a != d && b == d; + *dir = (a != '0' && b == '0') || (a != d && b == d); } return i; } @@ -285,24 +127,28 @@ int F_getsprid (const char n[4], int s, int d, char *dir) { } int F_getreslen (int r) { - return wad[r].l; + return WADRES_getsize(r); } void F_nextmus (char *s) { - int i; - i=F_findres(s); - if(i<=m_start || i>=m_end) i=m_start; - for(++i;;++i) { - if(i>=m_end) i=m_start+1; - - if (cp866_strcasecmp(wad[i].n,"MENU") == 0 || - cp866_strcasecmp(wad[i].n,"INTERMUS") == 0 || - cp866_strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0) - continue; - - if(cp866_strncasecmp(wad[i].n,"DMI",3)!=0) break; + int i = F_findres(s); + if (i <= m_start || i >= m_end) { + i = m_start; + } + for (++i; ; ++i) { + if (i >= m_end) { + i = m_start + 1; + } + WADRES_getname(i, s); + if (cp866_strcasecmp(s, "MENU") == 0 || + cp866_strcasecmp(s, "INTERMUS") == 0 || + cp866_strcasecmp(s, "\x8a\x8e\x8d\x85\x96\x0") == 0) { + continue; + } + if (cp866_strncasecmp(s, "DMI", 3) != 0) { + break; + } } - memcpy(s,wad[i].n,8); } void F_randmus (char *s) { @@ -330,79 +176,16 @@ void F_readstr (FILE* h, char *s, int m) { s[i] = 0; } -/* -// unused -// reads bytes from file until NUL -void F_readstrz (FILE* h,char *s,int m) { - int i = 0; - size_t len = 0; - static char c = 0; - while (i < m) { - c = 0; - len = myfreadc(&c, 1, 1, h); - if (len == 0 || c == 0) { - break; +void F_loadmap (char n[8]) { + int id = F_getresid(n); + if (id != -1) { + Reader *r = WADRES_getbasereader(id); + long offset = WADRES_getoffset(id); + r->setpos(r, offset); + if (!MAP_load(r)) { + ERR_fatal("Failed to load map"); } - s[i] = c; - i++; + } else { + ERR_fatal("Failed to load map: resource %.8s not found", n); } - s[i] = 0; -} -*/ - -/*void F_freemus(void) { - - int i; - - if(!pat) return; - S_stopmusic(); - free(pat);free(patp); - for(i=0;i // FILE #include "map.h" // map_block_t -#define MAX_WADS 20 -#define MAX_WAD 2000 - -typedef char wadname[8]; - -typedef struct { - int o, l; - char n[8]; -} wad_t; - -typedef struct { - int o, l; - char n[8]; - int f; -} mwad_t; - extern int d_start, d_end; -extern mwad_t wad[MAX_WAD]; -extern char wads[MAX_WADS][__MAX_PATH]; -extern FILE* wadh[MAX_WADS]; void F_startup (void); void F_addwad (const char *fn); void F_initwads (void); void F_allocres (void); -void F_loadres (int r, void *p, dword o, dword l); +void F_loadres (int r, void *p); int F_findres (const char n[8]); int F_getresid (const char n[8]); void F_getresname (char n[8], int r); @@ -57,4 +38,6 @@ void F_nextmus (char *s); void F_randmus (char *s); void F_readstr (FILE* h, char *s, int m); +void F_loadmap (char n[8]); + #endif /* FILES_H_INCLUDED */ diff --git a/src/map.c b/src/map.c index 1bdb4d3..dc65f0c 100644 --- a/src/map.c +++ b/src/map.c @@ -25,13 +25,10 @@ #include "view.h" #include "music.h" -#include "files.h" #include "render.h" -#include #include #include -#include "my.h" #include "error.h" #include "cp866.h" @@ -317,18 +314,8 @@ int MAP_load (Reader *r) { } } else { logo("Invalid map header\n"); + abort(); ok = 0; } return ok; } - -void F_loadmap (char n[8]) { - FILE_Reader rd; - int r = F_getresid(n); - FILE *h = wadh[wad[r].f]; - fseek(h, wad[r].o, SEEK_SET); - FILE_AssignReader(&rd, h); - if (!MAP_load(&rd.base)) { - ERR_fatal("Failed to load map"); - } -} diff --git a/src/map.h b/src/map.h index d661b36..4e14706 100644 --- a/src/map.h +++ b/src/map.h @@ -21,6 +21,5 @@ #include "common/streams.h" int MAP_load (Reader *r); -void F_loadmap (char n[8]); #endif /* MAP_H_INCLUDED */ diff --git a/src/memory.c b/src/memory.c index f118746..404bbc4 100644 --- a/src/memory.c +++ b/src/memory.c @@ -19,69 +19,73 @@ #include #include #include +#include #include "error.h" #include "files.h" #include "memory.h" -static byte m_active; -static void *resp[MAX_WAD]; -static short resl[MAX_WAD]; +#include "common/wadres.h" +#include "common/streams.h" + +typedef struct Block { + int id; + int ref; + char data[]; +} Block; + +static Block *blocks[MAX_RESOURCES]; void M_startup (void) { - if(m_active) return; - logo("M_startup: setup memory\n"); - memset(resp,0,sizeof(resp)); - memset(resl,0,sizeof(resl)); - // logo(" free DPMI-memory: %uK\n",dpmi_memavl()>>10); - m_active=TRUE; + memset(blocks, 0, sizeof(blocks)); } void M_shutdown (void) { - if(!m_active) return; - m_active=FALSE; -} - -static void allocres (int h) { - int *p,s; - - if(h>d_start && h=MAX_WAD) ERR_fatal("M_lock: invalid resource id"); - if(!resl[h]) if(!resp[h]) allocres(h); - ++resl[h]; - return resp[h]; +void *M_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 M_unlock (void *p) { - int h; - - if(!p) return; - h=((int*)p)[-1]; - if(h>=MAX_WAD) ERR_fatal("M_unlock: invalid resource id"); - if(!resl[h]) return; - --resl[h]; + if (p) { + Block *x = p - 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 M_locked (int h) { - return (h != -1) && (h != 0xFFFF) && (resl[h] != 0); +int M_locked (int id) { + assert(id >= -1 && id < MAX_RESOURCES); + return (id >= 0) && (blocks[id] != NULL) && (blocks[id]->ref >= 1); } -int M_was_locked (int h) { - return (h != -1) && (h != 0xFFFF) && (resp[h] != NULL); +int M_was_locked (int id) { + assert(id >= -1 && id < MAX_RESOURCES); + return (id >= 0) && (blocks[id] != NULL) && (blocks[id]->ref >= 0); } diff --git a/src/sdl/main.c b/src/sdl/main.c index 217890a..2c229fb 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -125,7 +125,7 @@ void ERR_failinit (char *s, ...) { vprintf(s, ap); va_end(ap); puts(""); - exit(1); + abort(); } void ERR_fatal (char *s, ...) { @@ -140,7 +140,7 @@ void ERR_fatal (char *s, ...) { vprintf(s, ap); va_end(ap); puts(""); - exit(1); + abort(); } void ERR_quit (void) { -- 2.29.2