-+-+-+-+-+-+-+-+ START OF PART 57 -+-+-+-+-+-+-+-+ X /* VMS files have version numbers, so don't worry about overwriting X the old save file. */ X#if !defined(ATARIST_MWC) && !defined(VMS) X fd = -1; X fileptr = NULL;`09`09/* Do not assume it has been init'ed */ X#if defined(MAC) `7C`7C defined(AMIGA) X /* The Mac version automatically overwrites */ X fd = open(fnam, O_RDWR`7CO_CREAT`7CO_TRUNC); X#ifdef MAC X macbeginwait (); X#endif X#else X fd = open(fnam, O_RDWR`7CO_CREAT`7CO_EXCL, 0600); X if (fd < 0 && access(fnam, 0) >= 0 && X (from_savefile `7C`7C X (wizard && get_check("Can't make new savefile. Overwrite old?")))) X `7B X (void) chmod(fnam, 0600); X fd = open(fnam, O_RDWR`7CO_TRUNC, 0600); X `7D X#endif X if (fd >= 0) X `7B X (void) close(fd); X#endif /* !ATARIST_MWC && !VMS */ X /* GCC for atari st defines atarist */ X#if defined(atarist) `7C`7C defined(ATARI_ST) `7C`7C defined(THINK_C) `7C`7C V defined(MSDOS) X fileptr = fopen(savefile, "wb"); X#else X fileptr = fopen(savefile, "w"); X#endif X#if !defined(ATARIST_MWC) && !defined(VMS) X `7D X#endif X DEBUG(logfile = fopen("IO_LOG", "a")); X DEBUG(fprintf (logfile, "Saving data to %s\n", savefile)); X if (fileptr != NULL) X `7B X xor_byte = 0; X wr_byte((int8u)CUR_VERSION_MAJ); X xor_byte = 0; X wr_byte((int8u)CUR_VERSION_MIN); X xor_byte = 0; X wr_byte((int8u)PATCH_LEVEL); X xor_byte = 0; X char_tmp = randint(256) - 1; X wr_byte(char_tmp); X /* Note that xor_byte is now equal to char_tmp */ X X ok = sv_write(); X X DEBUG(fclose (logfile)); X X if (fclose(fileptr) == EOF) X`09ok = FALSE; X `7D X X#ifdef MAC X macendwait (); X#endif X X if (!ok) X `7B X if (fd >= 0) X`09(void) unlink(fnam); X signals(); X if (fd >= 0) X`09(void) sprintf(temp, "Error writing to file %s", fnam); X else X`09(void) sprintf(temp, "Can't create new file %s", fnam); X msg_print(temp); X return FALSE; X `7D X else X character_saved = 1; X X turn = -1; X signals(); X X return TRUE; X`7D X X X#ifdef MAC X/* Wrapper to set the appropriate directory */ Xint get_char(generate) Xint *generate; X`7B X int rc, exit_flag; X int16 vrefnum; X X (void) getsavedefaults(savefile, &vrefnum); X X changedirectory(vrefnum); X rc = _get_char(generate, &exit_flag); X restoredirectory(); X X if (exit_flag) X exit_game(); X X return(rc); X`7D X#endif X X/* Certain checks are ommitted for the wizard. -CJS- */ X X#ifdef MAC Xint _get_char(generate, exit_flag) Xint *generate, *exit_flag; X#else Xint get_char(generate) Xint *generate; X#endif X`7B X register int i, j; X int fd, c, ok, total_count; X int32u l, age, time_saved; X vtype temp; X int16u int16u_tmp; X register cave_type *c_ptr; X register recall_type *r_ptr; X struct misc *m_ptr; X struct stats *s_ptr; X register struct flags *f_ptr; X store_type *st_ptr; X int8u char_tmp, ychar, xchar, count; X int8u version_maj, version_min, patch_level; X#if defined(MSDOS) `7C`7C defined(ATARI_ST) X inven_type *t_ptr; X#endif X X#ifdef MAC X *exit_flag = FALSE; X#endif X X nosignals(); X *generate = TRUE; X fd = -1; X X#ifndef MAC X /* Not required for Mac, because the file name is obtained through a dialo Vg. X There is no way for a non existnat file to be specified. -BS-`09*/ X if (access(savefile, 0) != 0) X `7B X signals(); X msg_print("Savefile does not exist."); X return FALSE;`09/* Don't bother with messages here. File absent. */ X `7D X#endif X X clear_screen(); X X (void) sprintf(temp, "Savefile %s present. Attempting restore.", savefile) V; X put_buffer(temp, 23, 0); X X if (turn >= 0) X msg_print("IMPOSSIBLE! Attempt to restore while still alive!"); X X /* Allow restoring a file belonging to someone else, if we can delete it. V */ X /* Hence first try to read without doing a chmod. */ X X#if defined(MAC) `7C`7C defined(AMIGA) X else if ((fd = open(savefile, O_RDONLY)) < 0) X#else X#ifdef ATARI_ST X else if (FALSE) X#else X else if ((fd = open(savefile, O_RDONLY, 0)) < 0 X`09 && (chmod(savefile, 0400) < 0 `7C`7C X`09 (fd = open(savefile, O_RDONLY, 0)) < 0)) X#endif X#endif X msg_print("Can't open file for reading."); X else X `7B X turn = -1; X ok = TRUE; X X (void) close(fd); X /* GCC for atari st defines atarist */ X#if defined(atarist) `7C`7C defined(ATARI_ST) `7C`7C defined(THINK_C) `7C`7C V defined(MSDOS) X fileptr = fopen(savefile, "rb"); X#else X fileptr = fopen(savefile, "r"); X#endif X if (fileptr == NULL) X`09goto error; X X#ifdef MAC X macbeginwait (); X#endif X X prt("Restoring Memory...", 0, 0); X put_qio(); X X DEBUG(logfile = fopen("IO_LOG", "a")); X DEBUG(fprintf (logfile, "Reading data from %s\n", savefile)); X X xor_byte = 0; X rd_byte(&version_maj); X xor_byte = 0; X rd_byte(&version_min); X xor_byte = 0; X rd_byte(&patch_level); X xor_byte = 0; X rd_byte(&xor_byte); X X /* COMPAT support savefiles from 5.0.14 to 5.0.17 */ X /* support savefiles from 5.1.0 to present */ X if ((version_maj != CUR_VERSION_MAJ) X#if 0 X`09 /* As of version 5.4, accept savefiles even if they have higher X`09 version numbers. The savefile format was frozen as of version X`09 5.2.2. */ X`09 `7C`7C (version_min > CUR_VERSION_MIN) X`09 `7C`7C (version_min == CUR_VERSION_MIN && patch_level > PATCH_LEVEL) X#endif X`09 `7C`7C (version_min == 0 && patch_level < 14)) X`09`7B X`09 prt("Sorry. This savefile is from a different version of umoria.", X`09 2, 0); X`09 goto error; X`09`7D X X rd_short(&int16u_tmp); X while (int16u_tmp != 0xFFFF) X`09`7B X`09 if (int16u_tmp >= MAX_CREATURES) X`09 goto error; X`09 r_ptr = &c_recall`5Bint16u_tmp`5D; X`09 rd_long(&r_ptr->r_cmove); X`09 rd_long(&r_ptr->r_spells); X`09 rd_short(&r_ptr->r_kills); X`09 rd_short(&r_ptr->r_deaths); X`09 rd_short(&r_ptr->r_cdefense); X`09 rd_byte(&r_ptr->r_wake); X`09 rd_byte(&r_ptr->r_ignore); X`09 rd_bytes(r_ptr->r_attacks, MAX_MON_NATTACK); X`09 rd_short(&int16u_tmp); X`09`7D X X /* for save files before 5.2.2, read and ignore log_index (sic) */ X if ((version_min < 2) `7C`7C (version_min == 2 && patch_level < 2)) X`09rd_short(&int16u_tmp); X rd_long(&l); X X if (l & 0x1) X`09find_cut = TRUE; X else X`09find_cut = FALSE; X if (l & 0x2) X`09find_examine = TRUE; X else X`09find_examine = FALSE; X if (l & 0x4) X`09find_prself = TRUE; X else X`09find_prself = FALSE; X if (l & 0x8) X`09find_bound = TRUE; X else X`09find_bound = FALSE; X if (l & 0x10) X`09prompt_carry_flag = TRUE; X else X`09prompt_carry_flag = FALSE; X if (l & 0x20) X`09rogue_like_commands = TRUE; X else X`09rogue_like_commands = FALSE; X if (l & 0x40) X`09show_weight_flag = TRUE; X else X`09show_weight_flag = FALSE; X if (l & 0x80) X`09highlight_seams = TRUE; X else X`09highlight_seams = FALSE; X if (l & 0x100) X`09find_ignore_doors = TRUE; X else X`09find_ignore_doors = FALSE; X /* save files before 5.2.2 don't have sound_beep_flag, set it on X`09 for compatibility */ X if ((version_min < 2) `7C`7C (version_min == 2 && patch_level < 2)) X`09sound_beep_flag = TRUE; X else if (l & 0x200) X`09sound_beep_flag = TRUE; X else X`09sound_beep_flag = FALSE; X /* save files before 5.2.2 don't have display_counts, set it on X`09 for compatibility */ X if ((version_min < 2) `7C`7C (version_min == 2 && patch_level < 2)) X`09display_counts = TRUE; X else if (l & 0x400) X`09display_counts = TRUE; X else X`09display_counts = FALSE; X X /* Don't allow resurrection of total_winner characters. It causes X`09 problems because the character level is out of the allowed range. */ X if (to_be_wizard && (l & 0x40000000L)) X`09`7B X`09 msg_print ("Sorry, this character is retired from moria."); X`09 msg_print ("You can not resurrect a retired character."); X`09`7D X else if (to_be_wizard && (l & 0x80000000L) X`09 && get_check("Resurrect a dead character?")) X`09l &= `7E0x80000000L; X if ((l & 0x80000000L) == 0) X`09`7B X`09 m_ptr = &py.misc; X`09 rd_string(m_ptr->name); X`09 rd_byte(&m_ptr->male); X`09 rd_long((int32u *)&m_ptr->au); X`09 rd_long((int32u *)&m_ptr->max_exp); X`09 rd_long((int32u *)&m_ptr->exp); X`09 rd_short(&m_ptr->exp_frac); X`09 rd_short(&m_ptr->age); X`09 rd_short(&m_ptr->ht); X`09 rd_short(&m_ptr->wt); X`09 rd_short(&m_ptr->lev); X`09 rd_short(&m_ptr->max_dlv); X`09 rd_short((int16u *)&m_ptr->srh); X`09 rd_short((int16u *)&m_ptr->fos); X`09 rd_short((int16u *)&m_ptr->bth); X`09 rd_short((int16u *)&m_ptr->bthb); X`09 rd_short((int16u *)&m_ptr->mana); X`09 rd_short((int16u *)&m_ptr->mhp); X`09 rd_short((int16u *)&m_ptr->ptohit); X`09 rd_short((int16u *)&m_ptr->ptodam); X`09 rd_short((int16u *)&m_ptr->pac); X`09 rd_short((int16u *)&m_ptr->ptoac); X`09 rd_short((int16u *)&m_ptr->dis_th); X`09 rd_short((int16u *)&m_ptr->dis_td); X`09 rd_short((int16u *)&m_ptr->dis_ac); X`09 rd_short((int16u *)&m_ptr->dis_tac); X`09 rd_short((int16u *)&m_ptr->disarm); X`09 rd_short((int16u *)&m_ptr->save); X`09 rd_short((int16u *)&m_ptr->sc); X`09 rd_short((int16u *)&m_ptr->stl); X`09 rd_byte(&m_ptr->pclass); X`09 rd_byte(&m_ptr->prace); X`09 rd_byte(&m_ptr->hitdie); X`09 rd_byte(&m_ptr->expfact); X`09 rd_short((int16u *)&m_ptr->cmana); X`09 rd_short(&m_ptr->cmana_frac); X`09 rd_short((int16u *)&m_ptr->chp); X`09 rd_short(&m_ptr->chp_frac); X`09 for (i = 0; i < 4; i++) X`09 rd_string (m_ptr->history`5Bi`5D); X X`09 s_ptr = &py.stats; X`09 rd_bytes(s_ptr->max_stat, 6); X`09 rd_bytes(s_ptr->cur_stat, 6); X`09 rd_shorts((int16u *)s_ptr->mod_stat, 6); X`09 rd_bytes(s_ptr->use_stat, 6); X X`09 f_ptr = &py.flags; X`09 rd_long(&f_ptr->status); X`09 rd_short((int16u *)&f_ptr->rest); X`09 rd_short((int16u *)&f_ptr->blind); X`09 rd_short((int16u *)&f_ptr->paralysis); X`09 rd_short((int16u *)&f_ptr->confused); X`09 rd_short((int16u *)&f_ptr->food); X`09 rd_short((int16u *)&f_ptr->food_digested); X`09 rd_short((int16u *)&f_ptr->protection); X`09 rd_short((int16u *)&f_ptr->speed); X`09 rd_short((int16u *)&f_ptr->fast); X`09 rd_short((int16u *)&f_ptr->slow); X`09 rd_short((int16u *)&f_ptr->afraid); X`09 rd_short((int16u *)&f_ptr->poisoned); X`09 rd_short((int16u *)&f_ptr->image); X`09 rd_short((int16u *)&f_ptr->protevil); X`09 rd_short((int16u *)&f_ptr->invuln); X`09 rd_short((int16u *)&f_ptr->hero); X`09 rd_short((int16u *)&f_ptr->shero); X`09 rd_short((int16u *)&f_ptr->blessed); X`09 rd_short((int16u *)&f_ptr->resist_heat); X`09 rd_short((int16u *)&f_ptr->resist_cold); X`09 rd_short((int16u *)&f_ptr->detect_inv); X`09 rd_short((int16u *)&f_ptr->word_recall); X`09 rd_short((int16u *)&f_ptr->see_infra); X`09 rd_short((int16u *)&f_ptr->tim_infra); X`09 rd_byte(&f_ptr->see_inv); X`09 rd_byte(&f_ptr->teleport); X`09 rd_byte(&f_ptr->free_act); X`09 rd_byte(&f_ptr->slow_digest); X`09 rd_byte(&f_ptr->aggravate); X`09 rd_byte(&f_ptr->fire_resist); X`09 rd_byte(&f_ptr->cold_resist); X`09 rd_byte(&f_ptr->acid_resist); X`09 rd_byte(&f_ptr->regenerate); X`09 rd_byte(&f_ptr->lght_resist); X`09 rd_byte(&f_ptr->ffall); X`09 rd_byte(&f_ptr->sustain_str); X`09 rd_byte(&f_ptr->sustain_int); X`09 rd_byte(&f_ptr->sustain_wis); X`09 rd_byte(&f_ptr->sustain_con); X`09 rd_byte(&f_ptr->sustain_dex); X`09 rd_byte(&f_ptr->sustain_chr); X`09 rd_byte(&f_ptr->confuse_monster); X`09 rd_byte(&f_ptr->new_spells); X X`09 rd_short((int16u *)&missile_ctr); X`09 rd_long((int32u *)&turn); X`09 rd_short((int16u *)&inven_ctr); X`09 if (inven_ctr > INVEN_WIELD) X`09 goto error; X`09 for (i = 0; i < inven_ctr; i++) X`09 rd_item(&inventory`5Bi`5D); X`09 for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) X`09 rd_item(&inventory`5Bi`5D); X`09 rd_short((int16u *)&inven_weight); X`09 rd_short((int16u *)&equip_ctr); X`09 rd_long(&spell_learned); X`09 rd_long(&spell_worked); X`09 rd_long(&spell_forgotten); X`09 rd_bytes(spell_order, 32); X`09 rd_bytes(object_ident, OBJECT_IDENT_SIZE); X`09 rd_long(&randes_seed); X`09 rd_long(&town_seed); X`09 rd_short((int16u *)&last_msg); X`09 for (i = 0; i < MAX_SAVE_MSG; i++) X`09 rd_string(old_msg`5Bi`5D); X X`09 rd_short((int16u *)&panic_save); X`09 rd_short((int16u *)&total_winner); X`09 rd_short((int16u *)&noscore); X`09 rd_shorts(player_hp, MAX_PLAYER_LEVEL); X X`09 if ((version_min >= 2) X`09 `7C`7C (version_min == 1 && patch_level >= 3)) X`09 for (i = 0; i < MAX_STORES; i++) X`09 `7B X`09`09st_ptr = &store`5Bi`5D; X`09`09rd_long((int32u *)&st_ptr->store_open); X`09`09rd_short((int16u *)&st_ptr->insult_cur); X`09`09rd_byte(&st_ptr->owner); X`09`09rd_byte(&st_ptr->store_ctr); X`09`09rd_short(&st_ptr->good_buy); X`09`09rd_short(&st_ptr->bad_buy); X`09`09if (st_ptr->store_ctr > STORE_INVEN_MAX) X`09`09 goto error; X`09`09for (j = 0; j < st_ptr->store_ctr; j++) X`09`09 `7B X`09`09 rd_long((int32u *)&st_ptr->store_inven`5Bj`5D.scost); X`09`09 rd_item(&st_ptr->store_inven`5Bj`5D.sitem); X`09`09 `7D X`09 `7D X X`09 if ((version_min >= 2) X`09 `7C`7C (version_min == 1 && patch_level >= 3)) X`09 rd_long(&time_saved); X X`09 if (version_min >= 2) X`09 rd_string(died_from); X X`09 if ((version_min >= 3) X`09 `7C`7C (version_min == 2 && patch_level >= 2)) X`09 rd_long ((int32u *)&max_score); X`09 else X`09 max_score = 0; X X`09 if ((version_min >= 3) X`09 `7C`7C (version_min == 2 && patch_level >= 2)) X`09 rd_long ((int32u *)&birth_date); X`09 else X#ifdef MAC X`09 birth_date = time((time_t *)0); X#else X`09 birth_date = time((long *)0); X#endif X`09`7D X if ((c = getc(fileptr)) == EOF `7C`7C (l & 0x80000000L)) X`09`7B X`09 if ((l & 0x80000000L) == 0) X`09 `7B X`09 if (!to_be_wizard `7C`7C turn < 0) X`09`09goto error; X`09 prt("Attempting a resurrection!", 0, 0); X`09 if (py.misc.chp < 0) X`09`09`7B X`09`09 py.misc.chp =`09 0; X`09`09 py.misc.chp_frac = 0; +-+-+-+-+-+-+-+- END OF PART 57 +-+-+-+-+-+-+-+-