Mercurial > hg > early-roguelike
diff rogue4/state.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Sat, 24 Oct 2009 16:52:52 +0000 |
parents | |
children | 09db0cf536af |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rogue4/state.c Sat Oct 24 16:52:52 2009 +0000 @@ -0,0 +1,2161 @@ +/* + 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 <string.h> +#include "rogue.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 end_of_file = FALSE; +int big_endian = 0; + +void * +get_list_item(THING *l, int i) +{ + int count = 0; + + while(l != NULL) + { + if (count == i) + return(l); + + l = l->l_next; + + count++; + } + + return(NULL); +} + +int +find_list_ptr(THING *l, void *ptr) +{ + int count = 0; + + while(l != NULL) + { + if (l == ptr) + return(count); + + l = l->l_next; + count++; + } + + return(-1); +} + +int +list_size(THING *l) +{ + int count = 0; + + while(l != NULL) + { + if (l == 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, shint 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, const char *master[], int max, + const 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("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_uchar(int inf, unsigned 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, shint *i) +{ + unsigned char buf; + + rs_read(inf, &buf, 1); + + *i = (shint) 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; + + 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); +} + +int +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); +} + +int +rs_read_string(int inf, char *s, int max) +{ + int len = 0; + + if (rs_read_int(inf, &len) != FALSE) + { + if (len > max) + {