diff --git a/include/file.h b/include/file.h index 997abd4b..5f831c36 100644 --- a/include/file.h +++ b/include/file.h @@ -35,6 +35,7 @@ #define _FILE_H_ #include +#include struct empfile { int ef_uid; /* Table ID */ @@ -127,13 +128,6 @@ struct empfile { #define EF_IS_GAME_STATE(type) (EF_SECTOR <= (type) && (type) <= EF_LOST) -struct fileinit { - int ef_type; - void (*init) (int, char *); - int (*postread) (int, char *); - int (*prewrite) (int, char *); -}; - extern struct castr *ef_cadef(int); extern int ef_read(int, int, void *); extern void *ef_ptr(int, int); @@ -150,6 +144,7 @@ extern int ef_nelem(int); extern int ef_flags(int); extern int ef_byname(char *); extern int ef_byname_from(char *, int *); +extern void ef_init(void); extern struct empfile empfile[EF_MAX + 1]; diff --git a/include/prototypes.h b/include/prototypes.h index 1bcfb1b2..16b41f6d 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -464,7 +464,7 @@ extern int disloan(int, register struct lonstr *); /* distrea.c */ extern int distrea(int, register struct trtstr *); /* fileinit.c */ -extern void ef_init(void); +extern void ef_init_srv(void); /* fortdef.c */ extern int sd(natid, natid, coord, coord, int, int, int); extern int dd(natid, natid, coord, coord, int, int); diff --git a/src/lib/common/file.c b/src/lib/common/file.c index 5229a2bc..53880586 100644 --- a/src/lib/common/file.c +++ b/src/lib/common/file.c @@ -47,6 +47,7 @@ #include "match.h" #include "misc.h" #include "nsc.h" +#include "optlist.h" static int fillcache(struct empfile *, int); static int do_write(struct empfile *, void *, int, int); @@ -506,3 +507,56 @@ ef_ensure_space(int type, int id, int count) } return 1; } + +static void +ef_fix_size(struct empfile *ep, int n) +{ + ep->cids = ep->fids = n; + ep->csize = n + 1; +} + +static void +ef_init_chr(int type, size_t size, ptrdiff_t name_offs) +{ + struct empfile *ep = &empfile[type]; + char *p; + + for (p = ep->cache; **((char **)(p + name_offs)); p += size) ; + ef_fix_size(ep, (p - ep->cache) / size); +} + +/* + * Initialize Empire tables. + * Must be called once, before using anything else from this module. + */ +void +ef_init(void) +{ + struct castr *ca; + struct empfile *ep; + struct symbol *lup; + int i; + + empfile[EF_MAP].size = empfile[EF_BMAP].size = (WORLD_X * WORLD_Y) / 2; + + ef_init_chr(EF_SHIP_CHR, + sizeof(struct mchrstr), offsetof(struct mchrstr, m_name)); + ef_init_chr(EF_PLANE_CHR, + sizeof(struct plchrstr), offsetof(struct plchrstr, pl_name)); + ef_init_chr(EF_LAND_CHR, + sizeof(struct lchrstr), offsetof(struct lchrstr, l_name)); + ef_init_chr(EF_NUKE_CHR, + sizeof(struct nchrstr), offsetof(struct nchrstr, n_name)); + + ca = (struct castr *)empfile[EF_META].cache; + for (i = 0; ca[i].ca_name; i++) ; + ef_fix_size(&empfile[EF_META], i); + + for (ep = empfile; ep->ef_uid >= 0; ep++) { + if (ep->cadef == symbol_ca) { + lup = (struct symbol *)ep->cache; + for (i = 0; lup[i].value; i++) ; + ef_fix_size(ep, i); + } + } +} diff --git a/src/lib/subs/fileinit.c b/src/lib/subs/fileinit.c index 57f41916..6b20eeb5 100644 --- a/src/lib/subs/fileinit.c +++ b/src/lib/subs/fileinit.c @@ -25,23 +25,24 @@ * * --- * - * fileinit.c: Fill the empfile[] with function pointers only required for - * full server operations. This allows the empfile[] to be - * used in files and fairland. + * fileinit.c: Initialize Empire tables for full server operations. * * Known contributors to this file: * Ron Koenderink, 2005 * */ -#include -#include "misc.h" -#include "nsc.h" #include "file.h" #include "prototypes.h" -#include "optlist.h" -struct fileinit fileinit[] = { +struct fileinit { + int ef_type; + void (*init) (int, char *); + int (*postread) (int, char *); + int (*prewrite) (int, char *); +}; + +static struct fileinit fileinit[] = { {EF_SECTOR, NULL, sct_postread, sct_prewrite}, {EF_SHIP, shp_init, shp_postread, shp_prewrite}, {EF_PLANE, pln_init, pln_postread, pln_prewrite}, @@ -49,10 +50,16 @@ struct fileinit fileinit[] = { {EF_NUKE, nuk_init, nuk_postread, nuk_prewrite} }; +/* + * Initialize empfile for full server operations. + * Like ef_init(), but additionally installs the server's callbacks. + * This is separate from ef_init(), so that utility programs like + * files can use empfile. + */ void -ef_init(void) +ef_init_srv(void) { - int i; + unsigned i; for (i = 0; i < sizeof(fileinit) / sizeof(fileinit[0]); i++) { empfile[fileinit[i].ef_type].init = fileinit[i].init; @@ -60,5 +67,5 @@ ef_init(void) empfile[fileinit[i].ef_type].prewrite = fileinit[i].prewrite; } - empfile[EF_MAP].size = empfile[EF_BMAP].size = (WORLD_X * WORLD_Y) / 2; + ef_init(); } diff --git a/src/server/main.c b/src/server/main.c index d8cefac0..21b0e31c 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -267,7 +267,7 @@ init_server(void) global_init(); shutdown_init(); player_init(); - ef_init(); + ef_init_srv(); init_files(); io_init(); init_nreport(); diff --git a/src/util/files.c b/src/util/files.c index 2261a829..f42c6db5 100644 --- a/src/util/files.c +++ b/src/util/files.c @@ -101,8 +101,7 @@ main(int argc, char *argv[]) if (emp_config(config_file) < 0) exit(1); - empfile[EF_MAP].size = (WORLD_X * WORLD_Y) / 2; - empfile[EF_BMAP].size = (WORLD_X * WORLD_Y) / 2; + ef_init(); if (access(datadir, F_OK) < 0 && mkdir(datadir, 0750) < 0) { perror(datadir);