Annotation of early-roguelike/rogue3/state.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: state.c - Portable Rogue Save State Code
3:
4: Copyright (C) 1999, 2000, 2005, 2007, 2008 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, char *master[], int max, 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, char *master[], int maxindex, 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_str_t(FILE *savef, str_t str)
340: {
341: rs_write_int(savef, str.st_str);
342: rs_write_int(savef, str.st_add);
343: }
344:
345: void
346: rs_read_str_t(FILE *savef, str_t *str)
347: {
348: str_t in;
349:
350: rs_read_int(savef,&in.st_str);
351: rs_read_int(savef,&in.st_add);
352:
353: if (!encerror())
354: {
355: str->st_str = in.st_str;
356: str->st_add = in.st_add;
357: }
358: }
359:
360: void
361: rs_write_window(FILE *savef, WINDOW *win)
362: {
363: int row,col,height,width;
364:
365: width = getmaxx(win);
366: height = getmaxy(win);
367:
368: rs_write_marker(savef,RSID_WINDOW);
369: rs_write_int(savef,height);
370: rs_write_int(savef,width);
371:
372: for(row=0;row<height;row++)
373: for(col=0;col<width;col++)
374: rs_write_int(savef, mvwinch(win,row,col));
375: }
376:
377: void
378: rs_read_window(FILE *savef, WINDOW *win)
379: {
380: int row,col,maxlines,maxcols,value,width,height;
381:
382: width = getmaxx(win);
383: height = getmaxy(win);
384:
385: rs_read_marker(savef, RSID_WINDOW);
386:
387: rs_read_int(savef, &maxlines);
388: rs_read_int(savef, &maxcols);
389:
390: if (encerror())
391: return;
392:
393: for(row = 0; row < maxlines; row++)
394: for(col = 0; col < maxcols; col++)
395: {
396: rs_read_int(savef, &value);
397:
398: if ((row < height) && (col < width))
399: mvwaddch(win,row,col,value);
400: }
401: }
402:
403: /******************************************************************************/
404:
405: void *
406: get_list_item(struct linked_list *l, int i)
407: {
408: int cnt;
409:
410: for(cnt = 0; l != NULL; cnt++, l = l->l_next)
411: if (cnt == i)
412: return(l->l_data);
413:
414: return(NULL);
415: }
416:
417: int
418: find_list_ptr(struct linked_list *l, void *ptr)
419: {
420: int cnt;
421:
422: for(cnt = 0; l != NULL; cnt++, l = l->l_next)
423: if (l->l_data == ptr)
424: return(cnt);
425:
426: return(-1);
427: }
428:
429: int
430: list_size(struct linked_list *l)
431: {
432: int cnt;
433:
434: for(cnt = 0; l != NULL; cnt++, l = l->l_next)
435: if (l->l_data == NULL)
436: return(cnt);
437:
438: return(cnt);
439: }
440:
441: /******************************************************************************/
442:
443: void
444: rs_write_stats(FILE *savef, struct stats *s)
445: {
446: rs_write_marker(savef, RSID_STATS);
447: rs_write_str_t(savef, s->s_str);
448: rs_write_int(savef, s->s_exp);
449: rs_write_int(savef, s->s_lvl);
450: rs_write_int(savef, s->s_arm);
451: rs_write_int(savef, s->s_hpt);
452: rs_write_chars(savef, s->s_dmg, sizeof(s->s_dmg));
453: }
454:
455:
456: void
457: rs_read_stats(FILE *savef, struct stats *s)
458: {
459: rs_read_marker(savef, RSID_STATS);
460: rs_read_str_t(savef,&s->s_str);
461: rs_read_int(savef,&s->s_exp);
462: rs_read_int(savef,&s->s_lvl);
463: rs_read_int(savef,&s->s_arm);
464: rs_read_int(savef,&s->s_hpt);
465: rs_read_chars(savef,s->s_dmg,sizeof(s->s_dmg));
466: }
467:
468:
469: void
470: rs_write_scrolls(FILE *savef)
471: {
472: int i;
473:
474: for(i = 0; i < MAXSCROLLS; i++)
475: {
476: rs_write_string(savef,s_names[i]);
477: rs_write_int(savef,s_know[i]);
478: rs_write_string(savef,s_guess[i]);
479: }
480: }
481:
482: void
483: rs_read_scrolls(FILE *savef)
484: {
485: int i;
486:
487: for(i = 0; i < MAXSCROLLS; i++)
488: {
489: rs_read_new_string(savef,&s_names[i]);
490: rs_read_int(savef,&s_know[i]);
491: rs_read_new_string(savef,&s_guess[i]);
492: }
493: }
494:
495: void
496: rs_write_potions(FILE *savef)
497: {
498: int i;
499:
500: for(i = 0; i < MAXPOTIONS; i++)
501: {
502: rs_write_string_index(savef, rainbow, cNCOLORS, p_colors[i]);
503: rs_write_int(savef,p_know[i]);
504: rs_write_string(savef,p_guess[i]);
505: }
506: }
507:
508: void
509: rs_read_potions(FILE *savef)
510: {
511: int i;
512:
513: for(i = 0; i < MAXPOTIONS; i++)
514: {
515: rs_read_string_index(savef, rainbow, cNCOLORS, &p_colors[i]);
516: rs_read_int(savef,&p_know[i]);
517: rs_read_new_string(savef,&p_guess[i]);
518: }
519: }
520:
521: void
522: rs_write_rings(FILE *savef)
523: {
524: int i;
525:
526: for(i = 0; i < MAXRINGS; i++)
527: {
528: rs_write_string_index(savef, stones, cNSTONES, r_stones[i]);
529: rs_write_int(savef,r_know[i]);
530: rs_write_string(savef,r_guess[i]);
531: }
532: }
533:
534: void
535: rs_read_rings(FILE *savef)
536: {
537: int i;
538:
539: for(i = 0; i < MAXRINGS; i++)
540: {
541: rs_read_string_index(savef, stones, cNSTONES, &r_stones[i]);
542: rs_read_int(savef,&r_know[i]);
543: rs_read_new_string(savef,&r_guess[i]);
544: }
545: }
546:
547: void
548: rs_write_sticks(FILE *savef)
549: {
550: int i;
551:
552: for (i = 0; i < MAXSTICKS; i++)
553: {
554: if (strcmp(ws_type[i],"staff") == 0)
555: {
556: rs_write_int(savef,0);
557: rs_write_string_index(savef, wood, cNWOOD, ws_made[i]);
558: }
559: else
560: {
561: rs_write_int(savef,1);
562: rs_write_string_index(savef, metal, cNMETAL, ws_made[i]);
563: }
564: rs_write_int(savef, ws_know[i]);
565: rs_write_string(savef, ws_guess[i]);
566: }
567: }
568:
569: void
570: rs_read_sticks(FILE *savef)
571: {
572: int i = 0, list = 0;
573:
574: for(i = 0; i < MAXSTICKS; i++)
575: {
576: rs_read_int(savef,&list);
577:
578: if (list == 0)
579: {
580: rs_read_string_index(savef, wood, cNWOOD, &ws_made[i]);
581: ws_type[i] = "staff";
582: }
583: else
584: {
585: rs_read_string_index(savef, metal, cNMETAL, &ws_made[i]);
586: ws_type[i] = "wand";
587: }
588: rs_read_int(savef, &ws_know[i]);
589: rs_read_new_string(savef, &ws_guess[i]);
590: }
591: }
592:
593: void
594: rs_write_daemons(FILE *savef, struct delayed_action *dlist, int cnt)
595: {
596: int i = 0;
597: int func = 0;
598:
599: rs_write_marker(savef, RSID_DAEMONS);
600: rs_write_int(savef, cnt);
601:
602: for(i = 0; i < cnt; i++)
603: {
604: if (dlist[i].d_func == rollwand)
605: func = 1;
606: else if (dlist[i].d_func == doctor)
607: func = 2;
608: else if (dlist[i].d_func == stomach)
609: func = 3;
610: else if (dlist[i].d_func == runners)
611: func = 4;
612: else if (dlist[i].d_func == swander)
613: func = 5;
614: else if (dlist[i].d_func == nohaste)
615: func = 6;
616: else if (dlist[i].d_func == unconfuse)
617: func = 7;
618: else if (dlist[i].d_func == unsee)
619: func = 8;
620: else if (dlist[i].d_func == sight)
621: func = 9;
622: else if (dlist[i].d_func == NULL)
623: func = 0;
624: else
625: func = -1;
626:
627: rs_write_int(savef, dlist[i].d_type);
628: rs_write_int(savef, func);
629: rs_write_int(savef, dlist[i].d_arg);
630: rs_write_int(savef, dlist[i].d_time);
631: }
632: }
633:
634: void
635: rs_read_daemons(FILE *savef, struct delayed_action *dlist, int cnt)
636: {
637: int i = 0;
638: int func = 0;
639: int value = 0;
640:
641: rs_read_marker(savef, RSID_DAEMONS);
642: rs_read_int(savef, &value);
643:
644: if (!encerror() && (value > cnt))
645: {
646: encseterr(EILSEQ);
647: return;
648: }
649:
650: for(i=0; i < cnt; i++)
651: {
652: func = 0;
653: rs_read_int(savef, &dlist[i].d_type);
654: rs_read_int(savef, &func);
655: rs_read_int(savef, &dlist[i].d_arg);
656: rs_read_int(savef, &dlist[i].d_time);
657:
658: if (encerror())
659: return;
660:
661: switch(func)
662: {
663: case 1: dlist[i].d_func = rollwand;
664: break;
665: case 2: dlist[i].d_func = doctor;
666: break;
667: case 3: dlist[i].d_func = stomach;
668: break;
669: case 4: dlist[i].d_func = runners;
670: break;
671: case 5: dlist[i].d_func = swander;
672: break;
673: case 6: dlist[i].d_func = nohaste;
674: break;
675: case 7: dlist[i].d_func = unconfuse;
676: break;
677: case 8: dlist[i].d_func = unsee;
678: break;
679: case 9: dlist[i].d_func = sight;
680: break;
681: default:dlist[i].d_func = NULL;
682: break;
683: }
684: if (dlist[i].d_func == NULL)
685: {
686: dlist[i].d_type = 0;
687: dlist[i].d_arg = 0;
688: dlist[i].d_time = 0;
689: }
690: }
691: }
692:
693: void
694: rs_write_room(FILE *savef, struct room *r)
695: {
696: rs_write_coord(savef, r->r_pos);
697: rs_write_coord(savef, r->r_max);
698: rs_write_coord(savef, r->r_gold);
699: rs_write_int(savef, r->r_goldval);
700: rs_write_int(savef, r->r_flags);
701: rs_write_int(savef, r->r_nexits);
702: rs_write_coord(savef, r->r_exit[0]);
703: rs_write_coord(savef, r->r_exit[1]);
704: rs_write_coord(savef, r->r_exit[2]);
705: rs_write_coord(savef, r->r_exit[3]);
706: }
707:
708: void
709: rs_read_room(FILE *savef, struct room *r)
710: {
711: rs_read_coord(savef,&r->r_pos);
712: rs_read_coord(savef,&r->r_max);
713: rs_read_coord(savef,&r->r_gold);
714: rs_read_int(savef,&r->r_goldval);
715: rs_read_int(savef,&r->r_flags);
716: rs_read_int(savef,&r->r_nexits);
717: rs_read_coord(savef,&r->r_exit[0]);
718: rs_read_coord(savef,&r->r_exit[1]);
719: rs_read_coord(savef,&r->r_exit[2]);
720: rs_read_coord(savef,&r->r_exit[3]);
721: }
722:
723: void
724: rs_write_rooms(FILE *savef, struct room r[], int cnt)
725: {
726: int n = 0;
727:
728: rs_write_int(savef, cnt);
729:
730: for(n = 0; n < cnt; n++)
731: rs_write_room(savef, &r[n]);
732: }
733:
734: void
735: rs_read_rooms(FILE *savef, struct room *r, int cnt)
736: {
737: int value = 0, n = 0;
738:
739: rs_read_int(savef,&value);
740:
741: if (!encerror() && (value > cnt))
742: encseterr(EILSEQ);
743: else
744: for(n = 0; n < value; n++)
745: rs_read_room(savef,&r[n]);
746: }
747:
748: void
749: rs_write_room_reference(FILE *savef, struct room *rp)
750: {
751: int i, room = -1;
752:
753: for (i = 0; i < MAXROOMS; i++)
754: if (&rooms[i] == rp)
755: room = i;
756:
757: rs_write_int(savef, room);
758: }
759:
760: void
761: rs_read_room_reference(FILE *savef, struct room **rp)
762: {
763: int i;
764:
765: rs_read_int(savef, &i);
766:
767: if (!encerror()) {
768: if (i >= 0 && i < MAXROOMS)
769: *rp = &rooms[i];
770: else
771: *rp = NULL;
772: }
773: }
774:
775: void
776: rs_write_object(FILE *savef, struct object *o)
777: {
778: rs_write_marker(savef, RSID_OBJECT);
779: rs_write_int(savef, o->o_type);
780: rs_write_coord(savef, o->o_pos);
781: rs_write_int(savef, o->o_launch);
782: rs_write_chars(savef, o->o_damage, sizeof(o->o_damage));
783: rs_write_chars(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
784: rs_write_int(savef, o->o_count);
785: rs_write_int(savef, o->o_which);
786: rs_write_int(savef, o->o_hplus);
787: rs_write_int(savef, o->o_dplus);
788: rs_write_int(savef, o->o_ac);
789: rs_write_int(savef, o->o_flags);
790: rs_write_int(savef, o->o_group);
791: }
792:
793: void
794: rs_read_object(FILE *savef, struct object *o)
795: {
796: rs_read_marker(savef, RSID_OBJECT);
797: rs_read_int(savef, &o->o_type);
798: rs_read_coord(savef, &o->o_pos);
799: rs_read_int(savef, &o->o_launch);
800: rs_read_chars(savef, o->o_damage, sizeof(o->o_damage));
801: rs_read_chars(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
802: rs_read_int(savef, &o->o_count);
803: rs_read_int(savef, &o->o_which);
804: rs_read_int(savef, &o->o_hplus);
805: rs_read_int(savef, &o->o_dplus);
806: rs_read_int(savef,&o->o_ac);
807: rs_read_int(savef,&o->o_flags);
808: rs_read_int(savef,&o->o_group);
809: }
810:
811: void
812: rs_write_object_list(FILE *savef, struct linked_list *l)
813: {
814: rs_write_marker(savef, RSID_OBJECTLIST);
815: rs_write_int(savef, list_size(l));
816:
817: for( ;l != NULL; l = l->l_next)
818: rs_write_object(savef, (struct object *) l->l_data);
819: }
820:
821: void
822: rs_read_object_list(FILE *savef, struct linked_list **list)
823: {
824: int i, cnt;
825: struct linked_list *l = NULL, *previous = NULL, *head = NULL;
826:
827: rs_read_marker(savef, RSID_OBJECTLIST);
828: rs_read_int(savef, &cnt);
829:
830: if (encerror())
831: return;
832:
833: for (i = 0; i < cnt; i++)
834: {
835: l = new_item(sizeof(struct object));
836:
837: memset(l->l_data,0,sizeof(struct object));
838:
839: l->l_prev = previous;
840:
841: if (previous != NULL)
842: previous->l_next = l;
843:
844: rs_read_object(savef,(struct object *) l->l_data);
845:
846: if (previous == NULL)
847: head = l;
848:
849: previous = l;
850: }
851:
852: if (l != NULL)
853: l->l_next = NULL;
854:
855: *list = head;
856: }
857:
858: void
859: rs_write_object_reference(FILE *savef, struct linked_list *list, struct object *item)
860: {
861: int i;
862:
863: i = find_list_ptr(list, item);
864:
865: rs_write_int(savef, i);
866: }
867:
868: void
869: rs_read_object_reference(FILE *savef, struct linked_list *list, struct object **item)
870: {
871: int i;
872:
873: rs_read_int(savef, &i);
874:
875: if (!encerror())
876: *item = get_list_item(list,i);
877: else
878: *item = NULL;
879: }
880:
881: int
882: find_room_coord(const struct room *rmlist, const coord *c, int n)
883: {
884: int i = 0;
885:
886: for(i = 0; i < n; i++)
887: if(&rmlist[i].r_gold == c)
888: return(i);
889:
890: return(-1);
891: }
892:
893: int
894: find_thing_coord(struct linked_list *monlist, coord *c)
895: {
896: struct linked_list *mitem;
897: struct thing *tp;
898: int i = 0;
899:
900: for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)
901: {
902: tp = THINGPTR(mitem);
903:
904: if (c == &tp->t_pos)
905: return(i);
906:
907: i++;
908: }
909:
910: return(-1);
911: }
912:
913: int
914: find_object_coord(struct linked_list *objlist, coord *c)
915: {
916: struct linked_list *oitem;
917: struct object *obj;
918: int i = 0;
919:
920: for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)
921: {
922: obj = OBJPTR(oitem);
923:
924: if (c == &obj->o_pos)
925: return(i);
926:
927: i++;
928: }
929:
930: return(-1);
931: }
932:
933: void
934: rs_write_thing(FILE *savef, struct thing *t)
935: {
936: int i = -1;
937:
938: rs_write_marker(savef, RSID_THING);
939:
940: if (t == NULL)
941: {
942: rs_write_int(savef, 0);
943: return;
944: }
945:
946: rs_write_int(savef, 1);
947: rs_write_coord(savef, t->t_pos);
948: rs_write_int(savef, t->t_turn);
949: rs_write_int(savef, t->t_type);
950: rs_write_int(savef, t->t_disguise);
951: rs_write_int(savef, t->t_oldch);
952:
953: /*
954: t_dest can be:
955: 0,0: NULL
956: 0,1: location of hero
957: 1,i: location of a thing (monster)
958: 2,i: location of an object
959: 3,i: location of gold in a room
960:
961: We need to remember what we are chasing rather than
962: the current location of what we are chasing.
963: */
964:
965: if (t->t_dest == &hero)
966: {
967: rs_write_int(savef,0);
968: rs_write_int(savef,1);
969: }
970: else if (t->t_dest != NULL)
971: {
972: i = find_thing_coord(mlist, t->t_dest);
973:
974: if (i >=0 )
975: {
976: rs_write_int(savef,1);
977: rs_write_int(savef,i);
978: }
979: else
980: {
981: i = find_object_coord(lvl_obj, t->t_dest);
982:
983: if (i >= 0)
984: {
985: rs_write_int(savef,2);
986: rs_write_int(savef,i);
987: }
988: else
989: {
990: i = find_room_coord(rooms, t->t_dest, MAXROOMS);
991:
992: if (i >= 0)
993: {
994: rs_write_int(savef,3);
995: rs_write_int(savef,i);
996: }
997: else
998: {
999: rs_write_int(savef, 0);
1000: rs_write_int(savef,1); /* chase the hero anyway */
1001: }
1002: }
1003: }
1004: }
1005: else
1006: {
1007: rs_write_int(savef,0);
1008: rs_write_int(savef,0);
1009: }
1010:
1011: rs_write_int(savef, t->t_flags);
1012: rs_write_stats(savef, &t->t_stats);
1013: rs_write_object_list(savef, t->t_pack);
1014: }
1015:
1016: void
1017: rs_read_thing(FILE *savef, struct thing *t)
1018: {
1019: int listid = 0, index = -1;
1020: struct linked_list *item;
1021:
1022: rs_read_marker(savef, RSID_THING);
1023: rs_read_int(savef, &index);
1024:
1025: if (encerror())
1026: return;
1027:
1028: if (index == 0)
1029: return;
1030:
1031: rs_read_coord(savef,&t->t_pos);
1032: rs_read_int(savef,&t->t_turn);
1033: rs_read_int(savef,&t->t_type);
1034: rs_read_int(savef,&t->t_disguise);
1035: rs_read_int(savef,&t->t_oldch);
1036:
1037: /*
1038: t_dest can be (listid,index):
1039: 0,0: NULL
1040: 0,1: location of hero
1041: 1,i: location of a thing (monster)
1042: 2,i: location of an object
1043: 3,i: location of gold in a room
1044:
1045: We need to remember what we are chasing rather than
1046: the current location of what we are chasing.
1047: */
1048:
1049: rs_read_int(savef, &listid);
1050: rs_read_int(savef, &index);
1051: t->t_reserved = -1;
1052:
1053: if (encerror())
1054: return;
1055:
1056: if (listid == 0) /* hero or NULL */
1057: {
1058: if (index == 1)
1059: t->t_dest = &hero;
1060: else
1061: t->t_dest = NULL;
1062: }
1063: else if (listid == 1) /* monster/thing */
1064: {
1065: t->t_dest = NULL;
1066: t->t_reserved = index;
1067: }
1068: else if (listid == 2) /* object */
1069: {
1070: struct object *obj;
1071:
1072: item = get_list_item(lvl_obj,index);
1073:
1074: if (item != NULL)
1075: {
1076: obj = OBJPTR(item);
1077: t->t_dest = &obj->o_pos;
1078: }
1079: }
1080: else if (listid == 3) /* gold */
1081: {
1082: t->t_dest = &rooms[index].r_gold;
1083: }
1084: else
1085: t->t_dest = NULL;
1086:
1087: rs_read_int(savef,&t->t_flags);
1088: rs_read_stats(savef,&t->t_stats);
1089: rs_read_object_list(savef,&t->t_pack);
1090: }
1091:
1092: void
1093: rs_fix_thing(struct thing *t)
1094: {
1095: struct linked_list *item;
1096: struct thing *tp;
1097:
1098: if (t->t_reserved < 0)
1099: return;
1100:
1101: item = get_list_item(mlist,t->t_reserved);
1102:
1103: if (item != NULL)
1104: {
1105: tp = THINGPTR(item);
1106: t->t_dest = &tp->t_pos;
1107: }
1108: }
1109:
1110: void
1111: rs_write_thing_list(FILE *savef, struct linked_list *l)
1112: {
1113: int cnt = 0;
1114:
1115: rs_write_marker(savef, RSID_MONSTERLIST);
1116:
1117: cnt = list_size(l);
1118:
1119: rs_write_int(savef, cnt);
1120:
1121: if (cnt < 1)
1122: return;
1123:
1124: while (l != NULL) {
1125: rs_write_thing(savef, (struct thing *)l->l_data);
1126: l = l->l_next;
1127: }
1128: }
1129:
1130: void
1131: rs_read_thing_list(FILE *savef, struct linked_list **list)
1132: {
1133: int i, cnt;
1134: struct linked_list *l = NULL, *previous = NULL, *head = NULL;
1135:
1136: rs_read_marker(savef, RSID_MONSTERLIST);
1137: rs_read_int(savef, &cnt);
1138:
1139: if (encerror())
1140: return;
1141:
1142: for (i = 0; i < cnt; i++)
1143: {
1144: l = new_item(sizeof(struct thing));
1145:
1146: l->l_prev = previous;
1147:
1148: if (previous != NULL)
1149: previous->l_next = l;
1150:
1151: rs_read_thing(savef,(struct thing *)l->l_data);
1152:
1153: if (previous == NULL)
1154: head = l;
1155:
1156: previous = l;
1157: }
1158:
1159: if (l != NULL)
1160: l->l_next = NULL;
1161:
1162: *list = head;
1163: }
1164:
1165: void
1166: rs_fix_thing_list(struct linked_list *list)
1167: {
1168: struct linked_list *item;
1169:
1170: for(item = list; item != NULL; item = item->l_next)
1171: rs_fix_thing(THINGPTR(item));
1172: }
1173:
1174: void
1175: rs_fix_magic_items(struct magic_item *mi, int cnt)
1176: {
1177: int i;
1178:
1179: for (i = 0; i < cnt; i++)
1180: if (i > 0)
1181: mi[i].mi_prob += mi[i-1].mi_prob;
1182: }
1183:
1184: void
1185: rs_fix_monsters(struct monster mons[26])
1186: {
1187: sprintf(mons['F'-'A'].m_stats.s_dmg,"%dd1",fung_hit);
1188: }
1189:
1190: void
1191: rs_write_trap(FILE *savef, struct trap *trap)
1192: {
1193: rs_write_coord(savef, trap->tr_pos);
1194: rs_write_int(savef, trap->tr_type);
1195: rs_write_int(savef, trap->tr_flags);
1196: }
1197:
1198: void
1199: rs_read_trap(FILE *savef, struct trap *trap)
1200: {
1201: rs_read_coord(savef,&trap->tr_pos);
1202: rs_read_int(savef,&trap->tr_type);
1203: rs_read_int(savef,&trap->tr_flags);
1204: }
1205:
1206: void
1207: rs_write_traps(FILE *savef, struct trap t[], int cnt)
1208: {
1209: int n = 0;
1210:
1211: rs_write_marker(savef, RSID_MONSTERS);
1212: rs_write_int(savef, cnt);
1213:
1214: for(n = 0; n < cnt; n++)
1215: rs_write_trap(savef, &t[n]);
1216: }
1217:
1218: void
1219: rs_read_traps(FILE *savef, struct trap *t, int cnt)
1220: {
1221: int value = 0, n = 0;
1222:
1223: rs_read_marker(savef, RSID_MONSTERS);
1224:
1225: rs_read_int(savef,&value);
1226:
1227: if (!encerror() && (value > cnt))
1228: encseterr(EILSEQ);
1229:
1230: for(n = 0; n < value; n++)
1231: rs_read_trap(savef,&t[n]);
1232: }
1233:
1234: int
1235: rs_save_file(FILE *savef)
1236: {
1237: encclearerr();
1238:
1239: rs_write_thing(savef, &player);
1240: rs_write_object_list(savef, lvl_obj);
1241: rs_write_thing_list(savef, mlist);
1242: rs_write_traps(savef, traps, MAXTRAPS);
1243: rs_write_rooms(savef, rooms, MAXROOMS);
1244: rs_write_room_reference(savef, oldrp);
1245: rs_write_stats(savef,&max_stats);
1246: rs_write_object_reference(savef, player.t_pack, cur_weapon);
1247: rs_write_object_reference(savef, player.t_pack, cur_armor);
1248: rs_write_object_reference(savef, player.t_pack, cur_ring[0]);
1249: rs_write_object_reference(savef, player.t_pack, cur_ring[1]);
1250: rs_write_int(savef, level);
1251: rs_write_int(savef, purse);
1252: rs_write_int(savef, mpos);
1253: rs_write_int(savef, ntraps);
1254: rs_write_int(savef, no_move);
1255: rs_write_int(savef, no_command);
1256: rs_write_int(savef, inpack);
1257: rs_write_int(savef, max_hp);
1258: rs_write_int(savef, total);
1259: rs_write_int(savef, lastscore);
1260: rs_write_int(savef, no_food);
1261: rs_write_int(savef, seed);
1262: rs_write_int(savef, count);
1263: rs_write_int(savef, dnum);
1264: rs_write_int(savef, fung_hit);
1265: rs_write_int(savef, quiet);
1266: rs_write_int(savef, max_level);
1267: rs_write_int(savef, food_left);
1268: rs_write_int(savef, group);
1269: rs_write_int(savef, hungry_state);
1270: rs_write_int(savef, take);
1271: rs_write_int(savef, runch);
1272: rs_write_scrolls(savef);
1273: rs_write_potions(savef);
1274: rs_write_rings(savef);
1275: rs_write_sticks(savef);
1276: rs_write_chars(savef,whoami,80);
1277: rs_write_chars(savef,fruit,80);
1278: rs_write_window(savef, cw);
1279: rs_write_window(savef, mw);
1280: rs_write_window(savef, stdscr);
1281: rs_write_int(savef, running);
1282: rs_write_int(savef, playing);
1283: rs_write_int(savef, wizard);
1284: rs_write_int(savef, after);
1285: rs_write_int(savef, notify);
1286: rs_write_int(savef, fight_flush);
1287: rs_write_int(savef, terse);
1288: rs_write_int(savef, door_stop);
1289: rs_write_int(savef, jump);
1290: rs_write_int(savef, slow_invent);
1291: rs_write_int(savef, firstmove);
1292: rs_write_int(savef, waswizard);
1293: rs_write_int(savef, askme);
1294: rs_write_int(savef, amulet);
1295: rs_write_int(savef, in_shell);
1296: rs_write_coord(savef, oldpos);
1297: rs_write_coord(savef, delta);
1298: rs_write_coord(savef, ch_ret); /* chase.c */
1299: rs_write_daemons(savef, &d_list[0], 20); /* daemon.c */
1300: rs_write_int(savef,between); /* daemons.c */
1301: rs_write_int(savef,num_checks); /* main.c */
1302: rs_write_chars(savef,lvl_mons,sizeof(lvl_mons)); /* monsters.c */
1303: rs_write_chars(savef,wand_mons,sizeof(wand_mons)); /* monsters.c */
1304:
1305: return( encclearerr() );
1306: }
1307:
1308: int
1309: rs_restore_file(FILE *savef)
1310: {
1311: encclearerr();
1312:
1313: rs_read_thing(savef, &player);
1314: rs_read_object_list(savef, &lvl_obj);
1315: rs_read_thing_list(savef, &mlist);
1316: rs_fix_thing(&player);
1317: rs_fix_thing_list(mlist);
1318: rs_read_traps(savef, traps, MAXTRAPS);
1319: rs_read_rooms(savef, rooms, MAXROOMS);
1320: rs_read_room_reference(savef, &oldrp);
1321: rs_read_stats(savef,&max_stats);
1322: rs_read_object_reference(savef, player.t_pack, &cur_weapon);
1323: rs_read_object_reference(savef, player.t_pack, &cur_armor);
1324: rs_read_object_reference(savef, player.t_pack, &cur_ring[0]);
1325: rs_read_object_reference(savef, player.t_pack, &cur_ring[1]);
1326: rs_fix_magic_items(things,NUMTHINGS);
1327: rs_fix_magic_items(s_magic,MAXSCROLLS);
1328: rs_fix_magic_items(p_magic,MAXPOTIONS);
1329: rs_fix_magic_items(r_magic,MAXRINGS);
1330: rs_fix_magic_items(ws_magic,MAXSTICKS);
1331: rs_read_int(savef, &level);
1332: rs_read_int(savef, &purse);
1333: rs_read_int(savef, &mpos);
1334: rs_read_int(savef, &ntraps);
1335: rs_read_int(savef, &no_move);
1336: rs_read_int(savef, &no_command);
1337: rs_read_int(savef, &inpack);
1338: rs_read_int(savef, &max_hp);
1339: rs_read_int(savef, &total);
1340: rs_read_int(savef, &lastscore);
1341: rs_read_int(savef, &no_food);
1342: rs_read_int(savef, &seed);
1343: rs_read_int(savef, &count);
1344: rs_read_int(savef, &dnum);
1345: rs_read_int(savef, &fung_hit);
1346: rs_read_int(savef, &quiet);
1347: rs_read_int(savef, &max_level);
1348: rs_read_int(savef, &food_left);
1349: rs_read_int(savef, &group);
1350: rs_read_int(savef, &hungry_state);
1351: rs_read_int(savef, &take);
1352: rs_read_int(savef, &runch);
1353: rs_read_scrolls(savef);
1354: rs_read_potions(savef);
1355: rs_read_rings(savef);
1356: rs_read_sticks(savef);
1357: rs_read_chars(savef,whoami,80);
1358: rs_read_chars(savef,fruit,80);
1359: rs_read_window(savef, cw);
1360: rs_read_window(savef, mw);
1361: rs_read_window(savef, stdscr);
1362: rs_read_int(savef, &running);
1363: rs_read_int(savef, &playing);
1364: rs_read_int(savef, &wizard);
1365: rs_read_int(savef, &after);
1366: rs_read_int(savef, ¬ify);
1367: rs_read_int(savef, &fight_flush);
1368: rs_read_int(savef, &terse);
1369: rs_read_int(savef, &door_stop);
1370: rs_read_int(savef, &jump);
1371: rs_read_int(savef, &slow_invent);
1372: rs_read_int(savef, &firstmove);
1373: rs_read_int(savef, &waswizard);
1374: rs_read_int(savef, &askme);
1375: rs_read_int(savef, &amulet);
1376: rs_read_int(savef, &in_shell);
1377: rs_read_coord(savef,&oldpos);
1378: rs_read_coord(savef,&delta);
1379: rs_read_coord(savef, &ch_ret); /* chase.c */
1380: rs_read_daemons(savef, d_list, 20); /* daemon.c */
1381: rs_read_int(savef,&between); /* daemons.c */
1382: rs_read_int(savef,&num_checks); /* main.c */
1383: rs_read_chars(savef, lvl_mons, sizeof(lvl_mons)); /* monsters.c */
1384: rs_read_chars(savef, wand_mons, sizeof(wand_mons)); /* monsters.c */
1385: rs_fix_monsters(monsters);
1386:
1387: return( encclearerr() );
1388: }
CVSweb