diff srogue/state.c @ 36:2128c7dc8a40

Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 25 Nov 2010 12:21:41 +0000
parents
children 3aa87373c908
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srogue/state.c	Thu Nov 25 12:21:41 2010 +0000
@@ -0,0 +1,2320 @@
+/*
+    state.c - Portable Rogue Save State Code
+
+    Copyright (C) 1999, 2000, 2005 Nicholas J. Kisseberth
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name(s) of the author(s) nor the names of other contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+/************************************************************************/
+/* Save State Code                                                      */
+/************************************************************************/
+
+#define RSID_STATS        0xABCD0001
+#define RSID_THING        0xABCD0002
+#define RSID_THING_NULL   0xDEAD0002
+#define RSID_OBJECT       0xABCD0003
+#define RSID_MAGICITEMS   0xABCD0004
+#define RSID_KNOWS        0xABCD0005
+#define RSID_GUESSES      0xABCD0006
+#define RSID_OBJECTLIST   0xABCD0007
+#define RSID_BAGOBJECT    0xABCD0008
+#define RSID_MONSTERLIST  0xABCD0009
+#define RSID_MONSTERSTATS 0xABCD000A
+#define RSID_MONSTERS     0xABCD000B
+#define RSID_TRAP         0xABCD000C
+#define RSID_WINDOW       0xABCD000D
+#define RSID_DAEMONS      0xABCD000E
+#define RSID_IWEAPS       0xABCD000F
+#define RSID_IARMOR       0xABCD0010
+#define RSID_SPELLS       0xABCD0011
+#define RSID_ILIST        0xABCD0012
+#define RSID_HLIST        0xABCD0013
+#define RSID_DEATHTYPE    0xABCD0014
+#define RSID_CTYPES       0XABCD0015
+#define RSID_COORDLIST    0XABCD0016
+#define RSID_ROOMS        0XABCD0017
+
+
+#include <curses.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "rogue.h"
+#include "rogue.ext"
+
+#define READSTAT ((format_error == 0) && (read_error == 0))
+#define WRITESTAT (write_error == 0)
+
+int read_error   = FALSE;
+int write_error  = FALSE;
+int format_error = FALSE;
+int end_of_file  = FALSE;
+int big_endian   = 0;
+const char *fmterr = "";
+
+char encstr[] = "\354\251\243\332A\201|\301\321p\210\251\327\"\257\365t\341%3\271^`~\203z{\341};\f\341\231\222e\234\351]\321";
+
+/*
+ * perform an encrypted write
+ */
+encwrite(starta, size, outf)
+register void *starta;
+unsigned int size;
+register FILE *outf;
+{
+    register char *ep;
+    register char *start = starta;
+
+    ep = encstr;
+
+    while (size--)
+    {
+        putc(*start++ ^ *ep++, outf);
+        if (*ep == '\0')
+            ep = encstr;
+    }
+}
+
+/*
+ * perform an encrypted read
+ */
+encread(starta, size, inf)
+register void *starta;
+unsigned int size;
+register int inf;
+{
+    register char *ep;
+    register int read_size;
+    register char *start = starta;
+
+    if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
+        return read_size;
+
+    ep = encstr;
+
+    while (size--)
+    {
+        *start++ ^= *ep++;
+        if (*ep == '\0')
+            ep = encstr;
+    }
+    return read_size;
+}
+
+void *
+get_list_item(struct linked_list *l, int i)
+{
+    int count = 0;
+
+    while(l != NULL)
+    {   
+        if (count == i)
+            return(l->l_data);
+                        
+        l = l->l_next;
+        
+        count++;
+    }
+    
+    return(NULL);
+}
+
+int
+find_list_ptr(struct linked_list *l, void *ptr)
+{
+    int count = 0;
+
+    while(l != NULL)
+    {
+        if (l->l_data == ptr)
+            return(count);
+            
+        l = l->l_next;
+        count++;
+    }
+    
+    return(-1);
+}
+
+int
+list_size(struct linked_list *l)
+{
+    int count = 0;
+    
+    while(l != NULL)
+    {
+        if (l->l_data == NULL)
+            return(count);
+            
+        count++;
+        
+        l = l->l_next;
+    }
+    
+    return(count);
+}
+
+int
+rs_write(FILE *savef, void *ptr, int size)
+{
+    if (!write_error)
+        encwrite(ptr,size,savef);
+
+    if (0)
+        write_error = TRUE;
+        
+    assert(write_error == 0);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_char(FILE *savef, char c)
+{
+    rs_write(savef, &c, 1);
+    
+    return(WRITESTAT);
+}
+
+int
+rs_write_boolean(FILE *savef, bool c)
+{
+    unsigned char buf = (c == 0) ? 0 : 1;
+    
+    rs_write(savef, &buf, 1);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_booleans(FILE *savef, bool *c, int count)
+{
+    int n = 0;
+
+    rs_write_int(savef,count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_boolean(savef,c[n]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_shint(FILE *savef, unsigned char c)
+{
+    unsigned char buf = c;
+
+    rs_write(savef, &buf, 1);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_short(FILE *savef, short c)
+{
+    unsigned char bytes[2];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+
+    rs_write(savef, buf, 2);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_shorts(FILE *savef, short *c, int count)
+{
+    int n = 0;
+
+    rs_write_int(savef,count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_short(savef,c[n]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_ushort(FILE *savef, unsigned short c)
+{
+    unsigned char bytes[2];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+
+    rs_write(savef, buf, 2);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_int(FILE *savef, int c)
+{
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_ints(FILE *savef, int *c, int count)
+{
+    int n = 0;
+
+    rs_write_int(savef,count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_int(savef,c[n]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_uint(FILE *savef, unsigned int c)
+{
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_long(FILE *savef, long c)
+{
+    int c2;
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *)&c;
+
+    if (sizeof(long) == 8)
+    {
+        c2 = c;
+        buf = (unsigned char *) &c2;
+    }
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_longs(FILE *savef, long *c, int count)
+{
+    int n = 0;
+
+    rs_write_int(savef,count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_long(savef,c[n]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_ulong(FILE *savef, unsigned long c)
+{
+    unsigned int c2;
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *)&c;
+
+    if ( (sizeof(long) == 8) && (sizeof(int) == 4) )
+    {
+        c2 = c;
+        buf = (unsigned char *) &c2;
+    }
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_ulongs(FILE *savef, unsigned long *c, int count)
+{
+    int n = 0;
+
+    rs_write_int(savef,count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_ulong(savef,c[n]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_string(FILE *savef, char *s)
+{
+    int len = 0;
+
+    len = (s == NULL) ? 0 : strlen(s) + 1;
+
+    rs_write_int(savef, len);
+    rs_write(savef, s, len);
+            
+    return(WRITESTAT);
+}
+
+int
+rs_write_string_index(FILE *savef, char *master[], int max, char *str)
+{
+    int i;
+
+    for(i = 0; i < max; i++)
+    {
+        if (str == master[i])
+        {
+            rs_write_int(savef,i);
+            return(WRITESTAT);
+        }
+    }
+
+    rs_write_int(savef,-1);
+
+    return(WRITESTAT);
+}
+
+int
+rs_write_strings(FILE *savef, char *s[], int count)
+{
+    int len = 0;
+    int n = 0;
+
+    rs_write_int(savef,count);
+
+    for(n = 0; n < count; n++)
+    {
+        len = (s[n] == NULL) ? 0L : strlen(s[n]) + 1;
+        rs_write_int(savef, len);
+        rs_write(savef, s[n], len);
+    }
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read(int inf, void *ptr, int size)
+{
+    int actual;
+
+    end_of_file = FALSE;
+
+    if (!read_error && !format_error)
+    {
+        actual = encread(ptr, size, inf);
+
+        if ((actual == 0) && (size != 0))
+           end_of_file = TRUE;
+    }
+       
+    if (read_error)
+    {
+        printf("read error has occurred. restore short-circuited.\n");
+        abort();
+    }
+
+    if (format_error)
+    {
+        printf("format error: %s\r\n", fmterr);
+        printf("game format invalid. restore short-circuited.\n");
+        abort();
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_read_char(int inf, char *c)
+{
+    rs_read(inf, c, 1);
+    
+    return(READSTAT);
+}
+
+int
+rs_read_boolean(int inf, bool *i)
+{
+    unsigned char buf;
+    
+    rs_read(inf, &buf, 1);
+    
+    *i = (bool) buf;
+    
+    return(READSTAT);
+}
+
+int
+rs_read_booleans(int inf, bool *i, int count)
+{
+    int n = 0, value = 0;
+    
+    if (rs_read_int(inf,&value) != 0)
+    {
+        if (value != count)
+        {
+            printf("Invalid booleans block. %d != requested %d\n",value,count); 
+            format_error = TRUE;
+        }
+        else
+        {
+            for(n = 0; n < value; n++)
+                rs_read_boolean(inf, &i[n]);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_read_shint(int inf, unsigned char *i)
+{
+    unsigned char buf;
+    
+    rs_read(inf, &buf, 1);
+    
+    *i = (unsigned char) buf;
+    
+    return(READSTAT);
+}
+
+int
+rs_read_short(int inf, short *i)
+{
+    unsigned char bytes[2];
+    short  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    rs_read(inf, &input, 2);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+    
+    *i = *((short *) buf);
+
+    return(READSTAT);
+} 
+
+int
+rs_read_shorts(int inf, short *i, int count)
+{
+    int n = 0, value = 0;
+
+    if (rs_read_int(inf,&value) != 0)
+    {
+        if (value != count)
+            format_error = TRUE;
+        else
+        {
+            for(n = 0; n < value; n++)
+                rs_read_short(inf, &i[n]);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_read_ushort(int inf, unsigned short *i)
+{
+    unsigned char bytes[2];
+    unsigned short  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    rs_read(inf, &input, 2);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+    
+    *i = *((unsigned short *) buf);
+
+    return(READSTAT);
+} 
+
+int
+rs_read_int(int inf, int *i)
+{
+    unsigned char bytes[4];
+    int  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((int *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_read_ints(int inf, int *i, int count)
+{
+    int n = 0, value = 0;
+    
+    if (rs_read_int(inf,&value) != 0)
+    {
+        if (value != count)
+            format_error = TRUE;
+        else
+        {
+            for(n = 0; n < value; n++)
+                rs_read_int(inf, &i[n]);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_read_uint(int inf, unsigned int *i)
+{
+    unsigned char bytes[4];
+    int  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((unsigned int *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_read_long(int inf, long *i)
+{
+    unsigned char bytes[4];
+    long input;
+    unsigned char *buf = (unsigned char *) &input;
+    
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((long *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_read_longs(int inf, long *i, int count)
+{
+    int n = 0, value = 0;
+    
+    if (rs_read_int(inf,&value) != 0)
+    {
+        if (value != count)
+            format_error = TRUE;
+        else
+        {
+            for(n = 0; n < value; n++)
+                rs_read_long(inf, &i[n]);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_read_ulong(int inf, unsigned long *i)
+{
+    unsigned char bytes[4];
+    unsigned long input;
+    unsigned char *buf = (unsigned char *) &input;