There should only be two changes in behavior: arogue7/fight.c, arogue7/fight.c: a to-hit bonus is now correctly applied to characters who are not monks instead of monks who are not empty-handed. urogue/fight.c: fixed an interaction with the "debug" macro that could cause the wrong message to be displayed.
306 lines
5.2 KiB
C
306 lines
5.2 KiB
C
/*
|
|
* save and restore routines
|
|
*
|
|
* @(#)save.c 9.0 (rdk) 7/17/84
|
|
*
|
|
* Super-Rogue
|
|
* Copyright (C) 1984 Robert D. Kindelberger
|
|
* All rights reserved.
|
|
*
|
|
* Based on "Rogue: Exploring the Dungeons of Doom"
|
|
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
|
* All rights reserved.
|
|
*
|
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <signal.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#if !defined(_WIN32)
|
|
#include <unistd.h>
|
|
#endif
|
|
#include "rogue.h"
|
|
#include "rogue.ext"
|
|
|
|
EXTCHAR version[];
|
|
|
|
bool dosave(void);
|
|
void save_file(FILE *savef);
|
|
|
|
typedef struct stat STAT;
|
|
STAT sbuf;
|
|
|
|
/*
|
|
* ignore:
|
|
* Ignore ALL signals possible
|
|
*/
|
|
void
|
|
ignore(void)
|
|
{
|
|
md_ignoreallsignals();
|
|
}
|
|
|
|
/*
|
|
* save_game:
|
|
* Save the current game
|
|
*/
|
|
bool
|
|
save_game(void)
|
|
{
|
|
reg int c;
|
|
char buf[LINLEN];
|
|
|
|
mpos = 0;
|
|
if (file_name[0] != '\0') {
|
|
if (use_savedir)
|
|
msg("Save game? (y/n) ");
|
|
else
|
|
msg("Save file (%s)? ", file_name);
|
|
do {
|
|
c = wgetch(cw);
|
|
if(c == ESCAPE) {
|
|
msg("");
|
|
return FALSE;
|
|
}
|
|
} while (c != 'n' && c != 'y');
|
|
mpos = 0;
|
|
if (c == 'y')
|
|
goto gotfile;
|
|
}
|
|
if (use_savedir) {
|
|
msg("");
|
|
return FALSE;
|
|
}
|
|
msg("File name: ");
|
|
mpos = 0;
|
|
buf[0] = '\0';
|
|
if (get_str(buf, cw) == QUIT) {
|
|
msg("");
|
|
return FALSE;
|
|
}
|
|
msg("");
|
|
strcpy(file_name, buf);
|
|
gotfile:
|
|
c = dosave(); /* try to save this game */
|
|
if (c == FALSE)
|
|
msg("Could not save game to file %s", file_name);
|
|
return c;
|
|
}
|
|
|
|
/*
|
|
* auto_save:
|
|
* Automatically save a game
|
|
*/
|
|
void
|
|
auto_save(int a)
|
|
{
|
|
dosave(); /* save this game */
|
|
byebye(1); /* so long for now */
|
|
}
|
|
|
|
/*
|
|
* game_err:
|
|
* When an error occurs. Set error flag and save game.
|
|
*/
|
|
void
|
|
game_err(int a)
|
|
{
|
|
int ok;
|
|
|
|
ok = dosave(); /* try to save this game */
|
|
clear();
|
|
refresh();
|
|
endwin();
|
|
|
|
printf("\nInternal error !!!\n\nYour game was ");
|
|
if (ok)
|
|
printf("saved.");
|
|
else
|
|
printf("NOT saveable.");
|
|
|
|
fflush(stdout);
|
|
|
|
#ifdef SIGIOT
|
|
signal(SIGIOT, SIG_DFL); /* allow core dump signal */
|
|
#endif
|
|
|
|
abort(); /* cause core dump */
|
|
byebye(3);
|
|
}
|
|
|
|
/*
|
|
* dosave:
|
|
* Save the game. UID/GID no longer get reset here.
|
|
*/
|
|
bool
|
|
dosave(void)
|
|
{
|
|
FILE *savef;
|
|
|
|
ignore();
|
|
umask(022);
|
|
|
|
if (file_name[0] != '\0') {
|
|
if ((savef = fopen(file_name,"w")) != NULL)
|
|
{
|
|
save_file(savef);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* save_file:
|
|
* Do the actual save of this game to a file
|
|
*/
|
|
void
|
|
save_file(FILE *savef)
|
|
{
|
|
int slines = LINES;
|
|
int scols = COLS;
|
|
|
|
#ifdef __DJGPP__ /* st_ino w/ DJGPP under WinXP broken */
|
|
_djstat_flags |= _STAT_INODE; /* so turn off computing it for now */
|
|
#endif
|
|
|
|
encwrite(version,strlen(version)+1,savef);
|
|
encwrite(&slines,sizeof(slines),savef);
|
|
encwrite(&scols,sizeof(scols),savef);
|
|
msg("");
|
|
rs_save_file(savef);
|
|
fclose(savef);
|
|
md_onsignal_exit();
|
|
wclear(cw);
|
|
draw(cw);
|
|
}
|
|
|
|
/*
|
|
* restore:
|
|
* Restore a saved game from a file
|
|
*/
|
|
bool
|
|
restore(char *file, char **envp)
|
|
{
|
|
#ifndef _AIX
|
|
extern char **environ;
|
|
#endif
|
|
#ifdef __DJGPP__ /* st_ino w/ DJGPP under WinXP broken */
|
|
_djstat_flags |= _STAT_INODE; /* so turn off computing it for now */
|
|
#endif
|
|
FILE *inf;
|
|
char buf[LINLEN];
|
|
STAT sbuf2;
|
|
int slines, scols;
|
|
|
|
if ((inf = fopen(file, "r")) == NULL) {
|
|
if (use_savedir && errno == ENOENT)
|
|
return TRUE;
|
|
else {
|
|
printf("Cannot read save game %s\n",file);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
encread(buf, strlen(version) + 1, inf);
|
|
|
|
if (strcmp(buf, version) != 0) {
|
|
printf("Sorry, saved game version is out of date.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
stat(file, &sbuf2);
|
|
|
|
encread(&slines,sizeof(slines),inf);
|
|
encread(&scols,sizeof(scols),inf);
|
|
|
|
/*
|
|
* we do not close the file so that we will have a hold of the
|
|
* inode for as long as possible
|
|
*/
|
|
|
|
#ifdef __INTERIX
|
|
setenv("TERM","interix");
|
|
#endif
|
|
|
|
initscr();
|
|
|
|
if (slines > LINES)
|
|
{
|
|
endwin();
|
|
printf("Sorry, original game was played on a screen with %d lines.\n",slines);
|
|
printf("Current screen only has %d lines. Unable to restore game\n",LINES);
|
|
return(FALSE);
|
|
}
|
|
|
|
if (scols > COLS)
|
|
{
|
|
endwin();
|
|
printf("Sorry, original game was played on a screen with %d columns.\n", scols);
|
|
printf("Current screen only has %d columns. Unable to restore game\n",COLS);
|
|
return(FALSE);
|
|
}
|
|
|
|
cw = newwin(LINES, COLS, 0, 0);
|
|
mw = newwin(LINES, COLS, 0, 0);
|
|
hw = newwin(LINES, COLS, 0, 0);
|
|
keypad(cw, 1);
|
|
|
|
mpos = 0;
|
|
mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
|
|
|
|
/* defeat multiple restarting from the same place */
|
|
|
|
if (!wizard)
|
|
{
|
|
if (sbuf2.st_nlink != 1)
|
|
{
|
|
endwin();
|
|
printf("Cannot restore from a linked file\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (rs_restore_file(inf) == FALSE)
|
|
{
|
|
endwin();
|
|
printf("Cannot restore file\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
#if defined(__CYGWIN__) || defined(__DJGPP__)
|
|
fclose(inf);
|
|
#endif
|
|
if (!wizard)
|
|
{
|
|
if (md_unlink_open_file(file, inf) < 0)
|
|
{
|
|
endwin();
|
|
printf("Cannot unlink file\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (him->s_hpt <= 0) {
|
|
endwin();
|
|
printf("This character is already dead.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
environ = envp;
|
|
|
|
strcpy(file_name, file);
|
|
setup();
|
|
restscr(cw);
|
|
md_srandom(md_random_seed());
|
|
playit();
|
|
return FALSE;
|
|
}
|