From: Christian Heller Date: Tue, 23 Jul 2013 03:04:27 +0000 (+0200) Subject: More documentation and re-styling of code according to new rules. X-Git-Tag: tce~1136 X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bdb.prefix%7D%7D/static/blog?a=commitdiff_plain;h=120715d0a4a308cdf748e1925be472ed6a59f092;p=plomrogue More documentation and re-styling of code according to new rules. --- diff --git a/src/map_objects.c b/src/map_objects.c index 747b718..9adf634 100644 --- a/src/map_objects.c +++ b/src/map_objects.c @@ -1,136 +1,216 @@ +/* map_objects.c */ + #include "map_objects.h" -#include -#include -#include -#include "readwrite.h" -#include "misc.h" -#include "main.h" - -static struct MapObj * get_next_map_obj (void *, char *, size_t, struct MapObj *); - -extern void init_map_object_defs (struct World * world, char * filename) { -// Initialize map object definitions from file at path "filename". - world->item_def = 0; - world->monster_def = 0; - FILE * file = fopen(filename, "r"); - uint16_t linemax; - textfile_sizes (file, &linemax, NULL); - 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; - while (fgets (defline, linemax, file)) { - mod.next = 0; - mod.id = atoi(defline); - line_p = strchr(defline, ' ') + 1; - m_or_i = * line_p; - mod.mapchar = * (line_p + 2); - if ('i' == m_or_i) - line_p = line_p + 5; - else { - md.hitpoints_start = atoi (line_p + 4); - line_p = strchr (line_p + 4, ' ') + 1; } - mod.desc = calloc (strlen (line_p), sizeof(char)); - memcpy (mod.desc, line_p, strlen(line_p) - 1); - if ('i' == m_or_i) { - id.map_obj_def = mod; - * p_p_id = malloc (sizeof (struct ItemDef)); - * * p_p_id = id; - p_p_id = (struct ItemDef * *) * p_p_id; } - else { - md.map_obj_def = mod; - * p_p_md = malloc (sizeof (struct MonsterDef)); - * * p_p_md = md; - p_p_md = (struct MonsterDef * *) * p_p_md; } } - free(defline); - fclose(file); }; - -extern void write_map_objects_monsterdata (void * start, FILE * file) { -// Write to file data specific to map objects of type monster. - struct Monster * m = (struct Monster *) start; - fputc(m->hitpoints, file); } - -extern void write_map_objects (void * start, FILE * file, void (* w_typedata) (void *, FILE *) ) { -// Write into file the map object chain starting at start, use write_type() for object-type specific data. - struct MapObj * map_obj; - for (map_obj = start; map_obj != 0; map_obj = map_obj->next) { - 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) - w_typedata (map_obj, file); } - write_uint16_bigendian(0, file); } - -extern void read_map_objects_monsterdata (void * start, FILE * file) { -// Read from file data speciifc to map objects of type monster. +#include /* for malloc(), calloc(), free(), atoi() */ +#include /* for FILE typedef */ +#include /* for strchr(), strlen(), memcpy() */ +#include "readwrite.h" /* for all the map object (def) loading/saving */ +#include "misc.h" /* for textfile_sizes(), find_passable_pos() */ +#include "main.h" /* for World struct */ + + + +/* Return pointer to newly allocated map object struct of size "size". If first + * in map object chain ("first" pointing to !0), point "start" to it. + */ +static struct MapObj * get_next_map_obj(void * start, char * first, + size_t size, struct MapObj * map_obj); + + + +static struct MapObj * get_next_map_obj(void * start, char * first, + size_t size, struct MapObj * map_obj) +{ + if (* first) + { + struct MapObj * * z = start; + map_obj = malloc(size); + * z = map_obj; + * first = 0; + } + else + { + map_obj->next = malloc(size); + map_obj = map_obj->next; + } + return map_obj; +} + + + +extern void init_map_object_defs(struct World * world, char * filename) +{ + world->item_def = 0; + world->monster_def = 0; + FILE * file = fopen(filename, "r"); + uint16_t linemax; + textfile_sizes (file, &linemax, NULL); + 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; + while (fgets(defline, linemax, file)) + { + mod.next = 0; + mod.id = atoi(defline); + line_p = strchr(defline, ' ') + 1; + m_or_i = * line_p; + mod.mapchar = * (line_p + 2); + if ('i' == m_or_i) + { + line_p = line_p + 5; + } + else + { + md.hitpoints_start = atoi (line_p + 4); + line_p = strchr (line_p + 4, ' ') + 1; + } + mod.desc = calloc (strlen (line_p), sizeof(char)); + memcpy (mod.desc, line_p, strlen(line_p) - 1); + if ('i' == m_or_i) + { + id.map_obj_def = mod; + * p_p_id = malloc(sizeof(struct ItemDef)); + * * p_p_id = id; + p_p_id = (struct ItemDef * *) * p_p_id; + } + else + { + md.map_obj_def = mod; + * p_p_md = malloc(sizeof(struct MonsterDef)); + * * p_p_md = md; + p_p_md = (struct MonsterDef * *) * p_p_md; + } + } + free(defline); + fclose(file); +}; + + + +extern void write_map_objects(void * start, FILE * file, + void (* w_typedata) (void *, FILE *) ) +{ + struct MapObj * map_obj; + for (map_obj = start; map_obj != 0; map_obj = map_obj->next) + { + 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) + { + w_typedata (map_obj, file); + } + } + write_uint16_bigendian(0, file); +} + + + +extern void read_map_objects (void * start, FILE * file, size_t size, + void (* r_typedata) (void *, FILE *) ) +{ + struct MapObj * map_obj; + uint16_t test; + char first = 1; + while (1) + { + test = read_uint16_bigendian(file); + if (0 == test) + { + break; + } + map_obj = get_next_map_obj(start, &first, size, map_obj); + map_obj->pos.y = test - 1; + map_obj->pos.x = read_uint16_bigendian(file) - 1; + map_obj->type = fgetc(file); + if (r_typedata) + { + r_typedata(map_obj, file); + } + } + if (!first) + { + map_obj->next = 0; + } +} + + + +extern void write_map_objects_monsterdata(void * start, FILE * file) +{ struct Monster * m = (struct Monster *) start; - m->hitpoints = fgetc(file); } - -static struct MapObj * get_next_map_obj (void * start, char * first, size_t size, struct MapObj * map_obj) { -// Return pointer to map object of "size". If first in chain ("first" pointing to !0), point "start" to it. - if (* first) { - struct MapObj * * z = start; - map_obj = malloc(size); - * z = map_obj; - * first = 0; } - else { - map_obj->next = malloc(size); - map_obj = map_obj->next; } - return map_obj; } - -extern void read_map_objects (void * start, FILE * file, size_t size, void (* r_typedata) (void *, FILE *) ) { -// Read from file chain of map objects starting at start, use r_typedata() for object-type specific data. - struct MapObj * map_obj; - uint16_t test; - char first = 1; - while (1) { - test = read_uint16_bigendian(file); - if (0 == test) - break; - map_obj = get_next_map_obj(start, &first, size, map_obj); - map_obj->pos.y = test - 1; - map_obj->pos.x = read_uint16_bigendian(file) - 1; - map_obj->type = fgetc(file); - if (r_typedata) - r_typedata (map_obj, file); } - if (!first) - map_obj->next = 0; } - -extern void build_map_objects_monsterdata (struct MapObjDef * map_obj_def, void * start) { -// Build data specific to map objects of type monster. + fputc(m->hitpoints, file); +} + + + +extern void read_map_objects_monsterdata (void * start, FILE * file) +{ 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; } + 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 i; + struct MapObj * mo; + char first = 1; + struct MapObjDef * mod = get_map_obj_def(world, def_id); + 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 (!first) + { + mo->next = 0; + } + return &mo->next; +} -extern void build_map_objects_itemdata (struct MapObjDef * map_obj_def, void * start) { -// Build data speciifc to map objects of type data. + + +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 (struct World * world, void * start, char def_id, unsigned char n, - size_t size, void (* b_typedata) (struct MapObjDef *, void *)) { -// Build chain of n map objects starting at start, use f() for object-specific data. - unsigned char i; - struct MapObj * mo; - char first = 1; - struct MapObjDef * mod = get_map_obj_def (world, def_id); - 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 (!first) - mo->next = 0; - return &mo->next; } - -extern struct MapObjDef * get_map_obj_def (struct World * world, char def_id) { -// Get pointer to the map object definition with id "def_id". - struct MapObjDef * d = NULL; - for (d = (struct MapObjDef *) world->monster_def; d->id != def_id && 0 != d->next; d = d->next); - if (d->id != def_id) - for (d = (struct MapObjDef *) world->item_def; d->id != def_id && 0 != d->next; d = d->next); - return d; } + 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; + for (d = (struct MapObjDef *) world->monster_def; + d->id != def_id && 0 != d->next; + d = d->next); + if (d->id != def_id) + { + for (d = (struct MapObjDef *) world->item_def; + d->id != def_id && 0 != d->next; + d = d->next); + } + return d; +} diff --git a/src/map_objects.h b/src/map_objects.h index f39df0d..ebda314 100644 --- a/src/map_objects.h +++ b/src/map_objects.h @@ -1,49 +1,122 @@ +/* map_objects.h + * + * Structs for objects on the map and their type definitions, and routines to + * initialize these and load and save them from/to files. + */ + #ifndef MAP_OBJECTS_H #define MAP_OBJECTS_H -#include -#include "yx_uint16.h" + +#include /* for FILE typedef */ +#include "yx_uint16.h" /* for yx_uint16 coordinates */ struct World; -struct Player { - struct yx_uint16 pos; - unsigned char hitpoints; }; - -struct MapObj { - void * next; - char type; - struct yx_uint16 pos; }; - -struct MapObjDef { - struct MapObjDef * next; - char id; - char mapchar; - char * desc; }; - -struct Item { - struct MapObj map_obj; }; - -struct Monster { - struct MapObj map_obj; - unsigned char hitpoints; }; - -struct ItemDef { - struct MapObjDef map_obj_def; }; - -struct MonsterDef { - struct MapObjDef map_obj_def; - unsigned char hitpoints_start; }; - -extern void init_map_object_defs (struct World *, char *); -extern void write_map_objects_monsterdata (void *, FILE *); -extern void write_map_objects (void * start, FILE *, void (*) (void *, FILE *) ); -extern void read_map_objects_monsterdata (void *, FILE *); -extern void read_map_objects (void *, FILE *, size_t, void (*) (void *, FILE *) ); -extern void build_map_objects_monsterdata (struct MapObjDef *, void *); -extern void build_map_objects_itemdata (struct MapObjDef *, void *); -extern void * build_map_objects (struct World *, void *, char, unsigned char, size_t, + + +/* Player is non-standard: single and of a hard-coded type. */ + +struct Player +{ + struct yx_uint16 pos; + unsigned char hitpoints; +}; + + + +/* Structs for standard map objects. */ + +struct MapObj +{ + void * next; + char type; /* Map object type identifier (see MapObjDef.id). */ + struct yx_uint16 pos; /* Coordinate of object on map. */ +}; + +struct Item +{ + struct MapObj map_obj; +}; + +struct Monster +{ + struct MapObj map_obj; + unsigned char hitpoints; +}; + + + +/* Structs for map object *type* definitions. Values common to all members of + * a single monster or item type are harvested from these. + */ + +struct MapObjDef +{ + struct MapObjDef * next; + 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. */ +}; + +struct ItemDef +{ + struct MapObjDef map_obj_def; +}; + +struct MonsterDef +{ + struct MapObjDef map_obj_def; + unsigned char hitpoints_start; /* Hitpoints each monster starts with. */ +}; + + + +/* Initialize map object type definitions from file at path "filename". */ +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. + */ +extern void * build_map_objects(struct World * world, void * start, char def_id, + unsigned char n, size_t size, void (*) (struct MapObjDef *, void *)); -extern struct MapObjDef * get_map_obj_def (struct World *, char); +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); + + + +/* 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. + */ +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); + + + +/* Get pointer to the map object definition of identifier "def_id". */ +extern struct MapObjDef * get_map_obj_def(struct World * world, char def_id); #endif diff --git a/src/readwrite.c b/src/readwrite.c index 9dbcac4..40fc63f 100644 --- a/src/readwrite.c +++ b/src/readwrite.c @@ -1,8 +1,10 @@ /* readwrite.c */ #include "readwrite.h" -#include -#include +#include /* for FILE typedef*/ +#include /* for uint16_t, uint32_t */ + + extern uint16_t read_uint16_bigendian(FILE * file) { @@ -12,6 +14,8 @@ extern uint16_t read_uint16_bigendian(FILE * file) return x; } + + extern uint32_t read_uint32_bigendian(FILE * file) { uint32_t x; @@ -22,12 +26,16 @@ extern uint32_t read_uint32_bigendian(FILE * file) return x; } + + extern void write_uint16_bigendian(uint16_t x, FILE * file) { fputc( x >> 8, file ); fputc( x & 0xFF, file ); } + + extern void write_uint32_bigendian(uint32_t x, FILE * file) { fputc( x >> 24, file); diff --git a/src/readwrite.h b/src/readwrite.h index 84085d2..a0c8dba 100644 --- a/src/readwrite.h +++ b/src/readwrite.h @@ -1,14 +1,18 @@ -/* readwrite.h: +/* readwrite.h: * - * Routines for reading/writing multibyte data from/to files. They ensure a - * defined endianness. + * Routines for reading/writing multibyte data from/to files. They ensure a + * defined endianness. */ #ifndef READWRITE_H #define READWRITE_H -#include -#include + + +#include /* for FILE typedef */ +#include /* for uint16_t, uint32_t */ + + extern uint16_t read_uint16_bigendian(FILE * file); extern uint32_t read_uint32_bigendian(FILE * file); diff --git a/src/yx_uint16.c b/src/yx_uint16.c index 8fb41bf..2d7503b 100644 --- a/src/yx_uint16.c +++ b/src/yx_uint16.c @@ -1,6 +1,10 @@ /* yx_uint16.c */ -#include "yx_uint16.h" + + +#include "yx_uint16.h" /* for uint16_t */ + + extern char yx_uint16_cmp(struct yx_uint16 a, struct yx_uint16 b) { @@ -10,6 +14,8 @@ extern char yx_uint16_cmp(struct yx_uint16 a, struct yx_uint16 b) return 0; } + + extern struct yx_uint16 mv_yx_in_dir(enum dir d, struct yx_uint16 yx) { if (d == NORTH) diff --git a/src/yx_uint16.h b/src/yx_uint16.h index eb951a7..29298e5 100644 --- a/src/yx_uint16.h +++ b/src/yx_uint16.h @@ -1,13 +1,17 @@ -/* yx_uint16.h +/* yx_uint16.h * - * Structs and routines for coordinates and movement in 2-dimensional space - * (such as the ncurses screen and game maps). + * Structs and routines for coordinates and movement in 2-dimensional space + * (such as the ncurses screen and game maps). */ #ifndef YX_UINT16_H #define YX_UINT16_H -#include + + +#include /* for uint16_t */ + + /* Coordinates for maps of max. 65536x65536 cells. */ struct yx_uint16 @@ -16,14 +20,13 @@ struct yx_uint16 uint16_t x; }; -/* This encodes directions. */ - +/* Directions available for movement. */ enum dir { NORTH = 1, - EAST = 2, - SOUTH = 3, - WEST = 4 + EAST, + SOUTH, + WEST }; /* Return 1 if two yx_uint16 coordinates a and b are equal, else 0. */