Mercurial > hg > early-roguelike
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, <); + + 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);