|
|
1.1 root 1: /*
2: * save.c
3: *
4: * This source herein may be modified and/or distributed by anybody who
5: * so desires, with the following restrictions:
6: * 1.) No portion of this notice shall be removed.
7: * 2.) Credit shall not be taken for the creation of this source.
8: * 3.) This code is not to be traded, sold, or used for personal
9: * gain or profit.
10: *
11: */
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)save.c 5.1 (Berkeley) 11/25/87";
15: #endif /* not lint */
16:
17: #include <stdio.h>
18: #include "rogue.h"
19:
20: short write_failed = 0;
21: char *save_file = (char *) 0;
22:
23: extern boolean detect_monster;
24: extern short cur_level, max_level;
25: extern char hunger_str[];
26: extern char login_name[];
27: extern short party_room;
28: extern short foods;
29: extern boolean is_wood[];
30: extern short cur_room;
31: extern boolean being_held;
32: extern short bear_trap;
33: extern short halluc;
34: extern short blind;
35: extern short confused;
36: extern short levitate;
37: extern short haste_self;
38: extern boolean see_invisible;
39: extern boolean detect_monster;
40: extern boolean wizard;
41: extern boolean score_only;
42: extern short m_moves;
43:
44: extern boolean msg_cleared;
45:
46: save_game()
47: {
48: char fname[64];
49:
50: if (!get_input_line("file name?", save_file, fname, "game not saved",
51: 0, 1)) {
52: return;
53: }
54: check_message();
55: message(fname, 0);
56: save_into_file(fname);
57: }
58:
59: save_into_file(sfile)
60: char *sfile;
61: {
62: FILE *fp;
63: int file_id;
64: char name_buffer[80];
65: char *hptr;
66: struct rogue_time rt_buf;
67:
68: if (sfile[0] == '~') {
69: if (hptr = md_getenv("HOME")) {
70: (void) strcpy(name_buffer, hptr);
71: (void) strcat(name_buffer, sfile+1);
72: sfile = name_buffer;
73: }
74: }
75: if ( ((fp = fopen(sfile, "w")) == NULL) ||
76: ((file_id = md_get_file_id(sfile)) == -1)) {
77: message("problem accessing the save file", 0);
78: return;
79: }
80: md_ignore_signals();
81: write_failed = 0;
82: (void) xxx(1);
83: r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
84: r_write(fp, (char *) &cur_level, sizeof(cur_level));
85: r_write(fp, (char *) &max_level, sizeof(max_level));
86: write_string(hunger_str, fp);
87: write_string(login_name, fp);
88: r_write(fp, (char *) &party_room, sizeof(party_room));
89: write_pack(&level_monsters, fp);
90: write_pack(&level_objects, fp);
91: r_write(fp, (char *) &file_id, sizeof(file_id));
92: rw_dungeon(fp, 1);
93: r_write(fp, (char *) &foods, sizeof(foods));
94: r_write(fp, (char *) &rogue, sizeof(fighter));
95: write_pack(&rogue.pack, fp);
96: rw_id(id_potions, fp, POTIONS, 1);
97: rw_id(id_scrolls, fp, SCROLS, 1);
98: rw_id(id_wands, fp, WANDS, 1);
99: rw_id(id_rings, fp, RINGS, 1);
100: r_write(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
101: r_write(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
102: r_write(fp, (char *) &cur_room, sizeof(cur_room));
103: rw_rooms(fp, 1);
104: r_write(fp, (char *) &being_held, sizeof(being_held));
105: r_write(fp, (char *) &bear_trap, sizeof(bear_trap));
106: r_write(fp, (char *) &halluc, sizeof(halluc));
107: r_write(fp, (char *) &blind, sizeof(blind));
108: r_write(fp, (char *) &confused, sizeof(confused));
109: r_write(fp, (char *) &levitate, sizeof(levitate));
110: r_write(fp, (char *) &haste_self, sizeof(haste_self));
111: r_write(fp, (char *) &see_invisible, sizeof(see_invisible));
112: r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
113: r_write(fp, (char *) &wizard, sizeof(wizard));
114: r_write(fp, (char *) &score_only, sizeof(score_only));
115: r_write(fp, (char *) &m_moves, sizeof(m_moves));
116: md_gct(&rt_buf);
117: rt_buf.second += 10; /* allow for some processing time */
118: r_write(fp, (char *) &rt_buf, sizeof(rt_buf));
119: fclose(fp);
120:
121: if (write_failed) {
122: (void) md_df(sfile); /* delete file */
123: } else {
124: clean_up("");
125: }
126: }
127:
128: restore(fname)
129: char *fname;
130: {
131: FILE *fp;
132: struct rogue_time saved_time, mod_time;
133: char buf[4];
134: char tbuf[40];
135: int new_file_id, saved_file_id;
136:
137: if ( ((new_file_id = md_get_file_id(fname)) == -1) ||
138: ((fp = fopen(fname, "r")) == NULL)) {
139: clean_up("cannot open file");
140: }
141: if (md_link_count(fname) > 1) {
142: clean_up("file has link");
143: }
144: (void) xxx(1);
145: r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
146: r_read(fp, (char *) &cur_level, sizeof(cur_level));
147: r_read(fp, (char *) &max_level, sizeof(max_level));
148: read_string(hunger_str, fp);
149:
150: (void) strcpy(tbuf, login_name);
151: read_string(login_name, fp);
152: if (strcmp(tbuf, login_name)) {
153: clean_up("you're not the original player");
154: }
155:
156: r_read(fp, (char *) &party_room, sizeof(party_room));
157: read_pack(&level_monsters, fp, 0);
158: read_pack(&level_objects, fp, 0);
159: r_read(fp, (char *) &saved_file_id, sizeof(saved_file_id));
160: if (new_file_id != saved_file_id) {
161: clean_up("sorry, saved game is not in the same file");
162: }
163: rw_dungeon(fp, 0);
164: r_read(fp, (char *) &foods, sizeof(foods));
165: r_read(fp, (char *) &rogue, sizeof(fighter));
166: read_pack(&rogue.pack, fp, 1);
167: rw_id(id_potions, fp, POTIONS, 0);
168: rw_id(id_scrolls, fp, SCROLS, 0);
169: rw_id(id_wands, fp, WANDS, 0);
170: rw_id(id_rings, fp, RINGS, 0);
171: r_read(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
172: r_read(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
173: r_read(fp, (char *) &cur_room, sizeof(cur_room));
174: rw_rooms(fp, 0);
175: r_read(fp, (char *) &being_held, sizeof(being_held));
176: r_read(fp, (char *) &bear_trap, sizeof(bear_trap));
177: r_read(fp, (char *) &halluc, sizeof(halluc));
178: r_read(fp, (char *) &blind, sizeof(blind));
179: r_read(fp, (char *) &confused, sizeof(confused));
180: r_read(fp, (char *) &levitate, sizeof(levitate));
181: r_read(fp, (char *) &haste_self, sizeof(haste_self));
182: r_read(fp, (char *) &see_invisible, sizeof(see_invisible));
183: r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
184: r_read(fp, (char *) &wizard, sizeof(wizard));
185: r_read(fp, (char *) &score_only, sizeof(score_only));
186: r_read(fp, (char *) &m_moves, sizeof(m_moves));
187: r_read(fp, (char *) &saved_time, sizeof(saved_time));
188:
189: if (fread(buf, sizeof(char), 1, fp) > 0) {
190: clear();
191: clean_up("extra characters in file");
192: }
193:
194: md_gfmt(fname, &mod_time); /* get file modification time */
195:
196: if (has_been_touched(&saved_time, &mod_time)) {
197: clear();
198: clean_up("sorry, file has been touched");
199: }
200: if ((!wizard) && !md_df(fname)) {
201: clean_up("cannot delete file");
202: }
203: msg_cleared = 0;
204: ring_stats(0);
205: fclose(fp);
206: }
207:
208: write_pack(pack, fp)
209: object *pack;
210: FILE *fp;
211: {
212: object t;
213:
214: while (pack = pack->next_object) {
215: r_write(fp, (char *) pack, sizeof(object));
216: }
217: t.ichar = t.what_is = 0;
218: r_write(fp, (char *) &t, sizeof(object));
219: }
220:
221: read_pack(pack, fp, is_rogue)
222: object *pack;
223: FILE *fp;
224: boolean is_rogue;
225: {
226: object read_obj, *new_obj;
227:
228: for (;;) {
229: r_read(fp, (char *) &read_obj, sizeof(object));
230: if (read_obj.ichar == 0) {
231: pack->next_object = (object *) 0;
232: break;
233: }
234: new_obj = alloc_object();
235: *new_obj = read_obj;
236: if (is_rogue) {
237: if (new_obj->in_use_flags & BEING_WORN) {
238: do_wear(new_obj);
239: } else if (new_obj->in_use_flags & BEING_WIELDED) {
240: do_wield(new_obj);
241: } else if (new_obj->in_use_flags & (ON_EITHER_HAND)) {
242: do_put_on(new_obj,
243: ((new_obj->in_use_flags & ON_LEFT_HAND) ? 1 : 0));
244: }
245: }
246: pack->next_object = new_obj;
247: pack = new_obj;
248: }
249: }
250:
251: rw_dungeon(fp, rw)
252: FILE *fp;
253: boolean rw;
254: {
255: short i, j;
256: char buf[DCOLS];
257:
258: for (i = 0; i < DROWS; i++) {
259: if (rw) {
260: r_write(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
261: for (j = 0; j < DCOLS; j++) {
262: buf[j] = mvinch(i, j);
263: }
264: r_write(fp, buf, DCOLS);
265: } else {
266: r_read(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
267: r_read(fp, buf, DCOLS);
268: for (j = 0; j < DCOLS; j++) {
269: mvaddch(i, j, buf[j]);
270: }
271: }
272: }
273: }
274:
275: rw_id(id_table, fp, n, wr)
276: struct id id_table[];
277: FILE *fp;
278: int n;
279: boolean wr;
280: {
281: short i;
282:
283: for (i = 0; i < n; i++) {
284: if (wr) {
285: r_write(fp, (char *) &(id_table[i].value), sizeof(short));
286: r_write(fp, (char *) &(id_table[i].id_status),
287: sizeof(unsigned short));
288: write_string(id_table[i].title, fp);
289: } else {
290: r_read(fp, (char *) &(id_table[i].value), sizeof(short));
291: r_read(fp, (char *) &(id_table[i].id_status),
292: sizeof(unsigned short));
293: read_string(id_table[i].title, fp);
294: }
295: }
296: }
297:
298: write_string(s, fp)
299: char *s;
300: FILE *fp;
301: {
302: short n;
303:
304: n = strlen(s) + 1;
305: xxxx(s, n);
306: r_write(fp, (char *) &n, sizeof(short));
307: r_write(fp, s, n);
308: }
309:
310: read_string(s, fp)
311: char *s;
312: FILE *fp;
313: {
314: short n;
315:
316: r_read(fp, (char *) &n, sizeof(short));
317: r_read(fp, s, n);
318: xxxx(s, n);
319: }
320:
321: rw_rooms(fp, rw)
322: FILE *fp;
323: boolean rw;
324: {
325: short i;
326:
327: for (i = 0; i < MAXROOMS; i++) {
328: rw ? r_write(fp, (char *) (rooms + i), sizeof(room)) :
329: r_read(fp, (char *) (rooms + i), sizeof(room));
330: }
331: }
332:
333: r_read(fp, buf, n)
334: FILE *fp;
335: char *buf;
336: int n;
337: {
338: if (fread(buf, sizeof(char), n, fp) != n) {
339: clean_up("read() failed, don't know why");
340: }
341: }
342:
343: r_write(fp, buf, n)
344: FILE *fp;
345: char *buf;
346: int n;
347: {
348: if (!write_failed) {
349: if (fwrite(buf, sizeof(char), n, fp) != n) {
350: message("write() failed, don't know why", 0);
351: sound_bell();
352: write_failed = 1;
353: }
354: }
355: }
356:
357: boolean
358: has_been_touched(saved_time, mod_time)
359: struct rogue_time *saved_time, *mod_time;
360: {
361: if (saved_time->year < mod_time->year) {
362: return(1);
363: } else if (saved_time->year > mod_time->year) {
364: return(0);
365: }
366: if (saved_time->month < mod_time->month) {
367: return(1);
368: } else if (saved_time->month > mod_time->month) {
369: return(0);
370: }
371: if (saved_time->day < mod_time->day) {
372: return(1);
373: } else if (saved_time->day > mod_time->day) {
374: return(0);
375: }
376: if (saved_time->hour < mod_time->hour) {
377: return(1);
378: } else if (saved_time->hour > mod_time->hour) {
379: return(0);
380: }
381: if (saved_time->minute < mod_time->minute) {
382: return(1);
383: } else if (saved_time->minute > mod_time->minute) {
384: return(0);
385: }
386: if (saved_time->second < mod_time->second) {
387: return(1);
388: }
389: return(0);
390: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.