Blob


1 #include "adventure.h"
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
8 #include <readline/readline.h>
10 /* the last 32 bits are a version number to be increased on breaking changes.
11 */
12 static const char magic[]
13 = { 0, 0, 0, 0, 'T', 'E', 'X', 'T', 'A', 'D', 'V', 0, 0, 0, 0 };
15 #define MLEN sizeof(magic)
17 /* Every object is serialized in a buffer with the following format:
18 *
19 * | offset | location | weight | capacity | health |
20 *
21 * with each field 32 bits long, for a total of 160 bytes. Each field is a
22 * SIGNED 32 bit integer. The meaning of the fields is as follows:
23 *
24 * - offset : the current object, that is objs[offset]
25 * - location : the offset of the location, if NULL -1
26 * - weight, capacity, health : the propriety of the object.
27 *
28 * This should make cheating a little bit harder.
29 */
31 int
32 save(void)
33 {
34 char *line;
35 FILE *f;
36 struct object *obj;
38 line = readline("Save to file: ");
39 if (!line || !*line) {
40 printf("Invalid filename\n");
42 if (line != NULL)
43 free(line);
45 return save();
46 }
48 /* b = binary mode, for windows compatibility I guess */
49 if ((f = fopen(line, "wb")) == NULL) {
50 printf("Cannot write file!\n");
51 return 0;
52 }
54 /* write magic header */
55 fwrite(magic, 1, MLEN, f);
57 /* write the objects */
58 for (obj = objs; obj < obj_end; ++obj) {
59 int32_t offset, location, weight, capacity, health;
61 offset = obj - objs;
62 if (obj->location == NULL)
63 location = -1;
64 else
65 location = obj->location - objs;
66 weight = obj->weight;
67 capacity = obj->capacity;
68 health = obj->health;
70 printf("saved: %d %d %d %d %d\n", offset, location, weight,
71 capacity, health);
73 fwrite(&offset, 4, 1, f);
74 fwrite(&location, 4, 1, f);
75 fwrite(&weight, 4, 1, f);
76 fwrite(&capacity, 4, 1, f);
77 fwrite(&health, 4, 1, f);
78 }
80 fclose(f);
81 free(line);
82 return 1;
83 }
85 int
86 load(void)
87 {
88 char *line, m[MLEN];
89 FILE *f;
90 ssize_t r;
92 line = readline("Load from file: ");
93 if (!line || !*line) {
94 printf("Invalid filename\n");
96 if (line != NULL)
97 free(line);
99 return load();
102 if ((f = fopen(line, "rb")) == NULL) {
103 printf("Cannot open file %s\n", line);
104 free(line);
105 return 0;
108 /* read the magic */
109 fread(m, MLEN, 1, f);
110 if (memcmp(m, magic, MLEN)) {
111 printf("Wrong magic in file, cannot load.\n");
112 goto err;
115 /* read all the objects */
116 while (1) {
117 int32_t offset, location, weight, capacity, health;
119 if ((r = fread(&offset, 1, 4, f)) != 4)
120 break;
121 if ((r = fread(&location, 1, 4, f)) != 4)
122 break;
123 if ((r = fread(&weight, 1, 4, f)) != 4)
124 break;
125 if ((r = fread(&capacity, 1, 4, f)) != 4)
126 break;
127 if ((r = fread(&health, 1, 4, f)) != 4)
128 break;
130 if (objs + offset >= obj_end)
131 goto err;
133 if (location == -1)
134 objs[offset].location = NULL;
135 else {
136 if (objs + location >= obj_end)
137 goto err;
139 objs[offset].location = objs + location;
142 objs[offset].weight = weight;
143 objs[offset].capacity = capacity;
144 objs[offset].health = health;
147 if (ferror(f)) {
148 perror(line);
149 goto err;
152 printf("OK!\n");
153 fclose(f);
154 free(line);
155 return 1;
157 err:
158 printf("Error in loading file!\n");
159 fclose(f);
160 free(line);
161 return 0;