#include "adventure.h" #include #include #include #include #include /* the last 32 bits are a version number to be increased on breaking changes. */ static const char magic[] = { 0, 0, 0, 0, 'T', 'E', 'X', 'T', 'A', 'D', 'V', 0, 0, 0, 0 }; #define MLEN sizeof(magic) /* Every object is serialized in a buffer with the following format: * * | offset | location | weight | capacity | health | * * with each field 32 bits long, for a total of 160 bytes. Each field is a * SIGNED 32 bit integer. The meaning of the fields is as follows: * * - offset : the current object, that is objs[offset] * - location : the offset of the location, if NULL -1 * - weight, capacity, health : the propriety of the object. * * This should make cheating a little bit harder. */ int save(void) { char *line; FILE *f; struct object *obj; line = readline("Save to file: "); if (!line || !*line) { printf("Invalid filename\n"); if (line != NULL) free(line); return save(); } /* b = binary mode, for windows compatibility I guess */ if ((f = fopen(line, "wb")) == NULL) { printf("Cannot write file!\n"); return 0; } /* write magic header */ fwrite(magic, 1, MLEN, f); /* write the objects */ for (obj = objs; obj < obj_end; ++obj) { int32_t offset, location, weight, capacity, health; offset = obj - objs; if (obj->location == NULL) location = -1; else location = obj->location - objs; weight = obj->weight; capacity = obj->capacity; health = obj->health; printf("saved: %d %d %d %d %d\n", offset, location, weight, capacity, health); fwrite(&offset, 4, 1, f); fwrite(&location, 4, 1, f); fwrite(&weight, 4, 1, f); fwrite(&capacity, 4, 1, f); fwrite(&health, 4, 1, f); } fclose(f); free(line); return 1; } int load(void) { char *line, m[MLEN]; FILE *f; ssize_t r; line = readline("Load from file: "); if (!line || !*line) { printf("Invalid filename\n"); if (line != NULL) free(line); return load(); } if ((f = fopen(line, "rb")) == NULL) { printf("Cannot open file %s\n", line); free(line); return 0; } /* read the magic */ fread(m, MLEN, 1, f); if (memcmp(m, magic, MLEN)) { printf("Wrong magic in file, cannot load.\n"); goto err; } /* read all the objects */ while (1) { int32_t offset, location, weight, capacity, health; if ((r = fread(&offset, 1, 4, f)) != 4) break; if ((r = fread(&location, 1, 4, f)) != 4) break; if ((r = fread(&weight, 1, 4, f)) != 4) break; if ((r = fread(&capacity, 1, 4, f)) != 4) break; if ((r = fread(&health, 1, 4, f)) != 4) break; if (objs + offset >= obj_end) goto err; if (location == -1) objs[offset].location = NULL; else { if (objs + location >= obj_end) goto err; objs[offset].location = objs + location; } objs[offset].weight = weight; objs[offset].capacity = capacity; objs[offset].health = health; } if (ferror(f)) { perror(line); goto err; } printf("OK!\n"); fclose(f); free(line); return 1; err: printf("Error in loading file!\n"); fclose(f); free(line); return 0; }