Blame


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