Wikihack
Advertisement

Below is the full text to restore.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/restore.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)restore.c	3.0	88/10/25
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    #include "lev.h"
7.    
8.    #ifdef WORM
9.    #include "wseg.h"
10.   #endif
11.   
12.   boolean restoring = FALSE;
13.   static struct fruit *oldfruit;
14.   static long omoves;
15.   
16.   /*
17.    * "stuff" objects back into containers (relink the fcobj list).
18.    */
19.   static void
20.   stuff_objs(cobj)
21.   register struct obj *cobj;
22.   {
23.   	register struct obj *otmp, *otmp2;
24.   
25.   	for(; cobj; cobj = cobj->nobj)
26.   	    if(Is_container(cobj))
27.   
28.   		for(otmp = cobj->nobj;
29.   		    otmp && otmp->cobj == (struct obj *) -1; otmp = otmp2) {
30.   
31.   		    otmp2 = otmp->nobj;
32.   
33.   		    otmp->cobj = cobj;
34.   		    cobj->nobj = otmp2;
35.   		    otmp->nobj = fcobj;
36.   		    fcobj = otmp;
37.   		}
38.   }
39.   
40.   static struct obj *
41.   restobjchn(fd, ghostly)
42.   register int fd;
43.   boolean ghostly;
44.   {
45.   	register struct obj *otmp, *otmp2;
46.   	register struct obj *first = 0;
47.   	register struct fruit *oldf;
48.   	int xl;
49.   #ifdef LINT
50.   	/* suppress "used before set" warning from lint */
51.   	otmp2 = 0;
52.   #endif
53.   	while(1) {
54.   		mread(fd, (genericptr_t) &xl, sizeof(xl));
55.   		if(xl == -1) break;
56.   		otmp = newobj(xl);
57.   		if(!first) first = otmp;
58.   		else otmp2->nobj = otmp;
59.   		mread(fd, (genericptr_t) otmp, (unsigned) xl + sizeof(struct obj));
60.   		if(!otmp->o_id) otmp->o_id = flags.ident++;
61.   		if(ghostly && otmp->otyp == SLIME_MOLD) {
62.   			for(oldf=oldfruit; oldf; oldf=oldf->nextf)
63.   				if (oldf->fid == otmp->spe) break;
64.   			if(!oldf) impossible("no old fruit?");
65.   			else otmp->spe = fruitadd(oldf->fname);
66.   		}
67.   	/* Ghost levels get object age shifted from old player's clock to
68.   	 * new player's clock.  Assumption: new player arrived immediately
69.   	 * after old player died.
70.   	 */
71.   		if (ghostly) otmp->age = moves-omoves+otmp->age;
72.   		otmp2 = otmp;
73.   	}
74.   	if(first && otmp2->nobj){
75.   		impossible("Restobjchn: error reading objchn.");
76.   		otmp2->nobj = 0;
77.   	}
78.   
79.   	stuff_objs(first);
80.   	return(first);
81.   }
82.   
83.   static struct monst *
84.   restmonchn(fd, ghostly)
85.   register int fd;
86.   boolean ghostly;
87.   {
88.   	register struct monst *mtmp, *mtmp2;
89.   	register struct monst *first = 0;
90.   	int xl;
91.   
92.   	struct permonst *monbegin;
93.   	off_t differ;
94.   
95.   	mread(fd, (genericptr_t)&monbegin, sizeof(monbegin));
96.   #ifndef MSDOS
97.   	differ = (genericptr_t)(&mons[0]) - (genericptr_t)(monbegin);
98.   #else
99.   	differ = (long)(&mons[0]) - (long)(monbegin);
100.  #endif
101.  
102.  #ifdef LINT
103.  	/* suppress "used before set" warning from lint */
104.  	mtmp2 = 0;
105.  #endif
106.  	while(1) {
107.  		mread(fd, (genericptr_t) &xl, sizeof(xl));
108.  		if(xl == -1) break;
109.  		mtmp = newmonst(xl);
110.  		if(!first) first = mtmp;
111.  		else mtmp2->nmon = mtmp;
112.  		mread(fd, (genericptr_t) mtmp, (unsigned) xl + sizeof(struct monst));
113.  		if(!mtmp->m_id)
114.  			mtmp->m_id = flags.ident++;
115.  #ifndef MSDOS
116.  		/*ANSI type for differ is ptrdiff_t - long may be wrong*/
117.  		/*for segmented architecture - may be better to cast pointers*/
118.  		/*to (struct permonst *) rather than (genericptr_t)*/
119.  		/*this code handles save file -  so any bug should glow*/
120.  		/*probably best not to keep lint from complaining*/
121.  /*#ifdef LINT	/*possible compiler/hardware dependency - */
122.  /*		if (differ) mtmp->data = NULL;*/
123.  /*#else*/
124.  		mtmp->data = (struct permonst *)
125.  			((genericptr_t)mtmp->data + differ);
126.  /*#endif	/*LINT*/
127.  #else
128.  		mtmp->data = (struct permonst *)
129.  			((long) mtmp->data + differ);
130.  #endif
131.  		if(mtmp->minvent)
132.  			mtmp->minvent = restobjchn(fd, ghostly);
133.  		mtmp2 = mtmp;
134.  	}
135.  	if(first && mtmp2->nmon){
136.  		impossible("Restmonchn: error reading monchn.");
137.  		mtmp2->nmon = 0;
138.  	}
139.  	return(first);
140.  }
141.  
142.  static void
143.  restgenoinfo(fd)
144.  register int fd;
145.  {
146.  	register int i;
147.  
148.  	for (i = 0; i < NUMMONS; i++)
149.  		mread(fd, (genericptr_t) &(mons[i].geno), sizeof(unsigned));
150.  }
151.  
152.  int
153.  dorecover(fd)
154.  register int fd;
155.  {
156.  	register int nfd;
157.  	int tmp;		/* not a register ! */
158.  	xchar ltmp;
159.  	unsigned int mid;		/* idem */
160.  	struct obj *otmp;
161.  	struct fruit *fruit;
162.  #ifdef MSDOS
163.  	struct flag oldflags;
164.  
165.  	oldflags = flags;	/* Save flags set in the config file */
166.  #endif
167.  #ifdef ZEROCOMP
168.  	minit();
169.  #endif
170.  	restoring = TRUE;
171.  	getlev(fd, 0, (xchar)0, FALSE);
172.  	invent = restobjchn(fd, FALSE);
173.  	for(otmp = invent; otmp; otmp = otmp->nobj)
174.  		if(otmp->owornmask)
175.  			setworn(otmp, otmp->owornmask);
176.  	fallen_down = restmonchn(fd, FALSE);
177.  	restgenoinfo(fd);
178.  	mread(fd, (genericptr_t) &tmp, sizeof tmp);
179.  #ifdef WIZARD
180.  	if(!wizard)
181.  #endif
182.  	    if(tmp != getuid()) {		/* strange ... */
183.  		(void) close(fd);
184.  		(void) unlink(SAVEF);
185.  		(void) puts("Saved game was not yours.");
186.  		restoring = FALSE;
187.  		return(0);
188.  	    }
189.  	mread(fd, (genericptr_t) &flags, sizeof(struct flag));
190.  	/* Some config file OPTIONS take precedence over those in save file.
191.  	 */
192.  #ifdef MSDOS
193.  #ifdef DGK
194.  	flags.rawio = oldflags.rawio;
195.  #ifdef DECRAINBOW
196.  	flags.DECRainbow = oldflags.DECRainbow;
197.  #endif /* DECRAINBOW */
198.  	flags.IBMBIOS = oldflags.IBMBIOS;
199.  #endif
200.  #endif
201.  	mread(fd, (genericptr_t) &dlevel, sizeof dlevel);
202.  	mread(fd, (genericptr_t) &maxdlevel, sizeof maxdlevel);
203.  	mread(fd, (genericptr_t) &moves, sizeof moves);
204.  	mread(fd, (genericptr_t) &wiz_level, sizeof wiz_level);
205.  	mread(fd, (genericptr_t) &medusa_level, sizeof medusa_level);
206.  #ifdef ORACLE
207.  	mread(fd, (genericptr_t) &oracle_level, sizeof oracle_level);
208.  #endif
209.  #ifdef REINCARNATION
210.  	mread(fd, (genericptr_t) &rogue_level, sizeof rogue_level);
211.  	if (dlevel==rogue_level)
212.  		savesyms = showsyms;
213.  #endif
214.  #ifdef STRONGHOLD
215.  	mread(fd, (genericptr_t) &stronghold_level, sizeof stronghold_level);
216.  	mread(fd, (genericptr_t) &tower_level, sizeof tower_level);
217.  	mread(fd, (genericptr_t) tune, sizeof tune);
218.  #  ifdef MUSIC
219.  	mread(fd, (genericptr_t) &music_heard, sizeof music_heard);
220.  #  endif
221.  #endif
222.  	mread(fd, (genericptr_t) &is_maze_lev, sizeof is_maze_lev);
223.  	mread(fd, (genericptr_t) &u, sizeof(struct you));
224.  #ifdef SPELLS
225.  	mread(fd, (genericptr_t) spl_book, sizeof(struct spell) * (MAXSPELL + 1));
226.  #endif
227.  	if(u.ustuck)
228.  		mread(fd, (genericptr_t) &mid, sizeof mid);
229.  	mread(fd, (genericptr_t) pl_character, sizeof pl_character);
230.  	mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
231.  	mread(fd, (genericptr_t) &current_fruit, sizeof current_fruit);
232.  	ffruit = 0;
233.  	while (fruit = newfruit(),
234.  	       mread(fd, (genericptr_t)fruit, sizeof(struct fruit)),
235.  	       fruit->fid) {
236.  		fruit->nextf = ffruit;
237.  		ffruit = fruit;
238.  	}
239.  	free((genericptr_t) fruit);
240.  
241.  	restnames(fd);
242.  #ifdef DGK
243.  	msmsg("\n");
244.  	cl_end();
245.  	msmsg("You got as far as level %d%s.\n", maxdlevel,
246.  		flags.debug ? " in WIZARD mode" :
247.  		flags.explore ? " in discovery mode" : "");
248.  	cl_end();
249.  	msmsg("Restoring: ");
250.  #endif
251.  	while(1) {
252.  #ifdef ZEROCOMP
253.  		if(mread(fd, (genericptr_t) &ltmp, sizeof ltmp) < 0)
254.  #else
255.  		if(read(fd, (genericptr_t) &ltmp, sizeof ltmp) != sizeof ltmp)
256.  #endif
257.  			break;
258.  		getlev(fd, 0, ltmp, FALSE);
259.  		glo(ltmp);
260.  #ifdef DGK
261.  		msmsg(".");
262.  #endif
263.  #if defined(MSDOS) && !defined(TOS)
264.  		nfd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
265.  #else
266.  		nfd = creat(lock, FCMASK);
267.  #endif
268.  		if (nfd < 0)	panic("Cannot open temp file %s!\n", lock);
269.  #if defined(DGK) && !defined(TOS)
270.  		if (!savelev(nfd, ltmp, COUNT | WRITE)) {
271.  
272.  			/* The savelev can't proceed because the size required
273.  			 * is greater than the available disk space.
274.  			 */
275.  			msmsg("\nNot enough space on `%s' to restore your game.\n",
276.  				levels);
277.  
278.  			/* Remove levels and bones that may have been created.
279.  			 */
280.  			(void) close(nfd);
281.  			eraseall(levels, alllevels);
282.  			eraseall(levels, allbones);
283.  
284.  			/* Perhaps the person would like to play without a
285.  			 * RAMdisk.
286.  			 */
287.  			if (ramdisk) {
288.  				/* PlaywoRAMdisk may not return, but if it does
289.  				 * it is certain that ramdisk will be 0.
290.  				 */
291.  				playwoRAMdisk();
292.  				/* Rewind save file and try again */
293.  				(void) lseek(fd, (off_t)0, 0);
294.  				return dorecover(fd);
295.  			} else {
296.  				msmsg("Be seeing you...\n");
297.  				exit(0);
298.  			}
299.  		}
300.  #else
301.  		savelev(nfd, ltmp);
302.  #endif
303.  #ifdef ZEROCOMP
304.  		bflush(nfd);
305.  #endif
306.  		(void) close(nfd);
307.  	}
308.  #ifdef BSD
309.  	(void) lseek(fd, 0L, 0);
310.  #else
311.  	(void) lseek(fd, (off_t)0, 0);
312.  #endif
313.  #ifdef ZEROCOMP
314.  	minit();
315.  #endif
316.  	getlev(fd, 0, (xchar)0, FALSE);
317.  	(void) close(fd);
318.  #ifdef EXPLORE_MODE
319.  	if(!discover)
320.  #endif
321.  		(void) unlink(SAVEF);
322.  #ifdef REINCARNATION
323.  	/* this can't be done earlier because we need to check the initial
324.  	 * showsyms against the one saved in each of the non-rogue levels */
325.  	if (dlevel==rogue_level)
326.  		showsyms = defsyms;
327.  #endif
328.  	if(u.ustuck) {
329.  		register struct monst *mtmp;
330.  
331.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
332.  			if(mtmp->m_id == mid) goto monfnd;
333.  		panic("Cannot find the monster ustuck.");
334.  	monfnd:
335.  		u.ustuck = mtmp;
336.  	}
337.  	setsee();  /* only to recompute seelx etc. - these weren't saved */
338.  #ifdef DGK
339.  	gameDiskPrompt();
340.  #endif
341.  	max_rank_sz(); /* to recompute mrank_sz (pri.c) */
342.  #ifdef POLYSELF
343.  	set_uasmon();
344.  #endif
345.  	/* take care of iron ball & chain */
346.  	for(otmp = fobj; otmp; otmp = otmp->nobj)
347.  		if(otmp->owornmask)
348.  			setworn(otmp, otmp->owornmask);
349.  	docrt();
350.  	restoring = FALSE;
351.  	return(1);
352.  }
353.  
354.  void
355.  getlev(fd, pid, lev, ghostly)
356.  int fd, pid;
357.  xchar lev;
358.  boolean ghostly;
359.  {
360.  	register struct gold *gold;
361.  	register struct trap *trap;
362.  #ifdef WORM
363.  	register struct wseg *wtmp;
364.  	register int tmp;
365.  #endif
366.  	long nhp;
367.  	int hpid;
368.  	xchar dlvl;
369.  	struct symbols osymbol;
370.  	int x, y;
371.  	uchar osym, nsym;
372.  #ifdef TOS
373.  	short tlev;
374.  #endif
375.  
376.  #ifdef MSDOS
377.  	setmode(fd, O_BINARY);	    /* is this required for TOS??? */
378.  #endif
379.  	/* Load the old fruit info.  We have to do it first, so the infor-
380.  	 * mation is available when restoring the objects.  
381.  	 */
382.  	if (ghostly) {
383.  		struct fruit *fruit;
384.  
385.  		oldfruit = 0;
386.  		while (fruit = newfruit(),
387.  		       mread(fd, (genericptr_t)fruit, sizeof(struct fruit)),
388.  		       fruit->fid) {
389.  			fruit->nextf = oldfruit;
390.  			oldfruit = fruit;
391.  		}
392.  		free((genericptr_t) fruit);
393.  	}
394.  
395.  	/* First some sanity checks */
396.  	mread(fd, (genericptr_t) &hpid, sizeof(hpid));
397.  #ifdef TOS
398.  	mread(fd, (genericptr_t) &tlev, sizeof(tlev));
399.  	dlvl=tlev&0xff;
400.  #else
401.  	mread(fd, (genericptr_t) &dlvl, sizeof(dlvl));
402.  #endif
403.  	if((pid && pid != hpid) || (lev && dlvl != lev)) {
404.  		pline("Strange, this map is not as I remember it.");
405.  		pline("Somebody is trying some trickery here...");
406.  		pline("This game is void.");
407.  		done("tricked");
408.  	}
409.  
410.  	mread(fd, (genericptr_t) levl, sizeof(levl));
411.  	mread(fd, (genericptr_t) &osymbol, sizeof(osymbol));
412.  	if (memcmp((genericptr_t) &osymbol,
413.  		   (genericptr_t) &showsyms, sizeof (struct symbols))
414.  #ifdef REINCARNATION
415.  		&& dlvl != rogue_level
416.  		/* rogue level always uses default syms, and showsyms will still
417.  		 * have its initial value from environment when restoring a
418.  		 * game */
419.  #endif
420.  	    ) {
421.  		for (x = 0; x < COLNO; x++)
422.  			for (y = 0; y < ROWNO; y++) {
423.  				osym = levl[x][y].scrsym;
424.  				nsym = 0;
425.  				switch (levl[x][y].typ) {
426.  				case STONE:
427.  				case SCORR:
428.  					if (osym == osymbol.stone)
429.  						nsym = showsyms.stone;
430.  					break;
431.  				case ROOM:
432.  #ifdef STRONGHOLD
433.  				case DRAWBRIDGE_DOWN:
434.  #endif /* STRONGHOLD /**/
435.  					if (osym == osymbol.room)
436.  						nsym = showsyms.room;
437.  					break;
438.  				case DOOR:
439.  					if (osym == osymbol.door)
440.  						nsym = showsyms.door;
441.  					break;
442.  				case CORR:
443.  					if (osym == osymbol.corr)
444.  						nsym = showsyms.corr;
445.  					break;
446.  				case VWALL:
447.  					if (osym == osymbol.vwall)
448.  						nsym = showsyms.vwall;
449.  #ifdef STRONGHOLD
450.  					else if (osym == osymbol.dbvwall)
451.  						nsym = showsyms.dbvwall;
452.  #endif
453.  					break;
454.  				case HWALL:
455.  					if (osym == osymbol.hwall)
456.  						nsym = showsyms.hwall;
457.  #ifdef STRONGHOLD
458.  					else if (osym == osymbol.dbhwall)
459.  						nsym = showsyms.dbhwall;
460.  #endif
461.  					break;
462.  				case TLCORNER:
463.  					if (osym == osymbol.tlcorn)
464.  						nsym = showsyms.tlcorn;
465.  					break;
466.  				case TRCORNER:
467.  					if (osym == osymbol.trcorn)
468.  						nsym = showsyms.trcorn;
469.  					break;
470.  				case BLCORNER:
471.  					if (osym == osymbol.blcorn)
472.  						nsym = showsyms.blcorn;
473.  					break;
474.  				case BRCORNER:
475.  					if (osym == osymbol.brcorn)
476.  						nsym = showsyms.brcorn;
477.  					break;
478.  				case SDOOR:
479.  					if (osym == osymbol.vwall)
480.  						nsym = showsyms.vwall;
481.  					else if (osym == osymbol.hwall)
482.  						nsym = showsyms.hwall;
483.  					break;
484.  				case CROSSWALL:
485.  					if (osym == osymbol.crwall)
486.  						nsym = showsyms.crwall;
487.  					break;
488.  				case TUWALL:
489.  					if (osym == osymbol.tuwall)
490.  						nsym = showsyms.tuwall;
491.  					break;
492.  				case TDWALL:
493.  					if (osym == osymbol.tdwall)
494.  						nsym = showsyms.tdwall;
495.  					break;
496.  				case TLWALL:
497.  					if (osym == osymbol.tlwall)
498.  						nsym = showsyms.tlwall;
499.  					break;
500.  				case TRWALL:
501.  					if (osym == osymbol.trwall)
502.  						nsym = showsyms.trwall;
503.  					break;
504.  				case STAIRS:
505.  					if (osym == osymbol.upstair)
506.  						nsym = showsyms.upstair;
507.  					else if (osym == osymbol.dnstair)
508.  						nsym = showsyms.dnstair;
509.  					break;
510.  #ifdef STRONGHOLD
511.  				case LADDER:
512.  					if (osym == osymbol.upladder)
513.  						nsym = showsyms.upladder;
514.  					else if (osym == osymbol.dnladder)
515.  						nsym = showsyms.dnladder;
516.  					break;
517.  #endif /* STRONGHOLD /**/
518.  				case POOL:
519.  				case MOAT:
520.  #ifdef STRONGHOLD
521.  				case DRAWBRIDGE_UP:
522.  #endif /* STRONGHOLD /**/
523.  					if (osym == osymbol.pool)
524.  						nsym = showsyms.pool;
525.  					break;
526.  #ifdef FOUNTAINS
527.  				case FOUNTAIN:
528.  					if (osym == osymbol.fountain)
529.  						nsym = showsyms.fountain;
530.  					break;
531.  #endif /* FOUNTAINS /**/
532.  #ifdef THRONES
533.  				case THRONE:
534.  					if (osym == osymbol.throne)
535.  						nsym = showsyms.throne;
536.  					break;
537.  #endif /* THRONES /**/
538.  #ifdef SINKS
539.  				case SINK:
540.  					if (osym == osymbol.sink)
541.  						nsym = showsyms.sink;
542.  					break;
543.  #endif /* SINKS /**/
544.  #ifdef ALTARS
545.  				case ALTAR:
546.  					if (osym == osymbol.altar)
547.  						nsym = showsyms.altar;
548.  					break;
549.  #endif /* ALTARS /**/
550.  				default:
551.  					break;
552.  				}
553.  				if (nsym)
554.  					levl[x][y].scrsym = nsym;
555.  			}
556.  	}
557.  
558.  	mread(fd, (genericptr_t)&omoves, sizeof(omoves));
559.  	mread(fd, (genericptr_t)&xupstair, sizeof(xupstair));
560.  	mread(fd, (genericptr_t)&yupstair, sizeof(yupstair));
561.  	mread(fd, (genericptr_t)&xdnstair, sizeof(xdnstair));
562.  	mread(fd, (genericptr_t)&ydnstair, sizeof(ydnstair));
563.  #ifdef STRONGHOLD
564.  	mread(fd, (genericptr_t)&xupladder, sizeof(xupladder));
565.  	mread(fd, (genericptr_t)&yupladder, sizeof(yupladder));
566.  	mread(fd, (genericptr_t)&xdnladder, sizeof(xdnladder));
567.  	mread(fd, (genericptr_t)&ydnladder, sizeof(ydnladder));
568.  #endif
569.  	mread(fd, (genericptr_t)&fountsound, sizeof(fountsound));
570.  	mread(fd, (genericptr_t)&sinksound, sizeof(sinksound));
571.  	fmon = restmonchn(fd, ghostly);
572.  
573.  	/* regenerate animals while on another level */
574.  	{ long tmoves = (moves > omoves) ? moves-omoves : 0;
575.  	  register struct monst *mtmp, *mtmp2;
576.  
577.  	  for(mtmp = fmon; mtmp; mtmp = mtmp2) {
578.  
579.  		mtmp2 = mtmp->nmon;
580.  		if(mtmp->data->geno & G_GENOD) {
581.  			mondead(mtmp);
582.  			continue;
583.  		}
584.  
585.  		if (ghostly) {
586.  			/* reset peaceful/malign relative to new character */
587.  			if(!mtmp->isshk)
588.  				/* shopkeepers will reset based on name */
589.  				mtmp->mpeaceful = peace_minded(mtmp->data);
590.  			set_malign(mtmp);
591.  		} else if (mtmp->mtame && tmoves > 250)
592.  		  	mtmp->mtame = mtmp->mpeaceful = 0;
593.  
594.  		/* restore shape changers - Maarten Jan Huisjes */
595.  		if (mtmp->data == &mons[PM_CHAMELEON]
596.  		    && !Protection_from_shape_changers
597.  		    && !mtmp->cham)
598.  			mtmp->cham = 1;
599.  		else if(Protection_from_shape_changers) {
600.  			if (mtmp->cham) {
601.  				mtmp->cham = 0;
602.  				(void) newcham(mtmp, &mons[PM_CHAMELEON]);
603.  			} else if(is_were(mtmp->data) && !is_human(mtmp->data))
604.  				(void) new_were(mtmp);
605.  		}
606.  
607.  		if (!ghostly) {
608.  			nhp = mtmp->mhp +
609.  				(regenerates(mtmp->data) ? tmoves : tmoves/20);
610.  			if(nhp > mtmp->mhpmax)
611.  				mtmp->mhp = mtmp->mhpmax;
612.  			else
613.  #ifdef LINT	/* (long)newhp -> (schar = short int) mhp; ok in context of text above */
614.  				mtmp->mhp = 0;
615.  #else
616.  				mtmp->mhp = nhp;
617.  #endif
618.  		}
619.  	  }
620.  	}
621.  
622.  	setgd();
623.  	fgold = 0;
624.  	while(gold = newgold(),
625.  	      mread(fd, (genericptr_t)gold, sizeof(struct gold)),
626.  	      gold->gx) {
627.  		gold->ngold = fgold;
628.  		fgold = gold;
629.  	}
630.  	free((genericptr_t) gold);
631.  	ftrap = 0;
632.  	while (trap = newtrap(),
633.  	       mread(fd, (genericptr_t)trap, sizeof(struct trap)),
634.  	       trap->tx) {
635.  		trap->ntrap = ftrap;
636.  		ftrap = trap;
637.  	}
638.  	free((genericptr_t) trap);
639.  	fobj = restobjchn(fd, ghostly);
640.  	billobjs = restobjchn(fd, ghostly);
641.  	rest_engravings(fd);
642.  	mread(fd, (genericptr_t)rooms, sizeof(rooms));
643.  	mread(fd, (genericptr_t)doors, sizeof(doors));
644.  #ifdef WORM
645.  	mread(fd, (genericptr_t)wsegs, sizeof(wsegs));
646.  	for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
647.  		wheads[tmp] = wsegs[tmp] = wtmp = newseg();
648.  		while(1) {
649.  			mread(fd, (genericptr_t)wtmp, sizeof(struct wseg));
650.  			if(!wtmp->nseg) break;
651.  			wheads[tmp]->nseg = wtmp = newseg();
652.  			wheads[tmp] = wtmp;
653.  		}
654.  	}
655.  	mread(fd, (genericptr_t)wgrowtime, sizeof(wgrowtime));
656.  #endif
657.  	/* Now get rid of all the temp fruits... */
658.  	if (ghostly) {
659.  		struct fruit *fruit;
660.  
661.  		while(oldfruit) {
662.  			fruit = oldfruit->nextf;
663.  			free((genericptr_t) oldfruit);
664.  			oldfruit = fruit;
665.  		}
666.  	}
667.  }
668.  
669.  #ifdef ZEROCOMP
670.  #define RLESC '\0' 	/* Leading character for run of RLESC's */
671.  
672.  static unsigned char inbuf[BUFSZ];
673.  static unsigned short inbufp = 0;
674.  static unsigned short inbufsz = 0;
675.  static short inrunlength = -1;
676.  static int mreadfd;
677.  
678.  static int
679.  mgetc()
680.  {
681.      if (inbufp >= inbufsz) {
682.        inbufsz = read(mreadfd, (genericptr_t)inbuf, (int)sizeof inbuf);
683.        if (!inbufsz) {
684.  	  if (inbufp > sizeof inbuf)
685.  	      error("EOF on file #%d.\n", mreadfd);
686.  	  inbufp = 1 + sizeof inbuf;  /* exactly one warning :-) */
687.  	  return -1;
688.        }
689.        inbufp = 0;
690.      }
691.      return inbuf[inbufp++];
692.  }
693.  
694.  void
695.  minit()
696.  {
697.      inbufsz = 0;
698.      inbufp = 0;
699.      inrunlength = -1;
700.  }
701.  
702.  int
703.  mread(fd, buf, len)
704.  int fd;
705.  register genericptr_t buf;
706.  register unsigned len;
707.  {
708.      /*register int readlen = 0;*/
709.      mreadfd = fd;
710.      while (len--) {
711.        if (inrunlength > 0) {
712.  	  inrunlength--;
713.  	  *((char *)buf)++ = '\0';
714.        } else {
715.  	  register short ch = mgetc();
716.  	  if (ch < 0) return -1; /*readlen;*/
717.  	  if ((*((char *)buf)++ = ch) == RLESC) {
718.  	      inrunlength = mgetc();
719.  	  }
720.        }
721.        /*readlen++;*/
722.      }
723.      return 0; /*readlen;*/
724.  }
725.  
726.  #else /* ZEROCOMP */
727.  
728.  void
729.  mread(fd, buf, len)
730.  register int fd;
731.  register genericptr_t buf;
732.  register unsigned int len;
733.  {
734.  	register int rlen;
735.  
736.  #if defined(BSD) || defined(ULTRIX)
737.  	rlen = read(fd, buf, (int) len);
738.  	if(rlen != len){
739.  #else /* e.g. SYSV, __TURBOC__ */
740.  	rlen = read(fd, buf, (unsigned) len);
741.  	if((unsigned)rlen != len){
742.  #endif
743.  		pline("Read %d instead of %u bytes.\n", rlen, len);
744.  		if(restoring) {
745.  			(void) unlink(SAVEF);
746.  			error("Error restoring old game.");
747.  		}
748.  		panic("Error reading level file.");
749.  	}
750.  }
751.  #endif /* ZEROCOMP */
Advertisement