diff --git a/include/display.h b/include/display.h index 7b7559726..94d54f749 100644 --- a/include/display.h +++ b/include/display.h @@ -317,7 +317,7 @@ /* The hero's glyph when seen as a monster. */ #define hero_glyph \ - monnum_to_glyph((Upolyd || !iflags.showrace) ? u.umonnum : \ + monnum_to_glyph((Upolyd || !Xflags.showrace) ? u.umonnum : \ (flags.female && urace.femalenum != NON_PM) ? urace.femalenum : \ urace.malenum) diff --git a/include/flag.h b/include/flag.h index 5f32398e8..8a12d22c2 100644 --- a/include/flag.h +++ b/include/flag.h @@ -15,6 +15,13 @@ */ struct flag { +#ifdef SAVEFILE_340_CONVERT + int version; /* flag structure version */ + boolean lootabc; /* use "a/b/c" rather than "o/i/b" when looting */ + boolean showrace; /* show hero glyph by race rather than by role */ + boolean travelcmd; /* allow travel command */ + int runmode; /* update screen display during run moves */ +#endif #ifdef AMIFLUSH boolean altmeta; /* use ALT keys as META */ boolean amiflush; /* kill typeahead */ @@ -254,11 +261,13 @@ struct instance_flags { boolean wc_eight_bit_input; /* allow eight bit input */ boolean wc_mouse_support; /* allow mouse support */ +#ifndef SAVEFILE_340_CONVERT /* Items which belong in flags, but are here to allow save compatibility */ boolean lootabc; /* use "a/b/c" rather than "o/i/b" when looting */ boolean showrace; /* show hero glyph by race rather than by role */ boolean travelcmd; /* allow travel command */ int runmode; /* update screen display during run moves */ +#endif }; /* @@ -289,4 +298,111 @@ extern NEARDATA struct instance_flags iflags; #define RUN_STEP 2 /* update display every single step */ #define RUN_CRAWL 3 /* walk w/ extra delay after each update */ +#ifndef SAVEFILE_340_CONVERT +# define Xflags iflags +#else +# define Xflags flags +/* This is identical to 3.4.0 flag structure */ +struct flag340 { +#ifdef AMIFLUSH + boolean altmeta; /* use ALT keys as META */ + boolean amiflush; /* kill typeahead */ +#endif +#ifdef MFLOPPY + boolean asksavedisk; +#endif + boolean autodig; /* MRKR: Automatically dig */ + boolean autoquiver; /* Automatically fill quiver */ + boolean beginner; +#ifdef MAIL + boolean biff; /* enable checking for mail */ +#endif + boolean botl; /* partially redo status line */ + boolean botlx; /* print an entirely new bottom line */ + boolean confirm; /* confirm before hitting tame monsters */ + boolean debug; /* in debugging mode */ + boolean end_own; /* list all own scores */ + boolean explore; /* in exploration mode */ +#ifdef OPT_DISPMAP + boolean fast_map; /* use optimized, less flexible map display */ +#endif +#define discover flags.explore + boolean female; + boolean forcefight; + boolean friday13; /* it's Friday the 13th */ + boolean help; /* look in data file for info about stuff */ + boolean ignintr; /* ignore interrupts */ +#ifdef INSURANCE + boolean ins_chkpt; /* checkpoint as appropriate */ +#endif + boolean invlet_constant; /* let objects keep their inventory symbol */ + boolean legacy; /* print game entry "story" */ + boolean lit_corridor; /* show a dark corr as lit if it is in sight */ + boolean made_amulet; + boolean mon_moving; /* monsters' turn to move */ + boolean move; + boolean mv; + boolean bypasses; /* bypass flag is set on at least one fobj */ + boolean nap; /* `timed_delay' option for display effects */ + boolean nopick; /* do not pickup objects (as when running) */ + boolean null; /* OK to send nulls to the terminal */ +#ifdef MAC + boolean page_wait; /* put up a --More-- after a page of messages */ +#endif + boolean perm_invent; /* keep full inventories up until dismissed */ + boolean pickup; /* whether you pickup or move and look */ + + boolean pushweapon; /* When wielding, push old weapon into second slot */ + boolean rest_on_space; /* space means rest */ + boolean safe_dog; /* give complete protection to the dog */ +#ifdef EXP_ON_BOTL + boolean showexp; /* show experience points */ +#endif +#ifdef SCORE_ON_BOTL + boolean showscore; /* show score */ +#endif + boolean silent; /* whether the bell rings or not */ + boolean sortpack; /* sorted inventory */ + boolean soundok; /* ok to tell about sounds heard */ + boolean sparkle; /* show "resisting" special FX (Scott Bigham) */ + boolean standout; /* use standout for --More-- */ + boolean time; /* display elapsed 'time' */ + boolean tombstone; /* print tombstone */ + boolean toptenwin; /* ending list in window instead of stdout */ + boolean verbose; /* max battle info */ + boolean prayconfirm; /* confirm before praying */ + int end_top, end_around; /* describe desired score list */ + unsigned ident; /* social security number for each monster */ + unsigned moonphase; + unsigned long suppress_alert; + + + unsigned no_of_wizards; /* 0, 1 or 2 (wizard and his shadow) */ + boolean travel; /* find way automatically to u.tx,u.ty */ + unsigned run; /* 0: h (etc), 1: H (etc), 2: fh (etc) */ + /* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */ + /* 8: travel */ + unsigned long warntype; /* warn_of_mon monster type M2 */ + int warnlevel; + int djinni_count, ghost_count; /* potion effect tuning */ + int pickup_burden; /* maximum burden before prompt */ + char inv_order[MAXOCLASSES]; + char pickup_types[MAXOCLASSES]; + char end_disclose[NUM_DISCLOSURE_OPTIONS + 1]; /* disclose various info + upon exit */ + char menu_style; /* User interface style setting */ +#ifdef AMII_GRAPHICS + int numcols; + unsigned short amii_dripens[ 20 ]; /* DrawInfo Pens currently there are 13 in v39 */ + AMII_COLOR_TYPE amii_curmap[ AMII_MAXCOLORS ]; /* colormap */ +#endif + int initrole; /* starting role (index into roles[]) */ + int initrace; /* starting race (index into races[]) */ + int initgend; /* starting gender (index into genders[]) */ + int initalign; /* starting alignment (index into aligns[]) */ + int randomall; /* randomly assign everything not specified */ + int pantheon; /* deity selection for priest character */ +}; +#endif /*SAVEFILE_340_CONVERT */ + #endif /* FLAG_H */ diff --git a/include/ntconf.h b/include/ntconf.h index a4cecf427..0b034ca3d 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -19,6 +19,8 @@ #define PC_LOCKING /* Prevent overwrites of aborted or in-progress games */ /* without first receiving confirmation. */ +#define SAVEFILE_340_CONVERT /* allow moving of some iflags fields to flags + without destroying savefile compatibility */ /* * ----------------------------------------------------------------- diff --git a/src/allmain.c b/src/allmain.c index 65ee608ef..ea01af272 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -409,7 +409,7 @@ moveloop() if (vision_full_recalc) vision_recalc(0); /* vision! */ /* when running in non-tport mode, this gets done through domove() */ - if ((!flags.run || iflags.runmode == RUN_TPORT) && + if ((!flags.run || Xflags.runmode == RUN_TPORT) && (multi && (!flags.travel ? !(multi % 7) : !(moves % 7L)))) { if (flags.time && flags.run) flags.botl = 1; display_nhwindow(WIN_MAP, FALSE); diff --git a/src/cmd.c b/src/cmd.c index 65984ea33..50496fd17 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1753,7 +1753,7 @@ register char *cmd; multi = 0; return; case CMD_TRAVEL: - if (iflags.travelcmd) { + if (Xflags.travelcmd) { flags.travel = 1; flags.run = 8; flags.nopick = 1; @@ -1954,7 +1954,7 @@ click_to_cmd(x, y, mod) x -= u.ux; y -= u.uy; - if (iflags.travelcmd) { + if (Xflags.travelcmd) { if (abs(x) <= 1 && abs(y) <= 1 ) { x = sgn(x), y = sgn(y); } else { @@ -2180,7 +2180,7 @@ dotravel() static char cmd[2]; coord cc; - if (!iflags.travelcmd) return 0; + if (!Xflags.travelcmd) return 0; cmd[1]=0; cc.x = u.ux; cc.y = u.uy; diff --git a/src/hack.c b/src/hack.c index fc74aa9e2..b9b956ce3 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1368,13 +1368,13 @@ domove() nomovemsg = ""; } - if (flags.run && iflags.runmode != RUN_TPORT) { + if (flags.run && Xflags.runmode != RUN_TPORT) { /* display every step or every 7th step depending upon mode */ - if (iflags.runmode != RUN_LEAP || !(moves % 7L)) { + if (Xflags.runmode != RUN_LEAP || !(moves % 7L)) { if (flags.time) flags.botl = 1; curs_on_u(); delay_output(); - if (iflags.runmode == RUN_CRAWL) { + if (Xflags.runmode == RUN_CRAWL) { delay_output(); delay_output(); delay_output(); diff --git a/src/mapglyph.c b/src/mapglyph.c index f9710f9b2..18aabf469 100644 --- a/src/mapglyph.c +++ b/src/mapglyph.c @@ -200,7 +200,7 @@ unsigned *ospecial; /* special case the hero for `showrace' option */ #ifdef TEXTCOLOR if (iflags.use_color && x == u.ux && y == u.uy && - iflags.showrace && !Upolyd) + Xflags.showrace && !Upolyd) color = HI_DOMESTIC; #endif } diff --git a/src/options.c b/src/options.c index 6506de7d8..f8d3f89da 100644 --- a/src/options.c +++ b/src/options.c @@ -106,7 +106,7 @@ static struct Bool_Opt {"large_font", &iflags.wc_large_font, FALSE, SET_IN_FILE}, /*WC*/ {"legacy", &flags.legacy, TRUE, DISP_IN_GAME}, {"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME}, - {"lootabc", &iflags.lootabc, FALSE, SET_IN_GAME}, + {"lootabc", &Xflags.lootabc, FALSE, SET_IN_GAME}, #ifdef MAC_GRAPHICS_ENV {"Macgraphics", &iflags.MACgraphics, TRUE, SET_IN_GAME}, #else @@ -158,7 +158,7 @@ static struct Bool_Opt #else {"showexp", (boolean *)0, FALSE, SET_IN_FILE}, #endif - {"showrace", &iflags.showrace, FALSE, SET_IN_GAME}, + {"showrace", &Xflags.showrace, FALSE, SET_IN_GAME}, #ifdef SCORE_ON_BOTL {"showscore", &flags.showscore, FALSE, SET_IN_GAME}, #else @@ -179,7 +179,7 @@ static struct Bool_Opt #endif {"tombstone",&flags.tombstone, TRUE, SET_IN_GAME}, {"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME}, - {"travel", &iflags.travelcmd, TRUE, SET_IN_GAME}, + {"travel", &Xflags.travelcmd, TRUE, SET_IN_GAME}, {"use_inverse", &iflags.wc_inverse, FALSE, SET_IN_GAME}, /*WC*/ {"verbose", &flags.verbose, TRUE, SET_IN_GAME}, {(char *)0, (boolean *)0, FALSE, 0} @@ -474,10 +474,13 @@ initoptions() if (boolopt[i].addr) *(boolopt[i].addr) = boolopt[i].initvalue; } +#ifdef SAVEFILE_340_CONVERT + flags.version = 341; +#endif flags.end_own = FALSE; flags.end_top = 3; flags.end_around = 2; - iflags.runmode = RUN_LEAP; + Xflags.runmode = RUN_LEAP; iflags.msg_history = 20; #ifdef TTY_GRAPHICS iflags.prevmsg_window = 's'; @@ -1056,16 +1059,16 @@ boolean tinitial, tfrom_file; fullname = "runmode"; if (match_optname(opts, fullname, 4, TRUE)) { if (negated) { - iflags.runmode = RUN_TPORT; + Xflags.runmode = RUN_TPORT; } else if ((op = string_for_opt(opts, FALSE)) != 0) { if (!strncmpi(op, "teleport", strlen(op))) - iflags.runmode = RUN_TPORT; + Xflags.runmode = RUN_TPORT; else if (!strncmpi(op, "run", strlen(op))) - iflags.runmode = RUN_LEAP; + Xflags.runmode = RUN_LEAP; else if (!strncmpi(op, "walk", strlen(op))) - iflags.runmode = RUN_STEP; + Xflags.runmode = RUN_STEP; else if (!strncmpi(op, "crawl", strlen(op))) - iflags.runmode = RUN_CRAWL; + Xflags.runmode = RUN_CRAWL; else badoption(opts); } @@ -2099,7 +2102,7 @@ goodfruit: vision_full_recalc = 1; /* delayed recalc */ } else if ((boolopt[i].addr) == &iflags.use_inverse || - (boolopt[i].addr) == &iflags.showrace || + (boolopt[i].addr) == &Xflags.showrace || (boolopt[i].addr) == &iflags.hilite_pet) { need_redraw = TRUE; } @@ -2514,7 +2517,7 @@ boolean setinitial,setfromfile; } end_menu(tmpwin, "Select run/travel display mode:"); if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) { - iflags.runmode = mode_pick->item.a_int - 1; + Xflags.runmode = mode_pick->item.a_int - 1; free((genericptr_t)mode_pick); } destroy_nhwindow(tmpwin); @@ -2716,7 +2719,7 @@ char *buf; else if (!strcmp(optname, "role")) Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m)); else if (!strcmp(optname, "runmode")) - Sprintf(buf, "%s", runmodes[iflags.runmode]); + Sprintf(buf, "%s", runmodes[Xflags.runmode]); else if (!strcmp(optname, "scores")) { Sprintf(buf, "%d top/%d around%s", flags.end_top, flags.end_around, flags.end_own ? "/own" : ""); diff --git a/src/pager.c b/src/pager.c index 75d9be982..411103c13 100644 --- a/src/pager.c +++ b/src/pager.c @@ -551,7 +551,7 @@ do_look(quick) symbol; firstmatch is assumed to already be set for '@' */ if ((from_screen ? (sym == monsyms[S_HUMAN] && cc.x == u.ux && cc.y == u.uy) : - (sym == def_monsyms[S_HUMAN] && !iflags.showrace)) && + (sym == def_monsyms[S_HUMAN] && !Xflags.showrace)) && !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd) found += append_str(out_str, "you"); /* tack on "or you" */ diff --git a/src/pickup.c b/src/pickup.c index 3225a5d99..b10edbf20 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -2210,7 +2210,7 @@ struct obj *obj; menu_item *pick_list; char buf[BUFSZ]; int n; - char *menuselector = iflags.lootabc ? "abc" : "oib"; + char *menuselector = Xflags.lootabc ? "abc" : "oib"; any.a_void = 0; win = create_nhwindow(NHW_MENU); diff --git a/src/restore.c b/src/restore.c index 899b5a69d..8903de61a 100644 --- a/src/restore.c +++ b/src/restore.c @@ -30,6 +30,12 @@ STATIC_DCL boolean FDECL(restgamestate, (int, unsigned int *, unsigned int *)); STATIC_DCL void FDECL(restlevelstate, (unsigned int, unsigned int)); STATIC_DCL int FDECL(restlevelfile, (int,XCHAR_P)); STATIC_DCL void FDECL(reset_oattached_mids, (BOOLEAN_P)); +#ifdef SAVEFILE_340_CONVERT +STATIC_DCL void FDECL(mread_set_checkpoint, (int)); +STATIC_DCL void FDECL(mread_seek_to_checkpoint, (int)); +STATIC_DCL void FDECL(mread_clear_checkpoint, (int)); +STATIC_DCL void FDECL(convertflags, (genericptr_t, struct flag *)); +#endif /* * Save a mapping of IDs from ghost levels to the current level. This @@ -371,7 +377,22 @@ unsigned int *stuckid, *steedid; /* STEED */ return FALSE; } +#ifndef SAVEFILE_340_CONVERT + mread(fd, (genericptr_t) &flags, sizeof(struct flag)); +#else + mread_set_checkpoint(fd); mread(fd, (genericptr_t) &flags, sizeof(struct flag)); + if (flags.version != 341) { + struct flag340 oldflags; + /* We need to try again and convert it */ + mread_seek_to_checkpoint(fd); + mread(fd, (genericptr_t) &oldflags, sizeof(struct flag340)); + convertflags((genericptr_t)&oldflags, &flags); + pline("Converted older savefile flags to new format."); + } + mread_clear_checkpoint(fd); +#endif + flags.bypasses = 0; /* never use the saved value of bypasses */ if (remember_discover) discover = remember_discover; @@ -1077,4 +1098,183 @@ register unsigned int len; } #endif /* ZEROCOMP */ +#ifdef SAVEFILE_340_CONVERT +struct mread_checkpoint_data { + int mreadfd; + long mreadloc; /* from tell() */ +# ifdef ZEROCOMP + unsigned char inbuf[ZEROCOMP_BUFSIZ]; + unsigned short inbufp; + unsigned short inbufsz; + short inrunlength; +# endif +}; +static NEARDATA struct mread_checkpoint_data mrcheckpoint; + +static void +mread_set_checkpoint(fd) +int fd; +{ + mrcheckpoint.mreadfd = fd; + mrcheckpoint.mreadloc = tell(fd); +# ifdef ZEROCOMP + memcpy(mrcheckpoint.inbuf, inbuf, ZEROCOMP_BUFSIZ); + mrcheckpoint.inbufp = inbufp; + mrcheckpoint.inbufsz = inbufsz; + mrcheckpoint.inrunlength = inrunlength; +# endif +}; + +static void +mread_seek_to_checkpoint(fd) +{ + long floc; + if (mrcheckpoint.mreadfd != fd) + panic("mread_seek_to_checkpoint: bad mrcheckpoint.mreadfd %d", fd); + floc = lseek(fd, mrcheckpoint.mreadloc, SEEK_SET); +#ifdef ZEROCOMP + memcpy(inbuf, mrcheckpoint.inbuf, ZEROCOMP_BUFSIZ); + inbufp = mrcheckpoint.inbufp; + inbufsz = mrcheckpoint.inbufsz; + inrunlength = mrcheckpoint.inrunlength; +#endif +} + +static void +mread_clear_checkpoint(fd) +int fd; +{ + if (mrcheckpoint.mreadfd != fd) + panic("mread_clear_checkpoint: bad mrcheckpoint.mreadfd %d", fd); + mrcheckpoint.mreadfd = 0; + mrcheckpoint.mreadloc = 0L; +# ifdef ZEROCOMP + /* memset((genericptr_t)mrcheckpoint.inbuf, 0, ZEROCOMP_BUFSIZ); */ + mrcheckpoint.inbufsz = 0; + mrcheckpoint.inbufp = 0; + mrcheckpoint.inrunlength = -1; +# endif +} + +void +convertflags(oldflagptr, newflags) +genericptr_t oldflagptr; +struct flag *newflags; +{ + int k; + struct flag340 *oldflags = (struct flag340 *)oldflagptr; + + /* set default values for these; they didn't exist in savefile*/ + newflags->version = 341; + newflags->lootabc = FALSE; + newflags->showrace = FALSE; + newflags->travelcmd = TRUE; + newflags->runmode = RUN_LEAP; + + /* convert these */ +#ifdef AMIFLUSH + newflags->altmeta = oldflags->altmeta; + newflags->amiflush = oldflags->amiflush; +#endif +#ifdef MFLOPPY + newflags->asksavedisk = oldflags->asksavedisk; +#endif + newflags->autodig = oldflags->autodig; + newflags->autoquiver = oldflags->autoquiver; + newflags->beginner = oldflags->beginner; +#ifdef MAIL + newflags->biff = oldflags->biff; +#endif + newflags->botl = oldflags->botl; + newflags->botlx = oldflags->botlx; + newflags->confirm = oldflags->confirm; + newflags->debug = oldflags->debug; + newflags->end_own = oldflags->end_own; + newflags->explore = oldflags->explore; +#ifdef OPT_DISPMAP + newflags->fast_map = oldflags->fast_map; +#endif +#define discover flags.explore + newflags->female = oldflags->female; + newflags->forcefight = oldflags->forcefight; + newflags->friday13 = oldflags->friday13; + newflags->help = oldflags->help; + newflags->ignintr = oldflags->ignintr; +#ifdef INSURANCE + newflags->ins_chkpt = oldflags->ins_chkpt; +#endif + newflags->invlet_constant = oldflags->invlet_constant; + newflags->invlet_constant = oldflags->invlet_constant; + newflags->legacy = oldflags->legacy; + newflags->lit_corridor = oldflags->lit_corridor; + newflags->made_amulet = oldflags->made_amulet; + newflags->mon_moving = oldflags->mon_moving; + newflags->move = oldflags->move; + newflags->mv = oldflags->mv; + newflags->bypasses = oldflags->bypasses; + newflags->nap = oldflags->nap; + newflags->nopick = oldflags->nopick; + newflags->null = oldflags->null; +#ifdef MAC + newflags->page_wait = oldflags->page_wait; +#endif + newflags->perm_invent = oldflags->perm_invent; + newflags->pickup = oldflags->pickup; + newflags->pushweapon = oldflags->pushweapon; + newflags->rest_on_space = oldflags->rest_on_space; + newflags->safe_dog = oldflags->safe_dog; +#ifdef EXP_ON_BOTL + newflags->showexp = oldflags->showexp; +#endif +#ifdef SCORE_ON_BOTL + newflags->showscore = oldflags->showscore; +#endif + newflags->silent = oldflags->silent; + newflags->sortpack = oldflags->sortpack; + newflags->soundok = oldflags->soundok; + newflags->sparkle = oldflags->sparkle; + newflags->standout = oldflags->standout; + newflags->time = oldflags->time; + newflags->tombstone = oldflags->tombstone; + newflags->toptenwin = oldflags->toptenwin; + newflags->verbose = oldflags->verbose; + newflags->prayconfirm = oldflags->prayconfirm; + newflags->end_top = oldflags->end_top; + newflags->end_around = oldflags->end_around; + newflags->ident = oldflags->ident; + newflags->moonphase = oldflags->moonphase; + newflags->suppress_alert = oldflags->suppress_alert; + newflags->no_of_wizards = oldflags->no_of_wizards; + newflags->travel = oldflags->travel; + newflags->run = oldflags->run; + newflags->warntype = oldflags->warntype; + newflags->warnlevel = oldflags->warnlevel; + newflags->djinni_count = oldflags->djinni_count; + newflags->ghost_count = oldflags->ghost_count; + newflags->pickup_burden = oldflags->pickup_burden; + for (k = 0; k < MAXOCLASSES; ++k) { + newflags->inv_order[k] = oldflags->inv_order[k]; + newflags->pickup_types[k] = oldflags->pickup_types[k]; + } + for (k = 0; k < NUM_DISCLOSURE_OPTIONS + 1; ++k) { + newflags->end_disclose[k] = oldflags->end_disclose[k]; + } + newflags->menu_style = oldflags->menu_style; +#ifdef AMII_GRAPHICS + newflags->numcols = oldflags->numcols; + for (k = 0; k < 20; ++k) { + newflags->amii_dripens[k] = oldflags->amii_dripens[k]; + } + for (k = 0; k < AMII_MAXCOLORS; ++k) { + newflags->amii_curmap[k] = oldflags->amii_curmap[k]; + } +#endif + newflags->initrole = oldflags->initrole; + newflags->initrace = oldflags->initrace; + newflags->initgend = oldflags->initgend; + newflags->initalign = oldflags->initalign; + newflags->randomall = oldflags->randomall; + newflags->pantheon = oldflags->pantheon; +} +#endif /*restore.c*/ diff --git a/src/version.c b/src/version.c index 02f577ec7..4de6e87a0 100644 --- a/src/version.c +++ b/src/version.c @@ -53,6 +53,15 @@ struct version_info *version_data; const char *filename; boolean complain; { +#ifdef SAVEFILE_340_CONVERT + unsigned long old_struct_sizes, vsanity2; + vsanity2 = VERSION_SANITY2; + old_struct_sizes = (((unsigned long)sizeof (struct flag340) << 24) | + ((unsigned long)sizeof (struct obj) << 17) | + ((unsigned long)sizeof (struct monst) << 10) | + ((unsigned long)sizeof (struct you))); +#endif + if ( #ifdef VERSION_COMPATIBILITY version_data->incarnation < VERSION_COMPATIBILITY || @@ -67,6 +76,13 @@ boolean complain; } else if (version_data->feature_set != VERSION_FEATURES || version_data->entity_count != VERSION_SANITY1 || version_data->struct_sizes != VERSION_SANITY2) { +#ifdef SAVEFILE_340_CONVERT + /* Check for older, convertible structure size compatibility */ + if (version_data->feature_set == VERSION_FEATURES && + version_data->entity_count == VERSION_SANITY1 && + version_data->struct_sizes == old_struct_sizes) + return TRUE; +#endif if (complain) pline("Configuration incompatibility for file \"%s\".", filename);