diff xrogue/state.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children cfa9d1609b78
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xrogue/state.c	Tue Apr 21 08:55:20 2015 -0400
@@ -0,0 +1,3366 @@
+/*
+    state.c - Portable Rogue Save State Code
+    
+    Copyright (C) 2000 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.
+*/
+
+#define RSXR_STATS        0xABCD0001
+#define RSXR_THING        0xABCD0002
+#define RSXR_OBJECT       0xABCD0003
+#define RSXR_MAGICITEMS   0xABCD0004
+#define RSXR_KNOWS        0xABCD0005
+#define RSXR_GUESSES      0xABCD0006
+#define RSXR_OBJECTLIST   0xABCD0007
+#define RSXR_BAGOBJECT    0xABCD0008
+#define RSXR_MONSTERLIST  0xABCD0009
+#define RSXR_MONSTERSTATS 0xABCD000A
+#define RSXR_MONSTERS     0xABCD000B
+#define RSXR_TRAP         0xABCD000C
+#define RSXR_WINDOW       0xABCD000D
+#define RSXR_DAEMONS      0xABCD000E
+#define RSXR_IWEAPS       0xABCD000F
+#define RSXR_IARMOR       0xABCD0010
+#define RSXR_SPELLS       0xABCD0011
+#define RSXR_ILIST        0xABCD0012
+#define RSXR_HLIST        0xABCD0013
+#define RSXR_DEATHTYPE    0xABCD0014
+#define RSXR_CTYPES       0XABCD0015
+#define RSXR_COORDLIST    0XABCD0016
+#define RSXR_ROOMS        0XABCD0017
+
+#if defined(_WIN32)
+#include <Windows.h>
+#include <Lmcons.h>
+#include <process.h>
+#include <shlobj.h>
+#include <Shlwapi.h>
+#undef VOID
+#undef MOUSE_MOVED
+#elif defined(__DJGPP__)
+#include <process.h>
+#else
+#include <pwd.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <curses.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <time.h>
+#include <signal.h>
+#include "rogue.h"
+#include "mach_dep.h"
+
+
+#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 save_debug = FALSE;
+#define DBG(x)   {if (save_debug) rsPrintf x;}
+
+int
+rsPrintf(char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr,fmt, ap);
+    va_end(ap); 
+
+    return(0);
+}
+
+
+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);
+}
+
+rs_write(FILE *savef, void *ptr, size_t size)
+{
+    size_t i = 0;
+    
+    if (!write_error)
+        i = ENCWRITE(ptr,size,savef);
+    if (i != size)
+        write_error = TRUE;
+
+    assert(write_error == 0);
+    return(WRITESTAT);
+}
+
+int end_of_file = FALSE;
+
+rs_read(int inf, void *ptr, size_t 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("game format invalid. restore short-circuited.\n");abort();}
+
+    return(READSTAT);
+}
+
+int big_endian = 0;
+
+rs_write_uint(FILE *savef, unsigned int c)
+{
+    char bytes[4];
+    char *buf = (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);
+}
+
+rs_write_int(FILE *savef, int c)
+{
+    char bytes[4];
+    char *buf = (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);
+}
+
+rs_write_ulong(FILE *savef, unsigned long c)
+{
+    char bytes[4];
+    char *buf = (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);
+}
+
+rs_write_long(FILE *savef, long c)
+{
+    char bytes[4];
+    char *buf = (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);
+}
+
+rs_write_boolean(FILE *savef, bool c)
+{
+    char buf;
+    
+    if (c == 0)
+        buf = 0;
+    else
+        buf = 1;
+    
+    rs_write(savef, &buf, 1);
+
+    return(WRITESTAT);
+}
+
+rs_read_int(int inf, int *i)
+{
+    char bytes[4];
+    int  input;
+    char *buf = (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);
+}
+
+rs_read_uint(int inf, unsigned int *i)
+{
+    char bytes[4];
+    int  input;
+    char *buf = (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);
+}
+
+rs_read_ulong(int inf, unsigned long *i)
+{
+    char bytes[4];
+    unsigned long input;
+    char *buf = (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 long *) buf);
+    return(READSTAT);
+}
+
+rs_read_long(int inf, long *i)
+{
+    char bytes[4];
+    long input;
+    char *buf = (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);
+}
+
+rs_read_boolean(int inf, bool *i)
+{
+    char buf;
+    
+    rs_read(inf, &buf, 1);
+    
+    *i = buf;
+    
+    return(READSTAT);
+}
+
+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);
+}
+
+rs_write_short(FILE *savef, short c)
+{
+    char bytes[2];
+    char *buf = (char *) &c;
+    
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 2);
+
+    return(WRITESTAT);
+}
+
+rs_read_short(int inf, short *s)
+{
+    char  bytes[2];
+    short input;
+    char *buf = (char *)&input;
+    
+    rs_read(inf, &input, 2);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+    
+    *s = *((short *) buf);
+    return(READSTAT);
+}
+
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+rs_read_ulongs(int inf, unsigned 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_ulong(inf, &i[n]);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+rs_read_booleans(int inf, bool *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_boolean(inf, &i[n]);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+rs_write_levtype(FILE *savef, LEVTYPE c)
+{
+    int lt;
+    
+    switch(c)
+    {
+        case NORMLEV: lt = 1; break;
+        case POSTLEV: lt = 2; break;
+        case MAZELEV: lt = 3; break;
+        case OUTSIDE: lt = 4; break;
+        case STARTLEV: lt = 5; break;
+        default: lt = -1; break;
+    }
+    
+    rs_write_int(savef,lt);
+        
+    return(WRITESTAT);
+}
+
+rs_read_levtype(int inf, LEVTYPE *l)
+{
+    int lt;
+    
+    rs_read_int(inf, &lt);
+    
+    switch(lt)
+    {
+        case 1: *l = NORMLEV; break;
+        case 2: *l = POSTLEV; break;
+        case 3: *l = MAZELEV; break;
+        case 4: *l = OUTSIDE; break;
+        case 5: *l = STARTLEV; break;
+        default: *l = NORMLEV; break;
+    }
+    
+    return(READSTAT);
+}
+
+rs_write_char(FILE *savef, char c)
+{
+    rs_write(savef, &c, 1);
+    DBG(("%c",c));    
+    
+    return(WRITESTAT);
+}
+
+rs_read_char(int inf, char *c)
+{
+    rs_read(inf, c, 1);
+    
+    return(READSTAT);
+}
+
+rs_write_uchar(FILE *savef, unsigned char c)
+{
+    rs_write(savef, &c, 1);
+    DBG(("%c",c));    
+    
+    return(WRITESTAT);
+}
+
+rs_read_uchar(int inf, unsigned char *c)
+{
+    rs_read(inf, c, 1);
+    
+    return(READSTAT);
+}
+
+rs_write_string(FILE *savef, char *s)
+{
+    int len = 0;
+
+    len = (s == NULL) ? 0 : (int) strlen(s) + 1;
+
+    rs_write_uint(savef, (unsigned int) len);
+    rs_write(savef, s, len);
+            
+    return(WRITESTAT);
+}
+
+rs_read_string_index(int inf, struct words master[], int maxindex, char **str)
+{
+    int i;
+
+    if (rs_read_int(inf,&i) != 0)
+    {
+        if (i > maxindex)
+        {
+            printf("String index is out of range. %d > %d\n",      
+                i, maxindex);
+            printf("Sorry, invalid save game format\n");
+            format_error = TRUE;
+        }
+        else if (i >= 0)
+            *str = master[i].w_string;
+        else
+            *str = NULL;
+    }
+    return(READSTAT);
+}
+
+rs_write_string_index(FILE *savef, struct words master[], int maxindex, char *str)
+{
+    int i;
+
+    for(i = 0; i < maxindex; i++)
+    {
+        if (str == master[i].w_string)
+        {
+            rs_write_int(savef,i);
+            return(WRITESTAT);
+        }
+    }
+
+    rs_write_int(savef,-1);
+    return(WRITESTAT);
+}
+ 
+rs_read_scrolls(int inf)
+{
+    int i;
+
+    for(i = 0; i < MAXSCROLLS; i++)
+    {
+        rs_read_new_string(inf,&s_names[i]);
+        rs_read_boolean(inf,&s_know[i]);
+        rs_read_new_string(inf,&s_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+rs_write_scrolls(FILE *savef)
+{
+    int i;
+
+    for(i = 0; i < MAXSCROLLS; i++)
+    {
+        rs_write_string(savef,s_names[i]);
+        rs_write_boolean(savef,s_know[i]);
+        rs_write_string(savef,s_guess[i]);
+    }
+    return(READSTAT);
+}
+
+rs_read_potions(int inf)
+{
+    int i;
+
+    for(i = 0; i < MAXPOTIONS; i++)
+    {
+        rs_read_string_index(inf,rainbow,NCOLORS,&p_colors[i]);
+        rs_read_boolean(inf,&p_know[i]);
+        rs_read_new_string(inf,&p_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+rs_write_potions(FILE *savef)
+{
+    int i;
+
+    for(i = 0; i < MAXPOTIONS; i++)
+    {
+        rs_write_string_index(savef,rainbow,NCOLORS,p_colors[i]);
+        rs_write_boolean(savef,p_know[i]);
+        rs_write_string(savef,p_guess[i]);
+    }
+
+    return(WRITESTAT);
+}
+
+rs_read_rings(int inf)
+{
+    int i;
+
+    for(i = 0; i < MAXRINGS; i++)
+    {
+        rs_read_string_index(inf,stones,NSTONES,&r_stones[i]);
+        rs_read_boolean(inf,&r_know[i]);
+        rs_read_new_string(inf,&r_guess[i]);
+    }
+
+    return(READSTAT);