Mercurial > hg > early-roguelike
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 { | |