comparison rogue4/state.c @ 12:9535a08ddc39

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