[comp.sources.games] v10i082: nethack3p9 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 82
Archive-name: nethack3p9/Part37
Supersedes: NetHack3: Volume 7, Issue 56-93



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 37 (of 56)."
# Contents:  others/Makefile.tcc others/pcmain.c src/save.c
# Wrapped by billr@saab on Wed Jul 11 17:11:47 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'others/Makefile.tcc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'others/Makefile.tcc'\"
else
echo shar: Extracting \"'others/Makefile.tcc'\" \(15565 characters\)
sed "s/^X//" >'others/Makefile.tcc' <<'END_OF_FILE'
X#	SCCS Id: @(#)Makefile.tcc	3.0	89/11/20
X#	PC NetHack 3.0 Makefile for Turbo C 2.0
X#	Perpetrator: Mike Threepoint, 890707
X
X###
X### Locals
X###
X# the name of the game
XGAME	= nethack
X
X# the place of the game
XGAMEDIR = \games\$(GAME)
X
X# the filename of the game
XGAMEFILE = $(GAMEDIR)\$(GAME).exe
X
X
X###
X### Directories
X###
X# makedefs.c hardcodes the include and auxil directories, don't change them.
XOBJ	= o
XINCL	= ..\include
XAUX	= ..\auxil
XSRC	= ..\src
XOTHERS	= ..\others
X
X# where the Turbo C libraries are kept
XLIB     = \turbo\c\lib
X
X# directory NDMAKE uses for temporary files
XMAKE_TMP = $(TMP)
X
X
X###
X### Compiler
X###
XCC	= tcc
X
X# must use Huge model; Large is limited to 64K total global data.
XMODEL   = h
X
X# signed chars, jump optimize, strict ANSI, register optimize, no stack frame
XCFLAGS	= -c -no -m$(MODEL) -I$(INCL) -K- -O -A -Z -k- -w-pia -w-pro $(WIZARD)
X## Note: Turbo C 2.0's -Z is bugged.  If you have weird problems, try -Z-.
X
X# wizardly defines
XWIZARD  =
X
X# linkers
XTLINK	= tlink
XLINK	= link
X## There is a bug in TLINK and huge model:
X##
X## TLINK 1.0 treated huge like large, with 64K data limit.
X## TLINK 1.1 fixed that, but chokes over huge data segments anyway.
X## TLINK 2.0 links and is smaller than LINK /EXEPACK, but for some
X## reason with too many objects it produces a file that freaks out
X## and hangs the system.
X##
X## Also note:
X##
X## Using /EXEPACK with LINK will greatly reduce the size of the
X## executable (about 50K), it will also greatly increase the memory
X## required to load it (about 20K).
X
XLIBS	= $(LIB)\c$(MODEL)
X# no need to link in the floating point library
XC0	= $(LIB)\c0$(MODEL).obj
X
XLFLAGS	= /noi /seg:1024
XTLFLAGS = /x/c
X
X# assembler
XASM	= tasm
XAFLAGS	= /MX
X
X# yacc/lex
XYACC	= bison
XLEX	= flex
X
X
X###
X### Rules
X###
X# search order
X.SUFFIXES: .exe .obj .c .asm .y .l
X
X# .l -> .c (for flex)
X.l.c:
X	$(LEX) $<
X	del $@
X	ren lex.yyc $@
X# .y -> .c (for bison)
X.y.c:
X	$(YACC) $<
X	del $@
X	ren y.tbc $@
X	del $*.h
X	ren y.tbh $*.h
X# .c -> .obj
X.c.obj:
X	$(CC) $(CFLAGS) -c $<
X# .asm -> .obj
X.asm.obj:
X	$(ASM) $(AFLAGS) $<;
X# .obj -> .exe (for tlink)
X.obj.exe:
X	$(TLINK) $(TLFLAGS) $(C0) $<, $@,, $(LIBS);
X
X# NDMAKE automatic response file generation
X.RESPONSE_LINK: tlink
X.RESPONSE_LIB:  tlib
X
X
X###
X### Optional features (see pcconf.h)
X###
X# uncomment the definitions used
X
X# overlays
X#OVERLAY = $(OBJ)\trampoli.obj ovlmgr.obj
X#OVERLAY_H = $(INCL)\trampoli.h
X#LINK_LIST = $(OVERLAYS)
XOVERLAY =
XOVERLAY_H =
XLINK_LIST = $(HOBJ)
X
X# Fish's TERMLIB termcap library (see the rule below)
X#TERMLIB = $(LIB)\termlib.lib
XTERMLIB =
X
X# high-quality BSD random number generation routines
X#RANDOM = $(OBJ)\random.obj
XRANDOM =
X
X
X###
X### Dependencies
X###
X# nothing below this line should have to be changed
X# other things that must be reconfigured are in config.h and $(TARG)conf.h
X
X# target prefix
XTARG	= pc
X
X# object files for makedefs.exe
XMAKEOBJS = $(OBJ)\makedefs.obj $(OBJ)\monst.obj $(OBJ)\objects.obj
X
X# object files for lev_comp.exe
XSPLEVOBJS = $(OBJ)\lev_comp.obj   $(OBJ)\lev_lex.obj  $(OBJ)\lev_main.obj \
X	    $(OBJ)\monst.obj	  $(OBJ)\objects.obj
X
X# object files for termlib.lib
XTERMOBJS = $(OBJ)\tgetent.obj  $(OBJ)\tgetflag.obj  $(OBJ)\tgetnum.obj \
X	   $(OBJ)\tgetstr.obj  $(OBJ)\tgoto.obj     $(OBJ)\tputs.obj \
X	   $(OBJ)\isdigit.obj  $(OBJ)\fgetlr.obj
XTERMLIST = -+ $(OBJ)\tgetent.obj -+ $(OBJ)\tgetflag.obj -+ $(OBJ)\tgetnum.obj \
X	   -+ $(OBJ)\tgetstr.obj -+ $(OBJ)\tgoto.obj	-+ $(OBJ)\tputs.obj \
X	   -+ $(OBJ)\isdigit.obj -+ $(OBJ)\fgetlr.obj
X
X# alloc.c is completely unnecessary for any PC NetHack executable.
X# panic.c is unnecessary for makedefs.exe and lev_comp.exe.
X# ioctl.c is unnecessary for nethack.exe.
X
XROOT =	$(OBJ)\main.obj    $(OBJ)\allmain.obj $(OBJ)\msdos.obj \
X	$(OBJ)\termcap.obj $(OBJ)\cmd.obj     $(OBJ)\hack.obj \
X	$(OVERLAY)
X
X# the overlays -- the Microsoft Overlay Linker is limited to 63
X
XOVL01 = $(OBJ)\decl.obj
XOVL02 = $(OBJ)\topl.obj
XOVL03 = $(OBJ)\pri.obj $(OBJ)\prisym.obj
XOVL04 = $(OBJ)\rnd.obj $(RANDOM)
XOVL05 = $(OBJ)\timeout.obj
XOVL06 = $(OBJ)\mon.obj $(OBJ)\exper.obj
XOVL07 = $(OBJ)\attrib.obj
XOVL08 = $(OBJ)\monst.obj $(OBJ)\mondata.obj
XOVL09 = $(OBJ)\monmove.obj $(OBJ)\track.obj
XOVL10 = $(OBJ)\dog.obj $(OBJ)\dogmove.obj
XOVL11 = $(OBJ)\makemon.obj
XOVL12 = $(OBJ)\do_name.obj $(OBJ)\getline.obj
XOVL13 = $(OBJ)\weapon.obj
XOVL14 = $(OBJ)\wield.obj
XOVL15 = $(OBJ)\invent.obj
XOVL16 = $(OBJ)\objects.obj
XOVL17 = $(OBJ)\mkobj.obj $(OBJ)\o_init.obj
XOVL18 = $(OBJ)\objnam.obj
XOVL19 = $(OBJ)\worn.obj
XOVL20 = $(OBJ)\do_wear.obj
XOVL21 = $(OBJ)\trap.obj
XOVL22 = $(OBJ)\dothrow.obj
XOVL23 = $(OBJ)\dokick.obj
XOVL24 = $(OBJ)\uhitm.obj
XOVL25 = $(OBJ)\mhitu.obj
XOVL26 = $(OBJ)\mcastu.obj
XOVL27 = $(OBJ)\mhitm.obj
XOVL28 = $(OBJ)\mthrowu.obj
XOVL29 = $(OBJ)\steal.obj
XOVL30 = $(OBJ)\priest.obj
XOVL31 = $(OBJ)\vault.obj
XOVL32 = $(OBJ)\shk.obj $(OBJ)\shknam.obj
XOVL33 = $(OBJ)\wizard.obj
XOVL34 = $(OBJ)\worm.obj
XOVL35 = $(OBJ)\were.obj
XOVL36 = $(OBJ)\demon.obj
XOVL37 = $(OBJ)\artifact.obj
XOVL38 = $(OBJ)\music.obj $(OBJ)\dbridge.obj
XOVL39 = $(OBJ)\sit.obj $(OBJ)\fountain.obj
XOVL40 = $(OBJ)\sounds.obj
XOVL41 = $(OBJ)\spell.obj
XOVL42 = $(OBJ)\read.obj
XOVL43 = $(OBJ)\potion.obj
XOVL44 = $(OBJ)\zap.obj
XOVL45 = $(OBJ)\eat.obj $(OBJ)\rumors.obj
XOVL46 = $(OBJ)\do.obj
XOVL47 = $(OBJ)\search.obj
XOVL48 = $(OBJ)\lock.obj
XOVL49 = $(OBJ)\apply.obj
XOVL50 = $(OBJ)\engrave.obj $(OBJ)\write.obj
XOVL51 = $(OBJ)\pray.obj
XOVL52 = $(OBJ)\options.obj
XOVL53 = $(OBJ)\pickup.obj
XOVL54 = $(OBJ)\polyself.obj
XOVL55 = $(OBJ)\u_init.obj
XOVL56 = $(OBJ)\extralev.obj
XOVL57 = $(OBJ)\mklev.obj $(OBJ)\mkroom.obj
XOVL58 = $(OBJ)\mkmaze.obj $(OBJ)\sp_lev.obj
XOVL59 = $(OBJ)\restore.obj $(OBJ)\save.obj $(OBJ)\bones.obj
XOVL60 = $(OBJ)\rip.obj $(OBJ)\topten.obj $(OBJ)\end.obj
XOVL61 = $(OBJ)\unix.obj $(OBJ)\tty.obj $(OBJ)\mail.obj
XOVL62 = $(OBJ)\pager.obj
XOVL63 = $(OBJ)\version.obj
X
X# date.h dependencies
XVOBJ = $(ROOT)	$(OVL01) $(OVL02) $(OVL03) $(OVL04) $(OVL05) $(OVL06) $(OVL07) \
X       $(OVL08) $(OVL09) $(OVL10) $(OVL11) $(OVL12) $(OVL13) $(OVL14) $(OVL15) \
X       $(OVL16) $(OVL17) $(OVL18) $(OVL19) $(OVL20) $(OVL21) $(OVL22) $(OVL23) \
X       $(OVL24) $(OVL25) $(OVL26) $(OVL27) $(OVL28) $(OVL29) $(OVL30) $(OVL31) \
X       $(OVL32) $(OVL33) $(OVL34) $(OVL35) $(OVL36) $(OVL37) $(OVL38) $(OVL39) \
X       $(OVL40) $(OVL41) $(OVL42) $(OVL43) $(OVL44) $(OVL45) $(OVL46) $(OVL47) \
X       $(OVL48) $(OVL49) $(OVL50) $(OVL51) $(OVL52) $(OVL53) $(OVL54) $(OVL55) \
X       $(OVL56) $(OVL57) $(OVL58) $(OVL59) $(OVL60) $(OVL61) $(OVL62)
X
X# nethack.exe dependencies, non-overlay link list
XHOBJ =	$(VOBJ) $(OVL63)
X
X# overlay link list
XOVERLAYS = $(ROOT)    ($(OVL01)) ($(OVL02)) ($(OVL03)) ($(OVL04)) ($(OVL05)) \
X	   ($(OVL06)) ($(OVL07)) ($(OVL08)) ($(OVL09)) ($(OVL10)) ($(OVL11)) \
X	   ($(OVL12)) ($(OVL13)) ($(OVL14)) ($(OVL15)) ($(OVL16)) ($(OVL17)) \
X	   ($(OVL18)) ($(OVL19)) ($(OVL20)) ($(OVL21)) ($(OVL22)) ($(OVL23)) \
X	   ($(OVL24)) ($(OVL25)) ($(OVL26)) ($(OVL27)) ($(OVL28)) ($(OVL29)) \
X	   ($(OVL30)) ($(OVL31)) ($(OVL32)) ($(OVL33)) ($(OVL34)) ($(OVL35)) \
X	   ($(OVL36)) ($(OVL37)) ($(OVL38)) ($(OVL39)) ($(OVL40)) ($(OVL41)) \
X	   ($(OVL42)) ($(OVL43)) ($(OVL44)) ($(OVL45)) ($(OVL46)) ($(OVL47)) \
X	   ($(OVL48)) ($(OVL49)) ($(OVL50)) ($(OVL51)) ($(OVL52)) ($(OVL53)) \
X	   ($(OVL54)) ($(OVL55)) ($(OVL56)) ($(OVL57)) ($(OVL58)) ($(OVL59)) \
X	   ($(OVL60)) ($(OVL61)) ($(OVL62)) ($(OVL63))
X
X# header dependencies
X
XPCCONF_H   = $(INCL)\$(TARG)conf.h  $(INCL)\msdos.h	$(INCL)\system.h
XGLOBAL_H   = $(PCCONF_H)	    $(INCL)\global.h	$(INCL)\coord.h
XCONFIG_H   = $(GLOBAL_H)	    $(INCL)\config.h	$(INCL)\tradstdc.h
XTRAP_H	   = $(INCL)\trap.h
XPERMONST_H = $(INCL)\permonst.h     $(INCL)\monattk.h	$(INCL)\monflag.h
XYOUPROP_H  = $(PERMONST_H)	    $(INCL)\prop.h	$(INCL)\mondata.h \
X	     $(INCL)\pm.h	    $(INCL)\youprop.h
XYOU_H	   = $(YOUPROP_H)	    $(INCL)\attrib.h	$(INCL)\monst.h	\
X	     $(INCL)\you.h
XDECL_H	   = $(YOU_H)		    $(INCL)\decl.h	$(INCL)\obj.h \
X	     $(INCL)\onames.h	    $(INCL)\spell.h	$(INCL)\color.h
XHACK_H	   = $(CONFIG_H)	    $(DECL_H)		$(INCL)\trap.h \
X	     $(INCL)\flag.h	    $(INCL)\gold.h	$(INCL)\mkroom.h \
X	     $(INCL)\monsym.h	    $(INCL)\objclass.h	$(INCL)\rm.h \
X	     $(INCL)\hack.h	    $(OVERLAY_H)
X
X## extern.h, and decl.h contain only external declarations.
X##
X## If anything in them changes, all other files involving the changed routines
X## should be changed to reflect them.  Including them in their respective
X## dependency lists will make sure everything is correct, but causes frequent
X## near-total recompiles.  By leaving them out, we allow quicker testing of
X## changes, but we presume the wiz knows to be circumspect.
X
X
X###
X### Main targets
X###
X
X$(GAME): $(GAMEFILE) $(GAMEDIR)\data $(GAMEDIR)\rumors
X
X$(GAMEFILE): $(GAMEDIR) $(OBJ) $(HOBJ) $(TERMLIB) Makefile
X	@echo Linking...
X	if exist $@ del $@
X        $(LINK) $(C0) $(LINK_LIST),$@,,$(LIBS) $(TERMLIB) $(LFLAGS);
X	@echo NetHack is up to date.
X
Xall:	$(GAME) install
X	@echo Done.
X
X$(OBJ):
X	mkdir $(OBJ)
X
X$(GAMEDIR):
X	mkdir $(GAMEDIR)
X	mkdir $(GAMEDIR)\bones
X
X
X###
X### makedefs.exe
X###
X
Xmakedefs.exe:  $(MAKEOBJS)
X	@$(TLINK) $(TLFLAGS) $(C0) $(MAKEOBJS),$@,,$(LIBS);
X
X$(OBJ)\makedefs.obj:  $(INCL)\config.h $(INCL)\permonst.h $(INCL)\objclass.h
X
X
X###
X### makedefs-generated files
X###
X
X# date.h should be remade any time any of the source is modified
X$(INCL)\date.h: 	makedefs.exe $(VOBJ)
X	makedefs -v
X
X$(INCL)\trap.h: 	makedefs.exe
X	makedefs -t
X
X$(INCL)\onames.h:	makedefs.exe
X	makedefs -o
X
X$(INCL)\pm.h:		makedefs.exe
X	makedefs -p
X
X$(GAMEDIR)\data:	makedefs.exe $(AUX)\data.base
X	makedefs -d
X	xcopy $(AUX)\data $(GAMEDIR)
X	del $(AUX)\data
X
X$(GAMEDIR)\rumors:	makedefs.exe $(AUX)\rumors.tru $(AUX)\rumors.fal
X	makedefs -r
X	xcopy $(AUX)\rumors $(GAMEDIR)
X	del $(AUX)\rumors
X
X
X###
X### lev_comp.exe
X###
X
Xlev_comp.exe:  $(SPLEVOBJS)
X	$(TLINK) $(TLFLAGS) $(C0) $(SPLEVOBJS),$@,,$(LIBS);
X
X## Note: UNIX yacc may generate a line reading "#", which Turbo C 2.0, despite
X##	 the manual's claims that it should be ignored, treats as an error.
X##	 You may have to remove such a line to compile lev_comp.c.
X$(OBJ)\lev_comp.obj:  $(HACK_H) $(INCL)\sp_lev.h
X	$(CC) $(CFLAGS) -A- $*.c
X$(OBJ)\lev_lex.obj:  $(INCL)\lev_comp.h $(HACK_H) $(INCL)\sp_lev.h
X$(OBJ)\lev_main.obj:  $(HACK_H) $(INCL)\sp_lev.h
X
X# If you have yacc or lex programs, and make any changes,
X# add some .y.c and .l.c rules to your Make.ini.
X#
X#lev_comp.c:  lev_comp.y
X#lev_lex.c:  lev_comp.l
X
X
X###
X### termlib.lib
X###
X
X#$(TERMLIB): $(TERMOBJS)
X#	tlib $(TERMLIB) /C $(TERMLIST);
X
X
X###
X### Secondary targets
X###
X
Xinstall:  $(GAMEDIR)\NetHack.cnf $(GAMEDIR)\record $(GAMEDIR)\termcap spec_levs
X	xcopy $(AUX)\*. $(GAMEDIR)
X	@echo Auxiliary files installed.
X
X$(GAMEDIR)\NetHack.cnf:
X	xcopy $(OTHERS)\NetHack.cnf $(GAMEDIR)
X$(GAMEDIR)\record:
X	touch $(GAMEDIR)\record
X$(GAMEDIR)\termcap:
X	xcopy $(OTHERS)\termcap $(GAMEDIR)
X
Xspec_levs: $(AUX)\castle.des $(AUX)\endgame.des $(AUX)\tower.des lev_comp.exe
X	lev_comp $(AUX)\castle.des
X	lev_comp $(AUX)\endgame.des
X	lev_comp $(AUX)\tower.des
X	chdir $(AUX)
X	xcopy castle $(GAMEDIR)
X	del castle
X	xcopy endgame $(GAMEDIR)
X	del endgame
X	xcopy tower? $(GAMEDIR)
X	del tower?
X	chdir $(SRC)
X	@echo Special levels compiled.
X
Xclean:
X	del $(OBJ)\*.obj
X	rmdir $(OBJ)
X
Xspotless: clean
X	del $(INCL)\date.h
X	del $(INCL)\onames.h
X	del $(INCL)\pm.h
X	del makedefs.exe
X	if exist lev_comp.exe del lev_comp.exe
X
X
X###
X### Other dependencies
X###
X
X# OS-dependent filenames
X$(OBJ)\main.obj:     $(HACK_H) $(TARG)main.c
X	$(CC) $(CFLAGS) -o$@ $(TARG)main.c
X
X$(OBJ)\tty.obj:      $(HACK_H) $(INCL)\func_tab.h $(TARG)tty.c
X	$(CC) $(CFLAGS) -o$@ $(TARG)tty.c
X
X$(OBJ)\unix.obj:     $(HACK_H) $(TARG)unix.c
X	$(CC) $(CFLAGS) -o$@ $(TARG)unix.c
X
X# GO AHEAD, DELETE THIS LINE
X
X$(OBJ)\allmain.obj:	$(HACK_H)
X$(OBJ)\alloc.obj:	$(CONFIG_H)
X$(OBJ)\apply.obj:	$(HACK_H)   $(INCL)\edog.h
X$(OBJ)\artifact.obj:	$(HACK_H)   $(INCL)\artifact.h
X$(OBJ)\attrib.obj:	$(HACK_H)
X$(OBJ)\bones.obj:	$(HACK_H)
X$(OBJ)\cmd.obj: 	$(HACK_H)   $(INCL)\func_tab.h
X$(OBJ)\dbridge.obj:	$(HACK_H)
X$(OBJ)\decl.obj:	$(HACK_H)
X$(OBJ)\demon.obj:	$(HACK_H)
X$(OBJ)\do.obj:		$(HACK_H)
X$(OBJ)\do_name.obj:	$(HACK_H)
X$(OBJ)\do_wear.obj:	$(HACK_H)
X$(OBJ)\dog.obj: 	$(HACK_H)   $(INCL)\edog.h
X$(OBJ)\dogmove.obj:	$(HACK_H)   $(INCL)\mfndpos.h	 $(INCL)\edog.h
X$(OBJ)\dokick.obj:	$(HACK_H)   $(INCL)\eshk.h
X$(OBJ)\dothrow.obj:	$(HACK_H)
X$(OBJ)\eat.obj: 	$(HACK_H)
X$(OBJ)\end.obj: 	$(HACK_H)   $(INCL)\eshk.h
X$(OBJ)\engrave.obj:	$(HACK_H)
X$(OBJ)\exper.obj:	$(HACK_H)
X$(OBJ)\extralev.obj:	$(HACK_H)
X$(OBJ)\fountain.obj:	$(HACK_H)
X$(OBJ)\getline.obj:	$(HACK_H)   $(INCL)\func_tab.h
X$(OBJ)\hack.obj:	$(HACK_H)
X$(OBJ)\invent.obj:	$(HACK_H)   $(INCL)\lev.h	 $(INCL)\wseg.h
X$(OBJ)\ioctl.obj:	$(HACK_H)
X$(OBJ)\lev_comp.obj:	$(HACK_H)   $(INCL)\sp_lev.h
X$(OBJ)\lev_lex.obj:	$(HACK_H)   $(INCL)\sp_lev.h	 $(INCL)\lev_comp.h
X$(OBJ)\lev_main.obj:	$(HACK_H)
X$(OBJ)\lock.obj:	$(HACK_H)
X$(OBJ)\makemon.obj:	$(HACK_H)
X$(OBJ)\mail.obj:	$(HACK_H)
X$(OBJ)\mcastu.obj:	$(HACK_H)
X$(OBJ)\mhitm.obj:	$(HACK_H)   $(INCL)\artifact.h
X$(OBJ)\mhitu.obj:	$(HACK_H)   $(INCL)\artifact.h	 $(INCL)\edog.h
X$(OBJ)\mklev.obj:	$(HACK_H)
X$(OBJ)\mkmaze.obj:	$(HACK_H)
X$(OBJ)\mkobj.obj:	$(HACK_H)
X$(OBJ)\mkroom.obj:	$(HACK_H)
X$(OBJ)\mon.obj: 	$(HACK_H)   $(INCL)\mfndpos.h	 $(INCL)\wseg.h
X$(OBJ)\mondata.obj:	$(HACK_H)   $(INCL)\eshk.h	 $(INCL)\epri.h
X$(OBJ)\monmove.obj:	$(HACK_H)   $(INCL)\mfndpos.h	 $(INCL)\artifact.h
X$(OBJ)\monst.obj:	$(CONFIG_H) $(PERMONST_H)	 $(INCL)\monsym.h \
X				    $(INCL)\eshk.h	 $(INCL)\vault.h \
X				    $(INCL)\epri.h	 $(INCL)\color.h
X$(OBJ)\msdos.obj:	$(HACK_H) msdos.c
X	$(CC) $(CFLAGS) -A- $*.c
X# set ANSI only off -- many MS-DOS specific things.
X$(OBJ)\mthrowu.obj:	$(HACK_H)
X$(OBJ)\music.obj:	$(HACK_H)
X$(OBJ)\o_init.obj:	$(HACK_H)
X$(OBJ)\objects.obj:	$(CONFIG_H) $(INCL)\obj.h	 $(INCL)\objclass.h \
X				    $(INCL)\prop.h	 $(INCL)\color.h
X$(OBJ)\objnam.obj:	$(HACK_H)
X$(OBJ)\options.obj:	$(HACK_H)
X$(OBJ)\pager.obj:	$(HACK_H)
X$(OBJ)\panic.obj:	$(CONFIG_H)
X$(OBJ)\pickup.obj:	$(HACK_H)
X$(OBJ)\polyself.obj:	$(HACK_H)
X$(OBJ)\potion.obj:	$(HACK_H)
X$(OBJ)\pray.obj:	$(HACK_H)
X$(OBJ)\pri.obj: 	$(HACK_H)   $(INCL)\epri.h	 $(INCL)\termcap.h
X$(OBJ)\priest.obj:	$(HACK_H)   $(INCL)\mfndpos.h	 $(INCL)\eshk.h \
X				    $(INCL)\epri.h
X$(OBJ)\prisym.obj:	$(HACK_H)   $(INCL)\lev.h	 $(INCL)\wseg.h
X$(OBJ)\random.obj:
X$(OBJ)\read.obj:	$(HACK_H)
X$(OBJ)\restore.obj:	$(HACK_H)   $(INCL)\lev.h	 $(INCL)\wseg.h
X$(OBJ)\rip.obj:
X	$(CC) $(CFLAGS) -d- $*.c
X# must not merge strings, or the tombstone lines will overlap
X$(OBJ)\rnd.obj: 	$(HACK_H)
X$(OBJ)\rumors.obj:	$(HACK_H)
X$(OBJ)\save.obj:	$(HACK_H)   $(INCL)\lev.h	 $(INCL)\wseg.h
X$(OBJ)\search.obj:	$(HACK_H)   $(INCL)\artifact.h
X$(OBJ)\shk.obj: 	$(HACK_H)   $(INCL)\eshk.h
X$(OBJ)\shknam.obj:	$(HACK_H)   $(INCL)\eshk.h
X$(OBJ)\sit.obj: 	$(HACK_H)
X$(OBJ)\sounds.obj:	$(HACK_H)   $(INCL)\edog.h	 $(INCL)\eshk.h
X$(OBJ)\sp_lev.obj:	$(HACK_H)   $(INCL)\sp_lev.h
X$(OBJ)\spell.obj:	$(HACK_H)
X$(OBJ)\steal.obj:	$(HACK_H)
X$(OBJ)\termcap.obj:	$(HACK_H)   $(INCL)\termcap.h
X$(OBJ)\timeout.obj:	$(HACK_H)
X$(OBJ)\topl.obj:	$(HACK_H)
X$(OBJ)\topten.obj:	$(HACK_H)
X$(OBJ)\track.obj:	$(HACK_H)
X$(OBJ)\trampoli.obj:	$(HACK_H)
X$(OBJ)\trap.obj:	$(HACK_H)   $(INCL)\edog.h
X$(OBJ)\u_init.obj:	$(HACK_H)
X$(OBJ)\uhitm.obj:	$(HACK_H)   $(INCL)\artifact.h
X$(OBJ)\vault.obj:	$(HACK_H)   $(INCL)\vault.h
X$(OBJ)\version.obj:	$(HACK_H)   $(INCL)\date.h	 $(INCL)\patchlev.h
X$(OBJ)\weapon.obj:	$(HACK_H)
X$(OBJ)\were.obj:	$(HACK_H)
X$(OBJ)\wield.obj:	$(HACK_H)
X$(OBJ)\wizard.obj:	$(HACK_H)
X$(OBJ)\worm.obj:	$(HACK_H)   $(INCL)\wseg.h
X$(OBJ)\worn.obj:	$(HACK_H)
X$(OBJ)\write.obj:	$(HACK_H)
X$(OBJ)\zap.obj: 	$(HACK_H)
END_OF_FILE
if test 15565 -ne `wc -c <'others/Makefile.tcc'`; then
    echo shar: \"'others/Makefile.tcc'\" unpacked with wrong size!
fi
# end of 'others/Makefile.tcc'
fi
if test -f 'others/pcmain.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'others/pcmain.c'\"
else
echo shar: Extracting \"'others/pcmain.c'\" \(19659 characters\)
sed "s/^X//" >'others/pcmain.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)pcmain.c	3.0	90/01/19
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X/* main.c - PC, ST, and Amiga NetHack */
X#include "hack.h"
X
X#ifndef NO_SIGNAL
X#include <signal.h>
X#endif
X#include <ctype.h>
X#ifdef DGK
X#ifndef AMIGA
X#include <sys\stat.h>
X#endif
X#endif
X
X#if defined(LATTICE) || defined(MACOS)
Xextern short *switches;
X#endif
X#ifdef MACOS
Xextern WindowPtr	HackWindow;
Xextern short macflags;
Xpascal boolean FDECL(startDlogFProc, (DialogPtr, EventRecord *, short *));
X#define msmsg mprintf
X#endif
X
X#if !defined(MACOS) && !defined(LATTICE)
Xchar orgdir[PATHLEN];
X#endif
Xchar SAVEF[FILENAME];
X#ifdef MSDOS
Xchar SAVEP[FILENAME];
X#endif
X
Xconst char *hname = "NetHack";	/* used for syntax messages */
X#if !defined(AMIGA) && !defined(MACOS)
Xchar obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
X#endif
Xint hackpid;		/* not used anymore, but kept in for save files */
X
X#if defined(DGK)
Xstruct finfo	zfinfo = ZFINFO;
Xint i;
X#endif /* DGK */
X
X#ifdef __TURBOC__	/* tell Turbo C to make a bigger stack */
Xextern unsigned _stklen = 0x2000;	/* 8K */
Xextern unsigned char _osmajor;
X#endif
X
X#ifdef TOS
Xextern long compiletime;
Xboolean run_from_desktop = TRUE;	/* should we pause before exiting?? */
X# ifdef __GNUC__
Xlong _stksize = 16*1024;
X# endif
X#endif
X
X#ifdef MACOS
X#  ifdef AZTEC
X#define OMASK	O_RDONLY
X#  else
X#define OMASK	(O_RDONLY | O_BINARY )
X#  endif
X# else
X#define OMASK	O_RDONLY
X#endif
X
X#ifdef MACOS
XBoolean justscores;
X#endif
X
X#ifdef AMIGA_WBENCH
Xextern int FromWBench;
X#endif
X
Xint FDECL(main, (int,char **));
X
Xconst char *classes = "ABCEHKPRSTVW";
X
Xint
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	extern int x_maze_max, y_maze_max;
X	register int fd;
X	register char *dir;
X#ifndef AMIGA
X	int (*funcp)();
X#endif
X#ifdef TOS
X	long clock;
X# ifdef __GNUC__
X	extern int _unixmode;
X	_unixmode = 0;
X# endif
X#endif
X#ifdef __TURBOC__
X	if (_osmajor >= 3) hname = argv[0];	/* DOS 3.0+ */
X#endif
X#ifdef TOS
X	if (*argv[0]) {			/* only a CLI can give us argv[0] */
X		hname = argv[0];
X		run_from_desktop = FALSE;
X	}
X#endif
X#ifdef MACOS
X	AppFile	theFile;
X	short	message,numFiles;
X	SFReply	reply;
X
X	initterm(24,80);
X	ObscureCursor();
X# ifdef SMALLDATA
X	init_decl();
X# endif
X	/* user might have started up with a save file, so check */
X	CountAppFiles(&message,&numFiles);
X	if (!message && numFiles) {
X		message = 1;
X
X		while(message <= numFiles) {
X			GetAppFiles(message,&theFile);
X			ClrAppFiles(message);
X			if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE))
X				break;
X			message++;
X		}
X		if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE)) {
X			(void)strncpy(SAVEF, (char *)&theFile.fName[1],
X						(int)theFile.fName[0]);
X			(void)strncpy(plname, (char *)&theFile.fName[1],
X						(int)theFile.fName[0]);
X			SetVol(0L,theFile.vRefNum);
X			SAVEF[(int)theFile.fName[0]] = '\0';
X			numFiles = 1;
X		} else
X			numFiles = 0;
X	}
X#endif
X#if defined(LATTICE) || defined(MACOS)
X	switches = (short *)malloc((NROFOBJECTS+2) * sizeof(long));
X	for (fd = 0; fd < (NROFOBJECTS + 2); fd++)
X		switches[fd] = fd;
X#endif
X
X
X	/*
X	 *  Initialize screen I/O before anything is displayed.
X	 *
X	 *  startup() must be called before initoptions()
X	 *    due to ordering of graphics settings
X	 *  and before error(), due to use of termcap strings.
X	 */
X	gettty();
X#if !defined(AMIGA) && !defined(MACOS)
X	setbuf(stdout,obuf);
X#endif
X	startup();
X#if !defined(AMIGA) && !defined(MACOS)
X	/* Save current directory and make sure it gets restored when
X	 * the game is exited.
X	 */
X	if (getcwd(orgdir, sizeof orgdir) == NULL)
X		error("NetHack: current directory path too long");
X	funcp = (int (*)())exit; /* Kludge to get around LINT_ARGS of signal. */
X# ifndef NO_SIGNAL
X	signal(SIGINT, (SIG_RET_TYPE) funcp);	/* restore original directory */
X# endif
X#endif /* AMIGA || MACOS */
X
X#ifndef MACOS
X	if ((dir = getenv("HACKDIR")) != NULL) {
X		Strcpy(hackdir, dir);
X# ifdef CHDIR
X		chdirx (dir, 1);
X# endif
X	}
X#if defined(AMIGA) && defined(CHDIR)
X	/*
X	 * If we're dealing with workbench, change the directory.  Otherwise
X	 * we could get "Insert disk in drive 0" messages. (Must be done
X	 * before initoptions())....
X	 */
X	if(argc == 0)
X		chdirx(HACKDIR, 1);
X#endif
X
X# if defined(DGK)
X	/* zero "fileinfo" array to prevent crashes on level change */
X	for (i = 0 ; i <= MAXLEVEL; i++) {
X		fileinfo[i] = zfinfo;
X	}
X# endif /* DGK */
X
X	initoptions();
X#ifdef AMIGA_WBENCH
X	ami_wbench_init(argc,argv);
X#endif
X# if defined(TOS) && defined(TEXTCOLOR)
X	if (flags.IBMBIOS && flags.use_color)
X		set_colors();
X# endif
X	if (!hackdir[0])
X#if !defined(LATTICE) && !defined(AMIGA)
X		Strcpy(hackdir, orgdir);
X#else
X		Strcpy(hackdir, HACKDIR);
X#endif
X	if(argc > 1) {
X	    if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
X		/* avoid matching "-dec" for DECgraphics; since the man page
X		 * says -d directory, hope nobody's using -desomething_else
X		 */
X		argc--;
X		argv++;
X		dir = argv[0]+2;
X		if(*dir == '=' || *dir == ':') dir++;
X		if(!*dir && argc > 1) {
X			argc--;
X			argv++;
X			dir = argv[0];
X		}
X		if(!*dir)
X		    error("Flag -d must be followed by a directory name.");
X		Strcpy(hackdir, dir);
X	    } else
X
X	/*
X	 * Now we know the directory containing 'record' and
X	 * may do a prscore().
X	 */
X	    if (!strncmp(argv[1], "-s", 2)) {
X# ifdef CHDIR
X		chdirx(hackdir,0);
X# endif
X		prscore(argc, argv);
X		exit(0);
X	    }
X	}
X#else
X	initoptions();
X#endif	/* MACOS /* */
X
X	/*
X	 * It seems you really want to play.
X	 */
X	setrandom();
X	cls();
X#ifdef TOS
X	if ((unsigned long)time(&clock) < (unsigned long)compiletime)
X		error("Your clock is incorrectly set!");
X#endif
X	u.uhp = 1;	/* prevent RIP on early quits */
X	u.ux = FAR;	/* prevent nscr() */
X
X	/*
X	 * Find the creation date of this game,
X	 * so as to avoid restoring outdated savefiles.
X	 */
X	/* gethdate(hname); */
X
X	/*
X	 * We cannot do chdir earlier, otherwise gethdate will fail.
X	 */
X#ifdef CHDIR
X	chdirx(hackdir,1);
X#endif
X
X#ifndef MACOS
X	/*
X	 * Process options.
X	 */
X	while(argc > 1 && argv[1][0] == '-'){
X		argv++;
X		argc--;
X		switch(argv[0][1]){
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X# ifndef EXPLORE_MODE
X		case 'X':
X# endif
X		case 'D':
X# ifdef WIZARD
X			/* Must have "name" set correctly by NETHACK.CNF,
X			 * NETHACKOPTIONS, or -u
X			 * before this flag to enter wizard mode. */
X#  ifdef KR1ED
X			if(!strcmp(plname, WIZARD_NAME)) {
X#  else
X			if(!strcmp(plname, WIZARD)) {
X#  endif
X				wizard = TRUE;
X				break;
X			}
X			/* otherwise fall thru to discover */
X# endif
X# ifdef EXPLORE_MODE
X		case 'X':
X			discover = TRUE;
X# endif
X			break;
X#endif
X#ifdef NEWS
X		case 'n':
X			flags.nonews = TRUE;
X			break;
X#endif
X		case 'u':
X			if(argv[0][2])
X			  (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X			else if(argc > 1) {
X			  argc--;
X			  argv++;
X			  (void) strncpy(plname, argv[0], sizeof(plname)-1);
X			} else
X				Printf("Player name expected after -u\n");
X			break;
X		case 'i':
X			if(!strcmp(argv[0]+1, "ibm")) assign_ibm_graphics();
X			break;
X		case 'd':
X			if(!strcmp(argv[0]+1, "dec")) assign_dec_graphics();
X			break;
X#ifdef DGK
X		/* Player doesn't want to use a RAM disk
X		 */
X		case 'r':
X			ramdisk = FALSE;
X			break;
X#endif
X		default:
X			if (index(classes, toupper(argv[0][1]))) {
X				/* allow -T for Tourist, etc. */
X				(void) strncpy(pl_character, argv[0]+1,
X					       sizeof(pl_character)-1);
X				break;
X			} else Printf("\nUnknown switch: %s\n", argv[0]);
X		case '?':
XPrintf("\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...", hname, classes);
XPrintf("\n       or");
XPrintf("\n       %s [-d dir] [-u name] [-[%s]]", hname, classes);
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X			Printf(" [-[DX]]");
X#endif
X#ifdef NEWS
X			Printf(" [-n]");
X#endif
X#ifdef DGK
X			Printf(" [-r]");
X#endif
X			putchar('\n');
X			return 0;
X		}
X	}
X#ifdef AMIGA_WBENCH
X	ami_wbench_args();
X#endif
X#ifdef DGK
X	set_lock_and_bones();
X	copybones(FROMPERM);
X#endif
X#ifdef WIZARD
X	if (wizard)
X		Strcpy(plname, "wizard");
X	else
X#endif
X	if (!*plname)
X		askname();
X	plnamesuffix();		/* strip suffix from name; calls askname() */
X				/* again if suffix was whole name */
X				/* accepts any suffix */
X#ifndef DGK
X	Strcpy(lock,plname);
X	Strcat(lock,".99");
X#endif
X#endif /* MACOS */
X	start_screen();
X
X	/*
X	 * Initialisation of the boundaries of the mazes
X	 * Both boundaries have to be even.
X	 */
X
X	x_maze_max = COLNO-1;
X	if (x_maze_max % 2)
X		x_maze_max--;
X	y_maze_max = ROWNO-1;
X	if (y_maze_max % 2)
X		y_maze_max--;
X
X	/* initialize static monster strength array */
X	init_monstr();
X#ifdef MACOS
X	if (!numFiles) {
X		askname();
X		if(justscores){
X			prscore(1,&classes);
X			exit(0);
X		}
X#endif
X#if defined(AMIGA) || defined(MACOS)
X# ifdef AMIGA_WBENCH
X	if(!FromWBench)
X# endif
X	(void) strncat(SAVEF, plname, 31-4);
X#else
X	{
X		int ix = strlen(SAVEF);
X		(void)strncat(SAVEF, plname, 8);
X		regularize(SAVEF+ix);
X	}
X#endif
X#ifndef MACOS
X# ifdef AMIGA_WBENCH
X	if(!FromWBench)
X# endif
X	Strcat(SAVEF, ".sav");
X#else
X	} else {	/* save file start, didn't askname() */
X		char *stripCharSuffix;
X
X		if (stripCharSuffix = strrchr((char *)plname, '-'))
X			*stripCharSuffix = '\0';
X	}
X	Strcpy(lock,plname);
X	Strcat(lock,".99");
X#endif
X	cls();
X	if (
X#ifdef DGK
X# ifdef AMIGA_WBENCH
X	    (FromWBench?1:saveDiskPrompt(1)) &&
X# else
X	    saveDiskPrompt(1) &&
X# endif
X#endif /* DGK */
X#ifdef AMIGA_WBENCH
X	    ((fd=ami_wbench_getsave(OMASK)) >=0) &&
X#else
X	    ((fd = open(SAVEF, OMASK)) >= 0) &&
X#endif
X	   /* if not up-to-date, quietly unlink file via false condition */
X	   (uptodate(fd) || unlink(SAVEF) == 666)) {
X#ifdef WIZARD
X		/* Since wizard is actually flags.debug, restoring might
X		 * overwrite it.
X		 */
X		boolean remember_wiz_mode = wizard;
X#endif
X#ifndef NO_SIGNAL
X		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
X#endif
X		pline("Restoring save file...");
X		(void) fflush(stdout);
X		if(!dorecover(fd))
X			goto not_recovered;
X#ifdef WIZARD
X		if(!wizard && remember_wiz_mode) wizard = TRUE;
X#endif
X		pline("Hello %s, welcome to NetHack!", plname);
X		/* get shopkeeper set properly if restore is in shop */
X		(void) inshop();
X#ifdef EXPLORE_MODE
X		if (discover)
X			You("are in non-scoring discovery mode.");
X#endif
X#if defined(EXPLORE_MODE) || defined(WIZARD)
X		if (discover || wizard) {
X			pline("Do you want to keep the save file? ");
X			if(yn() == 'n'){
X				(void) unlink(SAVEF);
X#ifdef AMIGA_WBENCH
X				ami_wbench_unlink(SAVEF);
X#endif
X			}
X		}
X#endif
X		flags.move = 0;
X	} else {
Xnot_recovered:
X		newgame();
X		/* give welcome message before pickup messages */
X		pline("Hello %s, welcome to NetHack!", plname);
X#ifdef EXPLORE_MODE
X		if (discover)
X			You("are in non-scoring discovery mode.");
X#endif
X		flags.move = 0;
X		set_wear();
X		pickup(1);
X		read_engr_at(u.ux,u.uy);
X	}
X	
X#ifdef MACOS
X	{
X		short	i;
X		MenuHandle	theMenu;
X		Rect	screen;
X		
X		theMenu = GetMHandle(appleMenu);
X		EnableItem(theMenu, 0);
X		EnableItem(theMenu, 1);
X		theMenu = GetMHandle(fileMenu);
X		EnableItem(theMenu,0);
X		for (i = inventMenu;i <= extendMenu; i++) {
X			theMenu = GetMHandle(i);
X			EnableItem(theMenu, 0);
X		}
X		DrawMenuBar();
X		macflags |= fDoUpdate;
X		SetPort(HackWindow);
X		screen = HackWindow->portRect;
X		ValidRect(&screen);
X		
X	}
X#endif
X			
X	flags.moonphase = phase_of_the_moon();
X	if(flags.moonphase == FULL_MOON) {
X		You("are lucky!  Full moon tonight.");
X		if(!u.uluck) change_luck(1);
X	} else if(flags.moonphase == NEW_MOON) {
X		pline("Be careful!  New moon tonight.");
X	}
X
X	initrack();
X#ifndef NO_SIGNAL
X	(void) signal(SIGINT, SIG_IGN);
X#endif
X#ifdef OS2
X	gettty(); /* somehow ctrl-P gets turned back on during startup ... */
X#endif
X
X	moveloop();
X#ifdef MACOS 
X	/* Help for Mac compilers */
X	free_decl();
X#endif
X	return 0;
X}
X
X
X/*
X * plname is filled either by an option (-u Player  or  -uPlayer) or
X * explicitly (by being the wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X */
Xvoid
Xaskname() {
X#ifndef MACOS
X	register int c, ct;
X
X	Printf("\nWho are you? ");
X	(void) fflush(stdout);
X	ct = 0;
X	while((c = Getchar()) != '\n') {
X		if(c == EOF) error("End of input\n");
X		/* some people get confused when their erase char is not ^H */
X		if(c == '\b') {
X			if(ct) {
X				ct--;
X#ifdef MSDOS
X				msmsg("\b \b");
X#endif
X			}
X			continue;
X		}
X		if(ct < sizeof(plname)-1) {
X#if defined(MSDOS)
X			msmsg("%c", c);
X#endif
X			plname[ct++] = c;
X		}
X	}
X	plname[ct] = 0;
X	if(ct == 0) askname();
X}
X#else /* MACOS */
X/* Macintosh startup Dialog written by Andy Swanson 10/20/89
X		modified for to include a few more options 12/17/89 */
X	DialogPtr asknameDlog;
X	DialogTHndl	th, centreDlgBox();
X	int kind;
X	Rect box;
X	Handle knob;
X	Boolean Done;
X	int chtype = 0,Hit,i;
X	Str255 ptemp;
X	char *p;
X#define OK 1
X#define NAME_TEXT 3
X#define RADIO_MIN 5
X#define RADIO_MAX 17
X#define CAVEPERSON 7
X#define CLERGY 11
X#define VALKYRIE 15
X#define ANY 17
X#define WIZ 18
X#define EXP 19
X#define FEM 20
X#define NO_NEWS_BOX 21
X#define SCORES 22
X#define setCheckBox(a,b,c) {GetDItem(a,b,&kind,&knob,&box);SetCtlValue(knob,c?1:0);}
X#define changeRadio(a,b,c) {setCheckBox(a,b,FALSE); setCheckBox(a,c,TRUE);}
X#define Disable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,255);}
X#define Enable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,0);}
X#define Hide(b)  {GetDItem(asknameDlog,b,&kind,&knob,&box);HideControl(knob);\
X			SetDItem(asknameDlog,b,kind+128,knob,&box);}
X	justscores = FALSE;
X	if(p=strrchr((char *)plname, '-')){
X		*p = 0;
X		if(('a'<= p[1]) && ('z'>= p[1]))p[1] += 'A' - 'a';
X		pl_character[0] = p[1];
X		pl_character[1] = 0;
X		if(chtype = (int)index(classes,p[1]))
X			chtype -= (int)(classes)-1;
X		if(p[1] == 'V')
X			flags.female = TRUE;
X	}
X	if(chtype != 0) chtype += 4;
X	else chtype = 17;
X#ifdef THINKC4
X	if(!*plname && (p = getlogin()))
X		(void) strncpy((char *)&plname,p,sizeof(plname)-1);
X#endif
X	th = centreDlgBox(131, FALSE);
X	
X	asknameDlog = GetNewDialog(131,0,-1);
X	
X	ReleaseResource((Handle)th);
X	if(*plname){
X		GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
X		strncpy((char*)ptemp,(char*)&plname,255);
X		CtoPstr((char*)ptemp);
X		SetIText(knob,ptemp);
X	}
X	GetDItem(asknameDlog,chtype,&kind,&knob,&box);
X	SetCtlValue(knob,1);
X	if(flags.female){
X		setCheckBox(asknameDlog,FEM,TRUE);
X		changeDgenders(asknameDlog,TRUE);
X	}
X#ifdef NEWS
X	setCheckBox(asknameDlog,NO_NEWS_BOX,flags.nonews);
X#else
X	Hide(NO_NEWS_BOX);
X#endif
X#ifdef WIZARD
X	wizard = FALSE;
X# ifdef KR1ED
X	if (strcmp(plname,WIZARD_NAME)) {
X# else
X	if (strcmp(plname,WIZARD)) {
X# endif
X#else
X	{
X#endif
X		Hide(WIZ);
X	}
X#ifdef EXPLORE_MODE
X	setCheckBox(asknameDlog,EXP,discover);
X#else
X		Hide(EXP);
X#endif
X	SelIText(asknameDlog, NAME_TEXT, 0, 32767);
X	ShowWindow(asknameDlog);
X	Done = FALSE;
X	while (!Done){
X		ModalDialog(startDlogFProc, &Hit);
X		if(Hit == OK){
X			Done = TRUE;
X			GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
X			GetIText(knob,&ptemp);
X			PtoCstr((char*)ptemp);
X			(void) strncpy((char*)&plname,(char*)ptemp,sizeof(plname)-1);
X			pl_character[0]=classes[chtype-5];
X			pl_character[1]=0;
X			HideWindow(asknameDlog);
X		} else if((Hit >= RADIO_MIN) && (Hit <= RADIO_MAX)){
X			extern int lastDlgBut;
X			
X			changeRadio(asknameDlog,chtype,Hit);
X			lastDlgBut = chtype = Hit;
X			if ((chtype == VALKYRIE) && !flags.female) {
X				flags.female = TRUE;
X				setCheckBox(asknameDlog,FEM,flags.female);
X				changeDgenders(asknameDlog,TRUE);
X			}
X		} else if(Hit == WIZ) {
X			wizard = !wizard;
X			setCheckBox(asknameDlog,WIZ,wizard);
X		} else if(Hit == EXP) {
X			discover = !discover;
X			setCheckBox(asknameDlog,EXP,discover);
X		} else if(Hit == FEM) {
X			flags.female = !flags.female;
X			setCheckBox(asknameDlog,FEM,flags.female);
X			if(chtype == VALKYRIE) {
X				chtype = ANY;
X				changeRadio(asknameDlog,VALKYRIE,ANY);
X			}
X			changeDgenders(asknameDlog,flags.female);
X		} else if(Hit == NO_NEWS_BOX) {
X			flags.nonews = !flags.nonews;
X			setCheckBox(asknameDlog,NO_NEWS_BOX,flags.nonews);
X		} else if(Hit == SCORES) {
X			justscores = !justscores;
X			setCheckBox(asknameDlog,SCORES,justscores);
X			if(justscores) for (i=RADIO_MIN;i<SCORES;i++) {
X				Disable(i);
X				}
X			else for (i=RADIO_MIN;i<SCORES;i++)
X				Enable(i);
X		}
X	}
X	DisposDialog(asknameDlog);
X}
X
X
X#define RADIO_STRING "ABCEHKPRSTVWL"
Xint	lastDlgBut = ANY;
X
X/* The filterProc for handling character selection from keyboard
X   by h+@nada.kth.se                                             */
Xpascal boolean
XstartDlogFProc(theDialog, theEvent, itemHit)
XDialogPtr theDialog;
XEventRecord * theEvent;
Xshort * itemHit;
X{
X	int x, c;
X
X	if(theEvent->what == keyDown) {
X		c = theEvent->message & 0xFF;
X#ifdef BETA /* We don't want this is no shipped version */
X		if(c == '#') Debugger();
X#endif
X		if(c == 10 || c == 13 || c == 3) { /* Accept */
X			*itemHit = OK;
X			return TRUE;
X		}
X		if(c == '\t' || c == ' ') { /* Select */
X			lastDlgBut++;
X			if(lastDlgBut > RADIO_MAX) lastDlgBut = RADIO_MIN;
X			*itemHit = lastDlgBut;
X			return TRUE;
X		}
X		if(theEvent->modifiers & cmdKey) {
X			if(c >= 'a' && c <= 'z') c &= 0x5F; /* Uppercase */
X			switch(c) {
X			case 'F' :
X				*itemHit = FEM;
X				return TRUE;
X			case 'X' :
X				*itemHit = EXP;
X				return TRUE;
X			case 'N' :
X				*itemHit = NO_NEWS_BOX;
X				return TRUE;
X			case 'J' :
X				*itemHit = SCORES;
X				return TRUE;
X			default :
X				for(x=0; RADIO_STRING[x]; x++) {
X					if(c == RADIO_STRING[x]) {
X						*itemHit = x + RADIO_MIN;
X						return TRUE;
X					}
X				}
X			}
X			theEvent->what = nullEvent;
X		}
X	}
X
X	return FALSE;
X}
X
X
XchangeDgenders(Dlog,fem)
XDialogPtr Dlog;
XBoolean fem;
X{	int kind;
X	Rect box;
X	Handle knob;
X	Str255 ptemp;
X	if(fem){
X		GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
X		strncpy((char*)ptemp,"Cave-Woman",255);
X		CtoPstr((char*)ptemp);
X		SetCTitle(knob,ptemp);
X		GetDItem(Dlog,CLERGY,&kind,&knob,&box);
X		strncpy((char*)ptemp,"Priestess",255);
X		CtoPstr((char*)ptemp);
X		SetCTitle(knob,ptemp);
X	} else {
X		GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
X		strncpy((char*)ptemp,"Cave-Man",255);
X		CtoPstr((char*)ptemp);
X		SetCTitle(knob,ptemp);
X		GetDItem(Dlog,CLERGY,&kind,&knob,&box);
X		strncpy((char*)ptemp,"Priest",255);
X		CtoPstr((char*)ptemp);
X		SetCTitle(knob,ptemp);
X	}
X}
X#endif /* MACOS */
X
X
X#ifdef CHDIR
Xvoid
Xchdirx(dir, wr)
Xchar *dir;
Xboolean wr;
X{
X#ifdef AMIGA
X	static char thisdir[] = "";
X#else
X	static char thisdir[] = ".";
X#endif
X	if(dir && chdir(dir) < 0) {
X		error("Cannot chdir to %s.", dir);
X	}
X
X	/* Change the default drive as well.
X	 */
X#ifndef AMIGA
X	chdrive(dir);
X#endif
X
X	/* warn the player if we can't write the record file */
X	/* perhaps we should also test whether . is writable */
X	/* unfortunately the access systemcall is worthless */
X	if(wr) {
X	    register int fd;
X
X	    if(dir == NULL)
X		dir = thisdir;
X#ifdef OS2_CODEVIEW  /* explicit path on opening for OS/2 */
X	    {
X	    char tmp[PATHLEN];
X
X	    Strcpy(tmp, dir);
X	    append_slash(tmp);
X	    Strcat(tmp, RECORD);
X	    if((fd = open(tmp, O_RDWR)) < 0) {
X#else
X	    if((fd = open(RECORD, O_RDWR)) < 0) {
X#endif
X#ifdef DGK
X# ifndef OS2_CODEVIEW
X		char tmp[PATHLEN];
X
X		Strcpy(tmp, dir);
X		append_slash(tmp);
X# endif
X		/* try to create empty record */
X
X# ifdef OS2_CODEVIEW
X		if((fd = open(tmp, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
X		    msmsg("Warning: cannot write %s\n", tmp);
X# else
X# ifdef AZTEC_C
X		/* Aztec doesn't use the third argument */
X		if((fd = open(RECORD, O_CREAT|O_RDWR)) < 0) {
X		    msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
X# else
X  		if((fd = open(RECORD, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
X		    msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
X# endif
X# endif
X		    getreturn("to continue");
X		} else
X		    (void) close(fd);
X#else
X		Printf("Warning: cannot write %s/%s", dir, RECORD);
X		getret();
X#endif
X	    } else
X		(void) close(fd);
X#ifdef OS2_CODEVIEW
X	    }
X#endif
X	}
X}
X#endif /* CHDIR /**/
END_OF_FILE
if test 19659 -ne `wc -c <'others/pcmain.c'`; then
    echo shar: \"'others/pcmain.c'\" unpacked with wrong size!
fi
# end of 'others/pcmain.c'
fi
if test -f 'src/save.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/save.c'\"
else
echo shar: Extracting \"'src/save.c'\" \(20116 characters\)
sed "s/^X//" >'src/save.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)save.c	3.0	89/04/13
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#define MONATTK_H	/* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include "hack.h"
X#include "lev.h"
X
X#ifdef WORM
X#include "wseg.h"
X#endif
X
X#ifndef NO_SIGNAL
X#include <signal.h>
X#endif /* !NO_SIGNAL */
X#if defined(EXPLORE_MODE) && !defined(LSC) && !defined(O_WRONLY) && !defined(AZTEC_C)
X#include <fcntl.h>
X#endif /* EXPLORE_MODE */
X
Xboolean hu;		/* set during hang-up */
X
X#ifdef DGK
Xstruct finfo fileinfo[MAXLEVEL+1];
Xlong bytes_counted;
Xint count_only;
X#else
Xboolean level_exists[MAXLEVEL+1];
X#endif
X
X#ifdef ZEROCOMP
Xstatic void FDECL(bputc, (UCHAR_P));
X#endif
Xstatic void FDECL(saveobjchn, (int,struct obj *));
Xstatic void FDECL(savemonchn, (int,struct monst *));
Xstatic void FDECL(savegoldchn, (int,struct gold *));
Xstatic void FDECL(savetrapchn, (int,struct trap *));
Xstatic void FDECL(savegenoinfo, (int));
X#ifdef DGK
Xstatic void FDECL(savelev0, (int,XCHAR_P));
Xstatic boolean NDECL(swapout_oldest);
Xstatic void FDECL(copyfile, (char *,char *));
X#endif /* DGK */
Xstatic void FDECL(spill_objs, (struct obj *));
X#ifdef __GNULINT__
Xstatic long nulls[10];
X#else
X#define nulls nul
X#endif
X
Xint
Xdosave(){
X	clrlin();
X#ifdef MACOS
X	if(!flags.silent) SysBeep(1);
X	if(UseMacAlertText(128, "Really save ?") != 1) {
X#else
X	pline("Really save? ");	/* especially useful if COMPRESS defined */
X	if(yn() == 'n') {
X#endif
X		clrlin();
X		(void) fflush(stdout);
X		if(multi > 0) nomul(0);
X	} else {
X		clear_screen();
X		(void) fflush(stdout);
X		hu = FALSE;
X		if(dosave0()) {
X			settty("Be seeing you...\n");
X			exit(0);
X		} else (void)doredraw();
X	}
X	return 0;
X}
X
X#ifndef NOSAVEONHANGUP
Xint
Xhangup(){
X	if (!hu)
X	{
X		hu = TRUE;
X		(void) dosave0();
X# ifndef VMS
X		exit(1);
X# endif
X	}
X	return 0;
X}
X#endif
X
X/* returns 1 if save successful */
Xint
Xdosave0() {
X	register int fd, ofd;
X	int tmp;		/* not register ! */
X	xchar ltmp;
X#ifdef DGK
X	long fds, needed;
X	int mode;
X#endif
X#ifdef COMPRESS
X	char	cmd[80];
X#endif
X#ifdef MACOS
X	short	savenum;
X#endif
X
X	if (!SAVEF[0])
X		return 0;
X
X#if defined(UNIX) || defined(VMS)
X	(void) signal(SIGHUP, SIG_IGN);
X#endif
X#if !defined(__TURBOC__) && !defined(NO_SIGNAL)
X	(void) signal(SIGINT, SIG_IGN);
X#endif
X
X#ifdef MSDOS
X# ifdef DGK
X	if(!hu && !saveDiskPrompt(0))	return 0;
X# endif
X# ifdef EXPLORE_MODE
X	if(!hu) {
X#  ifdef AMIGA_WBENCH
X	    (fd = ami_wbench_getsave(O_RDONLY));
X#  else
X	    (fd = open(SAVEF, O_RDONLY));
X#  endif
X	    if (fd > 0) {
X		(void) close(fd);
X		clrlin();
X		pline("There seems to be an old save file.  Overwrite it? ");
X		if (yn() == 'n') return 0;
X	    }
X	}
X# endif
X# ifdef TOS
X	fd = creat(SAVEF, FCMASK);
X# else
X#  ifdef AMIGA_WBENCH
X	fd=ami_wbench_getsave(O_WRONLY | O_CREAT | O_TRUNC);
X#  else
X	(fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK));
X#  endif
X# endif
X#else /* MSDOS */
X# ifdef EXPLORE_MODE
X	if(!hu) {
X	    fd = open(SAVEF, O_RDONLY);
X	    if (fd > 0) {
X		(void) close(fd);
X		clrlin();
X		pline("There seems to be an old save file.  Overwrite it? ");
X		if (yn() == 'n') return 0;
X	    }
X	}
X# endif
X# ifdef MACOS
X	{
X		Str255	fileName;
X		OSErr	er;
X		struct term_info	*t;
X		extern WindowPtr	HackWindow;
X		
X		t = (term_info *)GetWRefCon(HackWindow);
X		(void)GetVol(&fileName,&tmp);	/* tmp is old volume */
X		(void)SetVol(0L, savenum = t->recordVRefNum);	/* savenum is used below */
X		Strcpy((char *)&fileName[1], SAVEF);
X		fileName[0] = strlen(SAVEF);
X
X		if (er = Create(&fileName, 0, CREATOR, discover ? EXPLORE_TYPE : SAVE_TYPE))
X			SysBeep(1);
X		fd = open(SAVEF, O_WRONLY | O_BINARY);
X		(void)SetVol(0L, t->system.sysVRefNum);
X	}
X# else
X	fd = creat(SAVEF, FCMASK);
X# endif /* MACOS */
X#endif /* MSDOS */
X	if(fd < 0) {
X		if(!hu) pline("Cannot open save file.");
X#ifdef AMIGA_WBENCH
X		ami_wbench_unlink(SAVEF);
X#endif
X#ifdef MACOS
X		(void)SetVol(0L, savenum);
X#endif
X		(void) unlink(SAVEF);		/* ab@unido */
X#ifdef MACOS
X		(void)SetVol(0L, tmp);
X#endif
X		return(0);
X	}
X	if(flags.moonphase == FULL_MOON)	/* ut-sally!fletcher */
X		change_luck(-1);		/* and unido!ab */
X	home();
X	cl_end();
X#ifdef DGK
X	if(!hu) msmsg("Saving: ");
X	mode = COUNT;
Xagain:
X	savelev(fd, dlevel, mode);
X	/* count_only will be set properly by savelev */
X#else
X# ifdef MACOS
X	printf("Saving: ");
X# endif
X	savelev(fd,dlevel);
X#endif
X	saveobjchn(fd, invent);
X	savemonchn(fd, fallen_down);
X	savegenoinfo(fd);
X	tmp = getuid();
X	bwrite(fd, (genericptr_t) &tmp, sizeof tmp);
X	bwrite(fd, (genericptr_t) &flags, sizeof(struct flag));
X	bwrite(fd, (genericptr_t) &dlevel, sizeof dlevel);
X	bwrite(fd, (genericptr_t) &maxdlevel, sizeof maxdlevel);
X	bwrite(fd, (genericptr_t) &moves, sizeof moves);
X	bwrite(fd, (genericptr_t) &monstermoves, sizeof monstermoves);
X	bwrite(fd, (genericptr_t) &wiz_level, sizeof wiz_level);
X	bwrite(fd, (genericptr_t) &medusa_level, sizeof medusa_level);
X	bwrite(fd, (genericptr_t) &bigroom_level, sizeof bigroom_level);
X#ifdef ORACLE
X	bwrite(fd, (genericptr_t) &oracle_level, sizeof oracle_level);
X#endif
X#ifdef REINCARNATION
X	bwrite(fd, (genericptr_t) &rogue_level, sizeof rogue_level);
X#endif
X#ifdef STRONGHOLD
X	bwrite(fd, (genericptr_t) &stronghold_level, sizeof stronghold_level);
X	bwrite(fd, (genericptr_t) &tower_level, sizeof tower_level);
X	bwrite(fd, (genericptr_t) tune, sizeof tune);
X#  ifdef MUSIC
X	bwrite(fd, (genericptr_t) &music_heard, sizeof music_heard);
X#  endif
X#endif
X	bwrite(fd, (genericptr_t) &is_maze_lev, sizeof is_maze_lev);
X	bwrite(fd, (genericptr_t) &u, sizeof(struct you));
X#ifdef SPELLS
X	bwrite(fd, (genericptr_t) spl_book, 
X				sizeof(struct spell) * (MAXSPELL + 1));
X#endif
X#ifdef NAMED_ITEMS
X	bwrite(fd, (genericptr_t) artiexist, 
X				(unsigned)(sizeof(boolean) * artifact_num));
X#endif
X	if(u.ustuck)
X		bwrite(fd, (genericptr_t) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
X	bwrite(fd, (genericptr_t) pl_character, sizeof pl_character);
X#ifdef TUTTI_FRUTTI
X	bwrite(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
X	bwrite(fd, (genericptr_t) &current_fruit, sizeof current_fruit);
X	savefruitchn(fd);
X#endif
X	savenames(fd);
X#ifdef DGK
X	if (mode == COUNT) {
X# ifdef ZEROCOMP
X		bflush(fd);
X# endif
X		/* make sure there is enough disk space */
X		needed = bytes_counted;
X		for (ltmp = 1; ltmp <= maxdlevel; ltmp++)
X			if (ltmp != dlevel && fileinfo[ltmp].where)
X				needed += fileinfo[ltmp].size + (sizeof ltmp);
X#ifdef AMIGA_WBENCH
X		needed+=ami_wbench_iconsize(SAVEF);
X#endif
X		fds = freediskspace(SAVEF);
X		if(needed > fds) {
X		    if(!hu) {
X			pline("There is insufficient space on SAVE disk.");
X			pline("Require %ld bytes but only have %ld.", needed,
X				fds);
X		    }
X		    flushout();
X#ifdef AMIGA_WBENCH
X		    ami_wbench_unlink(SAVEF);
X#endif
X		    (void) close(fd);
X		    (void) unlink(SAVEF);
X		    return 0;
X		}
X		mode = WRITE;
X		goto again;
X	}
X#endif
X	for(ltmp = (xchar)1; ltmp <= maxdlevel; ltmp++) {
X#ifdef DGK
X		if (ltmp == dlevel || !fileinfo[ltmp].where) continue;
X		if (fileinfo[ltmp].where != ACTIVE)
X			swapin_file(ltmp);
X#else
X		if(ltmp == dlevel || !level_exists[ltmp]) continue;
X#endif
X		glo(ltmp);
X#if defined(DGK) || defined(MACOS)
X# ifdef MACOS
X#define msmsg printf
X# endif
X		if(!hu) msmsg(".");
X#endif
X		if((ofd = open(lock, OMASK)) < 0) {
X		    if(!hu) pline("Error while saving: cannot read %s.", lock);
X		    (void) close(fd);
X#ifdef MACOS
X			(void)SetVol(0L, savenum);
X#endif
X		    (void) unlink(SAVEF);
X#ifdef MACOS
X			(void)SetVol(0L, tmp);
X#endif
X#ifdef AMIGA_WBENCH
X		    ami_wbench_unlink(SAVEF);
X#endif
X		    if(!hu) done(TRICKED);
X		    return(0);
X		}
X#ifdef ZEROCOMP
X		minit();
X#endif
X		getlev(ofd, hackpid, ltmp, FALSE);
X		(void) close(ofd);
X		bwrite(fd, (genericptr_t) &ltmp, sizeof ltmp);  /* level number */
X#ifdef DGK
X		savelev(fd, ltmp, WRITE);			/* actual level */
X#else
X		savelev(fd, ltmp);			/* actual level */
X#endif
X		(void) unlink(lock);
X	}
X#ifdef ZEROCOMP
X	bflush(fd);
X#endif
X	(void) close(fd);
X	glo(dlevel);
X	(void) unlink(lock);	/* get rid of current level --jgm */
X	glo(0);
X	(void) unlink(lock);
X#ifdef COMPRESS
X	Strcpy(cmd, COMPRESS);
X	Strcat(cmd, " ");
X# ifdef COMPRESS_OPTIONS
X	Strcat(cmd, COMPRESS_OPTIONS);
X	Strcat(cmd, " ");
X# endif
X	Strcat(cmd, SAVEF);
X	(void) system(cmd);
X#endif
X#ifdef AMIGA_WBENCH
X	ami_wbench_iconwrite(SAVEF);
X#endif
X#ifdef MACOS
X	(void)SetVol(0L, tmp);
X#endif
X	return(1);
X}
X
X#ifdef DGK
Xboolean
Xsavelev(fd, lev, mode)
Xint fd;
Xxchar lev;
Xint mode;
X{
X	if (mode & COUNT) {
X# ifdef ZEROCOMP /* should be superfluous */
X		if (!count_only)	/* did we just write? */
X			bflush(0);
X		/*dbg();*/
X# endif
X		count_only = TRUE;
X		bytes_counted = 0;
X		savelev0(fd, lev);
X		while (bytes_counted > freediskspace(levels))
X			if (!swapout_oldest())
X				return FALSE;
X	}
X	if (mode & WRITE) {
X# ifdef ZEROCOMP
X		if (mode & COUNT)	/* did we just count? */
X			bflush(fd);
X# endif
X		count_only = FALSE;
X		bytes_counted = 0;
X		savelev0(fd, lev);
X	}
X	fileinfo[lev].where = ACTIVE;
X	fileinfo[lev].time = moves;
X	fileinfo[lev].size = bytes_counted;
X	return TRUE;
X}
X
Xstatic
Xvoid
Xsavelev0(fd,lev)
X#else
Xvoid
Xsavelev(fd,lev)
X#endif
Xint fd;
Xxchar lev;
X{
X#ifdef WORM
X	register struct wseg *wtmp, *wtmp2;
X	register int tmp;
X#endif
X#ifdef TOS
X	short tlev;
X#endif
X
X	if(fd < 0) panic("Save on bad file!");	/* impossible */
X#ifndef DGK
X	if(lev >= 0 && lev <= MAXLEVEL)
X		level_exists[lev] = TRUE;
X#endif
X	bwrite(fd,(genericptr_t) &hackpid,sizeof(hackpid));
X#ifdef TOS
X	tlev=lev; tlev &= 0x00ff;
X	bwrite(fd,(genericptr_t) &tlev,sizeof(tlev));
X#else
X	bwrite(fd,(genericptr_t) &lev,sizeof(lev));
X#endif
X#if defined(SMALLDATA) && defined(MACOS)
X	/* asssumes ROWNO*sizeof(struct rm) < 128 bytes */
X	{
X		short	i;
X		char	length;
X		char	bufr[256],*ptr,*src,*d,*p;
X		
X		d = calloc(ROWNO*COLNO, sizeof(struct rm));
X		p = d;
X		for (i = 0; i < COLNO; i++) {
X			ptr = &bufr[0];
X			src = (char *)&levl[i][0];
X			PackBits(&src, &ptr, ROWNO * sizeof(struct rm));
X			length = (char)(ptr - &bufr[0]);
X			BlockMove(&length, p++, (Size)1);
X			BlockMove(bufr, p, (Size)length);
X			p += (long)length;
X		}
X		i = (short)(p - d);
X		bwrite(fd, (genericptr_t)&i, sizeof(short));
X		bwrite(fd, (genericptr_t)d, i);
X		free(d);
X	}
X#else
X	bwrite(fd,(genericptr_t) levl,sizeof(levl));
X#endif /* SMALLDATA */
X#ifdef REINCARNATION
X	if(dlevel == rogue_level && lev != rogue_level)
X		/* save the symbols actually used to represent the level, not
X		 * those in use for the current level (the default symbols used
X		 * for rogue), since we will need to know whether to update
X		 * the display of the screen when the game is restored under
X		 * a potentially different value of showsyms from the
X		 * environment */
X		/* if a game is saved while not on rogue level, the usual
X		 * showsyms will be written out for the rogue level too, but
X		 * they will be ignored on restore so it doesn't matter */
X		bwrite(fd, (genericptr_t) savesyms, sizeof savesyms);
X	else
X#endif
X		bwrite(fd, (genericptr_t) showsyms, sizeof showsyms);
X	bwrite(fd,(genericptr_t) &monstermoves,sizeof(monstermoves));
X	bwrite(fd,(genericptr_t) &xupstair,sizeof(xupstair));
X	bwrite(fd,(genericptr_t) &yupstair,sizeof(yupstair));
X	bwrite(fd,(genericptr_t) &xdnstair,sizeof(xdnstair));
X	bwrite(fd,(genericptr_t) &ydnstair,sizeof(ydnstair));
X#ifdef STRONGHOLD
X	bwrite(fd,(genericptr_t) &xupladder,sizeof(xupladder));
X	bwrite(fd,(genericptr_t) &yupladder,sizeof(yupladder));
X	bwrite(fd,(genericptr_t) &xdnladder,sizeof(xdnladder));
X	bwrite(fd,(genericptr_t) &ydnladder,sizeof(ydnladder));
X#endif
X	bwrite(fd,(genericptr_t) &fountsound,sizeof(fountsound));
X	bwrite(fd,(genericptr_t) &sinksound,sizeof(sinksound));
X	savemonchn(fd, fmon);
X	savegoldchn(fd, fgold);
X	savetrapchn(fd, ftrap);
X
X	saveobjchn(fd, fobj);
X	saveobjchn(fd, billobjs);
X
X	save_engravings(fd);
X	bwrite(fd,(genericptr_t) rooms,sizeof(rooms));
X	bwrite(fd,(genericptr_t) doors,sizeof(doors));
X#ifdef WORM
X	bwrite(fd,(genericptr_t) wsegs,sizeof(wsegs));
X	for(tmp=1; tmp<32; tmp++){
X		for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
X			wtmp2 = wtmp->nseg;
X			bwrite(fd,(genericptr_t) wtmp,sizeof(struct wseg));
X#ifdef DGK
X			if (!count_only)
X#endif
X				free((genericptr_t) wtmp);
X		}
X#ifdef DGK
X		if (!count_only)
X#endif
X			wsegs[tmp] = 0;
X	}
X	bwrite(fd,(genericptr_t) wgrowtime,sizeof(wgrowtime));
X#endif /* WORM /**/
X#ifdef DGK
X	if (count_only)	return;
X#endif
X	billobjs = 0;
X	fgold = 0;
X	ftrap = 0;
X	fmon = 0;
X	fobj = 0;
X}
X
X#ifdef ZEROCOMP
X
X#define RLESC '\0'    /* Leading character for run of LRESC's */
X#define flushoutrun(ln) bputc(RLESC); bputc(ln); ln = -1;
X
Xstatic unsigned char NEARDATA outbuf[BUFSZ];
Xstatic unsigned short NEARDATA outbufp = 0;
Xstatic short NEARDATA outrunlength = -1;
Xstatic int NEARDATA bwritefd;
X
X/*dbg()
X{
X   if(!hu) printf("outbufp %d outrunlength %d\n", outbufp,outrunlength);
X}*/
X
Xstatic void bputc(c)
Xunsigned char c;
X{
X# ifdef DGK
X    bytes_counted++;
X    if (count_only)
X      return;
X# endif
X    if (outbufp >= BUFSZ) {
X      (void) write(bwritefd, outbuf, (int) BUFSZ);
X      outbufp = 0;
X    }
X    outbuf[outbufp++] = c;
X}
X
Xvoid
Xbflush(fd)  /* flush run and buffer */
Xregister int fd;
X{
X      bwritefd = fd;
X      if (outrunlength >= 0) {    /* flush run */
X	  flushoutrun(outrunlength);
X      }
X      if (outbufp) {
X#ifdef DGK
X	  if (!count_only)    /* flush buffer */
X#endif
X		  (void) write(fd, outbuf, outbufp);
X	  outbufp = 0;
X      }
X      /*printf("bflush()"); getret();*/
X}
X
Xvoid
Xbwrite(fd, loc, num)
Xregister int fd;
Xgenericptr_t loc;
Xregister unsigned num;
X{
X      bwritefd = fd;
X      for (; num; num--, (*(char **)&loc)++) {
X	      if (*((char *)loc) == RLESC) { /* One more char in run */
X		  if (++outrunlength == 0xFF) {
X		      flushoutrun(outrunlength);
X		  }
X	      } else { /* end of run */
X		  if (outrunlength >= 0) {    /* flush run */
X		      flushoutrun(outrunlength);
X		  }
X		  bputc(*((char *)loc));
X	      }
X      }
X}
X
X#else /* ZEROCOMP */
X
Xvoid
Xbwrite(fd,loc,num)
Xregister int fd;
Xregister genericptr_t loc;
Xregister unsigned num;
X{
X#ifdef DGK
X	bytes_counted += num;
X	if (!count_only)
X#endif
X/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
X#if defined(BSD) || defined(ULTRIX)
X	    if(write(fd, loc, (int)num) != (int)num) {
X#else /* e.g. SYSV, __TURBOC__ */
X	    if(write(fd, loc, num) != num) {
X#endif
X		if(!hu) panic("cannot write %u bytes to file #%d", num, fd);
X		else	exit(1);
X	    }
X}
X#endif /* ZEROCOMP */
X
Xstatic void
Xsaveobjchn(fd,otmp)
Xregister int fd;
Xregister struct obj *otmp;
X{
X	register struct obj *otmp2;
X	unsigned int xl;
X	int minusone = -1;
X
X	while(otmp) {
X	    if(Is_container(otmp))	/* unlink contained objects */
X		spill_objs(otmp);	/* (this rearranges the list) */
X
X	    otmp2 = otmp->nobj;
X	    xl = otmp->onamelth;
X	    bwrite(fd, (genericptr_t) &xl, sizeof(int));
X	    bwrite(fd, (genericptr_t) otmp, xl + sizeof(struct obj));
X#ifdef DGK
X	    if (!count_only)
X#endif
X		free((genericptr_t) otmp);
X	    otmp = otmp2;
X	}
X	bwrite(fd, (genericptr_t) &minusone, sizeof(int));
X}
X
Xstatic void
Xsavemonchn(fd,mtmp)
Xregister int fd;
Xregister struct monst *mtmp;
X{
X	register struct monst *mtmp2;
X	unsigned int xl;
X	int minusone = -1;
X	struct permonst *monbegin = &mons[0];
X
X	bwrite(fd, (genericptr_t) &monbegin, sizeof(monbegin));
X
X	while(mtmp) {
X		mtmp2 = mtmp->nmon;
X		xl = mtmp->mxlth + mtmp->mnamelth;
X		bwrite(fd, (genericptr_t) &xl, sizeof(int));
X		bwrite(fd, (genericptr_t) mtmp, xl + sizeof(struct monst));
X		if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
X#ifdef DGK
X		if (!count_only)
X#endif
X		free((genericptr_t) mtmp);
X		mtmp = mtmp2;
X	}
X	bwrite(fd, (genericptr_t) &minusone, sizeof(int));
X}
X
Xstatic void
Xsavegoldchn(fd,gold)
Xregister int fd;
Xregister struct gold *gold;
X{
X	register struct gold *gold2;
X	while(gold) {
X		gold2 = gold->ngold;
X		bwrite(fd, (genericptr_t) gold, sizeof(struct gold));
X#ifdef DGK
X		if (!count_only)
X#endif
X			free((genericptr_t) gold);
X		gold = gold2;
X	}
X	bwrite(fd, (genericptr_t)nulls, sizeof(struct gold));
X}
X
Xstatic void
Xsavetrapchn(fd,trap)
Xregister int fd;
Xregister struct trap *trap;
X{
X	register struct trap *trap2;
X	while(trap) {
X		trap2 = trap->ntrap;
X		bwrite(fd, (genericptr_t) trap, sizeof(struct trap));
X#ifdef DGK
X		if (!count_only)
X#endif
X			free((genericptr_t) trap);
X		trap = trap2;
X	}
X	bwrite(fd, (genericptr_t)nulls, sizeof(struct trap));
X}
X
X#ifdef TUTTI_FRUTTI
X/* save all the fruit names and ID's; this is used only in saving whole games
X * (not levels) and in saving bones levels.  When saving a bones level,
X * we only want to save the fruits which exist on the bones level; the bones
X * level routine marks nonexistent fruits by making the fid negative.
X */
Xvoid
Xsavefruitchn(fd)
Xregister int fd;
X{
X	register struct fruit *f2, *f1;
X
X	f1 = ffruit;
X	while(f1) {
X		f2 = f1->nextf;
X		if (f1->fid >= 0) {
X			bwrite(fd, (genericptr_t) f1, sizeof(struct fruit));
X		}
X#ifdef DGK
X		if (!count_only)
X#endif
X			free((genericptr_t) f1);
X		f1 = f2;
X	}
X	bwrite(fd, (genericptr_t)nulls, sizeof(struct fruit));
X}
X#endif
X
Xstatic void
Xsavegenoinfo(fd)
Xregister int fd;
X{
X	register int i;
X
X	for (i = 0; i < NUMMONS; i++)
X		bwrite(fd, (genericptr_t) &(mons[i].geno), sizeof(unsigned));
X}
X
X#ifdef DGK
Xboolean
Xswapin_file(lev)
Xint lev;
X{
X	char to[PATHLEN], from[PATHLEN];
X
X	Sprintf(from, "%s%s", permbones, alllevels);
X	Sprintf(to, "%s%s", levels, alllevels);
X	name_file(from, lev);
X	name_file(to, lev);
X	while (fileinfo[lev].size > freediskspace(to))
X		if (!swapout_oldest())
X			return FALSE;
X# ifdef WIZARD
X	if (wizard) {
X		pline("Swapping in `%s'", from);
X		(void) fflush(stdout);
X	}
X# endif
X	copyfile(from, to);
X	(void) unlink(from);
X	fileinfo[lev].where = ACTIVE;
X	return TRUE;
X}
X
Xstatic boolean
Xswapout_oldest() {
X	char to[PATHLEN], from[PATHLEN];
X	int i, oldest;
X	long oldtime;
X
X	if (!ramdisk)
X		return FALSE;
X	for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++)
X		if (fileinfo[i].where == ACTIVE
X		&& (!oldtime || fileinfo[i].time < oldtime)) {
X			oldest = i;
X			oldtime = fileinfo[i].time;
X		}
X	if (!oldest)
X		return FALSE;
X	Sprintf(from, "%s%s", levels, alllevels);
X	Sprintf(to, "%s%s", permbones, alllevels);
X	name_file(from, oldest);
X	name_file(to, oldest);
X# ifdef WIZARD
X	if (wizard) {
X		pline("Swapping out `%s'.", from);
X		(void) fflush(stdout);
X	}
X# endif
X	copyfile(from, to);
X	(void) unlink(from);
X	fileinfo[oldest].where = SWAPPED;
X	return TRUE;
X}
X
Xstatic
Xvoid
Xcopyfile(from, to)
Xchar *from, *to;
X{
X# ifdef TOS
X
X	if (_copyfile(from, to))
X		panic("Can't copy %s to %s\n", from, to);
X# else
X	char buf[BUFSIZ];
X	int nfrom, nto, fdfrom, fdto;
X
X	if ((fdfrom = open(from, O_RDONLY | O_BINARY, FCMASK)) < 0)
X		panic("Can't copy from %s !?", from);
X	if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK)) < 0)
X		panic("Can't copy to %s", to);
X	do {
X		nfrom = read(fdfrom, buf, BUFSIZ);
X		nto = write(fdto, buf, nfrom);
X		if (nto != nfrom)
X			panic("Copyfile failed!");
X	} while (nfrom == BUFSIZ);
X	(void) close(fdfrom);
X	(void) close(fdto);
X# endif /* TOS */
X}
X#endif
X
X/*
X * "spill" objects out of containers (unlinking from the fcobj list).
X *
X * The objects will be rearranged, and properly aged.  When we restore, they
X * can be put back into their containers.  By the time all of the calls to
X * saveobjchn() been made, the fcobj list should be empty.  Thus it need not
X * be saved, and doing so could cause some strange addressing problems.
X *
X * NOTE:  The cobj field is set to -1.  It will be used as a flag to indicate
X *	  that this object was previously in a container.
X */
X
Xstatic void
Xspill_objs(cobj)
Xregister struct obj *cobj;
X{
X	register struct obj *otmp, *otmp2, *probj;
X
X#if defined(LINT) || defined(__GNULINT__)
X	probj = (struct obj *)0;    /* suppress "used before set" error */
X#endif
X	for(otmp = fcobj; otmp; otmp = otmp2) {
X
X	    otmp2 = otmp->nobj;
X	    if(otmp->cobj == cobj) {
X
X		if(cobj->cursed && rn2(2))	otmp->cursed = 1;
X	/*
X	 * Place all of the objects in a given container after that container
X	 * in the list.  On restore, they should be able to be picked up and
X	 * put back in.
X	 */
X		if(otmp == fcobj) fcobj = otmp2;
X		else		  probj->nobj = otmp2;
X
X		otmp->nobj = cobj->nobj;
X		cobj->nobj = otmp;
X		otmp->cobj = (struct obj *)-1;
X	    } else probj = otmp;
X	}
X
X}
END_OF_FILE
if test 20116 -ne `wc -c <'src/save.c'`; then
    echo shar: \"'src/save.c'\" unpacked with wrong size!
fi
# end of 'src/save.c'
fi
echo shar: End of archive 37 \(of 56\).
cp /dev/null ark37isdone
MISSING=""
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
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 56 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0