* draw_log_win()
*/
#include "keybindings.h" /* for initkeybindings(), get_action_key() */
-#include "readwrite.h" /* for read_uint16_bigendian, read_uint32_bigendian,
- * write_uint32_bigendian
- */
+#include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */
#include "map_objects.h" /* for structs Monster, Item, Player,
* init_map_object_defs(), read_map_objects(),
* build_map_objects()
world.monster = 0;
world.item = 0;
init_map_object_defs(&world, "defs");
+ uint8_t fail = 0;
/* For interactive mode, try to load world state from savefile. */
FILE * file;
if (1 == world.interactive && 0 == access("savefile", F_OK))
{
file = fopen("savefile", "r");
- world.seed = read_uint32_bigendian(file);
- world.turn = read_uint32_bigendian(file);
- player.pos.y = read_uint16_bigendian(file) - 1;
- player.pos.x = read_uint16_bigendian(file) - 1;
- player.hitpoints = fgetc(file);
- read_map_objects(&world, &world.monster, file);
- read_map_objects(&world, &world.item, file);
+ fail = fail | read_uint32_bigendian(file, &world.seed);
+ fail = fail | read_uint32_bigendian(file, &world.turn);
+ fail = fail | read_uint16_bigendian(file, &player.pos.y);
+ fail = fail | read_uint16_bigendian(file, &player.pos.x);
+ player.pos.y--;
+ player.pos.x--;
+ fail = fail | read_uint8(file, &player.hitpoints);
+ fail = fail | read_map_objects(&world, &world.monster, file);
+ fail = fail | read_map_objects(&world, &world.item, file);
fclose(file);
}
if (0 == world.interactive)
{
file = fopen("record", "r");
- world.seed = read_uint32_bigendian(file);
+ fail = fail | read_uint32_bigendian(file, &world.seed);
+ }
+
+ /* For interactive-mode in newly started world, generate a start seed
+ * from the current time.
+ */
+ else
+ {
+ file = fopen("record", "w");
+ world.seed = time(NULL);
+ fail = fail | write_uint32_bigendian(world.seed, file);
+ fclose(file);
}
+ }
+
+ exit_err(fail, &world, "Failure initializing game.");
- /* For interactive-mode in newly started world, generate a start seed
- * from the current time.
- */
- else
- {
- file = fopen("record", "w");
- world.seed = time(NULL);
- write_uint32_bigendian(world.seed, file);
- fclose(file);
- }
- }
/* Generate map from seed and, if newly generated world, start positions of
* actors.
#include <stdlib.h> /* for malloc(), calloc(), free(), atoi() */
#include <stdio.h> /* for FILE typedef */
#include <string.h> /* for strchr(), strlen(), memcpy() */
-#include "readwrite.h" /* for all the map object (def) loading/saving */
+#include "readwrite.h" /* for [read/write]_uint[8/16/23][_bigendian]() */
#include "misc.h" /* for textfile_sizes(), find_passable_pos() */
#include "main.h" /* for World struct */
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 uint8_t write_map_objects_monsterdata(void * start, FILE * file);
+static uint8_t read_map_objects_monsterdata( void * start, FILE * file);
-static void write_map_objects_monsterdata(void * start, FILE * file)
+static uint8_t write_map_objects_monsterdata(void * start, FILE * file)
{
struct Monster * m = (struct Monster *) start;
- fputc(m->hitpoints, file);
+ return write_uint8(m->hitpoints, file);
}
-static void read_map_objects_monsterdata (void * start, FILE * file)
+static uint8_t read_map_objects_monsterdata (void * start, FILE * file)
{
struct Monster * m = (struct Monster *) start;
- m->hitpoints = fgetc(file);
+ return read_uint8(file, &m->hitpoints);
}
-extern void write_map_objects(struct World * world, void * start, FILE * file)
+extern uint8_t write_map_objects(struct World * world, void * start,
+ FILE * file)
{
struct MapObj * map_obj;
struct MapObjDef * mod;
+ uint8_t fail = 0;
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);
+ fail = fail | write_uint8(map_obj->type, file);
+ fail = fail | write_uint16_bigendian(map_obj->pos.y + 1, file);
+ fail = fail | write_uint16_bigendian(map_obj->pos.x + 1, file);
mod = get_map_obj_def(world, map_obj->type);
if ('m' == mod->m_or_i)
{
- write_map_objects_monsterdata(map_obj, file);
+ fail = fail | write_map_objects_monsterdata(map_obj, file);
}
}
- write_uint16_bigendian(0, file);
+ return (fail | write_uint16_bigendian(0, file));
}
-extern void read_map_objects(struct World * world, void * start, FILE * file)
+extern uint8_t read_map_objects(struct World * world, void * start, FILE * file)
{
struct MapObj * map_obj;
struct MapObjDef * mod;
size_t size;
- char type;
+ uint8_t type;
char first = 1;
long pos;
+ uint16_t read_uint16 = 0;
+ uint8_t fail = 0;
while (1)
{
pos = ftell(file);
- if (0 == read_uint16_bigendian(file))
+ fail = fail | read_uint16_bigendian(file, &read_uint16);
+ if (0 == read_uint16)
{
break;
}
fseek(file, pos, SEEK_SET);
- type = fgetc(file);
+ fail = fail | read_uint8(file, &type);
mod = get_map_obj_def(world, type);
if ('m' == mod->m_or_i)
{
}
map_obj = get_next_map_obj(start, &first, size, map_obj);
map_obj->type = type;
- map_obj->pos.y = read_uint16_bigendian(file) - 1;
- map_obj->pos.x = read_uint16_bigendian(file) - 1;
+ fail = fail | read_uint16_bigendian(file, &map_obj->pos.y);
+ fail = fail | read_uint16_bigendian(file, &map_obj->pos.x);
+ map_obj->pos.y--;
+ map_obj->pos.x--;
if ('m' == mod->m_or_i)
{
- read_map_objects_monsterdata(map_obj, file);
+ fail = fail | read_map_objects_monsterdata(map_obj, file);
}
}
if (!first)
{
map_obj->next = 0;
}
+ return fail;
}
/* Write to/read from file chain of map objects starting/to start in memory at
* "start".
*/
-extern void write_map_objects(struct World * world, void * start, FILE * file);
-extern void read_map_objects(struct World * world, void * start, FILE * file);
+extern uint8_t write_map_objects(struct World * world, void * start,
+ FILE * file);
+extern uint8_t read_map_objects(struct World * world, void * start, FILE * file);
#include "keybindings.h" /* for get_action_key(), save_keybindings(),
* keyswin_move_selection(), keyswin_mod_key()
*/
-#include "readwrite.h" /* for write_uint16_bigendian(), write_uint32_bigendian()
- */
+#include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */
#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 */
#include "yx_uint16.h" /* for yx_uint16 */
#include "rrand.h" /* for rrand(), rrand_seed() */
-
+#include "rexit.h" /* for exit_err() */
extern void textfile_sizes(FILE * file, uint16_t * linemax_p,
if (1 == world->interactive)
{
FILE * file = fopen("record", "a");
- fputc(action, file);
+ exit_err(write_uint8(action, file), world, "Record writing failure.");
fclose(file);
}
world->turn++;
extern void save_game(struct World * world)
{
+ uint8_t fail;
FILE * file = fopen("savefile", "w");
- write_uint32_bigendian(world->seed, file);
- write_uint32_bigendian(world->turn, file);
- 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, world->monster, file);
- write_map_objects(world, world->item, file);
+ fail = write_uint32_bigendian(world->seed, file);
+ fail = fail | write_uint32_bigendian(world->turn, file);
+ fail = fail | write_uint16_bigendian(world->player->pos.y + 1, file);
+ fail = fail | write_uint16_bigendian(world->player->pos.x + 1, file);
+ fail = fail | write_uint8(world->player->hitpoints, file);
+ fail = fail | write_map_objects(world, world->monster, file);
+ fail = fail | write_map_objects(world, world->item, file);
+ exit_err(fail, world, "Error saving game.");
fclose(file);
}
-extern uint16_t read_uint16_bigendian(FILE * file)
+/* Read/write "x" from/to "file" as bigendian representation of "size" bits. */
+static uint8_t read_uintX_bigendian(FILE * file, uint32_t * x, uint8_t size);
+static uint8_t write_uintX_bigendian(FILE * file, uint32_t x, uint8_t size);
+
+
+
+static uint8_t read_uintX_bigendian(FILE * file, uint32_t * x, uint8_t size)
+{
+ if (0 != size % 8)
+ {
+ return 1;
+ }
+ int16_t bitshift = size - 8;
+
+ * x = 0;
+ int test;
+ for (; bitshift >= 0; bitshift = bitshift - 8)
+ {
+ test = fgetc(file);
+ if (EOF == test)
+ {
+ return 1;
+ }
+ * x = * x + ((uint32_t) test << bitshift);
+ }
+ return 0;
+}
+
+
+
+static uint8_t write_uintX_bigendian(FILE * file, uint32_t x, uint8_t size)
+{
+ if (0 != size % 8)
+ {
+ return 1;
+ }
+ int16_t bitshift = size - 8;
+
+ for (; bitshift >= 0; bitshift = bitshift - 8)
+ {
+ if (EOF == fputc((x >> bitshift) & 0xFF, file))
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+
+extern uint8_t read_uint8(FILE * file, uint8_t * x)
+{
+ uint32_t y = * x;
+ uint8_t fail = read_uintX_bigendian(file, &y, 8);
+ * x = (uint8_t) y;
+ return fail;
+}
+
+
+
+extern uint8_t read_uint16_bigendian(FILE * file, uint16_t * x)
+{
+ uint32_t y = * x;
+ uint8_t fail = read_uintX_bigendian(file, &y, 16);
+ * x = (uint16_t) y;
+ return fail;
+}
+
+
+
+extern uint8_t read_uint32_bigendian(FILE * file, uint32_t * x)
{
- uint16_t x;
- x = (uint16_t) fgetc(file) << 8;
- x = x + (uint16_t) fgetc(file);
- return x;
+ return read_uintX_bigendian(file, x, 32);
}
-extern uint32_t read_uint32_bigendian(FILE * file)
+extern uint8_t write_uint8(uint8_t x, FILE * file)
{
- uint32_t x;
- x = (uint32_t) fgetc(file) << 24;
- x = x + ( (uint32_t) fgetc(file) << 16 );
- x = x + ( (uint32_t) fgetc(file) << 8 );
- x = x + (uint32_t) fgetc(file);
- return x;
+ return write_uintX_bigendian(file, x, 8);
}
-extern void write_uint16_bigendian(uint16_t x, FILE * file)
+extern uint8_t write_uint16_bigendian(uint16_t x, FILE * file)
{
- fputc( x >> 8, file );
- fputc( x & 0xFF, file );
+ return write_uintX_bigendian(file, x, 16);
}
-extern void write_uint32_bigendian(uint32_t x, FILE * file)
+extern uint8_t write_uint32_bigendian(uint32_t x, FILE * file)
{
- fputc( x >> 24, file);
- fputc( ( x >> 16 ) & 0xFF, file);
- fputc( ( x >> 8 ) & 0xFF, file);
- fputc( x & 0xFF, file);
+ return write_uintX_bigendian(file, x, 32);
}
/* readwrite.h:
*
- * Routines for reading/writing multibyte data from/to files. They ensure a
+ * Routines for reading/writing (multi-)byte data from/to files. They ensure a
* defined endianness.
*/
-extern uint16_t read_uint16_bigendian(FILE * file);
-extern uint32_t read_uint32_bigendian(FILE * file);
-extern void write_uint16_bigendian(uint16_t x, FILE * file);
-extern void write_uint32_bigendian(uint32_t x, FILE * file);
+/* Each function returns 0 on success and 1 on failure. "x" is the value to be
+ * written to "file" for write_* functions and for read_* functions the pointer
+ * to where the value read from "file" is to be written.
+ */
+extern uint8_t read_uint8(FILE * file, uint8_t * x);
+extern uint8_t read_uint16_bigendian(FILE * file, uint16_t * x);
+extern uint8_t read_uint32_bigendian(FILE * file, uint32_t * x);
+extern uint8_t write_uint8(uint8_t x, FILE * file);
+extern uint8_t write_uint16_bigendian(uint16_t x, FILE * file);
+extern uint8_t write_uint32_bigendian(uint32_t x, FILE * file);
#endif