home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  9.1 KB  |  393 lines

  1. /*    SCCS Id: @(#)save.c    2.3    88/01/24
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include <signal.h>
  5. #include <stdio.h>
  6. #include "hack.h"
  7.  
  8. extern char genocided[60];        /* defined in decl.c */
  9. extern char fut_geno[60];        /* idem */
  10. extern struct permonst    pm_wizard;    /* since the wizard evolves */
  11.  
  12. extern char SAVEF[], nul[];
  13. extern char pl_character[PL_CSIZ];
  14. extern long lseek();
  15. extern struct obj *restobjchn();
  16. extern struct monst *restmonchn();
  17.  
  18. dosave(){
  19.     clear_screen();
  20.     fflush(stdout);
  21.     if(dosave0(0)) {
  22.         settty("Be seeing you ...\n");
  23.         exit(0);
  24.     }
  25. #ifdef LINT
  26.     return(0);
  27. #endif
  28. }
  29.  
  30. #ifndef NOSAVEONHANGUP
  31. hangup(){
  32.     (void) dosave0(1);
  33.     exit(1);
  34. }
  35. #endif
  36.  
  37. /* returns 1 if save successful */
  38. dosave0(hu) int hu; {
  39.     register fd, ofd;
  40.     int tmp;        /* not register ! */
  41. #ifdef DGK
  42.     long fds, needed;
  43.     extern long bytes_counted;
  44.     int mode;
  45. #endif
  46. #ifdef UNIX
  47.     (void) signal(SIGHUP, SIG_IGN);
  48. #endif
  49. #ifndef __TURBOC__
  50.     (void) signal(SIGINT, SIG_IGN);
  51. #endif
  52. #ifdef DGK
  53.     if (!saveDiskPrompt(0))
  54.         return 0;
  55.     fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT, FMASK);
  56. #else
  57.     fd = creat(SAVEF, FMASK);
  58. #endif
  59.     if(fd < 0) {
  60.         if(!hu) pline("Cannot open save file. (Continue or Quit)");
  61.         (void) unlink(SAVEF);        /* ab@unido */
  62.         return(0);
  63.     }
  64.     if(flags.moonphase == FULL_MOON)    /* ut-sally!fletcher */
  65.         change_luck(-1);        /* and unido!ab */
  66. #ifdef DGKMOD
  67.     home();
  68.     cl_end();
  69. #endif
  70. #ifdef DGK
  71.     msmsg("Saving: ");
  72.     mode = COUNT;
  73. again:
  74.     savelev(fd, dlevel, mode);
  75.     /* count_only will be set properly by savelev */
  76. #else
  77.     savelev(fd,dlevel);
  78. #endif
  79.     saveobjchn(fd, invent);
  80.     saveobjchn(fd, fcobj);
  81.     savemonchn(fd, fallen_down);
  82.     tmp = getuid();
  83.     bwrite(fd, (char *) &tmp, sizeof tmp);
  84.     bwrite(fd, (char *) &flags, sizeof(struct flag));
  85.     bwrite(fd, (char *) &dlevel, sizeof dlevel);
  86.     bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
  87.     bwrite(fd, (char *) &moves, sizeof moves);
  88.     bwrite(fd, (char *) &u, sizeof(struct you));
  89. #ifdef SPELLS
  90.     bwrite(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1));
  91. #endif
  92.     if(u.ustuck)
  93.         bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
  94.     bwrite(fd, (char *) pl_character, sizeof pl_character);
  95.     bwrite(fd, (char *) genocided, sizeof genocided);
  96.     bwrite(fd, (char *) fut_geno, sizeof fut_geno);
  97. #ifdef HARD
  98.     bwrite(fd, (char *) &pm_wizard, sizeof(struct permonst));
  99. #endif
  100.     savenames(fd);
  101. #ifdef DGK
  102.     if (mode == COUNT) {
  103.         /* make sure there is enough disk space */
  104.         needed = bytes_counted;
  105.         for (tmp = 1; tmp <= maxdlevel; tmp++)
  106.             if (tmp != dlevel && fileinfo[tmp].where)
  107.                 needed += fileinfo[tmp].size + (sizeof tmp);
  108.         fds = freediskspace(SAVEF);
  109.         if (needed > fds) {
  110.             pline("There is insufficient space on SAVE disk.");
  111.             pline("Require %ld bytes but only have %ld.", needed,
  112.                 fds);
  113.             flushout();
  114.             (void) close(fd);
  115.             (void) unlink(SAVEF);
  116.             return 0;
  117.         }
  118.         mode = WRITE;
  119.         goto again;
  120.     }
  121. #endif
  122.     for(tmp = 1; tmp <= maxdlevel; tmp++) {
  123.         extern int hackpid;
  124. #ifdef DGK
  125.         if (tmp == dlevel || !fileinfo[tmp].where) continue;
  126.         if (fileinfo[tmp].where != ACTIVE)
  127.             swapin_file(tmp);
  128. #else
  129.         extern boolean level_exists[];
  130.  
  131.         if(tmp == dlevel || !level_exists[tmp]) continue;
  132. #endif
  133.         glo(tmp);
  134. #ifdef DGK
  135.         msmsg(".");
  136. #endif
  137.         if((ofd = open(lock, 0)) < 0) {
  138.             if(!hu) pline("Error while saving: cannot read %s.", lock);
  139.             (void) close(fd);
  140.             (void) unlink(SAVEF);
  141.             if(!hu) done("tricked");
  142.             return(0);
  143.         }
  144.         getlev(ofd, hackpid, tmp);
  145.         (void) close(ofd);
  146.         bwrite(fd, (char *) &tmp, sizeof tmp);    /* level number */
  147. #ifdef DGK
  148.         savelev(fd,tmp,WRITE);            /* actual level */
  149. #else
  150.         savelev(fd,tmp);            /* actual level */
  151. #endif
  152.         (void) unlink(lock);
  153.     }
  154.     (void) close(fd);
  155.     glo(dlevel);
  156.     (void) unlink(lock);    /* get rid of current level --jgm */
  157.     glo(0);
  158.     (void) unlink(lock);
  159.     return(1);
  160. }
  161.  
  162. dorecover(fd)
  163. register fd;
  164. {
  165.     register nfd;
  166.     int tmp;        /* not a register ! */
  167.     unsigned mid;        /* idem */
  168.     struct obj *otmp;
  169.     extern boolean restoring;
  170. #ifdef DGK
  171.     struct flag oldflags;
  172.  
  173.     oldflags = flags;    /* Save flags set in the config file */
  174. #endif
  175.     restoring = TRUE;
  176.     getlev(fd, 0, 0);
  177.     invent = restobjchn(fd);
  178.     for(otmp = invent; otmp; otmp = otmp->nobj)
  179.         if(otmp->owornmask)
  180.             setworn(otmp, otmp->owornmask);
  181.     fcobj = restobjchn(fd);
  182.     fallen_down = restmonchn(fd);
  183.     mread(fd, (char *) &tmp, sizeof tmp);
  184. #ifdef WIZARD
  185.     if(!wizard)
  186. #endif
  187.         if(tmp != getuid()) {        /* strange ... */
  188.         (void) close(fd);
  189.         (void) unlink(SAVEF);
  190.         puts("Saved game was not yours.");
  191.         restoring = FALSE;
  192.         return(0);
  193.         }
  194.     mread(fd, (char *) &flags, sizeof(struct flag));
  195. #ifdef DGK
  196.     /* Some config file OPTIONS take precedence over those in save file.
  197.      */
  198.     flags.rawio = oldflags.rawio;
  199.     flags.DECRainbow = oldflags.DECRainbow;
  200.     flags.IBMBIOS = oldflags.IBMBIOS;
  201. #endif
  202.     mread(fd, (char *) &dlevel, sizeof dlevel);
  203.     mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
  204.     mread(fd, (char *) &moves, sizeof moves);
  205.     mread(fd, (char *) &u, sizeof(struct you));
  206. #ifdef SPELLS
  207.     mread(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1));
  208. #endif
  209.     if(u.ustuck)
  210.         mread(fd, (char *) &mid, sizeof mid);
  211.     mread(fd, (char *) pl_character, sizeof pl_character);
  212.     mread(fd, (char *) genocided, sizeof genocided);
  213.     mread(fd, (char *) fut_geno, sizeof fut_geno);
  214. #ifdef HARD
  215.     {
  216.     /* Save name pointer from being munged -- tom@uw-warp */
  217.     char *name = pm_wizard.mname;
  218.     mread(fd, (char *) &pm_wizard, sizeof(struct permonst));
  219.     pm_wizard.mname = name;
  220.     }
  221. #endif
  222.     restnames(fd);
  223. #ifdef DGK
  224.     msmsg("\n");
  225.     cl_end();
  226.     msmsg("You got as far as level %d%s.\n", maxdlevel,
  227.         flags.debug ? " in WIZARD mode" : "");
  228.     cl_end();
  229.     msmsg("Restoring: ");
  230. #endif
  231.     while(1) {
  232.         if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
  233.             break;
  234.         getlev(fd, 0, tmp);
  235.         glo(tmp);
  236. #ifdef DGK
  237.         msmsg(".");
  238.         nfd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK);
  239. #else
  240.         nfd = creat(lock, FMASK);
  241. #endif
  242.         if (nfd < 0)    panic("Cannot open temp file %s!\n", lock);
  243. #ifdef DGK
  244.         if (!savelev(nfd, tmp, COUNT | WRITE)) {
  245.  
  246.             /* The savelev can't proceed because the size required
  247.              * is greater than the available disk space.
  248.              */
  249.             msmsg("\nNot enough space on `%s' to restore your game.\n",
  250.                 levels);
  251.  
  252.             /* Remove levels and bones that may have been created.
  253.              */
  254.             (void) close(nfd);
  255.             eraseall(levels, alllevels);
  256.             eraseall(levels, allbones);
  257.  
  258.             /* Perhaps the person would like to play without a
  259.              * RAMdisk.
  260.              */
  261.             if (ramdisk) {
  262.                 /* PlaywoRAMdisk may not return, but if it does
  263.                  * it is certain that ramdisk will be 0.
  264.                  */
  265.                 playwoRAMdisk();
  266.                 (void) lseek(fd, 0L, 0); /* Rewind save file */
  267.                 return dorecover(fd);     /* and try again */
  268.             } else {
  269.                 msmsg("Be seeing you ...\n");
  270.                 exit(0);
  271.             }
  272.         }
  273. #else
  274.         savelev(nfd,tmp);
  275. #endif
  276.         (void) close(nfd);
  277.     }
  278.     (void) lseek(fd, 0L, 0);
  279.     getlev(fd, 0, 0);
  280.     (void) close(fd);
  281.     (void) unlink(SAVEF);
  282.     if(Punished) {
  283.         for(otmp = fobj; otmp; otmp = otmp->nobj)
  284.             if(otmp->olet == CHAIN_SYM) goto chainfnd;
  285.         panic("Cannot find the iron chain?");
  286.     chainfnd:
  287.         uchain = otmp;
  288.         if(!uball){
  289.             for(otmp = fobj; otmp; otmp = otmp->nobj)
  290.                 if(otmp->olet == BALL_SYM && otmp->spe)
  291.                     goto ballfnd;
  292.             panic("Cannot find the iron ball?");
  293.         ballfnd:
  294.             uball = otmp;
  295.         }
  296.     }
  297.     if(u.ustuck) {
  298.         register struct monst *mtmp;
  299.  
  300.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  301.             if(mtmp->m_id == mid) goto monfnd;
  302.         panic("Cannot find the monster ustuck.");
  303.     monfnd:
  304.         u.ustuck = mtmp;
  305.     }
  306. #ifndef QUEST
  307.     setsee();  /* only to recompute seelx etc. - these weren't saved */
  308. #endif
  309. #ifdef DGK
  310.     gameDiskPrompt();
  311. #endif
  312.     docrt();
  313.     restoring = FALSE;
  314.     return(1);
  315. }
  316.  
  317. struct obj *
  318. restobjchn(fd)
  319. register fd;
  320. {
  321.     register struct obj *otmp, *otmp2;
  322.     register struct obj *first = 0;
  323.     int xl;
  324. #ifdef LINT
  325.     /* suppress "used before set" warning from lint */
  326.     otmp2 = 0;
  327. #endif
  328.     while(1) {
  329.         mread(fd, (char *) &xl, sizeof(xl));
  330.         if(xl == -1) break;
  331.         otmp = newobj(xl);
  332.         if(!first) first = otmp;
  333.         else otmp2->nobj = otmp;
  334.         mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
  335.         if(!otmp->o_id) otmp->o_id = flags.ident++;
  336.         otmp2 = otmp;
  337.     }
  338.     if(first && otmp2->nobj){
  339.         impossible("Restobjchn: error reading objchn.");
  340.         otmp2->nobj = 0;
  341.     }
  342.     return(first);
  343. }
  344.  
  345. struct monst *
  346. restmonchn(fd)
  347. register fd;
  348. {
  349.     register struct monst *mtmp, *mtmp2;
  350.     register struct monst *first = 0;
  351.     int xl;
  352.  
  353.     struct permonst *monbegin;
  354.     long differ;
  355.  
  356.     mread(fd, (char *)&monbegin, sizeof(monbegin));
  357. #ifndef MSDOS
  358.     differ = (char *)(&mons[0]) - (char *)(monbegin);
  359. #else
  360.     differ = (long)(&mons[0]) - (long)(monbegin);
  361. #endif
  362.  
  363. #ifdef LINT
  364.     /* suppress "used before set" warning from lint */
  365.     mtmp2 = 0;
  366. #endif
  367.     while(1) {
  368.         mread(fd, (char *) &xl, sizeof(xl));
  369.         if(xl == -1) break;
  370.         mtmp = newmonst(xl);
  371.         if(!first) first = mtmp;
  372.         else mtmp2->nmon = mtmp;
  373.         mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
  374.         if(!mtmp->m_id)
  375.             mtmp->m_id = flags.ident++;
  376. #ifndef MSDOS
  377.         mtmp->data = (struct permonst *)
  378.             ((char *) mtmp->data + differ);
  379. #else
  380.         mtmp->data = (struct permonst *)
  381.             ((long) mtmp->data + differ);
  382. #endif
  383.         if(mtmp->minvent)
  384.             mtmp->minvent = restobjchn(fd);
  385.         mtmp2 = mtmp;
  386.     }
  387.     if(first && mtmp2->nmon){
  388.         impossible("Restmonchn: error reading monchn.");
  389.         mtmp2->nmon = 0;
  390.     }
  391.     return(first);
  392. }
  393.