comparison xrogue/state.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children cfa9d1609b78
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 state.c - Portable Rogue Save State Code
3
4 Copyright (C) 2000 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 #define RSXR_STATS 0xABCD0001
32 #define RSXR_THING 0xABCD0002
33 #define RSXR_OBJECT 0xABCD0003
34 #define RSXR_MAGICITEMS 0xABCD0004
35 #define RSXR_KNOWS 0xABCD0005
36 #define RSXR_GUESSES 0xABCD0006
37 #define RSXR_OBJECTLIST 0xABCD0007
38 #define RSXR_BAGOBJECT 0xABCD0008
39 #define RSXR_MONSTERLIST 0xABCD0009
40 #define RSXR_MONSTERSTATS 0xABCD000A
41 #define RSXR_MONSTERS 0xABCD000B
42 #define RSXR_TRAP 0xABCD000C
43 #define RSXR_WINDOW 0xABCD000D
44 #define RSXR_DAEMONS 0xABCD000E
45 #define RSXR_IWEAPS 0xABCD000F
46 #define RSXR_IARMOR 0xABCD0010
47 #define RSXR_SPELLS 0xABCD0011
48 #define RSXR_ILIST 0xABCD0012
49 #define RSXR_HLIST 0xABCD0013
50 #define RSXR_DEATHTYPE 0xABCD0014
51 #define RSXR_CTYPES 0XABCD0015
52 #define RSXR_COORDLIST 0XABCD0016
53 #define RSXR_ROOMS 0XABCD0017
54
55 #if defined(_WIN32)
56 #include <Windows.h>
57 #include <Lmcons.h>
58 #include <process.h>
59 #include <shlobj.h>
60 #include <Shlwapi.h>
61 #undef VOID
62 #undef MOUSE_MOVED
63 #elif defined(__DJGPP__)
64 #include <process.h>
65 #else
66 #include <pwd.h>
67 #include <sys/utsname.h>
68 #include <unistd.h>
69 #endif
70
71 #include <stdlib.h>
72 #include <curses.h>
73 #include <sys/stat.h>
74 #include <stdio.h>
75 #include <stdarg.h>
76 #include <assert.h>
77 #include <fcntl.h>
78 #include <limits.h>
79 #include <time.h>
80 #include <signal.h>
81 #include "rogue.h"
82 #include "mach_dep.h"
83
84
85 #define READSTAT ((format_error == 0) && (read_error == 0))
86 #define WRITESTAT (write_error == 0)
87
88 int read_error = FALSE;
89 int write_error = FALSE;
90 int format_error = FALSE;
91
92 int save_debug = FALSE;
93 #define DBG(x) {if (save_debug) rsPrintf x;}
94
95 int
96 rsPrintf(char *fmt, ...)
97 {
98 va_list ap;
99
100 va_start(ap, fmt);
101 vfprintf(stderr,fmt, ap);
102 va_end(ap);
103
104 return(0);
105 }
106
107
108 void *
109 get_list_item(struct linked_list *l, int i)
110 {
111 int count = 0;
112
113 while(l != NULL)
114 {
115 if (count == i)
116 return(l->l_data);
117
118 l = l->l_next;
119
120 count++;
121 }
122
123 return(NULL);
124 }
125
126 rs_write(FILE *savef, void *ptr, size_t size)
127 {
128 size_t i = 0;
129
130 if (!write_error)
131 i = ENCWRITE(ptr,size,savef);
132 if (i != size)
133 write_error = TRUE;
134
135 assert(write_error == 0);
136 return(WRITESTAT);
137 }
138
139 int end_of_file = FALSE;
140
141 rs_read(int inf, void *ptr, size_t size)
142 {
143 int actual;
144 end_of_file =FALSE;
145 if (!read_error && !format_error)
146 {
147 actual = ENCREAD(ptr, size, inf);
148
149 if ((actual == 0) && (size != 0))
150 end_of_file = TRUE;
151 }
152
153 if (read_error){
154 printf("read error has occurred. restore short-circuited.\n");abort();}
155 if (format_error)
156 {printf("game format invalid. restore short-circuited.\n");abort();}
157
158 return(READSTAT);
159 }
160
161 int big_endian = 0;
162
163 rs_write_uint(FILE *savef, unsigned int c)
164 {
165 char bytes[4];
166 char *buf = (char *) &c;
167
168 if (big_endian)
169 {
170 bytes[3] = buf[0];
171 bytes[2] = buf[1];
172 bytes[1] = buf[2];
173 bytes[0] = buf[3];
174 buf = bytes;
175 }
176
177 rs_write(savef, buf, 4);
178
179 return(WRITESTAT);
180 }
181
182 rs_write_int(FILE *savef, int c)
183 {
184 char bytes[4];
185 char *buf = (char *) &c;
186
187 if (big_endian)
188 {
189 bytes[3] = buf[0];
190 bytes[2] = buf[1];
191 bytes[1] = buf[2];
192 bytes[0] = buf[3];
193 buf = bytes;
194 }
195
196 rs_write(savef, buf, 4);
197
198 return(WRITESTAT);
199 }
200
201 rs_write_ulong(FILE *savef, unsigned long c)
202 {
203 char bytes[4];
204 char *buf = (char *)&c;
205
206 if (big_endian)
207 {
208 bytes[3] = buf[0];
209 bytes[2] = buf[1];
210 bytes[1] = buf[2];
211 bytes[0] = buf[3];
212 buf = bytes;
213 }
214
215 rs_write(savef, buf, 4);
216
217 return(WRITESTAT);
218 }
219
220 rs_write_long(FILE *savef, long c)
221 {
222 char bytes[4];
223 char *buf = (char *)&c;
224
225 if (big_endian)
226 {
227 bytes[3] = buf[0];
228 bytes[2] = buf[1];
229 bytes[1] = buf[2];
230 bytes[0] = buf[3];
231 buf = bytes;
232 }
233
234 rs_write(savef, buf, 4);
235
236 return(WRITESTAT);
237 }
238
239 rs_write_boolean(FILE *savef, bool c)
240 {
241 char buf;
242
243 if (c == 0)
244 buf = 0;
245 else
246 buf = 1;
247
248 rs_write(savef, &buf, 1);
249
250 return(WRITESTAT);
251 }
252
253 rs_read_int(int inf, int *i)
254 {
255 char bytes[4];
256 int input;
257 char *buf = (char *)&input;
258
259 rs_read(inf, &input, 4);
260
261 if (big_endian)
262 {
263 bytes[3] = buf[0];
264 bytes[2] = buf[1];
265 bytes[1] = buf[2];
266 bytes[0] = buf[3];
267 buf = bytes;
268 }
269
270 *i = *((int *) buf);
271
272 return(READSTAT);
273 }
274
275 rs_read_uint(int inf, unsigned int *i)
276 {
277 char bytes[4];
278 int input;
279 char *buf = (char *)&input;
280
281 rs_read(inf, &input, 4);
282
283 if (big_endian)
284 {
285 bytes[3] = buf[0];
286 bytes[2] = buf[1];
287 bytes[1] = buf[2];
288 bytes[0] = buf[3];
289 buf = bytes;
290 }
291
292 *i = *((int *) buf);
293
294 return(READSTAT);
295 }
296
297 rs_read_ulong(int inf, unsigned long *i)
298 {
299 char bytes[4];
300 unsigned long input;
301 char *buf = (char *) &input;
302
303 rs_read(inf, &input, 4);
304
305 if (big_endian)
306 {
307 bytes[3] = buf[0];
308 bytes[2] = buf[1];
309 bytes[1] = buf[2];
310 bytes[0] = buf[3];
311 buf = bytes;
312 }
313
314 *i = *((unsigned long *) buf);
315 return(READSTAT);
316 }
317
318 rs_read_long(int inf, long *i)
319 {
320 char bytes[4];
321 long input;
322 char *buf = (char *) &input;
323
324 rs_read(inf, &input, 4);
325
326 if (big_endian)
327 {
328 bytes[3] = buf[0];
329 bytes[2] = buf[1];
330 bytes[1] = buf[2];
331 bytes[0] = buf[3];
332 buf = bytes;
333 }
334
335 *i = *((long *) buf);
336 return(READSTAT);
337 }
338
339 rs_read_boolean(int inf, bool *i)
340 {
341 char buf;
342
343 rs_read(inf, &buf, 1);
344
345 *i = buf;
346
347 return(READSTAT);
348 }
349
350 rs_write_ints(FILE *savef, int *c, int count)
351 {
352 int n=0;
353
354 rs_write_int(savef,count);
355
356 for(n=0;n<count;n++)
357 rs_write_int(savef,c[n]);
358
359 return(WRITESTAT);
360 }
361
362 rs_write_short(FILE *savef, short c)
363 {
364 char bytes[2];
365 char *buf = (char *) &c;
366
367 if (big_endian)
368 {
369 bytes[1] = buf[0];
370 bytes[0] = buf[1];
371 buf = bytes;
372 }
373
374 rs_write(savef, buf, 2);
375
376 return(WRITESTAT);
377 }
378
379 rs_read_short(int inf, short *s)
380 {
381 char bytes[2];
382 short input;
383 char *buf = (char *)&input;
384
385 rs_read(inf, &input, 2);
386
387 if (big_endian)
388 {
389 bytes[1] = buf[0];
390 bytes[0] = buf[1];
391 buf = bytes;
392 }
393
394 *s = *((short *) buf);
395 return(READSTAT);
396 }
397
398
399 rs_write_shorts(FILE *savef, short *c, int count)
400 {
401 int n=0;
402
403 rs_write_int(savef,count);
404
405 for(n=0;n<count;n++)
406 rs_write_short(savef,c[n]);
407
408 return(WRITESTAT);
409 }
410
411 rs_write_longs(FILE *savef, long *c, int count)
412 {
413 int n=0;
414
415 rs_write_int(savef,count);
416
417 for(n=0;n<count;n++)
418 rs_write_long(savef,c[n]);
419
420 return(WRITESTAT);
421 }
422
423 rs_write_ulongs(FILE *savef, unsigned long *c, int count)
424 {
425 int n=0;
426
427 rs_write_int(savef,count);
428
429 for(n=0;n<count;n++)
430 rs_write_ulong(savef,c[n]);
431
432 return(WRITESTAT);
433 }
434
435 rs_write_booleans(FILE *savef, bool *c, int count)
436 {
437 int n=0;
438
439 rs_write_int(savef,count);
440
441 for(n=0;n<count;n++)
442 rs_write_boolean(savef,c[n]);
443
444 return(WRITESTAT);
445 }
446
447 rs_read_ints(int inf, int *i, int count)
448 {
449 int n=0,value=0;
450
451 if (rs_read_int(inf,&value) != 0)
452 {
453 if (value != count)
454 format_error = TRUE;
455 else
456 {
457 for(n=0;n<value;n++)
458 rs_read_int(inf, &i[n]);
459 }
460 }
461
462 return(READSTAT);
463 }
464
465 rs_read_shorts(int inf, short *i, int count)
466 {
467 int n=0,value=0;
468
469 if (rs_read_int(inf,&value) != 0)
470 {
471 if (value != count)
472 format_error = TRUE;
473 else
474 {
475 for(n=0;n<value;n++)
476 rs_read_short(inf, &i[n]);
477 }
478 }
479
480 return(READSTAT);
481 }
482
483 rs_read_longs(int inf, long *i, int count)
484 {
485 int n=0,value=0;
486
487 if (rs_read_int(inf,&value) != 0)
488 {
489 if (value != count)
490 format_error = TRUE;
491 else
492 {
493 for(n=0;n<value;n++)
494 rs_read_long(inf, &i[n]);
495 }
496 }
497
498 return(READSTAT);
499 }
500
501 rs_read_ulongs(int inf, unsigned long *i, int count)
502 {
503 int n=0,value=0;
504
505 if (rs_read_int(inf,&value) != 0)
506 {
507 if (value != count)
508 format_error = TRUE;
509 else
510 {
511 for(n=0;n<value;n++)
512 rs_read_ulong(inf, &i[n]);
513 }
514 }
515
516 return(READSTAT);
517 }
518
519 rs_read_booleans(int inf, bool *i, int count)
520 {
521 int n=0,value=0;
522
523 if (rs_read_int(inf,&value) != 0)
524 {
525 if (value != count)
526 format_error = TRUE;
527 else
528 {
529 for(n=0;n<value;n++)
530 rs_read_boolean(inf, &i[n]);
531 }
532 }
533
534 return(READSTAT);
535 }
536
537 rs_write_levtype(FILE *savef, LEVTYPE c)
538 {
539 int lt;
540
541 switch(c)
542 {
543 case NORMLEV: lt = 1; break;
544 case POSTLEV: lt = 2; break;
545 case MAZELEV: lt = 3; break;
546 case OUTSIDE: lt = 4; break;
547 case STARTLEV: lt = 5; break;
548 default: lt = -1; break;
549 }
550
551 rs_write_int(savef,lt);
552
553 return(WRITESTAT);
554 }
555
556 rs_read_levtype(int inf, LEVTYPE *l)
557 {
558 int lt;
559
560 rs_read_int(inf, &lt);
561
562 switch(lt)
563 {
564 case 1: *l = NORMLEV; break;
565 case 2: *l = POSTLEV; break;
566 case 3: *l = MAZELEV; break;
567 case 4: *l = OUTSIDE; break;
568 case 5: *l = STARTLEV; break;
569 default: *l = NORMLEV; break;
570 }
571
572 return(READSTAT);
573 }
574
575 rs_write_char(FILE *savef, char c)
576 {
577 rs_write(savef, &c, 1);
578 DBG(("%c",c));
579
580 return(WRITESTAT);
581 }
582
583 rs_read_char(int inf, char *c)
584 {
585 rs_read(inf, c, 1);
586
587 return(READSTAT);
588 }
589
590 rs_write_uchar(FILE *savef, unsigned char c)
591 {
592 rs_write(savef, &c, 1);
593 DBG(("%c",c));
594
595 return(WRITESTAT);
596 }
597
598 rs_read_uchar(int inf, unsigned char *c)
599 {
600 rs_read(inf, c, 1);
601
602 return(READSTAT);
603 }
604
605 rs_write_string(FILE *savef, char *s)
606 {
607 int len = 0;
608
609 len = (s == NULL) ? 0 : (int) strlen(s) + 1;
610
611 rs_write_uint(savef, (unsigned int) len);
612 rs_write(savef, s, len);
613
614 return(WRITESTAT);
615 }
616
617 rs_read_string_index(int inf, struct words master[], int maxindex, char **str)
618 {
619 int i;
620
621 if (rs_read_int(inf,&i) != 0)
622 {
623 if (i > maxindex)
624 {
625 printf("String index is out of range. %d > %d\n",
626 i, maxindex);
627 printf("Sorry, invalid save game format\n");
628 format_error = TRUE;
629 }
630 else if (i >= 0)
631 *str = master[i].w_string;
632 else
633 *str = NULL;
634 }
635 return(READSTAT);
636 }
637
638 rs_write_string_index(FILE *savef, struct words master[], int maxindex, char *str)
639 {
640 int i;
641
642 for(i = 0; i < maxindex; i++)
643 {
644 if (str == master[i].w_string)
645 {
646 rs_write_int(savef,i);
647 return(WRITESTAT);
648 }
649 }
650
651 rs_write_int(savef,-1);
652 return(WRITESTAT);
653 }
654
655 rs_read_scrolls(int inf)
656 {
657 int i;
658
659 for(i = 0; i < MAXSCROLLS; i++)
660 {
661 rs_read_new_string(inf,&s_names[i]);
662 rs_read_boolean(inf,&s_know[i]);
663 rs_read_new_string(inf,&s_guess[i]);
664 }
665
666 return(READSTAT);
667 }
668
669 rs_write_scrolls(FILE *savef)
670 {
671 int i;
672
673 for(i = 0; i < MAXSCROLLS; i++)
674 {
675 rs_write_string(savef,s_names[i]);
676 rs_write_boolean(savef,s_know[i]);
677 rs_write_string(savef,s_guess[i]);
678 }
679 return(READSTAT);
680 }
681
682 rs_read_potions(int inf)
683 {
684 int i;
685
686 for(i = 0; i < MAXPOTIONS; i++)
687 {
688 rs_read_string_index(inf,rainbow,NCOLORS,&p_colors[i]);
689 rs_read_boolean(inf,&p_know[i]);
690 rs_read_new_string(inf,&p_guess[i]);
691 }
692
693 return(READSTAT);
694 }
695
696 rs_write_potions(FILE *savef)
697 {
698 int i;
699
700 for(i = 0; i < MAXPOTIONS; i++)
701 {
702 rs_write_string_index(savef,rainbow,NCOLORS,p_colors[i]);
703 rs_write_boolean(savef,p_know[i]);
704 rs_write_string(savef,p_guess[i]);
705 }
706
707 return(WRITESTAT);
708 }
709
710 rs_read_rings(int inf)
711 {
712 int i;
713
714 for(i = 0; i < MAXRINGS; i++)
715 {
716 rs_read_string_index(inf,stones,NSTONES,&r_stones[i]);
717 rs_read_boolean(inf,&r_know[i]);
718 rs_read_new_string(inf,&r_guess[i]);
719 }
720
721 return(READSTAT);
722 }
723
724 rs_write_rings(FILE *savef)
725 {
726 int i;
727
728 for(i = 0; i < MAXRINGS; i++)
729 {
730 rs_write_string_index(savef,stones,NSTONES,r_stones[i]);
731 rs_write_boolean(savef,r_know[i]);
732 rs_write_string(savef,r_guess[i]);
733 }
734
735 return(WRITESTAT);
736 }
737
738 rs_read_misc(int inf)
739 {
740 int i;
741
742 for(i = 0; i < MAXMM; i++)
743 {
744 rs_read_boolean(inf,&m_know[i]);
745 rs_read_new_string(inf,&m_guess[i]);
746 }
747
748 return(READSTAT);
749 }
750
751 rs_write_misc(FILE *savef)
752 {
753 int i;
754
755 for(i = 0; i < MAXMM; i++)
756 {
757 rs_write_boolean(savef,m_know[i]);
758 rs_write_string(savef,m_guess[i]);
759 }
760
761 return(WRITESTAT);
762 }
763
764 rs_write_sticks(FILE *savef)
765 {
766 int i;
767
768 for (i = 0; i < MAXSTICKS; i++)
769 {
770 if (strcmp(ws_type[i],"staff") == 0)
771 {
772 rs_write_int(savef,0);
773 rs_write_string_index(savef, wood, NWOOD, ws_made[i]);
774 }
775 else
776 {
777 rs_write_int(savef,1);
778 rs_write_string_index(savef, metal, NMETAL, ws_made[i]);
779 }
780 rs_write_boolean(savef, ws_know[i]);
781 rs_write_string(savef, ws_guess[i]);
782 }
783
784 return(WRITESTAT);
785 }
786
787 rs_read_sticks(int inf)
788 {
789 int i = 0, list = 0;
790
791 for(i = 0; i < MAXSTICKS; i++)
792 {
793 rs_read_int(inf,&list);
794 if (list == 0)
795 {
796 rs_read_string_index(inf,wood,NWOOD,&ws_made[i]);
797 ws_type[i] = "staff";
798 }
799 else
800 {
801 rs_read_string_index(inf,metal,NMETAL,&ws_made[i]);
802 ws_type[i] = "wand";
803 }
804 rs_read_boolean(inf, &ws_know[i]);
805 rs_read_new_string(inf, &ws_guess[i]);
806 }
807
808 return(READSTAT);
809 }
810
811 rs_read_string(int inf, char *s, int max)
812 {
813 int len = 0;
814
815 if (rs_read_int(inf, &len) != FALSE)
816 {
817 if (len > max)
818 {
819 printf("String too long to restore. %d > %d\n",len,max);
820 printf("Sorry, invalid save game format\n");
821 format_error = TRUE;
822 }
823
824 rs_read(inf, s, len);
825 }
826
827 return(READSTAT);
828 }
829
830 rs_read_new_string(int inf, char **s)
831 {
832 int len=0;
833 char *buf=0;
834
835 if (rs_read_int(inf, &len) != 0)
836 {
837 if (len == 0)
838 *s = NULL;
839 else
840 {
841 buf = malloc(len);
842
843 if (buf == NULL)
844 read_error = TRUE;
845 else
846 {
847 rs_read(inf, buf, len);
848 *s = buf;
849 }
850 }
851 }
852
853 return(READSTAT);
854 }
855
856 rs_write_strings(FILE *savef, char *s[], int count)
857 {
858 int len = 0;
859 int n = 0;
860
861 rs_write_int(savef,count);
862
863 for(n = 0; n < count; n++)
864 {
865 len = (s[n] == NULL) ? 0L : (int) strlen(s[n]) + 1;
866 rs_write_int(savef, len);
867 rs_write(savef, s[n], len);
868 DBG(("%s",s[n]));
869 }
870
871 return(WRITESTAT);
872 }
873
874 rs_write_words(FILE *savef, struct words *w, int count)
875 {
876 int n = 0;
877
878 rs_write_int(savef,count);
879
880 for(n = 0; n < count; n++)
881 {
882 rs_write(savef, w[n].w_string, sizeof(w[n].w_string));
883 DBG(("%s",w[n].w_string));
884 }
885
886 return(WRITESTAT);
887 }
888
889 rs_read_words(int inf, struct words *w, int count)
890 {
891 int n = 0;
892 int value = 0;
893
894 rs_read_int(inf,&value);
895
896 if (value != count)
897 {
898 printf("Incorrect number of words in block. %d != %d.",
899 value,count);
900 printf("Sorry, invalid save game format");
901 format_error = TRUE;
902 }
903 else for(n = 0; n < count; n++)
904 {
905 rs_read(inf, w[n].w_string, sizeof(w[n].w_string));
906 }
907
908 return(READSTAT);
909 }
910
911 rs_read_new_strings(int inf, char **s, int count)
912 {
913 int len = 0;
914 int n = 0;
915 int value = 0;
916
917 if (rs_read_int(inf,&value) != 0)
918 {
919 if (value != count)
920 {
921 printf("Incorrect number of strings in block. %d > %d.",
922 value,count);
923 printf("Sorry, invalid save game format");
924 format_error = TRUE;
925 }
926 else
927 for(n=0; n<value; n++)
928 {
929 rs_read_int(inf, &len);
930
931 if (len == 0)
932 s[n]=0;
933 else
934 {
935 s[n] = malloc(len);
936 rs_read(inf,s[n],len);
937 }
938 }
939 }
940
941 return(READSTAT);
942 }
943
944 rs_write_coord(FILE *savef, coord *c)
945 {
946 DBG(("X ="));
947 rs_write_int(savef, c->x);
948 DBG(("Y ="));
949 rs_write_int(savef, c->y);
950
951 return(WRITESTAT);
952 }
953
954 rs_read_coord(int inf, coord *c)
955 {
956 rs_read_int(inf,&c->x);
957 rs_read_int(inf,&c->y);
958
959 return(READSTAT);
960 }
961
962 struct delayed_action {
963 int d_type;
964 int (*d_func)();
965 union {
966 VOID *vp;
967 int i;
968 } d_arg;
969 int d_time;
970 };
971
972 rs_write_daemons(FILE *savef, struct delayed_action *d_list,int count)
973 {
974 int i = 0;
975 int func = 0;
976
977 DBG(("Daemons\n"));
978 rs_write_int(savef, RSXR_DAEMONS);
979 rs_write_int(savef, count);
980
981 for(i=0; i < count; i++)
982 {
983 if (d_list[i].d_func == rollwand)
984 func = 1;
985 else if (d_list[i].d_func == doctor)
986 func = 2;
987 else if (d_list[i].d_func == stomach)
988 func = 3;
989 else if (d_list[i].d_func == trap_look)
990 func = 4;
991 else if (d_list[i].d_func == eat_gold)
992 func = 5;
993 else if (d_list[i].d_func == ring_search)
994 func = 6;
995 else if (d_list[i].d_func == ring_teleport)
996 func = 7;
997 else if (d_list[i].d_func == fumble)
998 func = 8;
999 else if (d_list[i].d_func == strangle)
1000 func = 9;
1001 else if (d_list[i].d_func == unconfuse)
1002 func = 10;
1003 else if (d_list[i].d_func == swander)
1004 func = 11;
1005 else if (d_list[i].d_func == spell_recovery)
1006 func = 12;
1007 else if (d_list[i].d_func == chant_recovery)
1008 func = 13;
1009 else if (d_list[i].d_func == prayer_recovery)
1010 func = 14;
1011 else if (d_list[i].d_func == cure_disease)
1012 func = 15;
1013 else if (d_list[i].d_func == unstink)
1014 func = 16;
1015 else if (d_list[i].d_func == res_strength)
1016 func = 17;
1017 else if (d_list[i].d_func == undance)
1018 func = 18;
1019 else if (d_list[i].d_func == suffocate)
1020 func = 19;
1021 else if (d_list[i].d_func == wghtchk)
1022 func = 20;
1023 else if (d_list[i].d_func == dust_appear)
1024 func = 21;
1025 else if (d_list[i].d_func == unchoke)
1026 func = 22;
1027 else if (d_list[i].d_func == sight)
1028 func = 23;
1029 else if (d_list[i].d_func == changeclass)
1030 func = 24;
1031 else if (d_list[i].d_func == cloak_charge)
1032 func = 25;
1033 else if (d_list[i].d_func == quill_charge)
1034 func = 26;
1035 else if (d_list[i].d_func == nohaste)
1036 func = 27;
1037 else if (d_list[i].d_func == noslow)
1038 func = 28;
1039 else if (d_list[i].d_func == unclrhead)
1040 func = 29;
1041 else if (d_list[i].d_func == unsee)
1042 func = 30;
1043 else if (d_list[i].d_func == unphase)
1044 func = 31;
1045 else if (d_list[i].d_func == land)
1046 func = 32;
1047 else if (d_list[i].d_func == appear)
1048 func = 33;
1049 else if (d_list[i].d_func == unskill)
1050 func = 34;
1051 else if (d_list[i].d_func == nofire)
1052 func = 35;
1053 else if (d_list[i].d_func == nocold)
1054 func = 36;
1055 else if (d_list[i].d_func == nobolt)
1056 func = 37;
1057 else if (d_list[i].d_func == NULL)
1058 func = 0;
1059 else
1060 func = -1;
1061
1062 rs_write_int(savef, d_list[i].d_type);
1063 rs_write_int(savef, func);
1064
1065 if (d_list[i].d_func == doctor)
1066 rs_write_int(savef, 1);
1067 else if (d_list[i].d_func == eat_gold)
1068 {
1069 int index;
1070 index = find_list_ptr(player.t_pack,d_list[i].d_arg.vp);
1071 rs_write_int(savef,index);
1072 }
1073 else if (d_list[i].d_func == changeclass)
1074 {
1075 rs_write_int(savef, d_list[i].d_arg.i);
1076 }
1077 else if (d_list[i].d_func == cloak_charge)
1078 {
1079 int index;
1080 index = find_list_ptr(player.t_pack,d_list[i].d_arg.vp);
1081 rs_write_int(savef,index);
1082 }
1083 else
1084 rs_write_int(savef, d_list[i].d_arg.i);
1085
1086 rs_write_int(savef, d_list[i].d_time);
1087 }
1088
1089 return(WRITESTAT);
1090 }
1091
1092 rs_read_daemons(int inf, struct delayed_action *d_list, int count)
1093 {
1094 int i = 0;
1095 int func = 0;
1096 int value = 0;
1097 int id = 0;
1098 int dummy = 0;
1099
1100 if (d_list == NULL)
1101 printf("HELP THERE ARE NO DAEMONS\n");
1102
1103 if (rs_read_int(inf, &id) != 0)
1104 {
1105 if (id != RSXR_DAEMONS)
1106 {
1107 printf("Invalid id. %x != %x(RSXR_DAEMONS)\n",
1108 id,RSXR_DAEMONS);
1109 printf("Sorry, invalid save game format");
1110 format_error = TRUE;
1111 }
1112 else if (rs_read_int(inf, &value) != 0)
1113 {
1114 if (value > count)
1115 {
1116 printf("Incorrect number of daemons in block. %d > %d.",
1117 value,count);
1118 printf("Sorry, invalid save game format");
1119 format_error = TRUE;
1120 }
1121 else
1122 {
1123 for(i=0; i < value; i++)
1124 {
1125 func = 0;
1126 rs_read_int(inf, &d_list[i].d_type);
1127 rs_read_int(inf, &func);
1128
1129 switch(func)
1130 {
1131 case 1: d_list[i].d_func = rollwand;
1132 break;
1133 case 2: d_list[i].d_func = doctor;
1134 break;
1135 case 3: d_list[i].d_func = stomach;
1136 break;
1137 case 4: d_list[i].d_func = trap_look;
1138 break;
1139 case 5: d_list[i].d_func = eat_gold;
1140 break;
1141 case 6: d_list[i].d_func = ring_search;
1142 break;
1143 case 7: d_list[i].d_func = ring_teleport;
1144 break;
1145 case 8: d_list[i].d_func = fumble;
1146 break;
1147 case 9: d_list[i].d_func = strangle;
1148 break;
1149 case 10: d_list[i].d_func = unconfuse;
1150 break;
1151 case 11: d_list[i].d_func = swander;
1152 break;
1153 case 12: d_list[i].d_func = spell_recovery;
1154 break;
1155 case 13: d_list[i].d_func = chant_recovery;
1156 break;
1157 case 14: d_list[i].d_func = prayer_recovery;
1158 break;
1159 case 15: d_list[i].d_func = cure_disease;
1160 break;
1161 case 16: d_list[i].d_func = unstink;
1162 break;
1163 case 17: d_list[i].d_func = res_strength;
1164 break;
1165 case 18: d_list[i].d_func = undance;
1166 break;
1167 case 19: d_list[i].d_func = suffocate;
1168 break;
1169 case 20: d_list[i].d_func = wghtchk;
1170 break;
1171 case 21: d_list[i].d_func = dust_appear;
1172 break;
1173 case 22: d_list[i].d_func = unchoke;
1174 break;
1175 case 23: d_list[i].d_func = sight;
1176 break;
1177 case 24: d_list[i].d_func = changeclass;
1178 break;
1179 case 25: d_list[i].d_func = cloak_charge;
1180 break;
1181 case 26: d_list[i].d_func = quill_charge;
1182 break;
1183 case 27: d_list[i].d_func = nohaste;
1184 break;
1185 case 28: d_list[i].d_func = noslow;
1186 break;
1187 case 29: d_list[i].d_func = unclrhead;
1188 break;
1189 case 30: d_list[i].d_func = unsee;
1190 break;
1191 case 31: d_list[i].d_func = unphase;
1192 break;
1193 case 32: d_list[i].d_func = land;
1194 break;
1195 case 33: d_list[i].d_func = appear;
1196 break;
1197 case 34: d_list[i].d_func = unskill;
1198 break;
1199 case 35: d_list[i].d_func = nofire;
1200 break;
1201 case 36: d_list[i].d_func = nocold;
1202 break;
1203 case 37: d_list[i].d_func = nobolt;
1204 break;
1205 case 0:
1206 case -1:
1207 default: d_list[i].d_func = NULL;
1208 break;
1209 }
1210
1211 if (d_list[i].d_func == doctor)
1212 {
1213 rs_read_int(inf, &dummy);
1214 d_list[i].d_arg.vp = (void *)&player;
1215 }
1216 else if (d_list[i].d_func == eat_gold)
1217 {
1218 rs_read_int(inf, &dummy);
1219 d_list[i].d_arg.vp = get_list_item(player.t_pack,dummy);
1220 if (d_list[i].d_arg.vp == NULL)
1221 d_list[i].d_type = 0;
1222 }
1223 else if (d_list[i].d_func == changeclass)
1224 {
1225 rs_read_int(inf, &d_list[i].d_arg.i);
1226 }
1227 else if (d_list[i].d_func == cloak_charge)
1228 {
1229 rs_read_int(inf, &dummy);
1230 d_list[i].d_arg.vp = get_list_item(player.t_pack,dummy);
1231 if (d_list[i].d_arg.vp == NULL)
1232 d_list[i].d_type = 0;
1233 }
1234 else
1235 rs_read_int(inf, &d_list[i].d_arg.i);
1236
1237 rs_read_int(inf, &d_list[i].d_time);
1238
1239 if (d_list[i].d_func == NULL)
1240 {
1241 d_list[i].d_time = 0;
1242 d_list[i].d_arg.vp = NULL;
1243 d_list[i].d_type = 0;
1244 }
1245
1246 }
1247 }
1248 }
1249 }
1250
1251 return(READSTAT);
1252 }
1253
1254 rs_write_rooms(FILE *savef, struct room r[], int count)
1255 {
1256 int n = 0,i = -1;
1257 struct linked_list *l;
1258
1259 DBG(("Rooms\n"));
1260 rs_write_int(savef, RSXR_ROOMS);
1261 rs_write_int(savef, count);
1262
1263 for(n=0; n<count; n++)
1264 {
1265 rs_write_coord(savef, &r[n].r_pos);
1266 rs_write_coord(savef, &r[n].r_max);
1267 rs_write_long(savef, r[n].r_flags);
1268 rs_write_coord_list(savef, r[n].r_exit);
1269
1270 l = r[n].r_fires;
1271 i = list_size(l);
1272
1273 rs_write_int(savef, i);
1274
1275 if (i >0)
1276 while (l != NULL)
1277 {
1278 i = find_list_ptr(mlist,l->l_data);
1279 rs_write_int(savef,i);
1280 l = l->l_next;
1281 }
1282 }
1283 return(WRITESTAT);
1284 }
1285
1286 rs_read_rooms(int inf, struct room *r, int count)
1287 {
1288 int value = 0, n = 0, i = 0, index = 0, id = 0;
1289 struct linked_list *fires=NULL, *item = NULL;
1290
1291 if (rs_read_int(inf,&id) != 0)
1292 {
1293 if (id != RSXR_ROOMS)
1294 {
1295 printf("Invalid id. %x != %x(RSXR_ROOMS)\n",
1296 id,RSXR_ROOMS);
1297 printf("Sorry, invalid save game format");
1298 format_error = TRUE;
1299 }
1300 else if (rs_read_int(inf,&value) != 0)
1301 {
1302 if (value != count)
1303 {
1304 printf("Incorrect number of rooms in block. %d > %d.",
1305 value,count);
1306 printf("Sorry, invalid save game format");
1307 format_error = TRUE;
1308 }
1309 else
1310 {
1311 for(n=0; n<value; n++)
1312 {
1313 rs_read_coord(inf,&r[n].r_pos);
1314 rs_read_coord(inf,&r[n].r_max);
1315 rs_read_long(inf,&r[n].r_flags);
1316 rs_read_coord_list(inf, &r[n].r_exit);
1317
1318 rs_read_int(inf, &i);
1319 fires = NULL;
1320 while (i>0)
1321 {
1322 rs_read_int(inf,&index);
1323
1324 if (index >= 0)
1325 {
1326 void *data;
1327 data = get_list_item(mlist,index);
1328 item = creat_item();
1329 item->l_data = data;
1330 if (fires == NULL)
1331 fires = item;
1332 else
1333 attach(fires,item);
1334 }
1335 i--;
1336 }
1337 r[n].r_fires=fires;
1338 }
1339 }
1340 }
1341 }
1342
1343 return(READSTAT);
1344 }
1345
1346 rs_write_object(FILE *savef, struct object *o)
1347 {
1348 rs_write_int(savef, RSXR_OBJECT);
1349 rs_write_int(savef, o->o_type);
1350 rs_write_coord(savef, &o->o_pos);
1351 rs_write_char(savef, o->o_launch);
1352 rs_write(savef, o->o_damage, sizeof(o->o_damage));
1353 rs_write(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
1354 rs_write_int(savef, o->o_count);
1355 rs_write_int(savef, o->o_which);
1356 rs_write_int(savef, o->o_hplus);
1357 rs_write_int(savef, o->o_dplus);
1358 rs_write_int(savef, o->o_ac);
1359 rs_write_long(savef, o->o_flags);
1360 rs_write_int(savef, o->o_group);
1361 rs_write_int(savef, o->o_weight);
1362 rs_write(savef, o->o_mark, MARKLEN);
1363
1364 DBG(("Object\n"));
1365 DBG((" SaveID : %X\n",RSXR_OBJECT));
1366 DBG((" Type : %d\n",o->o_type));
1367 DBG((" Pos : %d %d\n",o->o_pos.x,o->o_pos.y));
1368 DBG((" Launch : %c\n",o->o_launch));
1369 DBG((" Damage : %s\n",o->o_damage));
1370 DBG((" Hurl : %s\n",o->o_hurldmg));
1371 DBG((" Count : %d\n",o->o_count));
1372 DBG((" Which : %d\n",o->o_which));
1373 DBG((" HPlus : %d\n",o->o_hplus));
1374 DBG((" DPlus : %d\n",o->o_dplus));
1375 DBG((" AC : %d\n",o->o_ac));
1376 DBG((" Flags : %X\n",o->o_flags));
1377 DBG((" Group : %d\n",o->o_group));
1378 DBG((" Weight : %d\n",o->o_weight));
1379 DBG((" Mark : %s\n",o->o_mark));
1380 if (o->contents == NULL)
1381 {
1382 DBG((" Contents: None\n"));
1383 }
1384 else
1385 {
1386 DBG((" CONTENTS\n"));
1387 }
1388
1389 rs_write_object_list(savef, o->contents);
1390
1391 if (o->contents != NULL)
1392 DBG((" END_CONTENTS\n"));
1393
1394 return(WRITESTAT);
1395 }
1396
1397 rs_read_object(int inf, struct object *o)
1398 {
1399 int id;
1400
1401 if (rs_read_int(inf, &id) != 0)
1402 {
1403 if (id != RSXR_OBJECT)
1404 {
1405 printf("Invalid id. %x != %x(RSXR_OBJECT)\n", id,RSXR_OBJECT);
1406 printf("Sorry, invalid save game format");
1407 format_error = TRUE;
1408 }
1409 else
1410 {
1411 rs_read_int(inf, &o->o_type);
1412 rs_read_coord(inf, &o->o_pos);
1413 rs_read_char(inf, &o->o_launch);
1414 rs_read(inf, o->o_damage,sizeof(o->o_damage));
1415 rs_read(inf, o->o_hurldmg,sizeof(o->o_hurldmg));
1416 rs_read_int(inf, &o->o_count);
1417 rs_read_int(inf, &o->o_which);
1418 rs_read_int(inf, &o->o_hplus);
1419 rs_read_int(inf, &o->o_dplus);
1420 rs_read_int(inf,&o->o_ac);
1421 rs_read_long(inf,&o->o_flags);
1422 rs_read_int(inf,&o->o_group);
1423 rs_read_int(inf, &o->o_weight);
1424 rs_read(inf, o->o_mark, MARKLEN);
1425 rs_read_object_list(inf,&o->contents);
1426
1427 }
1428 }
1429
1430 return(READSTAT);
1431 }
1432
1433 rs_write_stats(FILE *savef, struct stats *s)
1434 {
1435 DBG(("Stats\n"));
1436 rs_write_int(savef, RSXR_STATS);
1437
1438 rs_write_short(savef, s->s_str);
1439 rs_write_short(savef, s->s_intel);
1440 rs_write_short(savef, s->s_wisdom);
1441 rs_write_short(savef, s->s_dext);
1442 rs_write_short(savef, s->s_const);
1443 rs_write_short(savef, s->s_charisma);
1444 rs_write_ulong(savef, s->s_exp);
1445 rs_write_int(savef, s->s_lvladj);
1446 rs_write_int(savef, s->s_lvl);
1447 rs_write_int(savef, s->s_arm);
1448 rs_write_int(savef, s->s_hpt);
1449 rs_write_int(savef, s->s_pack);
1450 rs_write_int(savef, s->s_carry);
1451 rs_write(savef, s->s_dmg, sizeof(s->s_dmg));
1452
1453 return(WRITESTAT);
1454 }
1455
1456 rs_read_stats(int inf, struct stats *s)
1457 {
1458 int id;
1459
1460 if (rs_read_int(inf, &id) != 0)
1461 {
1462 if (id != RSXR_STATS)
1463 {
1464 printf("Invalid id. %x != %x(RSXR_STATS)\n", id,RSXR_STATS);
1465 printf("Sorry, invalid save game format");
1466 format_error = TRUE;
1467 }
1468 else
1469 {
1470 rs_read_short(inf,&s->s_str);
1471 rs_read_short(inf,&s->s_intel);
1472 rs_read_short(inf,&s->s_wisdom);
1473 rs_read_short(inf,&s->s_dext);
1474 rs_read_short(inf,&s->s_const);
1475 rs_read_short(inf,&s->s_charisma);
1476 rs_read_ulong(inf,&s->s_exp);
1477 rs_read_int(inf,&s->s_lvladj);
1478 rs_read_int(inf,&s->s_lvl);
1479 rs_read_int(inf,&s->s_arm);
1480 rs_read_int(inf,&s->s_hpt);
1481 rs_read_int(inf,&s->s_pack);
1482 rs_read_int(inf,&s->s_carry);
1483 rs_read(inf,s->s_dmg,sizeof(s->s_dmg));
1484 }
1485 }
1486
1487 return(READSTAT);
1488 }
1489
1490 rs_write_mstats(FILE *savef, struct mstats *s)
1491 {
1492 DBG(("M-Stats\n"));
1493 rs_write_int(savef, RSXR_STATS);
1494 rs_write_short(savef, s->ms_str);
1495 /*printf(" Strength: %d\n",s->ms_str);*/
1496 rs_write_short(savef, s->ms_dex);
1497 rs_write_short(savef, s->ms_move);
1498 rs_write_ulong(savef, s->ms_exp);
1499 rs_write_short(savef, s->ms_lvl);
1500 rs_write_short(savef, s->ms_arm);
1501 rs_write(savef, s->ms_hpt, sizeof(s->ms_hpt));
1502 rs_write(savef, s->ms_dmg, sizeof(s->ms_dmg));
1503 /*printf(" Damage: %s\n",s->ms_dmg);*/
1504
1505 return(WRITESTAT);
1506 }
1507
1508 rs_read_mstats(int inf, struct mstats *s)
1509 {
1510 int id;
1511
1512 if (rs_read_int(inf, &id) != 0)
1513 {
1514 if (id != RSXR_STATS)
1515 {
1516 printf("Invalid id. %x != %x(RSXR_STATS)\n", id,RSXR_STATS);
1517 printf("Sorry, invalid save game format");
1518 format_error = TRUE;
1519 }
1520 else
1521 {
1522 rs_read_short(inf,&s->ms_str);
1523 /*printf(" Strength: %d\n",s->ms_str);*/
1524 rs_read_short(inf,&s->ms_dex);
1525 /*printf(" Dexterity: %d\n",s->ms_dex);*/
1526 rs_read_short(inf,&s->ms_move);
1527 /*printf(" Moves: %d\n",s->ms_move);*/
1528 rs_read_ulong(inf,&s->ms_exp);
1529 /*printf(" Experience: %d\n",s->ms_exp);*/
1530 rs_read_short(inf,&s->ms_lvl);
1531 /*printf(" Level: %d\n",s->ms_lvl);*/
1532 rs_read_short(inf,&s->ms_arm);
1533 /*printf(" Armor: %d\n",s->ms_arm);*/
1534 rs_read(inf,s->ms_hpt,sizeof(s->ms_hpt));
1535 /*printf(" HP: %s\n",s->ms_hpt);*/
1536 rs_read(inf,s->ms_dmg,sizeof(s->ms_dmg));
1537 /*printf(" Damage: %s\n",s->ms_dmg);*/
1538 }
1539 }
1540
1541 return(READSTAT);
1542 }
1543
1544 rs_write_init_weps(FILE *savef, struct init_weps *w, int count)
1545 {
1546 int i;
1547
1548 DBG(("Init-Weps\n"));
1549 rs_write_int(savef, RSXR_IWEAPS);
1550 rs_write_int(savef, count);
1551
1552 for(i=0;i<count;i++)
1553 {
1554 rs_write(savef, w[i].w_name, sizeof(w[i].w_name));
1555 rs_write(savef, w[i].w_dam, sizeof(w[i].w_dam));
1556 rs_write(savef, w[i].w_hrl, sizeof(w[i].w_hrl));
1557 rs_write_char(savef, w[i].w_launch);
1558 rs_write_int(savef, w[i].w_flags);
1559 rs_write_int(savef, w[i].w_rate);
1560 rs_write_int(savef, w[i].w_wght);
1561 rs_write_int(savef, w[i].w_worth);
1562 }
1563 return(WRITESTAT);
1564 }
1565
1566 rs_read_init_weps(int inf, struct init_weps *w,int count)
1567 {
1568 int id,value,i;
1569
1570 rs_read_int(inf, &id);
1571 rs_read_int(inf, &value);
1572
1573 if (value != count)
1574 {
1575 printf("Incorrect number of init_weps in block. %d != %d.",
1576 value,count);
1577 printf("Sorry, invalid save game format");
1578 format_error = TRUE;
1579 }
1580 else for (i = 0; i < count; i++)
1581 {
1582 rs_read(inf, w[i].w_name, sizeof(w[i].w_name));
1583 rs_read(inf, w[i].w_dam, sizeof(w[i].w_dam));
1584 rs_read(inf, w[i].w_hrl, sizeof(w[i].w_hrl));
1585 rs_read_char(inf, &w[i].w_launch);
1586 rs_read_int(inf, &w[i].w_flags);
1587 rs_read_int(inf, &w[i].w_rate);
1588 rs_read_int(inf, &w[i].w_wght);
1589 rs_read_int(inf, &w[i].w_worth);
1590 }
1591 return(READSTAT);
1592 }
1593
1594 rs_write_init_armor(FILE *savef, struct init_armor *a, int count)
1595 {
1596 int i;
1597 DBG(("Init-Armor\n"));
1598 rs_write_int(savef, RSXR_IARMOR);
1599 rs_write_int(savef, count);
1600 for(i=0;i<count;i++)
1601 {
1602 rs_write(savef, a[i].a_name, sizeof(a[i].a_name));
1603 rs_write_int(savef, a[i].a_prob);
1604 rs_write_int(savef, a[i].a_class);
1605 rs_write_int(savef, a[i].a_worth);
1606 rs_write_int(savef, a[i].a_wght);
1607 }
1608 return(WRITESTAT);
1609 }
1610
1611 rs_read_init_armor(int inf, struct init_armor *a,int count)
1612 {
1613 int id,value,i;
1614
1615 rs_read_int(inf, &id);
1616 rs_read_int(inf, &value);
1617
1618 for(i=0;i<count;i++)
1619 {
1620 rs_read(inf, a[i].a_name, sizeof(a[i].a_name));
1621 rs_read_int(inf, &a[i].a_prob);
1622 rs_read_int(inf, &a[i].a_class);
1623 rs_read_int(inf, &a[i].a_worth);
1624 rs_read_int(inf, &a[i].a_wght);
1625 }
1626
1627 return(READSTAT);
1628 }
1629
1630 rs_write_spells(FILE *savef, struct spells *s, int count)
1631 {
1632 int i;
1633 DBG(("Spells\n"));
1634 rs_write_int(savef, RSXR_SPELLS);
1635 rs_write_int(savef, count);
1636 for(i=0;i<count;i++)
1637 {
1638 rs_write_short(savef, s[i].s_which);
1639 rs_write_short(savef, s[i].s_cost);
1640 rs_write_short(savef, s[i].s_type);
1641 rs_write_int(savef, s[i].s_flag);
1642 }
1643 return(WRITESTAT);
1644 }
1645
1646 rs_read_spells(int inf, struct spells *s,int count)
1647 {
1648 int id,value,i;
1649
1650 rs_read_int(inf, &id);
1651 rs_read_int(inf, &value);
1652
1653 for(i=0;i<count;i++)
1654 {
1655 rs_read_short(inf, &s[i].s_which);
1656 rs_read_short(inf, &s[i].s_cost);
1657 rs_read_short(inf, &s[i].s_type);
1658 rs_read_int(inf, &s[i].s_flag);
1659 }
1660 return(READSTAT);
1661 }
1662
1663 rs_write_item_list(FILE *savef, struct item_list *i)
1664 {
1665 DBG(("Item List\n"));
1666 rs_write_int(savef, RSXR_ILIST);
1667 rs_write_char(savef, i->item_ch);
1668 rs_write(savef, i->item_desc, sizeof(i->item_desc));
1669 return(WRITESTAT);
1670 }
1671 rs_read_item_list(int inf, struct item_list *i)
1672 {
1673 int id;
1674
1675 rs_read_int(inf, &id);
1676
1677 rs_read_uchar(inf, &i->item_ch);
1678 rs_read(inf, i->item_desc,sizeof(i->item_desc));
1679 return(READSTAT);
1680 }
1681
1682 rs_write_h_list(FILE *savef, struct h_list *h)
1683 {
1684 DBG(("H List\n"));
1685 rs_write_int(savef, RSXR_HLIST);
1686 rs_write_char(savef, h->h_ch);
1687 rs_write(savef, h->h_desc, sizeof(h->h_desc));
1688 return(WRITESTAT);
1689 }
1690
1691 rs_read_h_list(int inf, struct h_list *h)
1692 {
1693 int id;
1694
1695 rs_read_int(inf, &id);
1696
1697 rs_read_char(inf, &h->h_ch);
1698 rs_read(inf, h->h_desc,sizeof(h->h_desc));
1699 return(READSTAT);
1700 }
1701
1702 rs_write_death_types(FILE *savef, struct death_type *d,int count)
1703 {
1704 int i;
1705
1706 DBG(("Death Types\n"));
1707 rs_write_int(savef, RSXR_DEATHTYPE);
1708 rs_write_int(savef, count);
1709
1710 for(i=0; i < count; i++)
1711 {
1712 rs_write_int(savef, d[i].reason);
1713 rs_write(savef, d[i].name, sizeof(d[i].name));
1714 }
1715 return(WRITESTAT);
1716 }
1717 rs_read_death_types(int inf, struct death_type *d, int count)
1718 {
1719 int id,value,i;
1720
1721 rs_read_int(inf, &id);
1722 rs_read_int(inf, &value);
1723 if (value != count)
1724 {
1725 printf("Incorrect number of death_types in block. %d > %d.",
1726 value,count);
1727 printf("Sorry, invalid save game format");
1728 format_error = TRUE;
1729 }
1730 else for(i=0;i < count;i++)
1731 {
1732 rs_read_int(inf, &d[i].reason);
1733 rs_read(inf, d[i].name,sizeof(d[i].name));
1734 }
1735 return(READSTAT);
1736 }
1737
1738 rs_write_character_types(FILE *savef, struct character_types *c, int count)
1739 {
1740 int i;
1741
1742 DBG(("Character Types\n"));
1743 rs_write_int(savef, RSXR_CTYPES);
1744 rs_write_int(savef,count);
1745
1746 for(i=0;i<count;i++)
1747 {
1748 rs_write(savef, c[i].name, sizeof(c[i].name));
1749 rs_write_long(savef, c[i].start_exp);
1750 rs_write_long(savef, c[i].cap);
1751 rs_write_int(savef, c[i].hit_pts);
1752 rs_write_int(savef, c[i].base);
1753 rs_write_int(savef, c[i].max_lvl);
1754 rs_write_int(savef, c[i].factor);
1755 rs_write_int(savef, c[i].offset);
1756 rs_write_int(savef, c[i].range);
1757 }
1758 return(WRITESTAT);
1759 }
1760
1761 rs_read_character_types(int inf, struct character_types *c,int count)
1762 {
1763 int id,value,i;
1764
1765 rs_read_int(inf, &id);
1766 rs_read_int(inf, &value);
1767
1768 if (value != count)
1769 {
1770 printf("Incorrect number of character types in block. %d > %d.",
1771 value,count);
1772 printf("Sorry, invalid save game format");
1773 format_error = TRUE;
1774 }
1775 else for (i = 0; i < count; i++)
1776 {
1777 rs_read(inf, c[i].name,sizeof(c[i].name));
1778 rs_read_long(inf, &c[i].start_exp);
1779 rs_read_long(inf, &c[i].cap);
1780 rs_read_int(inf, &c[i].hit_pts);
1781 rs_read_int(inf, &c[i].base);
1782 rs_read_int(inf, &c[i].max_lvl);
1783 rs_read_int(inf, &c[i].factor);
1784 rs_read_int(inf, &c[i].offset);
1785 rs_read_int(inf, &c[i].range);
1786 }
1787 return(READSTAT);
1788 }
1789
1790 rs_write_traps(FILE *savef, struct trap *trap,int count)
1791 {
1792 int n;
1793
1794 DBG(("Traps\n"));
1795 rs_write_int(savef, RSXR_TRAP);
1796 rs_write_int(savef, count);
1797
1798 for(n=0; n<count; n++)
1799 {
1800 rs_write_char(savef, trap[n].tr_type);
1801 rs_write_char(savef, trap[n].tr_show);
1802 rs_write_coord(savef, &trap[n].tr_pos);
1803 rs_write_long(savef, trap[n].tr_flags);
1804 }
1805 }
1806
1807 rs_read_traps(int inf, struct trap *trap, int count)
1808 {
1809 int id = 0, value = 0, n = 0;
1810
1811 if (rs_read_int(inf,&id) != 0)
1812 {
1813 if (id != RSXR_TRAP)
1814 {
1815 printf("Invalid id. %x != %x(RSXR_TRAP)\n",
1816 id,RSXR_TRAP);
1817 printf("Sorry, invalid save game format");
1818 format_error = TRUE;
1819 }
1820 else if (rs_read_int(inf,&value) != 0)
1821 {
1822 if (value != count)
1823 {
1824 printf("Incorrect number of traps in block. %d > %d.",
1825 value,count);
1826 printf("Sorry, invalid save game format\n");
1827 format_error = TRUE;
1828 }
1829 else
1830 {
1831 for(n=0;n<value;n++)
1832 {
1833 rs_read_uchar(inf,&trap[n].tr_type);
1834 rs_read_uchar(inf,&trap[n].tr_show);
1835 rs_read_coord(inf,&trap[n].tr_pos);
1836 rs_read_long(inf,&trap[n].tr_flags);
1837 }
1838 }
1839 }
1840 else
1841 format_error = TRUE;
1842 }
1843
1844 return(READSTAT);
1845 }
1846
1847 rs_write_monsters(FILE * savef, struct monster * m, int count)
1848 {
1849 int n;
1850
1851 DBG(("Monsters\n"));
1852 rs_write_int(savef, RSXR_MONSTERS);
1853 rs_write_int(savef, count);
1854
1855 for(n=0;n<count;n++)
1856 {
1857 rs_write(savef, m[n].m_name, sizeof(m[n].m_name));
1858 /*printf("Monster: %s/%d/%d\n",m[n].m_name,sizeof(m[n].m_name),strlen(m[n].m_name));*/
1859 rs_write_short(savef, m[n].m_carry);
1860 rs_write_boolean(savef, m[n].m_normal);
1861 rs_write_boolean(savef, m[n].m_wander);
1862 rs_write_char(savef, m[n].m_appear);
1863 rs_write(savef, m[n].m_intel,sizeof(m[n].m_intel));
1864 rs_write_longs(savef, m[n].m_flags, MAXFLAGS);
1865 rs_write(savef, m[n].m_typesum,sizeof(m[n].m_typesum));
1866 rs_write_short(savef, m[n].m_numsum);
1867 rs_write_short(savef, m[n].m_add_exp);
1868
1869 rs_write_mstats(savef, &m[n].m_stats);
1870 }
1871
1872 return(WRITESTAT);
1873 }
1874
1875 rs_read_monsters(int inf, struct monster *m, int count)
1876 {
1877 int id = 0, value = 0, n = 0;
1878 char buffer[1024];
1879
1880 if (rs_read_int(inf, &id) != 0)
1881 {
1882 if (id != RSXR_MONSTERS)
1883 {
1884 printf("Invalid id. %x != %x(RSXR_MONSTERS)\n",
1885 id,RSXR_MONSTERS);
1886 printf("Sorry, invalid save game format");
1887 format_error = TRUE;
1888 }
1889 else if (rs_read_int(inf, &value) != 0)
1890 {
1891 if (value != count)
1892 { printf("Incorrect number of monsters in block. %d != %d.",
1893 value,count);
1894 printf("Sorry, invalid save game format\n");
1895 format_error = TRUE;
1896
1897 }
1898 else for(n=0;n<value;n++)
1899 {
1900 rs_read(inf, buffer,sizeof(m[n].m_name));
1901 assert( strcmp(buffer,m[n].m_name) == 0);
1902 /*printf("Monster: %s\n",m[n].m_name);*/
1903 rs_read_short(inf, &m[n].m_carry);
1904 /*printf(" Carry: %d\n",m[n].m_carry); */
1905 rs_read_boolean(inf, &m[n].m_normal);
1906 /*printf(" Normal: %d\n",m[n].m_normal);*/
1907 rs_read_boolean(inf, &m[n].m_wander);
1908 /*printf(" Wander: %d\n",m[n].m_wander);*/
1909 rs_read_char(inf, &m[n].m_appear);
1910 /*printf(" Appears: %c\n",m[n].m_appear);*/
1911 rs_read(inf, m[n].m_intel,sizeof(m[n].m_intel));
1912 /*printf(" Intelligence: %s\n",m[n].m_intel);*/
1913 rs_read_longs(inf, m[n].m_flags, MAXFLAGS);
1914 /*printf(" Flags: %X\n",m[n].m_flags);*/
1915 rs_read(inf, m[n].m_typesum, sizeof(m[n].m_typesum));
1916 /*printf(" Summons: %s\n",m[n].m_typesum);*/
1917 rs_read_short(inf, &m[n].m_numsum);
1918 /*printf(" # Summons: %d\n",m[n].m_numsum);*/
1919 rs_read_short(inf, &m[n].m_add_exp);
1920 /*printf(" Experience: %d\n",m[n].m_add_exp);*/
1921 rs_read_mstats(inf, &m[n].m_stats);
1922
1923 }
1924 }
1925 else
1926 format_error = TRUE;
1927 }
1928
1929 return(READSTAT);
1930 }
1931
1932 /*****************************************************************************/
1933
1934 rs_write_coord_list(FILE *savef, struct linked_list *l)
1935 {
1936 DBG(("Coordinate List\n"));
1937 rs_write_int(savef, RSXR_COORDLIST);
1938 rs_write_int(savef, list_size(l));
1939
1940 while (l != NULL)
1941 {
1942 rs_write_coord(savef, (coord *) l->l_data);
1943 l = l->l_next;
1944 }
1945
1946 return(WRITESTAT);
1947 }
1948
1949 rs_read_coord_list(int inf, struct linked_list **list)
1950 {
1951 int id;
1952 int i, cnt;
1953 struct linked_list *l = NULL, *previous = NULL, *head = NULL;
1954
1955 if (rs_read_int(inf,&id) != 0)
1956 {
1957 if (id != RSXR_COORDLIST)
1958 {
1959 printf("Invalid id. %x != %x(RSXR_COORDLIST)\n",
1960 id,RSXR_COORDLIST);
1961 printf("Sorry, invalid save game format");
1962 format_error = TRUE;
1963 }
1964 else if (rs_read_int(inf,&cnt) != 0)
1965 {
1966 for (i = 0; i < cnt; i++)
1967 {
1968 l = new_item(sizeof(coord));
1969 l->l_prev = previous;
1970 if (previous != NULL)
1971 previous->l_next = l;
1972 rs_read_coord(inf,(coord *) l->l_data);
1973 if (previous == NULL)
1974 head = l;
1975 previous = l;
1976 }
1977
1978 if (l != NULL)
1979 l->l_next = NULL;
1980
1981 *list = head;
1982 }
1983 else
1984 format_error = TRUE;
1985 }
1986 else
1987 format_error = TRUE;
1988
1989 return(READSTAT);
1990 }
1991
1992 rs_write_object_list(FILE *savef, struct linked_list *l)
1993 {
1994 DBG(("Object List\n"));
1995 rs_write_int(savef, RSXR_OBJECTLIST);
1996 rs_write_int(savef, list_size(l));
1997
1998 while (l != NULL)
1999 {
2000 rs_write_object(savef, (struct object *) l->l_data);
2001 l = l->l_next;
2002 }
2003
2004 return(WRITESTAT);
2005 }
2006
2007 rs_read_object_list(int inf, struct linked_list **list)
2008 {
2009 int id;
2010 int i, cnt;
2011 struct linked_list *l = NULL, *previous = NULL, *head = NULL;
2012
2013 if (rs_read_int(inf,&id) != 0)
2014 {
2015 if (rs_read_int(inf,&cnt) != 0)
2016 {
2017 for (i = 0; i < cnt; i++)
2018 {
2019 l = new_item(sizeof(struct object));
2020 memset(l->l_data,0,sizeof(struct object));
2021 l->l_prev = previous;
2022 if (previous != NULL)
2023 previous->l_next = l;
2024 rs_read_object(inf,(struct object *) l->l_data);
2025 if (previous == NULL)
2026 head = l;
2027 previous = l;
2028 }
2029
2030 if (l != NULL)
2031 l->l_next = NULL;
2032
2033 *list = head;
2034 }
2035 else
2036 format_error = TRUE;
2037 }
2038 else
2039 format_error = TRUE;
2040
2041
2042 return(READSTAT);
2043 }
2044
2045 int
2046 find_thing_coord(monlist, c)
2047 struct linked_list *monlist;
2048 coord *c;
2049 {
2050 struct linked_list *mitem;
2051 struct thing *tp;
2052 int i = 0;
2053
2054 for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)
2055 {
2056 tp = THINGPTR(mitem);
2057 if (c == &tp->t_pos)
2058 return(i);
2059 i++;
2060 }
2061
2062 return(-1);
2063 }
2064
2065 int
2066 find_object_coord(objlist, c)
2067 struct linked_list *objlist;
2068 coord *c;
2069 {
2070 struct linked_list *oitem;
2071 struct object *obj;
2072 int i = 0;
2073
2074 for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)
2075 {
2076 obj = OBJPTR(oitem);
2077 if (c == &obj->o_pos)
2078 return(i);
2079 i++;
2080 }
2081
2082 return(-1);
2083 }
2084
2085 rs_write_thing(FILE *savef, struct thing *t)
2086 {
2087 int i = -1;
2088
2089 DBG(("Thing\n"));
2090 rs_write_int(savef, RSXR_THING);
2091 rs_write_boolean(savef,t->t_wasshot);
2092 rs_write_char(savef, t->t_type);
2093 rs_write_char(savef, t->t_disguise);
2094 rs_write_char(savef, t->t_oldch);
2095 rs_write_short(savef, t->t_ctype);
2096 rs_write_short(savef, t->t_index);
2097 rs_write_short(savef, t->t_no_move);
2098 rs_write_short(savef, t->t_quiet);
2099 rs_write_short(savef, t->t_movement);
2100 rs_write_short(savef, t->t_action);
2101 rs_write_short(savef, t->t_artifact);
2102 rs_write_short(savef, t->t_wand);
2103 rs_write_short(savef, t->t_summon);
2104 rs_write_short(savef, t->t_cast);
2105 rs_write_short(savef, t->t_breathe);
2106
2107 rs_write_string(savef,t->t_name);
2108 rs_write_coord(savef, &t->t_doorgoal);
2109
2110 if (t->t_dest == &hero)
2111 {
2112 rs_write_int(savef,0);
2113 rs_write_int(savef,1);
2114 }
2115 else if (t->t_dest != NULL)
2116 {
2117 i = find_thing_coord(mlist, t->t_dest);
2118
2119 if (i >= 0)
2120 {
2121 rs_write_int(savef,1);
2122 rs_write_int(savef,i);
2123 }
2124 else
2125 {
2126 i = find_object_coord(lvl_obj, t->t_dest);
2127
2128 if (i >= 0)
2129 {
2130 rs_write_int(savef,2);
2131 rs_write_int(savef,i);
2132 }
2133 else
2134 {
2135 rs_write_int(savef,0);
2136 rs_write_int(savef,1); /* chase the hero anyway */
2137 }
2138 }
2139 }
2140 else
2141 {
2142 rs_write_int(savef,0);
2143 rs_write_int(savef,0);
2144 }
2145
2146 rs_write_coord(savef, &t->t_pos);
2147 rs_write_coord(savef, &t->t_oldpos);
2148 rs_write_coord(savef, &t->t_newpos);
2149 rs_write_ulongs(savef, t->t_flags, 16);
2150
2151 DBG(("Thing\n"));
2152 DBG((" SaveID : %X\n",RSXR_THING));
2153 DBG((" Name : %s\n",t->t_name));
2154 DBG((" WasShot : %d\n",t->t_wasshot));
2155 DBG((" Type : %c(%d)\n",t->t_type,t->t_type));
2156 DBG((" Disguise: %c(%d)\n",t->t_disguise,t->t_disguise));
2157 DBG((" OldCh : %c(%d)\n",t->t_oldch,t->t_oldch));
2158 DBG((" CType : %d\n",t->t_ctype));
2159 DBG((" Index : %d\n",t->t_index));
2160 DBG((" NoMove : %d\n",t->t_no_move));
2161 DBG((" Quiet : %d\n",t->t_quiet));
2162 DBG((" Movement: %d\n",t->t_movement));
2163 DBG((" Action : %d\n",t->t_action));
2164 DBG((" Artifact: %d\n",t->t_artifact));
2165 DBG((" Wand : %d\n",t->t_wand));
2166 DBG((" Summon : %d\n",t->t_summon));
2167 DBG((" Cast : %d\n",t->t_cast));
2168 DBG((" Breathe : %d\n",t->t_breathe));
2169 DBG((" DoorGoal: %d %d\n",t->t_doorgoal.x,t->t_doorgoal.y));
2170 if (t->t_dest)
2171 {
2172 DBG((" Dest : %d %d\n",t->t_dest->x,t->t_dest->y));
2173 }
2174 else
2175 {
2176 DBG((" Dest : None\n"));
2177 }
2178 DBG((" Pos : %d %d\n",t->t_pos.x,t->t_pos.y));
2179 DBG((" OldPos : %d %d\n",t->t_oldpos.x,t->t_oldpos.y));
2180 DBG((" NewPos : %d %d\n",t->t_newpos.x,t->t_newpos.y));
2181 DBG((" Flags : "));
2182 { int i; for(i=0;i<16;i++) {DBG(("%d ",t->t_flags[i]));} DBG(("\n")); }
2183
2184 rs_write_object_list(savef, t->t_pack);
2185 i = -1;
2186 if (t->t_using != NULL)
2187 i = find_list_ptr(t->t_pack, t->t_using->l_data);
2188 rs_write_int(savef, i);
2189 rs_write_stats(savef, &t->t_stats);
2190 rs_write_stats(savef, &t->maxstats);
2191
2192 return(WRITESTAT);
2193 }
2194
2195 rs_fix_thing(struct thing *t)
2196 {
2197 struct linked_list *item;
2198 struct thing *tp;
2199
2200 if (t->t_reserved < 0)
2201 return;
2202
2203 item = get_list_item(mlist,t->t_reserved);
2204
2205 if (item != NULL)
2206 {
2207 tp = THINGPTR(item);
2208 t->t_dest = &tp->t_pos;
2209 }
2210 }
2211
2212 rs_read_thing(int inf, struct thing *t)
2213 {
2214 int id;
2215 int listid = 0, index = -1;
2216 struct linked_list *item;
2217
2218 if (rs_read_int(inf, &id) != 0)
2219 {
2220 if (id != RSXR_THING)
2221 format_error = TRUE;
2222 else
2223 {
2224 rs_read_boolean(inf,&t->t_wasshot);
2225 rs_read_uchar(inf, &t->t_type);
2226 rs_read_uchar(inf, &t->t_disguise);
2227 rs_read_uchar(inf, &t->t_oldch);
2228 rs_read_short(inf, &t->t_ctype);
2229 rs_read_short(inf, &t->t_index);
2230 rs_read_short(inf, &t->t_no_move);
2231 rs_read_short(inf, &t->t_quiet);
2232 rs_read_short(inf, &t->t_movement);
2233 rs_read_short(inf, &t->t_action);
2234 rs_read_short(inf, &t->t_artifact);
2235 rs_read_short(inf, &t->t_wand);
2236 rs_read_short(inf, &t->t_summon);
2237 rs_read_short(inf, &t->t_cast);
2238 rs_read_short(inf, &t->t_breathe);
2239 rs_read_new_string(inf,&t->t_name);
2240 rs_read_coord(inf,&t->t_doorgoal);
2241
2242 rs_read_int(inf,&listid);
2243 rs_read_int(inf,&index);
2244 t->t_reserved = -1;
2245 if (listid == 0)
2246 {
2247 if (index == 1)
2248 t->t_dest = &hero;
2249 else
2250 t->t_dest = NULL;
2251 }
2252 else if (listid == 1)
2253 {
2254 t->t_dest = NULL;
2255 t->t_reserved = index;
2256 }
2257 else if (listid == 2)
2258 {
2259 struct object *obj;
2260 item = get_list_item(lvl_obj,index);
2261 if (item != NULL)
2262 {
2263 obj = OBJPTR(item);
2264 t->t_dest = &obj->o_pos;
2265 }
2266 }
2267 else
2268 t->t_dest = NULL;
2269
2270 rs_read_coord(inf,&t->t_pos);
2271 rs_read_coord(inf,&t->t_oldpos);
2272 rs_read_coord(inf,&t->t_newpos);
2273 rs_read_ulongs(inf,t->t_flags,16);
2274 rs_read_object_list(inf,&t->t_pack);
2275 rs_read_int(inf,&index);
2276 t->t_using = get_list_item(t->t_pack, index);
2277 rs_read_stats(inf,&t->t_stats);
2278 rs_read_stats(inf,&t->maxstats);
2279 }
2280 }
2281 else format_error = TRUE;
2282
2283 return(READSTAT);
2284 }
2285
2286 int
2287 find_list_ptr(struct linked_list *l, void *ptr)
2288 {
2289 int count = 0;
2290
2291 while(l != NULL)
2292 {
2293 if (l->l_data == ptr)
2294 return(count);
2295
2296 l = l->l_next;
2297 count++;
2298 }
2299
2300 return(-1);
2301 }
2302
2303
2304 int
2305 list_size(struct linked_list *l)
2306 {
2307 int count = 0;
2308
2309 while(l != NULL)
2310 {
2311 if (l->l_data == NULL)
2312 return(count);
2313
2314 count++;
2315
2316 l = l->l_next;
2317 }
2318
2319 return(count);
2320 }
2321
2322
2323 rs_write_monster_list(FILE *savef, struct linked_list *l)
2324 {
2325 int cnt = 0;
2326
2327 DBG(("Monster List\n"));
2328 rs_write_int(savef, RSXR_MONSTERLIST);
2329
2330 cnt = list_size(l);
2331
2332 rs_write_int(savef, cnt);
2333
2334 if (cnt < 1)
2335 return(WRITESTAT);
2336
2337 while (l != NULL) {
2338 rs_write_thing(savef, (struct thing *)l->l_data);
2339 l = l->l_next;
2340 }
2341
2342 return(WRITESTAT);
2343 }
2344
2345 rs_fix_monster_list(list)
2346 struct linked_list *list;
2347 {
2348 struct linked_list *item;
2349
2350 for(item = list; item != NULL; item = item->l_next)
2351 rs_fix_thing(THINGPTR(item));
2352 }
2353
2354 rs_read_monster_list(int inf, struct linked_list **list)
2355 {
2356 int id;
2357 int i, cnt;
2358 struct linked_list *l = NULL, *previous = NULL, *head = NULL;
2359
2360 if (rs_read_int(inf,&id) != 0)
2361 {
2362 if (id != RSXR_MONSTERLIST)
2363 {
2364 printf("Invalid id. %x != %x(RSXR_MONSTERLIST)\n",
2365 id,RSXR_MONSTERLIST);
2366 printf("Sorry, invalid save game format");
2367 format_error = TRUE;
2368 }
2369 else if (rs_read_int(inf,&cnt) != 0)
2370 {
2371 for (i = 0; i < cnt; i++)
2372 {
2373 l = new_item(sizeof(struct thing));
2374 l->l_prev = previous;
2375 if (previous != NULL)
2376 previous->l_next = l;
2377 rs_read_thing(inf,(struct thing *)l->l_data);
2378 if (previous == NULL)
2379 head = l;
2380 previous = l;
2381 }
2382
2383
2384 if (l != NULL)
2385 l->l_next = NULL;
2386
2387 *list = head;
2388 }
2389 }
2390 else format_error = TRUE;
2391
2392 return(READSTAT);
2393 }
2394
2395 rs_write_magic_items(FILE *savef, struct magic_item *i, int count)
2396 {
2397 int n;
2398
2399 DBG(("Magic Items\n"));
2400 rs_write_int(savef, RSXR_MAGICITEMS);
2401 rs_write_int(savef, count);
2402
2403 for(n=0;n<count;n++)
2404 {
2405 rs_write(savef,i[n].mi_name,sizeof(i[n].mi_name));
2406 rs_write_int(savef,i[n].mi_prob);
2407 rs_write_int(savef,i[n].mi_worth);
2408 rs_write_int(savef,i[n].mi_curse);
2409 rs_write_int(savef,i[n].mi_bless);
2410 }
2411
2412 return(WRITESTAT);
2413 }
2414
2415 rs_read_magic_items(int inf, struct magic_item *mi, int count)
2416 {
2417 int id;
2418 int n;
2419 int value;
2420
2421 if (rs_read_int(inf, &id) != 0)
2422 {
2423 if (id != RSXR_MAGICITEMS)
2424 {
2425 printf("Invalid id. %x != %x(RSXR_MAGICITEMS)\n",
2426 id,RSXR_MAGICITEMS);
2427 printf("Sorry, invalid save game format");
2428 format_error = TRUE;
2429 }
2430 else if (rs_read_int(inf, &value) != 0)
2431 {
2432 if (value > count)
2433 {
2434 printf("Incorrect number of magic items in block. %d > %d.",
2435 value,count);
2436 printf("Sorry, invalid save game format");
2437 format_error = TRUE;
2438 }
2439 else
2440 {
2441 for(n = 0; n < value; n++)
2442 {
2443 rs_read(inf,mi[n].mi_name,sizeof(mi[n].mi_name));
2444 rs_read_int(inf,&mi[n].mi_prob);
2445 rs_read_int(inf,&mi[n].mi_worth);
2446 rs_read_int(inf,&mi[n].mi_curse);
2447 rs_read_int(inf,&mi[n].mi_bless);
2448 }
2449 }
2450 }
2451 }
2452
2453 return(READSTAT);
2454 }
2455
2456 rs_write_window(FILE *savef, WINDOW *win)
2457 {
2458 int row,col,height,width;
2459 width = getmaxx(win);
2460 height = getmaxy(win);
2461 DBG(("Window\n"));
2462 rs_write_int(savef,height);
2463 rs_write_int(savef,width);
2464
2465 for(row=0;row<height;row++)
2466 for(col=0;col<width;col++)
2467 rs_write_int(savef, mvwinch(win,row,col));
2468 }
2469
2470 rs_read_window(int inf, WINDOW *win)
2471 {
2472 int row,col,maxlines,maxcols,value,width,height;
2473
2474 width = getmaxx(win);
2475 height = getmaxy(win);
2476
2477 rs_read_int(inf,&maxlines);
2478 rs_read_int(inf,&maxcols);
2479 if (maxlines > height)
2480 abort();
2481 if (maxcols > width)
2482 abort();
2483
2484 for(row=0;row<maxlines;row++)
2485 for(col=0;col<maxcols;col++)
2486 {
2487 rs_read_int(inf, &value);
2488 if ((value == '-') || (value == 196))
2489 value = HORZWALL;
2490 else if ((value == '|') || (value == 179))
2491 value = VERTWALL;
2492 mvwaddch(win,row,col,value);
2493 }
2494
2495 return(READSTAT);
2496 }
2497
2498 rs_save_file(FILE *savef)
2499 {
2500 int i, weapon, armor, ring, misc, room = -1;
2501 int endian = 0x01020304;
2502 big_endian = ( *((char *)&endian) == 0x01 );
2503
2504 rs_write_thing(savef, &player); /* rogue.c */
2505 rs_write_object_list(savef, lvl_obj); /* rogue.c */
2506 rs_write_monster_list(savef, mlist); /* rogue.c */
2507 rs_write_monster_list(savef, tlist); /* rogue.c */
2508
2509 rs_write_traps(savef, traps, MAXTRAPS); /* rogue.c */
2510
2511 armor = find_list_ptr(player.t_pack, cur_armor);
2512 rs_write_int(savef, armor); /* rogue.c */
2513
2514 for (i = 0; i < NUM_FINGERS; i++)
2515 {
2516 ring = find_list_ptr(player.t_pack, cur_ring[i]);
2517 rs_write_int(savef, ring); /* rogue.c */
2518 }
2519
2520 for (i = 0; i < NUM_MM; i++)
2521 {
2522 misc = find_list_ptr(player.t_pack, cur_misc[i]);
2523 rs_write_int(savef, misc); /* rogue.c */
2524 }
2525
2526 for (i=0; i<MAXRELIC; i++)
2527 rs_write_int(savef,cur_relic[i]); /* rogue.c */
2528
2529
2530 rs_write_rooms(savef, rooms, MAXROOMS); /* rogue.c */
2531
2532 for (i = 0; i < MAXROOMS; i++)
2533 if (&rooms[i] == oldrp)
2534 room = i;
2535 rs_write_int(savef, room); /* rogue.c */
2536
2537 weapon = find_list_ptr(player.t_pack, cur_weapon);
2538 rs_write_int(savef, weapon); /* rogue..c */
2539 rs_write_int(savef,char_type);
2540 rs_write_int(savef,foodlev);
2541 rs_write_int(savef,ntraps);
2542 rs_write_int(savef,trader);
2543 rs_write_int(savef,curprice);
2544 rs_write_int(savef,seed);
2545 rs_write_int(savef,max_level);
2546 rs_write_int(savef,cur_max);
2547 rs_write_int(savef,prev_max);
2548 rs_write_int(savef,move_free);
2549 rs_write_int(savef,mpos);
2550 rs_write_int(savef,level);
2551 rs_write_long(savef,purse);
2552 rs_write_int(savef,inpack);
2553 rs_write_int(savef,total);
2554 rs_write_int(savef,no_food);
2555 rs_write_int(savef,foods_this_level);
2556 rs_write_int(savef,count);
2557 rs_write_int(savef,food_left);
2558 rs_write_int(savef,group);
2559 rs_write_int(savef,hungry_state);
2560 rs_write_int(savef,infest_dam);
2561 rs_write_int(savef,lost_str);
2562 rs_write_int(savef,lastscore);
2563 rs_write_int(savef,hold_count);
2564 rs_write_int(savef,trap_tries);
2565 rs_write_int(savef,chant_time);
2566 rs_write_int(savef,pray_time);
2567 rs_write_int(savef,spell_power);
2568 rs_write_long(savef,turns);
2569 rs_write_int(savef,quest_item);
2570 rs_write_int(savef,cols);
2571 rs_write_int(savef,lines);
2572 rs_write_int(savef,nfloors);
2573 rs_write(savef,curpurch,LINELEN);
2574 rs_write_char(savef,PLAYER);
2575 rs_write_char(savef,take);
2576 rs_write_int(savef,1234);/*checkpoint*/
2577 rs_write(savef,prbuf,LINELEN*2);
2578 rs_write_int(savef,1234);/*checkpoint*/
2579 rs_write_char(savef,runch);
2580 rs_write_int(savef,1234);/*checkpoint*/
2581 rs_write_scrolls(savef);
2582 rs_write_potions(savef);
2583 rs_write_rings(savef);
2584 rs_write_sticks(savef);
2585 rs_write_misc(savef);
2586 rs_write_int(savef,1234);/*checkpoint*/
2587 rs_write(savef,whoami,LINELEN);
2588 rs_write_window(savef, cw);
2589 rs_write_window(savef, hw);
2590 rs_write_window(savef, mw);
2591 rs_write_window(savef, msgw);
2592 rs_write_window(savef, stdscr);
2593 rs_write_boolean(savef,pool_teleport);
2594 rs_write_boolean(savef,inwhgt);
2595 rs_write_boolean(savef,after);
2596 rs_write_boolean(savef,waswizard);
2597 rs_write_boolean(savef, playing); /* rogue.h/init.c */
2598 rs_write_boolean(savef, running); /* rogue.h/init.c */
2599 rs_write_boolean(savef, wizard); /* rogue.h/init.c */
2600 rs_write_boolean(savef, notify); /* rogue.h/init.c */
2601 rs_write_boolean(savef, fight_flush); /* rogue.h/init.c */
2602 rs_write_boolean(savef, terse); /* rogue.h/init.c */
2603 rs_write_boolean(savef, auto_pickup); /* rogue.h/init.c */
2604 rs_write_boolean(savef, def_attr); /* rogue.h/init.c */
2605 rs_write_boolean(savef, menu_overlay); /* rogue.h/init.c */
2606 rs_write_boolean(savef, door_stop); /* rogue.h/init.c */
2607 rs_write_boolean(savef, jump); /* rogue.h/init.c */
2608 rs_write_boolean(savef, slow_invent); /* rogue.h/init.c */
2609 rs_write_boolean(savef, firstmove); /* rogue.h/init.c */
2610 rs_write_boolean(savef, askme); /* rogue.h/init.c */
2611 rs_write_boolean(savef, in_shell); /* rogue.h/init.c */
2612 rs_write_boolean(savef, daytime); /* rogue.h/init.c */
2613 rs_write_boolean(savef, funfont); /* rogue.h/init.c */
2614 rs_write_levtype(savef,levtype);
2615 rs_write_character_types(savef,char_class,NUM_CHARTYPES);
2616 rs_write_words(savef,abilities,NUMABILITIES);
2617 for(i=0;i<9;i++)
2618 rs_write_coord(savef,&grid[i]);
2619 rs_write_death_types(savef,deaths,DEATHNUM);
2620 rs_write_init_weps(savef,weaps,MAXWEAPONS);
2621 rs_write_init_armor(savef,armors,MAXARMORS);
2622 rs_write_magic_items(savef, things, NUMTHINGS); /* rogue.h/init.c */
2623 rs_write_magic_items(savef, s_magic, MAXSCROLLS); /* rogue.h/init.c */
2624 rs_write_magic_items(savef, p_magic, MAXPOTIONS); /* rogue.h/init.c */
2625 rs_write_magic_items(savef, r_magic, MAXRINGS); /* rogue.h/init.c */
2626 rs_write_magic_items(savef, ws_magic, MAXSTICKS); /* rogue.h/init.c */
2627 rs_write_magic_items(savef, m_magic, MAXMM); /* rogue.h/init.c */
2628 rs_write_magic_items(savef, rel_magic, MAXRELIC); /* rogue.h/init.c */
2629 rs_write_magic_items(savef, foods, MAXFOODS); /* rogue.h/init.c */
2630 rs_write_spells(savef,magic_spells,MAXSPELLS);
2631 rs_write_spells(savef,cleric_spells,MAXPRAYERS);
2632 rs_write_spells(savef,druid_spells,MAXCHANTS);
2633 rs_write_spells(savef,quill_scrolls,MAXQUILL);
2634
2635 rs_write_int(savef,mf_count); /* actions.c */
2636 rs_write_int(savef,mf_jmpcnt); /* actions.c */
2637 rs_write_daemons(savef, d_list, MAXDAEMONS); /* daemon.c */
2638 rs_write_daemons(savef, f_list, MAXFUSES); /* daemon.c */
2639 rs_write_int(savef,demoncnt); /* daemon.c */
2640 rs_write_int(savef,fusecnt); /* daemon.c */
2641 rs_write_int(savef,killed_chance); /* fight.c */
2642 rs_write_words(savef,rainbow,NCOLORS); /* init.c */
2643 rs_write_words(savef,sylls,NSYLLS); /* init.c */
2644 rs_write_words(savef,stones,NSTONES); /* init.c */
2645 rs_write_words(savef,wood,NWOOD); /* init.c */
2646 rs_write_words(savef,metal,NMETAL); /* init.c */
2647 rs_write_monsters(savef,monsters,
2648 sizeof(monsters)/sizeof(struct monster)); /* mons_def.c */
2649 rs_write_coord(savef,&move_nh); /* move.c */
2650 return(WRITESTAT);
2651 }
2652
2653 rs_restore_file(int inf)
2654 {
2655 int weapon, armor, ring, misc, room = -1,i,checkpoint;
2656 int endian = 0x01020304;
2657 big_endian = ( *((char *)&endian) == 0x01 );
2658
2659 rs_read_thing(inf, &player); /* rogue.h */
2660 rs_read_object_list(inf, &lvl_obj); /* rogue.h/init.c */
2661 rs_read_monster_list(inf, &mlist); /* rogue.h/init.c */
2662 rs_read_monster_list(inf, &tlist); /* rogue.h/init.c */
2663 rs_fix_thing(&player);
2664 rs_fix_monster_list(mlist);
2665 rs_read_traps(inf, traps, MAXTRAPS);
2666
2667
2668 rs_read_int(inf, &armor); /* rogue.h */
2669 cur_armor = get_list_item(player.t_pack,armor);
2670
2671 for(i = 0; i < NUM_FINGERS; i++)
2672 {
2673 rs_read_int(inf,&ring);
2674 cur_ring[i] = get_list_item(player.t_pack,ring);
2675 }
2676
2677 for(i = 0; i < NUM_MM; i++)
2678 {
2679 rs_read_int(inf,&misc);
2680 cur_misc[i] = get_list_item(player.t_pack,misc);
2681 }
2682
2683 for(i=0;i<MAXRELIC;i++)
2684 rs_read_int(inf,&cur_relic[i]);
2685
2686 rs_read_rooms(inf, rooms, MAXROOMS);
2687 rs_read_int(inf, &room);
2688
2689 oldrp = &rooms[room];
2690
2691 rs_read_int(inf,&weapon);
2692 cur_weapon = get_list_item(player.t_pack,weapon);
2693
2694 rs_read_int(inf,&char_type);
2695 rs_read_int(inf,&foodlev);
2696 rs_read_int(inf,&ntraps);
2697 rs_read_int(inf,&trader);
2698 rs_read_int(inf,&curprice);
2699 rs_read_int(inf,&seed);
2700 rs_read_int(inf,&max_level);
2701 rs_read_int(inf,&cur_max);
2702 rs_read_int(inf,&prev_max);
2703 rs_read_int(inf,&move_free);
2704 rs_read_int(inf,&mpos);
2705 rs_read_int(inf,&level);
2706 rs_read_long(inf,&purse);
2707 rs_read_int(inf,&inpack);
2708 rs_read_int(inf,&total);
2709 rs_read_int(inf,&no_food);
2710 rs_read_int(inf,&foods_this_level);
2711 rs_read_int(inf,&count);
2712 rs_read_int(inf,&food_left);
2713 rs_read_int(inf,&group);
2714 rs_read_int(inf,&hungry_state);
2715 rs_read_int(inf,&infest_dam);
2716 rs_read_int(inf,&lost_str);
2717 rs_read_int(inf,&lastscore);
2718 rs_read_int(inf,&hold_count);
2719 rs_read_int(inf,&trap_tries);
2720 rs_read_int(inf,&chant_time);
2721 rs_read_int(inf,&pray_time);
2722 rs_read_int(inf,&spell_power);
2723 rs_read_long(inf,&turns);
2724 rs_read_int(inf,&quest_item);
2725 rs_read_int(inf,&cols);
2726 rs_read_int(inf,&lines);
2727 rs_read_int(inf,&nfloors);
2728 rs_read(inf,curpurch,LINELEN);
2729 rs_read_char(inf,&PLAYER);
2730 rs_read_char(inf,&take);
2731 rs_read_int(inf,&checkpoint);
2732 if (checkpoint != 1234){printf("Checkpoint failed");abort();}
2733 rs_read(inf,prbuf,LINELEN*2);
2734 rs_read_int(inf,&checkpoint);
2735 if (checkpoint != 1234){printf("Checkpoint failed");abort();}
2736 rs_read_char(inf,&runch);
2737 rs_read_int(inf,&checkpoint);
2738 if (checkpoint != 1234){printf("Checkpoint failed");abort();}
2739 rs_read_scrolls(inf);
2740 rs_read_potions(inf);
2741 rs_read_rings(inf);
2742 rs_read_sticks(inf);
2743 rs_read_misc(inf);
2744 rs_read_int(inf,&checkpoint);
2745 if (checkpoint != 1234){printf("Checkpoint failed");abort();}
2746 rs_read(inf,whoami,LINELEN);
2747 rs_read_window(inf, cw);
2748 rs_read_window(inf, hw);
2749 rs_read_window(inf, mw);
2750 rs_read_window(inf, msgw);
2751 rs_read_window(inf, stdscr);
2752 rs_read_boolean(inf,&pool_teleport);
2753 rs_read_boolean(inf,&inwhgt);
2754 rs_read_boolean(inf,&after);
2755 rs_read_boolean(inf,&waswizard);
2756 rs_read_boolean(inf, &playing); /* rogue.h/init.c */
2757 rs_read_boolean(inf, &running); /* rogue.h/init.c */
2758 rs_read_boolean(inf, &wizard); /* rogue.h/init.c */
2759 rs_read_boolean(inf, &notify); /* rogue.h/init.c */
2760 rs_read_boolean(inf, &fight_flush); /* rogue.h/init.c */
2761 rs_read_boolean(inf, &terse); /* rogue.h/init.c */
2762 rs_read_boolean(inf, &auto_pickup); /* rogue.h/init.c */
2763 rs_read_boolean(inf, &def_attr); /* rogue.h/init.c */
2764 rs_read_boolean(inf, &menu_overlay); /* rogue.h/init.c */
2765 rs_read_boolean(inf, &door_stop); /* rogue.h/init.c */
2766 rs_read_boolean(inf, &jump); /* rogue.h/init.c */
2767 rs_read_boolean(inf, &slow_invent); /* rogue.h/init.c */
2768 rs_read_boolean(inf, &firstmove); /* rogue.h/init.c */
2769 rs_read_boolean(inf, &askme); /* rogue.h/init.c */
2770 rs_read_boolean(inf, &in_shell); /* rogue.h/init.c */
2771 rs_read_boolean(inf, &daytime); /* rogue.h/init.c */
2772 rs_read_boolean(inf, &funfont); /* rogue.h/init.c */
2773 rs_read_levtype(inf,&levtype);
2774 rs_read_character_types(inf,char_class,NUM_CHARTYPES);
2775 rs_read_words(inf,abilities,NUMABILITIES);
2776 for(i=0;i<9;i++)
2777 rs_read_coord(inf,&grid[i]);
2778 rs_read_death_types(inf,deaths,DEATHNUM);
2779 rs_read_init_weps(inf,weaps,MAXWEAPONS);
2780 rs_read_init_armor(inf,armors,MAXARMORS);
2781 rs_read_magic_items(inf, things,NUMTHINGS); /* rogue.h/init.c */
2782 rs_read_magic_items(inf, s_magic,MAXSCROLLS); /* rogue.h/init.c */
2783 rs_read_magic_items(inf, p_magic,MAXPOTIONS); /* rogue.h/init.c */
2784 rs_read_magic_items(inf, r_magic,MAXRINGS); /* rogue.h/init.c */
2785 rs_read_magic_items(inf, ws_magic,MAXSTICKS); /* rogue.h/init.c */
2786 rs_read_magic_items(inf, m_magic,MAXMM); /* rogue.h/init.c */
2787 rs_read_magic_items(inf, rel_magic,MAXRELIC); /* rogue.h/init.c */
2788 rs_read_magic_items(inf, foods,MAXFOODS); /* rogue.h/init.c */
2789 rs_read_spells(inf,magic_spells,MAXSPELLS);
2790 rs_read_spells(inf,cleric_spells,MAXPRAYERS);
2791 rs_read_spells(inf,druid_spells,MAXCHANTS);
2792 rs_read_spells(inf,quill_scrolls,MAXQUILL);
2793
2794 rs_read_int(inf,&mf_count); /* actions.c */
2795 rs_read_int(inf,&mf_jmpcnt); /* actions.c */
2796 rs_read_daemons(inf, d_list, MAXDAEMONS); /* daemon.c */
2797 rs_read_daemons(inf, f_list, MAXFUSES); /* daemon.c */
2798 rs_read_int(inf,&demoncnt); /* daemon.c */
2799 rs_read_int(inf,&fusecnt); /* daemon.c */
2800 rs_read_int(inf,&killed_chance); /* fight.c */
2801 rs_read_words(inf,rainbow,NCOLORS); /* init.c */
2802 rs_read_words(inf,sylls,NSYLLS); /* init.c */
2803 rs_read_words(inf,stones,NSTONES); /* init.c */
2804 rs_read_words(inf,wood,NWOOD); /* init.c */
2805 rs_read_words(inf,metal,NMETAL); /* init.c */
2806
2807 rs_read_monsters(inf,monsters,
2808 sizeof(monsters)/sizeof(struct monster)); /* mons_def.c */
2809 rs_read_coord(inf,&move_nh); /* move.c */
2810
2811 return(READSTAT);
2812 }
2813
2814 rs_write_scorefile(FILE *savef, struct sc_ent *entries, int count)
2815 {
2816 int i;
2817
2818 rs_write_int(savef, count);
2819 for(i = 0; i < count; i++)
2820 {
2821 rs_write_ulong(savef, entries[i].sc_score);
2822 rs_write(savef, entries[i].sc_name, sizeof(entries[i].sc_name));
2823 rs_write(savef, entries[i].sc_system, sizeof(entries[i].sc_system));
2824 rs_write(savef, entries[i].sc_login, sizeof(entries[i].sc_login));
2825 rs_write_short(savef, entries[i].sc_flags);
2826 rs_write_short(savef, entries[i].sc_level);
2827 rs_write_short(savef, entries[i].sc_ctype);
2828 rs_write_short(savef, entries[i].sc_monster);
2829 rs_write_short(savef, entries[i].sc_quest);
2830 }
2831 }
2832
2833 rs_read_scorefile(FILE *savef, struct sc_ent *entries, int count)
2834 {
2835 int i,available = 0;
2836
2837 rs_read_int(fileno(savef), &available);
2838
2839 if (end_of_file)
2840 return(-1);
2841
2842 if (available != count)
2843 return(-2);
2844
2845 for(i = 0; i < count; i++)
2846 {
2847 rs_read_ulong(fileno(savef), &entries[i].sc_score);
2848 rs_read(fileno(savef), entries[i].sc_name, sizeof(entries[i].sc_name));
2849 rs_read(fileno(savef), entries[i].sc_system, sizeof(entries[i].sc_system));
2850 rs_read(fileno(savef), entries[i].sc_login, sizeof(entries[i].sc_login));
2851 rs_read_short(fileno(savef), &entries[i].sc_flags);
2852 rs_read_short(fileno(savef), &entries[i].sc_level);
2853 rs_read_short(fileno(savef), &entries[i].sc_ctype);
2854 rs_read_short(fileno(savef), &entries[i].sc_monster);
2855 rs_read_short(fileno(savef), &entries[i].sc_quest);
2856 }
2857
2858 return(0);
2859 }
2860
2861
2862
2863 rs_print_thing(FILE *outf, struct thing *thing, char *prefix, int list, int index)
2864 {
2865 int i;
2866
2867 fprintf(outf,"%sList Ident : %d\n", prefix, list);
2868 fprintf(outf,"%sList Index : %d\n", prefix, index);
2869 fprintf(outf,"%st_wasshot : %d\n", prefix, thing->t_wasshot);
2870 fprintf(outf,"%st_type : %c\n", prefix, thing->t_type);
2871 fprintf(outf,"%st_disguise : %c\n", prefix, thing->t_disguise);
2872 fprintf(outf,"%st_oldch : %c\n", prefix, thing->t_oldch);
2873 fprintf(outf,"%st_ctype : %d\n", prefix, thing->t_ctype);
2874 fprintf(outf,"%st_index : %d\n", prefix, thing->t_index);
2875 fprintf(outf,"%st_no_move : %d\n", prefix, thing->t_no_move);
2876 fprintf(outf,"%st_quiet : %d\n", prefix, thing->t_quiet);
2877 fprintf(outf,"%st_movement : %d\n", prefix, thing->t_movement);
2878 fprintf(outf,"%st_action : %d\n", prefix, thing->t_action);
2879 fprintf(outf,"%st_artificat: %d\n", prefix, thing->t_artifact);
2880 fprintf(outf,"%st_wand : %d\n", prefix, thing->t_wand);
2881 fprintf(outf,"%st_summon : %d\n", prefix, thing->t_summon);
2882 fprintf(outf,"%st_cast : %d\n", prefix, thing->t_cast);
2883 fprintf(outf,"%st_breathe : %d\n", prefix, thing->t_breathe);
2884 fprintf(outf,"%st_name : %s\n", prefix, (thing->t_name == NULL) ? "none" :
2885 thing->t_name);
2886 fprintf(outf,"%st_doorgoal : %d %d\n", prefix, thing->t_doorgoal.x, thing->t_doorgoal.y);
2887 fprintf(outf,"%st_dest : %p\n", prefix, thing->t_dest);
2888 fprintf(outf,"%st_pos : %d %d (%p)\n", prefix, thing->t_pos.x, thing->t_pos.y,&thing->t_pos);
2889 fprintf(outf,"%st_oldpos : %d %d\n", prefix, thing->t_oldpos.x, thing->t_oldpos.y);
2890 fprintf(outf,"%st_newpos : %d %d\n", prefix, thing->t_newpos.x, thing->t_newpos.y);
2891 fprintf(outf,"%st_flags : ", prefix);
2892
2893 for(i = 0; i<16; i++)
2894 fprintf(outf,"%X ",thing->t_flags[i]);
2895 fprintf(outf,"\n");
2896
2897 fprintf(outf,"%st_pack : %p\n",prefix,thing->t_pack);
2898 fprintf(outf,"%st_using : %p\n",prefix,thing->t_using);
2899 fprintf(outf,"%st_stats : Not Implemented\n",prefix);
2900 fprintf(outf,"%st_maxstats : Not Implemented\n",prefix);
2901 fprintf(outf,"%st_reserved : %d\n",prefix,thing->t_reserved);
2902 }
2903
2904 rs_print_game_state(FILE *outf)
2905 {
2906 fprintf(outf, "Player\n");
2907
2908 rs_print_thing(outf, &player, " ", 0, 0);
2909 }
2910
2911 /****
2912 Machine Dependent Functions
2913
2914 md_getuid()
2915 md_memused()
2916 md_getusername()
2917 md_gethostname()
2918 md_gethomedir()
2919 md_getroguedir()
2920 md_getshell()
2921 md_shellescape()
2922 md_getpass()
2923 md_crypt()
2924 md_htons()
2925 md_nstoh()
2926 md_unlink()
2927 md_isdir()
2928 md_ntohl()
2929 md_htonl()
2930
2931 ****/
2932
2933 int
2934 md_rand(range)
2935 register int range;
2936 {
2937 #ifdef _WIN32
2938 return(range <= 0 ? 0 : rand() % range);
2939 #else
2940 return(range <= 0 ? 0 : random() % range);
2941 #endif
2942 }
2943
2944 int
2945 md_srand(seed)
2946 register int seed;
2947 {
2948 #ifdef _WIN32
2949 srand(seed);
2950 #else
2951 srandom(seed);
2952 #endif
2953 }
2954
2955 void
2956 md_flushinp()
2957 {
2958 /* ioctl(0,TIOCFLUSH) */
2959 /* ioctl(_tty_ch,TCFLSH,0) */
2960 flushinp();
2961 }
2962
2963 int
2964 md_getuid()
2965 {
2966 #ifdef _WIN32
2967 return(42);
2968 #else
2969 return(getuid());
2970 #endif
2971 }
2972
2973 long
2974 md_memused()
2975 {
2976 #ifdef _WIN32
2977 MEMORYSTATUS stat;
2978
2979 GlobalMemoryStatus(&stat);
2980
2981 return((long)stat.dwTotalPageFile);
2982 #else
2983 return( (long)sbrk(0) );
2984 #endif
2985 }
2986
2987 char *
2988 md_getusername()
2989 {
2990 static char login[80];
2991 char *l = NULL;
2992 #ifdef _WIN32
2993 LPSTR mybuffer;
2994 DWORD size = UNLEN + 1;
2995 TCHAR buffer[UNLEN + 1];
2996
2997 mybuffer = buffer;
2998 GetUserName(mybuffer,&size);
2999 l = mybuffer;
3000 #endif
3001 #if !defined(_WIN32) && !defined(DJGPP)
3002 struct passwd *pw;
3003
3004 pw = getpwuid(getuid());
3005
3006 l = pw->pw_name;
3007 #endif
3008
3009 if ((l == NULL) || (*l == '\0'))
3010 if ( (l = getenv("USERNAME")) == NULL )
3011 if ( (l = getenv("LOGNAME")) == NULL )
3012 if ( (l = getenv("USER")) == NULL )
3013 l = "nobody";
3014
3015 strncpy(login,l,80);
3016 login[79] = 0;
3017
3018 return(login);
3019 }
3020
3021 char *
3022 md_gethomedir()
3023 {
3024 static char homedir[PATH_MAX];
3025 char *h = NULL;
3026 size_t len;
3027 #if defined(_WIN32)
3028 TCHAR szPath[MAX_PATH];
3029 #endif
3030 #if defined(_WIN32) || defined(DJGPP)
3031 char slash = '\\';
3032 #else
3033 char slash = '/';
3034 struct passwd *pw;
3035 pw = getpwuid(getuid());
3036
3037 h = pw->pw_dir;
3038
3039 if (strcmp(h,"/") == 0)
3040 h = NULL;
3041 #endif
3042 homedir[0] = 0;
3043
3044 #ifdef _WIN32
3045 if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath)))
3046 h = szPath;
3047 #endif
3048
3049 if ( (h == NULL) || (*h == '\0') )
3050 if ( (h = getenv("HOME")) == NULL )
3051 if ( (h = getenv("HOMEDRIVE")) == NULL)
3052 h = "";
3053 else
3054 {
3055 strncpy(homedir,h,PATH_MAX-1);
3056 homedir[PATH_MAX-1] = 0;
3057
3058 if ( (h = getenv("HOMEPATH")) == NULL)
3059 h = "";
3060 }
3061
3062
3063 len = strlen(homedir);
3064 strncat(homedir,h,PATH_MAX-len-1);
3065 len = strlen(homedir);
3066
3067 if ((len > 0) && (homedir[len-1] != slash)) {
3068 homedir[len] = slash;
3069 homedir[len+1] = 0;
3070 }
3071
3072 return(homedir);
3073 }
3074
3075 int
3076 directory_exists(char *dirname)
3077 {
3078 struct stat sb;
3079
3080 if (stat(dirname, &sb) == 0) /* path exists */
3081 return (sb.st_mode & S_IFDIR);
3082
3083 return(0);
3084 }
3085
3086 char *
3087 md_getroguedir()
3088 {
3089 static char path[1024];
3090 char *end,*home;
3091
3092 if ( (home = getenv("ROGUEHOME")) != NULL)
3093 {
3094 if (*home)
3095 {
3096 strncpy(path, home, PATH_MAX - 20);
3097
3098 end = &path[strlen(path)-1];
3099
3100
3101 while( (end >= path) && ((*end == '/') || (*end == '\\')))
3102 *end-- = '\0';
3103
3104 if (directory_exists(path))
3105 return(path);
3106 }
3107 }
3108
3109 if (directory_exists("/var/games/roguelike"))
3110 return("/var/games/roguelike");
3111 if (directory_exists("/var/lib/roguelike"))
3112 return("/var/lib/roguelike");
3113 if (directory_exists("/var/roguelike"))
3114 return("/var/roguelike");
3115 if (directory_exists("/usr/games/lib"))
3116 return("/usr/games/lib");
3117 if (directory_exists("/games/roguelik"))
3118 return("/games/roguelik");
3119
3120 return("");
3121 }
3122
3123 char *
3124 md_getshell()
3125 {
3126 static char shell[PATH_MAX];
3127 char *s = NULL;
3128 #ifdef _WIN32
3129 char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE";
3130 #elif defined(__DJGPP__)
3131 char *def = "C:\\COMMAND.COM";
3132 #else
3133 char *def = "/bin/sh";
3134 struct passwd *pw;
3135 pw = getpwuid(getuid());
3136 s = pw->pw_shell;
3137 #endif
3138 if ((s == NULL) || (*s == '\0'))
3139 if ( (s = getenv("COMSPEC")) == NULL)
3140 if ( (s = getenv("SHELL")) == NULL)
3141 if ( (s = getenv("SystemRoot")) == NULL)
3142 s = def;
3143
3144 strncpy(shell,s,PATH_MAX);
3145 shell[PATH_MAX-1] = 0;
3146
3147 return(shell);
3148 }
3149
3150 char *
3151 md_gethostname()
3152 {
3153 static char nodename[80];
3154 char *n = NULL;
3155 #if !defined(_WIN32) && !defined(__DJGPP__)
3156 struct utsname ourname;
3157
3158 if (uname(&ourname) == 0)
3159 n = ourname.nodename;
3160 #endif
3161 if ((n == NULL) || (*n == '\0'))
3162 if ( (n = getenv("COMPUTERNAME")) == NULL)
3163 if ( (n = getenv("HOSTNAME")) == NULL)
3164 n = "localhost";
3165
3166 strncpy(nodename, n, 80);
3167 nodename[79] = 0;
3168
3169 return(nodename);
3170 }
3171
3172 int
3173 md_shellescape()
3174 {
3175 #if (!defined(_WIN32) && !defined(__DJGPP__))
3176 int ret_status;
3177 int pid;
3178 #endif
3179 char *sh;
3180
3181 sh = md_getshell();
3182
3183 #if defined(_WIN32)
3184 return(_spawnl(_P_WAIT,sh,"shell",NULL,0));
3185 #elif defined(__DJGPP__)
3186 return ( spawnl(P_WAIT,sh,"shell",NULL,0) );
3187 #else
3188 while((pid = fork()) < 0)
3189 sleep(1);
3190
3191 if (pid == 0) /* Shell Process */
3192 {
3193 /*
3194 * Set back to original user, just in case
3195 */
3196 setuid(getuid());
3197 setgid(getgid());
3198 execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", 0);
3199 perror("No shelly");
3200 _exit(-1);
3201 }
3202 else /* Application */
3203 {
3204 while (wait(&ret_status) != pid)
3205 continue;
3206 }
3207
3208 return(ret_status);
3209 #endif
3210 }
3211
3212 int
3213 md_erasechar()
3214 {
3215 /*
3216 return(_tty.sg_erase);
3217 return(_tty.c_cc[VERASE]);
3218 */
3219 return(erasechar());
3220 }
3221
3222 int
3223 md_killchar()
3224 {
3225 /*
3226 return(_tty.sg_kill);
3227 return(_tty.c_cc[VKILL]);
3228 */
3229 return(killchar());
3230 }
3231
3232 long
3233 md_ntohl(netlong)
3234 long netlong;
3235 {
3236 return( ntohl(netlong) );
3237 }
3238
3239 long
3240 md_htonl(netlong)
3241 long netlong;
3242 {
3243 return(htonl(netlong));
3244 }
3245
3246 void
3247 md_init()
3248 {
3249 #ifdef __INTERIX
3250 char *term;
3251
3252 term = getenv("TERM");
3253
3254 if (term == NULL)
3255 setenv("TERM","interix");
3256 #endif
3257 #if defined(__DJGPP__) || defined(_WIN32)
3258 _fmode = _O_BINARY;
3259 #endif
3260 }
3261
3262 char *
3263 md_getpass(prompt)
3264 char *prompt;
3265 {
3266 #ifdef _WIN32
3267 static char password_buffer[9];
3268 char *p = password_buffer;
3269 int c, count = 0;
3270 int max_length = 9;
3271
3272 fflush(stdout);
3273 /* If we can't prompt, abort */
3274 if (fputs(prompt, stderr) < 0)
3275 {
3276 *p = '\0';
3277 return NULL;
3278 }
3279
3280 for(;;)
3281 {
3282 /* Get a character with no echo */
3283 c = _getch();
3284
3285 /* Exit on interrupt (^c or ^break) */
3286 if (c == '\003' || c == 0x100)
3287 exit(1);
3288
3289 /* Terminate on end of line or file (^j, ^m, ^d, ^z) */
3290 if (c == '\r' || c == '\n' || c == '\004' || c == '\032')
3291 break;
3292
3293 /* Back up on backspace */
3294 if (c == '\b')
3295 {
3296 if (count)
3297 count--;
3298 else if (p > password_buffer)
3299 p--;
3300 continue;
3301 }
3302
3303 /* Ignore DOS extended characters */
3304 if ((c & 0xff) != c)
3305 continue;
3306
3307 /* Add to password if it isn't full */
3308 if (p < password_buffer + max_length - 1)
3309 *p++ = c;
3310 else
3311 count++;
3312 }
3313 *p = '\0';
3314
3315 fputc('\n', stderr);
3316
3317 return password_buffer;
3318 #else
3319 return( (char *) getpass(prompt) );
3320 #endif
3321 }
3322
3323 #ifdef SIGTSTP
3324
3325 /*
3326 * handle stop and start signals
3327 */
3328
3329 /*UNUSED*/
3330 void
3331 tstp(a)
3332 int a;
3333 {
3334 mvcur(0, cols - 1, lines - 1, 0);
3335 fflush(stdout);
3336 kill(0, SIGTSTP);
3337 signal(SIGTSTP, tstp);
3338 crmode();
3339 noecho();
3340 clearok(curscr, TRUE);
3341 touchwin(cw);
3342 draw(cw);
3343 flushinp();
3344 }
3345 #endif
3346
3347 int
3348 md_setup()
3349 {
3350 #ifdef SIGTSTP
3351 signal(SIGTSTP, tstp);
3352 #endif
3353 #ifdef SIGHUP
3354 signal(SIGHUP, auto_save);
3355 #endif
3356 signal(SIGTERM, auto_save);
3357 signal(SIGINT, quit);
3358 #ifdef SIGQUIT
3359 signal(SIGQUIT, endit);
3360 #endif
3361 #if defined(__CYGWIN__) || defined(__MSYS__)
3362 ESCDELAY = 250;
3363 #endif
3364 crmode(); /* Cbreak mode */
3365 noecho(); /* Echo off */
3366 }