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); +} + +rs_write_rings(FILE *savef) +{ + int i; + + for(i = 0; i < MAXRINGS; i++) + { + rs_write_string_index(savef,stones,NSTONES,r_stones[i]); + rs_write_boolean(savef,r_know[i]); + rs_write_string(savef,r_guess[i]); + } + + return(WRITESTAT); +} + +rs_read_misc(int inf) +{ + int i; + + for(i = 0; i < MAXMM; i++) + { + rs_read_boolean(inf,&m_know[i]); + rs_read_new_string(inf,&m_guess[i]); + } + + return(READSTAT); +} + +rs_write_misc(FILE *savef) +{ + int i; + + for(i = 0; i < MAXMM; i++) + { + rs_write_boolean(savef,m_know[i]); + rs_write_string(savef,m_guess[i]); + } + + return(WRITESTAT); +} + +rs_write_sticks(FILE *savef) +{ + int i; + + for (i = 0; i < MAXSTICKS; i++) + { + if (strcmp(ws_type[i],"staff") == 0) + { + rs_write_int(savef,0); + rs_write_string_index(savef, wood, NWOOD, ws_made[i]); + } + else + { + rs_write_int(savef,1); + rs_write_string_index(savef, metal, NMETAL, ws_made[i]); + } + rs_write_boolean(savef, ws_know[i]); + rs_write_string(savef, ws_guess[i]); + } + + return(WRITESTAT); +} + +rs_read_sticks(int inf) +{ + int i = 0, list = 0; + + for(i = 0; i < MAXSTICKS; i++) + { + rs_read_int(inf,&list); + if (list == 0) + { + rs_read_string_index(inf,wood,NWOOD,&ws_made[i]); + ws_type[i] = "staff"; + } + else + { + rs_read_string_index(inf,metal,NMETAL,&ws_made[i]); + ws_type[i] = "wand"; + } + rs_read_boolean(inf, &ws_know[i]); + rs_read_new_string(inf, &ws_guess[i]); + } + + return(READSTAT); +} + +rs_read_string(int inf, char *s, int max) +{ + int len = 0; + + if (rs_read_int(inf, &len) != FALSE) + { + if (len > max) + { + printf("String too long to restore. %d > %d\n",len,max); + printf("Sorry, invalid save game format\n"); + format_error = TRUE; + } + + rs_read(inf, s, len); + } + + return(READSTAT); +} + +rs_read_new_string(int inf, char **s) +{ + int len=0; + char *buf=0; + + if (rs_read_int(inf, &len) != 0) + { + if (len == 0) + *s = NULL; + else + { + buf = malloc(len); + + if (buf == NULL) + read_error = TRUE; + else + { + rs_read(inf, buf, len); + *s = buf; + } + } + } + + return(READSTAT); +} + +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 : (int) strlen(s[n]) + 1; + rs_write_int(savef, len); + rs_write(savef, s[n], len); + DBG(("%s",s[n])); + } + + return(WRITESTAT); +} + +rs_write_words(FILE *savef, struct words *w, int count) +{ + int n = 0; + + rs_write_int(savef,count); + + for(n = 0; n < count; n++) + { + rs_write(savef, w[n].w_string, sizeof(w[n].w_string)); + DBG(("%s",w[n].w_string)); + } + + return(WRITESTAT); +} + +rs_read_words(int inf, struct words *w, int count) +{ + int n = 0; + int value = 0; + + rs_read_int(inf,&value); + + if (value != count) + { + printf("Incorrect number of words in block. %d != %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else for(n = 0; n < count; n++) + { + rs_read(inf, w[n].w_string, sizeof(w[n].w_string)); + } + + return(READSTAT); +} + +rs_read_new_strings(int inf, char **s, int count) +{ + int len = 0; + int n = 0; + int value = 0; + + if (rs_read_int(inf,&value) != 0) + { + if (value != count) + { + printf("Incorrect number of strings in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + for(n=0; n<value; n++) + { + rs_read_int(inf, &len); + + if (len == 0) + s[n]=0; + else + { + s[n] = malloc(len); + rs_read(inf,s[n],len); + } + } + } + + return(READSTAT); +} + +rs_write_coord(FILE *savef, coord *c) +{ + DBG(("X =")); + rs_write_int(savef, c->x); + DBG(("Y =")); + rs_write_int(savef, c->y); + + return(WRITESTAT); +} + +rs_read_coord(int inf, coord *c) +{ + rs_read_int(inf,&c->x); + rs_read_int(inf,&c->y); + + return(READSTAT); +} + +struct delayed_action { + int d_type; + int (*d_func)(); + union { + VOID *vp; + int i; + } d_arg; + int d_time; +}; + +rs_write_daemons(FILE *savef, struct delayed_action *d_list,int count) +{ + int i = 0; + int func = 0; + + DBG(("Daemons\n")); + rs_write_int(savef, RSXR_DAEMONS); + rs_write_int(savef, count); + + for(i=0; i < count; i++) + { + if (d_list[i].d_func == rollwand) + func = 1; + else if (d_list[i].d_func == doctor) + func = 2; + else if (d_list[i].d_func == stomach) + func = 3; + else if (d_list[i].d_func == trap_look) + func = 4; + else if (d_list[i].d_func == eat_gold) + func = 5; + else if (d_list[i].d_func == ring_search) + func = 6; + else if (d_list[i].d_func == ring_teleport) + func = 7; + else if (d_list[i].d_func == fumble) + func = 8; + else if (d_list[i].d_func == strangle) + func = 9; + else if (d_list[i].d_func == unconfuse) + func = 10; + else if (d_list[i].d_func == swander) + func = 11; + else if (d_list[i].d_func == spell_recovery) + func = 12; + else if (d_list[i].d_func == chant_recovery) + func = 13; + else if (d_list[i].d_func == prayer_recovery) + func = 14; + else if (d_list[i].d_func == cure_disease) + func = 15; + else if (d_list[i].d_func == unstink) + func = 16; + else if (d_list[i].d_func == res_strength) + func = 17; + else if (d_list[i].d_func == undance) + func = 18; + else if (d_list[i].d_func == suffocate) + func = 19; + else if (d_list[i].d_func == wghtchk) + func = 20; + else if (d_list[i].d_func == dust_appear) + func = 21; + else if (d_list[i].d_func == unchoke) + func = 22; + else if (d_list[i].d_func == sight) + func = 23; + else if (d_list[i].d_func == changeclass) + func = 24; + else if (d_list[i].d_func == cloak_charge) + func = 25; + else if (d_list[i].d_func == quill_charge) + func = 26; + else if (d_list[i].d_func == nohaste) + func = 27; + else if (d_list[i].d_func == noslow) + func = 28; + else if (d_list[i].d_func == unclrhead) + func = 29; + else if (d_list[i].d_func == unsee) + func = 30; + else if (d_list[i].d_func == unphase) + func = 31; + else if (d_list[i].d_func == land) + func = 32; + else if (d_list[i].d_func == appear) + func = 33; + else if (d_list[i].d_func == unskill) + func = 34; + else if (d_list[i].d_func == nofire) + func = 35; + else if (d_list[i].d_func == nocold) + func = 36; + else if (d_list[i].d_func == nobolt) + func = 37; + else if (d_list[i].d_func == NULL) + func = 0; + else + func = -1; + + rs_write_int(savef, d_list[i].d_type); + rs_write_int(savef, func); + + if (d_list[i].d_func == doctor) + rs_write_int(savef, 1); + else if (d_list[i].d_func == eat_gold) + { + int index; + index = find_list_ptr(player.t_pack,d_list[i].d_arg.vp); + rs_write_int(savef,index); + } + else if (d_list[i].d_func == changeclass) + { + rs_write_int(savef, d_list[i].d_arg.i); + } + else if (d_list[i].d_func == cloak_charge) + { + int index; + index = find_list_ptr(player.t_pack,d_list[i].d_arg.vp); + rs_write_int(savef,index); + } + else + rs_write_int(savef, d_list[i].d_arg.i); + + rs_write_int(savef, d_list[i].d_time); + } + + return(WRITESTAT); +} + +rs_read_daemons(int inf, struct delayed_action *d_list, int count) +{ + int i = 0; + int func = 0; + int value = 0; + int id = 0; + int dummy = 0; + + if (d_list == NULL) + printf("HELP THERE ARE NO DAEMONS\n"); + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_DAEMONS) + { + printf("Invalid id. %x != %x(RSXR_DAEMONS)\n", + id,RSXR_DAEMONS); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf, &value) != 0) + { + if (value > count) + { + printf("Incorrect number of daemons in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + { + for(i=0; i < value; i++) + { + func = 0; + rs_read_int(inf, &d_list[i].d_type); + rs_read_int(inf, &func); + + switch(func) + { + case 1: d_list[i].d_func = rollwand; + break; + case 2: d_list[i].d_func = doctor; + break; + case 3: d_list[i].d_func = stomach; + break; + case 4: d_list[i].d_func = trap_look; + break; + case 5: d_list[i].d_func = eat_gold; + break; + case 6: d_list[i].d_func = ring_search; + break; + case 7: d_list[i].d_func = ring_teleport; + break; + case 8: d_list[i].d_func = fumble; + break; + case 9: d_list[i].d_func = strangle; + break; + case 10: d_list[i].d_func = unconfuse; + break; + case 11: d_list[i].d_func = swander; + break; + case 12: d_list[i].d_func = spell_recovery; + break; + case 13: d_list[i].d_func = chant_recovery; + break; + case 14: d_list[i].d_func = prayer_recovery; + break; + case 15: d_list[i].d_func = cure_disease; + break; + case 16: d_list[i].d_func = unstink; + break; + case 17: d_list[i].d_func = res_strength; + break; + case 18: d_list[i].d_func = undance; + break; + case 19: d_list[i].d_func = suffocate; + break; + case 20: d_list[i].d_func = wghtchk; + break; + case 21: d_list[i].d_func = dust_appear; + break; + case 22: d_list[i].d_func = unchoke; + break; + case 23: d_list[i].d_func = sight; + break; + case 24: d_list[i].d_func = changeclass; + break; + case 25: d_list[i].d_func = cloak_charge; + break; + case 26: d_list[i].d_func = quill_charge; + break; + case 27: d_list[i].d_func = nohaste; + break; + case 28: d_list[i].d_func = noslow; + break; + case 29: d_list[i].d_func = unclrhead; + break; + case 30: d_list[i].d_func = unsee; + break; + case 31: d_list[i].d_func = unphase; + break; + case 32: d_list[i].d_func = land; + break; + case 33: d_list[i].d_func = appear; + break; + case 34: d_list[i].d_func = unskill; + break; + case 35: d_list[i].d_func = nofire; + break; + case 36: d_list[i].d_func = nocold; + break; + case 37: d_list[i].d_func = nobolt; + break; + case 0: + case -1: + default: d_list[i].d_func = NULL; + break; + } + + if (d_list[i].d_func == doctor) + { + rs_read_int(inf, &dummy); + d_list[i].d_arg.vp = (void *)&player; + } + else if (d_list[i].d_func == eat_gold) + { + rs_read_int(inf, &dummy); + d_list[i].d_arg.vp = get_list_item(player.t_pack,dummy); + if (d_list[i].d_arg.vp == NULL) + d_list[i].d_type = 0; + } + else if (d_list[i].d_func == changeclass) + { + rs_read_int(inf, &d_list[i].d_arg.i); + } + else if (d_list[i].d_func == cloak_charge) + { + rs_read_int(inf, &dummy); + d_list[i].d_arg.vp = get_list_item(player.t_pack,dummy); + if (d_list[i].d_arg.vp == NULL) + d_list[i].d_type = 0; + } + else + rs_read_int(inf, &d_list[i].d_arg.i); + + rs_read_int(inf, &d_list[i].d_time); + + if (d_list[i].d_func == NULL) + { + d_list[i].d_time = 0; + d_list[i].d_arg.vp = NULL; + d_list[i].d_type = 0; + } + + } + } + } + } + + return(READSTAT); +} + +rs_write_rooms(FILE *savef, struct room r[], int count) +{ + int n = 0,i = -1; + struct linked_list *l; + + DBG(("Rooms\n")); + rs_write_int(savef, RSXR_ROOMS); + rs_write_int(savef, count); + + for(n=0; n<count; n++) + { + rs_write_coord(savef, &r[n].r_pos); + rs_write_coord(savef, &r[n].r_max); + rs_write_long(savef, r[n].r_flags); + rs_write_coord_list(savef, r[n].r_exit); + + l = r[n].r_fires; + i = list_size(l); + + rs_write_int(savef, i); + + if (i >0) + while (l != NULL) + { + i = find_list_ptr(mlist,l->l_data); + rs_write_int(savef,i); + l = l->l_next; + } + } + return(WRITESTAT); +} + +rs_read_rooms(int inf, struct room *r, int count) +{ + int value = 0, n = 0, i = 0, index = 0, id = 0; + struct linked_list *fires=NULL, *item = NULL; + + if (rs_read_int(inf,&id) != 0) + { + if (id != RSXR_ROOMS) + { + printf("Invalid id. %x != %x(RSXR_ROOMS)\n", + id,RSXR_ROOMS); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf,&value) != 0) + { + if (value != count) + { + printf("Incorrect number of rooms in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + { + for(n=0; n<value; n++) + { + rs_read_coord(inf,&r[n].r_pos); + rs_read_coord(inf,&r[n].r_max); + rs_read_long(inf,&r[n].r_flags); + rs_read_coord_list(inf, &r[n].r_exit); + + rs_read_int(inf, &i); + fires = NULL; + while (i>0) + { + rs_read_int(inf,&index); + + if (index >= 0) + { + void *data; + data = get_list_item(mlist,index); + item = creat_item(); + item->l_data = data; + if (fires == NULL) + fires = item; + else + attach(fires,item); + } + i--; + } + r[n].r_fires=fires; + } + } + } + } + + return(READSTAT); +} + +rs_write_object(FILE *savef, struct object *o) +{ + rs_write_int(savef, RSXR_OBJECT); + rs_write_int(savef, o->o_type); + rs_write_coord(savef, &o->o_pos); + rs_write_char(savef, o->o_launch); + rs_write(savef, o->o_damage, sizeof(o->o_damage)); + rs_write(savef, o->o_hurldmg, sizeof(o->o_hurldmg)); + rs_write_int(savef, o->o_count); + rs_write_int(savef, o->o_which); + rs_write_int(savef, o->o_hplus); + rs_write_int(savef, o->o_dplus); + rs_write_int(savef, o->o_ac); + rs_write_long(savef, o->o_flags); + rs_write_int(savef, o->o_group); + rs_write_int(savef, o->o_weight); + rs_write(savef, o->o_mark, MARKLEN); + + DBG(("Object\n")); + DBG((" SaveID : %X\n",RSXR_OBJECT)); + DBG((" Type : %d\n",o->o_type)); + DBG((" Pos : %d %d\n",o->o_pos.x,o->o_pos.y)); + DBG((" Launch : %c\n",o->o_launch)); + DBG((" Damage : %s\n",o->o_damage)); + DBG((" Hurl : %s\n",o->o_hurldmg)); + DBG((" Count : %d\n",o->o_count)); + DBG((" Which : %d\n",o->o_which)); + DBG((" HPlus : %d\n",o->o_hplus)); + DBG((" DPlus : %d\n",o->o_dplus)); + DBG((" AC : %d\n",o->o_ac)); + DBG((" Flags : %X\n",o->o_flags)); + DBG((" Group : %d\n",o->o_group)); + DBG((" Weight : %d\n",o->o_weight)); + DBG((" Mark : %s\n",o->o_mark)); + if (o->contents == NULL) + { + DBG((" Contents: None\n")); + } + else + { + DBG((" CONTENTS\n")); + } + + rs_write_object_list(savef, o->contents); + + if (o->contents != NULL) + DBG((" END_CONTENTS\n")); + + return(WRITESTAT); +} + +rs_read_object(int inf, struct object *o) +{ + int id; + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_OBJECT) + { + printf("Invalid id. %x != %x(RSXR_OBJECT)\n", id,RSXR_OBJECT); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + { + rs_read_int(inf, &o->o_type); + rs_read_coord(inf, &o->o_pos); + rs_read_char(inf, &o->o_launch); + rs_read(inf, o->o_damage,sizeof(o->o_damage)); + rs_read(inf, o->o_hurldmg,sizeof(o->o_hurldmg)); + rs_read_int(inf, &o->o_count); + rs_read_int(inf, &o->o_which); + rs_read_int(inf, &o->o_hplus); + rs_read_int(inf, &o->o_dplus); + rs_read_int(inf,&o->o_ac); + rs_read_long(inf,&o->o_flags); + rs_read_int(inf,&o->o_group); + rs_read_int(inf, &o->o_weight); + rs_read(inf, o->o_mark, MARKLEN); + rs_read_object_list(inf,&o->contents); + + } + } + + return(READSTAT); +} + +rs_write_stats(FILE *savef, struct stats *s) +{ + DBG(("Stats\n")); + rs_write_int(savef, RSXR_STATS); + + rs_write_short(savef, s->s_str); + rs_write_short(savef, s->s_intel); + rs_write_short(savef, s->s_wisdom); + rs_write_short(savef, s->s_dext); + rs_write_short(savef, s->s_const); + rs_write_short(savef, s->s_charisma); + rs_write_ulong(savef, s->s_exp); + rs_write_int(savef, s->s_lvladj); + rs_write_int(savef, s->s_lvl); + rs_write_int(savef, s->s_arm); + rs_write_int(savef, s->s_hpt); + rs_write_int(savef, s->s_pack); + rs_write_int(savef, s->s_carry); + rs_write(savef, s->s_dmg, sizeof(s->s_dmg)); + + return(WRITESTAT); +} + +rs_read_stats(int inf, struct stats *s) +{ + int id; + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_STATS) + { + printf("Invalid id. %x != %x(RSXR_STATS)\n", id,RSXR_STATS); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + { + rs_read_short(inf,&s->s_str); + rs_read_short(inf,&s->s_intel); + rs_read_short(inf,&s->s_wisdom); + rs_read_short(inf,&s->s_dext); + rs_read_short(inf,&s->s_const); + rs_read_short(inf,&s->s_charisma); + rs_read_ulong(inf,&s->s_exp); + rs_read_int(inf,&s->s_lvladj); + rs_read_int(inf,&s->s_lvl); + rs_read_int(inf,&s->s_arm); + rs_read_int(inf,&s->s_hpt); + rs_read_int(inf,&s->s_pack); + rs_read_int(inf,&s->s_carry); + rs_read(inf,s->s_dmg,sizeof(s->s_dmg)); + } + } + + return(READSTAT); +} + +rs_write_mstats(FILE *savef, struct mstats *s) +{ + DBG(("M-Stats\n")); + rs_write_int(savef, RSXR_STATS); + rs_write_short(savef, s->ms_str); + /*printf(" Strength: %d\n",s->ms_str);*/ + rs_write_short(savef, s->ms_dex); + rs_write_short(savef, s->ms_move); + rs_write_ulong(savef, s->ms_exp); + rs_write_short(savef, s->ms_lvl); + rs_write_short(savef, s->ms_arm); + rs_write(savef, s->ms_hpt, sizeof(s->ms_hpt)); + rs_write(savef, s->ms_dmg, sizeof(s->ms_dmg)); + /*printf(" Damage: %s\n",s->ms_dmg);*/ + + return(WRITESTAT); +} + +rs_read_mstats(int inf, struct mstats *s) +{ + int id; + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_STATS) + { + printf("Invalid id. %x != %x(RSXR_STATS)\n", id,RSXR_STATS); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + { + rs_read_short(inf,&s->ms_str); + /*printf(" Strength: %d\n",s->ms_str);*/ + rs_read_short(inf,&s->ms_dex); + /*printf(" Dexterity: %d\n",s->ms_dex);*/ + rs_read_short(inf,&s->ms_move); + /*printf(" Moves: %d\n",s->ms_move);*/ + rs_read_ulong(inf,&s->ms_exp); + /*printf(" Experience: %d\n",s->ms_exp);*/ + rs_read_short(inf,&s->ms_lvl); + /*printf(" Level: %d\n",s->ms_lvl);*/ + rs_read_short(inf,&s->ms_arm); + /*printf(" Armor: %d\n",s->ms_arm);*/ + rs_read(inf,s->ms_hpt,sizeof(s->ms_hpt)); + /*printf(" HP: %s\n",s->ms_hpt);*/ + rs_read(inf,s->ms_dmg,sizeof(s->ms_dmg)); + /*printf(" Damage: %s\n",s->ms_dmg);*/ + } + } + + return(READSTAT); +} + +rs_write_init_weps(FILE *savef, struct init_weps *w, int count) +{ + int i; + + DBG(("Init-Weps\n")); + rs_write_int(savef, RSXR_IWEAPS); + rs_write_int(savef, count); + + for(i=0;i<count;i++) + { + rs_write(savef, w[i].w_name, sizeof(w[i].w_name)); + rs_write(savef, w[i].w_dam, sizeof(w[i].w_dam)); + rs_write(savef, w[i].w_hrl, sizeof(w[i].w_hrl)); + rs_write_char(savef, w[i].w_launch); + rs_write_int(savef, w[i].w_flags); + rs_write_int(savef, w[i].w_rate); + rs_write_int(savef, w[i].w_wght); + rs_write_int(savef, w[i].w_worth); + } + return(WRITESTAT); +} + +rs_read_init_weps(int inf, struct init_weps *w,int count) +{ + int id,value,i; + + rs_read_int(inf, &id); + rs_read_int(inf, &value); + + if (value != count) + { + printf("Incorrect number of init_weps in block. %d != %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else for (i = 0; i < count; i++) + { + rs_read(inf, w[i].w_name, sizeof(w[i].w_name)); + rs_read(inf, w[i].w_dam, sizeof(w[i].w_dam)); + rs_read(inf, w[i].w_hrl, sizeof(w[i].w_hrl)); + rs_read_char(inf, &w[i].w_launch); + rs_read_int(inf, &w[i].w_flags); + rs_read_int(inf, &w[i].w_rate); + rs_read_int(inf, &w[i].w_wght); + rs_read_int(inf, &w[i].w_worth); + } + return(READSTAT); +} + +rs_write_init_armor(FILE *savef, struct init_armor *a, int count) +{ + int i; + DBG(("Init-Armor\n")); + rs_write_int(savef, RSXR_IARMOR); + rs_write_int(savef, count); + for(i=0;i<count;i++) + { + rs_write(savef, a[i].a_name, sizeof(a[i].a_name)); + rs_write_int(savef, a[i].a_prob); + rs_write_int(savef, a[i].a_class); + rs_write_int(savef, a[i].a_worth); + rs_write_int(savef, a[i].a_wght); + } + return(WRITESTAT); +} + +rs_read_init_armor(int inf, struct init_armor *a,int count) +{ + int id,value,i; + + rs_read_int(inf, &id); + rs_read_int(inf, &value); + + for(i=0;i<count;i++) + { + rs_read(inf, a[i].a_name, sizeof(a[i].a_name)); + rs_read_int(inf, &a[i].a_prob); + rs_read_int(inf, &a[i].a_class); + rs_read_int(inf, &a[i].a_worth); + rs_read_int(inf, &a[i].a_wght); + } + + return(READSTAT); +} + +rs_write_spells(FILE *savef, struct spells *s, int count) +{ + int i; + DBG(("Spells\n")); + rs_write_int(savef, RSXR_SPELLS); + rs_write_int(savef, count); + for(i=0;i<count;i++) + { + rs_write_short(savef, s[i].s_which); + rs_write_short(savef, s[i].s_cost); + rs_write_short(savef, s[i].s_type); + rs_write_int(savef, s[i].s_flag); + } + return(WRITESTAT); +} + +rs_read_spells(int inf, struct spells *s,int count) +{ + int id,value,i; + + rs_read_int(inf, &id); + rs_read_int(inf, &value); + + for(i=0;i<count;i++) + { + rs_read_short(inf, &s[i].s_which); + rs_read_short(inf, &s[i].s_cost); + rs_read_short(inf, &s[i].s_type); + rs_read_int(inf, &s[i].s_flag); + } + return(READSTAT); +} + +rs_write_item_list(FILE *savef, struct item_list *i) +{ + DBG(("Item List\n")); + rs_write_int(savef, RSXR_ILIST); + rs_write_char(savef, i->item_ch); + rs_write(savef, i->item_desc, sizeof(i->item_desc)); + return(WRITESTAT); +} +rs_read_item_list(int inf, struct item_list *i) +{ + int id; + + rs_read_int(inf, &id); + + rs_read_uchar(inf, &i->item_ch); + rs_read(inf, i->item_desc,sizeof(i->item_desc)); + return(READSTAT); +} + +rs_write_h_list(FILE *savef, struct h_list *h) +{ + DBG(("H List\n")); + rs_write_int(savef, RSXR_HLIST); + rs_write_char(savef, h->h_ch); + rs_write(savef, h->h_desc, sizeof(h->h_desc)); + return(WRITESTAT); +} + +rs_read_h_list(int inf, struct h_list *h) +{ + int id; + + rs_read_int(inf, &id); + + rs_read_char(inf, &h->h_ch); + rs_read(inf, h->h_desc,sizeof(h->h_desc)); + return(READSTAT); +} + +rs_write_death_types(FILE *savef, struct death_type *d,int count) +{ + int i; + + DBG(("Death Types\n")); + rs_write_int(savef, RSXR_DEATHTYPE); + rs_write_int(savef, count); + + for(i=0; i < count; i++) + { + rs_write_int(savef, d[i].reason); + rs_write(savef, d[i].name, sizeof(d[i].name)); + } + return(WRITESTAT); +} +rs_read_death_types(int inf, struct death_type *d, int count) +{ + int id,value,i; + + rs_read_int(inf, &id); + rs_read_int(inf, &value); + if (value != count) + { + printf("Incorrect number of death_types in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else for(i=0;i < count;i++) + { + rs_read_int(inf, &d[i].reason); + rs_read(inf, d[i].name,sizeof(d[i].name)); + } + return(READSTAT); +} + +rs_write_character_types(FILE *savef, struct character_types *c, int count) +{ + int i; + + DBG(("Character Types\n")); + rs_write_int(savef, RSXR_CTYPES); + rs_write_int(savef,count); + + for(i=0;i<count;i++) + { + rs_write(savef, c[i].name, sizeof(c[i].name)); + rs_write_long(savef, c[i].start_exp); + rs_write_long(savef, c[i].cap); + rs_write_int(savef, c[i].hit_pts); + rs_write_int(savef, c[i].base); + rs_write_int(savef, c[i].max_lvl); + rs_write_int(savef, c[i].factor); + rs_write_int(savef, c[i].offset); + rs_write_int(savef, c[i].range); + } + return(WRITESTAT); +} + +rs_read_character_types(int inf, struct character_types *c,int count) +{ + int id,value,i; + + rs_read_int(inf, &id); + rs_read_int(inf, &value); + + if (value != count) + { + printf("Incorrect number of character types in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else for (i = 0; i < count; i++) + { + rs_read(inf, c[i].name,sizeof(c[i].name)); + rs_read_long(inf, &c[i].start_exp); + rs_read_long(inf, &c[i].cap); + rs_read_int(inf, &c[i].hit_pts); + rs_read_int(inf, &c[i].base); + rs_read_int(inf, &c[i].max_lvl); + rs_read_int(inf, &c[i].factor); + rs_read_int(inf, &c[i].offset); + rs_read_int(inf, &c[i].range); + } + return(READSTAT); +} + +rs_write_traps(FILE *savef, struct trap *trap,int count) +{ + int n; + + DBG(("Traps\n")); + rs_write_int(savef, RSXR_TRAP); + rs_write_int(savef, count); + + for(n=0; n<count; n++) + { + rs_write_char(savef, trap[n].tr_type); + rs_write_char(savef, trap[n].tr_show); + rs_write_coord(savef, &trap[n].tr_pos); + rs_write_long(savef, trap[n].tr_flags); + } +} + +rs_read_traps(int inf, struct trap *trap, int count) +{ + int id = 0, value = 0, n = 0; + + if (rs_read_int(inf,&id) != 0) + { + if (id != RSXR_TRAP) + { + printf("Invalid id. %x != %x(RSXR_TRAP)\n", + id,RSXR_TRAP); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf,&value) != 0) + { + if (value != count) + { + printf("Incorrect number of traps in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format\n"); + format_error = TRUE; + } + else + { + for(n=0;n<value;n++) + { + rs_read_uchar(inf,&trap[n].tr_type); + rs_read_uchar(inf,&trap[n].tr_show); + rs_read_coord(inf,&trap[n].tr_pos); + rs_read_long(inf,&trap[n].tr_flags); + } + } + } + else + format_error = TRUE; + } + + return(READSTAT); +} + +rs_write_monsters(FILE * savef, struct monster * m, int count) +{ + int n; + + DBG(("Monsters\n")); + rs_write_int(savef, RSXR_MONSTERS); + rs_write_int(savef, count); + + for(n=0;n<count;n++) + { + rs_write(savef, m[n].m_name, sizeof(m[n].m_name)); + /*printf("Monster: %s/%d/%d\n",m[n].m_name,sizeof(m[n].m_name),strlen(m[n].m_name));*/ + rs_write_short(savef, m[n].m_carry); + rs_write_boolean(savef, m[n].m_normal); + rs_write_boolean(savef, m[n].m_wander); + rs_write_char(savef, m[n].m_appear); + rs_write(savef, m[n].m_intel,sizeof(m[n].m_intel)); + rs_write_longs(savef, m[n].m_flags, MAXFLAGS); + rs_write(savef, m[n].m_typesum,sizeof(m[n].m_typesum)); + rs_write_short(savef, m[n].m_numsum); + rs_write_short(savef, m[n].m_add_exp); + + rs_write_mstats(savef, &m[n].m_stats); + } + + return(WRITESTAT); +} + +rs_read_monsters(int inf, struct monster *m, int count) +{ + int id = 0, value = 0, n = 0; + char buffer[1024]; + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_MONSTERS) + { + printf("Invalid id. %x != %x(RSXR_MONSTERS)\n", + id,RSXR_MONSTERS); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf, &value) != 0) + { + if (value != count) + { printf("Incorrect number of monsters in block. %d != %d.", + value,count); + printf("Sorry, invalid save game format\n"); + format_error = TRUE; + + } + else for(n=0;n<value;n++) + { + rs_read(inf, buffer,sizeof(m[n].m_name)); + assert( strcmp(buffer,m[n].m_name) == 0); + /*printf("Monster: %s\n",m[n].m_name);*/ + rs_read_short(inf, &m[n].m_carry); + /*printf(" Carry: %d\n",m[n].m_carry); */ + rs_read_boolean(inf, &m[n].m_normal); + /*printf(" Normal: %d\n",m[n].m_normal);*/ + rs_read_boolean(inf, &m[n].m_wander); + /*printf(" Wander: %d\n",m[n].m_wander);*/ + rs_read_char(inf, &m[n].m_appear); + /*printf(" Appears: %c\n",m[n].m_appear);*/ + rs_read(inf, m[n].m_intel,sizeof(m[n].m_intel)); + /*printf(" Intelligence: %s\n",m[n].m_intel);*/ + rs_read_longs(inf, m[n].m_flags, MAXFLAGS); + /*printf(" Flags: %X\n",m[n].m_flags);*/ + rs_read(inf, m[n].m_typesum, sizeof(m[n].m_typesum)); + /*printf(" Summons: %s\n",m[n].m_typesum);*/ + rs_read_short(inf, &m[n].m_numsum); + /*printf(" # Summons: %d\n",m[n].m_numsum);*/ + rs_read_short(inf, &m[n].m_add_exp); + /*printf(" Experience: %d\n",m[n].m_add_exp);*/ + rs_read_mstats(inf, &m[n].m_stats); + + } + } + else + format_error = TRUE; + } + + return(READSTAT); +} + +/*****************************************************************************/ + +rs_write_coord_list(FILE *savef, struct linked_list *l) +{ + DBG(("Coordinate List\n")); + rs_write_int(savef, RSXR_COORDLIST); + rs_write_int(savef, list_size(l)); + + while (l != NULL) + { + rs_write_coord(savef, (coord *) l->l_data); + l = l->l_next; + } + + return(WRITESTAT); +} + +rs_read_coord_list(int inf, struct linked_list **list) +{ + int id; + int i, cnt; + struct linked_list *l = NULL, *previous = NULL, *head = NULL; + + if (rs_read_int(inf,&id) != 0) + { + if (id != RSXR_COORDLIST) + { + printf("Invalid id. %x != %x(RSXR_COORDLIST)\n", + id,RSXR_COORDLIST); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf,&cnt) != 0) + { + for (i = 0; i < cnt; i++) + { + l = new_item(sizeof(coord)); + l->l_prev = previous; + if (previous != NULL) + previous->l_next = l; + rs_read_coord(inf,(coord *) l->l_data); + if (previous == NULL) + head = l; + previous = l; + } + + if (l != NULL) + l->l_next = NULL; + + *list = head; + } + else + format_error = TRUE; + } + else + format_error = TRUE; + + return(READSTAT); +} + +rs_write_object_list(FILE *savef, struct linked_list *l) +{ + DBG(("Object List\n")); + rs_write_int(savef, RSXR_OBJECTLIST); + rs_write_int(savef, list_size(l)); + + while (l != NULL) + { + rs_write_object(savef, (struct object *) l->l_data); + l = l->l_next; + } + + return(WRITESTAT); +} + +rs_read_object_list(int inf, struct linked_list **list) +{ + int id; + int i, cnt; + struct linked_list *l = NULL, *previous = NULL, *head = NULL; + + if (rs_read_int(inf,&id) != 0) + { + if (rs_read_int(inf,&cnt) != 0) + { + for (i = 0; i < cnt; i++) + { + l = new_item(sizeof(struct object)); + memset(l->l_data,0,sizeof(struct object)); + l->l_prev = previous; + if (previous != NULL) + previous->l_next = l; + rs_read_object(inf,(struct object *) l->l_data); + if (previous == NULL) + head = l; + previous = l; + } + + if (l != NULL) + l->l_next = NULL; + + *list = head; + } + else + format_error = TRUE; + } + else + format_error = TRUE; + + + return(READSTAT); +} + +int +find_thing_coord(monlist, c) +struct linked_list *monlist; +coord *c; +{ + struct linked_list *mitem; + struct thing *tp; + int i = 0; + + for(mitem = monlist; mitem != NULL; mitem = mitem->l_next) + { + tp = THINGPTR(mitem); + if (c == &tp->t_pos) + return(i); + i++; + } + + return(-1); +} + +int +find_object_coord(objlist, c) +struct linked_list *objlist; +coord *c; +{ + struct linked_list *oitem; + struct object *obj; + int i = 0; + + for(oitem = objlist; oitem != NULL; oitem = oitem->l_next) + { + obj = OBJPTR(oitem); + if (c == &obj->o_pos) + return(i); + i++; + } + + return(-1); +} + +rs_write_thing(FILE *savef, struct thing *t) +{ + int i = -1; + + DBG(("Thing\n")); + rs_write_int(savef, RSXR_THING); + rs_write_boolean(savef,t->t_wasshot); + rs_write_char(savef, t->t_type); + rs_write_char(savef, t->t_disguise); + rs_write_char(savef, t->t_oldch); + rs_write_short(savef, t->t_ctype); + rs_write_short(savef, t->t_index); + rs_write_short(savef, t->t_no_move); + rs_write_short(savef, t->t_quiet); + rs_write_short(savef, t->t_movement); + rs_write_short(savef, t->t_action); + rs_write_short(savef, t->t_artifact); + rs_write_short(savef, t->t_wand); + rs_write_short(savef, t->t_summon); + rs_write_short(savef, t->t_cast); + rs_write_short(savef, t->t_breathe); + + rs_write_string(savef,t->t_name); + rs_write_coord(savef, &t->t_doorgoal); + + if (t->t_dest == &hero) + { + rs_write_int(savef,0); + rs_write_int(savef,1); + } + else if (t->t_dest != NULL) + { + i = find_thing_coord(mlist, t->t_dest); + + if (i >= 0) + { + rs_write_int(savef,1); + rs_write_int(savef,i); + } + else + { + i = find_object_coord(lvl_obj, t->t_dest); + + if (i >= 0) + { + rs_write_int(savef,2); + rs_write_int(savef,i); + } + else + { + rs_write_int(savef,0); + rs_write_int(savef,1); /* chase the hero anyway */ + } + } + } + else + { + rs_write_int(savef,0); + rs_write_int(savef,0); + } + + rs_write_coord(savef, &t->t_pos); + rs_write_coord(savef, &t->t_oldpos); + rs_write_coord(savef, &t->t_newpos); + rs_write_ulongs(savef, t->t_flags, 16); + + DBG(("Thing\n")); + DBG((" SaveID : %X\n",RSXR_THING)); + DBG((" Name : %s\n",t->t_name)); + DBG((" WasShot : %d\n",t->t_wasshot)); + DBG((" Type : %c(%d)\n",t->t_type,t->t_type)); + DBG((" Disguise: %c(%d)\n",t->t_disguise,t->t_disguise)); + DBG((" OldCh : %c(%d)\n",t->t_oldch,t->t_oldch)); + DBG((" CType : %d\n",t->t_ctype)); + DBG((" Index : %d\n",t->t_index)); + DBG((" NoMove : %d\n",t->t_no_move)); + DBG((" Quiet : %d\n",t->t_quiet)); + DBG((" Movement: %d\n",t->t_movement)); + DBG((" Action : %d\n",t->t_action)); + DBG((" Artifact: %d\n",t->t_artifact)); + DBG((" Wand : %d\n",t->t_wand)); + DBG((" Summon : %d\n",t->t_summon)); + DBG((" Cast : %d\n",t->t_cast)); + DBG((" Breathe : %d\n",t->t_breathe)); + DBG((" DoorGoal: %d %d\n",t->t_doorgoal.x,t->t_doorgoal.y)); + if (t->t_dest) + { + DBG((" Dest : %d %d\n",t->t_dest->x,t->t_dest->y)); + } + else + { + DBG((" Dest : None\n")); + } + DBG((" Pos : %d %d\n",t->t_pos.x,t->t_pos.y)); + DBG((" OldPos : %d %d\n",t->t_oldpos.x,t->t_oldpos.y)); + DBG((" NewPos : %d %d\n",t->t_newpos.x,t->t_newpos.y)); + DBG((" Flags : ")); + { int i; for(i=0;i<16;i++) {DBG(("%d ",t->t_flags[i]));} DBG(("\n")); } + + rs_write_object_list(savef, t->t_pack); + i = -1; + if (t->t_using != NULL) + i = find_list_ptr(t->t_pack, t->t_using->l_data); + rs_write_int(savef, i); + rs_write_stats(savef, &t->t_stats); + rs_write_stats(savef, &t->maxstats); + + return(WRITESTAT); +} + +rs_fix_thing(struct thing *t) +{ + struct linked_list *item; + struct thing *tp; + + if (t->t_reserved < 0) + return; + + item = get_list_item(mlist,t->t_reserved); + + if (item != NULL) + { + tp = THINGPTR(item); + t->t_dest = &tp->t_pos; + } +} + +rs_read_thing(int inf, struct thing *t) +{ + int id; + int listid = 0, index = -1; + struct linked_list *item; + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_THING) + format_error = TRUE; + else + { + rs_read_boolean(inf,&t->t_wasshot); + rs_read_uchar(inf, &t->t_type); + rs_read_uchar(inf, &t->t_disguise); + rs_read_uchar(inf, &t->t_oldch); + rs_read_short(inf, &t->t_ctype); + rs_read_short(inf, &t->t_index); + rs_read_short(inf, &t->t_no_move); + rs_read_short(inf, &t->t_quiet); + rs_read_short(inf, &t->t_movement); + rs_read_short(inf, &t->t_action); + rs_read_short(inf, &t->t_artifact); + rs_read_short(inf, &t->t_wand); + rs_read_short(inf, &t->t_summon); + rs_read_short(inf, &t->t_cast); + rs_read_short(inf, &t->t_breathe); + rs_read_new_string(inf,&t->t_name); + rs_read_coord(inf,&t->t_doorgoal); + + rs_read_int(inf,&listid); + rs_read_int(inf,&index); + t->t_reserved = -1; + if (listid == 0) + { + if (index == 1) + t->t_dest = &hero; + else + t->t_dest = NULL; + } + else if (listid == 1) + { + t->t_dest = NULL; + t->t_reserved = index; + } + else if (listid == 2) + { + struct object *obj; + item = get_list_item(lvl_obj,index); + if (item != NULL) + { + obj = OBJPTR(item); + t->t_dest = &obj->o_pos; + } + } + else + t->t_dest = NULL; + + rs_read_coord(inf,&t->t_pos); + rs_read_coord(inf,&t->t_oldpos); + rs_read_coord(inf,&t->t_newpos); + rs_read_ulongs(inf,t->t_flags,16); + rs_read_object_list(inf,&t->t_pack); + rs_read_int(inf,&index); + t->t_using = get_list_item(t->t_pack, index); + rs_read_stats(inf,&t->t_stats); + rs_read_stats(inf,&t->maxstats); + } + } + else format_error = TRUE; + + return(READSTAT); +} + +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); +} + + +rs_write_monster_list(FILE *savef, struct linked_list *l) +{ + int cnt = 0; + + DBG(("Monster List\n")); + rs_write_int(savef, RSXR_MONSTERLIST); + + cnt = list_size(l); + + rs_write_int(savef, cnt); + + if (cnt < 1) + return(WRITESTAT); + + while (l != NULL) { + rs_write_thing(savef, (struct thing *)l->l_data); + l = l->l_next; + } + + return(WRITESTAT); +} + +rs_fix_monster_list(list) +struct linked_list *list; +{ + struct linked_list *item; + + for(item = list; item != NULL; item = item->l_next) + rs_fix_thing(THINGPTR(item)); +} + +rs_read_monster_list(int inf, struct linked_list **list) +{ + int id; + int i, cnt; + struct linked_list *l = NULL, *previous = NULL, *head = NULL; + + if (rs_read_int(inf,&id) != 0) + { + if (id != RSXR_MONSTERLIST) + { + printf("Invalid id. %x != %x(RSXR_MONSTERLIST)\n", + id,RSXR_MONSTERLIST); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf,&cnt) != 0) + { + for (i = 0; i < cnt; i++) + { + l = new_item(sizeof(struct thing)); + l->l_prev = previous; + if (previous != NULL) + previous->l_next = l; + rs_read_thing(inf,(struct thing *)l->l_data); + if (previous == NULL) + head = l; + previous = l; + } + + + if (l != NULL) + l->l_next = NULL; + + *list = head; + } + } + else format_error = TRUE; + + return(READSTAT); +} + +rs_write_magic_items(FILE *savef, struct magic_item *i, int count) +{ + int n; + + DBG(("Magic Items\n")); + rs_write_int(savef, RSXR_MAGICITEMS); + rs_write_int(savef, count); + + for(n=0;n<count;n++) + { + rs_write(savef,i[n].mi_name,sizeof(i[n].mi_name)); + rs_write_int(savef,i[n].mi_prob); + rs_write_int(savef,i[n].mi_worth); + rs_write_int(savef,i[n].mi_curse); + rs_write_int(savef,i[n].mi_bless); + } + + return(WRITESTAT); +} + +rs_read_magic_items(int inf, struct magic_item *mi, int count) +{ + int id; + int n; + int value; + + if (rs_read_int(inf, &id) != 0) + { + if (id != RSXR_MAGICITEMS) + { + printf("Invalid id. %x != %x(RSXR_MAGICITEMS)\n", + id,RSXR_MAGICITEMS); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else if (rs_read_int(inf, &value) != 0) + { + if (value > count) + { + printf("Incorrect number of magic items in block. %d > %d.", + value,count); + printf("Sorry, invalid save game format"); + format_error = TRUE; + } + else + { + for(n = 0; n < value; n++) + { + rs_read(inf,mi[n].mi_name,sizeof(mi[n].mi_name)); + rs_read_int(inf,&mi[n].mi_prob); + rs_read_int(inf,&mi[n].mi_worth); + rs_read_int(inf,&mi[n].mi_curse); + rs_read_int(inf,&mi[n].mi_bless); + } + } + } + } + + return(READSTAT); +} + +rs_write_window(FILE *savef, WINDOW *win) +{ + int row,col,height,width; + width = getmaxx(win); + height = getmaxy(win); + DBG(("Window\n")); + rs_write_int(savef,height); + rs_write_int(savef,width); + + for(row=0;row<height;row++) + for(col=0;col<width;col++) + rs_write_int(savef, mvwinch(win,row,col)); +} + +rs_read_window(int inf, WINDOW *win) +{ + int row,col,maxlines,maxcols,value,width,height; + + width = getmaxx(win); + height = getmaxy(win); + + rs_read_int(inf,&maxlines); + rs_read_int(inf,&maxcols); + if (maxlines > height) + abort(); + if (maxcols > width) + abort(); + + for(row=0;row<maxlines;row++) + for(col=0;col<maxcols;col++) + { + rs_read_int(inf, &value); + if ((value == '-') || (value == 196)) + value = HORZWALL; + else if ((value == '|') || (value == 179)) + value = VERTWALL; + mvwaddch(win,row,col,value); + } + + return(READSTAT); +} + +rs_save_file(FILE *savef) +{ + int i, weapon, armor, ring, misc, room = -1; + int endian = 0x01020304; + big_endian = ( *((char *)&endian) == 0x01 ); + + rs_write_thing(savef, &player); /* rogue.c */ + rs_write_object_list(savef, lvl_obj); /* rogue.c */ + rs_write_monster_list(savef, mlist); /* rogue.c */ + rs_write_monster_list(savef, tlist); /* rogue.c */ + + rs_write_traps(savef, traps, MAXTRAPS); /* rogue.c */ + + armor = find_list_ptr(player.t_pack, cur_armor); + rs_write_int(savef, armor); /* rogue.c */ + + for (i = 0; i < NUM_FINGERS; i++) + { + ring = find_list_ptr(player.t_pack, cur_ring[i]); + rs_write_int(savef, ring); /* rogue.c */ + } + + for (i = 0; i < NUM_MM; i++) + { + misc = find_list_ptr(player.t_pack, cur_misc[i]); + rs_write_int(savef, misc); /* rogue.c */ + } + + for (i=0; i<MAXRELIC; i++) + rs_write_int(savef,cur_relic[i]); /* rogue.c */ + + + rs_write_rooms(savef, rooms, MAXROOMS); /* rogue.c */ + + for (i = 0; i < MAXROOMS; i++) + if (&rooms[i] == oldrp) + room = i; + rs_write_int(savef, room); /* rogue.c */ + + weapon = find_list_ptr(player.t_pack, cur_weapon); + rs_write_int(savef, weapon); /* rogue..c */ + rs_write_int(savef,char_type); + rs_write_int(savef,foodlev); + rs_write_int(savef,ntraps); + rs_write_int(savef,trader); + rs_write_int(savef,curprice); + rs_write_int(savef,seed); + rs_write_int(savef,max_level); + rs_write_int(savef,cur_max); + rs_write_int(savef,prev_max); + rs_write_int(savef,move_free); + rs_write_int(savef,mpos); + rs_write_int(savef,level); + rs_write_long(savef,purse); + rs_write_int(savef,inpack); + rs_write_int(savef,total); + rs_write_int(savef,no_food); + rs_write_int(savef,foods_this_level); + rs_write_int(savef,count); + rs_write_int(savef,food_left); + rs_write_int(savef,group); + rs_write_int(savef,hungry_state); + rs_write_int(savef,infest_dam); + rs_write_int(savef,lost_str); + rs_write_int(savef,lastscore); + rs_write_int(savef,hold_count); + rs_write_int(savef,trap_tries); + rs_write_int(savef,chant_time); + rs_write_int(savef,pray_time); + rs_write_int(savef,spell_power); + rs_write_long(savef,turns); + rs_write_int(savef,quest_item); + rs_write_int(savef,cols); + rs_write_int(savef,lines); + rs_write_int(savef,nfloors); + rs_write(savef,curpurch,LINELEN); + rs_write_char(savef,PLAYER); + rs_write_char(savef,take); + rs_write_int(savef,1234);/*checkpoint*/ + rs_write(savef,prbuf,LINELEN*2); + rs_write_int(savef,1234);/*checkpoint*/ + rs_write_char(savef,runch); + rs_write_int(savef,1234);/*checkpoint*/ + rs_write_scrolls(savef); + rs_write_potions(savef); + rs_write_rings(savef); + rs_write_sticks(savef); + rs_write_misc(savef); + rs_write_int(savef,1234);/*checkpoint*/ + rs_write(savef,whoami,LINELEN); + rs_write_window(savef, cw); + rs_write_window(savef, hw); + rs_write_window(savef, mw); + rs_write_window(savef, msgw); + rs_write_window(savef, stdscr); + rs_write_boolean(savef,pool_teleport); + rs_write_boolean(savef,inwhgt); + rs_write_boolean(savef,after); + rs_write_boolean(savef,waswizard); + rs_write_boolean(savef, playing); /* rogue.h/init.c */ + rs_write_boolean(savef, running); /* rogue.h/init.c */ + rs_write_boolean(savef, wizard); /* rogue.h/init.c */ + rs_write_boolean(savef, notify); /* rogue.h/init.c */ + rs_write_boolean(savef, fight_flush); /* rogue.h/init.c */ + rs_write_boolean(savef, terse); /* rogue.h/init.c */ + rs_write_boolean(savef, auto_pickup); /* rogue.h/init.c */ + rs_write_boolean(savef, def_attr); /* rogue.h/init.c */ + rs_write_boolean(savef, menu_overlay); /* rogue.h/init.c */ + rs_write_boolean(savef, door_stop); /* rogue.h/init.c */ + rs_write_boolean(savef, jump); /* rogue.h/init.c */ + rs_write_boolean(savef, slow_invent); /* rogue.h/init.c */ + rs_write_boolean(savef, firstmove); /* rogue.h/init.c */ + rs_write_boolean(savef, askme); /* rogue.h/init.c */ + rs_write_boolean(savef, in_shell); /* rogue.h/init.c */ + rs_write_boolean(savef, daytime); /* rogue.h/init.c */ + rs_write_boolean(savef, funfont); /* rogue.h/init.c */ + rs_write_levtype(savef,levtype); + rs_write_character_types(savef,char_class,NUM_CHARTYPES); + rs_write_words(savef,abilities,NUMABILITIES); + for(i=0;i<9;i++) + rs_write_coord(savef,&grid[i]); + rs_write_death_types(savef,deaths,DEATHNUM); + rs_write_init_weps(savef,weaps,MAXWEAPONS); + rs_write_init_armor(savef,armors,MAXARMORS); + rs_write_magic_items(savef, things, NUMTHINGS); /* rogue.h/init.c */ + rs_write_magic_items(savef, s_magic, MAXSCROLLS); /* rogue.h/init.c */ + rs_write_magic_items(savef, p_magic, MAXPOTIONS); /* rogue.h/init.c */ + rs_write_magic_items(savef, r_magic, MAXRINGS); /* rogue.h/init.c */ + rs_write_magic_items(savef, ws_magic, MAXSTICKS); /* rogue.h/init.c */ + rs_write_magic_items(savef, m_magic, MAXMM); /* rogue.h/init.c */ + rs_write_magic_items(savef, rel_magic, MAXRELIC); /* rogue.h/init.c */ + rs_write_magic_items(savef, foods, MAXFOODS); /* rogue.h/init.c */ + rs_write_spells(savef,magic_spells,MAXSPELLS); + rs_write_spells(savef,cleric_spells,MAXPRAYERS); + rs_write_spells(savef,druid_spells,MAXCHANTS); + rs_write_spells(savef,quill_scrolls,MAXQUILL); + + rs_write_int(savef,mf_count); /* actions.c */ + rs_write_int(savef,mf_jmpcnt); /* actions.c */ + rs_write_daemons(savef, d_list, MAXDAEMONS); /* daemon.c */ + rs_write_daemons(savef, f_list, MAXFUSES); /* daemon.c */ + rs_write_int(savef,demoncnt); /* daemon.c */ + rs_write_int(savef,fusecnt); /* daemon.c */ + rs_write_int(savef,killed_chance); /* fight.c */ + rs_write_words(savef,rainbow,NCOLORS); /* init.c */ + rs_write_words(savef,sylls,NSYLLS); /* init.c */ + rs_write_words(savef,stones,NSTONES); /* init.c */ + rs_write_words(savef,wood,NWOOD); /* init.c */ + rs_write_words(savef,metal,NMETAL); /* init.c */ + rs_write_monsters(savef,monsters, + sizeof(monsters)/sizeof(struct monster)); /* mons_def.c */ + rs_write_coord(savef,&move_nh); /* move.c */ + return(WRITESTAT); +} + +rs_restore_file(int inf) +{ + int weapon, armor, ring, misc, room = -1,i,checkpoint; + int endian = 0x01020304; + big_endian = ( *((char *)&endian) == 0x01 ); + + rs_read_thing(inf, &player); /* rogue.h */ + rs_read_object_list(inf, &lvl_obj); /* rogue.h/init.c */ + rs_read_monster_list(inf, &mlist); /* rogue.h/init.c */ + rs_read_monster_list(inf, &tlist); /* rogue.h/init.c */ + rs_fix_thing(&player); + rs_fix_monster_list(mlist); + rs_read_traps(inf, traps, MAXTRAPS); + + + rs_read_int(inf, &armor); /* rogue.h */ + cur_armor = get_list_item(player.t_pack,armor); + + for(i = 0; i < NUM_FINGERS; i++) + { + rs_read_int(inf,&ring); + cur_ring[i] = get_list_item(player.t_pack,ring); + } + + for(i = 0; i < NUM_MM; i++) + { + rs_read_int(inf,&misc); + cur_misc[i] = get_list_item(player.t_pack,misc); + } + + for(i=0;i<MAXRELIC;i++) + rs_read_int(inf,&cur_relic[i]); + + rs_read_rooms(inf, rooms, MAXROOMS); + rs_read_int(inf, &room); + + oldrp = &rooms[room]; + + rs_read_int(inf,&weapon); + cur_weapon = get_list_item(player.t_pack,weapon); + + rs_read_int(inf,&char_type); + rs_read_int(inf,&foodlev); + rs_read_int(inf,&ntraps); + rs_read_int(inf,&trader); + rs_read_int(inf,&curprice); + rs_read_int(inf,&seed); + rs_read_int(inf,&max_level); + rs_read_int(inf,&cur_max); + rs_read_int(inf,&prev_max); + rs_read_int(inf,&move_free); + rs_read_int(inf,&mpos); + rs_read_int(inf,&level); + rs_read_long(inf,&purse); + rs_read_int(inf,&inpack); + rs_read_int(inf,&total); + rs_read_int(inf,&no_food); + rs_read_int(inf,&foods_this_level); + rs_read_int(inf,&count); + rs_read_int(inf,&food_left); + rs_read_int(inf,&group); + rs_read_int(inf,&hungry_state); + rs_read_int(inf,&infest_dam); + rs_read_int(inf,&lost_str); + rs_read_int(inf,&lastscore); + rs_read_int(inf,&hold_count); + rs_read_int(inf,&trap_tries); + rs_read_int(inf,&chant_time); + rs_read_int(inf,&pray_time); + rs_read_int(inf,&spell_power); + rs_read_long(inf,&turns); + rs_read_int(inf,&quest_item); + rs_read_int(inf,&cols); + rs_read_int(inf,&lines); + rs_read_int(inf,&nfloors); + rs_read(inf,curpurch,LINELEN); + rs_read_char(inf,&PLAYER); + rs_read_char(inf,&take); + rs_read_int(inf,&checkpoint); + if (checkpoint != 1234){printf("Checkpoint failed");abort();} + rs_read(inf,prbuf,LINELEN*2); + rs_read_int(inf,&checkpoint); + if (checkpoint != 1234){printf("Checkpoint failed");abort();} + rs_read_char(inf,&runch); + rs_read_int(inf,&checkpoint); + if (checkpoint != 1234){printf("Checkpoint failed");abort();} + rs_read_scrolls(inf); + rs_read_potions(inf); + rs_read_rings(inf); + rs_read_sticks(inf); + rs_read_misc(inf); + rs_read_int(inf,&checkpoint); + if (checkpoint != 1234){printf("Checkpoint failed");abort();} + rs_read(inf,whoami,LINELEN); + rs_read_window(inf, cw); + rs_read_window(inf, hw); + rs_read_window(inf, mw); + rs_read_window(inf, msgw); + rs_read_window(inf, stdscr); + rs_read_boolean(inf,&pool_teleport); + rs_read_boolean(inf,&inwhgt); + rs_read_boolean(inf,&after); + rs_read_boolean(inf,&waswizard); + rs_read_boolean(inf, &playing); /* rogue.h/init.c */ + rs_read_boolean(inf, &running); /* rogue.h/init.c */ + rs_read_boolean(inf, &wizard); /* rogue.h/init.c */ + rs_read_boolean(inf, ¬ify); /* rogue.h/init.c */ + rs_read_boolean(inf, &fight_flush); /* rogue.h/init.c */ + rs_read_boolean(inf, &terse); /* rogue.h/init.c */ + rs_read_boolean(inf, &auto_pickup); /* rogue.h/init.c */ + rs_read_boolean(inf, &def_attr); /* rogue.h/init.c */ + rs_read_boolean(inf, &menu_overlay); /* rogue.h/init.c */ + rs_read_boolean(inf, &door_stop); /* rogue.h/init.c */ + rs_read_boolean(inf, &jump); /* rogue.h/init.c */ + rs_read_boolean(inf, &slow_invent); /* rogue.h/init.c */ + rs_read_boolean(inf, &firstmove); /* rogue.h/init.c */ + rs_read_boolean(inf, &askme); /* rogue.h/init.c */ + rs_read_boolean(inf, &in_shell); /* rogue.h/init.c */ + rs_read_boolean(inf, &daytime); /* rogue.h/init.c */ + rs_read_boolean(inf, &funfont); /* rogue.h/init.c */ + rs_read_levtype(inf,&levtype); + rs_read_character_types(inf,char_class,NUM_CHARTYPES); + rs_read_words(inf,abilities,NUMABILITIES); + for(i=0;i<9;i++) + rs_read_coord(inf,&grid[i]); + rs_read_death_types(inf,deaths,DEATHNUM); + rs_read_init_weps(inf,weaps,MAXWEAPONS); + rs_read_init_armor(inf,armors,MAXARMORS); + rs_read_magic_items(inf, things,NUMTHINGS); /* rogue.h/init.c */ + rs_read_magic_items(inf, s_magic,MAXSCROLLS); /* rogue.h/init.c */ + rs_read_magic_items(inf, p_magic,MAXPOTIONS); /* rogue.h/init.c */ + rs_read_magic_items(inf, r_magic,MAXRINGS); /* rogue.h/init.c */ + rs_read_magic_items(inf, ws_magic,MAXSTICKS); /* rogue.h/init.c */ + rs_read_magic_items(inf, m_magic,MAXMM); /* rogue.h/init.c */ + rs_read_magic_items(inf, rel_magic,MAXRELIC); /* rogue.h/init.c */ + rs_read_magic_items(inf, foods,MAXFOODS); /* rogue.h/init.c */ + rs_read_spells(inf,magic_spells,MAXSPELLS); + rs_read_spells(inf,cleric_spells,MAXPRAYERS); + rs_read_spells(inf,druid_spells,MAXCHANTS); + rs_read_spells(inf,quill_scrolls,MAXQUILL); + + rs_read_int(inf,&mf_count); /* actions.c */ + rs_read_int(inf,&mf_jmpcnt); /* actions.c */ + rs_read_daemons(inf, d_list, MAXDAEMONS); /* daemon.c */ + rs_read_daemons(inf, f_list, MAXFUSES); /* daemon.c */ + rs_read_int(inf,&demoncnt); /* daemon.c */ + rs_read_int(inf,&fusecnt); /* daemon.c */ + rs_read_int(inf,&killed_chance); /* fight.c */ + rs_read_words(inf,rainbow,NCOLORS); /* init.c */ + rs_read_words(inf,sylls,NSYLLS); /* init.c */ + rs_read_words(inf,stones,NSTONES); /* init.c */ + rs_read_words(inf,wood,NWOOD); /* init.c */ + rs_read_words(inf,metal,NMETAL); /* init.c */ + + rs_read_monsters(inf,monsters, + sizeof(monsters)/sizeof(struct monster)); /* mons_def.c */ + rs_read_coord(inf,&move_nh); /* move.c */ + + return(READSTAT); +} + +rs_write_scorefile(FILE *savef, struct sc_ent *entries, int count) +{ + int i; + + rs_write_int(savef, count); + for(i = 0; i < count; i++) + { + rs_write_ulong(savef, entries[i].sc_score); + rs_write(savef, entries[i].sc_name, sizeof(entries[i].sc_name)); + rs_write(savef, entries[i].sc_system, sizeof(entries[i].sc_system)); + rs_write(savef, entries[i].sc_login, sizeof(entries[i].sc_login)); + rs_write_short(savef, entries[i].sc_flags); + rs_write_short(savef, entries[i].sc_level); + rs_write_short(savef, entries[i].sc_ctype); + rs_write_short(savef, entries[i].sc_monster); + rs_write_short(savef, entries[i].sc_quest); + } +} + +rs_read_scorefile(FILE *savef, struct sc_ent *entries, int count) +{ + int i,available = 0; + + rs_read_int(fileno(savef), &available); + + if (end_of_file) + return(-1); + + if (available != count) + return(-2); + + for(i = 0; i < count; i++) + { + rs_read_ulong(fileno(savef), &entries[i].sc_score); + rs_read(fileno(savef), entries[i].sc_name, sizeof(entries[i].sc_name)); + rs_read(fileno(savef), entries[i].sc_system, sizeof(entries[i].sc_system)); + rs_read(fileno(savef), entries[i].sc_login, sizeof(entries[i].sc_login)); + rs_read_short(fileno(savef), &entries[i].sc_flags); + rs_read_short(fileno(savef), &entries[i].sc_level); + rs_read_short(fileno(savef), &entries[i].sc_ctype); + rs_read_short(fileno(savef), &entries[i].sc_monster); + rs_read_short(fileno(savef), &entries[i].sc_quest); + } + + return(0); +} + + + +rs_print_thing(FILE *outf, struct thing *thing, char *prefix, int list, int index) +{ + int i; + + fprintf(outf,"%sList Ident : %d\n", prefix, list); + fprintf(outf,"%sList Index : %d\n", prefix, index); + fprintf(outf,"%st_wasshot : %d\n", prefix, thing->t_wasshot); + fprintf(outf,"%st_type : %c\n", prefix, thing->t_type); + fprintf(outf,"%st_disguise : %c\n", prefix, thing->t_disguise); + fprintf(outf,"%st_oldch : %c\n", prefix, thing->t_oldch); + fprintf(outf,"%st_ctype : %d\n", prefix, thing->t_ctype); + fprintf(outf,"%st_index : %d\n", prefix, thing->t_index); + fprintf(outf,"%st_no_move : %d\n", prefix, thing->t_no_move); + fprintf(outf,"%st_quiet : %d\n", prefix, thing->t_quiet); + fprintf(outf,"%st_movement : %d\n", prefix, thing->t_movement); + fprintf(outf,"%st_action : %d\n", prefix, thing->t_action); + fprintf(outf,"%st_artificat: %d\n", prefix, thing->t_artifact); + fprintf(outf,"%st_wand : %d\n", prefix, thing->t_wand); + fprintf(outf,"%st_summon : %d\n", prefix, thing->t_summon); + fprintf(outf,"%st_cast : %d\n", prefix, thing->t_cast); + fprintf(outf,"%st_breathe : %d\n", prefix, thing->t_breathe); + fprintf(outf,"%st_name : %s\n", prefix, (thing->t_name == NULL) ? "none" : + thing->t_name); + fprintf(outf,"%st_doorgoal : %d %d\n", prefix, thing->t_doorgoal.x, thing->t_doorgoal.y); + fprintf(outf,"%st_dest : %p\n", prefix, thing->t_dest); + fprintf(outf,"%st_pos : %d %d (%p)\n", prefix, thing->t_pos.x, thing->t_pos.y,&thing->t_pos); + fprintf(outf,"%st_oldpos : %d %d\n", prefix, thing->t_oldpos.x, thing->t_oldpos.y); + fprintf(outf,"%st_newpos : %d %d\n", prefix, thing->t_newpos.x, thing->t_newpos.y); + fprintf(outf,"%st_flags : ", prefix); + + for(i = 0; i<16; i++) + fprintf(outf,"%X ",thing->t_flags[i]); + fprintf(outf,"\n"); + + fprintf(outf,"%st_pack : %p\n",prefix,thing->t_pack); + fprintf(outf,"%st_using : %p\n",prefix,thing->t_using); + fprintf(outf,"%st_stats : Not Implemented\n",prefix); + fprintf(outf,"%st_maxstats : Not Implemented\n",prefix); + fprintf(outf,"%st_reserved : %d\n",prefix,thing->t_reserved); +} + +rs_print_game_state(FILE *outf) +{ + fprintf(outf, "Player\n"); + + rs_print_thing(outf, &player, " ", 0, 0); +} + +/**** + Machine Dependent Functions + + md_getuid() + md_memused() + md_getusername() + md_gethostname() + md_gethomedir() + md_getroguedir() + md_getshell() + md_shellescape() + md_getpass() + md_crypt() + md_htons() + md_nstoh() + md_unlink() + md_isdir() + md_ntohl() + md_htonl() + +****/ + +int +md_rand(range) +register int range; +{ +#ifdef _WIN32 + return(range <= 0 ? 0 : rand() % range); +#else + return(range <= 0 ? 0 : random() % range); +#endif +} + +int +md_srand(seed) +register int seed; +{ +#ifdef _WIN32 + srand(seed); +#else + srandom(seed); +#endif +} + +void +md_flushinp() +{ + /* ioctl(0,TIOCFLUSH) */ + /* ioctl(_tty_ch,TCFLSH,0) */ + flushinp(); +} + +int +md_getuid() +{ +#ifdef _WIN32 + return(42); +#else + return(getuid()); +#endif +} + +long +md_memused() +{ +#ifdef _WIN32 + MEMORYSTATUS stat; + + GlobalMemoryStatus(&stat); + + return((long)stat.dwTotalPageFile); +#else + return( (long)sbrk(0) ); +#endif +} + +char * +md_getusername() +{ + static char login[80]; + char *l = NULL; +#ifdef _WIN32 + LPSTR mybuffer; + DWORD size = UNLEN + 1; + TCHAR buffer[UNLEN + 1]; + + mybuffer = buffer; + GetUserName(mybuffer,&size); + l = mybuffer; +#endif +#if !defined(_WIN32) && !defined(DJGPP) + struct passwd *pw; + + pw = getpwuid(getuid()); + + l = pw->pw_name; +#endif + + if ((l == NULL) || (*l == '\0')) + if ( (l = getenv("USERNAME")) == NULL ) + if ( (l = getenv("LOGNAME")) == NULL ) + if ( (l = getenv("USER")) == NULL ) + l = "nobody"; + + strncpy(login,l,80); + login[79] = 0; + + return(login); +} + +char * +md_gethomedir() +{ + static char homedir[PATH_MAX]; + char *h = NULL; + size_t len; +#if defined(_WIN32) + TCHAR szPath[MAX_PATH]; +#endif +#if defined(_WIN32) || defined(DJGPP) + char slash = '\\'; +#else + char slash = '/'; + struct passwd *pw; + pw = getpwuid(getuid()); + + h = pw->pw_dir; + + if (strcmp(h,"/") == 0) + h = NULL; +#endif + homedir[0] = 0; + +#ifdef _WIN32 + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath))) + h = szPath; +#endif + + if ( (h == NULL) || (*h == '\0') ) + if ( (h = getenv("HOME")) == NULL ) + if ( (h = getenv("HOMEDRIVE")) == NULL) + h = ""; + else + { + strncpy(homedir,h,PATH_MAX-1); + homedir[PATH_MAX-1] = 0; + + if ( (h = getenv("HOMEPATH")) == NULL) + h = ""; + } + + + len = strlen(homedir); + strncat(homedir,h,PATH_MAX-len-1); + len = strlen(homedir); + + if ((len > 0) && (homedir[len-1] != slash)) { + homedir[len] = slash; + homedir[len+1] = 0; + } + + return(homedir); +} + +int +directory_exists(char *dirname) +{ + struct stat sb; + + if (stat(dirname, &sb) == 0) /* path exists */ + return (sb.st_mode & S_IFDIR); + + return(0); +} + +char * +md_getroguedir() +{ + static char path[1024]; + char *end,*home; + + if ( (home = getenv("ROGUEHOME")) != NULL) + { + if (*home) + { + strncpy(path, home, PATH_MAX - 20); + + end = &path[strlen(path)-1]; + + + while( (end >= path) && ((*end == '/') || (*end == '\\'))) + *end-- = '\0'; + + if (directory_exists(path)) + return(path); + } + } + + if (directory_exists("/var/games/roguelike")) + return("/var/games/roguelike"); + if (directory_exists("/var/lib/roguelike")) + return("/var/lib/roguelike"); + if (directory_exists("/var/roguelike")) + return("/var/roguelike"); + if (directory_exists("/usr/games/lib")) + return("/usr/games/lib"); + if (directory_exists("/games/roguelik")) + return("/games/roguelik"); + + return(""); +} + +char * +md_getshell() +{ + static char shell[PATH_MAX]; + char *s = NULL; +#ifdef _WIN32 + char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE"; +#elif defined(__DJGPP__) + char *def = "C:\\COMMAND.COM"; +#else + char *def = "/bin/sh"; + struct passwd *pw; + pw = getpwuid(getuid()); + s = pw->pw_shell; +#endif + if ((s == NULL) || (*s == '\0')) + if ( (s = getenv("COMSPEC")) == NULL) + if ( (s = getenv("SHELL")) == NULL) + if ( (s = getenv("SystemRoot")) == NULL) + s = def; + + strncpy(shell,s,PATH_MAX); + shell[PATH_MAX-1] = 0; + + return(shell); +} + +char * +md_gethostname() +{ + static char nodename[80]; + char *n = NULL; +#if !defined(_WIN32) && !defined(__DJGPP__) + struct utsname ourname; + + if (uname(&ourname) == 0) + n = ourname.nodename; +#endif + if ((n == NULL) || (*n == '\0')) + if ( (n = getenv("COMPUTERNAME")) == NULL) + if ( (n = getenv("HOSTNAME")) == NULL) + n = "localhost"; + + strncpy(nodename, n, 80); + nodename[79] = 0; + + return(nodename); +} + +int +md_shellescape() +{ +#if (!defined(_WIN32) && !defined(__DJGPP__)) + int ret_status; + int pid; +#endif + char *sh; + + sh = md_getshell(); + +#if defined(_WIN32) + return(_spawnl(_P_WAIT,sh,"shell",NULL,0)); +#elif defined(__DJGPP__) + return ( spawnl(P_WAIT,sh,"shell",NULL,0) ); +#else + while((pid = fork()) < 0) + sleep(1); + + if (pid == 0) /* Shell Process */ + { + /* + * Set back to original user, just in case + */ + setuid(getuid()); + setgid(getgid()); + execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", 0); + perror("No shelly"); + _exit(-1); + } + else /* Application */ + { + while (wait(&ret_status) != pid) + continue; + } + + return(ret_status); +#endif +} + +int +md_erasechar() +{ +/* + return(_tty.sg_erase); + return(_tty.c_cc[VERASE]); +*/ + return(erasechar()); +} + +int +md_killchar() +{ +/* + return(_tty.sg_kill); + return(_tty.c_cc[VKILL]); +*/ + return(killchar()); +} + +long +md_ntohl(netlong) +long netlong; +{ + return( ntohl(netlong) ); +} + +long +md_htonl(netlong) +long netlong; +{ + return(htonl(netlong)); +} + +void +md_init() +{ +#ifdef __INTERIX + char *term; + + term = getenv("TERM"); + + if (term == NULL) + setenv("TERM","interix"); +#endif +#if defined(__DJGPP__) || defined(_WIN32) + _fmode = _O_BINARY; +#endif +} + +char * +md_getpass(prompt) +char *prompt; +{ +#ifdef _WIN32 + static char password_buffer[9]; + char *p = password_buffer; + int c, count = 0; + int max_length = 9; + + fflush(stdout); + /* If we can't prompt, abort */ + if (fputs(prompt, stderr) < 0) + { + *p = '\0'; + return NULL; + } + + for(;;) + { + /* Get a character with no echo */ + c = _getch(); + + /* Exit on interrupt (^c or ^break) */ + if (c == '\003' || c == 0x100) + exit(1); + + /* Terminate on end of line or file (^j, ^m, ^d, ^z) */ + if (c == '\r' || c == '\n' || c == '\004' || c == '\032') + break; + + /* Back up on backspace */ + if (c == '\b') + { + if (count) + count--; + else if (p > password_buffer) + p--; + continue; + } + + /* Ignore DOS extended characters */ + if ((c & 0xff) != c) + continue; + + /* Add to password if it isn't full */ + if (p < password_buffer + max_length - 1) + *p++ = c; + else + count++; + } + *p = '\0'; + + fputc('\n', stderr); + + return password_buffer; +#else + return( (char *) getpass(prompt) ); +#endif +} + +#ifdef SIGTSTP + +/* + * handle stop and start signals + */ + +/*UNUSED*/ +void +tstp(a) +int a; +{ + mvcur(0, cols - 1, lines - 1, 0); + fflush(stdout); + kill(0, SIGTSTP); + signal(SIGTSTP, tstp); + crmode(); + noecho(); + clearok(curscr, TRUE); + touchwin(cw); + draw(cw); + flushinp(); +} +#endif + +int +md_setup() +{ +#ifdef SIGTSTP + signal(SIGTSTP, tstp); +#endif +#ifdef SIGHUP + signal(SIGHUP, auto_save); +#endif + signal(SIGTERM, auto_save); + signal(SIGINT, quit); +#ifdef SIGQUIT + signal(SIGQUIT, endit); +#endif +#if defined(__CYGWIN__) || defined(__MSYS__) + ESCDELAY = 250; +#endif + crmode(); /* Cbreak mode */ + noecho(); /* Echo off */ +}