From 1afe61cf5429407b416177893c7c86424ba31ff4 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Tue, 6 Aug 2013 06:09:00 +0200 Subject: [PATCH] Simplified interface of (build/read/write)_map_objects() by making them decide by themselves how to type-specifically handle each map object. --- defs | 10 +-- src/main.c | 29 +++----- src/map_objects.c | 170 ++++++++++++++++++++++++++++------------------ src/map_objects.h | 35 ++-------- src/misc.c | 8 +-- 5 files changed, 127 insertions(+), 125 deletions(-) diff --git a/defs b/defs index 4f2e61f..efa67c2 100644 --- a/defs +++ b/defs @@ -1,5 +1,5 @@ -0 m a 1 ANT -1 m z 3 ZOMBIE -2 m S 9 SHOGGOTH -3 i # THING -4 i % SKELETON +1 m a 1 ANT +2 m z 3 ZOMBIE +3 m S 9 SHOGGOTH +4 i # THING +5 i % SKELETON diff --git a/src/main.c b/src/main.c index 80e7b01..c48d57b 100644 --- a/src/main.c +++ b/src/main.c @@ -18,8 +18,7 @@ */ #include "map_objects.h" /* for structs Monster, Item, Player, * init_map_object_defs(), read_map_objects(), - * read_map_objects_monsterdata, - * read_map_objects_itemdata, build_map_objects() + * build_map_objects() */ #include "map_object_actions.h" /* for player_wait(), move_player() */ #include "map.h" /* for struct Map, init_map() */ @@ -72,9 +71,8 @@ int main(int argc, char *argv[]) player.pos.y = read_uint16_bigendian(file) - 1; player.pos.x = read_uint16_bigendian(file) - 1; player.hitpoints = fgetc(file); - read_map_objects(&world.monster, file, sizeof(struct Monster), - read_map_objects_monsterdata); - read_map_objects(&world.item, file, sizeof(struct Item), NULL); + read_map_objects(&world, &world.monster, file); + read_map_objects(&world, &world.item, file); fclose(file); } @@ -109,21 +107,12 @@ int main(int argc, char *argv[]) if (1 == world.turn) { player.pos = find_passable_pos(&map); - void * foo = build_map_objects(&world, &world.monster, - 0, 1 + rrand() % 27, - sizeof(struct Monster), - build_map_objects_monsterdata); - foo = build_map_objects(&world, foo, 1, 1 + rrand() % 9, - sizeof(struct Monster), - build_map_objects_monsterdata); - build_map_objects(&world, foo, 2, 1 + rrand() % 3, - sizeof(struct Monster), - build_map_objects_monsterdata); - foo = build_map_objects(&world, &world.item, 3, 1 + rrand() % 3, - sizeof(struct Item), - build_map_objects_itemdata); - build_map_objects(&world, foo, 4, 1 + rrand() % 3, - sizeof(struct Item), build_map_objects_itemdata); + void * foo; + foo = build_map_objects(&world, &world.monster, 1, 1 + rrand() % 27); + foo = build_map_objects(&world, foo, 2, 1 + rrand() % 9); + build_map_objects(&world, foo, 3, 1 + rrand() % 3); + foo = build_map_objects(&world, &world.item, 4, 1 + rrand() % 3); + build_map_objects(&world, foo, 5, 1 + rrand() % 3); } /* Initialize window system and windows. */ diff --git a/src/map_objects.c b/src/map_objects.c index 4fc9f1c..4340694 100644 --- a/src/map_objects.c +++ b/src/map_objects.c @@ -18,6 +18,16 @@ static struct MapObj * get_next_map_obj(void * start, char * first, +/* Map-object-type-specific helpers to (build|write|read)_map_objects(). */ +static void build_map_objects_itemdata(struct MapObjDef * map_obj_def, + void * start); +static void build_map_objects_monsterdata(struct MapObjDef * map_obj_def, + void * start); +static void write_map_objects_monsterdata(void * start, FILE * file); +static void read_map_objects_monsterdata( void * start, FILE * file); + + + static struct MapObj * get_next_map_obj(void * start, char * first, size_t size, struct MapObj * map_obj) { @@ -38,29 +48,64 @@ static struct MapObj * get_next_map_obj(void * start, char * first, +static void build_map_objects_itemdata(struct MapObjDef * map_obj_def, + void * start) +{ + struct Item * i = (struct Item *) start; + i->map_obj.type = map_obj_def->id; +} + + + +static void build_map_objects_monsterdata(struct MapObjDef * map_obj_def, + void * start) +{ + struct Monster * m = (struct Monster *) start; + m->map_obj.type = map_obj_def->id; + struct MonsterDef * md = (struct MonsterDef *) map_obj_def; + m->hitpoints = md->hitpoints_start; +} + + + +static void write_map_objects_monsterdata(void * start, FILE * file) +{ + struct Monster * m = (struct Monster *) start; + fputc(m->hitpoints, file); +} + + + +static void read_map_objects_monsterdata (void * start, FILE * file) +{ + struct Monster * m = (struct Monster *) start; + m->hitpoints = fgetc(file); +} + + + extern void init_map_object_defs(struct World * world, char * filename) { - world->item_def = 0; + world->item_def = 0; world->monster_def = 0; - FILE * file = fopen(filename, "r"); - uint16_t linemax; + FILE * file = fopen(filename, "r"); + uint16_t linemax; textfile_sizes (file, &linemax, NULL); - struct MapObjDef mod; - struct ItemDef id; - struct MonsterDef md; + struct MapObjDef mod; + struct ItemDef id; + struct MonsterDef md; struct ItemDef * * p_p_id = &world->item_def; struct MonsterDef * * p_p_md = &world->monster_def; - char * defline = malloc(linemax); - char * line_p; - char m_or_i; + char * defline = malloc(linemax); + char * line_p; while (fgets(defline, linemax, file)) { mod.next = 0; mod.id = atoi(defline); line_p = strchr(defline, ' ') + 1; - m_or_i = * line_p; + mod.m_or_i = * line_p; mod.mapchar = * (line_p + 2); - if ('i' == m_or_i) + if ('i' == mod.m_or_i) { line_p = line_p + 5; } @@ -71,7 +116,7 @@ extern void init_map_object_defs(struct World * world, char * filename) } mod.desc = calloc (strlen (line_p), sizeof(char)); memcpy (mod.desc, line_p, strlen(line_p) - 1); - if ('i' == m_or_i) + if ('i' == mod.m_or_i) { id.map_obj_def = mod; * p_p_id = malloc(sizeof(struct ItemDef)); @@ -92,18 +137,19 @@ extern void init_map_object_defs(struct World * world, char * filename) -extern void write_map_objects(void * start, FILE * file, - void (* w_typedata) (void *, FILE *) ) +extern void write_map_objects(struct World * world, void * start, FILE * file) { struct MapObj * map_obj; + struct MapObjDef * mod; for (map_obj = start; map_obj != 0; map_obj = map_obj->next) { + fputc(map_obj->type, file); write_uint16_bigendian(map_obj->pos.y + 1, file); write_uint16_bigendian(map_obj->pos.x + 1, file); - fputc(map_obj->type, file); - if (w_typedata) + mod = get_map_obj_def(world, map_obj->type); + if ('m' == mod->m_or_i) { - w_typedata (map_obj, file); + write_map_objects_monsterdata(map_obj, file); } } write_uint16_bigendian(0, file); @@ -111,26 +157,39 @@ extern void write_map_objects(void * start, FILE * file, -extern void read_map_objects(void * start, FILE * file, size_t size, - void (* r_typedata) (void *, FILE *) ) +extern void read_map_objects(struct World * world, void * start, FILE * file) { struct MapObj * map_obj; - uint16_t test; + struct MapObjDef * mod; + size_t size; + char type; char first = 1; + long pos; while (1) { - test = read_uint16_bigendian(file); - if (0 == test) + pos = ftell(file); + if (0 == read_uint16_bigendian(file)) { break; } + fseek(file, pos, SEEK_SET); + type = fgetc(file); + mod = get_map_obj_def(world, type); + if ('m' == mod->m_or_i) + { + size = sizeof(struct Monster); + } + else + { + size = sizeof(struct Item); + } map_obj = get_next_map_obj(start, &first, size, map_obj); - map_obj->pos.y = test - 1; + map_obj->type = type; + map_obj->pos.y = read_uint16_bigendian(file) - 1; map_obj->pos.x = read_uint16_bigendian(file) - 1; - map_obj->type = fgetc(file); - if (r_typedata) + if ('m' == mod->m_or_i) { - r_typedata(map_obj, file); + read_map_objects_monsterdata(map_obj, file); } } if (!first) @@ -141,36 +200,35 @@ extern void read_map_objects(void * start, FILE * file, size_t size, -extern void write_map_objects_monsterdata(void * start, FILE * file) -{ - struct Monster * m = (struct Monster *) start; - fputc(m->hitpoints, file); -} - - - -extern void read_map_objects_monsterdata (void * start, FILE * file) -{ - struct Monster * m = (struct Monster *) start; - m->hitpoints = fgetc(file); -} - - - extern void * build_map_objects(struct World * world, void * start, char def_id, - unsigned char n, size_t size, - void (* b_typedata) (struct MapObjDef *, - void *)) + unsigned char n) { unsigned char i; struct MapObj * mo; char first = 1; struct MapObjDef * mod = get_map_obj_def(world, def_id); + size_t size = 0; + if ('i' == mod->m_or_i) + { + size = sizeof(struct Item); + } + else + { + size = sizeof(struct Monster); + } for (i = 0; i < n; i++) { mo = get_next_map_obj(start, &first, size, mo); mo->pos = find_passable_pos(world->map); - b_typedata(mod, mo); + if ('i' == mod->m_or_i) + { + build_map_objects_itemdata(mod, mo); + } + else + { + build_map_objects_monsterdata(mod, mo); + } + } if (!first) { @@ -181,26 +239,6 @@ extern void * build_map_objects(struct World * world, void * start, char def_id, -extern void build_map_objects_itemdata(struct MapObjDef * map_obj_def, - void * start) -{ - struct Item * i = (struct Item *) start; - i->map_obj.type = map_obj_def->id; -} - - - -extern void build_map_objects_monsterdata(struct MapObjDef * map_obj_def, - void * start) -{ - struct Monster * m = (struct Monster *) start; - m->map_obj.type = map_obj_def->id; - struct MonsterDef * md = (struct MonsterDef *) map_obj_def; - m->hitpoints = md->hitpoints_start; -} - - - extern struct MapObjDef * get_map_obj_def (struct World * world, char def_id) { struct MapObjDef * d = NULL; diff --git a/src/map_objects.h b/src/map_objects.h index fb33fe5..9eb055c 100644 --- a/src/map_objects.h +++ b/src/map_objects.h @@ -53,6 +53,7 @@ struct Monster struct MapObjDef { struct MapObjDef * next; + char m_or_i; /* Is it item or monster? "i" for items, "m" for monsters. */ char id; /* Unique identifier of the map object type to describe. */ char mapchar; /* Map object symbol to appear on map.*/ char * desc; /* String describing map object in the game log. */ @@ -77,42 +78,18 @@ extern void init_map_object_defs(struct World * world, char * filename); /* Build into memory starting at "start" chain of "n" map objects of type - * "def_id", pass either "build_map_objects_itemdata" or - * "build_map_objects_monsterdata" as "b_typedata"() to build data specific - * to monsters or items (or more forms if they ever get invented). - * - * TODO: function should decide by itself what "b_typedata"() to call based - * on monster-or-item info in MapObjDef struct or from a table mapping type - * identifiers to these. + * "def_id". */ extern void * build_map_objects(struct World * world, void * start, char def_id, - unsigned char n, size_t size, - void (* b_typedata) (struct MapObjDef *, - void *)); -extern void build_map_objects_itemdata(struct MapObjDef * map_obj_def, - void * start); -extern void build_map_objects_monsterdata(struct MapObjDef * map_obj_def, - void * start); + unsigned char n); /* Write to/read from file chain of map objects starting/to start in memory at - * "start", use "w_typedata"()"/"r_typedata" for data specific to monsters - * (pass "write_map_objects_monsterdata"/"read_map_objects_itemdata") or items - * (currently they have no data specific only to them, so pass NULL). Use "size" - * in read_map_objects() to pass the size of structs of the affected map object - * type. - * - * TODO: the size of these structs should not need to be passed but instead be - * available via the type id of the affected map object type. The TODO above - * towards the function deciding its helper function by itself also applies. + * "start". */ -extern void write_map_objects(void * start, FILE * file, - void (* w_typedata) (void *, FILE *) ); -extern void read_map_objects(void * start, FILE * file, size_t size, - void (* w_typedata) (void *, FILE *) ); -extern void write_map_objects_monsterdata(void * start, FILE * file); -extern void read_map_objects_monsterdata( void * start, FILE * file); +extern void write_map_objects(struct World * world, void * start, FILE * file); +extern void read_map_objects(struct World * world, void * start, FILE * file); diff --git a/src/misc.c b/src/misc.c index b324058..6aeb8b4 100644 --- a/src/misc.c +++ b/src/misc.c @@ -13,9 +13,7 @@ */ #include "readwrite.h" /* for write_uint16_bigendian(), write_uint32_bigendian() */ -#include "map_objects.h" /* for struct Monster, write_map_objects(), - * write_map_objects_monsterdata() - */ +#include "map_objects.h" /* for struct Monster, write_map_objects(), */ #include "map_object_actions.h" /* for is_passable(), move_monster() */ #include "map.h" /* for map_scroll(),map_center_player(), Map struct,dir enum */ #include "main.h" /* for World struct */ @@ -159,8 +157,8 @@ extern void save_game(struct World * world) write_uint16_bigendian(world->player->pos.y + 1, file); write_uint16_bigendian(world->player->pos.x + 1, file); fputc(world->player->hitpoints, file); - write_map_objects (world->monster, file, write_map_objects_monsterdata); - write_map_objects (world->item, file, NULL); + write_map_objects(world, world->monster, file); + write_map_objects(world, world->item, file); fclose(file); } -- 2.30.2