+/*\r
+ state.c - Portable Rogue Save State Code\r
+\r
+ Copyright (C) 1999, 2000, 2005, 2006 Nicholas J. Kisseberth\r
+ All rights reserved.\r
+\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions\r
+ are met:\r
+ 1. Redistributions of source code must retain the above copyright\r
+ notice, this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright\r
+ notice, this list of conditions and the following disclaimer in the\r
+ documentation and/or other materials provided with the distribution.\r
+ 3. Neither the name(s) of the author(s) nor the names of other contributors\r
+ may be used to endorse or promote products derived from this software\r
+ without specific prior written permission.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND\r
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE\r
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ SUCH DAMAGE.\r
+*/\r
+\r
+/************************************************************************/\r
+/* Save State Code */\r
+/************************************************************************/\r
+\r
+#define RSID_STATS 0xABCD0001\r
+#define RSID_THING 0xABCD0002\r
+#define RSID_THING_NULL 0xDEAD0002\r
+#define RSID_OBJECT 0xABCD0003\r
+#define RSID_MAGICITEMS 0xABCD0004\r
+#define RSID_KNOWS 0xABCD0005\r
+#define RSID_GUESSES 0xABCD0006\r
+#define RSID_OBJECTLIST 0xABCD0007\r
+#define RSID_BAGOBJECT 0xABCD0008\r
+#define RSID_MONSTERLIST 0xABCD0009\r
+#define RSID_MONSTERSTATS 0xABCD000A\r
+#define RSID_MONSTERS 0xABCD000B\r
+#define RSID_TRAP 0xABCD000C\r
+#define RSID_WINDOW 0xABCD000D\r
+#define RSID_DAEMONS 0xABCD000E\r
+#define RSID_IWEAPS 0xABCD000F\r
+#define RSID_IARMOR 0xABCD0010\r
+#define RSID_SPELLS 0xABCD0011\r
+#define RSID_ILIST 0xABCD0012\r
+#define RSID_HLIST 0xABCD0013\r
+#define RSID_DEATHTYPE 0xABCD0014\r
+#define RSID_CTYPES 0XABCD0015\r
+#define RSID_COORDLIST 0XABCD0016\r
+#define RSID_ROOMS 0XABCD0017\r
+\r
+#include <curses.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include "rogue.h"\r
+\r
+#define READSTAT (format_error || read_error )\r
+#define WRITESTAT (write_error)\r
+\r
+static int read_error = FALSE;\r
+static int write_error = FALSE;\r
+static int format_error = FALSE;\r
+static int endian = 0x01020304;\r
+#define big_endian ( *((char *)&endian) == 0x01 )\r
+\r
+int\r
+rs_write(FILE *savef, void *ptr, size_t size)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if (encwrite(ptr, size, savef) != size)\r
+ write_error = 1;\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read(int inf, void *ptr, size_t size)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ if (encread(ptr, size, inf) != size)\r
+ read_error = 1;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_char(FILE *savef, char c)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write(savef, &c, 1);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_char(int inf, char *c)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, c, 1);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_chars(FILE *savef, char *c, int count)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, count);\r
+ rs_write(savef, c, count);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_chars(int inf, char *i, int count)\r
+{\r
+ int value = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &value);\r
+ \r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ rs_read(inf, i, count);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_int(FILE *savef, int c)\r
+{\r
+ unsigned char bytes[4];\r
+ unsigned char *buf = (unsigned char *) &c;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ rs_write(savef, buf, 4);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_int(int inf, int *i)\r
+{\r
+ unsigned char bytes[4];\r
+ int input = 0;\r
+ unsigned char *buf = (unsigned char *)&input;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &input, 4);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ *i = *((int *) buf);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_ints(FILE *savef, int *c, int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, count);\r
+\r
+ for(n = 0; n < count; n++)\r
+ if( rs_write_int(savef,c[n]) != 0)\r
+ break;\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_ints(int inf, int *i, int count)\r
+{\r
+ int n, value;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_read_int(inf, &i[n]) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_boolean(FILE *savef, bool c)\r
+{\r
+ unsigned char buf = (c == 0) ? 0 : 1;\r
+ \r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write(savef, &buf, 1);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_boolean(int inf, bool *i)\r
+{\r
+ unsigned char buf = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &buf, 1);\r
+\r
+ *i = (buf != 0);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_booleans(FILE *savef, bool *c, int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, count);\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_write_boolean(savef, c[n]) != 0)\r
+ break;\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_booleans(int inf, bool *i, int count)\r
+{\r
+ int n = 0, value = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_read_boolean(inf, &i[n]) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_short(FILE *savef, short c)\r
+{\r
+ unsigned char bytes[2];\r
+ unsigned char *buf = (unsigned char *) &c;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[1] = buf[0];\r
+ bytes[0] = buf[1];\r
+ buf = bytes;\r
+ }\r
+\r
+ rs_write(savef, buf, 2);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_short(int inf, short *i)\r
+{\r
+ unsigned char bytes[2];\r
+ short input;\r
+ unsigned char *buf = (unsigned char *)&input;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &input, 2);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[1] = buf[0];\r
+ bytes[0] = buf[1];\r
+ buf = bytes;\r
+ }\r
+ \r
+ *i = *((short *) buf);\r
+\r
+ return(READSTAT);\r
+} \r
+\r
+int\r
+rs_write_shorts(FILE *savef, short *c, int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, count);\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_write_short(savef, c[n]) != 0)\r
+ break; \r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_shorts(int inf, short *i, int count)\r
+{\r
+ int n = 0, value = 0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < value; n++)\r
+ if (rs_read_short(inf, &i[n]) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_ushort(FILE *savef, unsigned short c)\r
+{\r
+ unsigned char bytes[2];\r
+ unsigned char *buf = (unsigned char *) &c;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[1] = buf[0];\r
+ bytes[0] = buf[1];\r
+ buf = bytes;\r
+ }\r
+\r
+ rs_write(savef, buf, 2);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_ushort(int inf, unsigned short *i)\r
+{\r
+ unsigned char bytes[2];\r
+ unsigned short input;\r
+ unsigned char *buf = (unsigned char *)&input;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &input, 2);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[1] = buf[0];\r
+ bytes[0] = buf[1];\r
+ buf = bytes;\r
+ }\r
+ \r
+ *i = *((unsigned short *) buf);\r
+\r
+ return(READSTAT);\r
+} \r
+\r
+int\r
+rs_write_uint(FILE *savef, unsigned int c)\r
+{\r
+ unsigned char bytes[4];\r
+ unsigned char *buf = (unsigned char *) &c;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ rs_write(savef, buf, 4);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_uint(int inf, unsigned int *i)\r
+{\r
+ unsigned char bytes[4];\r
+ int input;\r
+ unsigned char *buf = (unsigned char *)&input;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &input, 4);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ *i = *((unsigned int *) buf);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_long(FILE *savef, long c)\r
+{\r
+ int c2;\r
+ unsigned char bytes[4];\r
+ unsigned char *buf = (unsigned char *)&c;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if (sizeof(long) == 8)\r
+ {\r
+ c2 = c;\r
+ buf = (unsigned char *) &c2;\r
+ }\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ rs_write(savef, buf, 4);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_long(int inf, long *i)\r
+{\r
+ unsigned char bytes[4];\r
+ long input;\r
+ unsigned char *buf = (unsigned char *) &input;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &input, 4);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ *i = *((long *) buf);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_longs(FILE *savef, long *c, int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef,count);\r
+ \r
+ for(n = 0; n < count; n++)\r
+ rs_write_long(savef, c[n]);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_longs(int inf, long *i, int count)\r
+{\r
+ int n = 0, value = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < value; n++)\r
+ if (rs_read_long(inf, &i[n]) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_ulong(FILE *savef, unsigned long c)\r
+{\r
+ unsigned int c2;\r
+ unsigned char bytes[4];\r
+ unsigned char *buf = (unsigned char *)&c;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ if ( (sizeof(long) == 8) && (sizeof(int) == 4) )\r
+ {\r
+ c2 = c;\r
+ buf = (unsigned char *) &c2;\r
+ }\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ rs_write(savef, buf, 4);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_ulong(int inf, unsigned long *i)\r
+{\r
+ unsigned char bytes[4];\r
+ unsigned long input;\r
+ unsigned char *buf = (unsigned char *) &input;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read(inf, &input, 4);\r
+\r
+ if (big_endian)\r
+ {\r
+ bytes[3] = buf[0];\r
+ bytes[2] = buf[1];\r
+ bytes[1] = buf[2];\r
+ bytes[0] = buf[3];\r
+ buf = bytes;\r
+ }\r
+ \r
+ *i = *((unsigned long *) buf);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_ulongs(FILE *savef, unsigned long *c, int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef,count);\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_write_ulong(savef,c[n]) != 0)\r
+ break;\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_ulongs(int inf, unsigned long *i, int count)\r
+{\r
+ int n = 0, value = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_read_ulong(inf, &i[n]) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_marker(FILE *savef, int id)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, id);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int \r
+rs_read_marker(int inf, int id)\r
+{\r
+ int nid;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ if (rs_read_int(inf, &nid) == 0)\r
+ if (id != nid)\r
+ format_error = 1;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+\r
+\r
+/******************************************************************************/\r
+\r
+int\r
+rs_write_string(FILE *savef, char *s)\r
+{\r
+ int len = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ len = (s == NULL) ? 0 : (int) strlen(s) + 1;\r
+\r
+ rs_write_int(savef, len);\r
+ rs_write_chars(savef, s, len);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_string(int inf, char *s, int max)\r
+{\r
+ int len = 0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &len);\r
+\r
+ if (len > max)\r
+ format_error = TRUE;\r
+\r
+ rs_read_chars(inf, s, len);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_read_new_string(int inf, char **s)\r
+{\r
+ int len=0;\r
+ char *buf=0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &len);\r
+\r
+ if (len == 0)\r
+ buf = NULL;\r
+ else\r
+ { \r
+ buf = malloc(len);\r
+\r
+ if (buf == NULL) \r
+ read_error = TRUE;\r
+ }\r
+\r
+ rs_read_chars(inf, buf, len);\r
+\r
+ *s = buf;\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_strings(FILE *savef, char *s[], int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, count);\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_write_string(savef, s[n]) != 0)\r
+ break;\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_strings(int inf, char **s, int count, int max)\r
+{\r
+ int n = 0;\r
+ int value = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_read_string(inf, s[n], max) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_read_new_strings(int inf, char **s, int count)\r
+{\r
+ int n = 0;\r
+ int value = 0;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < count; n++)\r
+ if (rs_read_new_string(inf, &s[n]) != 0)\r
+ break;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_string_index(FILE *savef, char *master[], int max, const char *str)\r
+{\r
+ int i;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ for(i = 0; i < max; i++)\r
+ if (str == master[i])\r
+ return( rs_write_int(savef, i) );\r
+\r
+ return( rs_write_int(savef,-1) );\r
+}\r
+\r
+int\r
+rs_read_string_index(int inf, char *master[], int maxindex, char **str)\r
+{\r
+ int i;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &i);\r
+\r
+ if (i > maxindex)\r
+ format_error = TRUE;\r
+ else if (i >= 0)\r
+ *str = master[i];\r
+ else\r
+ *str = NULL;\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_str_t(FILE *savef, str_t st)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_short(savef,st.st_str);\r
+ rs_write_short(savef,st.st_add);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_str_t(int inf, str_t *st)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_short(inf,&st->st_str);\r
+ rs_read_short(inf,&st->st_add);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_coord(FILE *savef, coord c)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, c.x);\r
+ rs_write_int(savef, c.y);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_coord(int inf, coord *c)\r
+{\r
+ coord in;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&in.x);\r
+ rs_read_int(inf,&in.y);\r
+\r
+ if (READSTAT == 0) \r
+ {\r
+ c->x = in.x;\r
+ c->y = in.y;\r
+ }\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_window(FILE *savef, WINDOW *win)\r
+{\r
+ int row,col,height,width;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ width = getmaxx(win);\r
+ height = getmaxy(win);\r
+\r
+ rs_write_marker(savef,RSID_WINDOW);\r
+ rs_write_int(savef,height);\r
+ rs_write_int(savef,width);\r
+\r
+ for(row=0;row<height;row++)\r
+ for(col=0;col<width;col++)\r
+ if (rs_write_int(savef, mvwinch(win,row,col)) != 0)\r
+ return(WRITESTAT);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_window(int inf, WINDOW *win)\r
+{\r
+ int row,col,maxlines,maxcols,value,width,height;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ width = getmaxx(win);\r
+ height = getmaxy(win);\r
+\r
+ rs_read_marker(inf, RSID_WINDOW);\r
+\r
+ rs_read_int(inf, &maxlines);\r
+ rs_read_int(inf, &maxcols);\r
+\r
+ for(row = 0; row < maxlines; row++)\r
+ for(col = 0; col < maxcols; col++)\r
+ {\r
+ if (rs_read_int(inf, &value) != 0)\r
+ return(READSTAT);\r
+\r
+ if ((row < height) && (col < width))\r
+ mvwaddch(win,row,col,value);\r
+ }\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+/******************************************************************************/\r
+\r
+void *\r
+get_list_item(struct linked_list *l, int i)\r
+{\r
+ int count;\r
+\r
+ for(count = 0; l != NULL; count++, l = l->l_next)\r
+ if (count == i)\r
+ return(l->l_data);\r
+ \r
+ return(NULL);\r
+}\r
+\r
+int\r
+find_list_ptr(struct linked_list *l, void *ptr)\r
+{\r
+ int count;\r
+\r
+ for(count = 0; l != NULL; count++, l = l->l_next)\r
+ if (l->l_data == ptr)\r
+ return(count);\r
+ \r
+ return(-1);\r
+}\r
+\r
+int\r
+list_size(struct linked_list *l)\r
+{\r
+ int count;\r
+ \r
+ for(count = 0; l != NULL; count++, l = l->l_next)\r
+ if (l->l_data == NULL)\r
+ return(count);\r
+ \r
+ return(count);\r
+}\r
+\r
+/******************************************************************************/\r
+\r
+int\r
+rs_write_stats(FILE *savef, struct stats *s)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_STATS);\r
+ rs_write_str_t(savef, s->s_str);\r
+ rs_write_long(savef, s->s_exp);\r
+ rs_write_int(savef, s->s_lvl);\r
+ rs_write_int(savef, s->s_arm);\r
+ rs_write_int(savef, s->s_hpt);\r
+ rs_write_chars(savef, s->s_dmg, sizeof(s->s_dmg));\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_stats(int inf, struct stats *s)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_marker(inf, RSID_STATS);\r
+ rs_read_str_t(inf,&s->s_str);\r
+ rs_read_long(inf,&s->s_exp);\r
+ rs_read_int(inf,&s->s_lvl);\r
+ rs_read_int(inf,&s->s_arm);\r
+ rs_read_int(inf,&s->s_hpt);\r
+ rs_read_chars(inf,s->s_dmg,sizeof(s->s_dmg));\r
+ \r
+ return(READSTAT);\r
+}\r
+ \r
+int\r
+rs_write_scrolls(FILE *savef)\r
+{\r
+ int i;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ for(i = 0; i < MAXSCROLLS; i++)\r
+ {\r
+ rs_write_string(savef,s_names[i]);\r
+ rs_write_boolean(savef,s_know[i]);\r
+ rs_write_string(savef,s_guess[i]);\r
+ }\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_read_scrolls(int inf)\r
+{\r
+ int i;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ for(i = 0; i < MAXSCROLLS; i++)\r
+ {\r
+ rs_read_new_string(inf,&s_names[i]);\r
+ rs_read_boolean(inf,&s_know[i]);\r
+ rs_read_new_string(inf,&s_guess[i]);\r
+ }\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_potions(FILE *savef)\r
+{\r
+ int i;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ for(i = 0; i < MAXPOTIONS; i++)\r
+ {\r
+ rs_write_string_index(savef, rainbow, cNCOLORS, p_colors[i]);\r
+ rs_write_boolean(savef,p_know[i]);\r
+ rs_write_string(savef,p_guess[i]);\r
+ }\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_potions(int inf)\r
+{\r
+ int i;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ for(i = 0; i < MAXPOTIONS; i++)\r
+ {\r
+ rs_read_string_index(inf, rainbow, cNCOLORS, &p_colors[i]);\r
+ rs_read_boolean(inf,&p_know[i]);\r
+ rs_read_new_string(inf,&p_guess[i]);\r
+ }\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_rings(FILE *savef)\r
+{\r
+ int i;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ for(i = 0; i < MAXRINGS; i++)\r
+ {\r
+ rs_write_string_index(savef, stones, cNSTONES, r_stones[i]);\r
+ rs_write_boolean(savef,r_know[i]);\r
+ rs_write_string(savef,r_guess[i]);\r
+ }\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_rings(int inf)\r
+{\r
+ int i;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ for(i = 0; i < MAXRINGS; i++)\r
+ {\r
+ rs_read_string_index(inf, stones, cNSTONES, &r_stones[i]);\r
+ rs_read_boolean(inf,&r_know[i]);\r
+ rs_read_new_string(inf,&r_guess[i]);\r
+ }\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_sticks(FILE *savef)\r
+{\r
+ int i;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ for (i = 0; i < MAXSTICKS; i++)\r
+ {\r
+ if (strcmp(ws_type[i],"staff") == 0)\r
+ {\r
+ rs_write_int(savef,0);\r
+ rs_write_string_index(savef, wood, cNWOOD, ws_made[i]);\r
+ }\r
+ else\r
+ {\r
+ rs_write_int(savef,1);\r
+ rs_write_string_index(savef, metal, cNMETAL, ws_made[i]);\r
+ }\r
+ rs_write_boolean(savef, ws_know[i]);\r
+ rs_write_string(savef, ws_guess[i]);\r
+ }\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_sticks(int inf)\r
+{\r
+ int i = 0, list = 0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ for(i = 0; i < MAXSTICKS; i++)\r
+ { \r
+ rs_read_int(inf,&list);\r
+\r
+ if (list == 0)\r
+ {\r
+ rs_read_string_index(inf, wood, cNWOOD, &ws_made[i]);\r
+ ws_type[i] = "staff";\r
+ }\r
+ else \r
+ {\r
+ rs_read_string_index(inf, metal, cNMETAL, &ws_made[i]);\r
+ ws_type[i] = "wand";\r
+ }\r
+ rs_read_boolean(inf, &ws_know[i]);\r
+ rs_read_new_string(inf, &ws_guess[i]);\r
+ }\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)\r
+{\r
+ int i = 0;\r
+ int func = 0;\r
+ \r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_DAEMONS);\r
+ rs_write_int(savef, count);\r
+ \r
+ for(i = 0; i < count; i++)\r
+ {\r
+ if (d_list[i].d_func == rollwand)\r
+ func = 1;\r
+ else if (d_list[i].d_func == doctor)\r
+ func = 2;\r
+ else if (d_list[i].d_func == stomach)\r
+ func = 3;\r
+ else if (d_list[i].d_func == runners)\r
+ func = 4;\r
+ else if (d_list[i].d_func == swander)\r
+ func = 5;\r
+ else if (d_list[i].d_func == nohaste)\r
+ func = 6;\r
+ else if (d_list[i].d_func == unconfuse)\r
+ func = 7;\r
+ else if (d_list[i].d_func == unsee)\r
+ func = 8;\r
+ else if (d_list[i].d_func == sight)\r
+ func = 9;\r
+ else if (d_list[i].d_func == NULL)\r
+ func = 0;\r
+ else\r
+ func = -1;\r
+\r
+ rs_write_int(savef, d_list[i].d_type);\r
+ rs_write_int(savef, func);\r
+ rs_write_int(savef, d_list[i].d_arg);\r
+ rs_write_int(savef, d_list[i].d_time);\r
+ }\r
+ \r
+ return(WRITESTAT);\r
+} \r
+\r
+int\r
+rs_read_daemons(int inf, struct delayed_action *d_list, int count)\r
+{\r
+ int i = 0;\r
+ int func = 0;\r
+ int value = 0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+ \r
+ rs_read_marker(inf, RSID_DAEMONS);\r
+ rs_read_int(inf, &value);\r
+\r
+ if (value != count)\r
+ format_error = TRUE;\r
+\r
+ for(i=0; i < count; i++)\r
+ {\r
+ func = 0;\r
+ rs_read_int(inf, &d_list[i].d_type);\r
+ rs_read_int(inf, &func);\r
+ rs_read_int(inf, &d_list[i].d_arg);\r
+ rs_read_int(inf, &d_list[i].d_time);\r
+ \r
+ switch(func)\r
+ {\r
+ case 1: d_list[i].d_func = rollwand;\r
+ break;\r
+ case 2: d_list[i].d_func = doctor;\r
+ break;\r
+ case 3: d_list[i].d_func = stomach;\r
+ break;\r
+ case 4: d_list[i].d_func = runners;\r
+ break;\r
+ case 5: d_list[i].d_func = swander;\r
+ break;\r
+ case 6: d_list[i].d_func = nohaste;\r
+ break;\r
+ case 7: d_list[i].d_func = unconfuse;\r
+ break;\r
+ case 8: d_list[i].d_func = unsee;\r
+ break;\r
+ case 9: d_list[i].d_func = sight;\r
+ break;\r
+ default:d_list[i].d_func = NULL;\r
+ break;\r
+ } \r
+ }\r
+\r
+ if (d_list[i].d_func == NULL)\r
+ {\r
+ d_list[i].d_type = 0;\r
+ d_list[i].d_arg = 0;\r
+ d_list[i].d_time = 0;\r
+ }\r
+ \r
+ return(READSTAT);\r
+} \r
+\r
+int\r
+rs_write_trap(FILE *savef, struct trap *trap)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_coord(savef, trap->tr_pos);\r
+ rs_write_char(savef, trap->tr_type);\r
+ rs_write_int(savef, trap->tr_flags);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_trap(int inf, struct trap *trap)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_coord(inf,&trap->tr_pos);\r
+ rs_read_char(inf,&trap->tr_type);\r
+ rs_read_int(inf,&trap->tr_flags);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_traps(FILE *savef, struct trap t[], int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_MONSTERS);\r
+ rs_write_int(savef, count);\r
+ \r
+ for(n = 0; n < count; n++)\r
+ rs_write_trap(savef, &t[n]);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_traps(int inf, struct trap *t, int count)\r
+{\r
+ int value = 0, n = 0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_marker(inf, RSID_MONSTERS);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value > count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < value; n++)\r
+ rs_read_trap(inf,&t[n]);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_room(FILE *savef, struct room *r)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_coord(savef, r->r_pos);\r
+ rs_write_coord(savef, r->r_max);\r
+ rs_write_coord(savef, r->r_gold);\r
+ rs_write_int(savef, r->r_goldval);\r
+ rs_write_int(savef, r->r_flags);\r
+ rs_write_int(savef, r->r_nexits);\r
+ rs_write_coord(savef, r->r_exit[0]);\r
+ rs_write_coord(savef, r->r_exit[1]);\r
+ rs_write_coord(savef, r->r_exit[2]);\r
+ rs_write_coord(savef, r->r_exit[3]);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_room(int inf, struct room *r)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_coord(inf,&r->r_pos);\r
+ rs_read_coord(inf,&r->r_max);\r
+ rs_read_coord(inf,&r->r_gold);\r
+ rs_read_int(inf,&r->r_goldval);\r
+ rs_read_int(inf,&r->r_flags);\r
+ rs_read_int(inf,&r->r_nexits);\r
+ rs_read_coord(inf,&r->r_exit[0]);\r
+ rs_read_coord(inf,&r->r_exit[1]);\r
+ rs_read_coord(inf,&r->r_exit[2]);\r
+ rs_read_coord(inf,&r->r_exit[3]);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_rooms(FILE *savef, struct room r[], int count)\r
+{\r
+ int n = 0;\r
+\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_int(savef, count);\r
+ \r
+ for(n = 0; n < count; n++)\r
+ rs_write_room(savef, &r[n]);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_rooms(int inf, struct room *r, int count)\r
+{\r
+ int value = 0, n = 0;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf,&value);\r
+\r
+ if (value > count)\r
+ format_error = TRUE;\r
+\r
+ for(n = 0; n < value; n++)\r
+ rs_read_room(inf,&r[n]);\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_room_reference(FILE *savef, struct room *rp)\r
+{\r
+ int i, room = -1;\r
+ \r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ for (i = 0; i < MAXROOMS; i++)\r
+ if (&rooms[i] == rp)\r
+ room = i;\r
+\r
+ rs_write_int(savef, room);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_room_reference(int inf, struct room **rp)\r
+{\r
+ int i;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &i);\r
+\r
+ *rp = &rooms[i];\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_object(FILE *savef, struct object *o)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_OBJECT);\r
+ rs_write_int(savef, o->o_type);\r
+ rs_write_coord(savef, o->o_pos);\r
+ rs_write_char(savef, o->o_launch);\r
+ rs_write_chars(savef, o->o_damage, sizeof(o->o_damage));\r
+ rs_write_chars(savef, o->o_hurldmg, sizeof(o->o_damage));\r
+ rs_write_int(savef, o->o_count);\r
+ rs_write_int(savef, o->o_which);\r
+ rs_write_int(savef, o->o_hplus);\r
+ rs_write_int(savef, o->o_dplus);\r
+ rs_write_int(savef, o->o_ac);\r
+ rs_write_int(savef, o->o_flags);\r
+ rs_write_int(savef, o->o_group);\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_object(int inf, struct object *o)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_marker(inf, RSID_OBJECT);\r
+ rs_read_int(inf, &o->o_type);\r
+ rs_read_coord(inf, &o->o_pos);\r
+ rs_read_char(inf, &o->o_launch);\r
+ rs_read_chars(inf, o->o_damage, sizeof(o->o_damage));\r
+ rs_read_chars(inf, o->o_hurldmg, sizeof(o->o_hurldmg));\r
+ rs_read_int(inf, &o->o_count);\r
+ rs_read_int(inf, &o->o_which);\r
+ rs_read_int(inf, &o->o_hplus);\r
+ rs_read_int(inf, &o->o_hplus);\r
+ rs_read_int(inf,&o->o_ac);\r
+ rs_read_int(inf,&o->o_flags);\r
+ rs_read_int(inf,&o->o_group);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_object_list(FILE *savef, struct linked_list *l)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_OBJECTLIST);\r
+ rs_write_int(savef, list_size(l));\r
+\r
+ for( ;l != NULL; l = l->l_next) \r
+ rs_write_object(savef, (struct object *) l->l_data);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_object_list(int inf, struct linked_list **list)\r
+{\r
+ int i, cnt;\r
+ struct linked_list *l = NULL, *previous = NULL, *head = NULL;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_marker(inf, RSID_OBJECTLIST);\r
+ rs_read_int(inf, &cnt);\r
+\r
+ for (i = 0; i < cnt; i++) \r
+ {\r
+ l = new_item(sizeof(struct object));\r
+\r
+ memset(l->l_data,0,sizeof(struct object));\r
+\r
+ l->l_prev = previous;\r
+\r
+ if (previous != NULL)\r
+ previous->l_next = l;\r
+\r
+ rs_read_object(inf,(struct object *) l->l_data);\r
+\r
+ if (previous == NULL)\r
+ head = l;\r
+\r
+ previous = l;\r
+ }\r
+ \r
+ if (l != NULL)\r
+ l->l_next = NULL;\r
+ \r
+ *list = head;\r
+\r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_write_object_reference(FILE *savef, struct linked_list *list, \r
+ struct object *item)\r
+{\r
+ int i;\r
+ \r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ i = find_list_ptr(list, item);\r
+\r
+ rs_write_int(savef, i);\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_object_reference(int inf, struct linked_list *list, \r
+ struct object **item)\r
+{\r
+ int i;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_int(inf, &i);\r
+\r
+ *item = get_list_item(list,i);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+find_room_coord(struct room *rmlist, coord *c, int n)\r
+{\r
+ int i = 0;\r
+ \r
+ for(i = 0; i < n; i++)\r
+ if(&rmlist[i].r_gold == c)\r
+ return(i);\r
+ \r
+ return(-1);\r
+}\r
+\r
+int\r
+find_thing_coord(struct linked_list *monlist, coord *c)\r
+{\r
+ struct linked_list *mitem;\r
+ struct thing *tp;\r
+ int i = 0;\r
+\r
+ for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)\r
+ {\r
+ tp = THINGPTR(mitem);\r
+\r
+ if (c == &tp->t_pos)\r
+ return(i);\r
+\r
+ i++;\r
+ }\r
+\r
+ return(-1);\r
+}\r
+\r
+int\r
+find_object_coord(struct linked_list *objlist, coord *c)\r
+{\r
+ struct linked_list *oitem;\r
+ struct object *obj;\r
+ int i = 0;\r
+\r
+ for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)\r
+ {\r
+ obj = OBJPTR(oitem);\r
+\r
+ if (c == &obj->o_pos)\r
+ return(i);\r
+\r
+ i++;\r
+ }\r
+\r
+ return(-1);\r
+}\r
+\r
+int\r
+rs_write_thing(FILE *savef, struct thing *t)\r
+{\r
+ int i = -1;\r
+ \r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_THING);\r
+\r
+ if (t == NULL)\r
+ {\r
+ rs_write_int(savef, 0);\r
+ return(WRITESTAT);\r
+ }\r
+\r
+ rs_write_int(savef, 1);\r
+ rs_write_coord(savef, t->t_pos);\r
+ rs_write_boolean(savef, t->t_turn);\r
+ rs_write_char(savef, t->t_type);\r
+ rs_write_char(savef, t->t_disguise);\r
+ rs_write_char(savef, t->t_oldch);\r
+\r
+ /* \r
+ t_dest can be:\r
+ 0,0: NULL\r
+ 0,1: location of hero\r
+ 1,i: location of a thing (monster)\r
+ 2,i: location of an object\r
+ 3,i: location of gold in a room\r
+\r
+ We need to remember what we are chasing rather than \r
+ the current location of what we are chasing.\r
+ */\r
+\r
+ if (t->t_dest == &hero)\r
+ {\r
+ rs_write_int(savef,0);\r
+ rs_write_int(savef,1);\r
+ }\r
+ else if (t->t_dest != NULL)\r
+ {\r
+ i = find_thing_coord(mlist, t->t_dest);\r
+ \r
+ if (i >=0 )\r
+ {\r
+ rs_write_int(savef,1);\r
+ rs_write_int(savef,i);\r
+ }\r
+ else\r
+ {\r
+ i = find_object_coord(lvl_obj, t->t_dest);\r
+ \r
+ if (i >= 0)\r
+ {\r
+ rs_write_int(savef,2);\r
+ rs_write_int(savef,i);\r
+ }\r
+ else\r
+ {\r
+ i = find_room_coord(rooms, t->t_dest, MAXROOMS);\r
+ \r
+ if (i >= 0) \r
+ {\r
+ rs_write_int(savef,3);\r
+ rs_write_int(savef,i);\r
+ }\r
+ else \r
+ {\r
+ rs_write_int(savef, 0);\r
+ rs_write_int(savef,1); /* chase the hero anyway */\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ rs_write_int(savef,0);\r
+ rs_write_int(savef,0);\r
+ }\r
+ \r
+ rs_write_short(savef, t->t_flags);\r
+ rs_write_stats(savef, &t->t_stats);\r
+ rs_write_object_list(savef, t->t_pack);\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_thing(int inf, struct thing *t)\r
+{\r
+ int listid = 0, index = -1;\r
+ struct linked_list *item;\r
+ \r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_marker(inf, RSID_THING);\r
+\r
+ rs_read_int(inf, &index);\r
+\r
+ if (index == 0)\r
+ return(READSTAT);\r
+\r
+ rs_read_coord(inf,&t->t_pos);\r
+ rs_read_boolean(inf,&t->t_turn);\r
+ rs_read_char(inf,&t->t_type);\r
+ rs_read_char(inf,&t->t_disguise);\r
+ rs_read_char(inf,&t->t_oldch);\r
+\r
+ /* \r
+ t_dest can be (listid,index):\r
+ 0,0: NULL\r
+ 0,1: location of hero\r
+ 1,i: location of a thing (monster)\r
+ 2,i: location of an object\r
+ 3,i: location of gold in a room\r
+\r
+ We need to remember what we are chasing rather than \r
+ the current location of what we are chasing.\r
+ */\r
+ \r
+ rs_read_int(inf, &listid);\r
+ rs_read_int(inf, &index);\r
+ t->t_reserved = -1;\r
+\r
+ if (listid == 0) /* hero or NULL */\r
+ {\r
+ if (index == 1)\r
+ t->t_dest = &hero;\r
+ else\r
+ t->t_dest = NULL;\r
+ }\r
+ else if (listid == 1) /* monster/thing */\r
+ {\r
+ t->t_dest = NULL;\r
+ t->t_reserved = index;\r
+ }\r
+ else if (listid == 2) /* object */\r
+ {\r
+ struct object *obj;\r
+\r
+ item = get_list_item(lvl_obj,index);\r
+\r
+ if (item != NULL)\r
+ {\r
+ obj = OBJPTR(item);\r
+ t->t_dest = &obj->o_pos; \r
+ }\r
+ }\r
+ else if (listid == 3) /* gold */\r
+ {\r
+ t->t_dest = &rooms[index].r_gold;\r
+ }\r
+ else\r
+ t->t_dest = NULL;\r
+ \r
+ rs_read_short(inf,&t->t_flags);\r
+ rs_read_stats(inf,&t->t_stats);\r
+ rs_read_object_list(inf,&t->t_pack);\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_fix_thing(struct thing *t)\r
+{\r
+ struct linked_list *item;\r
+ struct thing *tp;\r
+\r
+ if (t->t_reserved < 0)\r
+ return;\r
+\r
+ item = get_list_item(mlist,t->t_reserved);\r
+\r
+ if (item != NULL)\r
+ {\r
+ tp = THINGPTR(item);\r
+ t->t_dest = &tp->t_pos;\r
+ }\r
+}\r
+\r
+int\r
+rs_write_thing_list(FILE *savef, struct linked_list *l)\r
+{\r
+ int cnt = 0;\r
+ \r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_marker(savef, RSID_MONSTERLIST);\r
+\r
+ cnt = list_size(l);\r
+\r
+ rs_write_int(savef, cnt);\r
+\r
+ if (cnt < 1)\r
+ return(WRITESTAT);\r
+\r
+ while (l != NULL) {\r
+ rs_write_thing(savef, (struct thing *)l->l_data);\r
+ l = l->l_next;\r
+ }\r
+ \r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_read_thing_list(int inf, struct linked_list **list)\r
+{\r
+ int i, cnt;\r
+ struct linked_list *l = NULL, *previous = NULL, *head = NULL;\r
+\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_marker(inf, RSID_MONSTERLIST);\r
+\r
+ rs_read_int(inf, &cnt);\r
+\r
+ for (i = 0; i < cnt; i++) \r
+ {\r
+ l = new_item(sizeof(struct thing));\r
+\r
+ l->l_prev = previous;\r
+ \r
+ if (previous != NULL)\r
+ previous->l_next = l;\r
+\r
+ rs_read_thing(inf,(struct thing *)l->l_data);\r
+\r
+ if (previous == NULL)\r
+ head = l;\r
+\r
+ previous = l;\r
+ }\r
+ \r
+ if (l != NULL)\r
+ l->l_next = NULL;\r
+\r
+ *list = head;\r
+ \r
+ return(READSTAT);\r
+}\r
+\r
+int\r
+rs_fix_thing_list(struct linked_list *list)\r
+{\r
+ struct linked_list *item;\r
+\r
+ for(item = list; item != NULL; item = item->l_next)\r
+ rs_fix_thing(THINGPTR(item));\r
+}\r
+\r
+int\r
+rs_fix_magic_items(struct magic_item *mi, int count)\r
+{\r
+ int i;\r
+\r
+ for (i = 0; i < count; i++)\r
+ if (i > 0)\r
+ mi[i].mi_prob += mi[i-1].mi_prob;\r
+}\r
+\r
+int\r
+rs_fix_monsters(struct monster monsters[26])\r
+{\r
+ sprintf(monsters['F'-'A'].m_stats.s_dmg,"%dd1",fung_hit);\r
+}\r
+\r
+int\r
+rs_save_file(FILE *savef)\r
+{\r
+ if (write_error)\r
+ return(WRITESTAT);\r
+\r
+ rs_write_thing(savef, &player); \r
+ rs_write_object_list(savef, lvl_obj); \r
+ rs_write_thing_list(savef, mlist); \r
+ rs_write_traps(savef, traps, MAXTRAPS); \r
+ rs_write_rooms(savef, rooms, MAXROOMS); \r
+ rs_write_room_reference(savef, oldrp); \r
+ rs_write_stats(savef,&max_stats); \r
+ rs_write_object_reference(savef, player.t_pack, cur_weapon); \r
+ rs_write_object_reference(savef, player.t_pack, cur_armor);\r
+ rs_write_object_reference(savef, player.t_pack, cur_ring[0]);\r
+ rs_write_object_reference(savef, player.t_pack, cur_ring[1]);\r
+ rs_write_int(savef, level); \r
+ rs_write_int(savef, purse); \r
+ rs_write_int(savef, mpos); \r
+ rs_write_int(savef, ntraps); \r
+ rs_write_int(savef, no_move); \r
+ rs_write_int(savef, no_command); \r
+ rs_write_int(savef, inpack); \r
+ rs_write_int(savef, max_hp); \r
+ rs_write_int(savef, total); \r
+ rs_write_int(savef, lastscore); \r
+ rs_write_int(savef, no_food); \r
+ rs_write_int(savef, seed); \r
+ rs_write_int(savef, count); \r
+ rs_write_int(savef, dnum); \r
+ rs_write_int(savef, fung_hit); \r
+ rs_write_int(savef, quiet); \r
+ rs_write_int(savef, max_level); \r
+ rs_write_int(savef, food_left); \r
+ rs_write_int(savef, group); \r
+ rs_write_int(savef, hungry_state); \r
+ rs_write_char(savef, take);\r
+ rs_write_char(savef, runch);\r
+ rs_write_scrolls(savef);\r
+ rs_write_potions(savef);\r
+ rs_write_rings(savef);\r
+ rs_write_sticks(savef);\r
+ rs_write_chars(savef,whoami,80);\r
+ rs_write_chars(savef,fruit,80);\r
+ rs_write_window(savef, cw);\r
+ rs_write_window(savef, mw);\r
+ rs_write_window(savef, stdscr);\r
+ rs_write_boolean(savef, running); \r
+ rs_write_boolean(savef, playing); \r
+ rs_write_boolean(savef, wizard); \r
+ rs_write_boolean(savef, after);\r
+ rs_write_boolean(savef, notify); \r
+ rs_write_boolean(savef, fight_flush); \r
+ rs_write_boolean(savef, terse); \r
+ rs_write_boolean(savef, door_stop); \r
+ rs_write_boolean(savef, jump); \r
+ rs_write_boolean(savef, slow_invent); \r
+ rs_write_boolean(savef, firstmove); \r
+ rs_write_boolean(savef, waswizard); \r
+ rs_write_boolean(savef, askme); \r
+ rs_write_boolean(savef, amulet); \r
+ rs_write_boolean(savef, in_shell); \r
+ rs_write_coord(savef, oldpos); \r
+ rs_write_coord(savef, delta); \r
+ rs_write_coord(savef, ch_ret); /* chase.c */\r
+ rs_write_daemons(savef, &d_list[0], 20); /* daemon.c */\r
+ rs_write_int(savef,between); /* daemons.c */\r
+ rs_write_int(savef,num_checks); /* main.c */\r
+ rs_write_chars(savef,lvl_mons,sizeof(lvl_mons)); /* monsters.c */\r
+ rs_write_chars(savef,wand_mons,sizeof(wand_mons)); /* monsters.c */\r
+\r
+ return(WRITESTAT);\r
+}\r
+\r
+int\r
+rs_restore_file(int inf)\r
+{\r
+ if (read_error || format_error)\r
+ return(READSTAT);\r
+\r
+ rs_read_thing(inf, &player); \r
+ rs_read_object_list(inf, &lvl_obj); \r
+ rs_read_thing_list(inf, &mlist); \r
+ rs_fix_thing(&player);\r
+ rs_fix_thing_list(mlist);\r
+ rs_read_traps(inf, traps, MAXTRAPS);\r
+ rs_read_rooms(inf, rooms, MAXROOMS);\r
+ rs_read_room_reference(inf, &oldrp);\r
+ rs_read_stats(inf,&max_stats); \r
+ rs_read_object_reference(inf, player.t_pack, &cur_weapon);\r
+ rs_read_object_reference(inf, player.t_pack, &cur_armor);\r
+ rs_read_object_reference(inf, player.t_pack, &cur_ring[0]);\r
+ rs_read_object_reference(inf, player.t_pack, &cur_ring[1]);\r
+ rs_fix_magic_items(things,NUMTHINGS); \r
+ rs_fix_magic_items(s_magic,MAXSCROLLS); \r
+ rs_fix_magic_items(p_magic,MAXPOTIONS); \r
+ rs_fix_magic_items(r_magic,MAXRINGS); \r
+ rs_fix_magic_items(ws_magic,MAXSTICKS); \r
+ rs_read_int(inf, &level); \r
+ rs_read_int(inf, &purse); \r
+ rs_read_int(inf, &mpos); \r
+ rs_read_int(inf, &ntraps); \r
+ rs_read_int(inf, &no_move); \r
+ rs_read_int(inf, &no_command); \r
+ rs_read_int(inf, &inpack); \r
+ rs_read_int(inf, &max_hp); \r
+ rs_read_int(inf, &total); \r
+ rs_read_int(inf, &lastscore); \r
+ rs_read_int(inf, &no_food); \r
+ rs_read_int(inf, &seed); \r
+ rs_read_int(inf, &count); \r
+ rs_read_int(inf, &dnum); \r
+ rs_read_int(inf, &fung_hit); \r
+ rs_read_int(inf, &quiet); \r
+ rs_read_int(inf, &max_level); \r
+ rs_read_int(inf, &food_left); \r
+ rs_read_int(inf, &group); \r
+ rs_read_int(inf, &hungry_state); \r
+ rs_read_char(inf, &take);\r
+ rs_read_char(inf, &runch);\r
+ rs_read_scrolls(inf);\r
+ rs_read_potions(inf);\r
+ rs_read_rings(inf);\r
+ rs_read_sticks(inf);\r
+ rs_read_chars(inf,whoami,80);\r
+ rs_read_chars(inf,fruit,80);\r
+ rs_read_window(inf, cw);\r
+ rs_read_window(inf, mw);\r
+ rs_read_window(inf, stdscr);\r
+ rs_read_boolean(inf, &running); \r
+ rs_read_boolean(inf, &playing); \r
+ rs_read_boolean(inf, &wizard); \r
+ rs_read_boolean(inf, &after);\r
+ rs_read_boolean(inf, ¬ify); \r
+ rs_read_boolean(inf, &fight_flush); \r
+ rs_read_boolean(inf, &terse); \r
+ rs_read_boolean(inf, &door_stop); \r
+ rs_read_boolean(inf, &jump); \r
+ rs_read_boolean(inf, &slow_invent); \r
+ rs_read_boolean(inf, &firstmove); \r
+ rs_read_boolean(inf, &waswizard); \r
+ rs_read_boolean(inf, &askme); \r
+ rs_read_boolean(inf, &amulet); \r
+ rs_read_boolean(inf, &in_shell); \r
+ rs_read_coord(inf,&oldpos); \r
+ rs_read_coord(inf,&delta); \r
+ rs_read_coord(inf, &ch_ret); /* chase.c */\r
+ rs_read_daemons(inf, d_list, 20); /* daemon.c */\r
+ rs_read_int(inf,&between); /* daemons.c */\r
+ rs_read_int(inf,&num_checks); /* main.c */\r
+ rs_read_chars(inf, lvl_mons, sizeof(lvl_mons)); /* monsters.c */\r
+ rs_read_chars(inf, wand_mons, sizeof(wand_mons)); /* monsters.c */\r
+ rs_fix_monsters(monsters); \r
+ return(READSTAT);\r
+}\r