NetHack minor release checklist items - savefiles
Make some progress on a couple of next minor release checklist
items, hopefully without introducing too many new bugs. This
is just the initial commit, and work continues.
Checklist items:
Savefiles compatible between Windows versions, whether 64-bit
or 32-bit in little-endian field format.
Selection of file formats:
historical (structlevel saves),
lendian (little-endian, fieldlevel saves),
and just for proof-of-concept, ascii fieldlevel saves
(the ascii is huge! 10x bigger than little-endian).
For the fieldlevel save, all complex data structures recursively
get broken down until until it is one of the simple types that
can't be broken down any further, and that gets when it gets
written to the output file.
New files needed for this build:
hand-coded:
include/sfprocs.h
src/sfbase.c - really a dispatcher to one of the
output/input format routines.
src/sflendian.c - little-endian output writer/reader.
src/sfascii.c - ascii text output writer/reader.
auto-coded (generated):
include/sfproto.h
src/sfdata.c
This is just one approach. I'm sure there are countless others
and they have different pros and cons.
For producing the auto-coded files a utility called
universal-ctags, that is actively maintained and evolving,
was used to do all the heavy-lifting of parsing the
NetHack C sources to tabulate the data fields, and store
them in an intermediate file called util/nethack.tags
(not required for building NetHack if you already have a
generated include/sfproto.h and src/sfdata.c)
util/readtags (also not required for building NetHack
itself) will decipher the nethack.tags file and produce
the functions that can deal with the NetHack struct data
fields.
You can obtain the source for universal-ctags by cloning it
from here:
https://github.com/universal-ctags/ctags.git
The combination universal-ctags + util/readtags has been
tried and tested under both Windows and Linux, so it is
not tied to a particular platform.
Note: util/readtags will work only with universal-ctags
output, so other ctags are unlikely to work as-is.
Universal-ctags can be build from source very easily
under Linux, or under Windows using visual studio.
This commit is contained in:
+33
-9
@@ -6,6 +6,8 @@
|
||||
#include "hack.h"
|
||||
#include "artifact.h"
|
||||
#include "artilist.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/*
|
||||
* Note: both artilist[] and artiexist[] have a dummy element #0,
|
||||
@@ -76,20 +78,42 @@ init_artifacts()
|
||||
}
|
||||
|
||||
void
|
||||
save_artifacts(fd)
|
||||
int fd;
|
||||
save_artifacts(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
bwrite(fd, (genericptr_t) g.artiexist, sizeof g.artiexist);
|
||||
bwrite(fd, (genericptr_t) g.artidisco, sizeof g.artidisco);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) g.artiexist, sizeof g.artiexist);
|
||||
bwrite(nhfp->fd, (genericptr_t) g.artidisco, sizeof g.artidisco);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (1 + NROFARTIFACTS + 1); ++i)
|
||||
sfo_boolean(nhfp, &g.artiexist[i], "artifacts", "g.artiexist", 1);
|
||||
|
||||
for (i = 0; i < NROFARTIFACTS; ++i)
|
||||
sfo_xchar(nhfp, &g.artidisco[i], "artifacts", "g.artidisco", 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
restore_artifacts(fd)
|
||||
int fd;
|
||||
restore_artifacts(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
mread(fd, (genericptr_t) g.artiexist, sizeof g.artiexist);
|
||||
mread(fd, (genericptr_t) g.artidisco, sizeof g.artidisco);
|
||||
hack_artifacts(); /* redo non-saved special cases */
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) g.artiexist, sizeof g.artiexist);
|
||||
mread(nhfp->fd, (genericptr_t) g.artidisco, sizeof g.artidisco);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (1 + NROFARTIFACTS + 1); ++i)
|
||||
sfi_boolean(nhfp, &g.artiexist[i], "artifacts", "g.artiexist", 1);
|
||||
|
||||
for (i = 0; i < NROFARTIFACTS; ++i)
|
||||
sfi_xchar(nhfp, &g.artidisco[i], "artifacts", "g.artidisco", 1);
|
||||
}
|
||||
hack_artifacts(); /* redo non-saved special cases */
|
||||
}
|
||||
|
||||
const char *
|
||||
|
||||
+68
-32
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
#ifdef MFLOPPY
|
||||
extern long bytes_counted;
|
||||
@@ -338,7 +340,7 @@ int how;
|
||||
time_t when;
|
||||
struct obj *corpse;
|
||||
{
|
||||
int fd, x, y;
|
||||
int x, y;
|
||||
struct trap *ttmp;
|
||||
struct monst *mtmp;
|
||||
struct permonst *mptr;
|
||||
@@ -346,13 +348,14 @@ struct obj *corpse;
|
||||
struct cemetery *newbones;
|
||||
char c, *bonesid;
|
||||
char whynot[BUFSZ];
|
||||
NHFILE *nhfp;
|
||||
|
||||
/* caller has already checked `can_make_bones()' */
|
||||
|
||||
clear_bypasses();
|
||||
fd = open_bonesfile(&u.uz, &bonesid);
|
||||
if (fd >= 0) {
|
||||
(void) nhclose(fd);
|
||||
nhfp = open_bonesfile(&u.uz, &bonesid);
|
||||
if (nhfp) {
|
||||
close_nhfile(nhfp);
|
||||
if (wizard) {
|
||||
if (yn("Bones file already exists. Replace it?") == 'y') {
|
||||
if (delete_bonesfile(&u.uz))
|
||||
@@ -500,8 +503,8 @@ struct obj *corpse;
|
||||
if (wizard)
|
||||
g.level.flags.wizard_bones = 1;
|
||||
|
||||
fd = create_bonesfile(&u.uz, &bonesid, whynot);
|
||||
if (fd < 0) {
|
||||
nhfp = create_bonesfile(&u.uz, &bonesid, whynot);
|
||||
if (!nhfp) {
|
||||
if (wizard)
|
||||
pline1(whynot);
|
||||
/* bones file creation problems are silent to the player.
|
||||
@@ -514,7 +517,10 @@ struct obj *corpse;
|
||||
|
||||
#ifdef MFLOPPY /* check whether there is room */
|
||||
if (iflags.checkspace) {
|
||||
savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
|
||||
int savemode = nhfp->mode;
|
||||
|
||||
nhfp->mode = COUNTING;
|
||||
savelev(nhfp, ledger_no(&u.uz));
|
||||
/* savelev() initializes bytes_counted to 0, so it must come
|
||||
* first here even though it does not in the real save. the
|
||||
* resulting extra bflush() at the end of savelev() may increase
|
||||
@@ -525,31 +531,47 @@ struct obj *corpse;
|
||||
* this code would have to know the size of the version
|
||||
* information itself.
|
||||
*/
|
||||
store_version(fd);
|
||||
store_savefileinfo(fd);
|
||||
bwrite(fd, (genericptr_t) &c, sizeof c);
|
||||
bwrite(fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */
|
||||
savefruitchn(fd, COUNT_SAVE);
|
||||
bflush(fd);
|
||||
store_version(nhfp);
|
||||
store_savefileinfo(nhfp);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &c, sizeof c);
|
||||
bwrite(nhfp->fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_char(nhfp, &c, "bones", "bones_count", 1);
|
||||
sfo_char(nhfp, bonesid, "bones", "bonesid", (int) c);
|
||||
}
|
||||
savefruitchn(nhfp);
|
||||
if (nhfp->structlevel)
|
||||
bflush(nhfp->fd);
|
||||
if (bytes_counted > freediskspace(bones)) { /* not enough room */
|
||||
if (wizard)
|
||||
pline("Insufficient space to create bones file.");
|
||||
(void) nhclose(fd);
|
||||
close_nhfile(nhfp);
|
||||
cancel_bonesfile();
|
||||
return;
|
||||
}
|
||||
co_false(); /* make sure stuff before savelev() gets written */
|
||||
nhfp->mode = savemode;
|
||||
}
|
||||
#endif /* MFLOPPY */
|
||||
|
||||
store_version(fd);
|
||||
store_savefileinfo(fd);
|
||||
bwrite(fd, (genericptr_t) &c, sizeof c);
|
||||
bwrite(fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */
|
||||
savefruitchn(fd, WRITE_SAVE | FREE_SAVE);
|
||||
nhfp->mode = WRITING | FREEING;
|
||||
store_version(nhfp);
|
||||
store_savefileinfo(nhfp);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &c, sizeof c);
|
||||
bwrite(nhfp->fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */
|
||||
savefruitchn(nhfp);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_char(nhfp, &c, "bones", "bones_count", 1);
|
||||
sfo_char(nhfp, bonesid, "bones", "bonesid", (int) c); /* DD.nnn */
|
||||
savefruitchn(nhfp);
|
||||
}
|
||||
update_mlstmv(); /* update monsters for eventual restoration */
|
||||
savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
|
||||
bclose(fd);
|
||||
savelev(nhfp, ledger_no(&u.uz));
|
||||
close_nhfile(nhfp);
|
||||
commit_bonesfile(&u.uz);
|
||||
compress_bonesfile();
|
||||
}
|
||||
@@ -557,8 +579,8 @@ struct obj *corpse;
|
||||
int
|
||||
getbones()
|
||||
{
|
||||
register int fd;
|
||||
register int ok;
|
||||
int ok, i;
|
||||
NHFILE *nhfp = (NHFILE *) 0;
|
||||
char c, *bonesid, oldbonesid[40]; /* was [10]; more should be safer */
|
||||
|
||||
if (discover) /* save bones files for real games */
|
||||
@@ -572,11 +594,18 @@ getbones()
|
||||
return 0;
|
||||
if (no_bones_level(&u.uz))
|
||||
return 0;
|
||||
fd = open_bonesfile(&u.uz, &bonesid);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
if (validate(fd, g.bones) != 0) {
|
||||
nhfp = open_bonesfile(&u.uz, &bonesid);
|
||||
if (!nhfp)
|
||||
return 0;
|
||||
if (nhfp && nhfp->structlevel && nhfp->fd < 0)
|
||||
return 0;
|
||||
if (nhfp && nhfp->fieldlevel) {
|
||||
if (nhfp->style.deflt && !nhfp->fpdef)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (validate(nhfp, g.bones) != 0) {
|
||||
if (!wizard)
|
||||
pline("Discarding unuseable bones; no need to panic...");
|
||||
ok = FALSE;
|
||||
@@ -584,13 +613,20 @@ getbones()
|
||||
ok = TRUE;
|
||||
if (wizard) {
|
||||
if (yn("Get bones?") == 'n') {
|
||||
(void) nhclose(fd);
|
||||
close_nhfile(nhfp);
|
||||
compress_bonesfile();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mread(fd, (genericptr_t) &c, sizeof c); /* length incl. '\0' */
|
||||
mread(fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &c, sizeof c); /* length incl. '\0' */
|
||||
mread(nhfp->fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_char(nhfp, &c, "bones", "bones_count", 1); /* length incl. '\0' */
|
||||
for (i = 0; i < (int) c; ++i)
|
||||
sfi_char(nhfp, &oldbonesid[i], "bones", "bonesid", 1);
|
||||
}
|
||||
if (strcmp(bonesid, oldbonesid) != 0
|
||||
/* from 3.3.0 through 3.6.0, bones in the quest branch stored
|
||||
a bogus bonesid in the file; 3.6.1 fixed that, but for
|
||||
@@ -612,7 +648,7 @@ getbones()
|
||||
} else {
|
||||
register struct monst *mtmp;
|
||||
|
||||
getlev(fd, 0, 0, TRUE);
|
||||
getlev(nhfp, 0, 0, TRUE);
|
||||
|
||||
/* Note that getlev() now keeps tabs on unique
|
||||
* monsters such as demon lords, and tracks the
|
||||
@@ -638,7 +674,7 @@ getbones()
|
||||
resetobjs(g.level.buriedobjlist, TRUE);
|
||||
}
|
||||
}
|
||||
(void) nhclose(fd);
|
||||
close_nhfile(nhfp);
|
||||
sanitize_engravings();
|
||||
u.uroleplay.numbones++;
|
||||
|
||||
|
||||
@@ -789,6 +789,8 @@ wiz_identify(VOID_ARGS)
|
||||
STATIC_PTR int
|
||||
wiz_makemap(VOID_ARGS)
|
||||
{
|
||||
NHFILE tmpnhfp;
|
||||
|
||||
if (wizard) {
|
||||
struct monst *mtmp;
|
||||
boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
|
||||
@@ -835,7 +837,9 @@ wiz_makemap(VOID_ARGS)
|
||||
keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */
|
||||
|
||||
/* discard current level; "saving" is used to release dynamic data */
|
||||
savelev(-1, ledger_no(&u.uz), FREE_SAVE);
|
||||
zero_nhfile(&tmpnhfp); /* also sets fd to -1 as desired */
|
||||
tmpnhfp.mode = FREEING;
|
||||
savelev(&tmpnhfp, ledger_no(&u.uz));
|
||||
/* create a new level; various things like bestowing a guardian
|
||||
angel on Astral or setting off alarm on Ft.Ludios are handled
|
||||
by goto_level(do.c) so won't occur for replacement levels */
|
||||
|
||||
@@ -15,7 +15,7 @@ STATIC_DCL void FDECL(dosinkring, (struct obj *));
|
||||
STATIC_PTR int FDECL(drop, (struct obj *));
|
||||
STATIC_PTR int NDECL(wipeoff);
|
||||
STATIC_DCL int FDECL(menu_drop, (int));
|
||||
STATIC_DCL int NDECL(currentlevel_rewrite);
|
||||
STATIC_DCL NHFILE *NDECL(currentlevel_rewrite);
|
||||
STATIC_DCL void NDECL(final_level);
|
||||
/* static boolean FDECL(badspot, (XCHAR_P,XCHAR_P)); */
|
||||
|
||||
@@ -1114,18 +1114,21 @@ doup()
|
||||
}
|
||||
|
||||
/* check that we can write out the current level */
|
||||
STATIC_OVL int
|
||||
STATIC_OVL NHFILE *
|
||||
currentlevel_rewrite()
|
||||
{
|
||||
register int fd;
|
||||
NHFILE *nhfp;
|
||||
char whynot[BUFSZ];
|
||||
#ifdef MFLOPPY
|
||||
int savemode;
|
||||
#endif
|
||||
|
||||
/* since level change might be a bit slow, flush any buffered screen
|
||||
* output (like "you fall through a trap door") */
|
||||
mark_synch();
|
||||
|
||||
fd = create_levelfile(ledger_no(&u.uz), whynot);
|
||||
if (fd < 0) {
|
||||
nhfp = create_levelfile(ledger_no(&u.uz), whynot);
|
||||
if (!nhfp) {
|
||||
/*
|
||||
* This is not quite impossible: e.g., we may have
|
||||
* exceeded our quota. If that is the case then we
|
||||
@@ -1134,35 +1137,39 @@ currentlevel_rewrite()
|
||||
* writable.
|
||||
*/
|
||||
pline1(whynot);
|
||||
return -1;
|
||||
return (NHFILE *) 0;
|
||||
}
|
||||
|
||||
#ifdef MFLOPPY
|
||||
if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) {
|
||||
(void) nhclose(fd);
|
||||
savemode = nhfp->mode;
|
||||
nhfp->mode = COUNTING;
|
||||
if (!savelev(nhfp, ledger_no(&u.uz))) {
|
||||
close_nhfile(nhfp);
|
||||
delete_levelfile(ledger_no(&u.uz));
|
||||
pline("NetHack is out of disk space for making levels!");
|
||||
You("can save, quit, or continue playing.");
|
||||
return -1;
|
||||
}
|
||||
nhfp->mode = savemode;
|
||||
#endif
|
||||
return fd;
|
||||
return nhfp;
|
||||
}
|
||||
|
||||
#ifdef INSURANCE
|
||||
void
|
||||
save_currentstate()
|
||||
{
|
||||
int fd;
|
||||
NHFILE *nhfp;
|
||||
|
||||
if (flags.ins_chkpt) {
|
||||
/* write out just-attained level, with pets and everything */
|
||||
fd = currentlevel_rewrite();
|
||||
if (fd < 0)
|
||||
nhfp = currentlevel_rewrite();
|
||||
if (!nhfp)
|
||||
return;
|
||||
bufon(fd);
|
||||
savelev(fd, ledger_no(&u.uz), WRITE_SAVE);
|
||||
bclose(fd);
|
||||
bufon(nhfp->fd);
|
||||
nhfp->mode = WRITING;
|
||||
savelev(nhfp,ledger_no(&u.uz));
|
||||
close_nhfile(nhfp);
|
||||
}
|
||||
|
||||
/* write out non-level state */
|
||||
@@ -1226,7 +1233,8 @@ goto_level(newlevel, at_stairs, falling, portal)
|
||||
d_level *newlevel;
|
||||
boolean at_stairs, falling, portal;
|
||||
{
|
||||
int fd, l_idx;
|
||||
int l_idx, save_mode;
|
||||
NHFILE *nhfp;
|
||||
xchar new_ledger;
|
||||
boolean cant_go_back, great_effort,
|
||||
up = (depth(newlevel) < depth(&u.uz)),
|
||||
@@ -1307,8 +1315,8 @@ boolean at_stairs, falling, portal;
|
||||
if (u.utrap && u.utraptype == TT_BURIEDBALL)
|
||||
buried_ball_to_punishment(); /* (before we save/leave old level) */
|
||||
|
||||
fd = currentlevel_rewrite();
|
||||
if (fd < 0)
|
||||
nhfp = currentlevel_rewrite();
|
||||
if (!nhfp)
|
||||
return;
|
||||
|
||||
/* discard context which applies to the level we're leaving;
|
||||
@@ -1354,10 +1362,12 @@ boolean at_stairs, falling, portal;
|
||||
cant_go_back = (newdungeon && In_endgame(newlevel));
|
||||
if (!cant_go_back) {
|
||||
update_mlstmv(); /* current monsters are becoming inactive */
|
||||
bufon(fd); /* use buffered output */
|
||||
bufon(nhfp->fd); /* use buffered output */
|
||||
}
|
||||
savelev(fd, ledger_no(&u.uz),
|
||||
cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE));
|
||||
save_mode = nhfp->mode;
|
||||
nhfp->mode = cant_go_back ? FREEING : (WRITING | FREEING);
|
||||
savelev(nhfp, ledger_no(&u.uz));
|
||||
nhfp->mode = save_mode;
|
||||
/* air bubbles and clouds are saved in game-state rather than with the
|
||||
level they're used on; in normal play, you can't leave and return
|
||||
to any endgame level--bubbles aren't needed once you move to the
|
||||
@@ -1366,9 +1376,15 @@ boolean at_stairs, falling, portal;
|
||||
aren't saved with the level and restored upon return (new ones are
|
||||
created instead), we need to discard them to avoid a memory leak;
|
||||
so bubbles are now discarded as we leave the level they're used on */
|
||||
if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
|
||||
save_waterlevel(-1, FREE_SAVE);
|
||||
bclose(fd);
|
||||
if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
|
||||
NHFILE tmpnhfp;
|
||||
|
||||
zero_nhfile(&tmpnhfp);
|
||||
tmpnhfp.fd = -1;
|
||||
tmpnhfp.mode = FREEING;
|
||||
save_waterlevel(&tmpnhfp);
|
||||
}
|
||||
close_nhfile(nhfp);
|
||||
if (cant_go_back) {
|
||||
/* discard unreachable levels; keep #0 */
|
||||
for (l_idx = maxledgerno(); l_idx > 0; --l_idx)
|
||||
@@ -1418,21 +1434,26 @@ boolean at_stairs, falling, portal;
|
||||
new = TRUE; /* made the level */
|
||||
} else {
|
||||
/* returning to previously visited level; reload it */
|
||||
fd = open_levelfile(new_ledger, whynot);
|
||||
if (tricked_fileremoved(fd, whynot)) {
|
||||
nhfp = open_levelfile(new_ledger, whynot);
|
||||
if (tricked_fileremoved(nhfp, whynot)) {
|
||||
/* we'll reach here if running in wizard mode */
|
||||
error("Cannot continue this game.");
|
||||
}
|
||||
reseed_random(rn2);
|
||||
reseed_random(rn2_on_display_rng);
|
||||
minit(); /* ZEROCOMP */
|
||||
getlev(fd, g.hackpid, new_ledger, FALSE);
|
||||
getlev(nhfp, g.hackpid, new_ledger, FALSE);
|
||||
/* when in wizard mode, it is possible to leave from and return to
|
||||
any level in the endgame; above, we discarded bubble/cloud info
|
||||
when leaving Plane of Water or Air so recreate some now */
|
||||
if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
|
||||
restore_waterlevel(-1);
|
||||
(void) nhclose(fd);
|
||||
if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
|
||||
NHFILE tmpnhfp;
|
||||
|
||||
zero_nhfile(&tmpnhfp);
|
||||
tmpnhfp.fd = -1;
|
||||
restore_waterlevel(&tmpnhfp);
|
||||
}
|
||||
close_nhfile(nhfp);
|
||||
oinit(); /* reassign level dependent obj probabilities */
|
||||
}
|
||||
reglyph_darkroom();
|
||||
|
||||
+173
-64
@@ -7,6 +7,8 @@
|
||||
#include "dgn_file.h"
|
||||
#include "dlb.h"
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
#define DUNGEON_FILE "dungeon"
|
||||
|
||||
@@ -56,8 +58,9 @@ STATIC_DCL const char *FDECL(br_string, (int));
|
||||
STATIC_DCL char FDECL(chr_u_on_lvl, (d_level *));
|
||||
STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P,
|
||||
struct lchoice *));
|
||||
STATIC_DCL mapseen *FDECL(load_mapseen, (int));
|
||||
STATIC_DCL void FDECL(save_mapseen, (int, mapseen *));
|
||||
/* SAVE2018 */
|
||||
STATIC_DCL mapseen *FDECL(load_mapseen, (NHFILE *));
|
||||
STATIC_DCL void FDECL(save_mapseen, (NHFILE *, mapseen *));
|
||||
STATIC_DCL mapseen *FDECL(find_mapseen, (d_level *));
|
||||
STATIC_DCL mapseen *FDECL(find_mapseen_by_str, (const char *));
|
||||
STATIC_DCL void FDECL(print_mapseen, (winid, mapseen *, int, int, BOOLEAN_P));
|
||||
@@ -129,41 +132,68 @@ dumpit()
|
||||
|
||||
/* Save the dungeon structures. */
|
||||
void
|
||||
save_dungeon(fd, perform_write, free_data)
|
||||
int fd;
|
||||
save_dungeon(nhfp, perform_write, free_data)
|
||||
NHFILE *nhfp;
|
||||
boolean perform_write, free_data;
|
||||
{
|
||||
int i, count;
|
||||
branch *curr, *next;
|
||||
mapseen *curr_ms, *next_ms;
|
||||
int count;
|
||||
|
||||
if (perform_write) {
|
||||
bwrite(fd, (genericptr_t) &g.n_dgns, sizeof g.n_dgns);
|
||||
bwrite(fd, (genericptr_t) g.dungeons,
|
||||
sizeof(dungeon) * (unsigned) g.n_dgns);
|
||||
bwrite(fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology);
|
||||
bwrite(fd, (genericptr_t) g.tune, sizeof tune);
|
||||
|
||||
if(nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof g.n_dgns);
|
||||
bwrite(nhfp->fd, (genericptr_t) g.dungeons,
|
||||
sizeof(dungeon) * (unsigned) g.n_dgns);
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology);
|
||||
bwrite(nhfp->fd, (genericptr_t) g.tune, sizeof tune);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_int(nhfp, &g.n_dgns, "dungeon", "dungeon_count", 1);
|
||||
for (i = 0; i < g.n_dgns; ++i)
|
||||
sfo_dungeon(nhfp, &g.dungeons[i], "dungeon", "dungeon", 1);
|
||||
sfo_dgn_topology(nhfp, &g.dungeon_topology, "dungeon", "g.dungeon_topology", 1);
|
||||
for (i = 0; i < sizeof tune; ++i)
|
||||
sfo_char(nhfp, &g.tune[i], "dungeon", "tune", 1);
|
||||
}
|
||||
for (count = 0, curr = g.branches; curr; curr = curr->next)
|
||||
count++;
|
||||
bwrite(fd, (genericptr_t) &count, sizeof(count));
|
||||
|
||||
for (curr = g.branches; curr; curr = curr->next)
|
||||
bwrite(fd, (genericptr_t) curr, sizeof(branch));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &count, sizeof(count));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &count, "dungeon", "branch_count", 1);
|
||||
|
||||
for (curr = g.branches; curr; curr = curr->next) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) curr, sizeof(branch));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_branch(nhfp, curr, "dungeon", "branch", 1);
|
||||
}
|
||||
count = maxledgerno();
|
||||
bwrite(fd, (genericptr_t) &count, sizeof count);
|
||||
bwrite(fd, (genericptr_t) g.level_info,
|
||||
(unsigned) count * sizeof(struct linfo));
|
||||
bwrite(fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos);
|
||||
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &count, sizeof count);
|
||||
bwrite(nhfp->fd, (genericptr_t) g.level_info,
|
||||
(unsigned) count * sizeof(struct linfo));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_int(nhfp, &count, "dungeon", "level_info_count", 1);
|
||||
for (i = 0; i < count; ++i)
|
||||
sfo_linfo(nhfp, &g.level_info[i], "dungeon", "g.level_info", 1);
|
||||
sfo_nhcoord(nhfp, &g.inv_pos, "dungeon", "g.inv_pos", 1);
|
||||
}
|
||||
for (count = 0, curr_ms = g.mapseenchn; curr_ms;
|
||||
curr_ms = curr_ms->next)
|
||||
count++;
|
||||
bwrite(fd, (genericptr_t) &count, sizeof(count));
|
||||
|
||||
for (curr_ms = g.mapseenchn; curr_ms; curr_ms = curr_ms->next)
|
||||
save_mapseen(fd, curr_ms);
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &count, sizeof(count));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &count, "dungeon", "mapseen_count", 1);
|
||||
|
||||
for (curr_ms = g.mapseenchn; curr_ms; curr_ms = curr_ms->next) {
|
||||
save_mapseen(nhfp, curr_ms);
|
||||
}
|
||||
}
|
||||
|
||||
if (free_data) {
|
||||
@@ -177,7 +207,7 @@ boolean perform_write, free_data;
|
||||
if (curr_ms->custom)
|
||||
free((genericptr_t) curr_ms->custom);
|
||||
if (curr_ms->final_resting_place)
|
||||
savecemetery(fd, FREE_SAVE, &curr_ms->final_resting_place);
|
||||
savecemetery(nhfp, &curr_ms->final_resting_place);
|
||||
free((genericptr_t) curr_ms);
|
||||
}
|
||||
g.mapseenchn = 0;
|
||||
@@ -186,24 +216,40 @@ boolean perform_write, free_data;
|
||||
|
||||
/* Restore the dungeon structures. */
|
||||
void
|
||||
restore_dungeon(fd)
|
||||
int fd;
|
||||
restore_dungeon(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
branch *curr, *last;
|
||||
int count, i;
|
||||
mapseen *curr_ms, *last_ms;
|
||||
|
||||
mread(fd, (genericptr_t) &g.n_dgns, sizeof(g.n_dgns));
|
||||
mread(fd, (genericptr_t) g.dungeons, sizeof(dungeon) * (unsigned) g.n_dgns);
|
||||
mread(fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology);
|
||||
mread(fd, (genericptr_t) g.tune, sizeof tune);
|
||||
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof(g.n_dgns));
|
||||
mread(nhfp->fd, (genericptr_t) g.dungeons, sizeof(dungeon) * (unsigned) g.n_dgns);
|
||||
mread(nhfp->fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology);
|
||||
mread(nhfp->fd, (genericptr_t) g.tune, sizeof tune);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_int(nhfp, &g.n_dgns, "dungeon", "dungeon_count", 1);
|
||||
for (i = 0; i < g.n_dgns; ++i)
|
||||
sfi_dungeon(nhfp, &g.dungeons[i], "dungeon", "dungeon", 1);
|
||||
sfi_dgn_topology(nhfp, &g.dungeon_topology, "dungeon", "g.dungeon_topology", 1);
|
||||
for (i = 0; i < sizeof tune; ++i)
|
||||
sfi_char(nhfp, &g.tune[i], "dungeon", "tune", 1);
|
||||
}
|
||||
last = g.branches = (branch *) 0;
|
||||
|
||||
mread(fd, (genericptr_t) &count, sizeof(count));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &count, sizeof(count));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &count, "dungeon", "branch_count", 1);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
curr = (branch *) alloc(sizeof(branch));
|
||||
mread(fd, (genericptr_t) curr, sizeof(branch));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) curr, sizeof(branch));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_branch(nhfp, curr, "dungeon", "branch", 1);
|
||||
curr->next = (branch *) 0;
|
||||
if (last)
|
||||
last->next = curr;
|
||||
@@ -212,18 +258,33 @@ int fd;
|
||||
last = curr;
|
||||
}
|
||||
|
||||
mread(fd, (genericptr_t) &count, sizeof(count));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &count, sizeof(count));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &count, "dungeon", "level_info_count", 1);
|
||||
|
||||
if (count >= MAXLINFO)
|
||||
panic("level information count larger (%d) than allocated size",
|
||||
count);
|
||||
mread(fd, (genericptr_t) g.level_info,
|
||||
(unsigned) count * sizeof(struct linfo));
|
||||
mread(fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) g.level_info,
|
||||
(unsigned) count * sizeof(struct linfo));
|
||||
if (nhfp->fieldlevel)
|
||||
for (i = 0; i < count; ++i)
|
||||
sfi_linfo(nhfp, &g.level_info[i], "dungeon", "g.level_info", 1);
|
||||
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos);
|
||||
mread(nhfp->fd, (genericptr_t) &count, sizeof(count));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_nhcoord(nhfp, &g.inv_pos, "dungeon", "inv_pos", 1);
|
||||
sfi_int(nhfp, &count, "dungeon", "mapseen_count", 1);
|
||||
}
|
||||
|
||||
mread(fd, (genericptr_t) &count, sizeof(count));
|
||||
last_ms = (mapseen *) 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
curr_ms = load_mapseen(fd);
|
||||
curr_ms = load_mapseen(nhfp);
|
||||
curr_ms->next = (mapseen *) 0;
|
||||
if (last_ms)
|
||||
last_ms->next = curr_ms;
|
||||
@@ -752,7 +813,7 @@ init_dungeons()
|
||||
*/
|
||||
if (iflags.window_inited)
|
||||
clear_nhwindow(WIN_MAP);
|
||||
if (!check_version(&vers_info, DUNGEON_FILE, TRUE))
|
||||
if (!check_version(&vers_info, DUNGEON_FILE, TRUE, UTD_CHECKSIZES))
|
||||
panic("Dungeon description not valid.");
|
||||
|
||||
/*
|
||||
@@ -2187,58 +2248,106 @@ int ledger_num;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
save_mapseen(fd, mptr)
|
||||
int fd;
|
||||
save_mapseen(nhfp, mptr)
|
||||
NHFILE *nhfp;
|
||||
mapseen *mptr;
|
||||
{
|
||||
branch *curr;
|
||||
int brindx;
|
||||
int i, brindx;
|
||||
|
||||
for (brindx = 0, curr = g.branches; curr; curr = curr->next, ++brindx)
|
||||
if (curr == mptr->br)
|
||||
break;
|
||||
bwrite(fd, (genericptr_t) &brindx, sizeof brindx);
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &brindx, sizeof brindx);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &brindx, "mapseen", "branch_index", 1);
|
||||
|
||||
bwrite(fd, (genericptr_t) &mptr->lev, sizeof mptr->lev);
|
||||
bwrite(fd, (genericptr_t) &mptr->feat, sizeof mptr->feat);
|
||||
bwrite(fd, (genericptr_t) &mptr->flags, sizeof mptr->flags);
|
||||
bwrite(fd, (genericptr_t) &mptr->custom_lth, sizeof mptr->custom_lth);
|
||||
if (mptr->custom_lth)
|
||||
bwrite(fd, (genericptr_t) mptr->custom, mptr->custom_lth);
|
||||
bwrite(fd, (genericptr_t) mptr->msrooms, sizeof mptr->msrooms);
|
||||
savecemetery(fd, WRITE_SAVE, &mptr->final_resting_place);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &mptr->lev, sizeof mptr->lev);
|
||||
bwrite(nhfp->fd, (genericptr_t) &mptr->feat, sizeof mptr->feat);
|
||||
bwrite(nhfp->fd, (genericptr_t) &mptr->flags, sizeof mptr->flags);
|
||||
bwrite(nhfp->fd, (genericptr_t) &mptr->custom_lth, sizeof mptr->custom_lth);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_d_level(nhfp, &mptr->lev, "mapseen", "d_level", 1);
|
||||
sfo_mapseen_feat(nhfp, &mptr->feat, "mapseen", "feat", 1);
|
||||
sfo_mapseen_flags(nhfp, &mptr->flags, "mapseen", "flags", 1);
|
||||
sfo_unsigned(nhfp, &mptr->custom_lth, "mapseen", "custom_lth", 1);
|
||||
}
|
||||
|
||||
if (mptr->custom_lth) {
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) mptr->custom, mptr->custom_lth);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < (int) mptr->custom_lth; ++i)
|
||||
sfo_char(nhfp, &mptr->custom[i], "mapseen", "custom", 1);
|
||||
}
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &mptr->msrooms, sizeof mptr->msrooms);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < ((MAXNROFROOMS + 1) * 2); ++i)
|
||||
sfo_mapseen_rooms(nhfp, &mptr->msrooms[i], "mapseen", "msrooms", 1);
|
||||
}
|
||||
savecemetery(nhfp, &mptr->final_resting_place);
|
||||
}
|
||||
|
||||
STATIC_OVL mapseen *
|
||||
load_mapseen(fd)
|
||||
int fd;
|
||||
load_mapseen(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
int branchnum, brindx;
|
||||
int i, branchnum, brindx;
|
||||
mapseen *load;
|
||||
branch *curr;
|
||||
|
||||
load = (mapseen *) alloc(sizeof *load);
|
||||
|
||||
mread(fd, (genericptr_t) &branchnum, sizeof branchnum);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &branchnum, sizeof branchnum);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &branchnum, "mapseen", "branch_index", 1);
|
||||
for (brindx = 0, curr = g.branches; curr; curr = curr->next, ++brindx)
|
||||
if (brindx == branchnum)
|
||||
break;
|
||||
load->br = curr;
|
||||
|
||||
mread(fd, (genericptr_t) &load->lev, sizeof load->lev);
|
||||
mread(fd, (genericptr_t) &load->feat, sizeof load->feat);
|
||||
mread(fd, (genericptr_t) &load->flags, sizeof load->flags);
|
||||
mread(fd, (genericptr_t) &load->custom_lth, sizeof load->custom_lth);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &load->lev, sizeof load->lev);
|
||||
mread(nhfp->fd, (genericptr_t) &load->feat, sizeof load->feat);
|
||||
mread(nhfp->fd, (genericptr_t) &load->flags, sizeof load->flags);
|
||||
mread(nhfp->fd, (genericptr_t) &load->custom_lth, sizeof load->custom_lth);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_d_level(nhfp, &load->lev, "mapseen", "d_level", 1);
|
||||
sfi_mapseen_feat(nhfp, &load->feat, "mapseen", "feat", 1);
|
||||
sfi_mapseen_flags(nhfp, &load->flags, "mapseen", "flags", 1);
|
||||
sfi_unsigned(nhfp, &load->custom_lth, "mapseen", "custom_lth", 1);
|
||||
}
|
||||
|
||||
if (load->custom_lth) {
|
||||
/* length doesn't include terminator (which isn't saved & restored) */
|
||||
load->custom = (char *) alloc(load->custom_lth + 1);
|
||||
mread(fd, (genericptr_t) load->custom, load->custom_lth);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) load->custom, load->custom_lth);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < (int) load->custom_lth; ++i)
|
||||
sfi_char(nhfp, &load->custom[i], "mapseen", "custom", 1);
|
||||
}
|
||||
load->custom[load->custom_lth] = '\0';
|
||||
} else
|
||||
load->custom = 0;
|
||||
mread(fd, (genericptr_t) load->msrooms, sizeof load->msrooms);
|
||||
restcemetery(fd, &load->final_resting_place);
|
||||
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &load->msrooms, sizeof load->msrooms);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < ((MAXNROFROOMS + 1) * 2); ++i)
|
||||
sfi_mapseen_rooms(nhfp, &load->msrooms[i], "mapseen", "msrooms", 1);
|
||||
}
|
||||
restcemetery(nhfp, &load->final_resting_place);
|
||||
return load;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#include "dlb.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/* add b to long a, convert wraparound to max value */
|
||||
#define nowrap_add(a, b) (a = ((a + b) < 0 ? LONG_MAX : (a + b)))
|
||||
@@ -2131,18 +2133,20 @@ struct kinfo *kptr;
|
||||
}
|
||||
|
||||
void
|
||||
save_killers(fd, mode)
|
||||
int fd;
|
||||
int mode;
|
||||
save_killers(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
struct kinfo *kptr;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
if (perform_bwrite(nhfp)) {
|
||||
for (kptr = &g.killer; kptr != (struct kinfo *) 0; kptr = kptr->next) {
|
||||
bwrite(fd, (genericptr_t) kptr, sizeof (struct kinfo));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t)kptr, sizeof(struct kinfo));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_kinfo(nhfp, kptr, "killers", "kinfo", 1);
|
||||
}
|
||||
}
|
||||
if (release_data(mode)) {
|
||||
if (release_data(nhfp)) {
|
||||
while (g.killer.next) {
|
||||
kptr = g.killer.next->next;
|
||||
free((genericptr_t) g.killer.next);
|
||||
@@ -2152,13 +2156,16 @@ int mode;
|
||||
}
|
||||
|
||||
void
|
||||
restore_killers(fd)
|
||||
int fd;
|
||||
restore_killers(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
struct kinfo *kptr;
|
||||
|
||||
for (kptr = &g.killer; kptr != (struct kinfo *) 0; kptr = kptr->next) {
|
||||
mread(fd, (genericptr_t) kptr, sizeof (struct kinfo));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t)kptr, sizeof(struct kinfo));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_kinfo(nhfp, kptr, "killers", "kinfo", 1);
|
||||
if (kptr->next) {
|
||||
kptr->next = (struct kinfo *) alloc(sizeof (struct kinfo));
|
||||
}
|
||||
|
||||
+40
-17
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
STATIC_VAR NEARDATA struct engr *head_engr;
|
||||
STATIC_DCL const char *NDECL(blengr);
|
||||
@@ -1173,48 +1175,69 @@ sanitize_engravings()
|
||||
}
|
||||
|
||||
void
|
||||
save_engravings(fd, mode)
|
||||
int fd, mode;
|
||||
save_engravings(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
struct engr *ep, *ep2;
|
||||
unsigned no_more_engr = 0;
|
||||
|
||||
for (ep = head_engr; ep; ep = ep2) {
|
||||
ep2 = ep->nxt_engr;
|
||||
if (ep->engr_lth && ep->engr_txt[0] && perform_bwrite(mode)) {
|
||||
bwrite(fd, (genericptr_t) &ep->engr_lth, sizeof ep->engr_lth);
|
||||
bwrite(fd, (genericptr_t) ep, sizeof (struct engr) + ep->engr_lth);
|
||||
if (ep->engr_lth && ep->engr_txt[0] && perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t)&(ep->engr_lth), sizeof(ep->engr_lth));
|
||||
bwrite(nhfp->fd, (genericptr_t)ep, sizeof(struct engr) + ep->engr_lth);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_unsigned(nhfp, &(ep->engr_lth), "engravings", "engr_lth", 1);
|
||||
sfo_engr(nhfp, ep, "engravings", "engr", 1);
|
||||
sfo_str(nhfp, ep->engr_txt, "engravings", "engr_txt", ep->engr_lth);
|
||||
}
|
||||
}
|
||||
if (release_data(mode))
|
||||
if (release_data(nhfp))
|
||||
dealloc_engr(ep);
|
||||
}
|
||||
if (perform_bwrite(mode))
|
||||
bwrite(fd, (genericptr_t) &no_more_engr, sizeof no_more_engr);
|
||||
if (release_data(mode))
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t)&no_more_engr, sizeof no_more_engr);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_unsigned(nhfp, &no_more_engr, "engravings", "engr_lth", 1);
|
||||
}
|
||||
if (release_data(nhfp))
|
||||
head_engr = 0;
|
||||
}
|
||||
|
||||
void
|
||||
rest_engravings(fd)
|
||||
int fd;
|
||||
rest_engravings(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
struct engr *ep;
|
||||
unsigned lth;
|
||||
|
||||
head_engr = 0;
|
||||
while (1) {
|
||||
mread(fd, (genericptr_t) <h, sizeof lth);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) <h, sizeof(unsigned));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_unsigned(nhfp, <h, "engravings", "engr_lth", 1);
|
||||
|
||||
if (lth == 0)
|
||||
return;
|
||||
ep = newengr(lth);
|
||||
mread(fd, (genericptr_t) ep, sizeof (struct engr) + lth);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) ep, sizeof(struct engr) + lth);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_engr(nhfp, ep, "engravings", "engr", 1);
|
||||
ep->engr_txt = (char *) (ep + 1);
|
||||
sfi_str(nhfp, ep->engr_txt, "engravings", "engr_txt", lth);
|
||||
}
|
||||
ep->nxt_engr = head_engr;
|
||||
head_engr = ep;
|
||||
ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
|
||||
/* Mark as finished for bones levels -- no problem for
|
||||
ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
|
||||
/* mark as finished for bones levels -- no problem for
|
||||
* normal levels as the player must have finished engraving
|
||||
* to be able to move again.
|
||||
*/
|
||||
* to be able to move again */
|
||||
ep->engr_time = g.moves;
|
||||
}
|
||||
}
|
||||
|
||||
+538
-148
File diff suppressed because it is too large
Load Diff
+58
-25
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h" /* for checking save modes */
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/*
|
||||
* Mobile light sources.
|
||||
@@ -42,25 +44,27 @@
|
||||
#define LSF_SHOW 0x1 /* display the light source */
|
||||
#define LSF_NEEDS_FIXUP 0x2 /* need oid fixup */
|
||||
|
||||
STATIC_DCL void FDECL(write_ls, (int, light_source *));
|
||||
STATIC_DCL int FDECL(maybe_write_ls, (int, int, BOOLEAN_P));
|
||||
/* SAVE2018 */
|
||||
STATIC_DCL void FDECL(write_ls, (NHFILE *, light_source *));
|
||||
STATIC_DCL int FDECL(maybe_write_ls, (NHFILE *, int, BOOLEAN_P));
|
||||
|
||||
/* imported from vision.c, for small circles */
|
||||
extern char circle_data[];
|
||||
extern char circle_start[];
|
||||
|
||||
|
||||
/* Create a new light source. */
|
||||
void
|
||||
new_light_source(x, y, range, type, id)
|
||||
xchar x, y;
|
||||
int range, type;
|
||||
anything *id;
|
||||
xchar x, y;
|
||||
int range, type;
|
||||
anything *id;
|
||||
{
|
||||
light_source *ls;
|
||||
|
||||
if (range > MAX_RADIUS || range < 1) {
|
||||
impossible("new_light_source: illegal range %d", range);
|
||||
return;
|
||||
impossible("new_light_source: illegal range %d", range);
|
||||
return;
|
||||
}
|
||||
|
||||
ls = (light_source *) alloc(sizeof *ls);
|
||||
@@ -311,22 +315,28 @@ unsigned fmflags;
|
||||
|
||||
/* Save all light sources of the given range. */
|
||||
void
|
||||
save_light_sources(fd, mode, range)
|
||||
int fd, mode, range;
|
||||
save_light_sources(nhfp, range)
|
||||
NHFILE *nhfp;
|
||||
int range;
|
||||
{
|
||||
int count, actual, is_global;
|
||||
light_source **prev, *curr;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
count = maybe_write_ls(fd, range, FALSE);
|
||||
bwrite(fd, (genericptr_t) &count, sizeof count);
|
||||
actual = maybe_write_ls(fd, range, TRUE);
|
||||
if (perform_bwrite(nhfp)) {
|
||||
count = maybe_write_ls(nhfp, range, FALSE);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &count, sizeof count);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_int(nhfp, &count, "lightsources", "lightsource_count", 1);
|
||||
}
|
||||
actual = maybe_write_ls(nhfp, range, TRUE);
|
||||
if (actual != count)
|
||||
panic("counted %d light sources, wrote %d! [range=%d]", count,
|
||||
actual, range);
|
||||
}
|
||||
|
||||
if (release_data(mode)) {
|
||||
|
||||
if (release_data(nhfp)) {
|
||||
for (prev = &g.light_base; (curr = *prev) != 0;) {
|
||||
if (!curr->id.a_monst) {
|
||||
impossible("save_light_sources: no id! [range=%d]", range);
|
||||
@@ -361,18 +371,24 @@ int fd, mode, range;
|
||||
* pointers.
|
||||
*/
|
||||
void
|
||||
restore_light_sources(fd)
|
||||
int fd;
|
||||
restore_light_sources(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
int count;
|
||||
light_source *ls;
|
||||
|
||||
/* restore elements */
|
||||
mread(fd, (genericptr_t) &count, sizeof count);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &count, sizeof count);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &count, "lightsources", "lightsource_count", 1);
|
||||
|
||||
while (count-- > 0) {
|
||||
ls = (light_source *) alloc(sizeof(light_source));
|
||||
mread(fd, (genericptr_t) ls, sizeof(light_source));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) ls, sizeof(light_source));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_ls_t(nhfp, ls, "lightsources", "lightsource", 1);
|
||||
ls->next = g.light_base;
|
||||
g.light_base = ls;
|
||||
}
|
||||
@@ -430,14 +446,17 @@ boolean ghostly;
|
||||
}
|
||||
}
|
||||
|
||||
/* SAVE2018 */
|
||||
|
||||
/*
|
||||
* Part of the light source save routine. Count up the number of light
|
||||
* sources that would be written. If write_it is true, actually write
|
||||
* the light source out.
|
||||
*/
|
||||
STATIC_OVL int
|
||||
maybe_write_ls(fd, range, write_it)
|
||||
int fd, range;
|
||||
maybe_write_ls(nhfp, range, write_it)
|
||||
NHFILE *nhfp;
|
||||
int range;
|
||||
boolean write_it;
|
||||
{
|
||||
int count = 0, is_global;
|
||||
@@ -465,7 +484,7 @@ boolean write_it;
|
||||
if (is_global ^ (range == RANGE_LEVEL)) {
|
||||
count++;
|
||||
if (write_it)
|
||||
write_ls(fd, ls);
|
||||
write_ls(nhfp, ls);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,11 +518,19 @@ light_sources_sanity_check()
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a light source structure to disk. */
|
||||
/* SAVE2018 */
|
||||
#if 0
|
||||
STATIC_OVL void
|
||||
write_ls(fd, ls)
|
||||
int fd;
|
||||
light_source *ls;
|
||||
#endif /* 0 */
|
||||
|
||||
/* Write a light source structure to disk. */
|
||||
STATIC_OVL void
|
||||
write_ls(nhfp, ls)
|
||||
NHFILE *nhfp;
|
||||
light_source *ls;
|
||||
{
|
||||
anything arg_save;
|
||||
struct obj *otmp;
|
||||
@@ -511,7 +538,10 @@ light_source *ls;
|
||||
|
||||
if (ls->type == LS_OBJECT || ls->type == LS_MONSTER) {
|
||||
if (ls->flags & LSF_NEEDS_FIXUP) {
|
||||
bwrite(fd, (genericptr_t) ls, sizeof(light_source));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) ls, sizeof(light_source));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_ls_t(nhfp, ls, "lightsources", "lightsource", 1);
|
||||
} else {
|
||||
/* replace object pointer with id for write, then put back */
|
||||
arg_save = ls->id;
|
||||
@@ -531,7 +561,10 @@ light_source *ls;
|
||||
ls->id.a_uint);
|
||||
}
|
||||
ls->flags |= LSF_NEEDS_FIXUP;
|
||||
bwrite(fd, (genericptr_t) ls, sizeof(light_source));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) ls, sizeof(light_source));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_ls_t(nhfp, ls, "lightsources", "lightsource", 1);
|
||||
ls->id = arg_save;
|
||||
ls->flags &= ~LSF_NEEDS_FIXUP;
|
||||
}
|
||||
|
||||
+56
-29
@@ -6,6 +6,8 @@
|
||||
#include "hack.h"
|
||||
#include "sp_lev.h"
|
||||
#include "lev.h" /* save & restore info */
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
STATIC_DCL int FDECL(iswall, (int, int));
|
||||
STATIC_DCL int FDECL(iswall_or_stone, (int, int));
|
||||
@@ -1558,33 +1560,46 @@ water_friction()
|
||||
}
|
||||
|
||||
void
|
||||
save_waterlevel(fd, mode)
|
||||
int fd, mode;
|
||||
save_waterlevel(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
struct bubble *b;
|
||||
|
||||
if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz))
|
||||
return;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
if (perform_bwrite(nhfp)) {
|
||||
int n = 0;
|
||||
for (b = g.bbubbles; b; b = b->next)
|
||||
++n;
|
||||
bwrite(fd, (genericptr_t) &n, sizeof n);
|
||||
bwrite(fd, (genericptr_t) &g.xmin, sizeof g.xmin);
|
||||
bwrite(fd, (genericptr_t) &g.ymin, sizeof g.ymin);
|
||||
bwrite(fd, (genericptr_t) &g.xmax, sizeof g.xmax);
|
||||
bwrite(fd, (genericptr_t) &g.ymax, sizeof g.ymax);
|
||||
for (b = g.bbubbles; b; b = b->next)
|
||||
bwrite(fd, (genericptr_t) b, sizeof *b);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &n, sizeof(int));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.xmin, sizeof(int));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.ymin, sizeof(int));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.xmax, sizeof(int));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.ymax, sizeof(int));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_int(nhfp, &n, "waterlevel", "bubble_count", 1);
|
||||
sfo_int(nhfp, &g.xmin, "waterlevel", "g.xmin", 1);
|
||||
sfo_int(nhfp, &g.ymin, "waterlevel", "g.ymin", 1);
|
||||
sfo_int(nhfp, &g.xmax, "waterlevel", "g.xmax", 1);
|
||||
sfo_int(nhfp, &g.ymax, "waterlevel", "g.ymax", 1);
|
||||
}
|
||||
for (b = g.bbubbles; b; b = b->next) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) b, sizeof(struct bubble));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_bubble(nhfp, b, "waterlevel", "bubble", 1);
|
||||
}
|
||||
}
|
||||
if (release_data(mode))
|
||||
if (release_data(nhfp))
|
||||
unsetup_waterlevel();
|
||||
}
|
||||
|
||||
void
|
||||
restore_waterlevel(fd)
|
||||
int fd;
|
||||
restore_waterlevel(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
struct bubble *b = (struct bubble *) 0, *btmp;
|
||||
int i, n;
|
||||
@@ -1592,7 +1607,7 @@ int fd;
|
||||
if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz))
|
||||
return;
|
||||
|
||||
if (fd == -1) { /* special handling for restore in goto_level() */
|
||||
if (nhfp->fd == -1) { /* special handling for restore in goto_level() */
|
||||
if (!wizard)
|
||||
impossible("restore_waterlevel: returning to %s?",
|
||||
Is_waterlevel(&u.uz) ? "Water" : "Air");
|
||||
@@ -1601,23 +1616,35 @@ int fd;
|
||||
}
|
||||
|
||||
set_wportal();
|
||||
mread(fd, (genericptr_t) &n, sizeof n);
|
||||
mread(fd, (genericptr_t) &g.xmin, sizeof g.xmin);
|
||||
mread(fd, (genericptr_t) &g.ymin, sizeof g.ymin);
|
||||
mread(fd, (genericptr_t) &g.xmax, sizeof g.xmax);
|
||||
mread(fd, (genericptr_t) &g.ymax, sizeof g.ymax);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd,(genericptr_t)&n,sizeof(int));
|
||||
mread(nhfp->fd,(genericptr_t)&g.xmin,sizeof(int));
|
||||
mread(nhfp->fd,(genericptr_t)&g.ymin,sizeof(int));
|
||||
mread(nhfp->fd,(genericptr_t)&g.xmax,sizeof(int));
|
||||
mread(nhfp->fd,(genericptr_t)&g.ymax,sizeof(int));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_int(nhfp, &n, "waterlevel", "bubble_count", 1);
|
||||
sfi_int(nhfp, &g.xmin, "waterlevel", "g.xmin", 1);
|
||||
sfi_int(nhfp, &g.ymin, "waterlevel", "g.ymin", 1);
|
||||
sfi_int(nhfp, &g.xmax, "waterlevel", "g.xmax", 1);
|
||||
sfi_int(nhfp, &g.ymax, "waterlevel", "g.ymax", 1);
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
btmp = b;
|
||||
b = (struct bubble *) alloc(sizeof *b);
|
||||
mread(fd, (genericptr_t) b, sizeof *b);
|
||||
if (g.bbubbles) {
|
||||
btmp->next = b;
|
||||
b->prev = btmp;
|
||||
} else {
|
||||
g.bbubbles = b;
|
||||
b->prev = (struct bubble *) 0;
|
||||
}
|
||||
mv_bubble(b, 0, 0, TRUE);
|
||||
b = (struct bubble *) alloc(sizeof(struct bubble));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd,(genericptr_t) b, sizeof(struct bubble));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_bubble(nhfp, b, "waterlevel", "bubble", 1);
|
||||
if (g.bbubbles) {
|
||||
btmp->next = b;
|
||||
b->prev = btmp;
|
||||
} else {
|
||||
g.bbubbles = b;
|
||||
b->prev = (struct bubble *) 0;
|
||||
}
|
||||
mv_bubble(b, 0, 0, TRUE);
|
||||
}
|
||||
g.ebubbles = b;
|
||||
b->next = (struct bubble *) 0;
|
||||
|
||||
+39
-19
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "hack.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
STATIC_DCL boolean FDECL(isbig, (struct mkroom *));
|
||||
STATIC_DCL struct mkroom *FDECL(pick_room, (BOOLEAN_P));
|
||||
@@ -24,8 +26,11 @@ STATIC_DCL void NDECL(mktemple);
|
||||
STATIC_DCL coord *FDECL(shrine_pos, (int));
|
||||
STATIC_DCL struct permonst *NDECL(morguemon);
|
||||
STATIC_DCL struct permonst *NDECL(squadmon);
|
||||
STATIC_DCL void FDECL(save_room, (int, struct mkroom *));
|
||||
STATIC_DCL void FDECL(rest_room, (int, struct mkroom *));
|
||||
/* SAVE2018 */
|
||||
/* STATIC_DCL void FDECL(save_room, (int,struct mkroom *)); */
|
||||
/* STATIC_DCL void FDECL(rest_room, (int,struct mkroom *)); */
|
||||
STATIC_DCL void FDECL(save_room, (NHFILE *, struct mkroom *));
|
||||
STATIC_DCL void FDECL(rest_room, (NHFILE *, struct mkroom *));
|
||||
|
||||
#define sq(x) ((x) * (x))
|
||||
|
||||
@@ -796,8 +801,8 @@ gotone:
|
||||
* (if any).
|
||||
*/
|
||||
STATIC_OVL void
|
||||
save_room(fd, r)
|
||||
int fd;
|
||||
save_room(nhfp, r)
|
||||
NHFILE *nhfp;
|
||||
struct mkroom *r;
|
||||
{
|
||||
short i;
|
||||
@@ -807,37 +812,48 @@ struct mkroom *r;
|
||||
* of writing the whole structure. That is I should not write
|
||||
* the g.subrooms pointers, but who cares ?
|
||||
*/
|
||||
bwrite(fd, (genericptr_t) r, sizeof (struct mkroom));
|
||||
for (i = 0; i < r->nsubrooms; i++)
|
||||
save_room(fd, r->sbrooms[i]);
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) r, sizeof (struct mkroom));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_mkroom(nhfp, r, "room", "mkroom", 1);
|
||||
for (i = 0; i < r->nsubrooms; i++) {
|
||||
save_room(nhfp, r->sbrooms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* save_rooms : Save all the rooms on disk!
|
||||
*/
|
||||
void
|
||||
save_rooms(fd)
|
||||
int fd;
|
||||
save_rooms(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
short i;
|
||||
|
||||
/* First, write the number of rooms */
|
||||
bwrite(fd, (genericptr_t) &g.nroom, sizeof(g.nroom));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.nroom, sizeof(g.nroom));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &g.nroom, "room", "g.nroom", 1);
|
||||
for (i = 0; i < g.nroom; i++)
|
||||
save_room(fd, &g.rooms[i]);
|
||||
save_room(nhfp, &g.rooms[i]);
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
rest_room(fd, r)
|
||||
int fd;
|
||||
rest_room(nhfp, r)
|
||||
NHFILE *nhfp;
|
||||
struct mkroom *r;
|
||||
{
|
||||
short i;
|
||||
|
||||
mread(fd, (genericptr_t) r, sizeof(struct mkroom));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) r, sizeof(struct mkroom));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_mkroom(nhfp, r, "room", "mkroom", 1);
|
||||
|
||||
for (i = 0; i < r->nsubrooms; i++) {
|
||||
r->sbrooms[i] = &g.subrooms[g.nsubroom];
|
||||
rest_room(fd, &g.subrooms[g.nsubroom]);
|
||||
rest_room(nhfp, &g.subrooms[g.nsubroom]);
|
||||
g.subrooms[g.nsubroom++].resident = (struct monst *) 0;
|
||||
}
|
||||
}
|
||||
@@ -847,15 +863,19 @@ struct mkroom *r;
|
||||
* the disk.
|
||||
*/
|
||||
void
|
||||
rest_rooms(fd)
|
||||
int fd;
|
||||
rest_rooms(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
short i;
|
||||
|
||||
mread(fd, (genericptr_t) &g.nroom, sizeof(g.nroom));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.nroom, sizeof(g.nroom));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &g.nroom, "room", "g.nroom", 1);
|
||||
|
||||
g.nsubroom = 0;
|
||||
for (i = 0; i < g.nroom; i++) {
|
||||
rest_room(fd, &g.rooms[i]);
|
||||
rest_room(nhfp, &g.rooms[i]);
|
||||
g.rooms[i].resident = (struct monst *) 0;
|
||||
}
|
||||
g.rooms[g.nroom].hx = -1; /* restore ending flags */
|
||||
|
||||
+65
-22
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h" /* save & restore info */
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
STATIC_DCL void FDECL(setgemprobs, (d_level *));
|
||||
STATIC_DCL void FDECL(shuffle, (int, int, BOOLEAN_P));
|
||||
@@ -286,29 +288,46 @@ oinit()
|
||||
}
|
||||
|
||||
void
|
||||
savenames(fd, mode)
|
||||
int fd, mode;
|
||||
savenames(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
register int i;
|
||||
int i, j;
|
||||
unsigned int len;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
bwrite(fd, (genericptr_t) g.bases, sizeof g.bases);
|
||||
bwrite(fd, (genericptr_t) g.disco, sizeof g.disco);
|
||||
bwrite(fd, (genericptr_t) objects,
|
||||
sizeof(struct objclass) * NUM_OBJECTS);
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t)g.bases, sizeof g.bases);
|
||||
bwrite(nhfp->fd, (genericptr_t)g.disco, sizeof g.disco);
|
||||
bwrite(nhfp->fd, (genericptr_t)objects,
|
||||
sizeof(struct objclass) * NUM_OBJECTS);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < MAXOCLASSES; ++i)
|
||||
sfo_int(nhfp, &g.bases[i], "names", "g.bases", 1);
|
||||
for (i = 0; i < NUM_OBJECTS; ++i)
|
||||
sfo_short(nhfp, &g.disco[i], "names", "g.disco", 1);
|
||||
for (i = 0; i < NUM_OBJECTS; ++i)
|
||||
sfo_objclass(nhfp, &objects[i], "names", "objclass", 1);
|
||||
}
|
||||
}
|
||||
/* as long as we use only one version of Hack we
|
||||
need not save oc_name and oc_descr, but we must save
|
||||
oc_uname for all objects */
|
||||
for (i = 0; i < NUM_OBJECTS; i++)
|
||||
if (objects[i].oc_uname) {
|
||||
if (perform_bwrite(mode)) {
|
||||
if (perform_bwrite(nhfp)) {
|
||||
len = strlen(objects[i].oc_uname) + 1;
|
||||
bwrite(fd, (genericptr_t) &len, sizeof len);
|
||||
bwrite(fd, (genericptr_t) objects[i].oc_uname, len);
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t)&len, sizeof len);
|
||||
bwrite(nhfp->fd, (genericptr_t)objects[i].oc_uname, len);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_unsigned(nhfp, &len, "names", "len", 1);
|
||||
for (j = 0; (unsigned) j < len; ++j)
|
||||
sfo_char(nhfp, &objects[i].oc_uname[j], "names", "oc_uname", 1);
|
||||
}
|
||||
}
|
||||
if (release_data(mode)) {
|
||||
if (release_data(nhfp)) {
|
||||
free((genericptr_t) objects[i].oc_uname);
|
||||
objects[i].oc_uname = 0;
|
||||
}
|
||||
@@ -316,21 +335,45 @@ int fd, mode;
|
||||
}
|
||||
|
||||
void
|
||||
restnames(fd)
|
||||
register int fd;
|
||||
restnames(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
register int i;
|
||||
int i, j;
|
||||
unsigned int len;
|
||||
|
||||
mread(fd, (genericptr_t)g.bases, sizeof g.bases);
|
||||
mread(fd, (genericptr_t) g.disco, sizeof g.disco);
|
||||
mread(fd, (genericptr_t) objects, sizeof(struct objclass) * NUM_OBJECTS);
|
||||
for (i = 0; i < NUM_OBJECTS; i++)
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) g.bases, sizeof g.bases);
|
||||
mread(nhfp->fd, (genericptr_t) g.disco, sizeof g.disco);
|
||||
mread(nhfp->fd, (genericptr_t) objects,
|
||||
sizeof(struct objclass) * NUM_OBJECTS);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < MAXOCLASSES; ++i)
|
||||
sfi_int(nhfp, &g.bases[i], "names", "g.bases", 1);
|
||||
for (i = 0; i < NUM_OBJECTS; ++i)
|
||||
sfi_short(nhfp, &g.disco[i], "names", "g.disco", 1);
|
||||
for (i = 0; i < NUM_OBJECTS; ++i)
|
||||
sfi_objclass(nhfp, &objects[i], "names", "objclass", 1);
|
||||
}
|
||||
for (i = 0; i < NUM_OBJECTS; i++) {
|
||||
if (objects[i].oc_uname) {
|
||||
mread(fd, (genericptr_t) &len, sizeof len);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &len, sizeof len);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_unsigned(nhfp, &len, "names", "len", 1);
|
||||
}
|
||||
objects[i].oc_uname = (char *) alloc(len);
|
||||
mread(fd, (genericptr_t) objects[i].oc_uname, len);
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t)objects[i].oc_uname, len);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (j = 0; (unsigned) j < len; ++j)
|
||||
sfi_char(nhfp, &objects[i].oc_uname[j],
|
||||
"names", "oc_uname", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef USE_TILES
|
||||
shuffle_tiles();
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@ NEARDATA struct instance_flags iflags; /* provide linkage */
|
||||
#include "tcap.h"
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#include "sfprocs.h"
|
||||
|
||||
#define BACKWARD_COMPAT
|
||||
|
||||
@@ -698,6 +699,9 @@ initoptions_init()
|
||||
if (boolopt[i].addr)
|
||||
*(boolopt[i].addr) = boolopt[i].initvalue;
|
||||
}
|
||||
/* initialize the function pointers for fieldlevel saves */
|
||||
sf_init();
|
||||
|
||||
#if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
set_savepref("externalcomp");
|
||||
set_restpref("externalcomp");
|
||||
|
||||
+227
-88
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/*
|
||||
* This should really go into the level structure, but
|
||||
@@ -613,64 +615,126 @@ xchar x, y;
|
||||
* save_regions :
|
||||
*/
|
||||
void
|
||||
save_regions(fd, mode)
|
||||
int fd;
|
||||
int mode;
|
||||
save_regions(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
int i, j;
|
||||
unsigned n;
|
||||
|
||||
if (!perform_bwrite(mode))
|
||||
if (!perform_bwrite(nhfp))
|
||||
goto skip_lots;
|
||||
|
||||
bwrite(fd, (genericptr_t) &g.moves, sizeof(g.moves)); /* timestamp */
|
||||
bwrite(fd, (genericptr_t) &g.n_regions, sizeof(g.n_regions));
|
||||
for (i = 0; i < g.n_regions; i++) {
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->bounding_box, sizeof(NhRect));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->nrects, sizeof(short));
|
||||
for (j = 0; j < g.regions[i]->nrects; j++)
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->rects[j], sizeof(NhRect));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->attach_2_u, sizeof(boolean));
|
||||
n = 0;
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->attach_2_m, sizeof(unsigned));
|
||||
n = g.regions[i]->enter_msg != (const char *) 0
|
||||
? strlen(g.regions[i]->enter_msg)
|
||||
: 0;
|
||||
bwrite(fd, (genericptr_t) &n, sizeof n);
|
||||
if (n > 0)
|
||||
bwrite(fd, (genericptr_t) g.regions[i]->enter_msg, n);
|
||||
n = g.regions[i]->leave_msg != (const char *) 0
|
||||
? strlen(g.regions[i]->leave_msg)
|
||||
: 0;
|
||||
bwrite(fd, (genericptr_t) &n, sizeof n);
|
||||
if (n > 0)
|
||||
bwrite(fd, (genericptr_t) g.regions[i]->leave_msg, n);
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->ttl, sizeof(long));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->expire_f, sizeof(short));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->can_enter_f, sizeof(short));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->enter_f, sizeof(short));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->can_leave_f, sizeof(short));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->leave_f, sizeof(short));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->inside_f, sizeof(short));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->player_flags,
|
||||
sizeof(unsigned int));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->n_monst, sizeof(short));
|
||||
for (j = 0; j < g.regions[i]->n_monst; j++)
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->monsters[j],
|
||||
sizeof(unsigned));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->visible, sizeof(boolean));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->glyph, sizeof(int));
|
||||
bwrite(fd, (genericptr_t) &g.regions[i]->arg, sizeof(anything));
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.moves, sizeof (g.moves)); /* timestamp */
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.n_regions, sizeof (g.n_regions));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_long(nhfp, &g.moves, "regions", "tmstamp", 1);
|
||||
sfo_int(nhfp, &g.n_regions, "regions", "region_count", 1);
|
||||
}
|
||||
for (i = 0; i < g.n_regions; i++) {
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->bounding_box, sizeof (NhRect));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->nrects, sizeof (short));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_nhrect(nhfp, &g.regions[i]->bounding_box, "g.regions", "bounding_box", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->nrects, "g.regions", "nrects", 1);
|
||||
}
|
||||
for (j = 0; j < g.regions[i]->nrects; j++) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->rects[j], sizeof (NhRect));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_nhrect(nhfp, &g.regions[i]->rects[j], "g.regions", "rect", 1);
|
||||
}
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->attach_2_u, sizeof (boolean));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_boolean(nhfp, &g.regions[i]->attach_2_u, "g.regions", "attach_2_u", 1);
|
||||
n = 0;
|
||||
|
||||
skip_lots:
|
||||
if (release_data(mode))
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->attach_2_m, sizeof (unsigned));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_unsigned(nhfp, &g.regions[i]->attach_2_m, "g.regions", "attach_2_m", 1);
|
||||
|
||||
n = g.regions[i]->enter_msg != (const char *)0 ?
|
||||
strlen(g.regions[i]->enter_msg) : 0;
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &n, sizeof n);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_unsigned(nhfp, &n, "g.regions", "enter_msg_length", 1);
|
||||
|
||||
if (n > 0) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) g.regions[i]->enter_msg, n);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_char(nhfp, g.regions[i]->enter_msg, "g.regions", "enter_msg", 1);
|
||||
}
|
||||
n = g.regions[i]->leave_msg != (const char *)0 ?
|
||||
strlen(g.regions[i]->leave_msg) : 0;
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &n, sizeof n);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_unsigned(nhfp, &n, "g.regions", "leave_msg_length", 1);
|
||||
|
||||
if (n > 0) {
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) g.regions[i]->leave_msg, n);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (j = 0; j < (int) n; ++j)
|
||||
sfo_char(nhfp, &g.regions[i]->leave_msg[j], "g.regions", "leave_msg", 1);
|
||||
}
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->ttl, sizeof (long));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->expire_f, sizeof (short));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->can_enter_f, sizeof (short));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->enter_f, sizeof (short));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->can_leave_f, sizeof (short));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->leave_f, sizeof (short));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->inside_f, sizeof (short));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->player_flags, sizeof (unsigned int));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->n_monst, sizeof (short));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_long(nhfp, &g.regions[i]->ttl, "g.regions", "ttl", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->expire_f, "g.regions", "expire_f", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->can_enter_f, "g.regions", "can_enter_f", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->enter_f, "g.regions", "enter_f", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->can_leave_f, "g.regions", "can_leave_f", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->leave_f, "g.regions", "leave_f", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->inside_f, "g.regions", "inside_f", 1);
|
||||
sfo_unsigned(nhfp, &g.regions[i]->player_flags, "g.regions", "player_flags", 1);
|
||||
sfo_short(nhfp, &g.regions[i]->n_monst, "g.regions", "monster_count", 1);
|
||||
}
|
||||
for (j = 0; j < g.regions[i]->n_monst; j++) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->monsters[j],
|
||||
sizeof (unsigned));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_unsigned(nhfp, &g.regions[i]->monsters[j], "g.regions", "monster", 1);
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->visible, sizeof (boolean));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->glyph, sizeof (int));
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.regions[i]->arg, sizeof (anything));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_boolean(nhfp, &g.regions[i]->visible, "g.regions", "visible", 1);
|
||||
sfo_int(nhfp, &g.regions[i]->glyph, "g.regions", "glyph", 1);
|
||||
sfo_any(nhfp, &g.regions[i]->arg, "g.regions", "arg", 1);
|
||||
}
|
||||
}
|
||||
|
||||
skip_lots:
|
||||
if (release_data(nhfp))
|
||||
clear_regions();
|
||||
}
|
||||
|
||||
void
|
||||
rest_regions(fd, ghostly)
|
||||
int fd;
|
||||
rest_regions(nhfp, ghostly)
|
||||
NHFILE *nhfp;
|
||||
boolean ghostly; /* If a bones file restore */
|
||||
{
|
||||
int i, j;
|
||||
@@ -678,77 +742,152 @@ boolean ghostly; /* If a bones file restore */
|
||||
long tmstamp;
|
||||
char *msg_buf;
|
||||
|
||||
clear_regions(); /* Just for security */
|
||||
mread(fd, (genericptr_t) &tmstamp, sizeof(tmstamp));
|
||||
clear_regions(); /* Just for security */
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &tmstamp, sizeof (tmstamp));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_long(nhfp, &tmstamp, "regions", "tmstamp", 1);
|
||||
if (ghostly)
|
||||
tmstamp = 0;
|
||||
else
|
||||
tmstamp = (g.moves - tmstamp);
|
||||
mread(fd, (genericptr_t) &g.n_regions, sizeof(g.n_regions));
|
||||
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.n_regions, sizeof (g.n_regions));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &g.n_regions, "regions", "region_count", 1);
|
||||
|
||||
g.max_regions = g.n_regions;
|
||||
if (g.n_regions > 0)
|
||||
g.regions = (NhRegion **) alloc(sizeof(NhRegion *) * g.n_regions);
|
||||
g.regions = (NhRegion **) alloc(sizeof (NhRegion *) * g.n_regions);
|
||||
for (i = 0; i < g.n_regions; i++) {
|
||||
g.regions[i] = (NhRegion *) alloc(sizeof(NhRegion));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->bounding_box, sizeof(NhRect));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->nrects, sizeof(short));
|
||||
|
||||
g.regions[i] = (NhRegion *) alloc(sizeof (NhRegion));
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->bounding_box, sizeof (NhRect));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->nrects, sizeof (short));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_nhrect(nhfp, &g.regions[i]->bounding_box, "g.regions", "bounding box", 1);
|
||||
sfi_short(nhfp, &g.regions[i]->nrects, "g.regions", "nrects", 1);
|
||||
}
|
||||
if (g.regions[i]->nrects > 0)
|
||||
g.regions[i]->rects =
|
||||
(NhRect *) alloc(sizeof(NhRect) * g.regions[i]->nrects);
|
||||
for (j = 0; j < g.regions[i]->nrects; j++)
|
||||
mread(fd, (genericptr_t) &g.regions[i]->rects[j], sizeof(NhRect));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->attach_2_u, sizeof(boolean));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->attach_2_m, sizeof(unsigned));
|
||||
g.regions[i]->rects = (NhRect *)
|
||||
alloc(sizeof (NhRect) * g.regions[i]->nrects);
|
||||
for (j = 0; j < g.regions[i]->nrects; j++) {
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->rects[j], sizeof (NhRect));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_nhrect(nhfp, &g.regions[i]->rects[j], "g.regions", "rect", 1);
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->attach_2_u, sizeof (boolean));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->attach_2_m, sizeof (unsigned));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_boolean(nhfp, &g.regions[i]->attach_2_u, "g.regions", "attach_2_u", 1);
|
||||
sfi_unsigned(nhfp, &g.regions[i]->attach_2_m, "g.regions", "attach_2_m", 1);
|
||||
}
|
||||
|
||||
mread(fd, (genericptr_t) &n, sizeof n);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &n, sizeof n);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_unsigned(nhfp, &n, "g.regions", "enter_msg_length", 1);
|
||||
if (n > 0) {
|
||||
msg_buf = (char *) alloc(n + 1);
|
||||
mread(fd, (genericptr_t) msg_buf, n);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) msg_buf, n);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (j = 0; (unsigned) j < n; ++j)
|
||||
sfi_char(nhfp, &msg_buf[j], "g.regions", "enter_msg", 1);
|
||||
}
|
||||
msg_buf[n] = '\0';
|
||||
g.regions[i]->enter_msg = (const char *) msg_buf;
|
||||
} else
|
||||
g.regions[i]->enter_msg = (const char *) 0;
|
||||
g.regions[i]->enter_msg = (const char *)0;
|
||||
|
||||
mread(fd, (genericptr_t) &n, sizeof n);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &n, sizeof n);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_unsigned(nhfp, &n, "g.regions", "leave_msg_length", 1);
|
||||
if (n > 0) {
|
||||
msg_buf = (char *) alloc(n + 1);
|
||||
mread(fd, (genericptr_t) msg_buf, n);
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) msg_buf, n);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (j = 0; (unsigned) j < n; ++j)
|
||||
sfi_char(nhfp, &msg_buf[j], "g.regions", "leave_msg", 1);
|
||||
}
|
||||
msg_buf[n] = '\0';
|
||||
g.regions[i]->leave_msg = (const char *) msg_buf;
|
||||
g.regions[i]->leave_msg = (const char *) msg_buf;
|
||||
} else
|
||||
g.regions[i]->leave_msg = (const char *) 0;
|
||||
g.regions[i]->leave_msg = (const char *)0;
|
||||
|
||||
mread(fd, (genericptr_t) &g.regions[i]->ttl, sizeof(long));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->ttl, sizeof (long));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_long(nhfp, &g.regions[i]->ttl, "g.regions", "ttl", 1);
|
||||
/* check for expired region */
|
||||
if (g.regions[i]->ttl >= 0L)
|
||||
g.regions[i]->ttl =
|
||||
(g.regions[i]->ttl > tmstamp) ? g.regions[i]->ttl - tmstamp : 0L;
|
||||
mread(fd, (genericptr_t) &g.regions[i]->expire_f, sizeof(short));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->can_enter_f, sizeof(short));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->enter_f, sizeof(short));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->can_leave_f, sizeof(short));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->leave_f, sizeof(short));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->inside_f, sizeof(short));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->player_flags,
|
||||
sizeof(unsigned int));
|
||||
if (ghostly) { /* settings pertained to old player */
|
||||
(g.regions[i]->ttl > tmstamp) ? g.regions[i]->ttl - tmstamp : 0L;
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->expire_f,
|
||||
sizeof (short));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->can_enter_f,
|
||||
sizeof (short));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->enter_f,
|
||||
sizeof (short));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->can_leave_f,
|
||||
sizeof (short));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->leave_f,
|
||||
sizeof (short));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->inside_f,
|
||||
sizeof (short));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->player_flags,
|
||||
sizeof (unsigned int));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_short(nhfp, &g.regions[i]->expire_f, "g.regions", "expire_f", 1);
|
||||
sfi_short(nhfp, &g.regions[i]->can_enter_f, "g.regions", "can_enter_f", 1);
|
||||
sfi_short(nhfp, &g.regions[i]->enter_f, "g.regions", "enter_f", 1);
|
||||
sfi_short(nhfp, &g.regions[i]->can_leave_f, "g.regions", "can_leave_f", 1);
|
||||
sfi_short(nhfp, &g.regions[i]->leave_f, "g.regions", "leave_f", 1);
|
||||
sfi_short(nhfp, &g.regions[i]->inside_f, "g.regions", "inside_f", 1);
|
||||
sfi_unsigned(nhfp, &g.regions[i]->player_flags, "g.regions", "player_flags", 1);
|
||||
}
|
||||
if (ghostly) { /* settings pertained to old player */
|
||||
clear_hero_inside(g.regions[i]);
|
||||
clear_heros_fault(g.regions[i]);
|
||||
}
|
||||
mread(fd, (genericptr_t) &g.regions[i]->n_monst, sizeof(short));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->n_monst, sizeof (short));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_short(nhfp, &g.regions[i]->n_monst, "g.regions", "monster_count", 1);
|
||||
if (g.regions[i]->n_monst > 0)
|
||||
g.regions[i]->monsters =
|
||||
(unsigned *) alloc(sizeof(unsigned) * g.regions[i]->n_monst);
|
||||
(unsigned *) alloc(sizeof (unsigned) * g.regions[i]->n_monst);
|
||||
else
|
||||
g.regions[i]->monsters = (unsigned int *) 0;
|
||||
g.regions[i]->monsters = (unsigned int *)0;
|
||||
g.regions[i]->max_monst = g.regions[i]->n_monst;
|
||||
for (j = 0; j < g.regions[i]->n_monst; j++)
|
||||
mread(fd, (genericptr_t) &g.regions[i]->monsters[j],
|
||||
sizeof(unsigned));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->visible, sizeof(boolean));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->glyph, sizeof(int));
|
||||
mread(fd, (genericptr_t) &g.regions[i]->arg, sizeof(anything));
|
||||
for (j = 0; j < g.regions[i]->n_monst; j++) {
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->monsters[j],
|
||||
sizeof (unsigned));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_unsigned(nhfp, &g.regions[i]->monsters[j], "g.regions", "monster", 1);
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->visible, sizeof (boolean));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->glyph, sizeof (int));
|
||||
mread(nhfp->fd, (genericptr_t) &g.regions[i]->arg, sizeof (anything));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_boolean(nhfp, &g.regions[i]->visible, "g.regions", "visible", 1);
|
||||
sfi_int(nhfp, &g.regions[i]->glyph, "g.regions", "glyph", 1);
|
||||
sfi_any(nhfp, &g.regions[i]->arg, "g.regions", "arg", 1);
|
||||
}
|
||||
}
|
||||
/* remove expired regions, do not trigger the expire_f callback (yet!);
|
||||
also update monster lists if this data is coming from a bones file */
|
||||
|
||||
+649
-309
File diff suppressed because it is too large
Load Diff
+36
-11
@@ -6,6 +6,8 @@
|
||||
#include "hack.h"
|
||||
#include "lev.h"
|
||||
#include "dlb.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/* [note: this comment is fairly old, but still accurate for 3.1]
|
||||
* Rumors have been entirely rewritten to speed up the access. This is
|
||||
@@ -383,15 +385,27 @@ dlb *fp;
|
||||
}
|
||||
|
||||
void
|
||||
save_oracles(fd, mode)
|
||||
int fd, mode;
|
||||
save_oracles(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
if (perform_bwrite(mode)) {
|
||||
bwrite(fd, (genericptr_t) &g.oracle_cnt, sizeof g.oracle_cnt);
|
||||
if (g.oracle_cnt)
|
||||
bwrite(fd, (genericptr_t) g.oracle_loc, g.oracle_cnt * sizeof(long));
|
||||
int i;
|
||||
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.oracle_cnt, sizeof g.oracle_cnt);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_unsigned(nhfp, &g.oracle_cnt, "oracles", "g.oracle_cnt", 1);
|
||||
if (g.oracle_cnt) {
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t)g.oracle_loc, g.oracle_cnt * sizeof (long));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; (unsigned) i < g.oracle_cnt; ++i)
|
||||
sfo_ulong(nhfp, &g.oracle_loc[i], "oracles", "oracle loc", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (release_data(mode)) {
|
||||
if (release_data(nhfp)) {
|
||||
if (g.oracle_cnt) {
|
||||
free((genericptr_t) g.oracle_loc);
|
||||
g.oracle_loc = 0, g.oracle_cnt = 0, g.oracle_flg = 0;
|
||||
@@ -400,13 +414,24 @@ int fd, mode;
|
||||
}
|
||||
|
||||
void
|
||||
restore_oracles(fd)
|
||||
int fd;
|
||||
restore_oracles(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
mread(fd, (genericptr_t) &g.oracle_cnt, sizeof g.oracle_cnt);
|
||||
int i;
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.oracle_cnt, sizeof g.oracle_cnt);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_unsigned(nhfp, &g.oracle_cnt, "oracles", "g.oracle_cnt", 1);
|
||||
|
||||
if (g.oracle_cnt) {
|
||||
g.oracle_loc = (unsigned long *) alloc(g.oracle_cnt * sizeof(long));
|
||||
mread(fd, (genericptr_t) g.oracle_loc, g.oracle_cnt * sizeof(long));
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) g.oracle_loc, g.oracle_cnt * sizeof (long));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; (unsigned) i < g.oracle_cnt; ++i)
|
||||
sfi_ulong(nhfp, &g.oracle_loc[i], "oracles", "g.oracle_loc", 1);
|
||||
}
|
||||
g.oracle_flg = 1; /* no need to call init_oracles() */
|
||||
}
|
||||
}
|
||||
|
||||
+616
-294
File diff suppressed because it is too large
Load Diff
+1112
File diff suppressed because it is too large
Load Diff
+640
@@ -0,0 +1,640 @@
|
||||
/* NetHack 3.6 sf_base.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */
|
||||
/* Copyright (c) Michael Allison, 2019. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
#include "integer.h"
|
||||
#include "sfprocs.h"
|
||||
|
||||
struct sf_procs sfoprocs[4], sfiprocs[4],
|
||||
zerosfoprocs = {0}, zerosfiprocs = {0};
|
||||
|
||||
void FDECL(sfi_log, (NHFILE *, const char *, const char *, const char *, int));
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* initialize the function pointers. These are called from initoptions_init().
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
sf_init()
|
||||
{
|
||||
sfoprocs[invalid] = zerosfoprocs;
|
||||
sfiprocs[invalid] = zerosfiprocs;
|
||||
sfoprocs[historical] = zerosfoprocs;
|
||||
sfiprocs[historical] = zerosfiprocs;
|
||||
sfoprocs[lendian] = lendian_sfo_procs;
|
||||
sfiprocs[lendian] = lendian_sfi_procs;
|
||||
sfoprocs[ascii] = ascii_sfo_procs;
|
||||
sfiprocs[ascii] = ascii_sfi_procs;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------
|
||||
* routines called from engine core and
|
||||
* from functions in generated sfdata.c
|
||||
*----------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
sfo_any(nhfp, d_any, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
union any *d_any;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_any)(nhfp, d_any, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_aligntyp(nhfp, d_aligntyp, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
aligntyp *d_aligntyp;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_aligntyp)(nhfp, d_aligntyp, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_bitfield(nhfp, d_bitfield, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
uint8_t *d_bitfield;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_bitfield)(nhfp, d_bitfield, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_boolean(nhfp, d_boolean, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
boolean *d_boolean;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_boolean)(nhfp, d_boolean, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_char(nhfp, d_char, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
char *d_char;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_char)(nhfp, d_char, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_genericptr(nhfp, d_genericptr, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
genericptr_t d_genericptr;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_genericptr)(nhfp, d_genericptr, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_int(nhfp, d_int, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
int *d_int;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_int)(nhfp, d_int, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_long(nhfp, d_long, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
long *d_long;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_long)(nhfp, d_long, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_schar(nhfp, d_schar, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
schar *d_schar;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_schar)(nhfp, d_schar, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_short(nhfp, d_short, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
short *d_short;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_short)(nhfp, d_short, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_size_t(nhfp, d_size_t, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
size_t *d_size_t;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_size_t)(nhfp, d_size_t, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_time_t(nhfp, d_time_t, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
time_t *d_time_t;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_time_t)(nhfp, d_time_t, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_unsigned(nhfp, d_unsigned, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned *d_unsigned;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_unsigned)(nhfp, d_unsigned, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_uchar(nhfp, d_uchar, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned char *d_uchar;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_uchar)(nhfp, d_uchar, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_uint(nhfp, d_uint, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned int *d_uint;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_uint)(nhfp, d_uint, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_ulong(nhfp, d_ulong, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned long *d_ulong;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_ulong)(nhfp, d_ulong, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_ushort(nhfp, d_ushort, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned short *d_ushort;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_ushort)(nhfp, d_ushort, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_xchar(nhfp, d_xchar, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
xchar *d_xchar;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_xchar)(nhfp, d_xchar, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_str(nhfp, d_str, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
char *d_str;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_str)(nhfp, d_str, myparent, myname, cnt);
|
||||
}
|
||||
|
||||
void
|
||||
sfo_addinfo(nhfp, parent, action, myname, index)
|
||||
NHFILE *nhfp;
|
||||
const char *parent, *action, *myname;
|
||||
int index;
|
||||
{
|
||||
(*sfoprocs[nhfp->fnidx].fn.sf_addinfo)(nhfp, parent, action, myname, index);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* routines called from core and from functions in generated sfi_data.c
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
sfi_any(nhfp, d_any, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
union any *d_any;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "any";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_any)(nhfp, d_any, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%ld)\n", d_any->a_long);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_aligntyp(nhfp, d_aligntyp, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
aligntyp *d_aligntyp;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "aligntyp";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_aligntyp)(nhfp, d_aligntyp, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%d)\n", *d_aligntyp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_bitfield(nhfp, d_bitfield, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
uint8_t *d_bitfield;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "bitfield";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_bitfield)(nhfp, d_bitfield, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%hd)\n", *d_bitfield);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_boolean(nhfp, d_boolean, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
boolean *d_boolean;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "boolean";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_boolean)(nhfp, d_boolean, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%s)\n", (*d_boolean) ? "true" : "false");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_char(nhfp, d_char, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
char *d_char;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "char";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_char)(nhfp, d_char, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%s)\n", d_char ? d_char : "");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_genericptr(nhfp, d_genericptr, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
genericptr_t d_genericptr;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "genericptr";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_genericptr)(nhfp, d_genericptr, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%s)\n", (d_genericptr) ? "set" : "null");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_int(nhfp, d_int, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
int *d_int;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "int";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_int)(nhfp, d_int, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%d)\n", *d_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_long(nhfp, d_long, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
long *d_long;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "long";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_long)(nhfp, d_long, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%ld)\n", *d_long);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_schar(nhfp, d_schar, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
schar *d_schar;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "schar";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_schar)(nhfp, d_schar, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%hd)\n", (short) *d_schar);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_short(nhfp, d_short, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
short *d_short;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "short";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_short)(nhfp, d_short, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%hd)\n", *d_short);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_size_t(nhfp, d_size_t, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
size_t *d_size_t;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "size_t";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_size_t)(nhfp, d_size_t, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%lu)\n", (unsigned long) *d_size_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_time_t(nhfp, d_time_t, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
time_t *d_time_t;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "time_t";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_time_t)(nhfp, d_time_t, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%s)\n", yyyymmddhhmmss(*d_time_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_unsigned(nhfp, d_unsigned, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned *d_unsigned;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "unsigned";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_unsigned)(nhfp, d_unsigned, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%u)\n", *d_unsigned);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_uchar(nhfp, d_uchar, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned char *d_uchar;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "uchar";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_uchar)(nhfp, d_uchar, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%hu)\n", (unsigned short) *d_uchar);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_uint(nhfp, d_uint, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned int *d_uint;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "uint";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_uint)(nhfp, d_uint, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%u)\n", *d_uint);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_ulong(nhfp, d_ulong, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned long *d_ulong;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "ulong";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_ulong)(nhfp, d_ulong, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%lu)\n", *d_ulong);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_ushort(nhfp, d_ushort, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
unsigned short *d_ushort;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "ushort";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_ushort)(nhfp, d_ushort, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%hu)\n", *d_ushort);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_xchar(nhfp, d_xchar, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
xchar *d_xchar;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "xchar";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_xchar)(nhfp, d_xchar, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(%hd)\n", (short) *d_xchar);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_str(nhfp, d_str, myparent, myname, cnt)
|
||||
NHFILE *nhfp;
|
||||
char *d_str;
|
||||
const char *myparent;
|
||||
const char *myname;
|
||||
int cnt;
|
||||
{
|
||||
const char *parent = "str";
|
||||
|
||||
sfi_log(nhfp, myparent, myname, parent, cnt);
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_str)(nhfp, d_str, myparent, myname, cnt);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
fprintf(nhfp->fpdebug, "(\"%s\")\n", d_str);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sfi_addinfo(nhfp, myparent, action, myname, index)
|
||||
NHFILE *nhfp;
|
||||
const char *myparent, *action, *myname;
|
||||
int index;
|
||||
{
|
||||
if (nhfp) {
|
||||
if (nhfp->fplog)
|
||||
(void) fprintf(nhfp->fplog, "# %s %s %s %d\n", myparent, action, myname, index);
|
||||
#ifdef DO_DEBUG
|
||||
if (nhfp->fpdebug)
|
||||
(void) fprintf(nhfp->fpdebug, "# %s %s %s %d\n", myparent, action, myname, index);
|
||||
#endif
|
||||
}
|
||||
(*sfiprocs[nhfp->fnidx].fn.sf_addinfo)(nhfp, myparent, action, myname, index);
|
||||
}
|
||||
|
||||
void
|
||||
sfi_log(nhfp, t1, t2, t3, cnt)
|
||||
NHFILE *nhfp;
|
||||
const char *t1, *t2, *t3;
|
||||
int cnt;
|
||||
{
|
||||
#ifdef DO_DEBUG
|
||||
#ifdef SAVEFILE_DEBUGGING
|
||||
if (nhfp) {
|
||||
if (nhfp->fplog)
|
||||
(void) fprintf(nhfp->fplog, "%s %s %s cnt=%d\n", t1, t2, t3, cnt);
|
||||
if (nhfp->fpdebug)
|
||||
(void) fprintf(nhfp->fpdebug, "%s %s %s cnt=%d ", t1, t2, t3, cnt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
+5776
File diff suppressed because it is too large
Load Diff
+1313
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -6032,7 +6032,7 @@ const char *name;
|
||||
if (!fd)
|
||||
return FALSE;
|
||||
Fread((genericptr_t) &vers_info, sizeof vers_info, 1, fd);
|
||||
if (!check_version(&vers_info, name, TRUE)) {
|
||||
if (!check_version(&vers_info, name, TRUE, UTD_CHECKSIZES)) {
|
||||
(void) dlb_fclose(fd);
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
+73
-38
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h" /* for checking save modes */
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
STATIC_DCL void NDECL(stoned_dialogue);
|
||||
STATIC_DCL void NDECL(vomiting_dialogue);
|
||||
@@ -1631,13 +1633,13 @@ do_storms()
|
||||
* Call timers that have timed out.
|
||||
*
|
||||
* Save/Restore:
|
||||
* void save_timers(int fd, int mode, int range)
|
||||
* void save_timers(NHFILE *, int range)
|
||||
* Save all timers of range 'range'. Range is either global
|
||||
* or local. Global timers follow game play, local timers
|
||||
* are saved with a level. Object and monster timers are
|
||||
* saved using their respective id's instead of pointers.
|
||||
*
|
||||
* void restore_timers(int fd, int range, boolean ghostly, long adjust)
|
||||
* void restore_timers(NHFILE *, int range, boolean ghostly, long adjust)
|
||||
* Restore timers of range 'range'. If from a ghost pile,
|
||||
* adjust the timeout by 'adjust'. The object and monster
|
||||
* ids are not restored until later.
|
||||
@@ -1665,10 +1667,10 @@ STATIC_DCL void FDECL(print_queue, (winid, timer_element *));
|
||||
STATIC_DCL void FDECL(insert_timer, (timer_element *));
|
||||
STATIC_DCL timer_element *FDECL(remove_timer,
|
||||
(timer_element **, SHORT_P, ANY_P *));
|
||||
STATIC_DCL void FDECL(write_timer, (int, timer_element *));
|
||||
STATIC_DCL void FDECL(write_timer, (NHFILE *, timer_element *));
|
||||
STATIC_DCL boolean FDECL(mon_is_local, (struct monst *));
|
||||
STATIC_DCL boolean FDECL(timer_is_local, (timer_element *));
|
||||
STATIC_DCL int FDECL(maybe_write_timer, (int, int, BOOLEAN_P));
|
||||
STATIC_DCL int FDECL(maybe_write_timer, (NHFILE *, int, BOOLEAN_P));
|
||||
|
||||
/* If defined, then include names when printing out the timer queue */
|
||||
#define VERBOSE_TIMER
|
||||
@@ -2110,8 +2112,8 @@ anything *arg;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
write_timer(fd, timer)
|
||||
int fd;
|
||||
write_timer(nhfp, timer)
|
||||
NHFILE *nhfp;
|
||||
timer_element *timer;
|
||||
{
|
||||
anything arg_save;
|
||||
@@ -2121,34 +2123,49 @@ timer_element *timer;
|
||||
case TIMER_GLOBAL:
|
||||
case TIMER_LEVEL:
|
||||
/* assume no pointers in arg */
|
||||
bwrite(fd, (genericptr_t) timer, sizeof(timer_element));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) timer, sizeof(timer_element));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_fe(nhfp, timer, "timers", "timer", 1);
|
||||
break;
|
||||
|
||||
case TIMER_OBJECT:
|
||||
if (timer->needs_fixup)
|
||||
bwrite(fd, (genericptr_t) timer, sizeof(timer_element));
|
||||
else {
|
||||
if (timer->needs_fixup) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t)timer, sizeof(timer_element));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_fe(nhfp, timer, "timers", "timer", 1);
|
||||
} else {
|
||||
/* replace object pointer with id */
|
||||
arg_save.a_obj = timer->arg.a_obj;
|
||||
timer->arg = cg.zeroany;
|
||||
timer->arg.a_uint = (arg_save.a_obj)->o_id;
|
||||
timer->needs_fixup = 1;
|
||||
bwrite(fd, (genericptr_t) timer, sizeof(timer_element));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t)timer, sizeof(timer_element));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_fe(nhfp, timer, "timers", "timer", 1);
|
||||
timer->arg.a_obj = arg_save.a_obj;
|
||||
timer->needs_fixup = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case TIMER_MONSTER:
|
||||
if (timer->needs_fixup)
|
||||
bwrite(fd, (genericptr_t) timer, sizeof(timer_element));
|
||||
else {
|
||||
if (timer->needs_fixup) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t)timer, sizeof(timer_element));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_fe(nhfp, timer, "timers", "timer", 1);
|
||||
} else {
|
||||
/* replace monster pointer with id */
|
||||
arg_save.a_monst = timer->arg.a_monst;
|
||||
timer->arg = cg.zeroany;
|
||||
timer->arg.a_uint = (arg_save.a_monst)->m_id;
|
||||
timer->needs_fixup = 1;
|
||||
bwrite(fd, (genericptr_t) timer, sizeof(timer_element));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t)timer, sizeof(timer_element));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_fe(nhfp, timer, "timers", "timer", 1);
|
||||
timer->arg.a_monst = arg_save.a_monst;
|
||||
timer->needs_fixup = 0;
|
||||
}
|
||||
@@ -2231,8 +2248,9 @@ timer_element *timer;
|
||||
* be written. If write_it is true, actually write the timer.
|
||||
*/
|
||||
STATIC_OVL int
|
||||
maybe_write_timer(fd, range, write_it)
|
||||
int fd, range;
|
||||
maybe_write_timer(nhfp, range, write_it)
|
||||
NHFILE *nhfp;
|
||||
int range;
|
||||
boolean write_it;
|
||||
{
|
||||
int count = 0;
|
||||
@@ -2244,17 +2262,14 @@ boolean write_it;
|
||||
|
||||
if (!timer_is_local(curr)) {
|
||||
count++;
|
||||
if (write_it)
|
||||
write_timer(fd, curr);
|
||||
if (write_it) write_timer(nhfp, curr);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* local timers */
|
||||
|
||||
if (timer_is_local(curr)) {
|
||||
count++;
|
||||
if (write_it)
|
||||
write_timer(fd, curr);
|
||||
if (write_it) write_timer(nhfp, curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2262,6 +2277,7 @@ boolean write_it;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save part of the timer list. The parameter 'range' specifies either
|
||||
* global or level timers to save. The timer ID is saved with the global
|
||||
@@ -2276,22 +2292,29 @@ boolean write_it;
|
||||
* + timeouts that stay with the level (obj & monst)
|
||||
*/
|
||||
void
|
||||
save_timers(fd, mode, range)
|
||||
int fd, mode, range;
|
||||
save_timers(nhfp, range)
|
||||
NHFILE *nhfp;
|
||||
int range;
|
||||
{
|
||||
timer_element *curr, *prev, *next_timer = 0;
|
||||
int count;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
if (range == RANGE_GLOBAL)
|
||||
bwrite(fd, (genericptr_t) &g.timer_id, sizeof(g.timer_id));
|
||||
|
||||
count = maybe_write_timer(fd, range, FALSE);
|
||||
bwrite(fd, (genericptr_t) &count, sizeof count);
|
||||
(void) maybe_write_timer(fd, range, TRUE);
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (range == RANGE_GLOBAL) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &g.timer_id, sizeof(g.timer_id));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_ulong(nhfp, &g.timer_id, "timers", "g.timer_id", 1);
|
||||
}
|
||||
count = maybe_write_timer(nhfp, range, FALSE);
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &count, sizeof count);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &count, "timers", "timer_count", 1);
|
||||
(void) maybe_write_timer(nhfp, range, TRUE);
|
||||
}
|
||||
|
||||
if (release_data(mode)) {
|
||||
if (release_data(nhfp)) {
|
||||
for (prev = 0, curr = g.timer_base; curr; curr = next_timer) {
|
||||
next_timer = curr->next; /* in case curr is removed */
|
||||
|
||||
@@ -2314,22 +2337,34 @@ int fd, mode, range;
|
||||
* monster pointers.
|
||||
*/
|
||||
void
|
||||
restore_timers(fd, range, ghostly, adjust)
|
||||
int fd, range;
|
||||
restore_timers(nhfp, range, ghostly, adjust)
|
||||
NHFILE *nhfp;
|
||||
int range;
|
||||
boolean ghostly; /* restoring from a ghost level */
|
||||
long adjust; /* how much to adjust timeout */
|
||||
{
|
||||
int count;
|
||||
timer_element *curr;
|
||||
|
||||
if (range == RANGE_GLOBAL)
|
||||
mread(fd, (genericptr_t) &g.timer_id, sizeof g.timer_id);
|
||||
if (range == RANGE_GLOBAL) {
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &g.timer_id, sizeof g.timer_id);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_ulong(nhfp, &g.timer_id, "timers", "g.timer_id", 1);
|
||||
}
|
||||
|
||||
/* restore elements */
|
||||
mread(fd, (genericptr_t) &count, sizeof count);
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &count, sizeof count);
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &count, "timers", "timer_count", 1);
|
||||
|
||||
while (count-- > 0) {
|
||||
curr = (timer_element *) alloc(sizeof(timer_element));
|
||||
mread(fd, (genericptr_t) curr, sizeof(timer_element));
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) curr, sizeof(timer_element));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_fe(nhfp, curr, "timers", "timer", 1);
|
||||
if (ghostly)
|
||||
curr->timeout += adjust;
|
||||
insert_timer(curr);
|
||||
|
||||
+60
-23
@@ -6,6 +6,10 @@
|
||||
#include "hack.h"
|
||||
#include "dlb.h"
|
||||
#include "date.h"
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/*
|
||||
* All the references to the contents of patchlevel.h have been moved
|
||||
* into makedefs....
|
||||
@@ -250,10 +254,11 @@ long filetime;
|
||||
#endif
|
||||
|
||||
boolean
|
||||
check_version(version_data, filename, complain)
|
||||
check_version(version_data, filename, complain, utdflags)
|
||||
struct version_info *version_data;
|
||||
const char *filename;
|
||||
boolean complain;
|
||||
unsigned long utdflags;
|
||||
{
|
||||
if (
|
||||
#ifdef VERSION_COMPATIBILITY
|
||||
@@ -273,9 +278,12 @@ boolean complain;
|
||||
(version_data->feature_set & ~IGNORED_FEATURES)
|
||||
!= (VERSION_FEATURES & ~IGNORED_FEATURES)
|
||||
#endif
|
||||
|| version_data->entity_count != VERSION_SANITY1
|
||||
|| version_data->struct_sizes1 != VERSION_SANITY2
|
||||
|| version_data->struct_sizes2 != VERSION_SANITY3) {
|
||||
|| ((utdflags & UTD_SKIP_SANITY1) == 0
|
||||
&& version_data->entity_count != VERSION_SANITY1)
|
||||
|| ((utdflags & UTD_CHECKSIZES) &&
|
||||
(version_data->struct_sizes1 != VERSION_SANITY2))
|
||||
|| ((utdflags & UTD_CHECKSIZES) &&
|
||||
(version_data->struct_sizes2 != VERSION_SANITY3))) {
|
||||
if (complain)
|
||||
pline("Configuration incompatibility for file \"%s\".", filename);
|
||||
return FALSE;
|
||||
@@ -286,24 +294,47 @@ boolean complain;
|
||||
/* this used to be based on file date and somewhat OS-dependant,
|
||||
but now examines the initial part of the file's contents */
|
||||
boolean
|
||||
uptodate(fd, name)
|
||||
int fd;
|
||||
uptodate(nhfp, name, utdflags)
|
||||
NHFILE *nhfp;
|
||||
const char *name;
|
||||
unsigned long utdflags;
|
||||
{
|
||||
int rlen;
|
||||
int rlen, cmc = 0, filecmc = 0;
|
||||
struct version_info vers_info;
|
||||
boolean verbose = name ? TRUE : FALSE;
|
||||
char indicator;
|
||||
|
||||
rlen = read(fd, (genericptr_t) &vers_info, sizeof vers_info);
|
||||
minit(); /* ZEROCOMP */
|
||||
if (rlen == 0) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" is empty?", name);
|
||||
wait_synch();
|
||||
}
|
||||
return FALSE;
|
||||
if (nhfp->structlevel) {
|
||||
rlen = read(nhfp->fd, (genericptr_t) &indicator, sizeof indicator);
|
||||
rlen = read(nhfp->fd, (genericptr_t) &filecmc, sizeof filecmc);
|
||||
if (rlen == 0)
|
||||
return FALSE;
|
||||
}
|
||||
if (!check_version(&vers_info, name, verbose)) {
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_char(nhfp, &indicator, "indicate", "format", 1);
|
||||
sfi_int(nhfp, &filecmc, "validate", "critical_members_count", 1);
|
||||
cmc = critical_members_count();
|
||||
}
|
||||
if (cmc != filecmc)
|
||||
return FALSE;
|
||||
|
||||
if (nhfp->fieldlevel && (nhfp->fnidx > historical)) {
|
||||
sfi_version_info(nhfp, &vers_info, "version", "version_info", 1);
|
||||
} else {
|
||||
int rlen;
|
||||
|
||||
rlen = read(nhfp->fd, (genericptr_t) &vers_info, sizeof vers_info);
|
||||
minit(); /* ZEROCOMP */
|
||||
if (rlen == 0) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" is empty?", name);
|
||||
wait_synch();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_version(&vers_info, name, verbose, utdflags)) {
|
||||
if (verbose)
|
||||
wait_synch();
|
||||
return FALSE;
|
||||
@@ -312,19 +343,25 @@ const char *name;
|
||||
}
|
||||
|
||||
void
|
||||
store_version(fd)
|
||||
int fd;
|
||||
store_version(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
static const struct version_info version_data = {
|
||||
VERSION_NUMBER, VERSION_FEATURES,
|
||||
VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3
|
||||
};
|
||||
|
||||
bufoff(fd);
|
||||
/* bwrite() before bufon() uses plain write() */
|
||||
bwrite(fd, (genericptr_t) &version_data,
|
||||
(unsigned) (sizeof version_data));
|
||||
bufon(fd);
|
||||
if (nhfp->structlevel) {
|
||||
bufoff(nhfp->fd);
|
||||
/* bwrite() before bufon() uses plain write() */
|
||||
bwrite(nhfp->fd,(genericptr_t) &version_data,
|
||||
(unsigned) (sizeof version_data));
|
||||
bufon(nhfp->fd);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_version_info(nhfp, (struct version_info *) &version_data,
|
||||
"version", "version_info", 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+48
-16
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
#define newseg() (struct wseg *) alloc(sizeof (struct wseg))
|
||||
#define dealloc_seg(wseg) free((genericptr_t) (wseg))
|
||||
@@ -477,31 +479,46 @@ boolean use_detection_glyph;
|
||||
* of segments, including the dummy. Called from save.c.
|
||||
*/
|
||||
void
|
||||
save_worm(fd, mode)
|
||||
int fd, mode;
|
||||
save_worm(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
struct wseg *curr, *temp;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
if (perform_bwrite(nhfp)) {
|
||||
for (i = 1; i < MAX_NUM_WORMS; i++) {
|
||||
for (count = 0, curr = wtails[i]; curr; curr = curr->nseg)
|
||||
count++;
|
||||
/* Save number of segments */
|
||||
bwrite(fd, (genericptr_t) &count, sizeof(int));
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &count, sizeof(int));
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &count, "worm", "segment_count", 1);
|
||||
/* Save segment locations of the monster. */
|
||||
if (count) {
|
||||
for (curr = wtails[i]; curr; curr = curr->nseg) {
|
||||
bwrite(fd, (genericptr_t) & (curr->wx), sizeof(xchar));
|
||||
bwrite(fd, (genericptr_t) & (curr->wy), sizeof(xchar));
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) &(curr->wx), sizeof(xchar));
|
||||
bwrite(nhfp->fd, (genericptr_t) &(curr->wy), sizeof(xchar));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfo_xchar(nhfp, &(curr->wx), "worm", "wx", 1);
|
||||
sfo_xchar(nhfp, &(curr->wy), "worm", "wy", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bwrite(fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
|
||||
if (nhfp->structlevel) {
|
||||
bwrite(nhfp->fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < MAX_NUM_WORMS; ++i)
|
||||
sfo_long(nhfp, &wgrowtime[i], "worm", "wgrowtime", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (release_data(mode)) {
|
||||
if (release_data(nhfp)) {
|
||||
/* Free the segments only. savemonchn() will take care of the
|
||||
* monsters. */
|
||||
for (i = 1; i < MAX_NUM_WORMS; i++) {
|
||||
@@ -518,29 +535,38 @@ int fd, mode;
|
||||
}
|
||||
}
|
||||
|
||||
/* SAVE2018 */
|
||||
|
||||
/*
|
||||
* rest_worm()
|
||||
*
|
||||
* Restore the worm information from the save file. Called from restore.c
|
||||
*/
|
||||
void
|
||||
rest_worm(fd)
|
||||
int fd;
|
||||
rest_worm(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
int i, j, count;
|
||||
struct wseg *curr, *temp;
|
||||
|
||||
for (i = 1; i < MAX_NUM_WORMS; i++) {
|
||||
mread(fd, (genericptr_t) &count, sizeof(int));
|
||||
if (!count)
|
||||
continue; /* none */
|
||||
if (nhfp->structlevel)
|
||||
mread(nhfp->fd, (genericptr_t) &count, sizeof(int));
|
||||
if (nhfp->fieldlevel)
|
||||
sfi_int(nhfp, &count, "worm", "segment_count", 1);
|
||||
|
||||
/* Get the segments. */
|
||||
for (curr = (struct wseg *) 0, j = 0; j < count; j++) {
|
||||
temp = newseg();
|
||||
temp->nseg = (struct wseg *) 0;
|
||||
mread(fd, (genericptr_t) & (temp->wx), sizeof(xchar));
|
||||
mread(fd, (genericptr_t) & (temp->wy), sizeof(xchar));
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) &(temp->wx), sizeof(xchar));
|
||||
mread(nhfp->fd, (genericptr_t) &(temp->wy), sizeof(xchar));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
sfi_xchar(nhfp, &(temp->wx), "worm", "wx", 1);
|
||||
sfi_xchar(nhfp, &(temp->wy), "worm", "wy", 1);
|
||||
}
|
||||
if (curr)
|
||||
curr->nseg = temp;
|
||||
else
|
||||
@@ -549,7 +575,13 @@ int fd;
|
||||
}
|
||||
wheads[i] = curr;
|
||||
}
|
||||
mread(fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
for (i = 0; i < MAX_NUM_WORMS; ++i)
|
||||
sfi_long(nhfp, &wgrowtime[i], "worm", "wgrowtime", 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user