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