Annotation of early-roguelike/rogue4/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 Nicholas J. Kisseberth
5:
6: Redistribution and use in source and binary forms, with or without
7: modification, are permitted provided that the following conditions
8: are met:
9: 1. Redistributions of source code must retain the above copyright
10: notice, this list of conditions and the following disclaimer.
11: 2. Redistributions in binary form must reproduce the above copyright
12: notice, this list of conditions and the following disclaimer in the
13: documentation and/or other materials provided with the distribution.
14: 3. Neither the name(s) of the author(s) nor the names of other contributors
15: may be used to endorse or promote products derived from this software
16: without specific prior written permission.
17:
18: THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
19: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21: ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
22: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28: SUCH DAMAGE.
29: */
30:
31: /************************************************************************/
32: /* Save State Code */
33: /************************************************************************/
34:
35: #define RSID_STATS 0xABCD0001
36: #define RSID_THING 0xABCD0002
37: #define RSID_THING_NULL 0xDEAD0002
38: #define RSID_OBJECT 0xABCD0003
39: #define RSID_MAGICITEMS 0xABCD0004
40: #define RSID_KNOWS 0xABCD0005
41: #define RSID_GUESSES 0xABCD0006
42: #define RSID_OBJECTLIST 0xABCD0007
43: #define RSID_BAGOBJECT 0xABCD0008
44: #define RSID_MONSTERLIST 0xABCD0009
45: #define RSID_MONSTERSTATS 0xABCD000A
46: #define RSID_MONSTERS 0xABCD000B
47: #define RSID_TRAP 0xABCD000C
48: #define RSID_WINDOW 0xABCD000D
49: #define RSID_DAEMONS 0xABCD000E
50: #define RSID_IWEAPS 0xABCD000F
51: #define RSID_IARMOR 0xABCD0010
52: #define RSID_SPELLS 0xABCD0011
53: #define RSID_ILIST 0xABCD0012
54: #define RSID_HLIST 0xABCD0013
55: #define RSID_DEATHTYPE 0xABCD0014
56: #define RSID_CTYPES 0XABCD0015
57: #define RSID_COORDLIST 0XABCD0016
58: #define RSID_ROOMS 0XABCD0017
59:
60:
61:
62: #include <curses.h>
63: #include <sys/stat.h>
64: #include <stdio.h>
65: #include <stdlib.h>
66: #include <assert.h>
67: #include <string.h>
68: #include "rogue.h"
69:
70: #define READSTAT ((format_error == 0) && (read_error == 0))
71: #define WRITESTAT (write_error == 0)
72:
73: int rs_write_int(FILE *savef, int c);
74: int rs_read_int(FILE *inf, int *i);
75:
76: int read_error = FALSE;
77: int write_error = FALSE;
78: int format_error = FALSE;
79: int end_of_file = FALSE;
80: int big_endian = 0;
81:
82: void *
83: get_list_item(THING *l, int i)
84: {
85: int count = 0;
86:
87: while(l != NULL)
88: {
89: if (count == i)
90: return(l);
91:
92: l = l->l_next;
93:
94: count++;
95: }
96:
97: return(NULL);
98: }
99:
100: int
101: find_list_ptr(THING *l, void *ptr)
102: {
103: int count = 0;
104:
105: while(l != NULL)
106: {
107: if (l == ptr)
108: return(count);
109:
110: l = l->l_next;
111: count++;
112: }
113:
114: return(-1);
115: }
116:
117: int
118: list_size(THING *l)
119: {
120: int count = 0;
121:
122: while(l != NULL)
123: {
124: if (l == NULL)
125: return(count);
126:
127: count++;
128:
129: l = l->l_next;
130: }
131:
132: return(count);
133: }
134:
135: int
136: rs_write(FILE *savef, void *ptr, int size)
137: {
138: if (!write_error)
139: encwrite(ptr,size,savef);
140:
141: if (0)
142: write_error = TRUE;
143:
144: assert(write_error == 0);
145:
146: return(WRITESTAT);
147: }
148:
149: int
150: rs_write_char(FILE *savef, char c)
151: {
152: rs_write(savef, &c, 1);
153:
154: return(WRITESTAT);
155: }
156:
157: int
158: rs_write_boolean(FILE *savef, bool c)
159: {
160: unsigned char buf = (c == 0) ? 0 : 1;
161:
162: rs_write(savef, &buf, 1);
163:
164: return(WRITESTAT);
165: }
166:
167: int
168: rs_write_booleans(FILE *savef, bool *c, int count)
169: {
170: int n = 0;
171:
172: rs_write_int(savef,count);
173:
174: for(n = 0; n < count; n++)
175: rs_write_boolean(savef,c[n]);
176:
177: return(WRITESTAT);
178: }
179:
180: int
181: rs_write_shint(FILE *savef, shint c)
182: {
183: unsigned char buf = c;
184:
185: rs_write(savef, &buf, 1);
186:
187: return(WRITESTAT);
188: }
189:
190: int
191: rs_write_short(FILE *savef, short c)
192: {
193: unsigned char bytes[2];
194: unsigned char *buf = (unsigned char *) &c;
195:
196: if (big_endian)
197: {
198: bytes[1] = buf[0];
199: bytes[0] = buf[1];
200: buf = bytes;
201: }
202:
203: rs_write(savef, buf, 2);
204:
205: return(WRITESTAT);
206: }
207:
208: int
209: rs_write_shorts(FILE *savef, short *c, int count)
210: {
211: int n = 0;
212:
213: rs_write_int(savef,count);
214:
215: for(n = 0; n < count; n++)
216: rs_write_short(savef,c[n]);
217:
218: return(WRITESTAT);
219: }
220:
221: int
222: rs_write_ushort(FILE *savef, unsigned short c)
223: {
224: unsigned char bytes[2];
225: unsigned char *buf = (unsigned char *) &c;
226:
227: if (big_endian)
228: {
229: bytes[1] = buf[0];
230: bytes[0] = buf[1];
231: buf = bytes;
232: }
233:
234: rs_write(savef, buf, 2);
235:
236: return(WRITESTAT);
237: }
238:
239: int
240: rs_write_int(FILE *savef, int c)
241: {
242: unsigned char bytes[4];
243: unsigned char *buf = (unsigned char *) &c;
244:
245: if (big_endian)
246: {
247: bytes[3] = buf[0];
248: bytes[2] = buf[1];
249: bytes[1] = buf[2];
250: bytes[0] = buf[3];
251: buf = bytes;
252: }
253:
254: rs_write(savef, buf, 4);
255:
256: return(WRITESTAT);
257: }
258:
259: int
260: rs_write_ints(FILE *savef, int *c, int count)
261: {
262: int n = 0;
263:
264: rs_write_int(savef,count);
265:
266: for(n = 0; n < count; n++)
267: rs_write_int(savef,c[n]);
268:
269: return(WRITESTAT);
270: }
271:
272: int
273: rs_write_uint(FILE *savef, unsigned int c)
274: {
275: unsigned char bytes[4];
276: unsigned char *buf = (unsigned char *) &c;
277:
278: if (big_endian)
279: {
280: bytes[3] = buf[0];
281: bytes[2] = buf[1];
282: bytes[1] = buf[2];
283: bytes[0] = buf[3];
284: buf = bytes;
285: }
286:
287: rs_write(savef, buf, 4);
288:
289: return(WRITESTAT);
290: }
291:
292: int
293: rs_write_long(FILE *savef, long c)
294: {
295: int c2;
296: unsigned char bytes[4];
297: unsigned char *buf = (unsigned char *)&c;
298:
299: if (sizeof(long) == 8)
300: {
301: c2 = c;
302: buf = (unsigned char *) &c2;
303: }
304:
305: if (big_endian)
306: {
307: bytes[3] = buf[0];
308: bytes[2] = buf[1];
309: bytes[1] = buf[2];
310: bytes[0] = buf[3];
311: buf = bytes;
312: }
313:
314: rs_write(savef, buf, 4);
315:
316: return(WRITESTAT);
317: }
318:
319: int
320: rs_write_longs(FILE *savef, long *c, int count)
321: {
322: int n = 0;
323:
324: rs_write_int(savef,count);
325:
326: for(n = 0; n < count; n++)
327: rs_write_long(savef,c[n]);
328:
329: return(WRITESTAT);
330: }
331:
332: int
333: rs_write_ulong(FILE *savef, unsigned long c)
334: {
335: unsigned int c2;
336: unsigned char bytes[4];
337: unsigned char *buf = (unsigned char *)&c;
338:
339: if ( (sizeof(long) == 8) && (sizeof(int) == 4) )
340: {
341: c2 = c;
342: buf = (unsigned char *) &c2;
343: }
344:
345: if (big_endian)
346: {
347: bytes[3] = buf[0];
348: bytes[2] = buf[1];
349: bytes[1] = buf[2];
350: bytes[0] = buf[3];
351: buf = bytes;
352: }
353:
354: rs_write(savef, buf, 4);
355:
356: return(WRITESTAT);
357: }
358:
359: int
360: rs_write_ulongs(FILE *savef, unsigned long *c, int count)
361: {
362: int n = 0;
363:
364: rs_write_int(savef,count);
365:
366: for(n = 0; n < count; n++)
367: rs_write_ulong(savef,c[n]);
368:
369: return(WRITESTAT);
370: }
371:
372: int
373: rs_write_string(FILE *savef, char *s)
374: {
375: int len = 0;
376:
377: len = (s == NULL) ? 0 : strlen(s) + 1;
378:
379: rs_write_int(savef, len);
380: rs_write(savef, s, len);
381:
382: return(WRITESTAT);
383: }
384:
385: int
386: rs_write_string_index(FILE *savef, const char *master[], int max,
387: const char *str)
388: {
389: int i;
390:
391: for(i = 0; i < max; i++)
392: {
393: if (str == master[i])
394: {
395: rs_write_int(savef,i);
396: return(WRITESTAT);
397: }
398: }
399:
400: rs_write_int(savef,-1);
401:
402: return(WRITESTAT);
403: }
404:
405: int
406: rs_write_strings(FILE *savef, char *s[], int count)
407: {
408: int len = 0;
409: int n = 0;
410:
411: rs_write_int(savef,count);
412:
413: for(n = 0; n < count; n++)
414: {
415: len = (s[n] == NULL) ? 0L : strlen(s[n]) + 1;
416: rs_write_int(savef, len);
417: rs_write(savef, s[n], len);
418: }
419:
420: return(WRITESTAT);
421: }
422:
423: int
424: rs_read(FILE *inf, void *ptr, int size)
425: {
426: int actual;
427:
428: end_of_file = FALSE;
429:
430: if (!read_error && !format_error)
431: {
432: actual = encread(ptr, size, inf);
433:
434: if ((actual == 0) && (size != 0))
435: end_of_file = TRUE;
436: }
437:
438: if (read_error)
439: {
440: printf("read error has occurred. restore short-circuited.\n");
441: abort();
442: }
443:
444: if (format_error)
445: {
446: printf("game format invalid. restore short-circuited.\n");
447: abort();
448: }
449:
450: return(READSTAT);
451: }
452:
453: int
454: rs_read_char(FILE *inf, char *c)
455: {
456: rs_read(inf, c, 1);
457:
458: return(READSTAT);
459: }
460: int
461: rs_read_uchar(FILE *inf, unsigned char *c)
462: {
463: rs_read(inf, c, 1);
464:
465: return(READSTAT);
466: }
467:
468: int
469: rs_read_boolean(FILE *inf, bool *i)
470: {
471: unsigned char buf;
472:
473: rs_read(inf, &buf, 1);
474:
475: *i = (bool) buf;
476:
477: return(READSTAT);
478: }
479:
480: int
481: rs_read_booleans(FILE *inf, bool *i, int count)
482: {
483: int n = 0, value = 0;
484:
485: if (rs_read_int(inf,&value) != 0)
486: {
487: if (value != count)
488: {
489: printf("Invalid booleans block. %d != requested %d\n",value,count);
490: format_error = TRUE;
491: }
492: else
493: {
494: for(n = 0; n < value; n++)
495: rs_read_boolean(inf, &i[n]);
496: }
497: }
498:
499: return(READSTAT);
500: }
501:
502: int
503: rs_read_shint(FILE *inf, shint *i)
504: {
505: unsigned char buf;
506:
507: rs_read(inf, &buf, 1);
508:
509: *i = (shint) buf;
510:
511: return(READSTAT);
512: }
513:
514: int
515: rs_read_short(FILE *inf, short *i)
516: {
517: unsigned char bytes[2];
518: short input;
519: unsigned char *buf = (unsigned char *)&input;
520:
521: rs_read(inf, &input, 2);
522:
523: if (big_endian)
524: {
525: bytes[1] = buf[0];
526: bytes[0] = buf[1];
527: buf = bytes;
528: }
529:
530: *i = *((short *) buf);
531:
532: return(READSTAT);
533: }
534:
535: int
536: rs_read_shorts(FILE *inf, short *i, int count)
537: {
538: int n = 0, value = 0;
539:
540: if (rs_read_int(inf,&value) != 0)
541: {
542: if (value != count)
543: format_error = TRUE;
544: else
545: {
546: for(n = 0; n < value; n++)
547: rs_read_short(inf, &i[n]);
548: }
549: }
550:
551: return(READSTAT);
552: }
553:
554: int
555: rs_read_ushort(FILE *inf, unsigned short *i)
556: {
557: unsigned char bytes[2];
558: unsigned short input;
559: unsigned char *buf = (unsigned char *)&input;
560:
561: rs_read(inf, &input, 2);
562:
563: if (big_endian)
564: {
565: bytes[1] = buf[0];
566: bytes[0] = buf[1];
567: buf = bytes;
568: }
569:
570: *i = *((unsigned short *) buf);
571:
572: return(READSTAT);
573: }
574:
575: int
576: rs_read_int(FILE *inf, int *i)
577: {
578: unsigned char bytes[4];
579: int input;
580: unsigned char *buf = (unsigned char *)&input;
581:
582: rs_read(inf, &input, 4);
583:
584: if (big_endian)
585: {
586: bytes[3] = buf[0];
587: bytes[2] = buf[1];
588: bytes[1] = buf[2];
589: bytes[0] = buf[3];
590: buf = bytes;
591: }
592:
593: *i = *((int *) buf);
594:
595: return(READSTAT);
596: }
597:
598: int
599: rs_read_ints(FILE *inf, int *i, int count)
600: {
601: int n = 0, value = 0;
602:
603: if (rs_read_int(inf,&value) != 0)
604: {
605: if (value != count)
606: format_error = TRUE;
607: else
608: {
609: for(n = 0; n < value; n++)
610: rs_read_int(inf, &i[n]);
611: }
612: }
613:
614: return(READSTAT);
615: }
616:
617: int
618: rs_read_uint(FILE *inf, unsigned int *i)
619: {
620: unsigned char bytes[4];
621: int input;
622: unsigned char *buf = (unsigned char *)&input;
623:
624: rs_read(inf, &input, 4);
625:
626: if (big_endian)
627: {
628: bytes[3] = buf[0];
629: bytes[2] = buf[1];
630: bytes[1] = buf[2];
631: bytes[0] = buf[3];
632: buf = bytes;
633: }
634:
635: *i = *((unsigned int *) buf);
636:
637: return(READSTAT);
638: }
639:
640: int
641: rs_read_long(FILE *inf, long *i)
642: {
643: unsigned char bytes[4];
644: long input;
645: unsigned char *buf = (unsigned char *) &input;
646:
647: rs_read(inf, &input, 4);
648:
649: if (big_endian)
650: {
651: bytes[3] = buf[0];
652: bytes[2] = buf[1];
653: bytes[1] = buf[2];
654: bytes[0] = buf[3];
655: buf = bytes;
656: }
657:
658: *i = *((long *) buf);
659:
660: return(READSTAT);
661: }
662:
663: int
664: rs_read_longs(FILE *inf, long *i, int count)
665: {
666: int n = 0, value = 0;
667:
668: if (rs_read_int(inf,&value) != 0)
669: {
670: if (value != count)
671: format_error = TRUE;
672: else
673: {
674: for(n = 0; n < value; n++)
675: rs_read_long(inf, &i[n]);
676: }
677: }
678:
679: return(READSTAT);
680: }
681:
682: int
683: rs_read_ulong(FILE *inf, unsigned long *i)
684: {
685: unsigned char bytes[4];
686: unsigned long input;
687: unsigned char *buf = (unsigned char *) &input;
688:
689: rs_read(inf, &input, 4);
690:
691: if (big_endian)
692: {
693: bytes[3] = buf[0];
694: bytes[2] = buf[1];
695: bytes[1] = buf[2];
696: bytes[0] = buf[3];
697: buf = bytes;
698: }
699:
700: *i = *((unsigned long *) buf);
701:
702: return(READSTAT);
703: }
704:
705: int
706: rs_read_ulongs(FILE *inf, unsigned long *i, int count)
707: {
708: int n = 0, value = 0;
709:
710: if (rs_read_int(inf,&value) != 0)
711: {
712: if (value != count)
713: format_error = TRUE;
714: else
715: {
716: for(n = 0; n < value; n++)
717: rs_read_ulong(inf, &i[n]);
718: }
719: }
720:
721: return(READSTAT);
722: }
723:
724: int
725: rs_read_string(FILE *inf, char *s, int max)
726: {
727: int len = 0;
728:
729: if (rs_read_int(inf, &len) != FALSE)
730: {
731: if (len > max)
732: {
733: printf("String too long to restore. %d > %d\n",len,max);
734: printf("Sorry, invalid save game format\n");
735: format_error = TRUE;
736: }
737:
738: rs_read(inf, s, len);
739: }
740:
741: return(READSTAT);
742: }
743:
744: int
745: rs_read_new_string(FILE *inf, char **s)
746: {
747: int len=0;
748: char *buf=0;
749:
750: if (rs_read_int(inf, &len) != 0)
751: {
752: if (len == 0)
753: *s = NULL;
754: else
755: {
756: buf = malloc(len);
757:
758: if (buf == NULL)
759: read_error = TRUE;
760: else
761: {
762: rs_read(inf, buf, len);
763: *s = buf;
764: }
765: }
766: }
767:
768: return(READSTAT);
769: }
770:
771: int
772: rs_read_string_index(FILE *inf, const char *master[], int maxindex,
773: const char **str)
774: {
775: int i;
776:
777: if (rs_read_int(inf,&i) != 0)
778: {
779: if (i > maxindex)
780: {
781: printf("String index is out of range. %d > %d\n", i, maxindex);
782: printf("Sorry, invalid save game format\n");
783: format_error = TRUE;
784: }
785: else if (i >= 0)
786: *str = master[i];
787: else
788: *str = NULL;
789: }
790:
791: return(READSTAT);
792: }
793:
794: int
795: rs_read_strings(FILE *inf, char **s, int count, int max)
796: {
797: int n = 0;
798: int value = 0;
799:
800: if (rs_read_int(inf,&value) != 0)
801: {
802: if (value != count)
803: {
804: printf("Incorrect number of strings in block. %d > %d.",
805: value, count);
806: printf("Sorry, invalid save game format");
807: format_error = TRUE;
808: }
809: else
810: {
811: for(n = 0; n < value; n++)
812: {
813: rs_read_string(inf, s[n], max);
814: }
815: }
816: }
817:
818: return(READSTAT);
819: }
820:
821: int
822: rs_read_new_strings(FILE *inf, char **s, int count)
823: {
824: int len = 0;
825: int n = 0;
826: int value = 0;
827:
828: if (rs_read_int(inf,&value) != 0)
829: {
830: if (value != count)
831: {
832: printf("Incorrect number of new strings in block. %d > %d.",
833: value,count);abort();
834: printf("Sorry, invalid save game format");
835: format_error = TRUE;
836: }
837: else
838: for(n=0; n<value; n++)
839: {
840: rs_read_int(inf, &len);
841:
842: if (len == 0)
843: s[n]=0;
844: else
845: {
846: s[n] = malloc(len);
847: rs_read(inf,s[n],len);
848: }
849: }
850: }
851:
852: return(READSTAT);
853: }
854:
855: /******************************************************************************/
856:
857: int
858: rs_write_str_t(FILE *savef, str_t st)
859: {
860: rs_write_uint(savef,st);
861:
862: return(WRITESTAT);
863: }
864:
865: int
866: rs_read_str_t(FILE *inf, str_t *st)
867: {
868: rs_read_uint(inf,st);
869:
870: return(READSTAT);
871: }
872:
873: int
874: rs_write_coord(FILE *savef, coord c)
875: {
876: rs_write_shint(savef, c.x);
877: rs_write_shint(savef, c.y);
878:
879: return(WRITESTAT);
880: }
881:
882: int
883: rs_read_coord(FILE *inf, coord *c)
884: {
885: rs_read_shint(inf,&c->x);
886: rs_read_shint(inf,&c->y);
887:
888: return(READSTAT);
889: }
890:
891: int
892: rs_write_window(FILE *savef, WINDOW *win)
893: {
894: int row,col,height,width;
895: width = getmaxx(win);
896: height = getmaxy(win);
897:
898: rs_write_int(savef,RSID_WINDOW);
899: rs_write_int(savef,height);
900: rs_write_int(savef,width);
901:
902: for(row=0;row<height;row++)
903: for(col=0;col<width;col++)
904: rs_write_int(savef, mvwinch(win,row,col));
905:
906: return(WRITESTAT);
907: }
908:
909: int
910: rs_read_window(FILE *inf, WINDOW *win)
911: {
912: int id,row,col,maxlines,maxcols,value,width,height;
913:
914: width = getmaxx(win);
915: height = getmaxy(win);
916:
917: if (rs_read_int(inf, &id) != 0)
918: {
919: if (id != RSID_WINDOW)
920: {
921: printf("Invalid head id. %x != %x(RSID_WINDOW)\n", id, RSID_WINDOW);
922: printf("Sorry, invalid save game format");
923: format_error = TRUE;
924: }
925: else
926: {
927: rs_read_int(inf,&maxlines);
928: rs_read_int(inf,&maxcols);
929: if (maxlines > height)
930: abort();
931: if (maxcols > width)
932: abort();
933:
934: for(row=0;row<maxlines;row++)
935: for(col=0;col<maxcols;col++)
936: {
937: rs_read_int(inf, &value);
938: mvwaddch(win,row,col,value);
939: }
940: }
941: }
942:
943: return(READSTAT);
944: }
945:
946: int
947: rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)
948: {
949: int i = 0;
950: int func = 0;
951:
952: rs_write_int(savef, RSID_DAEMONS);
953: rs_write_int(savef, count);
954:
955: for(i = 0; i < count; i++)
956: {
957: if (d_list[i].d_func == rollwand)
958: func = 1;
959: else if (d_list[i].d_func == doctor)
960: func = 2;
961: else if (d_list[i].d_func == stomach)
962: func = 3;
963: else if (d_list[i].d_func == runners)
964: func = 4;
965: else if (d_list[i].d_func == swander)
966: func = 5;
967: else if (d_list[i].d_func == nohaste)
968: func = 6;
969: else if (d_list[i].d_func == unconfuse)
970: func = 7;
971: else if (d_list[i].d_func == unsee)
972: func = 8;
973: else if (d_list[i].d_func == sight)
974: func = 9;
975: else if (d_list[i].d_func == turn_see_off)
976: func = 10;
977: else
978: func = 0;
979:
980: rs_write_int(savef, d_list[i].d_type);
981: rs_write_int(savef, func);
982: rs_write_int(savef, d_list[i].d_arg);
983: rs_write_int(savef, d_list[i].d_time);
984: }
985:
986: return(WRITESTAT);
987: }
988:
989: int
990: rs_read_daemons(FILE *inf, struct delayed_action *d_list, int count)
991: {
992: int i = 0;
993: int func = 0;
994: int value = 0;
995: int id = 0;
996:
997: if (d_list == NULL)
998: printf("HELP THERE ARE NO DAEMONS\n");
999:
1000: if (rs_read_int(inf, &id) != 0)
1001: {
1002: if (id != RSID_DAEMONS)
1003: {
1004: printf("Invalid id. %x != %x(RSID_DAEMONS)\n", id, RSID_DAEMONS);
1005: printf("Sorry, invalid save game format");
1006: format_error = TRUE;
1007: }
1008: else if (rs_read_int(inf, &value) != 0)
1009: {
1010: if (value > count)
1011: {
1012: printf("Incorrect number of daemons in block. %d > %d.",
1013: value, count);
1014: printf("Sorry, invalid save game format");
1015: format_error = TRUE;
1016: }
1017: else
1018: {
1019: for(i=0; i < value; i++)
1020: {
1021: func = 0;
1022: rs_read_int(inf, &d_list[i].d_type);
1023: rs_read_int(inf, &func);
1024: rs_read_int(inf, &d_list[i].d_arg);
1025: rs_read_int(inf, &d_list[i].d_time);
1026:
1027: switch(func)
1028: {
1029: case 1: d_list[i].d_func = rollwand;
1030: break;
1031: case 2: d_list[i].d_func = doctor;
1032: break;
1033: case 3: d_list[i].d_func = stomach;
1034: break;
1035: case 4: d_list[i].d_func = runners;
1036: break;
1037: case 5: d_list[i].d_func = swander;
1038: break;
1039: case 6: d_list[i].d_func = nohaste;
1040: break;
1041: case 7: d_list[i].d_func = unconfuse;
1042: break;
1043: case 8: d_list[i].d_func = unsee;
1044: break;
1045: case 9: d_list[i].d_func = sight;
1046: break;
1047: case 10: d_list[i].d_func = turn_see_off;
1048: break;
1049: default:d_list[i].d_func = NULL;
1050: break;
1051: }
1052:
1053: if (d_list[i].d_func == NULL)
1054: {
1055: d_list[i].d_type = 0;
1056: d_list[i].d_arg = 0;
1057: d_list[i].d_time = 0;
1058: }
1059: }
1060: }
1061: }
1062: }
1063:
1064: return(READSTAT);
1065: }
1066:
1067: int
1068: rs_write_magic_items(FILE *savef, struct magic_item *i, int count)
1069: {
1070: int n;
1071:
1072: rs_write_int(savef, RSID_MAGICITEMS);
1073: rs_write_int(savef, count);
1074:
1075: for(n = 0; n < count; n++)
1076: {
1077: /* mi_name is constant, defined at compile time in all cases */
1078: rs_write_shint(savef,i[n].mi_prob);
1079: rs_write_short(savef,i[n].mi_worth);
1080: }
1081:
1082: return(WRITESTAT);
1083: }
1084:
1085: int
1086: rs_read_magic_items(FILE *inf, struct magic_item *mi, int count)
1087: {
1088: int id;
1089: int n;
1090: int value;
1091:
1092: if (rs_read_int(inf, &id) != 0)
1093: {
1094: if (id != RSID_MAGICITEMS)
1095: {
1096: printf("Invalid id. %x != %x(RSID_MAGICITEMS)\n",
1097: id, RSID_MAGICITEMS);
1098: printf("Sorry, invalid save game format");
1099: format_error = TRUE;
1100: }
1101: else if (rs_read_int(inf, &value) != 0)
1102: {
1103: if (value > count)
1104: {
1105: printf("Incorrect number of magic items in block. %d > %d.",
1106: value, count);
1107: printf("Sorry, invalid save game format");
1108: format_error = TRUE;
1109: }
1110: else
1111: {
1112: for(n = 0; n < value; n++)
1113: {
1114: /* mi_name is constant, defined at compile time in all cases */
1115: rs_read_shint(inf,&mi[n].mi_prob);
1116: rs_read_short(inf,&mi[n].mi_worth);
1117: }
1118: }
1119: }
1120: }
1121:
1122: return(READSTAT);
1123: }
1124:
1125: int
1126: rs_write_room(FILE *savef, struct room *r)
1127: {
1128: rs_write_coord(savef, r->r_pos);
1129: rs_write_coord(savef, r->r_max);
1130: rs_write_coord(savef, r->r_gold);
1131: rs_write_int(savef, r->r_goldval);
1132: rs_write_short(savef, r->r_flags);
1133: rs_write_shint(savef, r->r_nexits);
1134: rs_write_coord(savef, r->r_exit[0]);
1135: rs_write_coord(savef, r->r_exit[1]);
1136: rs_write_coord(savef, r->r_exit[2]);
1137: rs_write_coord(savef, r->r_exit[3]);
1138: rs_write_coord(savef, r->r_exit[4]);
1139: rs_write_coord(savef, r->r_exit[5]);
1140: rs_write_coord(savef, r->r_exit[6]);
1141: rs_write_coord(savef, r->r_exit[7]);
1142: rs_write_coord(savef, r->r_exit[8]);
1143: rs_write_coord(savef, r->r_exit[9]);
1144: rs_write_coord(savef, r->r_exit[10]);
1145: rs_write_coord(savef, r->r_exit[11]);
1146:
1147: return(WRITESTAT);
1148: }
1149:
1150: int
1151: rs_write_rooms(FILE *savef, struct room r[], int count)
1152: {
1153: int n = 0;
1154:
1155: rs_write_int(savef, count);
1156:
1157: for(n=0; n<count; n++)
1158: rs_write_room(savef, &r[n]);
1159:
1160: return(WRITESTAT);
1161: }
1162:
1163: int
1164: rs_read_room(FILE *inf, struct room *r)
1165: {
1166: rs_read_coord(inf,&r->r_pos);
1167: rs_read_coord(inf,&r->r_max);
1168: rs_read_coord(inf,&r->r_gold);
1169: rs_read_int(inf,&r->r_goldval);
1170: rs_read_short(inf,&r->r_flags);
1171: rs_read_shint(inf,&r->r_nexits);
1172: rs_read_coord(inf,&r->r_exit[0]);
1173: rs_read_coord(inf,&r->r_exit[1]);
1174: rs_read_coord(inf,&r->r_exit[2]);
1175: rs_read_coord(inf,&r->r_exit[3]);
1176: rs_read_coord(inf,&r->r_exit[4]);
1177: rs_read_coord(inf,&r->r_exit[5]);
1178: rs_read_coord(inf,&r->r_exit[6]);
1179: rs_read_coord(inf,&r->r_exit[7]);
1180: rs_read_coord(inf,&r->r_exit[8]);
1181: rs_read_coord(inf,&r->r_exit[9]);
1182: rs_read_coord(inf,&r->r_exit[10]);
1183: rs_read_coord(inf,&r->r_exit[11]);
1184:
1185: return(READSTAT);
1186: }
1187:
1188: int
1189: rs_read_rooms(FILE *inf, struct room *r, int count)
1190: {
1191: int value = 0, n = 0;
1192:
1193: if (rs_read_int(inf,&value) != 0)
1194: {
1195: if (value > count)
1196: {
1197: printf("Incorrect number of rooms in block. %d > %d.",
1198: value,count);
1199: printf("Sorry, invalid save game format");
1200: format_error = TRUE;
1201: }
1202: else
1203: for(n = 0; n < value; n++)
1204: rs_read_room(inf,&r[n]);
1205: }
1206:
1207: return(READSTAT);
1208: }
1209:
1210: int
1211: rs_write_room_reference(FILE *savef, struct room *rp)
1212: {
1213: int i, room = -1;
1214:
1215: for (i = 0; i < MAXROOMS; i++)
1216: if (&rooms[i] == rp)
1217: room = i;
1218:
1219: rs_write_int(savef, room);
1220:
1221: return(WRITESTAT);
1222: }
1223:
1224: int
1225: rs_read_room_reference(FILE *inf, struct room **rp)
1226: {
1227: int i;
1228:
1229: rs_read_int(inf, &i);
1230:
1231: if (i >= 0 && i < MAXROOMS)
1232: *rp = &rooms[i];
1233: else
1234: *rp = NULL;
1235:
1236: return(READSTAT);
1237: }
1238:
1239: int
1240: rs_write_stats(FILE *savef, struct stats *s)
1241: {
1242: rs_write_int(savef, RSID_STATS);
1243: rs_write_str_t(savef, s->s_str);
1244: rs_write_long(savef, s->s_exp);
1245: rs_write_shint(savef, s->s_lvl);
1246: rs_write_shint(savef, s->s_arm);
1247: rs_write_short(savef, s->s_hpt);
1248: rs_write(savef, s->s_dmg, sizeof(s->s_dmg));
1249: rs_write_shint(savef,s->s_maxhp);
1250:
1251: return(WRITESTAT);
1252: }
1253:
1254: int
1255: rs_read_stats(FILE *inf, struct stats *s)
1256: {
1257: int id;
1258:
1259: rs_read_int(inf, &id);
1260:
1261: rs_read_str_t(inf,&s->s_str);
1262: rs_read_long(inf,&s->s_exp);
1263: rs_read_shint(inf,&s->s_lvl);
1264: rs_read_shint(inf,&s->s_arm);
1265: rs_read_short(inf,&s->s_hpt);
1266: rs_read(inf,s->s_dmg,sizeof(s->s_dmg));
1267: rs_read_shint(inf,&s->s_maxhp);
1268:
1269: return(READSTAT);
1270: }
1271:
1272: int
1273: rs_write_object(FILE *savef, THING *o)
1274: {
1275: rs_write_int(savef, RSID_OBJECT);
1276: rs_write_shint(savef, o->_o._o_type);
1277: rs_write_coord(savef, o->_o._o_pos);
1278: rs_write_char(savef, o->_o._o_launch);
1279: rs_write(savef, o->_o._o_damage, sizeof(o->_o._o_damage));
1280: rs_write(savef, o->_o._o_hurldmg, sizeof(o->_o._o_hurldmg));
1281: rs_write_shint(savef, o->_o._o_count);
1282: rs_write_shint(savef, o->_o._o_which);
1283: rs_write_shint(savef, o->_o._o_hplus);
1284: rs_write_shint(savef, o->_o._o_dplus);
1285: rs_write_short(savef, o->_o._o_ac);
1286: rs_write_short(savef, o->_o._o_flags);
1287: rs_write_shint(savef, o->_o._o_group);
1288:
1289: return(WRITESTAT);
1290: }
1291:
1292: int
1293: rs_read_object(FILE *inf, THING *o)
1294: {
1295: int id;
1296:
1297: if (rs_read_int(inf, &id) != 0)
1298: {
1299: if (id != RSID_OBJECT)
1300: {
1301: printf("Invalid id. %x != %x(RSID_OBJECT)\n",
1302: id,RSID_OBJECT);
1303: printf("Sorry, invalid save game format");
1304: format_error = TRUE;
1305: }
1306: else
1307: {
1308: rs_read_shint(inf, &o->_o._o_type);
1309: rs_read_coord(inf, &o->_o._o_pos);
1310: rs_read_char(inf, &o->_o._o_launch);
1311: rs_read(inf, &o->_o._o_damage, sizeof(o->_o._o_damage));
1312: rs_read(inf, &o->_o._o_hurldmg, sizeof(o->_o._o_hurldmg));
1313: rs_read_shint(inf, &o->_o._o_count);
1314: rs_read_shint(inf, &o->_o._o_which);
1315: rs_read_shint(inf, &o->_o._o_hplus);
1316: rs_read_shint(inf, &o->_o._o_dplus);
1317: rs_read_short(inf, &o->_o._o_ac);
1318: rs_read_short(inf, &o->_o._o_flags);
1319: rs_read_shint(inf, &o->_o._o_group);
1320: }
1321: }
1322:
1323: return(READSTAT);
1324: }
1325:
1326: int
1327: rs_write_object_list(FILE *savef, THING *l)
1328: {
1329: rs_write_int(savef, RSID_OBJECTLIST);
1330: rs_write_int(savef, list_size(l));
1331:
1332: while (l != NULL)
1333: {
1334: rs_write_object(savef, l);
1335: l = l->l_next;
1336: }
1337:
1338: return(WRITESTAT);
1339: }
1340:
1341: int
1342: rs_read_object_list(FILE *inf, THING **list)
1343: {
1344: int id;
1345: int i, cnt;
1346: THING *l = NULL, *previous = NULL, *head = NULL;
1347:
1348: if (rs_read_int(inf,&id) != 0)
1349: {
1350: if (rs_read_int(inf,&cnt) != 0)
1351: {
1352: for (i = 0; i < cnt; i++)
1353: {
1354: l = new_item();
1355: memset(l,0,sizeof(THING));
1356: l->l_prev = previous;
1357: if (previous != NULL)
1358: previous->l_next = l;
1359: rs_read_object(inf,l);
1360: if (previous == NULL)
1361: head = l;
1362: previous = l;
1363: }
1364:
1365: if (l != NULL)
1366: l->l_next = NULL;
1367:
1368: *list = head;
1369: }
1370: else
1371: format_error = TRUE;
1372: }
1373: else
1374: format_error = TRUE;
1375:
1376:
1377: return(READSTAT);
1378: }
1379:
1380: int
1381: rs_write_object_reference(FILE *savef, THING *list, THING *item)
1382: {
1383: int i;
1384:
1385: i = find_list_ptr(list, item);
1386:
1387: rs_write_int(savef, i);
1388:
1389: return(WRITESTAT);
1390: }
1391:
1392: int
1393: rs_read_object_reference(FILE *inf, THING *list, THING **item)
1394: {
1395: int i;
1396:
1397: rs_read_int(inf, &i);
1398:
1399: *item = get_list_item(list,i);
1400:
1401: return(READSTAT);
1402: }
1403:
1404: int
1405: find_thing_coord(THING *monlist, coord *c)
1406: {
1407: THING *mitem;
1408: THING *tp;
1409: int i = 0;
1410:
1411: for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)
1412: {
1413: tp = mitem;
1414:
1415: if (c == &tp->t_pos)
1416: return(i);
1417:
1418: i++;
1419: }
1420:
1421: return(-1);
1422: }
1423:
1424: int
1425: find_room_coord(struct room *rmlist, coord *c, int n)
1426: {
1427: int i = 0;
1428:
1429: for(i = 0; i < n; i++)
1430: if(&rmlist[i].r_gold == c)
1431: return(i);
1432:
1433: return(-1);
1434: }
1435:
1436: int
1437: find_object_coord(THING *objlist, coord *c)
1438: {
1439: THING *oitem;
1440: THING *obj;
1441: int i = 0;
1442:
1443: for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)
1444: {
1445: obj = oitem;
1446:
1447: if (c == &obj->o_pos)
1448: return(i);
1449:
1450: i++;
1451: }
1452:
1453: return(-1);
1454: }
1455:
1456: int
1457: rs_write_thing(FILE *savef, THING *t)
1458: {
1459: int i = -1;
1460:
1461: if (t == NULL)
1462: {
1463: rs_write_int(savef, RSID_THING_NULL);
1464: return(WRITESTAT);
1465: }
1466:
1467: rs_write_int(savef, RSID_THING);
1468:
1469: rs_write_coord(savef, t->_t._t_pos);
1470: rs_write_boolean(savef, t->_t._t_turn);
1471: rs_write_char(savef, t->_t._t_type);
1472: rs_write_char(savef, t->_t._t_disguise);
1473: rs_write_char(savef, t->_t._t_oldch);
1474:
1475: /*
1476: t_dest can be:
1477: 0,0: NULL
1478: 0,1: location of hero
1479: 1,i: location of a thing (monster)
1480: 2,i: location of an object
1481: 3,i: location of gold in a room
1482:
1483: We need to remember what we are chasing rather than
1484: the current location of what we are chasing.
1485: */
1486:
1487: if (t->t_dest == &hero)
1488: {
1489: rs_write_int(savef,0);
1490: rs_write_int(savef,1);
1491: }
1492: else if (t->t_dest != NULL)
1493: {
1494: i = find_thing_coord(mlist, t->t_dest);
1495:
1496: if (i >=0 )
1497: {
1498: rs_write_int(savef,1);
1499: rs_write_int(savef,i);
1500: }
1501: else
1502: {
1503: i = find_object_coord(lvl_obj, t->t_dest);
1504:
1505: if (i >= 0)
1506: {
1507: rs_write_int(savef,2);
1508: rs_write_int(savef,i);
1509: }
1510: else
1511: {
1512: i = find_room_coord(rooms, t->t_dest, MAXROOMS);
1513:
1514: if (i >= 0)
1515: {
1516: rs_write_int(savef,3);
1517: rs_write_int(savef,i);
1518: }
1519: else
1520: {
1521: rs_write_int(savef, 0);
1522: rs_write_int(savef,1); /* chase the hero anyway */
1523: }
1524: }
1525: }
1526: }
1527: else
1528: {
1529: rs_write_int(savef,0);
1530: rs_write_int(savef,0);
1531: }
1532:
1533: rs_write_short(savef, t->_t._t_flags);
1534: rs_write_stats(savef, &t->_t._t_stats);
1535: rs_write_room_reference(savef, t->_t._t_room);
1536: rs_write_object_list(savef, t->_t._t_pack);
1537:
1538: return(WRITESTAT);
1539: }
1540:
1541: void
1542: rs_fix_thing(THING *t)
1543: {
1544: THING *item;
1545: THING *tp;
1546:
1547: if (t->t_reserved < 0)
1548: return;
1549:
1550: item = get_list_item(mlist,t->t_reserved);
1551:
1552: if (item != NULL)
1553: {
1554: tp = item;
1555: t->t_dest = &tp->t_pos;
1556: }
1557: }
1558:
1559: void
1560: rs_fix_thing_list(THING *list)
1561: {
1562: THING *item;
1563:
1564: for(item = list; item != NULL; item = item->l_next)
1565: rs_fix_thing(item);
1566: }
1567:
1568: int
1569: rs_read_thing(FILE *inf, THING *t)
1570: {
1571: int id;
1572: int listid = 0, index = -1;
1573: THING *item;
1574:
1575: if (rs_read_int(inf, &id) != 0)
1576: {
1577: if (id != RSID_THING)
1578: format_error = TRUE;
1579: else
1580: {
1581: rs_read_coord(inf,&t->_t._t_pos);
1582: rs_read_boolean(inf,&t->_t._t_turn);
1583: rs_read_uchar(inf,&t->_t._t_type);
1584: rs_read_char(inf,&t->_t._t_disguise);
1585: rs_read_char(inf,&t->_t._t_oldch);
1586:
1587: /*
1588: t_dest can be (listid,index):
1589: 0,0: NULL
1590: 0,1: location of hero
1591: 1,i: location of a thing (monster)
1592: 2,i: location of an object
1593: 3,i: location of gold in a room
1594:
1595: We need to remember what we are chasing rather than
1596: the current location of what we are chasing.
1597: */
1598:
1599: rs_read_int(inf, &listid);
1600: rs_read_int(inf, &index);
1601: t->_t._t_reserved = -1;
1602:
1603: if (listid == 0) /* hero or NULL */
1604: {
1605: if (index == 1)
1606: t->_t._t_dest = &hero;
1607: else
1608: t->_t._t_dest = NULL;
1609: }
1610: else if (listid == 1) /* monster/thing */
1611: {
1612: t->_t._t_dest = NULL;
1613: t->_t._t_reserved = index;
1614: }
1615: else if (listid == 2) /* object */
1616: {
1617: THING *obj;
1618:
1619: item = get_list_item(lvl_obj, index);
1620:
1621: if (item != NULL)
1622: {
1623: obj = item;
1624: t->_t._t_dest = &obj->o_pos;
1625: }
1626: }
1627: else if (listid == 3) /* gold */
1628: {
1629: t->_t._t_dest = &rooms[index].r_gold;
1630: }
1631: else
1632: t->_t._t_dest = NULL;
1633:
1634: rs_read_short(inf,&t->_t._t_flags);
1635: rs_read_stats(inf,&t->_t._t_stats);
1636: rs_read_room_reference(inf, &t->_t._t_room);
1637: rs_read_object_list(inf,&t->_t._t_pack);
1638: }
1639: }
1640: else
1641: format_error = TRUE;
1642:
1643: return(READSTAT);
1644: }
1645:
1646: int
1647: rs_write_thing_list(FILE *savef, THING *l)
1648: {
1649: int cnt = 0;
1650:
1651: rs_write_int(savef, RSID_MONSTERLIST);
1652:
1653: cnt = list_size(l);
1654:
1655: rs_write_int(savef, cnt);
1656:
1657: if (cnt < 1)
1658: return(WRITESTAT);
1659:
1660: while (l != NULL) {
1661: rs_write_thing(savef, l);
1662: l = l->l_next;
1663: }
1664:
1665: return(WRITESTAT);
1666: }
1667:
1668: int
1669: rs_read_thing_list(FILE *inf, THING **list)
1670: {
1671: int id;
1672: int i, cnt;
1673: THING *l = NULL, *previous = NULL, *head = NULL;
1674:
1675: if (rs_read_int(inf,&id) != 0)
1676: {
1677: if (id != RSID_MONSTERLIST)
1678: {
1679: printf("Invalid id. %x != %x(RSID_MONSTERLIST)\n",
1680: id,RSID_MONSTERLIST);
1681: printf("Sorry, invalid save game format");
1682: format_error = TRUE;
1683: }
1684: else if (rs_read_int(inf,&cnt) != 0)
1685: {
1686: for (i = 0; i < cnt; i++)
1687: {
1688: l = new_item();
1689: l->l_prev = previous;
1690: if (previous != NULL)
1691: previous->l_next = l;
1692: rs_read_thing(inf,l);
1693: if (previous == NULL)
1694: head = l;
1695: previous = l;
1696: }
1697:
1698:
1699: if (l != NULL)
1700: l->l_next = NULL;
1701:
1702: *list = head;
1703: }
1704: }
1705: else
1706: format_error = TRUE;
1707:
1708: return(READSTAT);
1709: }
1710:
1711: int
1712: rs_write_monsters(FILE *savef, struct monster *m, int count)
1713: {
1714: int n;
1715:
1716: rs_write_int(savef, RSID_MONSTERS);
1717: rs_write_int(savef, count);
1718:
1719: for(n=0;n<count;n++)
1720: {
1721: /*
1722: rs_write(savef, m[n].m_name, sizeof(m[n].m_name));
1723: rs_write_char(savef, m[n].m_carry);
1724: rs_write_short(savef, m[n].m_flags);
1725: */
1726: rs_write_stats(savef, &m[n].m_stats);
1727: }
1728:
1729: return(WRITESTAT);
1730: }
1731:
1732: int
1733: rs_read_monsters(FILE *inf, struct monster *m, int count)
1734: {
1735: int id = 0, value = 0, n = 0;
1736:
1737: if (rs_read_int(inf, &id) != 0)
1738: {
1739: if (id != RSID_MONSTERS)
1740: {
1741: printf("Invalid id. %x != %x(RSID_MONSTERS)\n",
1742: id,RSID_MONSTERS);
1743: printf("Sorry, invalid save game format");
1744: format_error = TRUE;
1745: }
1746: else if (rs_read_int(inf, &value) != 0)
1747: {
1748: for(n=0;n<value;n++)
1749: {
1750: /*
1751: rs_read(inf,m[n].m_name,sizeof(m[n].m_name));
1752: rs_read_char(inf, &m[n].m_carry);
1753: rs_read_short(inf, &m[n].m_flags);
1754: */
1755: rs_read_stats(inf, &m[n].m_stats);
1756: }
1757: }
1758: else
1759: format_error = TRUE;
1760: }
1761:
1762: return(READSTAT);
1763: }
1764:
1765: int
1766: rs_write_scrolls(FILE *savef)
1767: {
1768: int i;
1769:
1770: for(i = 0; i < MAXSCROLLS; i++)
1771: {
1772: rs_write_string(savef,s_names[i]);
1773: rs_write_boolean(savef,s_know[i]);
1774: rs_write_string(savef,s_guess[i]);
1775: }
1776:
1777: return(WRITESTAT);
1778: }
1779:
1780: int
1781: rs_read_scrolls(FILE *inf)
1782: {
1783: int i;
1784:
1785: for(i = 0; i < MAXSCROLLS; i++)
1786: {
1787: rs_read_new_string(inf,&s_names[i]);
1788: rs_read_boolean(inf,&s_know[i]);
1789: rs_read_new_string(inf,&s_guess[i]);
1790: }
1791:
1792: return(READSTAT);
1793: }
1794:
1795: int
1796: rs_write_potions(FILE *savef)
1797: {
1798: int i;
1799:
1800: for(i = 0; i < MAXPOTIONS; i++)
1801: {
1802: rs_write_string_index(savef,rainbow,NCOLORS,p_colors[i]);
1803: rs_write_boolean(savef,p_know[i]);
1804: rs_write_string(savef,p_guess[i]);
1805: }
1806:
1807: return(WRITESTAT);
1808: }
1809:
1810: int
1811: rs_read_potions(FILE *inf)
1812: {
1813: int i;
1814:
1815: for(i = 0; i < MAXPOTIONS; i++)
1816: {
1817: rs_read_string_index(inf,rainbow,NCOLORS,&p_colors[i]);
1818: rs_read_boolean(inf,&p_know[i]);
1819: rs_read_new_string(inf,&p_guess[i]);
1820: }
1821:
1822: return(READSTAT);
1823: }
1824:
1825:
1826: int
1827: rs_write_rings(FILE *savef)
1828: {
1829: int i;
1830: const char *stones_list[NSTONES];
1831:
1832: for(i = 0; i < NSTONES; i++)
1833: stones_list[i] = stones[i].st_name;
1834:
1835: for(i = 0; i < MAXRINGS; i++)
1836: {
1837: rs_write_string_index(savef,stones_list,NSTONES,r_stones[i]);
1838: rs_write_boolean(savef,r_know[i]);
1839: rs_write_string(savef,r_guess[i]);
1840: }
1841:
1842: return(WRITESTAT);
1843: }
1844:
1845: int
1846: rs_read_rings(FILE *inf)
1847: {
1848: int i;
1849: const char *stones_list[NSTONES];
1850:
1851: for(i = 0; i < NSTONES; i++)
1852: stones_list[i] = stones[i].st_name;
1853:
1854: for(i = 0; i < MAXRINGS; i++)
1855: {
1856: rs_read_string_index(inf,stones_list,NSTONES,&r_stones[i]);
1857: rs_read_boolean(inf,&r_know[i]);
1858: rs_read_new_string(inf,&r_guess[i]);
1859: }
1860:
1861: return(READSTAT);
1862: }
1863:
1864: int
1865: rs_write_sticks(FILE *savef)
1866: {
1867: int i;
1868:
1869: for (i = 0; i < MAXSTICKS; i++)
1870: {
1871: if (strcmp(ws_type[i],"staff") == 0)
1872: {
1873: rs_write_int(savef,0);
1874: rs_write_string_index(savef, wood, NWOOD, ws_made[i]);
1875: }
1876: else
1877: {
1878: rs_write_int(savef,1);
1879: rs_write_string_index(savef, metal, NMETAL, ws_made[i]);
1880: }
1881: rs_write_boolean(savef, ws_know[i]);
1882: rs_write_string(savef, ws_guess[i]);
1883: }
1884:
1885: return(WRITESTAT);
1886: }
1887:
1888: int
1889: rs_read_sticks(FILE *inf)
1890: {
1891: int i = 0, list = 0;
1892:
1893: for(i = 0; i < MAXSTICKS; i++)
1894: {
1895: rs_read_int(inf,&list);
1896: if (list == 0)
1897: {
1898: rs_read_string_index(inf,wood,NWOOD,&ws_made[i]);
1899: ws_type[i] = "staff";
1900: }
1901: else
1902: {
1903: rs_read_string_index(inf,metal,NMETAL,&ws_made[i]);
1904: ws_type[i] = "wand";
1905: }
1906: rs_read_boolean(inf, &ws_know[i]);
1907: rs_read_new_string(inf, &ws_guess[i]);
1908: }
1909:
1910: return(READSTAT);
1911: }
1912:
1913: /******************************************************************************/
1914: int
1915: rs_write_thing_reference(FILE *savef, THING *list, THING *item)
1916: {
1917: int i;
1918:
1919: if (item == NULL)
1920: rs_write_int(savef,-1);
1921: else
1922: {
1923: i = find_list_ptr(list, item);
1924:
1925: assert(i >= 0);
1926:
1927: rs_write_int(savef, i);
1928: }
1929:
1930: return(WRITESTAT);
1931: }
1932:
1933: int
1934: rs_read_thing_reference(FILE *inf, THING *list, THING **item)
1935: {
1936: int i;
1937:
1938: rs_read_int(inf, &i);
1939:
1940: if (i == -1)
1941: *item = NULL;
1942: else
1943: {
1944: *item = get_list_item(list,i);
1945:
1946: assert(item != NULL);
1947: }
1948:
1949: return(READSTAT);
1950: }
1951:
1952: int
1953: rs_write_thing_references(FILE *savef, THING *list, THING *items[], int count)
1954: {
1955: int i;
1956:
1957: for(i = 0; i < count; i++)
1958: rs_write_thing_reference(savef,list,items[i]);
1959:
1960: return(WRITESTAT);
1961: }
1962:
1963: int
1964: rs_read_thing_references(FILE *inf, THING *list, THING *items[], int count)
1965: {
1966: int i;
1967:
1968: for(i = 0; i < count; i++)
1969: rs_read_thing_reference(inf,list,&items[i]);
1970:
1971: return(WRITESTAT);
1972: }
1973:
1974: int
1975: rs_save_file(FILE *savef)
1976: {
1977: int endian = 0x01020304;
1978: big_endian = ( *((char *)&endian) == 0x01 );
1979:
1980: rs_write_boolean(savef, after);
1981: rs_write_boolean(savef, noscore);
1982: rs_write_boolean(savef, amulet);
1983: rs_write_boolean(savef, askme);
1984: rs_write_boolean(savef, door_stop);
1985: rs_write_boolean(savef, fight_flush);
1986: rs_write_boolean(savef, firstmove);
1987: rs_write_boolean(savef, in_shell);
1988: rs_write_boolean(savef, jump);
1989: rs_write_boolean(savef, passgo);
1990: rs_write_boolean(savef, playing);
1991: rs_write_boolean(savef, running);
1992: rs_write_boolean(savef, save_msg);
1993: rs_write_boolean(savef, slow_invent);
1994: rs_write_boolean(savef, terse);
1995: #ifdef WIZARD
1996: rs_write_boolean(savef, wizard);
1997: #else
1998: rs_write_boolean(savef, 0);
1999: #endif
2000: rs_write_char(savef, take);
2001: rs_write(savef, prbuf, MAXSTR);
2002: rs_write_char(savef, runch);
2003:
2004: rs_write_scrolls(savef);
2005: rs_write_potions(savef);
2006: rs_write_rings(savef);
2007: rs_write_sticks(savef);
2008:
2009: rs_write_string(savef, release);
2010: rs_write(savef, whoami, MAXSTR);
2011: rs_write(savef, fruit, MAXSTR);
2012:
2013: rs_write(savef, _level, MAXLINES*MAXCOLS);
2014: rs_write(savef, _flags, MAXLINES*MAXCOLS);
2015:
2016: rs_write_int(savef, max_level);
2017: rs_write_int(savef, ntraps);
2018: rs_write_int(savef, dnum);
2019: rs_write_int(savef, level);
2020: rs_write_int(savef, purse);
2021: rs_write_int(savef, no_move);
2022: rs_write_int(savef, no_command);
2023: rs_write_int(savef, inpack);
2024: rs_write_int(savef, lastscore);
2025: rs_write_int(savef, no_food);
2026: rs_write_int(savef, count);
2027: rs_write_int(savef, fung_hit);
2028: rs_write_int(savef, quiet);
2029: rs_write_int(savef, food_left);
2030: rs_write_int(savef, group);
2031: rs_write_int(savef, hungry_state);
2032:
2033: /* rs_write_ints(savef, a_chances, MAXARMORS); *//* constant */
2034: /* rs_write_ints(savef, a_class, MAXARMORS); *//* constant */
2035:
2036: rs_write_long(savef, seed);
2037: rs_write_coord(savef, oldpos);
2038: rs_write_coord(savef, delta);
2039:
2040: rs_write_thing(savef, &player);
2041: rs_write_object_reference(savef, player.t_pack, cur_armor);
2042: rs_write_object_reference(savef, player.t_pack, cur_weapon);
2043: rs_write_object_reference(savef, player.t_pack, cur_ring[0]);
2044: rs_write_object_reference(savef, player.t_pack, cur_ring[1]);
2045:
2046: rs_write_object_list(savef, lvl_obj);
2047: rs_write_thing_list(savef, mlist);
2048: rs_write_thing_references(savef, mlist, _monst, MAXLINES*MAXCOLS);
2049:
2050: rs_write_window(savef, stdscr);
2051: rs_write_stats(savef,&max_stats);
2052:
2053: rs_write_rooms(savef, rooms, MAXROOMS);
2054: rs_write_room_reference(savef, oldrp);
2055: rs_write_rooms(savef, passages, MAXPASS);
2056:
2057: rs_write_monsters(savef,monsters,26);
2058: rs_write_magic_items(savef, things, NUMTHINGS);
2059: rs_write_magic_items(savef, s_magic, MAXSCROLLS);
2060: rs_write_magic_items(savef, p_magic, MAXPOTIONS);
2061: rs_write_magic_items(savef, r_magic, MAXRINGS);
2062: rs_write_magic_items(savef, ws_magic, MAXSTICKS);
2063:
2064: rs_write_coord(savef, ch_ret); /* 5.2-chase.c */
2065: rs_write_char(savef,countch); /* 5.2-command.c*/
2066: rs_write_char(savef,direction); /* 5.2-command.c*/
2067: rs_write_char(savef,newcount); /* 5.2-command.c*/
2068: rs_write_daemons(savef, &d_list[0], 20); /* 5.2-daemon.c */
2069: rs_write_int(savef,between); /* 5.2-daemons.c*/
2070: rs_write(savef,lvl_mons,sizeof(lvl_mons)); /* 5.2-monsters.c*/
2071: rs_write(savef,wand_mons,sizeof(wand_mons)); /* 5.2-monsters.c*/
2072: rs_write_coord(savef, nh); /* 5.2-move.c */
2073: rs_write_boolean(savef, got_genocide); /* 5.2-things.c */
2074:
2075: return(WRITESTAT);
2076: }
2077:
2078: int
2079: rs_restore_file(FILE *inf)
2080: {
2081: bool junk;
2082: THING *mitem;
2083: int endian = 0x01020304;
2084: big_endian = ( *((char *)&endian) == 0x01 );
2085:
2086: rs_read_boolean(inf, &after);
2087: rs_read_boolean(inf, &noscore);
2088: rs_read_boolean(inf, &amulet);
2089: rs_read_boolean(inf, &askme);
2090: rs_read_boolean(inf, &door_stop);
2091: rs_read_boolean(inf, &fight_flush);
2092: rs_read_boolean(inf, &firstmove);
2093: rs_read_boolean(inf, &in_shell);
2094: rs_read_boolean(inf, &jump);
2095: rs_read_boolean(inf, &passgo);
2096: rs_read_boolean(inf, &playing);
2097: rs_read_boolean(inf, &running);
2098: rs_read_boolean(inf, &save_msg);
2099: rs_read_boolean(inf, &slow_invent);
2100: rs_read_boolean(inf, &terse);
2101: #ifdef WIZARD
2102: rs_read_boolean(inf, &wizard);
2103: #else
2104: rs_read_boolean(inf, &junk);
2105: #endif
2106: rs_read_char(inf, &take);
2107: rs_read(inf, prbuf, MAXSTR);
2108: rs_read_char(inf, &runch);
2109:
2110: rs_read_scrolls(inf);
2111: rs_read_potions(inf);
2112: rs_read_rings(inf);
2113: rs_read_sticks(inf);
2114:
2115: rs_read_new_string(inf, &release);
2116: rs_read(inf, whoami, MAXSTR);
2117: rs_read(inf, fruit, MAXSTR);
2118:
2119: rs_read(inf, _level, MAXLINES*MAXCOLS);
2120: rs_read(inf, _flags, MAXLINES*MAXCOLS);
2121:
2122: rs_read_int(inf, &max_level);
2123: rs_read_int(inf, &ntraps);
2124: rs_read_int(inf, &dnum);
2125: rs_read_int(inf, &level);
2126: rs_read_int(inf, &purse);
2127: rs_read_int(inf, &no_move);
2128: rs_read_int(inf, &no_command);
2129: rs_read_int(inf, &inpack);
2130: rs_read_int(inf, &lastscore);
2131: rs_read_int(inf, &no_food);
2132: rs_read_int(inf, &count);
2133: rs_read_int(inf, &fung_hit);
2134: rs_read_int(inf, &quiet);
2135: rs_read_int(inf, &food_left);
2136: rs_read_int(inf, &group);
2137: rs_read_int(inf, &hungry_state);
2138:
2139: rs_read_long(inf, &seed);
2140: rs_read_coord(inf, &oldpos);
2141: rs_read_coord(inf, &delta);
2142:
2143: rs_read_thing(inf, &player);
2144: rs_read_object_reference(inf, player.t_pack, &cur_armor);
2145: rs_read_object_reference(inf, player.t_pack, &cur_weapon);
2146: rs_read_object_reference(inf, player.t_pack, &cur_ring[0]);
2147: rs_read_object_reference(inf, player.t_pack, &cur_ring[1]);
2148:
2149: rs_read_object_list(inf, &lvl_obj);
2150: rs_read_thing_list(inf, &mlist);
2151: rs_fix_thing(&player);
2152: rs_fix_thing_list(mlist);
2153: rs_read_thing_references(inf,mlist,_monst,MAXLINES*MAXCOLS);
2154:
2155: rs_read_window(inf, stdscr);
2156: rs_read_stats(inf, &max_stats);
2157:
2158: rs_read_rooms(inf, rooms, MAXROOMS);
2159: rs_read_room_reference(inf, &oldrp);
2160: rs_read_rooms(inf, passages, MAXPASS);
2161:
2162: rs_read_monsters(inf,monsters,26);
2163: rs_read_magic_items(inf, things, NUMTHINGS);
2164: rs_read_magic_items(inf, s_magic, MAXSCROLLS);
2165: rs_read_magic_items(inf, p_magic, MAXPOTIONS);
2166: rs_read_magic_items(inf, r_magic, MAXRINGS);
2167: rs_read_magic_items(inf, ws_magic, MAXSTICKS);
2168:
2169: rs_read_coord(inf, &ch_ret); /* 5.2-chase.c */
2170: rs_read_char(inf,&countch); /* 5.2-command.c */
2171: rs_read_char(inf,&direction); /* 5.2-command.c */
2172: rs_read_char(inf,&newcount); /* 5.2-command.c */
2173: rs_read_daemons(inf, d_list, 20); /* 5.2-daemon.c */
2174: rs_read_int(inf,&between); /* 5.2-daemons.c */
2175: rs_read(inf, lvl_mons, sizeof(lvl_mons)); /* 5.2-monsters.c */
2176: rs_read(inf, wand_mons, sizeof(wand_mons)); /* 5.2-monsters.c */
2177: rs_read_coord(inf, &nh); /* 5.2-move.c */
2178: rs_read_boolean(inf, &got_genocide); /* 5.2-things.c */
2179:
2180: if (proom == NULL)
2181: proom = roomin(&hero);
2182: for (mitem = mlist; mitem != NULL; mitem = mitem->l_next) {
2183: if (mitem->t_room == NULL)
2184: mitem->t_room = roomin(&(mitem->t_pos));
2185: }
2186:
2187: return(READSTAT);
2188: }
CVSweb