Source:NetHack 3.0.0/restore.c
Revision as of 05:21, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/restore.c moved to Source:NetHack 3.0.0/restore.c: Robot: moved page)
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.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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) ¤t_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) <mp, sizeof ltmp) < 0) 254. #else 255. if(read(fd, (genericptr_t) <mp, 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 */