comparison arogue5/state.c @ 63:0ed67132cf10

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