home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume10
/
nethack3p9
/
part37
< prev
next >
Wrap
Internet Message Format
|
1990-07-27
|
60KB
Path: uunet!mailrus!cornell!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v10i082: nethack3p9 - display oriented dungeons & dragons (Ver. 3.0i), Part37/56
Message-ID: <5940@tekred.CNA.TEK.COM>
Date: 12 Jul 90 16:09:25 GMT
Sender: news@tekred.CNA.TEK.COM
Lines: 2355
Approved: billr@saab.CNA.TEK.COM
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) ¤t_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) <mp, 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