zlib support; also internal compression changes
o Add support for zlib compression via ZLIB_COMP in config.h (ZLIB_COMP and COMPRESS are mutually exclusive). o rlecomp and zerocomp are run time options available if RLECOMP and ZEROCOMP are defined, but not turned on by default if either COMPRESS or ZLIB_COMP are defined. o Add information to the save file about internal compression options used when writing the save file, particularly rlecomp and zerocomp support. o Automatically adjust rlecomp and zerocomp (if support compiled in) when reading in an existing savefile that was saved with those options turned on. Still allows writing out of savefile in preferred format. o In order to support zlib and not conflict with compress and uncompress routines there, the NetHack internal functions were changed to nh_uncompress and nh_compress as done in the zlib contribution received in 1999 from <Someone>. I tagged the sources NETHACK_3_5_0_PREZLIB prior to applying these changes.
This commit is contained in:
@@ -427,12 +427,14 @@ getbones()
|
||||
fd = open_bonesfile(&u.uz, &bonesid);
|
||||
if (fd < 0) return(0);
|
||||
|
||||
if ((ok = uptodate(fd, bones)) == 0) {
|
||||
if (validate(fd, bones) != 0) {
|
||||
#ifdef WIZARD
|
||||
if (!wizard)
|
||||
#endif
|
||||
pline("Discarding unuseable bones; no need to panic...");
|
||||
ok = FALSE;
|
||||
} else {
|
||||
ok = TRUE;
|
||||
#ifdef WIZARD
|
||||
if(wizard) {
|
||||
if(yn("Get bones?") == 'n') {
|
||||
|
||||
46
src/decl.c
46
src/decl.c
@@ -275,6 +275,52 @@ char *fqn_prefix_names[PREFIX_COUNT] = { "hackdir", "leveldir", "savedir",
|
||||
"lockdir", "configdir", "troubledir" };
|
||||
#endif
|
||||
|
||||
NEARDATA struct savefile_info sfcap = {
|
||||
#ifdef NHSTDC
|
||||
0x00000000UL
|
||||
#else
|
||||
0x00000000L
|
||||
#endif
|
||||
#if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
| SFI1_EXTERNALCOMP
|
||||
#endif
|
||||
#if defined(ZEROCOMP)
|
||||
| SFI1_ZEROCOMP
|
||||
#endif
|
||||
#if defined(RLECOMP)
|
||||
| SFI1_RLECOMP
|
||||
#endif
|
||||
,
|
||||
#ifdef NHSTDC
|
||||
0x00000000UL, 0x00000000UL
|
||||
#else
|
||||
0x00000000L, 0x00000000L
|
||||
#endif
|
||||
};
|
||||
|
||||
NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = {
|
||||
#ifdef NHSTDC
|
||||
0x00000000UL
|
||||
#else
|
||||
0x00000000L
|
||||
#endif
|
||||
#if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
| SFI1_EXTERNALCOMP
|
||||
#endif
|
||||
#if defined(ZEROCOMP)
|
||||
| SFI1_ZEROCOMP
|
||||
#endif
|
||||
#if defined(RLECOMP)
|
||||
| SFI1_RLECOMP
|
||||
#endif
|
||||
,
|
||||
#ifdef NHSTDC
|
||||
0x00000000UL, 0x00000000UL
|
||||
#else
|
||||
0x00000000L, 0x00000000L
|
||||
#endif
|
||||
};
|
||||
|
||||
/* dummy routine used to force linkage */
|
||||
void
|
||||
decl_init()
|
||||
|
||||
205
src/files.c
205
src/files.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)files.c 3.5 2004/11/22 */
|
||||
/* SCCS Id: @(#)files.c 3.5 2005/01/04 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -32,6 +32,13 @@ const
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef ZLIB_COMP /* RLC 09 Mar 1999: Support internal ZLIB */
|
||||
#include "zlib.h"
|
||||
# ifndef COMPRESS_EXTENSION
|
||||
#define COMPRESS_EXTENSION ".gz"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(UNIX) && defined(QT_GRAPHICS)
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
@@ -158,6 +165,8 @@ STATIC_DCL char *FDECL(set_bonesfile_name, (char *,d_level*));
|
||||
STATIC_DCL char *NDECL(set_bonestemp_name);
|
||||
#ifdef COMPRESS
|
||||
STATIC_DCL void FDECL(redirect, (const char *,const char *,FILE *,BOOLEAN_P));
|
||||
#endif
|
||||
#if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
STATIC_DCL void FDECL(docompress_file, (const char *,BOOLEAN_P));
|
||||
#endif
|
||||
STATIC_DCL char *FDECL(make_lockname, (const char *,char *));
|
||||
@@ -770,7 +779,7 @@ char **bonesid;
|
||||
|
||||
*bonesid = set_bonesfile_name(bones, lev);
|
||||
fq_bones = fqname(bones, BONESPREFIX, 0);
|
||||
uncompress(fq_bones); /* no effect if nonexistent */
|
||||
nh_uncompress(fq_bones); /* no effect if nonexistent */
|
||||
#ifdef MAC
|
||||
fd = macopen(fq_bones, O_RDONLY | O_BINARY, BONE_TYPE);
|
||||
#else
|
||||
@@ -794,7 +803,7 @@ d_level *lev;
|
||||
void
|
||||
compress_bonesfile()
|
||||
{
|
||||
compress(fqname(bones, BONESPREFIX, 0));
|
||||
nh_compress(fqname(bones, BONESPREFIX, 0));
|
||||
}
|
||||
|
||||
/* ---------- END BONES FILE HANDLING ----------- */
|
||||
@@ -945,6 +954,7 @@ restore_saved_game()
|
||||
const char *fq_save;
|
||||
int fd;
|
||||
|
||||
reset_restpref();
|
||||
set_savefile_name();
|
||||
#ifdef MFLOPPY
|
||||
if (!saveDiskPrompt(1))
|
||||
@@ -952,10 +962,10 @@ restore_saved_game()
|
||||
#endif /* MFLOPPY */
|
||||
fq_save = fqname(SAVEF, SAVEPREFIX, 0);
|
||||
|
||||
uncompress(fq_save);
|
||||
nh_uncompress(fq_save);
|
||||
if ((fd = open_savefile()) < 0) return fd;
|
||||
|
||||
if (!uptodate(fd, fq_save)) {
|
||||
if (validate(fd, fq_save) != 0) {
|
||||
(void) close(fd), fd = -1;
|
||||
(void) delete_savefile();
|
||||
}
|
||||
@@ -975,16 +985,16 @@ const char* filename;
|
||||
# ifdef COMPRESS_EXTENSION
|
||||
SAVEF[strlen(SAVEF)-strlen(COMPRESS_EXTENSION)] = '\0';
|
||||
# endif
|
||||
uncompress(SAVEF);
|
||||
nh_uncompress(SAVEF);
|
||||
if ((fd = open_savefile()) >= 0) {
|
||||
if (uptodate(fd, filename)) {
|
||||
if (validate(fd, filename)==0) {
|
||||
char tplname[PL_NSIZ];
|
||||
get_plname_from_file(fd, tplname);
|
||||
result = strdup(tplname);
|
||||
}
|
||||
(void) close(fd);
|
||||
}
|
||||
compress(SAVEF);
|
||||
nh_compress(SAVEF);
|
||||
|
||||
return result;
|
||||
# if 0
|
||||
@@ -1033,6 +1043,9 @@ get_saved_games()
|
||||
(void)fname_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.",
|
||||
'%', fnamebuf, encodedfnamebuf, BUFSZ);
|
||||
Sprintf(SAVEF, "%s*.NetHack-saved-game", encodedfnamebuf);
|
||||
#if defined(ZLIB_COMP)
|
||||
Strcat(SAVEF, COMPRESS_EXTENSION);
|
||||
#endif
|
||||
fq_save = fqname(SAVEF, SAVEPREFIX, 0);
|
||||
|
||||
n = 0;
|
||||
@@ -1278,10 +1291,10 @@ boolean uncomp;
|
||||
|
||||
/* compress file */
|
||||
void
|
||||
compress(filename)
|
||||
nh_compress(filename)
|
||||
const char *filename;
|
||||
{
|
||||
#ifndef COMPRESS
|
||||
#if !defined(COMPRESS) && !defined(ZLIB_COMP)
|
||||
#if (defined(macintosh) && (defined(__SC__) || defined(__MRC__))) || defined(__MWERKS__)
|
||||
# pragma unused(filename)
|
||||
#endif
|
||||
@@ -1293,10 +1306,10 @@ const char *filename;
|
||||
|
||||
/* uncompress file if it exists */
|
||||
void
|
||||
uncompress(filename)
|
||||
nh_uncompress(filename)
|
||||
const char *filename;
|
||||
{
|
||||
#ifndef COMPRESS
|
||||
#if !defined(COMPRESS) && !defined(ZLIB_COMP)
|
||||
#if (defined(macintosh) && (defined(__SC__) || defined(__MRC__))) || defined(__MWERKS__)
|
||||
# pragma unused(filename)
|
||||
#endif
|
||||
@@ -1305,6 +1318,174 @@ const char *filename;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ZLIB_COMP /* RLC 09 Mar 1999: Support internal ZLIB */
|
||||
static int
|
||||
make_compressed_name(filename,cfn)
|
||||
const char *filename;
|
||||
char *cfn;
|
||||
{
|
||||
#ifndef SHORT_FILENAMES
|
||||
/* Assume free-form filename */
|
||||
|
||||
strcpy(cfn, filename);
|
||||
strcat(cfn, COMPRESS_EXTENSION);
|
||||
return TRUE;
|
||||
#else
|
||||
/* Accomodates 8.3 restriction, but otherwise assumes free-form filenames.
|
||||
This may need to be revised for some systems. If a name cannot be
|
||||
generated, this function may return FALSE and the file will then remain
|
||||
uncompressed. */
|
||||
unsigned len;
|
||||
|
||||
/* Assume DOS style filename */
|
||||
|
||||
strcpy(cfn, filename);
|
||||
len = strlen(cfn);
|
||||
if (len>4 && stricmp(cfn+len-4,".sav")==0) {
|
||||
/* Save file; change .SAV extension to .SAZ */
|
||||
/* EMX/GCC (for OS/2) seems to miscompile cfn[len-1] */
|
||||
|
||||
cfn[strlen(cfn)-1]='z';
|
||||
return TRUE;
|
||||
} else if (strnicmp(cfn,"bones",5)==0) {
|
||||
/* Bones file; change BONES prefix to BONEZ */
|
||||
|
||||
cfn[4]='z';
|
||||
return TRUE;
|
||||
} else {
|
||||
/* Don't know how to convert this filename */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* !MSDOS */
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
docompress_file(filename, uncomp)
|
||||
const char *filename;
|
||||
boolean uncomp;
|
||||
{
|
||||
gzFile *compressedfile;
|
||||
FILE *uncompressedfile;
|
||||
char cfn[256];
|
||||
char buf[1024];
|
||||
unsigned len, len2;
|
||||
|
||||
if (!make_compressed_name(filename, cfn)) {
|
||||
/* Can't generate a name for the compressed file
|
||||
due to 8.3 restriction */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uncomp) {
|
||||
/* Open the input and output files */
|
||||
/* Note that gzopen takes "wb" as its mode, even on systems where
|
||||
fopen takes "r" and "w" */
|
||||
|
||||
uncompressedfile = fopen(filename, RDBMODE);
|
||||
if (uncompressedfile == NULL) {
|
||||
perror(filename);
|
||||
return;
|
||||
}
|
||||
compressedfile = gzopen(cfn, "wb");
|
||||
if (compressedfile == NULL) {
|
||||
if (errno == 0) {
|
||||
pline("zlib failed to allocate memory");
|
||||
} else {
|
||||
perror(filename);
|
||||
}
|
||||
fclose(uncompressedfile);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy from the uncompressed to the compressed file */
|
||||
|
||||
while (1) {
|
||||
len = fread(buf, 1, sizeof(buf), uncompressedfile);
|
||||
if (ferror(uncompressedfile)) {
|
||||
pline("Failure reading uncompressed file");
|
||||
pline("Can't compress %s.", filename);
|
||||
fclose(uncompressedfile);
|
||||
gzclose(compressedfile);
|
||||
(void)unlink(cfn);
|
||||
return;
|
||||
}
|
||||
if (len == 0) break; /* End of file */
|
||||
|
||||
len2 = gzwrite(compressedfile, buf, len);
|
||||
if (len2 == 0) {
|
||||
pline("Failure writing compressed file");
|
||||
pline("Can't compress %s.", filename);
|
||||
fclose(uncompressedfile);
|
||||
gzclose(compressedfile);
|
||||
(void)unlink(cfn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(uncompressedfile);
|
||||
gzclose(compressedfile);
|
||||
|
||||
/* Delete the file left behind */
|
||||
|
||||
(void)unlink(filename);
|
||||
|
||||
} else { /* uncomp */
|
||||
|
||||
/* Open the input and output files */
|
||||
/* Note that gzopen takes "rb" as its mode, even on systems where
|
||||
fopen takes "r" and "w" */
|
||||
|
||||
compressedfile = gzopen(cfn, "rb");
|
||||
if (compressedfile == NULL) {
|
||||
if (errno == 0) {
|
||||
pline("zlib failed to allocate memory");
|
||||
} else if (errno != ENOENT) {
|
||||
perror(filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
uncompressedfile = fopen(filename, WRBMODE);
|
||||
if (uncompressedfile == NULL) {
|
||||
perror(filename);
|
||||
gzclose(compressedfile);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy from the compressed to the uncompressed file */
|
||||
|
||||
while (1) {
|
||||
len = gzread(compressedfile, buf, sizeof(buf));
|
||||
if (len == (unsigned)-1) {
|
||||
pline("Failure reading compressed file");
|
||||
pline("Can't uncompress %s.", filename);
|
||||
fclose(uncompressedfile);
|
||||
gzclose(compressedfile);
|
||||
(void)unlink(filename);
|
||||
return;
|
||||
}
|
||||
if (len == 0) break; /* End of file */
|
||||
|
||||
fwrite(buf, 1, len, uncompressedfile);
|
||||
if (ferror(uncompressedfile)) {
|
||||
pline("Failure writing uncompressed file");
|
||||
pline("Can't uncompress %s.", filename);
|
||||
fclose(uncompressedfile);
|
||||
gzclose(compressedfile);
|
||||
(void)unlink(filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(uncompressedfile);
|
||||
gzclose(compressedfile);
|
||||
|
||||
/* Delete the file left behind */
|
||||
(void)unlink(cfn);
|
||||
}
|
||||
}
|
||||
#endif /* RLC 09 Mar 1999: End ZLIB patch */
|
||||
|
||||
/* ---------- END FILE COMPRESSION HANDLING ----------- */
|
||||
|
||||
|
||||
|
||||
@@ -165,6 +165,15 @@ static struct Bool_Opt
|
||||
{"rawio", (boolean *)0, FALSE, SET_IN_FILE},
|
||||
#endif
|
||||
{"rest_on_space", &flags.rest_on_space, FALSE, SET_IN_GAME},
|
||||
#ifdef RLECOMP
|
||||
{"rlecomp", &iflags.rlecomp,
|
||||
# if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
FALSE,
|
||||
# else
|
||||
TRUE,
|
||||
# endif
|
||||
DISP_IN_GAME},
|
||||
#endif
|
||||
{"safe_pet", &flags.safe_dog, TRUE, SET_IN_GAME},
|
||||
#ifdef WIZARD
|
||||
{"sanity_check", &iflags.sanity_check, FALSE, SET_IN_GAME},
|
||||
@@ -206,6 +215,15 @@ static struct Bool_Opt
|
||||
#endif
|
||||
{"verbose", &flags.verbose, TRUE, SET_IN_GAME},
|
||||
{"wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME},
|
||||
#ifdef ZEROCOMP
|
||||
{"zerocomp", &iflags.zerocomp,
|
||||
# if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
FALSE,
|
||||
# else
|
||||
TRUE,
|
||||
# endif
|
||||
DISP_IN_GAME},
|
||||
#endif
|
||||
{(char *)0, (boolean *)0, FALSE, 0}
|
||||
};
|
||||
|
||||
@@ -515,6 +533,23 @@ initoptions()
|
||||
if (boolopt[i].addr)
|
||||
*(boolopt[i].addr) = boolopt[i].initvalue;
|
||||
}
|
||||
#if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
set_savepref("externalcomp");
|
||||
set_restpref("externalcomp");
|
||||
# ifdef RLECOMP
|
||||
set_savepref("!rlecomp");
|
||||
set_restpref("!rlecomp");
|
||||
# endif
|
||||
#else
|
||||
# ifdef ZEROCOMP
|
||||
set_savepref("zerocomp");
|
||||
set_restpref("zerocomp");
|
||||
# endif
|
||||
# ifdef RLECOMP
|
||||
set_savepref("rlecomp");
|
||||
set_restpref("rlecomp");
|
||||
# endif
|
||||
#endif
|
||||
#ifdef SYSFLAGS
|
||||
Strcpy(sysflags.sysflagsid, "sysflags");
|
||||
sysflags.sysflagsid[9] = (char)sizeof(struct sysflag);
|
||||
@@ -2328,7 +2363,22 @@ goodfruit:
|
||||
# endif
|
||||
}
|
||||
#endif /* TERMLIB || ASCIIGRAPH || MAC_GRAPHICS_ENV */
|
||||
|
||||
#ifdef RLECOMP
|
||||
if ((boolopt[i].addr) == &iflags.rlecomp) {
|
||||
if (*boolopt[i].addr)
|
||||
set_savepref("rlecomp");
|
||||
else
|
||||
set_savepref("!rlecomp");
|
||||
}
|
||||
#endif
|
||||
#ifdef ZEROCOMP
|
||||
if ((boolopt[i].addr) == &iflags.zerocomp) {
|
||||
if (*boolopt[i].addr)
|
||||
set_savepref("zerocomp");
|
||||
else
|
||||
set_savepref("externalcomp");
|
||||
}
|
||||
#endif
|
||||
/* only do processing below if setting with doset() */
|
||||
if (initial) return;
|
||||
|
||||
|
||||
295
src/restore.c
295
src/restore.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)restore.c 3.5 2003/09/06 */
|
||||
/* SCCS Id: @(#)restore.c 3.5 2005/01/04 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -16,8 +16,14 @@ extern void FDECL(substitute_tiles, (d_level *)); /* from tile.c */
|
||||
#endif
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
static int NDECL(mgetc);
|
||||
STATIC_DCL void NDECL(zerocomp_minit);
|
||||
STATIC_DCL void FDECL(zerocomp_mread, (int,genericptr_t,unsigned int));
|
||||
STATIC_DCL int NDECL(zerocomp_mgetc);
|
||||
#endif
|
||||
|
||||
STATIC_DCL void NDECL(def_minit);
|
||||
STATIC_DCL void FDECL(def_mread, (int,genericptr_t,unsigned int));
|
||||
|
||||
STATIC_DCL void NDECL(find_lev_obj);
|
||||
STATIC_DCL void FDECL(restlevchn, (int));
|
||||
STATIC_DCL void FDECL(restdamage, (int,BOOLEAN_P));
|
||||
@@ -34,6 +40,27 @@ STATIC_DCL void FDECL(reset_oattached_mids, (BOOLEAN_P));
|
||||
#ifndef GOLDOBJ
|
||||
STATIC_DCL struct obj *FDECL(gold_in, (struct obj *));
|
||||
#endif
|
||||
STATIC_DCL void FDECL(rest_levl, (int,BOOLEAN_P));
|
||||
|
||||
static struct restore_procs {
|
||||
const char *name;
|
||||
int mread_flags;
|
||||
void NDECL((*restore_minit));
|
||||
void FDECL((*restore_mread), (int,genericptr_t,unsigned int));
|
||||
void FDECL((*restore_bclose), (int));
|
||||
} restoreprocs = {
|
||||
#if !defined(ZEROCOMP) || (defined(COMPRESS) || defined(ZLIB_COMP))
|
||||
"externalcomp", 0,
|
||||
def_minit,
|
||||
def_mread,
|
||||
def_bclose,
|
||||
#else
|
||||
"zerocomp", 0,
|
||||
zerocomp_minit,
|
||||
zerocomp_mread,
|
||||
zerocomp_bclose,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Save a mapping of IDs from ghost levels to the current level. This
|
||||
@@ -547,7 +574,7 @@ xchar ltmp;
|
||||
playwoRAMdisk();
|
||||
/* Rewind save file and try again */
|
||||
(void) lseek(fd, (off_t)0, 0);
|
||||
(void) uptodate(fd, (char *)0); /* skip version */
|
||||
(void) validate(fd, (char *)0); /* skip version etc */
|
||||
return dorecover(fd); /* 0 or 1 */
|
||||
} else {
|
||||
# endif
|
||||
@@ -624,12 +651,10 @@ register int fd;
|
||||
if (strncmpi("X11", windowprocs.name, 3))
|
||||
putstr(WIN_MAP, 0, "Restoring:");
|
||||
#endif
|
||||
restoreprocs.mread_flags = 1; /* return despite error */
|
||||
while(1) {
|
||||
#ifdef ZEROCOMP
|
||||
if(mread(fd, (genericptr_t) <mp, sizeof ltmp) < 0)
|
||||
#else
|
||||
if(read(fd, (genericptr_t) <mp, sizeof ltmp) != sizeof ltmp)
|
||||
#endif
|
||||
mread(fd, (genericptr_t) <mp, sizeof ltmp);
|
||||
if (restoreprocs.mread_flags == -1)
|
||||
break;
|
||||
getlev(fd, 0, ltmp, FALSE);
|
||||
#ifdef MICRO
|
||||
@@ -646,18 +671,24 @@ register int fd;
|
||||
rtmp = restlevelfile(fd, ltmp);
|
||||
if (rtmp < 2) return(rtmp); /* dorecover called recursively */
|
||||
}
|
||||
restoreprocs.mread_flags = 0;
|
||||
|
||||
#ifdef BSD
|
||||
(void) lseek(fd, 0L, 0);
|
||||
#else
|
||||
(void) lseek(fd, (off_t)0, 0);
|
||||
#endif
|
||||
(void) uptodate(fd, (char *)0); /* skip version info */
|
||||
(void) validate(fd, (char *)0); /* skip version and savefile info */
|
||||
get_plname_from_file(fd, plname);
|
||||
|
||||
getlev(fd, 0, (xchar)0, FALSE);
|
||||
(void) close(fd);
|
||||
|
||||
/* Now set the restore settings to match the
|
||||
* settings used by the save file output routines
|
||||
*/
|
||||
reset_restpref();
|
||||
|
||||
if (!wizard && !discover)
|
||||
(void) delete_savefile();
|
||||
#ifdef REINCARNATION
|
||||
@@ -700,6 +731,41 @@ register int fd;
|
||||
return(1);
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
rest_levl(fd, rlecomp)
|
||||
int fd;
|
||||
boolean rlecomp;
|
||||
{
|
||||
#ifdef RLECOMP
|
||||
short i, j;
|
||||
uchar len;
|
||||
struct rm r;
|
||||
|
||||
if (rlecomp) {
|
||||
# if defined(MAC)
|
||||
/* Suppress warning about used before set */
|
||||
(void) memset((genericptr_t) &r, 0, sizeof(r));
|
||||
# endif
|
||||
i = 0; j = 0; len = 0;
|
||||
while(i < ROWNO) {
|
||||
while(j < COLNO) {
|
||||
if(len > 0) {
|
||||
levl[j][i] = r;
|
||||
len -= 1;
|
||||
j += 1;
|
||||
} else {
|
||||
mread(fd, (genericptr_t)&len, sizeof(uchar));
|
||||
mread(fd, (genericptr_t)&r, sizeof(struct rm));
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i += 1;
|
||||
}
|
||||
} else
|
||||
#endif /* RLECOMP */
|
||||
mread(fd, (genericptr_t) levl, sizeof(levl));
|
||||
}
|
||||
|
||||
void
|
||||
trickery(reason)
|
||||
char *reason;
|
||||
@@ -760,37 +826,7 @@ boolean ghostly;
|
||||
#endif
|
||||
trickery(trickbuf);
|
||||
}
|
||||
|
||||
#ifdef RLECOMP
|
||||
{
|
||||
short i, j;
|
||||
uchar len;
|
||||
struct rm r;
|
||||
|
||||
#if defined(MAC)
|
||||
/* Suppress warning about used before set */
|
||||
(void) memset((genericptr_t) &r, 0, sizeof(r));
|
||||
#endif
|
||||
i = 0; j = 0; len = 0;
|
||||
while(i < ROWNO) {
|
||||
while(j < COLNO) {
|
||||
if(len > 0) {
|
||||
levl[j][i] = r;
|
||||
len -= 1;
|
||||
j += 1;
|
||||
} else {
|
||||
mread(fd, (genericptr_t)&len, sizeof(uchar));
|
||||
mread(fd, (genericptr_t)&r, sizeof(struct rm));
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
mread(fd, (genericptr_t) levl, sizeof(levl));
|
||||
#endif /* RLECOMP */
|
||||
|
||||
rest_levl(fd, (boolean)((sfrestinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP));
|
||||
mread(fd, (genericptr_t)&omoves, sizeof(omoves));
|
||||
mread(fd, (genericptr_t)&upstair, sizeof(stairway));
|
||||
mread(fd, (genericptr_t)&dnstair, sizeof(stairway));
|
||||
@@ -1051,6 +1087,145 @@ boolean ghostly;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
minit()
|
||||
{
|
||||
(*restoreprocs.restore_minit)();
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mread(fd, buf, len)
|
||||
register int fd;
|
||||
register genericptr_t buf;
|
||||
register unsigned int len;
|
||||
{
|
||||
(*restoreprocs.restore_mread)(fd, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* examine the version info and the savefile_info data
|
||||
that immediately follows it.
|
||||
Return 0 if it passed the checks.
|
||||
Return 1 if it failed the version check.
|
||||
Return 2 if it failed the savefile feature check.
|
||||
Return -1 if it failed for some unknown reason.
|
||||
*/
|
||||
int
|
||||
validate(fd, name)
|
||||
int fd;
|
||||
const char *name;
|
||||
{
|
||||
int rlen;
|
||||
struct savefile_info sfi;
|
||||
unsigned long compatible;
|
||||
boolean verbose = name ? TRUE : FALSE, reslt = FALSE;
|
||||
|
||||
if (!(reslt = uptodate(fd, name))) return 1;
|
||||
|
||||
rlen = read(fd, (genericptr_t) &sfi, sizeof sfi);
|
||||
minit(); /* ZEROCOMP */
|
||||
if (rlen == 0) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" is empty during save file feature check?", name);
|
||||
wait_synch();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
compatible = (sfi.sfi1 & sfcap.sfi1);
|
||||
|
||||
if ((sfi.sfi1 & SFI1_ZEROCOMP) == SFI1_ZEROCOMP) {
|
||||
if ((compatible & SFI1_ZEROCOMP) != SFI1_ZEROCOMP) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" has incompatible ZEROCOMP compression.", name);
|
||||
wait_synch();
|
||||
}
|
||||
return 2;
|
||||
} else if ((sfrestinfo.sfi1 & SFI1_ZEROCOMP) != SFI1_ZEROCOMP) {
|
||||
set_restpref("zerocomp");
|
||||
}
|
||||
}
|
||||
|
||||
if ((sfi.sfi1 & SFI1_EXTERNALCOMP) == SFI1_EXTERNALCOMP) {
|
||||
if ((compatible & SFI1_EXTERNALCOMP) != SFI1_EXTERNALCOMP) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" lacks required internal compression.", name);
|
||||
wait_synch();
|
||||
}
|
||||
return 2;
|
||||
} else if ((sfrestinfo.sfi1 & SFI1_EXTERNALCOMP) != SFI1_EXTERNALCOMP) {
|
||||
set_restpref("externalcomp");
|
||||
}
|
||||
}
|
||||
|
||||
/* RLECOMP check must be last, after ZEROCOMP or INTERNALCOMP adjustments */
|
||||
if ((sfi.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP) {
|
||||
if ((compatible & SFI1_RLECOMP) != SFI1_RLECOMP) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" has incompatible run-length compression.", name);
|
||||
wait_synch();
|
||||
}
|
||||
return 2;
|
||||
} else if ((sfrestinfo.sfi1 & SFI1_RLECOMP) != SFI1_RLECOMP) {
|
||||
set_restpref("rlecomp");
|
||||
}
|
||||
}
|
||||
/* savefile does not have RLECOMP level location compression, so adjust */
|
||||
else set_restpref("!rlecomp");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
reset_restpref()
|
||||
{
|
||||
#ifdef ZEROCOMP
|
||||
if (iflags.zerocomp)
|
||||
set_restpref("zerocomp");
|
||||
else
|
||||
#endif
|
||||
set_restpref("externalcomp");
|
||||
#ifdef RLECOMP
|
||||
if (iflags.rlecomp)
|
||||
set_restpref("rlecomp");
|
||||
else
|
||||
#endif
|
||||
set_restpref("!rlecomp");
|
||||
}
|
||||
|
||||
void
|
||||
set_restpref(suitename)
|
||||
const char *suitename;
|
||||
{
|
||||
if (!strcmpi(suitename, "externalcomp")) {
|
||||
restoreprocs.name = "externalcomp";
|
||||
restoreprocs.restore_mread = def_mread;
|
||||
restoreprocs.restore_minit = def_minit;
|
||||
sfrestinfo.sfi1 |= SFI1_EXTERNALCOMP;
|
||||
sfrestinfo.sfi1 &= ~SFI1_ZEROCOMP;
|
||||
def_minit();
|
||||
}
|
||||
if (!strcmpi(suitename, "!rlecomp")) {
|
||||
sfrestinfo.sfi1 &= ~SFI1_RLECOMP;
|
||||
}
|
||||
#ifdef ZEROCOMP
|
||||
if (!strcmpi(suitename, "zerocomp")) {
|
||||
restoreprocs.name = "zerocomp";
|
||||
restoreprocs.restore_mread = zerocomp_mread;
|
||||
restoreprocs.restore_minit = zerocomp_minit;
|
||||
sfrestinfo.sfi1 |= SFI1_ZEROCOMP;
|
||||
sfrestinfo.sfi1 &= ~SFI1_EXTERNALCOMP;
|
||||
zerocomp_minit();
|
||||
}
|
||||
#endif
|
||||
#ifdef RLECOMP
|
||||
if (!strcmpi(suitename, "rlecomp")) {
|
||||
sfrestinfo.sfi1 |= SFI1_RLECOMP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
#define RLESC '\0' /* Leading character for run of RLESC's */
|
||||
|
||||
@@ -1063,8 +1238,8 @@ static NEARDATA unsigned short inbufsz = 0;
|
||||
static NEARDATA short inrunlength = -1;
|
||||
static NEARDATA int mreadfd;
|
||||
|
||||
static int
|
||||
mgetc()
|
||||
STATIC_OVL int
|
||||
zerocomp_mgetc()
|
||||
{
|
||||
if (inbufp >= inbufsz) {
|
||||
inbufsz = read(mreadfd, (genericptr_t)inbuf, sizeof inbuf);
|
||||
@@ -1079,16 +1254,16 @@ mgetc()
|
||||
return inbuf[inbufp++];
|
||||
}
|
||||
|
||||
void
|
||||
minit()
|
||||
STATIC_OVL void
|
||||
zerocomp_minit()
|
||||
{
|
||||
inbufsz = 0;
|
||||
inbufp = 0;
|
||||
inrunlength = -1;
|
||||
}
|
||||
|
||||
int
|
||||
mread(fd, buf, len)
|
||||
STATIC_OVL void
|
||||
zerocomp_mread(fd, buf, len)
|
||||
int fd;
|
||||
genericptr_t buf;
|
||||
register unsigned len;
|
||||
@@ -1101,27 +1276,28 @@ register unsigned len;
|
||||
inrunlength--;
|
||||
*(*((char **)&buf))++ = '\0';
|
||||
} else {
|
||||
register short ch = mgetc();
|
||||
if (ch < 0) return -1; /*readlen;*/
|
||||
register short ch = zerocomp_mgetc();
|
||||
if (ch < 0) {
|
||||
restoreprocs.mread_flags = -1;
|
||||
return;
|
||||
}
|
||||
if ((*(*(char **)&buf)++ = (char)ch) == RLESC) {
|
||||
inrunlength = mgetc();
|
||||
inrunlength = zerocomp_mgetc();
|
||||
}
|
||||
}
|
||||
/*readlen++;*/
|
||||
}
|
||||
return 0; /*readlen;*/
|
||||
}
|
||||
#endif /* ZEROCOMP */
|
||||
|
||||
#else /* ZEROCOMP */
|
||||
|
||||
void
|
||||
minit()
|
||||
STATIC_OVL void
|
||||
def_minit()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mread(fd, buf, len)
|
||||
STATIC_OVL void
|
||||
def_mread(fd, buf, len)
|
||||
register int fd;
|
||||
register genericptr_t buf;
|
||||
register unsigned int len;
|
||||
@@ -1135,6 +1311,10 @@ register unsigned int len;
|
||||
rlen = read(fd, buf, (unsigned) len);
|
||||
if((unsigned)rlen != len){
|
||||
#endif
|
||||
if (restoreprocs.mread_flags == 1) { /* means "return anyway" */
|
||||
restoreprocs.mread_flags = -1;
|
||||
return;
|
||||
} else {
|
||||
pline("Read %d instead of %u bytes.", rlen, len);
|
||||
if(restoring) {
|
||||
(void) close(fd);
|
||||
@@ -1142,9 +1322,10 @@ register unsigned int len;
|
||||
error("Error restoring old game.");
|
||||
}
|
||||
panic("Error reading level file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ZEROCOMP */
|
||||
|
||||
#ifndef GOLDOBJ
|
||||
/*
|
||||
* Takes all of the gold objects out of the invent or
|
||||
|
||||
480
src/save.c
480
src/save.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)save.c 3.5 2003/11/14 */
|
||||
/* SCCS Id: @(#)save.c 3.5 2005/01/04 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -22,9 +22,6 @@ static int count_only;
|
||||
int dotcnt, dotrow; /* also used in restore */
|
||||
#endif
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
STATIC_DCL void FDECL(bputc, (int));
|
||||
#endif
|
||||
STATIC_DCL void FDECL(savelevchn, (int,int));
|
||||
STATIC_DCL void FDECL(savedamage, (int,int));
|
||||
STATIC_DCL void FDECL(saveobjchn, (int,struct obj *,int));
|
||||
@@ -37,6 +34,44 @@ STATIC_DCL void FDECL(savelev0, (int,XCHAR_P,int));
|
||||
STATIC_DCL boolean NDECL(swapout_oldest);
|
||||
STATIC_DCL void FDECL(copyfile, (char *,char *));
|
||||
#endif /* MFLOPPY */
|
||||
STATIC_DCL void FDECL(savelevl, (int fd, BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(def_bufon, (int));
|
||||
STATIC_DCL void FDECL(def_bufoff, (int));
|
||||
STATIC_DCL void FDECL(def_bflush, (int));
|
||||
STATIC_DCL void FDECL(def_bwrite, (int,genericptr_t,unsigned int));
|
||||
#ifdef ZEROCOMP
|
||||
STATIC_DCL void FDECL(zerocomp_bufon, (int));
|
||||
STATIC_DCL void FDECL(zerocomp_bufoff, (int));
|
||||
STATIC_DCL void FDECL(zerocomp_bflush, (int));
|
||||
STATIC_DCL void FDECL(zerocomp_bwrite, (int,genericptr_t,unsigned int));
|
||||
STATIC_DCL void FDECL(zerocomp_bputc, (int));
|
||||
#endif
|
||||
|
||||
static struct save_procs {
|
||||
const char *name;
|
||||
void FDECL((*save_bufon), (int));
|
||||
void FDECL((*save_bufoff), (int));
|
||||
void FDECL((*save_bflush), (int));
|
||||
void FDECL((*save_bwrite), (int,genericptr_t,unsigned int));
|
||||
void FDECL((*save_bclose), (int));
|
||||
} saveprocs = {
|
||||
#if !defined(ZEROCOMP) || (defined(COMPRESS) || defined(ZLIB_COMP))
|
||||
"externalcomp",
|
||||
def_bufon,
|
||||
def_bufoff,
|
||||
def_bflush,
|
||||
def_bwrite,
|
||||
def_bclose,
|
||||
#else
|
||||
"zerocomp",
|
||||
zerocomp_bufon,
|
||||
zerocomp_bufoff,
|
||||
zerocomp_bflush,
|
||||
zerocomp_bwrite,
|
||||
zerocomp_bclose,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef GCC_WARN
|
||||
static long nulls[10];
|
||||
#else
|
||||
@@ -140,14 +175,14 @@ dosave0()
|
||||
#endif
|
||||
|
||||
HUP if (iflags.window_inited) {
|
||||
uncompress(fq_save);
|
||||
nh_uncompress(fq_save);
|
||||
fd = open_savefile();
|
||||
if (fd > 0) {
|
||||
(void) close(fd);
|
||||
clear_nhwindow(WIN_MESSAGE);
|
||||
There("seems to be an old save file.");
|
||||
if (yn("Overwrite the old file?") == 'n') {
|
||||
compress(fq_save);
|
||||
nh_compress(fq_save);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -209,6 +244,7 @@ dosave0()
|
||||
#endif /* MFLOPPY */
|
||||
|
||||
store_version(fd);
|
||||
store_savefileinfo(fd);
|
||||
store_plname_in_file(fd);
|
||||
ustuck_id = (u.ustuck ? u.ustuck->m_id : 0);
|
||||
#ifdef STEED
|
||||
@@ -269,7 +305,7 @@ dosave0()
|
||||
/* get rid of current level --jgm */
|
||||
delete_levelfile(ledger_no(&u.uz));
|
||||
delete_levelfile(0);
|
||||
compress(fq_save);
|
||||
nh_compress(fq_save);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -405,6 +441,7 @@ savestateinlock()
|
||||
(void) write(fd, (genericptr_t) &currlev, sizeof(currlev));
|
||||
save_savefile_name(fd);
|
||||
store_version(fd);
|
||||
store_savefileinfo(fd);
|
||||
store_plname_in_file(fd);
|
||||
|
||||
ustuck_id = (u.ustuck ? u.ustuck->m_id : 0);
|
||||
@@ -489,54 +526,7 @@ int mode;
|
||||
#else
|
||||
bwrite(fd,(genericptr_t) &lev,sizeof(lev));
|
||||
#endif
|
||||
#ifdef RLECOMP
|
||||
{
|
||||
/* perform run-length encoding of rm structs */
|
||||
struct rm *prm, *rgrm;
|
||||
int x, y;
|
||||
uchar match;
|
||||
|
||||
rgrm = &levl[0][0]; /* start matching at first rm */
|
||||
match = 0;
|
||||
|
||||
for (y = 0; y < ROWNO; y++) {
|
||||
for (x = 0; x < COLNO; x++) {
|
||||
prm = &levl[x][y];
|
||||
if (prm->glyph == rgrm->glyph
|
||||
&& prm->typ == rgrm->typ
|
||||
&& prm->seenv == rgrm->seenv
|
||||
&& prm->horizontal == rgrm->horizontal
|
||||
&& prm->flags == rgrm->flags
|
||||
&& prm->lit == rgrm->lit
|
||||
&& prm->waslit == rgrm->waslit
|
||||
&& prm->roomno == rgrm->roomno
|
||||
&& prm->edge == rgrm->edge) {
|
||||
match++;
|
||||
if (match > 254) {
|
||||
match = 254; /* undo this match */
|
||||
goto writeout;
|
||||
}
|
||||
} else {
|
||||
/* the run has been broken,
|
||||
* write out run-length encoding */
|
||||
writeout:
|
||||
bwrite(fd, (genericptr_t)&match, sizeof(uchar));
|
||||
bwrite(fd, (genericptr_t)rgrm, sizeof(struct rm));
|
||||
/* start encoding again. we have at least 1 rm
|
||||
* in the next run, viz. this one. */
|
||||
match = 1;
|
||||
rgrm = prm;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match > 0) {
|
||||
bwrite(fd, (genericptr_t)&match, sizeof(uchar));
|
||||
bwrite(fd, (genericptr_t)rgrm, sizeof(struct rm));
|
||||
}
|
||||
}
|
||||
#else
|
||||
bwrite(fd,(genericptr_t) levl,sizeof(levl));
|
||||
#endif /* RLECOMP */
|
||||
savelevl(fd, (boolean)((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP));
|
||||
|
||||
bwrite(fd,(genericptr_t) &monstermoves,sizeof(monstermoves));
|
||||
bwrite(fd,(genericptr_t) &upstair,sizeof(stairway));
|
||||
@@ -575,6 +565,202 @@ int mode;
|
||||
if (mode != FREE_SAVE) bflush(fd);
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
savelevl(fd, rlecomp)
|
||||
int fd;
|
||||
boolean rlecomp;
|
||||
{
|
||||
#ifdef RLECOMP
|
||||
struct rm *prm, *rgrm;
|
||||
int x, y;
|
||||
uchar match;
|
||||
|
||||
if (rlecomp) {
|
||||
/* perform run-length encoding of rm structs */
|
||||
|
||||
rgrm = &levl[0][0]; /* start matching at first rm */
|
||||
match = 0;
|
||||
|
||||
for (y = 0; y < ROWNO; y++) {
|
||||
for (x = 0; x < COLNO; x++) {
|
||||
prm = &levl[x][y];
|
||||
if (prm->glyph == rgrm->glyph
|
||||
&& prm->typ == rgrm->typ
|
||||
&& prm->seenv == rgrm->seenv
|
||||
&& prm->horizontal == rgrm->horizontal
|
||||
&& prm->flags == rgrm->flags
|
||||
&& prm->lit == rgrm->lit
|
||||
&& prm->waslit == rgrm->waslit
|
||||
&& prm->roomno == rgrm->roomno
|
||||
&& prm->edge == rgrm->edge) {
|
||||
match++;
|
||||
if (match > 254) {
|
||||
match = 254; /* undo this match */
|
||||
goto writeout;
|
||||
}
|
||||
} else {
|
||||
/* the run has been broken,
|
||||
* write out run-length encoding */
|
||||
writeout:
|
||||
bwrite(fd, (genericptr_t)&match, sizeof(uchar));
|
||||
bwrite(fd, (genericptr_t)rgrm, sizeof(struct rm));
|
||||
/* start encoding again. we have at least 1 rm
|
||||
* in the next run, viz. this one. */
|
||||
match = 1;
|
||||
rgrm = prm;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match > 0) {
|
||||
bwrite(fd, (genericptr_t)&match, sizeof(uchar));
|
||||
bwrite(fd, (genericptr_t)rgrm, sizeof(struct rm));
|
||||
}
|
||||
} else
|
||||
#endif /* RLECOMP */
|
||||
bwrite(fd,(genericptr_t) levl,sizeof(levl));
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
(*saveprocs.save_bufon)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
(*saveprocs.save_bufoff)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bflush(fd) /* flush run and buffer */
|
||||
register int fd;
|
||||
{
|
||||
(*saveprocs.save_bflush)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bwrite(fd, loc, num)
|
||||
int fd;
|
||||
genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
(*saveprocs.save_bwrite)(fd, loc, num);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
(*saveprocs.save_bclose)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
static int bw_fd = -1;
|
||||
static FILE *bw_FILE = 0;
|
||||
static boolean buffering = FALSE;
|
||||
|
||||
STATIC_OVL void
|
||||
def_bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef UNIX
|
||||
if(bw_fd != fd) {
|
||||
if(bw_fd >= 0)
|
||||
panic("double buffering unexpected");
|
||||
bw_fd = fd;
|
||||
if((bw_FILE = fdopen(fd, "w")) == 0)
|
||||
panic("buffering of file %d failed", fd);
|
||||
}
|
||||
#endif
|
||||
buffering = TRUE;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
def_bflush(fd);
|
||||
buffering = FALSE;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_bflush(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef UNIX
|
||||
if(fd == bw_fd) {
|
||||
if(fflush(bw_FILE) == EOF)
|
||||
panic("flush of savefile failed!");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_bwrite(fd,loc,num)
|
||||
register int fd;
|
||||
register genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
boolean failed;
|
||||
|
||||
#ifdef MFLOPPY
|
||||
bytes_counted += num;
|
||||
if (count_only) return;
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
if (buffering) {
|
||||
if(fd != bw_fd)
|
||||
panic("unbuffered write to fd %d (!= %d)", fd, bw_fd);
|
||||
|
||||
failed = (fwrite(loc, (int)num, 1, bw_FILE) != 1);
|
||||
} else
|
||||
#endif /* UNIX */
|
||||
{
|
||||
/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
|
||||
#if defined(BSD) || defined(ULTRIX) || defined(WIN32)
|
||||
failed = (write(fd, loc, (int)num) != (int)num);
|
||||
#else /* e.g. SYSV, __TURBOC__ */
|
||||
failed = (write(fd, loc, num) != num);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||
if (program_state.done_hup)
|
||||
terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
panic("cannot write %u bytes to file #%d", num, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
def_bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
bufoff(fd);
|
||||
#ifdef UNIX
|
||||
if (fd == bw_fd) {
|
||||
(void) fclose(bw_FILE);
|
||||
bw_fd = -1;
|
||||
bw_FILE = 0;
|
||||
} else
|
||||
#endif
|
||||
(void) close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
/* The runs of zero-run compression are flushed after the game state or a
|
||||
* level is written out. This adds a couple bytes to a save file, where
|
||||
@@ -585,7 +771,7 @@ int mode;
|
||||
*/
|
||||
|
||||
#define RLESC '\0' /* Leading character for run of LRESC's */
|
||||
#define flushoutrun(ln) (bputc(RLESC), bputc(ln), ln = -1)
|
||||
#define flushoutrun(ln) (zerocomp_bputc(RLESC), zerocomp_bputc(ln), ln = -1)
|
||||
|
||||
#ifndef ZEROCOMP_BUFSIZ
|
||||
# define ZEROCOMP_BUFSIZ BUFSZ
|
||||
@@ -602,7 +788,7 @@ static NEARDATA boolean compressing = FALSE;
|
||||
}*/
|
||||
|
||||
STATIC_OVL void
|
||||
bputc(c)
|
||||
zerocomp_bputc(c)
|
||||
int c;
|
||||
{
|
||||
#ifdef MFLOPPY
|
||||
@@ -619,7 +805,7 @@ int c;
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bufon(fd)
|
||||
STATIC_OVL zerocomp_bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
compressing = TRUE;
|
||||
@@ -627,8 +813,8 @@ int fd;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bufoff(fd)
|
||||
STATIC_OVL void
|
||||
zerocomp_bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
if (outbufp) {
|
||||
@@ -640,8 +826,8 @@ int fd;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bflush(fd) /* flush run and buffer */
|
||||
STATIC_OVL void
|
||||
zerocomp_bflush(fd) /* flush run and buffer */
|
||||
register int fd;
|
||||
{
|
||||
bwritefd = fd;
|
||||
@@ -659,14 +845,14 @@ register int fd;
|
||||
terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
bclose(fd); /* panic (outbufp != 0) */
|
||||
zerocomp_bclose(fd); /* panic (outbufp != 0) */
|
||||
}
|
||||
outbufp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bwrite(fd, loc, num)
|
||||
STATIC_OVL void
|
||||
zerocomp_bwrite(fd, loc, num)
|
||||
int fd;
|
||||
genericptr_t loc;
|
||||
register unsigned num;
|
||||
@@ -697,119 +883,20 @@ register unsigned num;
|
||||
if (outrunlength >= 0) { /* flush run */
|
||||
flushoutrun(outrunlength);
|
||||
}
|
||||
bputc(*bp);
|
||||
zerocomp_bputc(*bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bclose(fd)
|
||||
zerocomp_bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
bufoff(fd);
|
||||
zerocomp_bufoff(fd);
|
||||
(void) close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
#else /* ZEROCOMP */
|
||||
|
||||
static int bw_fd = -1;
|
||||
static FILE *bw_FILE = 0;
|
||||
static boolean buffering = FALSE;
|
||||
|
||||
void
|
||||
bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef UNIX
|
||||
if(bw_fd != fd) {
|
||||
if(bw_fd >= 0)
|
||||
panic("double buffering unexpected");
|
||||
bw_fd = fd;
|
||||
if((bw_FILE = fdopen(fd, "w")) == 0)
|
||||
panic("buffering of file %d failed", fd);
|
||||
}
|
||||
#endif
|
||||
buffering = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
bflush(fd);
|
||||
buffering = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
bflush(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef UNIX
|
||||
if(fd == bw_fd) {
|
||||
if(fflush(bw_FILE) == EOF)
|
||||
panic("flush of savefile failed!");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bwrite(fd,loc,num)
|
||||
register int fd;
|
||||
register genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
boolean failed;
|
||||
|
||||
#ifdef MFLOPPY
|
||||
bytes_counted += num;
|
||||
if (count_only) return;
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
if (buffering) {
|
||||
if(fd != bw_fd)
|
||||
panic("unbuffered write to fd %d (!= %d)", fd, bw_fd);
|
||||
|
||||
failed = (fwrite(loc, (int)num, 1, bw_FILE) != 1);
|
||||
} else
|
||||
#endif /* UNIX */
|
||||
{
|
||||
/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
|
||||
#if defined(BSD) || defined(ULTRIX)
|
||||
failed = (write(fd, loc, (int)num) != (int)num);
|
||||
#else /* e.g. SYSV, __TURBOC__ */
|
||||
failed = (write(fd, loc, num) != num);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||
if (program_state.done_hup)
|
||||
terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
panic("cannot write %u bytes to file #%d", num, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
bufoff(fd);
|
||||
#ifdef UNIX
|
||||
if (fd == bw_fd) {
|
||||
(void) fclose(bw_FILE);
|
||||
bw_fd = -1;
|
||||
bw_FILE = 0;
|
||||
} else
|
||||
#endif
|
||||
(void) close(fd);
|
||||
return;
|
||||
}
|
||||
#endif /* ZEROCOMP */
|
||||
|
||||
STATIC_OVL void
|
||||
@@ -1048,6 +1135,65 @@ register int fd, mode;
|
||||
pline("Stored %d messages into savefile.", msgcount);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
store_savefileinfo(fd)
|
||||
int fd;
|
||||
{
|
||||
/* sfcap (decl.c) describes the savefile feature capabilities
|
||||
* that are supported by this port/platform build.
|
||||
*
|
||||
* sfsaveinfo (decl.c) describes the savefile info that actually
|
||||
* gets written into the savefile, and is used to determine the
|
||||
* save file being written.
|
||||
|
||||
* sfrestinfo (decl.c) describes the savefile info that is
|
||||
* being used to read the information from an existing savefile.
|
||||
*
|
||||
*/
|
||||
|
||||
bufoff(fd);
|
||||
/* bwrite() before bufon() uses plain write() */
|
||||
bwrite(fd,(genericptr_t)&sfsaveinfo, (unsigned)(sizeof sfsaveinfo));
|
||||
bufon(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
set_savepref(suitename)
|
||||
const char *suitename;
|
||||
{
|
||||
if (!strcmpi(suitename, "externalcomp")) {
|
||||
saveprocs.name = "externalcomp";
|
||||
saveprocs.save_bufon = def_bufon;
|
||||
saveprocs.save_bufoff = def_bufoff;
|
||||
saveprocs.save_bflush = def_bflush;
|
||||
saveprocs.save_bwrite = def_bwrite;
|
||||
saveprocs.save_bclose = def_bclose;
|
||||
sfsaveinfo.sfi1 |= SFI1_EXTERNALCOMP;
|
||||
sfsaveinfo.sfi1 &= ~SFI1_ZEROCOMP;
|
||||
}
|
||||
if (!strcmpi(suitename, "!rlecomp")) {
|
||||
sfsaveinfo.sfi1 &= ~SFI1_RLECOMP;
|
||||
}
|
||||
#ifdef ZEROCOMP
|
||||
if (!strcmpi(suitename, "zerocomp")) {
|
||||
saveprocs.name = "zerocomp";
|
||||
saveprocs.save_bufon = zerocomp_bufon;
|
||||
saveprocs.save_bufoff = zerocomp_bufoff;
|
||||
saveprocs.save_bflush = zerocomp_bflush;
|
||||
saveprocs.save_bwrite = zerocomp_bwrite;
|
||||
saveprocs.save_bclose = zerocomp_bclose;
|
||||
sfsaveinfo.sfi1 |= SFI1_ZEROCOMP;
|
||||
sfsaveinfo.sfi1 &= ~SFI1_EXTERNALCOMP;
|
||||
}
|
||||
#endif
|
||||
#ifdef RLECOMP
|
||||
if (!strcmpi(suitename, "rlecomp")) {
|
||||
sfsaveinfo.sfi1 |= SFI1_RLECOMP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* also called by prscore(); this probably belongs in dungeon.c... */
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user