comparison rogue5/state.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children 09db0cf536af
comparison
equal deleted inserted replaced
32:2dcd75e6a736 33:f502bf60e6e4
1 /*
2 state.c - Portable Rogue Save State Code
3
4 Copyright (C) 1999, 2000, 2005 Nicholas J. Kisseberth
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. Neither the name(s) of the author(s) nor the names of other contributors
16 may be used to endorse or promote products derived from this software
17 without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 SUCH DAMAGE.
30 */
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <curses.h>
35 #include <errno.h>
36 #include "rogue.h"
37
38 /************************************************************************/
39 /* Save State Code */
40 /************************************************************************/
41
42 #define RSID_STATS 0xABCD0001
43 #define RSID_THING 0xABCD0002
44 #define RSID_THING_NULL 0xDEAD0002
45 #define RSID_OBJECT 0xABCD0003
46 #define RSID_MAGICITEMS 0xABCD0004
47 #define RSID_KNOWS 0xABCD0005
48 #define RSID_GUESSES 0xABCD0006
49 #define RSID_OBJECTLIST 0xABCD0007
50 #define RSID_BAGOBJECT 0xABCD0008
51 #define RSID_MONSTERLIST 0xABCD0009
52 #define RSID_MONSTERSTATS 0xABCD000A
53 #define RSID_MONSTERS 0xABCD000B
54 #define RSID_TRAP 0xABCD000C
55 #define RSID_WINDOW 0xABCD000D
56 #define RSID_DAEMONS 0xABCD000E
57 #define RSID_IWEAPS 0xABCD000F
58 #define RSID_IARMOR 0xABCD0010
59 #define RSID_SPELLS 0xABCD0011
60 #define RSID_ILIST 0xABCD0012
61 #define RSID_HLIST 0xABCD0013
62 #define RSID_DEATHTYPE 0xABCD0014
63 #define RSID_CTYPES 0XABCD0015
64 #define RSID_COORDLIST 0XABCD0016
65 #define RSID_ROOMS 0XABCD0017
66
67 #define READSTAT (format_error || read_error )
68 #define WRITESTAT (write_error)
69
70 static int read_error = FALSE;
71 static int write_error = FALSE;
72 static int format_error = FALSE;
73 static int endian = 0x01020304;
74 #define big_endian ( *((char *)&endian) == 0x01 )
75
76 void
77 rs_write(FILE *savef, const void *ptr, size_t size)
78 {
79 encwrite(ptr, size, savef);
80 }
81
82 void
83 rs_read(FILE *savef, void *ptr, size_t size)
84 {
85 encread(ptr, size, savef);
86 }
87
88 void
89 rs_write_int(FILE *savef, int c)
90 {
91 char bytes[4];
92 char *buf = (char *) &c;
93
94 if (big_endian)
95 {
96 bytes[3] = buf[0];
97 bytes[2] = buf[1];
98 bytes[1] = buf[2];
99 bytes[0] = buf[3];
100 buf = bytes;
101 }
102
103 rs_write(savef, buf, 4);
104 }
105
106 void
107 rs_read_int(FILE *savef, int *i)
108 {
109 char bytes[4];
110 int input = 0;
111 char *buf = (char *)&input;
112
113 rs_read(savef, &input, 4);
114
115 if (encerror())
116 return;
117
118 if (big_endian)
119 {
120 bytes[3] = buf[0];
121 bytes[2] = buf[1];
122 bytes[1] = buf[2];
123 bytes[0] = buf[3];
124 buf = bytes;
125 }
126
127 *i = *((int *) buf);
128 }
129
130 void
131 rs_write_uint(FILE *savef, unsigned int c)
132 {
133 char bytes[4];
134 char *buf = (char *) &c;
135
136 if (big_endian)
137 {
138 bytes[3] = buf[0];
139 bytes[2] = buf[1];
140 bytes[1] = buf[2];
141 bytes[0] = buf[3];
142 buf = bytes;
143 }
144
145 rs_write(savef, buf, 4);
146 }
147
148 void
149 rs_read_uint(FILE *savef, unsigned int *i)
150 {
151 char bytes[4];
152 int input = 0;
153 char *buf = (char *)&input;
154
155 rs_read(savef, &input, 4);
156
157 if (encerror())
158 return;
159
160 if (big_endian)
161 {
162 bytes[3] = buf[0];
163 bytes[2] = buf[1];
164 bytes[1] = buf[2];
165 bytes[0] = buf[3];
166 buf = bytes;
167 }
168
169 *i = *((unsigned int *) buf);
170 }
171
172 void
173 rs_write_chars(FILE *savef, const char *c, int cnt)
174 {
175 rs_write_int(savef, cnt);
176 rs_write(savef, c, cnt);
177 }
178
179 void
180 rs_read_chars(FILE *savef, char *i, int cnt)
181 {
182 int value = 0;
183
184 rs_read_int(savef, &value);
185
186 if (!encerror() && (value != cnt))
187 encseterr(EILSEQ);
188
189 rs_read(savef, i, cnt);
190 }
191
192 void
193 rs_write_ints(FILE *savef, int *c, int cnt)
194 {
195 int n = 0;
196
197 rs_write_int(savef, cnt);
198
199 for(n = 0; n < cnt; n++)
200 rs_write_int(savef,c[n]);
201 }
202
203 void
204 rs_read_ints(FILE *savef, int *i, int cnt)
205 {
206 int n, value;
207
208 rs_read_int(savef,&value);
209
210 if (!encerror() && (value != cnt))
211 encseterr(EILSEQ);
212
213 for(n = 0; n < cnt; n++)
214 rs_read_int(savef, &i[n]);
215 }
216
217 void
218 rs_write_marker(FILE *savef, int id)
219 {
220 rs_write_int(savef, id);
221 }
222
223 void
224 rs_read_marker(FILE *savef, int id)
225 {
226 int nid;
227
228 rs_read_int(savef, &nid);
229
230 if (!encerror() && (id != nid))
231 encseterr(EILSEQ);
232 }
233
234 /******************************************************************************/
235
236 void
237 rs_write_string(FILE *savef, const char *s)
238 {
239 int len = 0;
240
241 len = (s == NULL) ? 0 : (int) strlen(s) + 1;
242
243 rs_write_int(savef, len);
244 rs_write_chars(savef, s, len);
245 }
246
247 void
248 rs_read_string(FILE *savef, char *s, int max)
249 {
250 int len = 0;
251
252 rs_read_int(savef, &len);
253
254 if (!encerror() && (len > max))
255 encseterr(EILSEQ);
256
257 rs_read_chars(savef, s, len);
258 }
259
260 void
261 rs_read_new_string(FILE *savef, char **s)
262 {
263 int len=0;
264 char *buf=0;
265
266 rs_read_int(savef, &len);
267
268 if (encerror())
269 return;
270
271 if (len == 0)
272 buf = NULL;
273 else
274 {
275 buf = malloc(len);
276
277 if (buf == NULL)
278 encseterr(ENOMEM);
279 }
280
281 rs_read_chars(savef, buf, len);
282
283 *s = buf;
284 }
285
286 void
287 rs_write_string_index(FILE *savef, const char *master[], int max, const char *str)
288 {
289 int i;
290
291 for(i = 0; i < max; i++)
292 if (str == master[i])
293 {
294 rs_write_int(savef, i);
295 return;
296 }
297
298 rs_write_int(savef,-1);
299 }
300
301 void
302 rs_read_string_index(FILE *savef, const char *master[], int maxindex, const char **str)
303 {
304 int i;
305
306 rs_read_int(savef, &i);
307
308 if (!encerror() && (i > maxindex))
309 encseterr(EILSEQ);
310 else if (i >= 0)
311 *str = master[i];
312 else
313 *str = NULL;
314 }
315
316 void
317 rs_write_coord(FILE *savef, coord c)
318 {
319 rs_write_int(savef, c.x);
320 rs_write_int(savef, c.y);
321 }
322
323 void
324 rs_read_coord(FILE *savef, coord *c)
325 {
326 coord in;
327
328 rs_read_int(savef,&in.x);
329 rs_read_int(savef,&in.y);
330
331 if (!encerror())
332 {
333 c->x = in.x;
334 c->y = in.y;
335 }
336 }
337
338 void
339 rs_write_window(FILE *savef, WINDOW *win)
340 {
341 int row,col,height,width;
342
343 width = getmaxx(win);
344 height = getmaxy(win);
345
346 rs_write_marker(savef,RSID_WINDOW);
347 rs_write_int(savef,height);
348 rs_write_int(savef,width);
349
350 for(row=0;row<height;row++)
351 for(col=0;col<width;col++)
352 rs_write_int(savef, mvwinch(win,row,col));
353 }
354
355 void
356 rs_read_window(FILE *savef, WINDOW *win)
357 {
358 int row,col,maxlines,maxcols,value,width,height;
359
360 width = getmaxx(win);
361 height = getmaxy(win);
362
363 rs_read_marker(savef, RSID_WINDOW);
364
365 rs_read_int(savef, &maxlines);
366 rs_read_int(savef, &maxcols);
367
368 if (encerror())
369 return;
370
371 for(row = 0; row < maxlines; row++)
372 for(col = 0; col < maxcols; col++)
373 {
374 rs_read_int(savef, &value);
375
376 if ((row < height) && (col < width))
377 mvwaddch(win,row,col,value);
378 }
379 }
380
381 /******************************************************************************/
382
383 void *
384 get_list_item(THING *l, int i)
385 {