Rewrite save/resume in idiomatic C. Savefile version bumped to 26.
[open-adventure.git] / saveresume.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "advent.h"
5 #include "database.h"
6 #include "linenoise/linenoise.h"
7
8 /*
9  * (ESR) This replaces  a bunch of particularly nasty FORTRAN-derived code;
10  * see the history.adoc file in the source distribution for discussion.
11  */
12
13 #define VRSION  26      /* bump on save format change */
14
15 /*
16  * If you change the first three members, the resume function may not properly
17  * reject saves from older versions.  Yes, this glues us to a hardware-
18  * dependent length of long.  Later members can change, but bump the version
19  * when you do that.
20  */
21 struct save_t {
22     long savetime;
23     long mode;          /* not used, must be present for version detection */
24     long version;
25     struct game_t game;
26     long bird;
27     long bivalve;
28 };
29 struct save_t save;
30
31 int saveresume(FILE *input, bool resume)
32 /* Suspend and resume */
33 {
34     long i, k;
35     FILE *fp = NULL;
36     char *name;
37  
38     if (!resume) {
39         /*  Suspend.  Offer to save things in a file, but charging
40          *  some points (so can't win by using saved games to retry
41          *  battles or to start over after learning zzword). */
42         RSPEAK(260);
43         if (!YES(input,200,54,54)) return(2012);
44         game.saved=game.saved+5;
45     }
46     else
47     {
48         /*  Resume.  Read a suspended game back from a file. */
49         if (game.loc != 1 || game.abbrev[1] != 1) {
50             RSPEAK(268);
51             if (!YES(input,200,54,54)) return(2012);
52         }
53     }
54
55     while (fp == NULL) {
56         name = linenoise("File name: ");
57         fp = fopen(name,(resume ? READ_MODE : WRITE_MODE));
58         if (fp == NULL)
59             printf("Can't open file %s, try again.\n", name); 
60     }
61     linenoiseFree(name);
62     
63     DATIME(&i,&k);
64     k=i+650*k;
65     if (!resume)
66     {
67         save.savetime = k;
68         save.mode = -1;
69         save.version = VRSION;
70         memcpy(&save.game, &game, sizeof(struct game_t));
71         save.bird = OBJSND[BIRD];
72         save.bivalve = OBJTXT[OYSTER];
73         IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp));
74         fclose(fp);
75         RSPEAK(266);
76         exit(0);
77     } else {
78         IGNORE(fread(&save, sizeof(struct save_t), 1, fp));
79         fclose(fp);
80         if (save.version != VRSION) {
81             SETPRM(1,k/10,MOD(k,10));
82             SETPRM(3,VRSION/10,MOD(VRSION,10));
83             RSPEAK(269);
84             return(2000);
85         }
86         memcpy(&game, &save.game, sizeof(struct game_t));
87         OBJSND[BIRD] = save.bird;
88         OBJTXT[OYSTER] = save.bivalve;
89         game.zzword=RNDVOC(3,game.zzword);
90         return(2000);
91     }
92 }
93
94 /* end */