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