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) ¤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