home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume10 / nethack3p9 / part37 < prev    next >
Internet Message Format  |  1990-07-27  |  60KB

  1. Path: uunet!mailrus!cornell!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v10i082:  nethack3p9 -  display oriented dungeons & dragons (Ver. 3.0i), Part37/56
  5. Message-ID: <5940@tekred.CNA.TEK.COM>
  6. Date: 12 Jul 90 16:09:25 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2355
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 10, Issue 82
  13. Archive-name: nethack3p9/Part37
  14. Supersedes: NetHack3: Volume 7, Issue 56-93
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 37 (of 56)."
  25. # Contents:  others/Makefile.tcc others/pcmain.c src/save.c
  26. # Wrapped by billr@saab on Wed Jul 11 17:11:47 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'others/Makefile.tcc' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'others/Makefile.tcc'\"
  30. else
  31. echo shar: Extracting \"'others/Makefile.tcc'\" \(15565 characters\)
  32. sed "s/^X//" >'others/Makefile.tcc' <<'END_OF_FILE'
  33. X#    SCCS Id: @(#)Makefile.tcc    3.0    89/11/20
  34. X#    PC NetHack 3.0 Makefile for Turbo C 2.0
  35. X#    Perpetrator: Mike Threepoint, 890707
  36. X
  37. X###
  38. X### Locals
  39. X###
  40. X# the name of the game
  41. XGAME    = nethack
  42. X
  43. X# the place of the game
  44. XGAMEDIR = \games\$(GAME)
  45. X
  46. X# the filename of the game
  47. XGAMEFILE = $(GAMEDIR)\$(GAME).exe
  48. X
  49. X
  50. X###
  51. X### Directories
  52. X###
  53. X# makedefs.c hardcodes the include and auxil directories, don't change them.
  54. XOBJ    = o
  55. XINCL    = ..\include
  56. XAUX    = ..\auxil
  57. XSRC    = ..\src
  58. XOTHERS    = ..\others
  59. X
  60. X# where the Turbo C libraries are kept
  61. XLIB     = \turbo\c\lib
  62. X
  63. X# directory NDMAKE uses for temporary files
  64. XMAKE_TMP = $(TMP)
  65. X
  66. X
  67. X###
  68. X### Compiler
  69. X###
  70. XCC    = tcc
  71. X
  72. X# must use Huge model; Large is limited to 64K total global data.
  73. XMODEL   = h
  74. X
  75. X# signed chars, jump optimize, strict ANSI, register optimize, no stack frame
  76. XCFLAGS    = -c -no -m$(MODEL) -I$(INCL) -K- -O -A -Z -k- -w-pia -w-pro $(WIZARD)
  77. X## Note: Turbo C 2.0's -Z is bugged.  If you have weird problems, try -Z-.
  78. X
  79. X# wizardly defines
  80. XWIZARD  =
  81. X
  82. X# linkers
  83. XTLINK    = tlink
  84. XLINK    = link
  85. X## There is a bug in TLINK and huge model:
  86. X##
  87. X## TLINK 1.0 treated huge like large, with 64K data limit.
  88. X## TLINK 1.1 fixed that, but chokes over huge data segments anyway.
  89. X## TLINK 2.0 links and is smaller than LINK /EXEPACK, but for some
  90. X## reason with too many objects it produces a file that freaks out
  91. X## and hangs the system.
  92. X##
  93. X## Also note:
  94. X##
  95. X## Using /EXEPACK with LINK will greatly reduce the size of the
  96. X## executable (about 50K), it will also greatly increase the memory
  97. X## required to load it (about 20K).
  98. X
  99. XLIBS    = $(LIB)\c$(MODEL)
  100. X# no need to link in the floating point library
  101. XC0    = $(LIB)\c0$(MODEL).obj
  102. X
  103. XLFLAGS    = /noi /seg:1024
  104. XTLFLAGS = /x/c
  105. X
  106. X# assembler
  107. XASM    = tasm
  108. XAFLAGS    = /MX
  109. X
  110. X# yacc/lex
  111. XYACC    = bison
  112. XLEX    = flex
  113. X
  114. X
  115. X###
  116. X### Rules
  117. X###
  118. X# search order
  119. X.SUFFIXES: .exe .obj .c .asm .y .l
  120. X
  121. X# .l -> .c (for flex)
  122. X.l.c:
  123. X    $(LEX) $<
  124. X    del $@
  125. X    ren lex.yyc $@
  126. X# .y -> .c (for bison)
  127. X.y.c:
  128. X    $(YACC) $<
  129. X    del $@
  130. X    ren y.tbc $@
  131. X    del $*.h
  132. X    ren y.tbh $*.h
  133. X# .c -> .obj
  134. X.c.obj:
  135. X    $(CC) $(CFLAGS) -c $<
  136. X# .asm -> .obj
  137. X.asm.obj:
  138. X    $(ASM) $(AFLAGS) $<;
  139. X# .obj -> .exe (for tlink)
  140. X.obj.exe:
  141. X    $(TLINK) $(TLFLAGS) $(C0) $<, $@,, $(LIBS);
  142. X
  143. X# NDMAKE automatic response file generation
  144. X.RESPONSE_LINK: tlink
  145. X.RESPONSE_LIB:  tlib
  146. X
  147. X
  148. X###
  149. X### Optional features (see pcconf.h)
  150. X###
  151. X# uncomment the definitions used
  152. X
  153. X# overlays
  154. X#OVERLAY = $(OBJ)\trampoli.obj ovlmgr.obj
  155. X#OVERLAY_H = $(INCL)\trampoli.h
  156. X#LINK_LIST = $(OVERLAYS)
  157. XOVERLAY =
  158. XOVERLAY_H =
  159. XLINK_LIST = $(HOBJ)
  160. X
  161. X# Fish's TERMLIB termcap library (see the rule below)
  162. X#TERMLIB = $(LIB)\termlib.lib
  163. XTERMLIB =
  164. X
  165. X# high-quality BSD random number generation routines
  166. X#RANDOM = $(OBJ)\random.obj
  167. XRANDOM =
  168. X
  169. X
  170. X###
  171. X### Dependencies
  172. X###
  173. X# nothing below this line should have to be changed
  174. X# other things that must be reconfigured are in config.h and $(TARG)conf.h
  175. X
  176. X# target prefix
  177. XTARG    = pc
  178. X
  179. X# object files for makedefs.exe
  180. XMAKEOBJS = $(OBJ)\makedefs.obj $(OBJ)\monst.obj $(OBJ)\objects.obj
  181. X
  182. X# object files for lev_comp.exe
  183. XSPLEVOBJS = $(OBJ)\lev_comp.obj   $(OBJ)\lev_lex.obj  $(OBJ)\lev_main.obj \
  184. X        $(OBJ)\monst.obj      $(OBJ)\objects.obj
  185. X
  186. X# object files for termlib.lib
  187. XTERMOBJS = $(OBJ)\tgetent.obj  $(OBJ)\tgetflag.obj  $(OBJ)\tgetnum.obj \
  188. X       $(OBJ)\tgetstr.obj  $(OBJ)\tgoto.obj     $(OBJ)\tputs.obj \
  189. X       $(OBJ)\isdigit.obj  $(OBJ)\fgetlr.obj
  190. XTERMLIST = -+ $(OBJ)\tgetent.obj -+ $(OBJ)\tgetflag.obj -+ $(OBJ)\tgetnum.obj \
  191. X       -+ $(OBJ)\tgetstr.obj -+ $(OBJ)\tgoto.obj    -+ $(OBJ)\tputs.obj \
  192. X       -+ $(OBJ)\isdigit.obj -+ $(OBJ)\fgetlr.obj
  193. X
  194. X# alloc.c is completely unnecessary for any PC NetHack executable.
  195. X# panic.c is unnecessary for makedefs.exe and lev_comp.exe.
  196. X# ioctl.c is unnecessary for nethack.exe.
  197. X
  198. XROOT =    $(OBJ)\main.obj    $(OBJ)\allmain.obj $(OBJ)\msdos.obj \
  199. X    $(OBJ)\termcap.obj $(OBJ)\cmd.obj     $(OBJ)\hack.obj \
  200. X    $(OVERLAY)
  201. X
  202. X# the overlays -- the Microsoft Overlay Linker is limited to 63
  203. X
  204. XOVL01 = $(OBJ)\decl.obj
  205. XOVL02 = $(OBJ)\topl.obj
  206. XOVL03 = $(OBJ)\pri.obj $(OBJ)\prisym.obj
  207. XOVL04 = $(OBJ)\rnd.obj $(RANDOM)
  208. XOVL05 = $(OBJ)\timeout.obj
  209. XOVL06 = $(OBJ)\mon.obj $(OBJ)\exper.obj
  210. XOVL07 = $(OBJ)\attrib.obj
  211. XOVL08 = $(OBJ)\monst.obj $(OBJ)\mondata.obj
  212. XOVL09 = $(OBJ)\monmove.obj $(OBJ)\track.obj
  213. XOVL10 = $(OBJ)\dog.obj $(OBJ)\dogmove.obj
  214. XOVL11 = $(OBJ)\makemon.obj
  215. XOVL12 = $(OBJ)\do_name.obj $(OBJ)\getline.obj
  216. XOVL13 = $(OBJ)\weapon.obj
  217. XOVL14 = $(OBJ)\wield.obj
  218. XOVL15 = $(OBJ)\invent.obj
  219. XOVL16 = $(OBJ)\objects.obj
  220. XOVL17 = $(OBJ)\mkobj.obj $(OBJ)\o_init.obj
  221. XOVL18 = $(OBJ)\objnam.obj
  222. XOVL19 = $(OBJ)\worn.obj
  223. XOVL20 = $(OBJ)\do_wear.obj
  224. XOVL21 = $(OBJ)\trap.obj
  225. XOVL22 = $(OBJ)\dothrow.obj
  226. XOVL23 = $(OBJ)\dokick.obj
  227. XOVL24 = $(OBJ)\uhitm.obj
  228. XOVL25 = $(OBJ)\mhitu.obj
  229. XOVL26 = $(OBJ)\mcastu.obj
  230. XOVL27 = $(OBJ)\mhitm.obj
  231. XOVL28 = $(OBJ)\mthrowu.obj
  232. XOVL29 = $(OBJ)\steal.obj
  233. XOVL30 = $(OBJ)\priest.obj
  234. XOVL31 = $(OBJ)\vault.obj
  235. XOVL32 = $(OBJ)\shk.obj $(OBJ)\shknam.obj
  236. XOVL33 = $(OBJ)\wizard.obj
  237. XOVL34 = $(OBJ)\worm.obj
  238. XOVL35 = $(OBJ)\were.obj
  239. XOVL36 = $(OBJ)\demon.obj
  240. XOVL37 = $(OBJ)\artifact.obj
  241. XOVL38 = $(OBJ)\music.obj $(OBJ)\dbridge.obj
  242. XOVL39 = $(OBJ)\sit.obj $(OBJ)\fountain.obj
  243. XOVL40 = $(OBJ)\sounds.obj
  244. XOVL41 = $(OBJ)\spell.obj
  245. XOVL42 = $(OBJ)\read.obj
  246. XOVL43 = $(OBJ)\potion.obj
  247. XOVL44 = $(OBJ)\zap.obj
  248. XOVL45 = $(OBJ)\eat.obj $(OBJ)\rumors.obj
  249. XOVL46 = $(OBJ)\do.obj
  250. XOVL47 = $(OBJ)\search.obj
  251. XOVL48 = $(OBJ)\lock.obj
  252. XOVL49 = $(OBJ)\apply.obj
  253. XOVL50 = $(OBJ)\engrave.obj $(OBJ)\write.obj
  254. XOVL51 = $(OBJ)\pray.obj
  255. XOVL52 = $(OBJ)\options.obj
  256. XOVL53 = $(OBJ)\pickup.obj
  257. XOVL54 = $(OBJ)\polyself.obj
  258. XOVL55 = $(OBJ)\u_init.obj
  259. XOVL56 = $(OBJ)\extralev.obj
  260. XOVL57 = $(OBJ)\mklev.obj $(OBJ)\mkroom.obj
  261. XOVL58 = $(OBJ)\mkmaze.obj $(OBJ)\sp_lev.obj
  262. XOVL59 = $(OBJ)\restore.obj $(OBJ)\save.obj $(OBJ)\bones.obj
  263. XOVL60 = $(OBJ)\rip.obj $(OBJ)\topten.obj $(OBJ)\end.obj
  264. XOVL61 = $(OBJ)\unix.obj $(OBJ)\tty.obj $(OBJ)\mail.obj
  265. XOVL62 = $(OBJ)\pager.obj
  266. XOVL63 = $(OBJ)\version.obj
  267. X
  268. X# date.h dependencies
  269. XVOBJ = $(ROOT)    $(OVL01) $(OVL02) $(OVL03) $(OVL04) $(OVL05) $(OVL06) $(OVL07) \
  270. X       $(OVL08) $(OVL09) $(OVL10) $(OVL11) $(OVL12) $(OVL13) $(OVL14) $(OVL15) \
  271. X       $(OVL16) $(OVL17) $(OVL18) $(OVL19) $(OVL20) $(OVL21) $(OVL22) $(OVL23) \
  272. X       $(OVL24) $(OVL25) $(OVL26) $(OVL27) $(OVL28) $(OVL29) $(OVL30) $(OVL31) \
  273. X       $(OVL32) $(OVL33) $(OVL34) $(OVL35) $(OVL36) $(OVL37) $(OVL38) $(OVL39) \
  274. X       $(OVL40) $(OVL41) $(OVL42) $(OVL43) $(OVL44) $(OVL45) $(OVL46) $(OVL47) \
  275. X       $(OVL48) $(OVL49) $(OVL50) $(OVL51) $(OVL52) $(OVL53) $(OVL54) $(OVL55) \
  276. X       $(OVL56) $(OVL57) $(OVL58) $(OVL59) $(OVL60) $(OVL61) $(OVL62)
  277. X
  278. X# nethack.exe dependencies, non-overlay link list
  279. XHOBJ =    $(VOBJ) $(OVL63)
  280. X
  281. X# overlay link list
  282. XOVERLAYS = $(ROOT)    ($(OVL01)) ($(OVL02)) ($(OVL03)) ($(OVL04)) ($(OVL05)) \
  283. X       ($(OVL06)) ($(OVL07)) ($(OVL08)) ($(OVL09)) ($(OVL10)) ($(OVL11)) \
  284. X       ($(OVL12)) ($(OVL13)) ($(OVL14)) ($(OVL15)) ($(OVL16)) ($(OVL17)) \
  285. X       ($(OVL18)) ($(OVL19)) ($(OVL20)) ($(OVL21)) ($(OVL22)) ($(OVL23)) \
  286. X       ($(OVL24)) ($(OVL25)) ($(OVL26)) ($(OVL27)) ($(OVL28)) ($(OVL29)) \
  287. X       ($(OVL30)) ($(OVL31)) ($(OVL32)) ($(OVL33)) ($(OVL34)) ($(OVL35)) \
  288. X       ($(OVL36)) ($(OVL37)) ($(OVL38)) ($(OVL39)) ($(OVL40)) ($(OVL41)) \
  289. X       ($(OVL42)) ($(OVL43)) ($(OVL44)) ($(OVL45)) ($(OVL46)) ($(OVL47)) \
  290. X       ($(OVL48)) ($(OVL49)) ($(OVL50)) ($(OVL51)) ($(OVL52)) ($(OVL53)) \
  291. X       ($(OVL54)) ($(OVL55)) ($(OVL56)) ($(OVL57)) ($(OVL58)) ($(OVL59)) \
  292. X       ($(OVL60)) ($(OVL61)) ($(OVL62)) ($(OVL63))
  293. X
  294. X# header dependencies
  295. X
  296. XPCCONF_H   = $(INCL)\$(TARG)conf.h  $(INCL)\msdos.h    $(INCL)\system.h
  297. XGLOBAL_H   = $(PCCONF_H)        $(INCL)\global.h    $(INCL)\coord.h
  298. XCONFIG_H   = $(GLOBAL_H)        $(INCL)\config.h    $(INCL)\tradstdc.h
  299. XTRAP_H       = $(INCL)\trap.h
  300. XPERMONST_H = $(INCL)\permonst.h     $(INCL)\monattk.h    $(INCL)\monflag.h
  301. XYOUPROP_H  = $(PERMONST_H)        $(INCL)\prop.h    $(INCL)\mondata.h \
  302. X         $(INCL)\pm.h        $(INCL)\youprop.h
  303. XYOU_H       = $(YOUPROP_H)        $(INCL)\attrib.h    $(INCL)\monst.h    \
  304. X         $(INCL)\you.h
  305. XDECL_H       = $(YOU_H)            $(INCL)\decl.h    $(INCL)\obj.h \
  306. X         $(INCL)\onames.h        $(INCL)\spell.h    $(INCL)\color.h
  307. XHACK_H       = $(CONFIG_H)        $(DECL_H)        $(INCL)\trap.h \
  308. X         $(INCL)\flag.h        $(INCL)\gold.h    $(INCL)\mkroom.h \
  309. X         $(INCL)\monsym.h        $(INCL)\objclass.h    $(INCL)\rm.h \
  310. X         $(INCL)\hack.h        $(OVERLAY_H)
  311. X
  312. X## extern.h, and decl.h contain only external declarations.
  313. X##
  314. X## If anything in them changes, all other files involving the changed routines
  315. X## should be changed to reflect them.  Including them in their respective
  316. X## dependency lists will make sure everything is correct, but causes frequent
  317. X## near-total recompiles.  By leaving them out, we allow quicker testing of
  318. X## changes, but we presume the wiz knows to be circumspect.
  319. X
  320. X
  321. X###
  322. X### Main targets
  323. X###
  324. X
  325. X$(GAME): $(GAMEFILE) $(GAMEDIR)\data $(GAMEDIR)\rumors
  326. X
  327. X$(GAMEFILE): $(GAMEDIR) $(OBJ) $(HOBJ) $(TERMLIB) Makefile
  328. X    @echo Linking...
  329. X    if exist $@ del $@
  330. X        $(LINK) $(C0) $(LINK_LIST),$@,,$(LIBS) $(TERMLIB) $(LFLAGS);
  331. X    @echo NetHack is up to date.
  332. X
  333. Xall:    $(GAME) install
  334. X    @echo Done.
  335. X
  336. X$(OBJ):
  337. X    mkdir $(OBJ)
  338. X
  339. X$(GAMEDIR):
  340. X    mkdir $(GAMEDIR)
  341. X    mkdir $(GAMEDIR)\bones
  342. X
  343. X
  344. X###
  345. X### makedefs.exe
  346. X###
  347. X
  348. Xmakedefs.exe:  $(MAKEOBJS)
  349. X    @$(TLINK) $(TLFLAGS) $(C0) $(MAKEOBJS),$@,,$(LIBS);
  350. X
  351. X$(OBJ)\makedefs.obj:  $(INCL)\config.h $(INCL)\permonst.h $(INCL)\objclass.h
  352. X
  353. X
  354. X###
  355. X### makedefs-generated files
  356. X###
  357. X
  358. X# date.h should be remade any time any of the source is modified
  359. X$(INCL)\date.h:     makedefs.exe $(VOBJ)
  360. X    makedefs -v
  361. X
  362. X$(INCL)\trap.h:     makedefs.exe
  363. X    makedefs -t
  364. X
  365. X$(INCL)\onames.h:    makedefs.exe
  366. X    makedefs -o
  367. X
  368. X$(INCL)\pm.h:        makedefs.exe
  369. X    makedefs -p
  370. X
  371. X$(GAMEDIR)\data:    makedefs.exe $(AUX)\data.base
  372. X    makedefs -d
  373. X    xcopy $(AUX)\data $(GAMEDIR)
  374. X    del $(AUX)\data
  375. X
  376. X$(GAMEDIR)\rumors:    makedefs.exe $(AUX)\rumors.tru $(AUX)\rumors.fal
  377. X    makedefs -r
  378. X    xcopy $(AUX)\rumors $(GAMEDIR)
  379. X    del $(AUX)\rumors
  380. X
  381. X
  382. X###
  383. X### lev_comp.exe
  384. X###
  385. X
  386. Xlev_comp.exe:  $(SPLEVOBJS)
  387. X    $(TLINK) $(TLFLAGS) $(C0) $(SPLEVOBJS),$@,,$(LIBS);
  388. X
  389. X## Note: UNIX yacc may generate a line reading "#", which Turbo C 2.0, despite
  390. X##     the manual's claims that it should be ignored, treats as an error.
  391. X##     You may have to remove such a line to compile lev_comp.c.
  392. X$(OBJ)\lev_comp.obj:  $(HACK_H) $(INCL)\sp_lev.h
  393. X    $(CC) $(CFLAGS) -A- $*.c
  394. X$(OBJ)\lev_lex.obj:  $(INCL)\lev_comp.h $(HACK_H) $(INCL)\sp_lev.h
  395. X$(OBJ)\lev_main.obj:  $(HACK_H) $(INCL)\sp_lev.h
  396. X
  397. X# If you have yacc or lex programs, and make any changes,
  398. X# add some .y.c and .l.c rules to your Make.ini.
  399. X#
  400. X#lev_comp.c:  lev_comp.y
  401. X#lev_lex.c:  lev_comp.l
  402. X
  403. X
  404. X###
  405. X### termlib.lib
  406. X###
  407. X
  408. X#$(TERMLIB): $(TERMOBJS)
  409. X#    tlib $(TERMLIB) /C $(TERMLIST);
  410. X
  411. X
  412. X###
  413. X### Secondary targets
  414. X###
  415. X
  416. Xinstall:  $(GAMEDIR)\NetHack.cnf $(GAMEDIR)\record $(GAMEDIR)\termcap spec_levs
  417. X    xcopy $(AUX)\*. $(GAMEDIR)
  418. X    @echo Auxiliary files installed.
  419. X
  420. X$(GAMEDIR)\NetHack.cnf:
  421. X    xcopy $(OTHERS)\NetHack.cnf $(GAMEDIR)
  422. X$(GAMEDIR)\record:
  423. X    touch $(GAMEDIR)\record
  424. X$(GAMEDIR)\termcap:
  425. X    xcopy $(OTHERS)\termcap $(GAMEDIR)
  426. X
  427. Xspec_levs: $(AUX)\castle.des $(AUX)\endgame.des $(AUX)\tower.des lev_comp.exe
  428. X    lev_comp $(AUX)\castle.des
  429. X    lev_comp $(AUX)\endgame.des
  430. X    lev_comp $(AUX)\tower.des
  431. X    chdir $(AUX)
  432. X    xcopy castle $(GAMEDIR)
  433. X    del castle
  434. X    xcopy endgame $(GAMEDIR)
  435. X    del endgame
  436. X    xcopy tower? $(GAMEDIR)
  437. X    del tower?
  438. X    chdir $(SRC)
  439. X    @echo Special levels compiled.
  440. X
  441. Xclean:
  442. X    del $(OBJ)\*.obj
  443. X    rmdir $(OBJ)
  444. X
  445. Xspotless: clean
  446. X    del $(INCL)\date.h
  447. X    del $(INCL)\onames.h
  448. X    del $(INCL)\pm.h
  449. X    del makedefs.exe
  450. X    if exist lev_comp.exe del lev_comp.exe
  451. X
  452. X
  453. X###
  454. X### Other dependencies
  455. X###
  456. X
  457. X# OS-dependent filenames
  458. X$(OBJ)\main.obj:     $(HACK_H) $(TARG)main.c
  459. X    $(CC) $(CFLAGS) -o$@ $(TARG)main.c
  460. X
  461. X$(OBJ)\tty.obj:      $(HACK_H) $(INCL)\func_tab.h $(TARG)tty.c
  462. X    $(CC) $(CFLAGS) -o$@ $(TARG)tty.c
  463. X
  464. X$(OBJ)\unix.obj:     $(HACK_H) $(TARG)unix.c
  465. X    $(CC) $(CFLAGS) -o$@ $(TARG)unix.c
  466. X
  467. X# GO AHEAD, DELETE THIS LINE
  468. X
  469. X$(OBJ)\allmain.obj:    $(HACK_H)
  470. X$(OBJ)\alloc.obj:    $(CONFIG_H)
  471. X$(OBJ)\apply.obj:    $(HACK_H)   $(INCL)\edog.h
  472. X$(OBJ)\artifact.obj:    $(HACK_H)   $(INCL)\artifact.h
  473. X$(OBJ)\attrib.obj:    $(HACK_H)
  474. X$(OBJ)\bones.obj:    $(HACK_H)
  475. X$(OBJ)\cmd.obj:     $(HACK_H)   $(INCL)\func_tab.h
  476. X$(OBJ)\dbridge.obj:    $(HACK_H)
  477. X$(OBJ)\decl.obj:    $(HACK_H)
  478. X$(OBJ)\demon.obj:    $(HACK_H)
  479. X$(OBJ)\do.obj:        $(HACK_H)
  480. X$(OBJ)\do_name.obj:    $(HACK_H)
  481. X$(OBJ)\do_wear.obj:    $(HACK_H)
  482. X$(OBJ)\dog.obj:     $(HACK_H)   $(INCL)\edog.h
  483. X$(OBJ)\dogmove.obj:    $(HACK_H)   $(INCL)\mfndpos.h     $(INCL)\edog.h
  484. X$(OBJ)\dokick.obj:    $(HACK_H)   $(INCL)\eshk.h
  485. X$(OBJ)\dothrow.obj:    $(HACK_H)
  486. X$(OBJ)\eat.obj:     $(HACK_H)
  487. X$(OBJ)\end.obj:     $(HACK_H)   $(INCL)\eshk.h
  488. X$(OBJ)\engrave.obj:    $(HACK_H)
  489. X$(OBJ)\exper.obj:    $(HACK_H)
  490. X$(OBJ)\extralev.obj:    $(HACK_H)
  491. X$(OBJ)\fountain.obj:    $(HACK_H)
  492. X$(OBJ)\getline.obj:    $(HACK_H)   $(INCL)\func_tab.h
  493. X$(OBJ)\hack.obj:    $(HACK_H)
  494. X$(OBJ)\invent.obj:    $(HACK_H)   $(INCL)\lev.h     $(INCL)\wseg.h
  495. X$(OBJ)\ioctl.obj:    $(HACK_H)
  496. X$(OBJ)\lev_comp.obj:    $(HACK_H)   $(INCL)\sp_lev.h
  497. X$(OBJ)\lev_lex.obj:    $(HACK_H)   $(INCL)\sp_lev.h     $(INCL)\lev_comp.h
  498. X$(OBJ)\lev_main.obj:    $(HACK_H)
  499. X$(OBJ)\lock.obj:    $(HACK_H)
  500. X$(OBJ)\makemon.obj:    $(HACK_H)
  501. X$(OBJ)\mail.obj:    $(HACK_H)
  502. X$(OBJ)\mcastu.obj:    $(HACK_H)
  503. X$(OBJ)\mhitm.obj:    $(HACK_H)   $(INCL)\artifact.h
  504. X$(OBJ)\mhitu.obj:    $(HACK_H)   $(INCL)\artifact.h     $(INCL)\edog.h
  505. X$(OBJ)\mklev.obj:    $(HACK_H)
  506. X$(OBJ)\mkmaze.obj:    $(HACK_H)
  507. X$(OBJ)\mkobj.obj:    $(HACK_H)
  508. X$(OBJ)\mkroom.obj:    $(HACK_H)
  509. X$(OBJ)\mon.obj:     $(HACK_H)   $(INCL)\mfndpos.h     $(INCL)\wseg.h
  510. X$(OBJ)\mondata.obj:    $(HACK_H)   $(INCL)\eshk.h     $(INCL)\epri.h
  511. X$(OBJ)\monmove.obj:    $(HACK_H)   $(INCL)\mfndpos.h     $(INCL)\artifact.h
  512. X$(OBJ)\monst.obj:    $(CONFIG_H) $(PERMONST_H)     $(INCL)\monsym.h \
  513. X                    $(INCL)\eshk.h     $(INCL)\vault.h \
  514. X                    $(INCL)\epri.h     $(INCL)\color.h
  515. X$(OBJ)\msdos.obj:    $(HACK_H) msdos.c
  516. X    $(CC) $(CFLAGS) -A- $*.c
  517. X# set ANSI only off -- many MS-DOS specific things.
  518. X$(OBJ)\mthrowu.obj:    $(HACK_H)
  519. X$(OBJ)\music.obj:    $(HACK_H)
  520. X$(OBJ)\o_init.obj:    $(HACK_H)
  521. X$(OBJ)\objects.obj:    $(CONFIG_H) $(INCL)\obj.h     $(INCL)\objclass.h \
  522. X                    $(INCL)\prop.h     $(INCL)\color.h
  523. X$(OBJ)\objnam.obj:    $(HACK_H)
  524. X$(OBJ)\options.obj:    $(HACK_H)
  525. X$(OBJ)\pager.obj:    $(HACK_H)
  526. X$(OBJ)\panic.obj:    $(CONFIG_H)
  527. X$(OBJ)\pickup.obj:    $(HACK_H)
  528. X$(OBJ)\polyself.obj:    $(HACK_H)
  529. X$(OBJ)\potion.obj:    $(HACK_H)
  530. X$(OBJ)\pray.obj:    $(HACK_H)
  531. X$(OBJ)\pri.obj:     $(HACK_H)   $(INCL)\epri.h     $(INCL)\termcap.h
  532. X$(OBJ)\priest.obj:    $(HACK_H)   $(INCL)\mfndpos.h     $(INCL)\eshk.h \
  533. X                    $(INCL)\epri.h
  534. X$(OBJ)\prisym.obj:    $(HACK_H)   $(INCL)\lev.h     $(INCL)\wseg.h
  535. X$(OBJ)\random.obj:
  536. X$(OBJ)\read.obj:    $(HACK_H)
  537. X$(OBJ)\restore.obj:    $(HACK_H)   $(INCL)\lev.h     $(INCL)\wseg.h
  538. X$(OBJ)\rip.obj:
  539. X    $(CC) $(CFLAGS) -d- $*.c
  540. X# must not merge strings, or the tombstone lines will overlap
  541. X$(OBJ)\rnd.obj:     $(HACK_H)
  542. X$(OBJ)\rumors.obj:    $(HACK_H)
  543. X$(OBJ)\save.obj:    $(HACK_H)   $(INCL)\lev.h     $(INCL)\wseg.h
  544. X$(OBJ)\search.obj:    $(HACK_H)   $(INCL)\artifact.h
  545. X$(OBJ)\shk.obj:     $(HACK_H)   $(INCL)\eshk.h
  546. X$(OBJ)\shknam.obj:    $(HACK_H)   $(INCL)\eshk.h
  547. X$(OBJ)\sit.obj:     $(HACK_H)
  548. X$(OBJ)\sounds.obj:    $(HACK_H)   $(INCL)\edog.h     $(INCL)\eshk.h
  549. X$(OBJ)\sp_lev.obj:    $(HACK_H)   $(INCL)\sp_lev.h
  550. X$(OBJ)\spell.obj:    $(HACK_H)
  551. X$(OBJ)\steal.obj:    $(HACK_H)
  552. X$(OBJ)\termcap.obj:    $(HACK_H)   $(INCL)\termcap.h
  553. X$(OBJ)\timeout.obj:    $(HACK_H)
  554. X$(OBJ)\topl.obj:    $(HACK_H)
  555. X$(OBJ)\topten.obj:    $(HACK_H)
  556. X$(OBJ)\track.obj:    $(HACK_H)
  557. X$(OBJ)\trampoli.obj:    $(HACK_H)
  558. X$(OBJ)\trap.obj:    $(HACK_H)   $(INCL)\edog.h
  559. X$(OBJ)\u_init.obj:    $(HACK_H)
  560. X$(OBJ)\uhitm.obj:    $(HACK_H)   $(INCL)\artifact.h
  561. X$(OBJ)\vault.obj:    $(HACK_H)   $(INCL)\vault.h
  562. X$(OBJ)\version.obj:    $(HACK_H)   $(INCL)\date.h     $(INCL)\patchlev.h
  563. X$(OBJ)\weapon.obj:    $(HACK_H)
  564. X$(OBJ)\were.obj:    $(HACK_H)
  565. X$(OBJ)\wield.obj:    $(HACK_H)
  566. X$(OBJ)\wizard.obj:    $(HACK_H)
  567. X$(OBJ)\worm.obj:    $(HACK_H)   $(INCL)\wseg.h
  568. X$(OBJ)\worn.obj:    $(HACK_H)
  569. X$(OBJ)\write.obj:    $(HACK_H)
  570. X$(OBJ)\zap.obj:     $(HACK_H)
  571. END_OF_FILE
  572. if test 15565 -ne `wc -c <'others/Makefile.tcc'`; then
  573.     echo shar: \"'others/Makefile.tcc'\" unpacked with wrong size!
  574. fi
  575. # end of 'others/Makefile.tcc'
  576. fi
  577. if test -f 'others/pcmain.c' -a "${1}" != "-c" ; then 
  578.   echo shar: Will not clobber existing file \"'others/pcmain.c'\"
  579. else
  580. echo shar: Extracting \"'others/pcmain.c'\" \(19659 characters\)
  581. sed "s/^X//" >'others/pcmain.c' <<'END_OF_FILE'
  582. X/*    SCCS Id: @(#)pcmain.c    3.0    90/01/19
  583. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  584. X/* NetHack may be freely redistributed.  See license for details. */
  585. X/* main.c - PC, ST, and Amiga NetHack */
  586. X#include "hack.h"
  587. X
  588. X#ifndef NO_SIGNAL
  589. X#include <signal.h>
  590. X#endif
  591. X#include <ctype.h>
  592. X#ifdef DGK
  593. X#ifndef AMIGA
  594. X#include <sys\stat.h>
  595. X#endif
  596. X#endif
  597. X
  598. X#if defined(LATTICE) || defined(MACOS)
  599. Xextern short *switches;
  600. X#endif
  601. X#ifdef MACOS
  602. Xextern WindowPtr    HackWindow;
  603. Xextern short macflags;
  604. Xpascal boolean FDECL(startDlogFProc, (DialogPtr, EventRecord *, short *));
  605. X#define msmsg mprintf
  606. X#endif
  607. X
  608. X#if !defined(MACOS) && !defined(LATTICE)
  609. Xchar orgdir[PATHLEN];
  610. X#endif
  611. Xchar SAVEF[FILENAME];
  612. X#ifdef MSDOS
  613. Xchar SAVEP[FILENAME];
  614. X#endif
  615. X
  616. Xconst char *hname = "NetHack";    /* used for syntax messages */
  617. X#if !defined(AMIGA) && !defined(MACOS)
  618. Xchar obuf[BUFSIZ];    /* BUFSIZ is defined in stdio.h */
  619. X#endif
  620. Xint hackpid;        /* not used anymore, but kept in for save files */
  621. X
  622. X#if defined(DGK)
  623. Xstruct finfo    zfinfo = ZFINFO;
  624. Xint i;
  625. X#endif /* DGK */
  626. X
  627. X#ifdef __TURBOC__    /* tell Turbo C to make a bigger stack */
  628. Xextern unsigned _stklen = 0x2000;    /* 8K */
  629. Xextern unsigned char _osmajor;
  630. X#endif
  631. X
  632. X#ifdef TOS
  633. Xextern long compiletime;
  634. Xboolean run_from_desktop = TRUE;    /* should we pause before exiting?? */
  635. X# ifdef __GNUC__
  636. Xlong _stksize = 16*1024;
  637. X# endif
  638. X#endif
  639. X
  640. X#ifdef MACOS
  641. X#  ifdef AZTEC
  642. X#define OMASK    O_RDONLY
  643. X#  else
  644. X#define OMASK    (O_RDONLY | O_BINARY )
  645. X#  endif
  646. X# else
  647. X#define OMASK    O_RDONLY
  648. X#endif
  649. X
  650. X#ifdef MACOS
  651. XBoolean justscores;
  652. X#endif
  653. X
  654. X#ifdef AMIGA_WBENCH
  655. Xextern int FromWBench;
  656. X#endif
  657. X
  658. Xint FDECL(main, (int,char **));
  659. X
  660. Xconst char *classes = "ABCEHKPRSTVW";
  661. X
  662. Xint
  663. Xmain(argc,argv)
  664. Xint argc;
  665. Xchar *argv[];
  666. X{
  667. X    extern int x_maze_max, y_maze_max;
  668. X    register int fd;
  669. X    register char *dir;
  670. X#ifndef AMIGA
  671. X    int (*funcp)();
  672. X#endif
  673. X#ifdef TOS
  674. X    long clock;
  675. X# ifdef __GNUC__
  676. X    extern int _unixmode;
  677. X    _unixmode = 0;
  678. X# endif
  679. X#endif
  680. X#ifdef __TURBOC__
  681. X    if (_osmajor >= 3) hname = argv[0];    /* DOS 3.0+ */
  682. X#endif
  683. X#ifdef TOS
  684. X    if (*argv[0]) {            /* only a CLI can give us argv[0] */
  685. X        hname = argv[0];
  686. X        run_from_desktop = FALSE;
  687. X    }
  688. X#endif
  689. X#ifdef MACOS
  690. X    AppFile    theFile;
  691. X    short    message,numFiles;
  692. X    SFReply    reply;
  693. X
  694. X    initterm(24,80);
  695. X    ObscureCursor();
  696. X# ifdef SMALLDATA
  697. X    init_decl();
  698. X# endif
  699. X    /* user might have started up with a save file, so check */
  700. X    CountAppFiles(&message,&numFiles);
  701. X    if (!message && numFiles) {
  702. X        message = 1;
  703. X
  704. X        while(message <= numFiles) {
  705. X            GetAppFiles(message,&theFile);
  706. X            ClrAppFiles(message);
  707. X            if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE))
  708. X                break;
  709. X            message++;
  710. X        }
  711. X        if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE)) {
  712. X            (void)strncpy(SAVEF, (char *)&theFile.fName[1],
  713. X                        (int)theFile.fName[0]);
  714. X            (void)strncpy(plname, (char *)&theFile.fName[1],
  715. X                        (int)theFile.fName[0]);
  716. X            SetVol(0L,theFile.vRefNum);
  717. X            SAVEF[(int)theFile.fName[0]] = '\0';
  718. X            numFiles = 1;
  719. X        } else
  720. X            numFiles = 0;
  721. X    }
  722. X#endif
  723. X#if defined(LATTICE) || defined(MACOS)
  724. X    switches = (short *)malloc((NROFOBJECTS+2) * sizeof(long));
  725. X    for (fd = 0; fd < (NROFOBJECTS + 2); fd++)
  726. X        switches[fd] = fd;
  727. X#endif
  728. X
  729. X
  730. X    /*
  731. X     *  Initialize screen I/O before anything is displayed.
  732. X     *
  733. X     *  startup() must be called before initoptions()
  734. X     *    due to ordering of graphics settings
  735. X     *  and before error(), due to use of termcap strings.
  736. X     */
  737. X    gettty();
  738. X#if !defined(AMIGA) && !defined(MACOS)
  739. X    setbuf(stdout,obuf);
  740. X#endif
  741. X    startup();
  742. X#if !defined(AMIGA) && !defined(MACOS)
  743. X    /* Save current directory and make sure it gets restored when
  744. X     * the game is exited.
  745. X     */
  746. X    if (getcwd(orgdir, sizeof orgdir) == NULL)
  747. X        error("NetHack: current directory path too long");
  748. X    funcp = (int (*)())exit; /* Kludge to get around LINT_ARGS of signal. */
  749. X# ifndef NO_SIGNAL
  750. X    signal(SIGINT, (SIG_RET_TYPE) funcp);    /* restore original directory */
  751. X# endif
  752. X#endif /* AMIGA || MACOS */
  753. X
  754. X#ifndef MACOS
  755. X    if ((dir = getenv("HACKDIR")) != NULL) {
  756. X        Strcpy(hackdir, dir);
  757. X# ifdef CHDIR
  758. X        chdirx (dir, 1);
  759. X# endif
  760. X    }
  761. X#if defined(AMIGA) && defined(CHDIR)
  762. X    /*
  763. X     * If we're dealing with workbench, change the directory.  Otherwise
  764. X     * we could get "Insert disk in drive 0" messages. (Must be done
  765. X     * before initoptions())....
  766. X     */
  767. X    if(argc == 0)
  768. X        chdirx(HACKDIR, 1);
  769. X#endif
  770. X
  771. X# if defined(DGK)
  772. X    /* zero "fileinfo" array to prevent crashes on level change */
  773. X    for (i = 0 ; i <= MAXLEVEL; i++) {
  774. X        fileinfo[i] = zfinfo;
  775. X    }
  776. X# endif /* DGK */
  777. X
  778. X    initoptions();
  779. X#ifdef AMIGA_WBENCH
  780. X    ami_wbench_init(argc,argv);
  781. X#endif
  782. X# if defined(TOS) && defined(TEXTCOLOR)
  783. X    if (flags.IBMBIOS && flags.use_color)
  784. X        set_colors();
  785. X# endif
  786. X    if (!hackdir[0])
  787. X#if !defined(LATTICE) && !defined(AMIGA)
  788. X        Strcpy(hackdir, orgdir);
  789. X#else
  790. X        Strcpy(hackdir, HACKDIR);
  791. X#endif
  792. X    if(argc > 1) {
  793. X        if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  794. X        /* avoid matching "-dec" for DECgraphics; since the man page
  795. X         * says -d directory, hope nobody's using -desomething_else
  796. X         */
  797. X        argc--;
  798. X        argv++;
  799. X        dir = argv[0]+2;
  800. X        if(*dir == '=' || *dir == ':') dir++;
  801. X        if(!*dir && argc > 1) {
  802. X            argc--;
  803. X            argv++;
  804. X            dir = argv[0];
  805. X        }
  806. X        if(!*dir)
  807. X            error("Flag -d must be followed by a directory name.");
  808. X        Strcpy(hackdir, dir);
  809. X        } else
  810. X
  811. X    /*
  812. X     * Now we know the directory containing 'record' and
  813. X     * may do a prscore().
  814. X     */
  815. X        if (!strncmp(argv[1], "-s", 2)) {
  816. X# ifdef CHDIR
  817. X        chdirx(hackdir,0);
  818. X# endif
  819. X        prscore(argc, argv);
  820. X        exit(0);
  821. X        }
  822. X    }
  823. X#else
  824. X    initoptions();
  825. X#endif    /* MACOS /* */
  826. X
  827. X    /*
  828. X     * It seems you really want to play.
  829. X     */
  830. X    setrandom();
  831. X    cls();
  832. X#ifdef TOS
  833. X    if ((unsigned long)time(&clock) < (unsigned long)compiletime)
  834. X        error("Your clock is incorrectly set!");
  835. X#endif
  836. X    u.uhp = 1;    /* prevent RIP on early quits */
  837. X    u.ux = FAR;    /* prevent nscr() */
  838. X
  839. X    /*
  840. X     * Find the creation date of this game,
  841. X     * so as to avoid restoring outdated savefiles.
  842. X     */
  843. X    /* gethdate(hname); */
  844. X
  845. X    /*
  846. X     * We cannot do chdir earlier, otherwise gethdate will fail.
  847. X     */
  848. X#ifdef CHDIR
  849. X    chdirx(hackdir,1);
  850. X#endif
  851. X
  852. X#ifndef MACOS
  853. X    /*
  854. X     * Process options.
  855. X     */
  856. X    while(argc > 1 && argv[1][0] == '-'){
  857. X        argv++;
  858. X        argc--;
  859. X        switch(argv[0][1]){
  860. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  861. X# ifndef EXPLORE_MODE
  862. X        case 'X':
  863. X# endif
  864. X        case 'D':
  865. X# ifdef WIZARD
  866. X            /* Must have "name" set correctly by NETHACK.CNF,
  867. X             * NETHACKOPTIONS, or -u
  868. X             * before this flag to enter wizard mode. */
  869. X#  ifdef KR1ED
  870. X            if(!strcmp(plname, WIZARD_NAME)) {
  871. X#  else
  872. X            if(!strcmp(plname, WIZARD)) {
  873. X#  endif
  874. X                wizard = TRUE;
  875. X                break;
  876. X            }
  877. X            /* otherwise fall thru to discover */
  878. X# endif
  879. X# ifdef EXPLORE_MODE
  880. X        case 'X':
  881. X            discover = TRUE;
  882. X# endif
  883. X            break;
  884. X#endif
  885. X#ifdef NEWS
  886. X        case 'n':
  887. X            flags.nonews = TRUE;
  888. X            break;
  889. X#endif
  890. X        case 'u':
  891. X            if(argv[0][2])
  892. X              (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  893. X            else if(argc > 1) {
  894. X              argc--;
  895. X              argv++;
  896. X              (void) strncpy(plname, argv[0], sizeof(plname)-1);
  897. X            } else
  898. X                Printf("Player name expected after -u\n");
  899. X            break;
  900. X        case 'i':
  901. X            if(!strcmp(argv[0]+1, "ibm")) assign_ibm_graphics();
  902. X            break;
  903. X        case 'd':
  904. X            if(!strcmp(argv[0]+1, "dec")) assign_dec_graphics();
  905. X            break;
  906. X#ifdef DGK
  907. X        /* Player doesn't want to use a RAM disk
  908. X         */
  909. X        case 'r':
  910. X            ramdisk = FALSE;
  911. X            break;
  912. X#endif
  913. X        default:
  914. X            if (index(classes, toupper(argv[0][1]))) {
  915. X                /* allow -T for Tourist, etc. */
  916. X                (void) strncpy(pl_character, argv[0]+1,
  917. X                           sizeof(pl_character)-1);
  918. X                break;
  919. X            } else Printf("\nUnknown switch: %s\n", argv[0]);
  920. X        case '?':
  921. XPrintf("\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...", hname, classes);
  922. XPrintf("\n       or");
  923. XPrintf("\n       %s [-d dir] [-u name] [-[%s]]", hname, classes);
  924. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  925. X            Printf(" [-[DX]]");
  926. X#endif
  927. X#ifdef NEWS
  928. X            Printf(" [-n]");
  929. X#endif
  930. X#ifdef DGK
  931. X            Printf(" [-r]");
  932. X#endif
  933. X            putchar('\n');
  934. X            return 0;
  935. X        }
  936. X    }
  937. X#ifdef AMIGA_WBENCH
  938. X    ami_wbench_args();
  939. X#endif
  940. X#ifdef DGK
  941. X    set_lock_and_bones();
  942. X    copybones(FROMPERM);
  943. X#endif
  944. X#ifdef WIZARD
  945. X    if (wizard)
  946. X        Strcpy(plname, "wizard");
  947. X    else
  948. X#endif
  949. X    if (!*plname)
  950. X        askname();
  951. X    plnamesuffix();        /* strip suffix from name; calls askname() */
  952. X                /* again if suffix was whole name */
  953. X                /* accepts any suffix */
  954. X#ifndef DGK
  955. X    Strcpy(lock,plname);
  956. X    Strcat(lock,".99");
  957. X#endif
  958. X#endif /* MACOS */
  959. X    start_screen();
  960. X
  961. X    /*
  962. X     * Initialisation of the boundaries of the mazes
  963. X     * Both boundaries have to be even.
  964. X     */
  965. X
  966. X    x_maze_max = COLNO-1;
  967. X    if (x_maze_max % 2)
  968. X        x_maze_max--;
  969. X    y_maze_max = ROWNO-1;
  970. X    if (y_maze_max % 2)
  971. X        y_maze_max--;
  972. X
  973. X    /* initialize static monster strength array */
  974. X    init_monstr();
  975. X#ifdef MACOS
  976. X    if (!numFiles) {
  977. X        askname();
  978. X        if(justscores){
  979. X            prscore(1,&classes);
  980. X            exit(0);
  981. X        }
  982. X#endif
  983. X#if defined(AMIGA) || defined(MACOS)
  984. X# ifdef AMIGA_WBENCH
  985. X    if(!FromWBench)
  986. X# endif
  987. X    (void) strncat(SAVEF, plname, 31-4);
  988. X#else
  989. X    {
  990. X        int ix = strlen(SAVEF);
  991. X        (void)strncat(SAVEF, plname, 8);
  992. X        regularize(SAVEF+ix);
  993. X    }
  994. X#endif
  995. X#ifndef MACOS
  996. X# ifdef AMIGA_WBENCH
  997. X    if(!FromWBench)
  998. X# endif
  999. X    Strcat(SAVEF, ".sav");
  1000. X#else
  1001. X    } else {    /* save file start, didn't askname() */
  1002. X        char *stripCharSuffix;
  1003. X
  1004. X        if (stripCharSuffix = strrchr((char *)plname, '-'))
  1005. X            *stripCharSuffix = '\0';
  1006. X    }
  1007. X    Strcpy(lock,plname);
  1008. X    Strcat(lock,".99");
  1009. X#endif
  1010. X    cls();
  1011. X    if (
  1012. X#ifdef DGK
  1013. X# ifdef AMIGA_WBENCH
  1014. X        (FromWBench?1:saveDiskPrompt(1)) &&
  1015. X# else
  1016. X        saveDiskPrompt(1) &&
  1017. X# endif
  1018. X#endif /* DGK */
  1019. X#ifdef AMIGA_WBENCH
  1020. X        ((fd=ami_wbench_getsave(OMASK)) >=0) &&
  1021. X#else
  1022. X        ((fd = open(SAVEF, OMASK)) >= 0) &&
  1023. X#endif
  1024. X       /* if not up-to-date, quietly unlink file via false condition */
  1025. X       (uptodate(fd) || unlink(SAVEF) == 666)) {
  1026. X#ifdef WIZARD
  1027. X        /* Since wizard is actually flags.debug, restoring might
  1028. X         * overwrite it.
  1029. X         */
  1030. X        boolean remember_wiz_mode = wizard;
  1031. X#endif
  1032. X#ifndef NO_SIGNAL
  1033. X        (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  1034. X#endif
  1035. X        pline("Restoring save file...");
  1036. X        (void) fflush(stdout);
  1037. X        if(!dorecover(fd))
  1038. X            goto not_recovered;
  1039. X#ifdef WIZARD
  1040. X        if(!wizard && remember_wiz_mode) wizard = TRUE;
  1041. X#endif
  1042. X        pline("Hello %s, welcome to NetHack!", plname);
  1043. X        /* get shopkeeper set properly if restore is in shop */
  1044. X        (void) inshop();
  1045. X#ifdef EXPLORE_MODE
  1046. X        if (discover)
  1047. X            You("are in non-scoring discovery mode.");
  1048. X#endif
  1049. X#if defined(EXPLORE_MODE) || defined(WIZARD)
  1050. X        if (discover || wizard) {
  1051. X            pline("Do you want to keep the save file? ");
  1052. X            if(yn() == 'n'){
  1053. X                (void) unlink(SAVEF);
  1054. X#ifdef AMIGA_WBENCH
  1055. X                ami_wbench_unlink(SAVEF);
  1056. X#endif
  1057. X            }
  1058. X        }
  1059. X#endif
  1060. X        flags.move = 0;
  1061. X    } else {
  1062. Xnot_recovered:
  1063. X        newgame();
  1064. X        /* give welcome message before pickup messages */
  1065. X        pline("Hello %s, welcome to NetHack!", plname);
  1066. X#ifdef EXPLORE_MODE
  1067. X        if (discover)
  1068. X            You("are in non-scoring discovery mode.");
  1069. X#endif
  1070. X        flags.move = 0;
  1071. X        set_wear();
  1072. X        pickup(1);
  1073. X        read_engr_at(u.ux,u.uy);
  1074. X    }
  1075. X    
  1076. X#ifdef MACOS
  1077. X    {
  1078. X        short    i;
  1079. X        MenuHandle    theMenu;
  1080. X        Rect    screen;
  1081. X        
  1082. X        theMenu = GetMHandle(appleMenu);
  1083. X        EnableItem(theMenu, 0);
  1084. X        EnableItem(theMenu, 1);
  1085. X        theMenu = GetMHandle(fileMenu);
  1086. X        EnableItem(theMenu,0);
  1087. X        for (i = inventMenu;i <= extendMenu; i++) {
  1088. X            theMenu = GetMHandle(i);
  1089. X            EnableItem(theMenu, 0);
  1090. X        }
  1091. X        DrawMenuBar();
  1092. X        macflags |= fDoUpdate;
  1093. X        SetPort(HackWindow);
  1094. X        screen = HackWindow->portRect;
  1095. X        ValidRect(&screen);
  1096. X        
  1097. X    }
  1098. X#endif
  1099. X            
  1100. X    flags.moonphase = phase_of_the_moon();
  1101. X    if(flags.moonphase == FULL_MOON) {
  1102. X        You("are lucky!  Full moon tonight.");
  1103. X        if(!u.uluck) change_luck(1);
  1104. X    } else if(flags.moonphase == NEW_MOON) {
  1105. X        pline("Be careful!  New moon tonight.");
  1106. X    }
  1107. X
  1108. X    initrack();
  1109. X#ifndef NO_SIGNAL
  1110. X    (void) signal(SIGINT, SIG_IGN);
  1111. X#endif
  1112. X#ifdef OS2
  1113. X    gettty(); /* somehow ctrl-P gets turned back on during startup ... */
  1114. X#endif
  1115. X
  1116. X    moveloop();
  1117. X#ifdef MACOS 
  1118. X    /* Help for Mac compilers */
  1119. X    free_decl();
  1120. X#endif
  1121. X    return 0;
  1122. X}
  1123. X
  1124. X
  1125. X/*
  1126. X * plname is filled either by an option (-u Player  or  -uPlayer) or
  1127. X * explicitly (by being the wizard) or by askname.
  1128. X * It may still contain a suffix denoting pl_character.
  1129. X */
  1130. Xvoid
  1131. Xaskname() {
  1132. X#ifndef MACOS
  1133. X    register int c, ct;
  1134. X
  1135. X    Printf("\nWho are you? ");
  1136. X    (void) fflush(stdout);
  1137. X    ct = 0;
  1138. X    while((c = Getchar()) != '\n') {
  1139. X        if(c == EOF) error("End of input\n");
  1140. X        /* some people get confused when their erase char is not ^H */
  1141. X        if(c == '\b') {
  1142. X            if(ct) {
  1143. X                ct--;
  1144. X#ifdef MSDOS
  1145. X                msmsg("\b \b");
  1146. X#endif
  1147. X            }
  1148. X            continue;
  1149. X        }
  1150. X        if(ct < sizeof(plname)-1) {
  1151. X#if defined(MSDOS)
  1152. X            msmsg("%c", c);
  1153. X#endif
  1154. X            plname[ct++] = c;
  1155. X        }
  1156. X    }
  1157. X    plname[ct] = 0;
  1158. X    if(ct == 0) askname();
  1159. X}
  1160. X#else /* MACOS */
  1161. X/* Macintosh startup Dialog written by Andy Swanson 10/20/89
  1162. X        modified for to include a few more options 12/17/89 */
  1163. X    DialogPtr asknameDlog;
  1164. X    DialogTHndl    th, centreDlgBox();
  1165. X    int kind;
  1166. X    Rect box;
  1167. X    Handle knob;
  1168. X    Boolean Done;
  1169. X    int chtype = 0,Hit,i;
  1170. X    Str255 ptemp;
  1171. X    char *p;
  1172. X#define OK 1
  1173. X#define NAME_TEXT 3
  1174. X#define RADIO_MIN 5
  1175. X#define RADIO_MAX 17
  1176. X#define CAVEPERSON 7
  1177. X#define CLERGY 11
  1178. X#define VALKYRIE 15
  1179. X#define ANY 17
  1180. X#define WIZ 18
  1181. X#define EXP 19
  1182. X#define FEM 20
  1183. X#define NO_NEWS_BOX 21
  1184. X#define SCORES 22
  1185. X#define setCheckBox(a,b,c) {GetDItem(a,b,&kind,&knob,&box);SetCtlValue(knob,c?1:0);}
  1186. X#define changeRadio(a,b,c) {setCheckBox(a,b,FALSE); setCheckBox(a,c,TRUE);}
  1187. X#define Disable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,255);}
  1188. X#define Enable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,0);}
  1189. X#define Hide(b)  {GetDItem(asknameDlog,b,&kind,&knob,&box);HideControl(knob);\
  1190. X            SetDItem(asknameDlog,b,kind+128,knob,&box);}
  1191. X    justscores = FALSE;
  1192. X    if(p=strrchr((char *)plname, '-')){
  1193. X        *p = 0;
  1194. X        if(('a'<= p[1]) && ('z'>= p[1]))p[1] += 'A' - 'a';
  1195. X        pl_character[0] = p[1];
  1196. X        pl_character[1] = 0;
  1197. X        if(chtype = (int)index(classes,p[1]))
  1198. X            chtype -= (int)(classes)-1;
  1199. X        if(p[1] == 'V')
  1200. X            flags.female = TRUE;
  1201. X    }
  1202. X    if(chtype != 0) chtype += 4;
  1203. X    else chtype = 17;
  1204. X#ifdef THINKC4
  1205. X    if(!*plname && (p = getlogin()))
  1206. X        (void) strncpy((char *)&plname,p,sizeof(plname)-1);
  1207. X#endif
  1208. X    th = centreDlgBox(131, FALSE);
  1209. X    
  1210. X    asknameDlog = GetNewDialog(131,0,-1);
  1211. X    
  1212. X    ReleaseResource((Handle)th);
  1213. X    if(*plname){
  1214. X        GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
  1215. X        strncpy((char*)ptemp,(char*)&plname,255);
  1216. X        CtoPstr((char*)ptemp);
  1217. X        SetIText(knob,ptemp);
  1218. X    }
  1219. X    GetDItem(asknameDlog,chtype,&kind,&knob,&box);
  1220. X    SetCtlValue(knob,1);
  1221. X    if(flags.female){
  1222. X        setCheckBox(asknameDlog,FEM,TRUE);
  1223. X        changeDgenders(asknameDlog,TRUE);
  1224. X    }
  1225. X#ifdef NEWS
  1226. X    setCheckBox(asknameDlog,NO_NEWS_BOX,flags.nonews);
  1227. X#else
  1228. X    Hide(NO_NEWS_BOX);
  1229. X#endif
  1230. X#ifdef WIZARD
  1231. X    wizard = FALSE;
  1232. X# ifdef KR1ED
  1233. X    if (strcmp(plname,WIZARD_NAME)) {
  1234. X# else
  1235. X    if (strcmp(plname,WIZARD)) {
  1236. X# endif
  1237. X#else
  1238. X    {
  1239. X#endif
  1240. X        Hide(WIZ);
  1241. X    }
  1242. X#ifdef EXPLORE_MODE
  1243. X    setCheckBox(asknameDlog,EXP,discover);
  1244. X#else
  1245. X        Hide(EXP);
  1246. X#endif
  1247. X    SelIText(asknameDlog, NAME_TEXT, 0, 32767);
  1248. X    ShowWindow(asknameDlog);
  1249. X    Done = FALSE;
  1250. X    while (!Done){
  1251. X        ModalDialog(startDlogFProc, &Hit);
  1252. X        if(Hit == OK){
  1253. X            Done = TRUE;
  1254. X            GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
  1255. X            GetIText(knob,&ptemp);
  1256. X            PtoCstr((char*)ptemp);
  1257. X            (void) strncpy((char*)&plname,(char*)ptemp,sizeof(plname)-1);
  1258. X            pl_character[0]=classes[chtype-5];
  1259. X            pl_character[1]=0;
  1260. X            HideWindow(asknameDlog);
  1261. X        } else if((Hit >= RADIO_MIN) && (Hit <= RADIO_MAX)){
  1262. X            extern int lastDlgBut;
  1263. X            
  1264. X            changeRadio(asknameDlog,chtype,Hit);
  1265. X            lastDlgBut = chtype = Hit;
  1266. X            if ((chtype == VALKYRIE) && !flags.female) {
  1267. X                flags.female = TRUE;
  1268. X                setCheckBox(asknameDlog,FEM,flags.female);
  1269. X                changeDgenders(asknameDlog,TRUE);
  1270. X            }
  1271. X        } else if(Hit == WIZ) {
  1272. X            wizard = !wizard;
  1273. X            setCheckBox(asknameDlog,WIZ,wizard);
  1274. X        } else if(Hit == EXP) {
  1275. X            discover = !discover;
  1276. X            setCheckBox(asknameDlog,EXP,discover);
  1277. X        } else if(Hit == FEM) {
  1278. X            flags.female = !flags.female;
  1279. X            setCheckBox(asknameDlog,FEM,flags.female);
  1280. X            if(chtype == VALKYRIE) {
  1281. X                chtype = ANY;
  1282. X                changeRadio(asknameDlog,VALKYRIE,ANY);
  1283. X            }
  1284. X            changeDgenders(asknameDlog,flags.female);
  1285. X        } else if(Hit == NO_NEWS_BOX) {
  1286. X            flags.nonews = !flags.nonews;
  1287. X            setCheckBox(asknameDlog,NO_NEWS_BOX,flags.nonews);
  1288. X        } else if(Hit == SCORES) {
  1289. X            justscores = !justscores;
  1290. X            setCheckBox(asknameDlog,SCORES,justscores);
  1291. X            if(justscores) for (i=RADIO_MIN;i<SCORES;i++) {
  1292. X                Disable(i);
  1293. X                }
  1294. X            else for (i=RADIO_MIN;i<SCORES;i++)
  1295. X                Enable(i);
  1296. X        }
  1297. X    }
  1298. X    DisposDialog(asknameDlog);
  1299. X}
  1300. X
  1301. X
  1302. X#define RADIO_STRING "ABCEHKPRSTVWL"
  1303. Xint    lastDlgBut = ANY;
  1304. X
  1305. X/* The filterProc for handling character selection from keyboard
  1306. X   by h+@nada.kth.se                                             */
  1307. Xpascal boolean
  1308. XstartDlogFProc(theDialog, theEvent, itemHit)
  1309. XDialogPtr theDialog;
  1310. XEventRecord * theEvent;
  1311. Xshort * itemHit;
  1312. X{
  1313. X    int x, c;
  1314. X
  1315. X    if(theEvent->what == keyDown) {
  1316. X        c = theEvent->message & 0xFF;
  1317. X#ifdef BETA /* We don't want this is no shipped version */
  1318. X        if(c == '#') Debugger();
  1319. X#endif
  1320. X        if(c == 10 || c == 13 || c == 3) { /* Accept */
  1321. X            *itemHit = OK;
  1322. X            return TRUE;
  1323. X        }
  1324. X        if(c == '\t' || c == ' ') { /* Select */
  1325. X            lastDlgBut++;
  1326. X            if(lastDlgBut > RADIO_MAX) lastDlgBut = RADIO_MIN;
  1327. X            *itemHit = lastDlgBut;
  1328. X            return TRUE;
  1329. X        }
  1330. X        if(theEvent->modifiers & cmdKey) {
  1331. X            if(c >= 'a' && c <= 'z') c &= 0x5F; /* Uppercase */
  1332. X            switch(c) {
  1333. X            case 'F' :
  1334. X                *itemHit = FEM;
  1335. X                return TRUE;
  1336. X            case 'X' :
  1337. X                *itemHit = EXP;
  1338. X                return TRUE;
  1339. X            case 'N' :
  1340. X                *itemHit = NO_NEWS_BOX;
  1341. X                return TRUE;
  1342. X            case 'J' :
  1343. X                *itemHit = SCORES;
  1344. X                return TRUE;
  1345. X            default :
  1346. X                for(x=0; RADIO_STRING[x]; x++) {
  1347. X                    if(c == RADIO_STRING[x]) {
  1348. X                        *itemHit = x + RADIO_MIN;
  1349. X                        return TRUE;
  1350. X                    }
  1351. X                }
  1352. X            }
  1353. X            theEvent->what = nullEvent;
  1354. X        }
  1355. X    }
  1356. X
  1357. X    return FALSE;
  1358. X}
  1359. X
  1360. X
  1361. XchangeDgenders(Dlog,fem)
  1362. XDialogPtr Dlog;
  1363. XBoolean fem;
  1364. X{    int kind;
  1365. X    Rect box;
  1366. X    Handle knob;
  1367. X    Str255 ptemp;
  1368. X    if(fem){
  1369. X        GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
  1370. X        strncpy((char*)ptemp,"Cave-Woman",255);
  1371. X        CtoPstr((char*)ptemp);
  1372. X        SetCTitle(knob,ptemp);
  1373. X        GetDItem(Dlog,CLERGY,&kind,&knob,&box);
  1374. X        strncpy((char*)ptemp,"Priestess",255);
  1375. X        CtoPstr((char*)ptemp);
  1376. X        SetCTitle(knob,ptemp);
  1377. X    } else {
  1378. X        GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
  1379. X        strncpy((char*)ptemp,"Cave-Man",255);
  1380. X        CtoPstr((char*)ptemp);
  1381. X        SetCTitle(knob,ptemp);
  1382. X        GetDItem(Dlog,CLERGY,&kind,&knob,&box);
  1383. X        strncpy((char*)ptemp,"Priest",255);
  1384. X        CtoPstr((char*)ptemp);
  1385. X        SetCTitle(knob,ptemp);
  1386. X    }
  1387. X}
  1388. X#endif /* MACOS */
  1389. X
  1390. X
  1391. X#ifdef CHDIR
  1392. Xvoid
  1393. Xchdirx(dir, wr)
  1394. Xchar *dir;
  1395. Xboolean wr;
  1396. X{
  1397. X#ifdef AMIGA
  1398. X    static char thisdir[] = "";
  1399. X#else
  1400. X    static char thisdir[] = ".";
  1401. X#endif
  1402. X    if(dir && chdir(dir) < 0) {
  1403. X        error("Cannot chdir to %s.", dir);
  1404. X    }
  1405. X
  1406. X    /* Change the default drive as well.
  1407. X     */
  1408. X#ifndef AMIGA
  1409. X    chdrive(dir);
  1410. X#endif
  1411. X
  1412. X    /* warn the player if we can't write the record file */
  1413. X    /* perhaps we should also test whether . is writable */
  1414. X    /* unfortunately the access systemcall is worthless */
  1415. X    if(wr) {
  1416. X        register int fd;
  1417. X
  1418. X        if(dir == NULL)
  1419. X        dir = thisdir;
  1420. X#ifdef OS2_CODEVIEW  /* explicit path on opening for OS/2 */
  1421. X        {
  1422. X        char tmp[PATHLEN];
  1423. X
  1424. X        Strcpy(tmp, dir);
  1425. X        append_slash(tmp);
  1426. X        Strcat(tmp, RECORD);
  1427. X        if((fd = open(tmp, O_RDWR)) < 0) {
  1428. X#else
  1429. X        if((fd = open(RECORD, O_RDWR)) < 0) {
  1430. X#endif
  1431. X#ifdef DGK
  1432. X# ifndef OS2_CODEVIEW
  1433. X        char tmp[PATHLEN];
  1434. X
  1435. X        Strcpy(tmp, dir);
  1436. X        append_slash(tmp);
  1437. X# endif
  1438. X        /* try to create empty record */
  1439. X
  1440. X# ifdef OS2_CODEVIEW
  1441. X        if((fd = open(tmp, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
  1442. X            msmsg("Warning: cannot write %s\n", tmp);
  1443. X# else
  1444. X# ifdef AZTEC_C
  1445. X        /* Aztec doesn't use the third argument */
  1446. X        if((fd = open(RECORD, O_CREAT|O_RDWR)) < 0) {
  1447. X            msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
  1448. X# else
  1449. X          if((fd = open(RECORD, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
  1450. X            msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
  1451. X# endif
  1452. X# endif
  1453. X            getreturn("to continue");
  1454. X        } else
  1455. X            (void) close(fd);
  1456. X#else
  1457. X        Printf("Warning: cannot write %s/%s", dir, RECORD);
  1458. X        getret();
  1459. X#endif
  1460. X        } else
  1461. X        (void) close(fd);
  1462. X#ifdef OS2_CODEVIEW
  1463. X        }
  1464. X#endif
  1465. X    }
  1466. X}
  1467. X#endif /* CHDIR /**/
  1468. END_OF_FILE
  1469. if test 19659 -ne `wc -c <'others/pcmain.c'`; then
  1470.     echo shar: \"'others/pcmain.c'\" unpacked with wrong size!
  1471. fi
  1472. # end of 'others/pcmain.c'
  1473. fi
  1474. if test -f 'src/save.c' -a "${1}" != "-c" ; then 
  1475.   echo shar: Will not clobber existing file \"'src/save.c'\"
  1476. else
  1477. echo shar: Extracting \"'src/save.c'\" \(20116 characters\)
  1478. sed "s/^X//" >'src/save.c' <<'END_OF_FILE'
  1479. X/*    SCCS Id: @(#)save.c    3.0    89/04/13
  1480. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1481. X/* NetHack may be freely redistributed.  See license for details. */
  1482. X
  1483. X#define MONATTK_H    /* comment line for pre-compiled headers */
  1484. X/* block some unused #defines to avoid overloading some cpp's */
  1485. X#include "hack.h"
  1486. X#include "lev.h"
  1487. X
  1488. X#ifdef WORM
  1489. X#include "wseg.h"
  1490. X#endif
  1491. X
  1492. X#ifndef NO_SIGNAL
  1493. X#include <signal.h>
  1494. X#endif /* !NO_SIGNAL */
  1495. X#if defined(EXPLORE_MODE) && !defined(LSC) && !defined(O_WRONLY) && !defined(AZTEC_C)
  1496. X#include <fcntl.h>
  1497. X#endif /* EXPLORE_MODE */
  1498. X
  1499. Xboolean hu;        /* set during hang-up */
  1500. X
  1501. X#ifdef DGK
  1502. Xstruct finfo fileinfo[MAXLEVEL+1];
  1503. Xlong bytes_counted;
  1504. Xint count_only;
  1505. X#else
  1506. Xboolean level_exists[MAXLEVEL+1];
  1507. X#endif
  1508. X
  1509. X#ifdef ZEROCOMP
  1510. Xstatic void FDECL(bputc, (UCHAR_P));
  1511. X#endif
  1512. Xstatic void FDECL(saveobjchn, (int,struct obj *));
  1513. Xstatic void FDECL(savemonchn, (int,struct monst *));
  1514. Xstatic void FDECL(savegoldchn, (int,struct gold *));
  1515. Xstatic void FDECL(savetrapchn, (int,struct trap *));
  1516. Xstatic void FDECL(savegenoinfo, (int));
  1517. X#ifdef DGK
  1518. Xstatic void FDECL(savelev0, (int,XCHAR_P));
  1519. Xstatic boolean NDECL(swapout_oldest);
  1520. Xstatic void FDECL(copyfile, (char *,char *));
  1521. X#endif /* DGK */
  1522. Xstatic void FDECL(spill_objs, (struct obj *));
  1523. X#ifdef __GNULINT__
  1524. Xstatic long nulls[10];
  1525. X#else
  1526. X#define nulls nul
  1527. X#endif
  1528. X
  1529. Xint
  1530. Xdosave(){
  1531. X    clrlin();
  1532. X#ifdef MACOS
  1533. X    if(!flags.silent) SysBeep(1);
  1534. X    if(UseMacAlertText(128, "Really save ?") != 1) {
  1535. X#else
  1536. X    pline("Really save? ");    /* especially useful if COMPRESS defined */
  1537. X    if(yn() == 'n') {
  1538. X#endif
  1539. X        clrlin();
  1540. X        (void) fflush(stdout);
  1541. X        if(multi > 0) nomul(0);
  1542. X    } else {
  1543. X        clear_screen();
  1544. X        (void) fflush(stdout);
  1545. X        hu = FALSE;
  1546. X        if(dosave0()) {
  1547. X            settty("Be seeing you...\n");
  1548. X            exit(0);
  1549. X        } else (void)doredraw();
  1550. X    }
  1551. X    return 0;
  1552. X}
  1553. X
  1554. X#ifndef NOSAVEONHANGUP
  1555. Xint
  1556. Xhangup(){
  1557. X    if (!hu)
  1558. X    {
  1559. X        hu = TRUE;
  1560. X        (void) dosave0();
  1561. X# ifndef VMS
  1562. X        exit(1);
  1563. X# endif
  1564. X    }
  1565. X    return 0;
  1566. X}
  1567. X#endif
  1568. X
  1569. X/* returns 1 if save successful */
  1570. Xint
  1571. Xdosave0() {
  1572. X    register int fd, ofd;
  1573. X    int tmp;        /* not register ! */
  1574. X    xchar ltmp;
  1575. X#ifdef DGK
  1576. X    long fds, needed;
  1577. X    int mode;
  1578. X#endif
  1579. X#ifdef COMPRESS
  1580. X    char    cmd[80];
  1581. X#endif
  1582. X#ifdef MACOS
  1583. X    short    savenum;
  1584. X#endif
  1585. X
  1586. X    if (!SAVEF[0])
  1587. X        return 0;
  1588. X
  1589. X#if defined(UNIX) || defined(VMS)
  1590. X    (void) signal(SIGHUP, SIG_IGN);
  1591. X#endif
  1592. X#if !defined(__TURBOC__) && !defined(NO_SIGNAL)
  1593. X    (void) signal(SIGINT, SIG_IGN);
  1594. X#endif
  1595. X
  1596. X#ifdef MSDOS
  1597. X# ifdef DGK
  1598. X    if(!hu && !saveDiskPrompt(0))    return 0;
  1599. X# endif
  1600. X# ifdef EXPLORE_MODE
  1601. X    if(!hu) {
  1602. X#  ifdef AMIGA_WBENCH
  1603. X        (fd = ami_wbench_getsave(O_RDONLY));
  1604. X#  else
  1605. X        (fd = open(SAVEF, O_RDONLY));
  1606. X#  endif
  1607. X        if (fd > 0) {
  1608. X        (void) close(fd);
  1609. X        clrlin();
  1610. X        pline("There seems to be an old save file.  Overwrite it? ");
  1611. X        if (yn() == 'n') return 0;
  1612. X        }
  1613. X    }
  1614. X# endif
  1615. X# ifdef TOS
  1616. X    fd = creat(SAVEF, FCMASK);
  1617. X# else
  1618. X#  ifdef AMIGA_WBENCH
  1619. X    fd=ami_wbench_getsave(O_WRONLY | O_CREAT | O_TRUNC);
  1620. X#  else
  1621. X    (fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK));
  1622. X#  endif
  1623. X# endif
  1624. X#else /* MSDOS */
  1625. X# ifdef EXPLORE_MODE
  1626. X    if(!hu) {
  1627. X        fd = open(SAVEF, O_RDONLY);
  1628. X        if (fd > 0) {
  1629. X        (void) close(fd);
  1630. X        clrlin();
  1631. X        pline("There seems to be an old save file.  Overwrite it? ");
  1632. X        if (yn() == 'n') return 0;
  1633. X        }
  1634. X    }
  1635. X# endif
  1636. X# ifdef MACOS
  1637. X    {
  1638. X        Str255    fileName;
  1639. X        OSErr    er;
  1640. X        struct term_info    *t;
  1641. X        extern WindowPtr    HackWindow;
  1642. X        
  1643. X        t = (term_info *)GetWRefCon(HackWindow);
  1644. X        (void)GetVol(&fileName,&tmp);    /* tmp is old volume */
  1645. X        (void)SetVol(0L, savenum = t->recordVRefNum);    /* savenum is used below */
  1646. X        Strcpy((char *)&fileName[1], SAVEF);
  1647. X        fileName[0] = strlen(SAVEF);
  1648. X
  1649. X        if (er = Create(&fileName, 0, CREATOR, discover ? EXPLORE_TYPE : SAVE_TYPE))
  1650. X            SysBeep(1);
  1651. X        fd = open(SAVEF, O_WRONLY | O_BINARY);
  1652. X        (void)SetVol(0L, t->system.sysVRefNum);
  1653. X    }
  1654. X# else
  1655. X    fd = creat(SAVEF, FCMASK);
  1656. X# endif /* MACOS */
  1657. X#endif /* MSDOS */
  1658. X    if(fd < 0) {
  1659. X        if(!hu) pline("Cannot open save file.");
  1660. X#ifdef AMIGA_WBENCH
  1661. X        ami_wbench_unlink(SAVEF);
  1662. X#endif
  1663. X#ifdef MACOS
  1664. X        (void)SetVol(0L, savenum);
  1665. X#endif
  1666. X        (void) unlink(SAVEF);        /* ab@unido */
  1667. X#ifdef MACOS
  1668. X        (void)SetVol(0L, tmp);
  1669. X#endif
  1670. X        return(0);
  1671. X    }
  1672. X    if(flags.moonphase == FULL_MOON)    /* ut-sally!fletcher */
  1673. X        change_luck(-1);        /* and unido!ab */
  1674. X    home();
  1675. X    cl_end();
  1676. X#ifdef DGK
  1677. X    if(!hu) msmsg("Saving: ");
  1678. X    mode = COUNT;
  1679. Xagain:
  1680. X    savelev(fd, dlevel, mode);
  1681. X    /* count_only will be set properly by savelev */
  1682. X#else
  1683. X# ifdef MACOS
  1684. X    printf("Saving: ");
  1685. X# endif
  1686. X    savelev(fd,dlevel);
  1687. X#endif
  1688. X    saveobjchn(fd, invent);
  1689. X    savemonchn(fd, fallen_down);
  1690. X    savegenoinfo(fd);
  1691. X    tmp = getuid();
  1692. X    bwrite(fd, (genericptr_t) &tmp, sizeof tmp);
  1693. X    bwrite(fd, (genericptr_t) &flags, sizeof(struct flag));
  1694. X    bwrite(fd, (genericptr_t) &dlevel, sizeof dlevel);
  1695. X    bwrite(fd, (genericptr_t) &maxdlevel, sizeof maxdlevel);
  1696. X    bwrite(fd, (genericptr_t) &moves, sizeof moves);
  1697. X    bwrite(fd, (genericptr_t) &monstermoves, sizeof monstermoves);
  1698. X    bwrite(fd, (genericptr_t) &wiz_level, sizeof wiz_level);
  1699. X    bwrite(fd, (genericptr_t) &medusa_level, sizeof medusa_level);
  1700. X    bwrite(fd, (genericptr_t) &bigroom_level, sizeof bigroom_level);
  1701. X#ifdef ORACLE
  1702. X    bwrite(fd, (genericptr_t) &oracle_level, sizeof oracle_level);
  1703. X#endif
  1704. X#ifdef REINCARNATION
  1705. X    bwrite(fd, (genericptr_t) &rogue_level, sizeof rogue_level);
  1706. X#endif
  1707. X#ifdef STRONGHOLD
  1708. X    bwrite(fd, (genericptr_t) &stronghold_level, sizeof stronghold_level);
  1709. X    bwrite(fd, (genericptr_t) &tower_level, sizeof tower_level);
  1710. X    bwrite(fd, (genericptr_t) tune, sizeof tune);
  1711. X#  ifdef MUSIC
  1712. X    bwrite(fd, (genericptr_t) &music_heard, sizeof music_heard);
  1713. X#  endif
  1714. X#endif
  1715. X    bwrite(fd, (genericptr_t) &is_maze_lev, sizeof is_maze_lev);
  1716. X    bwrite(fd, (genericptr_t) &u, sizeof(struct you));
  1717. X#ifdef SPELLS
  1718. X    bwrite(fd, (genericptr_t) spl_book, 
  1719. X                sizeof(struct spell) * (MAXSPELL + 1));
  1720. X#endif
  1721. X#ifdef NAMED_ITEMS
  1722. X    bwrite(fd, (genericptr_t) artiexist, 
  1723. X                (unsigned)(sizeof(boolean) * artifact_num));
  1724. X#endif
  1725. X    if(u.ustuck)
  1726. X        bwrite(fd, (genericptr_t) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
  1727. X    bwrite(fd, (genericptr_t) pl_character, sizeof pl_character);
  1728. X#ifdef TUTTI_FRUTTI
  1729. X    bwrite(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
  1730. X    bwrite(fd, (genericptr_t) ¤t_fruit, sizeof current_fruit);
  1731. X    savefruitchn(fd);
  1732. X#endif
  1733. X    savenames(fd);
  1734. X#ifdef DGK
  1735. X    if (mode == COUNT) {
  1736. X# ifdef ZEROCOMP
  1737. X        bflush(fd);
  1738. X# endif
  1739. X        /* make sure there is enough disk space */
  1740. X        needed = bytes_counted;
  1741. X        for (ltmp = 1; ltmp <= maxdlevel; ltmp++)
  1742. X            if (ltmp != dlevel && fileinfo[ltmp].where)
  1743. X                needed += fileinfo[ltmp].size + (sizeof ltmp);
  1744. X#ifdef AMIGA_WBENCH
  1745. X        needed+=ami_wbench_iconsize(SAVEF);
  1746. X#endif
  1747. X        fds = freediskspace(SAVEF);
  1748. X        if(needed > fds) {
  1749. X            if(!hu) {
  1750. X            pline("There is insufficient space on SAVE disk.");
  1751. X            pline("Require %ld bytes but only have %ld.", needed,
  1752. X                fds);
  1753. X            }
  1754. X            flushout();
  1755. X#ifdef AMIGA_WBENCH
  1756. X            ami_wbench_unlink(SAVEF);
  1757. X#endif
  1758. X            (void) close(fd);
  1759. X            (void) unlink(SAVEF);
  1760. X            return 0;
  1761. X        }
  1762. X        mode = WRITE;
  1763. X        goto again;
  1764. X    }
  1765. X#endif
  1766. X    for(ltmp = (xchar)1; ltmp <= maxdlevel; ltmp++) {
  1767. X#ifdef DGK
  1768. X        if (ltmp == dlevel || !fileinfo[ltmp].where) continue;
  1769. X        if (fileinfo[ltmp].where != ACTIVE)
  1770. X            swapin_file(ltmp);
  1771. X#else
  1772. X        if(ltmp == dlevel || !level_exists[ltmp]) continue;
  1773. X#endif
  1774. X        glo(ltmp);
  1775. X#if defined(DGK) || defined(MACOS)
  1776. X# ifdef MACOS
  1777. X#define msmsg printf
  1778. X# endif
  1779. X        if(!hu) msmsg(".");
  1780. X#endif
  1781. X        if((ofd = open(lock, OMASK)) < 0) {
  1782. X            if(!hu) pline("Error while saving: cannot read %s.", lock);
  1783. X            (void) close(fd);
  1784. X#ifdef MACOS
  1785. X            (void)SetVol(0L, savenum);
  1786. X#endif
  1787. X            (void) unlink(SAVEF);
  1788. X#ifdef MACOS
  1789. X            (void)SetVol(0L, tmp);
  1790. X#endif
  1791. X#ifdef AMIGA_WBENCH
  1792. X            ami_wbench_unlink(SAVEF);
  1793. X#endif
  1794. X            if(!hu) done(TRICKED);
  1795. X            return(0);
  1796. X        }
  1797. X#ifdef ZEROCOMP
  1798. X        minit();
  1799. X#endif
  1800. X        getlev(ofd, hackpid, ltmp, FALSE);
  1801. X        (void) close(ofd);
  1802. X        bwrite(fd, (genericptr_t) <mp, sizeof ltmp);  /* level number */
  1803. X#ifdef DGK
  1804. X        savelev(fd, ltmp, WRITE);            /* actual level */
  1805. X#else
  1806. X        savelev(fd, ltmp);            /* actual level */
  1807. X#endif
  1808. X        (void) unlink(lock);
  1809. X    }
  1810. X#ifdef ZEROCOMP
  1811. X    bflush(fd);
  1812. X#endif
  1813. X    (void) close(fd);
  1814. X    glo(dlevel);
  1815. X    (void) unlink(lock);    /* get rid of current level --jgm */
  1816. X    glo(0);
  1817. X    (void) unlink(lock);
  1818. X#ifdef COMPRESS
  1819. X    Strcpy(cmd, COMPRESS);
  1820. X    Strcat(cmd, " ");
  1821. X# ifdef COMPRESS_OPTIONS
  1822. X    Strcat(cmd, COMPRESS_OPTIONS);
  1823. X    Strcat(cmd, " ");
  1824. X# endif
  1825. X    Strcat(cmd, SAVEF);
  1826. X    (void) system(cmd);
  1827. X#endif
  1828. X#ifdef AMIGA_WBENCH
  1829. X    ami_wbench_iconwrite(SAVEF);
  1830. X#endif
  1831. X#ifdef MACOS
  1832. X    (void)SetVol(0L, tmp);
  1833. X#endif
  1834. X    return(1);
  1835. X}
  1836. X
  1837. X#ifdef DGK
  1838. Xboolean
  1839. Xsavelev(fd, lev, mode)
  1840. Xint fd;
  1841. Xxchar lev;
  1842. Xint mode;
  1843. X{
  1844. X    if (mode & COUNT) {
  1845. X# ifdef ZEROCOMP /* should be superfluous */
  1846. X        if (!count_only)    /* did we just write? */
  1847. X            bflush(0);
  1848. X        /*dbg();*/
  1849. X# endif
  1850. X        count_only = TRUE;
  1851. X        bytes_counted = 0;
  1852. X        savelev0(fd, lev);
  1853. X        while (bytes_counted > freediskspace(levels))
  1854. X            if (!swapout_oldest())
  1855. X                return FALSE;
  1856. X    }
  1857. X    if (mode & WRITE) {
  1858. X# ifdef ZEROCOMP
  1859. X        if (mode & COUNT)    /* did we just count? */
  1860. X            bflush(fd);
  1861. X# endif
  1862. X        count_only = FALSE;
  1863. X        bytes_counted = 0;
  1864. X        savelev0(fd, lev);
  1865. X    }
  1866. X    fileinfo[lev].where = ACTIVE;
  1867. X    fileinfo[lev].time = moves;
  1868. X    fileinfo[lev].size = bytes_counted;
  1869. X    return TRUE;
  1870. X}
  1871. X
  1872. Xstatic
  1873. Xvoid
  1874. Xsavelev0(fd,lev)
  1875. X#else
  1876. Xvoid
  1877. Xsavelev(fd,lev)
  1878. X#endif
  1879. Xint fd;
  1880. Xxchar lev;
  1881. X{
  1882. X#ifdef WORM
  1883. X    register struct wseg *wtmp, *wtmp2;
  1884. X    register int tmp;
  1885. X#endif
  1886. X#ifdef TOS
  1887. X    short tlev;
  1888. X#endif
  1889. X
  1890. X    if(fd < 0) panic("Save on bad file!");    /* impossible */
  1891. X#ifndef DGK
  1892. X    if(lev >= 0 && lev <= MAXLEVEL)
  1893. X        level_exists[lev] = TRUE;
  1894. X#endif
  1895. X    bwrite(fd,(genericptr_t) &hackpid,sizeof(hackpid));
  1896. X#ifdef TOS
  1897. X    tlev=lev; tlev &= 0x00ff;
  1898. X    bwrite(fd,(genericptr_t) &tlev,sizeof(tlev));
  1899. X#else
  1900. X    bwrite(fd,(genericptr_t) &lev,sizeof(lev));
  1901. X#endif
  1902. X#if defined(SMALLDATA) && defined(MACOS)
  1903. X    /* asssumes ROWNO*sizeof(struct rm) < 128 bytes */
  1904. X    {
  1905. X        short    i;
  1906. X        char    length;
  1907. X        char    bufr[256],*ptr,*src,*d,*p;
  1908. X        
  1909. X        d = calloc(ROWNO*COLNO, sizeof(struct rm));
  1910. X        p = d;
  1911. X        for (i = 0; i < COLNO; i++) {
  1912. X            ptr = &bufr[0];
  1913. X            src = (char *)&levl[i][0];
  1914. X            PackBits(&src, &ptr, ROWNO * sizeof(struct rm));
  1915. X            length = (char)(ptr - &bufr[0]);
  1916. X            BlockMove(&length, p++, (Size)1);
  1917. X            BlockMove(bufr, p, (Size)length);
  1918. X            p += (long)length;
  1919. X        }
  1920. X        i = (short)(p - d);
  1921. X        bwrite(fd, (genericptr_t)&i, sizeof(short));
  1922. X        bwrite(fd, (genericptr_t)d, i);
  1923. X        free(d);
  1924. X    }
  1925. X#else
  1926. X    bwrite(fd,(genericptr_t) levl,sizeof(levl));
  1927. X#endif /* SMALLDATA */
  1928. X#ifdef REINCARNATION
  1929. X    if(dlevel == rogue_level && lev != rogue_level)
  1930. X        /* save the symbols actually used to represent the level, not
  1931. X         * those in use for the current level (the default symbols used
  1932. X         * for rogue), since we will need to know whether to update
  1933. X         * the display of the screen when the game is restored under
  1934. X         * a potentially different value of showsyms from the
  1935. X         * environment */
  1936. X        /* if a game is saved while not on rogue level, the usual
  1937. X         * showsyms will be written out for the rogue level too, but
  1938. X         * they will be ignored on restore so it doesn't matter */
  1939. X        bwrite(fd, (genericptr_t) savesyms, sizeof savesyms);
  1940. X    else
  1941. X#endif
  1942. X        bwrite(fd, (genericptr_t) showsyms, sizeof showsyms);
  1943. X    bwrite(fd,(genericptr_t) &monstermoves,sizeof(monstermoves));
  1944. X    bwrite(fd,(genericptr_t) &xupstair,sizeof(xupstair));
  1945. X    bwrite(fd,(genericptr_t) &yupstair,sizeof(yupstair));
  1946. X    bwrite(fd,(genericptr_t) &xdnstair,sizeof(xdnstair));
  1947. X    bwrite(fd,(genericptr_t) &ydnstair,sizeof(ydnstair));
  1948. X#ifdef STRONGHOLD
  1949. X    bwrite(fd,(genericptr_t) &xupladder,sizeof(xupladder));
  1950. X    bwrite(fd,(genericptr_t) &yupladder,sizeof(yupladder));
  1951. X    bwrite(fd,(genericptr_t) &xdnladder,sizeof(xdnladder));
  1952. X    bwrite(fd,(genericptr_t) &ydnladder,sizeof(ydnladder));
  1953. X#endif
  1954. X    bwrite(fd,(genericptr_t) &fountsound,sizeof(fountsound));
  1955. X    bwrite(fd,(genericptr_t) &sinksound,sizeof(sinksound));
  1956. X    savemonchn(fd, fmon);
  1957. X    savegoldchn(fd, fgold);
  1958. X    savetrapchn(fd, ftrap);
  1959. X
  1960. X    saveobjchn(fd, fobj);
  1961. X    saveobjchn(fd, billobjs);
  1962. X
  1963. X    save_engravings(fd);
  1964. X    bwrite(fd,(genericptr_t) rooms,sizeof(rooms));
  1965. X    bwrite(fd,(genericptr_t) doors,sizeof(doors));
  1966. X#ifdef WORM
  1967. X    bwrite(fd,(genericptr_t) wsegs,sizeof(wsegs));
  1968. X    for(tmp=1; tmp<32; tmp++){
  1969. X        for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
  1970. X            wtmp2 = wtmp->nseg;
  1971. X            bwrite(fd,(genericptr_t) wtmp,sizeof(struct wseg));
  1972. X#ifdef DGK
  1973. X            if (!count_only)
  1974. X#endif
  1975. X                free((genericptr_t) wtmp);
  1976. X        }
  1977. X#ifdef DGK
  1978. X        if (!count_only)
  1979. X#endif
  1980. X            wsegs[tmp] = 0;
  1981. X    }
  1982. X    bwrite(fd,(genericptr_t) wgrowtime,sizeof(wgrowtime));
  1983. X#endif /* WORM /**/
  1984. X#ifdef DGK
  1985. X    if (count_only)    return;
  1986. X#endif
  1987. X    billobjs = 0;
  1988. X    fgold = 0;
  1989. X    ftrap = 0;
  1990. X    fmon = 0;
  1991. X    fobj = 0;
  1992. X}
  1993. X
  1994. X#ifdef ZEROCOMP
  1995. X
  1996. X#define RLESC '\0'    /* Leading character for run of LRESC's */
  1997. X#define flushoutrun(ln) bputc(RLESC); bputc(ln); ln = -1;
  1998. X
  1999. Xstatic unsigned char NEARDATA outbuf[BUFSZ];
  2000. Xstatic unsigned short NEARDATA outbufp = 0;
  2001. Xstatic short NEARDATA outrunlength = -1;
  2002. Xstatic int NEARDATA bwritefd;
  2003. X
  2004. X/*dbg()
  2005. X{
  2006. X   if(!hu) printf("outbufp %d outrunlength %d\n", outbufp,outrunlength);
  2007. X}*/
  2008. X
  2009. Xstatic void bputc(c)
  2010. Xunsigned char c;
  2011. X{
  2012. X# ifdef DGK
  2013. X    bytes_counted++;
  2014. X    if (count_only)
  2015. X      return;
  2016. X# endif
  2017. X    if (outbufp >= BUFSZ) {
  2018. X      (void) write(bwritefd, outbuf, (int) BUFSZ);
  2019. X      outbufp = 0;
  2020. X    }
  2021. X    outbuf[outbufp++] = c;
  2022. X}
  2023. X
  2024. Xvoid
  2025. Xbflush(fd)  /* flush run and buffer */
  2026. Xregister int fd;
  2027. X{
  2028. X      bwritefd = fd;
  2029. X      if (outrunlength >= 0) {    /* flush run */
  2030. X      flushoutrun(outrunlength);
  2031. X      }
  2032. X      if (outbufp) {
  2033. X#ifdef DGK
  2034. X      if (!count_only)    /* flush buffer */
  2035. X#endif
  2036. X          (void) write(fd, outbuf, outbufp);
  2037. X      outbufp = 0;
  2038. X      }
  2039. X      /*printf("bflush()"); getret();*/
  2040. X}
  2041. X
  2042. Xvoid
  2043. Xbwrite(fd, loc, num)
  2044. Xregister int fd;
  2045. Xgenericptr_t loc;
  2046. Xregister unsigned num;
  2047. X{
  2048. X      bwritefd = fd;
  2049. X      for (; num; num--, (*(char **)&loc)++) {
  2050. X          if (*((char *)loc) == RLESC) { /* One more char in run */
  2051. X          if (++outrunlength == 0xFF) {
  2052. X              flushoutrun(outrunlength);
  2053. X          }
  2054. X          } else { /* end of run */
  2055. X          if (outrunlength >= 0) {    /* flush run */
  2056. X              flushoutrun(outrunlength);
  2057. X          }
  2058. X          bputc(*((char *)loc));
  2059. X          }
  2060. X      }
  2061. X}
  2062. X
  2063. X#else /* ZEROCOMP */
  2064. X
  2065. Xvoid
  2066. Xbwrite(fd,loc,num)
  2067. Xregister int fd;
  2068. Xregister genericptr_t loc;
  2069. Xregister unsigned num;
  2070. X{
  2071. X#ifdef DGK
  2072. X    bytes_counted += num;
  2073. X    if (!count_only)
  2074. X#endif
  2075. X/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
  2076. X#if defined(BSD) || defined(ULTRIX)
  2077. X        if(write(fd, loc, (int)num) != (int)num) {
  2078. X#else /* e.g. SYSV, __TURBOC__ */
  2079. X        if(write(fd, loc, num) != num) {
  2080. X#endif
  2081. X        if(!hu) panic("cannot write %u bytes to file #%d", num, fd);
  2082. X        else    exit(1);
  2083. X        }
  2084. X}
  2085. X#endif /* ZEROCOMP */
  2086. X
  2087. Xstatic void
  2088. Xsaveobjchn(fd,otmp)
  2089. Xregister int fd;
  2090. Xregister struct obj *otmp;
  2091. X{
  2092. X    register struct obj *otmp2;
  2093. X    unsigned int xl;
  2094. X    int minusone = -1;
  2095. X
  2096. X    while(otmp) {
  2097. X        if(Is_container(otmp))    /* unlink contained objects */
  2098. X        spill_objs(otmp);    /* (this rearranges the list) */
  2099. X
  2100. X        otmp2 = otmp->nobj;
  2101. X        xl = otmp->onamelth;
  2102. X        bwrite(fd, (genericptr_t) &xl, sizeof(int));
  2103. X        bwrite(fd, (genericptr_t) otmp, xl + sizeof(struct obj));
  2104. X#ifdef DGK
  2105. X        if (!count_only)
  2106. X#endif
  2107. X        free((genericptr_t) otmp);
  2108. X        otmp = otmp2;
  2109. X    }
  2110. X    bwrite(fd, (genericptr_t) &minusone, sizeof(int));
  2111. X}
  2112. X
  2113. Xstatic void
  2114. Xsavemonchn(fd,mtmp)
  2115. Xregister int fd;
  2116. Xregister struct monst *mtmp;
  2117. X{
  2118. X    register struct monst *mtmp2;
  2119. X    unsigned int xl;
  2120. X    int minusone = -1;
  2121. X    struct permonst *monbegin = &mons[0];
  2122. X
  2123. X    bwrite(fd, (genericptr_t) &monbegin, sizeof(monbegin));
  2124. X
  2125. X    while(mtmp) {
  2126. X        mtmp2 = mtmp->nmon;
  2127. X        xl = mtmp->mxlth + mtmp->mnamelth;
  2128. X        bwrite(fd, (genericptr_t) &xl, sizeof(int));
  2129. X        bwrite(fd, (genericptr_t) mtmp, xl + sizeof(struct monst));
  2130. X        if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
  2131. X#ifdef DGK
  2132. X        if (!count_only)
  2133. X#endif
  2134. X        free((genericptr_t) mtmp);
  2135. X        mtmp = mtmp2;
  2136. X    }
  2137. X    bwrite(fd, (genericptr_t) &minusone, sizeof(int));
  2138. X}
  2139. X
  2140. Xstatic void
  2141. Xsavegoldchn(fd,gold)
  2142. Xregister int fd;
  2143. Xregister struct gold *gold;
  2144. X{
  2145. X    register struct gold *gold2;
  2146. X    while(gold) {
  2147. X        gold2 = gold->ngold;
  2148. X        bwrite(fd, (genericptr_t) gold, sizeof(struct gold));
  2149. X#ifdef DGK
  2150. X        if (!count_only)
  2151. X#endif
  2152. X            free((genericptr_t) gold);
  2153. X        gold = gold2;
  2154. X    }
  2155. X    bwrite(fd, (genericptr_t)nulls, sizeof(struct gold));
  2156. X}
  2157. X
  2158. Xstatic void
  2159. Xsavetrapchn(fd,trap)
  2160. Xregister int fd;
  2161. Xregister struct trap *trap;
  2162. X{
  2163. X    register struct trap *trap2;
  2164. X    while(trap) {
  2165. X        trap2 = trap->ntrap;
  2166. X        bwrite(fd, (genericptr_t) trap, sizeof(struct trap));
  2167. X#ifdef DGK
  2168. X        if (!count_only)
  2169. X#endif
  2170. X            free((genericptr_t) trap);
  2171. X        trap = trap2;
  2172. X    }
  2173. X    bwrite(fd, (genericptr_t)nulls, sizeof(struct trap));
  2174. X}
  2175. X
  2176. X#ifdef TUTTI_FRUTTI
  2177. X/* save all the fruit names and ID's; this is used only in saving whole games
  2178. X * (not levels) and in saving bones levels.  When saving a bones level,
  2179. X * we only want to save the fruits which exist on the bones level; the bones
  2180. X * level routine marks nonexistent fruits by making the fid negative.
  2181. X */
  2182. Xvoid
  2183. Xsavefruitchn(fd)
  2184. Xregister int fd;
  2185. X{
  2186. X    register struct fruit *f2, *f1;
  2187. X
  2188. X    f1 = ffruit;
  2189. X    while(f1) {
  2190. X        f2 = f1->nextf;
  2191. X        if (f1->fid >= 0) {
  2192. X            bwrite(fd, (genericptr_t) f1, sizeof(struct fruit));
  2193. X        }
  2194. X#ifdef DGK
  2195. X        if (!count_only)
  2196. X#endif
  2197. X            free((genericptr_t) f1);
  2198. X        f1 = f2;
  2199. X    }
  2200. X    bwrite(fd, (genericptr_t)nulls, sizeof(struct fruit));
  2201. X}
  2202. X#endif
  2203. X
  2204. Xstatic void
  2205. Xsavegenoinfo(fd)
  2206. Xregister int fd;
  2207. X{
  2208. X    register int i;
  2209. X
  2210. X    for (i = 0; i < NUMMONS; i++)
  2211. X        bwrite(fd, (genericptr_t) &(mons[i].geno), sizeof(unsigned));
  2212. X}
  2213. X
  2214. X#ifdef DGK
  2215. Xboolean
  2216. Xswapin_file(lev)
  2217. Xint lev;
  2218. X{
  2219. X    char to[PATHLEN], from[PATHLEN];
  2220. X
  2221. X    Sprintf(from, "%s%s", permbones, alllevels);
  2222. X    Sprintf(to, "%s%s", levels, alllevels);
  2223. X    name_file(from, lev);
  2224. X    name_file(to, lev);
  2225. X    while (fileinfo[lev].size > freediskspace(to))
  2226. X        if (!swapout_oldest())
  2227. X            return FALSE;
  2228. X# ifdef WIZARD
  2229. X    if (wizard) {
  2230. X        pline("Swapping in `%s'", from);
  2231. X        (void) fflush(stdout);
  2232. X    }
  2233. X# endif
  2234. X    copyfile(from, to);
  2235. X    (void) unlink(from);
  2236. X    fileinfo[lev].where = ACTIVE;
  2237. X    return TRUE;
  2238. X}
  2239. X
  2240. Xstatic boolean
  2241. Xswapout_oldest() {
  2242. X    char to[PATHLEN], from[PATHLEN];
  2243. X    int i, oldest;
  2244. X    long oldtime;
  2245. X
  2246. X    if (!ramdisk)
  2247. X        return FALSE;
  2248. X    for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++)
  2249. X        if (fileinfo[i].where == ACTIVE
  2250. X        && (!oldtime || fileinfo[i].time < oldtime)) {
  2251. X            oldest = i;
  2252. X            oldtime = fileinfo[i].time;
  2253. X        }
  2254. X    if (!oldest)
  2255. X        return FALSE;
  2256. X    Sprintf(from, "%s%s", levels, alllevels);
  2257. X    Sprintf(to, "%s%s", permbones, alllevels);
  2258. X    name_file(from, oldest);
  2259. X    name_file(to, oldest);
  2260. X# ifdef WIZARD
  2261. X    if (wizard) {
  2262. X        pline("Swapping out `%s'.", from);
  2263. X        (void) fflush(stdout);
  2264. X    }
  2265. X# endif
  2266. X    copyfile(from, to);
  2267. X    (void) unlink(from);
  2268. X    fileinfo[oldest].where = SWAPPED;
  2269. X    return TRUE;
  2270. X}
  2271. X
  2272. Xstatic
  2273. Xvoid
  2274. Xcopyfile(from, to)
  2275. Xchar *from, *to;
  2276. X{
  2277. X# ifdef TOS
  2278. X
  2279. X    if (_copyfile(from, to))
  2280. X        panic("Can't copy %s to %s\n", from, to);
  2281. X# else
  2282. X    char buf[BUFSIZ];
  2283. X    int nfrom, nto, fdfrom, fdto;
  2284. X
  2285. X    if ((fdfrom = open(from, O_RDONLY | O_BINARY, FCMASK)) < 0)
  2286. X        panic("Can't copy from %s !?", from);
  2287. X    if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK)) < 0)
  2288. X        panic("Can't copy to %s", to);
  2289. X    do {
  2290. X        nfrom = read(fdfrom, buf, BUFSIZ);
  2291. X        nto = write(fdto, buf, nfrom);
  2292. X        if (nto != nfrom)
  2293. X            panic("Copyfile failed!");
  2294. X    } while (nfrom == BUFSIZ);
  2295. X    (void) close(fdfrom);
  2296. X    (void) close(fdto);
  2297. X# endif /* TOS */
  2298. X}
  2299. X#endif
  2300. X
  2301. X/*
  2302. X * "spill" objects out of containers (unlinking from the fcobj list).
  2303. X *
  2304. X * The objects will be rearranged, and properly aged.  When we restore, they
  2305. X * can be put back into their containers.  By the time all of the calls to
  2306. X * saveobjchn() been made, the fcobj list should be empty.  Thus it need not
  2307. X * be saved, and doing so could cause some strange addressing problems.
  2308. X *
  2309. X * NOTE:  The cobj field is set to -1.  It will be used as a flag to indicate
  2310. X *      that this object was previously in a container.
  2311. X */
  2312. X
  2313. Xstatic void
  2314. Xspill_objs(cobj)
  2315. Xregister struct obj *cobj;
  2316. X{
  2317. X    register struct obj *otmp, *otmp2, *probj;
  2318. X
  2319. X#if defined(LINT) || defined(__GNULINT__)
  2320. X    probj = (struct obj *)0;    /* suppress "used before set" error */
  2321. X#endif
  2322. X    for(otmp = fcobj; otmp; otmp = otmp2) {
  2323. X
  2324. X        otmp2 = otmp->nobj;
  2325. X        if(otmp->cobj == cobj) {
  2326. X
  2327. X        if(cobj->cursed && rn2(2))    otmp->cursed = 1;
  2328. X    /*
  2329. X     * Place all of the objects in a given container after that container
  2330. X     * in the list.  On restore, they should be able to be picked up and
  2331. X     * put back in.
  2332. X     */
  2333. X        if(otmp == fcobj) fcobj = otmp2;
  2334. X        else          probj->nobj = otmp2;
  2335. X
  2336. X        otmp->nobj = cobj->nobj;
  2337. X        cobj->nobj = otmp;
  2338. X        otmp->cobj = (struct obj *)-1;
  2339. X        } else probj = otmp;
  2340. X    }
  2341. X
  2342. X}
  2343. END_OF_FILE
  2344. if test 20116 -ne `wc -c <'src/save.c'`; then
  2345.     echo shar: \"'src/save.c'\" unpacked with wrong size!
  2346. fi
  2347. # end of 'src/save.c'
  2348. fi
  2349. echo shar: End of archive 37 \(of 56\).
  2350. cp /dev/null ark37isdone
  2351. MISSING=""
  2352. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
  2353.     if test ! -f ark${I}isdone ; then
  2354.     MISSING="${MISSING} ${I}"
  2355.     fi
  2356. done
  2357. if test "${MISSING}" = "" ; then
  2358.     echo You have unpacked all 56 archives.
  2359.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2360. else
  2361.     echo You still need to unpack the following archives:
  2362.     echo "        " ${MISSING}
  2363. fi
  2364. ##  End of shell archive.
  2365. exit 0
  2366.