billr@saab.CNA.TEK.COM (Bill Randle) (04/24/91)
Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 12, Issue 64
Archive-name: larn2/Part11
Supersedes: larn: Volume 11, Issue 84-94
Environment: Unix, VMS, MS-DOS, OS/2, termcap
#! /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 11 (of 12)."
# Contents: larn123.fix makefile.pc nansi.doc regen.c signal.c
# spheres.c tgetstr.c vms.c
# Wrapped by billr@saab on Tue Apr 23 13:50:37 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'larn123.fix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'larn123.fix'\"
else
echo shar: Extracting \"'larn123.fix'\" \(7408 characters\)
sed "s/^X//" >'larn123.fix' <<'END_OF_FILE'
XThis is a list of the fixes and enhancements made to create Larn V12.3 from
XLarn 12.2. SPOILER ALERT!
X
X1. The player's position is now marked with an ampersand, instead of just with
X the cursor.
X
X2. The 'G' command ("give the stairs a kick") has been removed. Since you can
X tell the stairs apart (as opposed to the original Larn 12.0), this command
X doesn't make sense anymore.
X
X3. The 'V' command has been removed and its information incorporated into the
X 'v' command.
X
X4. An idea from Ultra-Larn: when the player enters the 5th level branch of the
X bank after teleporting, the '?' in the level display is changed to a '5'.
X
X5. Larn -? can be used to print command line arguments.
X
X6. The player is no longer positioned near the shaft of the volcano when
X climbing down to the first volcano level.
X
X7. A couple of pauses were eliminated, making some actions very fast now.
X
X8. The player can no longer escape punishment by donating more gold then he
X possesses when praying at the altar.
X
X9. When performing an action and doing an inventory list, a character typed at
X the "press space for more" prompt is taken as the inventory item to select.
X That is, if you say 'q' for quaff, '*' to see all the potions you can quaff,
X Larn used to require that you type a space before you could select a potion,
X causing the list to disappear. You can now select an item in the list while
X the list is displayed. You can also use Escape and Return in place of a
X space.
X
X10. The spells/potions/scrolls inventory ('I' command) are now sorted.
X
X11. The '/' command has been added, to allow the user to identify objects.
X You can choose to either type a character or move the cursor around to
X select a character to identify (a la Hack). The only limitation is that
X characters that have several objects (weapons, gems, dragons, etc) display
X all the matching object names.
X
X12. The potion of gold detection has been changed into the potion of object
X detection. It will find scrolls, books, potions, weapons, armor, and
X artifacts. If you have an old savefile, all gold detection potions get
X turned into object detection potions.
X
X13. It is now possible to find rings of cleverness in the dungeon.
X
X14. It is now possible for killed monsters to drop splint mail, battle axes,
X cookies, and rings of cleverness.
X
X15. Source cleanup, reduction in the size of the executable and the memory
X required, performance improvements.
X
X16. Fix problems with positioning the player when entering or leaving the
X dungeon. You will no longer find yourself on the opposite side of the
X town level when leaving the dungeon. You will no longer be able to enter
X the dungeon on top of a monster.
X
X17. Prevented monsters from moving into the dungeon entrance, causing them to
X be destroyed when the player exits the dungeon. The top dungeon level now
X has the dungeon entrance character where there used to be a space.
X
X18. If you are standing on a chest and try and open it, you will no longer pick
X it up immediately if you have auto-pickup on.
X
X19. Added the capability to add comments to the options file.
X
X20. Fixed the bug where a missing options file prevented anything from being
X displayed.
X
X21. There is now a visible repeat count when greater than 10 (a la Hack). You
X can also edit the repeat count.
X
X22. The 'm' command has been added to move onto an object without picking it
X up (a la Hack).
X
X23. Fixed a problem where the a) item in the inventory couldn't be dulled.
X
X25. Allow a space between '-o' and the option filename.
X
X26. Fix possible errors when looking at the inventory.
X
X27. Prevent the player from changing levels into a level from the maze file with
X a space that had no means of exit.
X
X================================================================================
X
XThis is a list of the fixes and enhancements made to create Larn V12.2 from
XLarn 12.0. SPOILER ALERT!
X
XChanges made to create version 12.2 from 12.1:
X
X1. Add messages to improve feedback to the user.
X
X2. Improved screen drawing performance again.
X
X3. Flying monsters (bats, floating eyes) are no longer affected by traps.
X
X4. Added HACK-like objects, with 'original-objects' option.
X
X5. Added 'bold-objects' option.
X
X6. Fixed a bug where the game would apparently 'hang' for a long period of
X time, especially just after killing a monster with a missile spell.
X
X7. Prevented invulnerability when doing VPR on a throne or altar.
X
X8. Scrolls of pulverization now have the same affect when directed against
X an altar or fountain as they did directed against a throne. VPR spell
X cause a waterlord to appear when used near a fountain.
X
X9. Added the '@' command and 'auto-pickup' option.
X
X10. Added 'prompt-on-objects' option.
X
X11. Improved monster movement performance again.
X
X12. You can now weild '-' to unweild your weapon.
X
X13. Waterlords can now be found in the dungeon, not just when washing at a
X fountain.
X
X14. The Eye of Larn can now be sold in the Trading Post.
X
X15. Spells can now bounce off mirrors at an angle.
X
X
XChanges made to create version 12.1 from 12.0:
X
X1. When drinking at a fountain, "improved sight" caused the "see invisible"
X potion to be known by the player. The player must now identify the potion
X in the usual manner.
X
X2. Falling through a pit told you the damage you received, but falling through
X a trap door did not. Made trap doors act the same as pits.
X
X3. If you dropped a ring of dexterity/strength/cleverness that had been dulled
X to a negative amount, the corresponding stat was permanently increased. No
X longer.
X
X4. The potion of monster location would show invisible monsters as the floor
X character on new levels. Now prevented.
X
X5. Selling all your gems at the bank could destroy items in your inventory.
X
X6. Monster creation was being allowed on closed doors. This was particularly
X a problem with treasure rooms, since it meant that a monster much too
X powerful for the player to handle was loose in the maze. Monsters cannot
X now be created on closed doors.
X
X7. When entering a number (when entering gold amounts) you could not use the
X backspace key to delete digits. Fixed.
X
X8. To make it more convenient when selling items in the Larn Trading Post, a
X display of those items in the players inventory that can be sold has been
X added.
X
X9. Performance of the display has been improved slightly.
X
X10. Monster movement has been improved for large numbers of monsters. It is
X somewhat better on PC's, even with aggravation.
X
X11. I have added new mazes to LARN.MAZ.
X
X12. A Rogue-like command mode has been added, and is the default. The
X version 12.0 prompting mode has been preserved for those who like it,
X accessible via a command line option. Command letters have been added
X to provide the ability to perform all the same actions as the prompt mode.
X The help file and command line help have been updated. When in command
X mode, the player will automatically pick up objects, and can read, quaff,
X eat, look at, and pick up objects that you are standing on.
X
X In order to implement the new commands, the A and D commands from version
X 12.0 have been changed. They are now ^A and I. For consistancy, to see
X the list of known spells at the spell prompt, 'I' also shows all known
X spells.
END_OF_FILE
if test 7408 -ne `wc -c <'larn123.fix'`; then
echo shar: \"'larn123.fix'\" unpacked with wrong size!
fi
# end of 'larn123.fix'
fi
if test -f 'makefile.pc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.pc'\"
else
echo shar: Extracting \"'makefile.pc'\" \(6666 characters\)
sed "s/^X//" >'makefile.pc' <<'END_OF_FILE'
X############################################################################
X#
X# A list of available compile-time defines:
X#
X# BSD - use BSD specific features (mostly timer and signal stuff)
X# BSD4.1 - use BSD4.1 to avoid some 4.2 dependencies (must be used with
X# BSD above; do not mix with SYSV)
X# DECRainbow - DEC Rainbow specific display code.
X# DOCHECKPOINTS - if not defined, checkpoint files are periodically written
X# by the larn process (no forking) if enabled in the .larnopts
X# description file. Checkpointing is handy on an unreliable
X# system, but takes CPU. Inclusion of DOCHECKPOINTS will cause
X# fork()ing to perform the checkpoints (again if enabled in
X# the .larnopts file). This usually avoids pauses in larn
X# while the checkpointing is being done (on large machines).
X# EXTRA - incorporates code to gather additional performance stats
X# FLUSHNO=# - Set the input queue excess flushing threshold (default 5)
X# HIDEBYLINK - if defined, the program attempts to hide from ps
X# MACRORND - Define to use macro version of rnd() and rund() (fast & big)
X# MAIL - system supports mail messages (see bill.c). Not useful on
X# non-networked machines.
X# MSDOS - MS-DOS specific code.
X# OS2LARN - OS/2 Specific code. MSDOS must be defined.
X# NONAP - causes napms() to return immediately instead of delaying
X# n milliseconds. This define may be needed on some systems
X# if the nap stuff does not work correctly (possible hang).
X# nap() is primarilly used to delay for effect when casting
X# missile type spells.
X# NOVARARGS - Define for systems that don't have varargs (a default
X# varargs will be used).
X# RFCMAIL - mail messages are RFC822 conformant. Must be used with
X# MAIL above.
X# SAVEINHOME - put save files in users HOME instead of LARNHOME (default)
X# SYSV - use system III/V (instead of V7) type ioctl calls
X# TIMECHECK - incorporates code to disable play during working hours (8-5)
X# UIDSCORE - Define to use user id's to manage scoreboard. Leaving this
X# out will cause player id's from the file ".playerids" to
X# be used instead. (.playerids is created upon demand).
X# Only one entry per id # is allowed in each scoreboard
X# (winning & non-winning).
X# VT100 - Compile for using vt100 family of terminals. Omission of
X# this define will cause larn to use termcap.
X# WIZID=xxx - this is the userid (or playerid) of the wizard. Default is
X# zero (superuser), which disables all wizard functions.
X# Players must have this userid (or playerid) in order to
X# become the non-scoring wizard player. Definition of WIZID
X# to non-zero will enable the special wizard debugging
X# commands. For root to become wizard, use WIZID= -1.
X#
X############################################################################
X#
X# Configuration options
X# LARNHOME is the directory where the larn data files will be installed.
X# BINDIR is the directory where the larn binary will be installed.
X#
XLARNHOME = # The current directory unless changed in larn.opt
XBINDIR = c:\games
XCC= tcc
XOPTIONS = -DSYSV -DMSDOS -DNOVARARGS
X
X########################################################################
X#
XOBJS= action.obj \
X bill.obj \
X config.obj \
X create.obj \
X data.obj \
X diag.obj \
X display.obj \
X fgetlr.obj \
X fortune.obj \
X global.obj \
X help.obj \
X iventory.obj\
X io.obj \
X main.obj \
X monster.obj \
X moreobj.obj \
X movem.obj \
X msdos.obj \
X nap.obj \
X object.obj \
X regen.obj \
X savelev.obj \
X scores.obj \
X signal.obj \
X spheres.obj \
X spells.obj \
X store.obj \
X tgetent.obj \
X tgetstr.obj \
X tgoto.obj \
X tok.obj \
X tputs.obj \
X vms.obj
X
XDOTFILES= larn.hlp larn.maz larn.ftn # larn.opt
X
X# merge literal strings
X# large memory model
X# include file directory pointer
X# use extended memory during compile
X#
XFLAGS= $(OPTIONS) -d -ml -I\TCPP\INCLUDE -Qx
X
X# case-sensitive link, no map file
X#
Xlarn: larn123.exe
Xlarn123.exe: $(OBJS)
X tlink \TCPP\LIB\C0L @tlink.rsp, larn123,,\TCPP\LIB\EMU \TCPP\LIB\MATHL \TCPP\LIB\CL /c /x
X
X.c.obj:
X $(CC) -c $(FLAGS) $<
X
Xaction.obj: action.c header.h larndefs.h monsters.h objects.h player.h
Xbill.obj: bill.c header.h larndefs.h
Xconfig.obj: config.c header.h larndefs.h
Xcreate.obj: create.c header.h larndefs.h monsters.h objects.h player.h
Xdata.obj: data.c header.h monsters.h objects.h
Xdiag.obj: diag.c header.h larndefs.h monsters.h objects.h player.h
Xdisplay.obj: display.c header.h larndefs.h objects.h player.h
Xfgetlr.obj: fgetlr.c
Xfortune.obj: fortune.c header.h
Xglobal.obj: global.c header.h larndefs.h monsters.h objects.h player.h
Xhelp.obj: help.c header.h larndefs.h
Xiventory.obj: iventory.c header.h larndefs.h objects.h player.h
Xio.obj: io.c header.h larndefs.h
Xmain.obj: main.c header.h larndefs.h monsters.h objects.h player.h patchlev.h
Xmonster.obj: monster.c header.h larndefs.h monsters.h objects.h player.h
Xmoreobj.obj: moreobj.c header.h larndefs.h monsters.h objects.h player.h
Xmovem.obj: movem.c header.h larndefs.h monsters.h objects.h player.h
Xmsdos.obj: msdos.c header.h larndefs.h
Xnap.obj: nap.c
Xobject.obj: object.c header.h larndefs.h monsters.h objects.h player.h
Xregen.obj: regen.c header.h larndefs.h monsters.h player.h
Xsavelev.obj: savelev.c header.h larndefs.h
Xscores.obj: scores.c header.h larndefs.h monsters.h objects.h player.h
Xsignal.obj: signal.c header.h larndefs.h
Xspheres.obj: spheres.c header.h larndefs.h monsters.h objects.h player.h
Xspells.obj: spells.c header.h larndefs.h monsters.h objects.h player.h
Xstore.obj: store.c header.h larndefs.h objects.h player.h
Xtgetent.obj: tgetent.c
Xtgetstr.obj: tgetstr.c
Xtgoto.obj: tgoto.c
Xtok.obj: tok.c header.h larndefs.h monsters.h objects.h player.h
Xtputs.obj: tputs.c
Xvms.obj: vms.c header.h larndefs.h
X
Xinstall:
X exepack larn123.exe $(BINDIR)\larn123.exe
X exemod $(BINDIR)\larn123.exe /max 1
END_OF_FILE
if test 6666 -ne `wc -c <'makefile.pc'`; then
echo shar: \"'makefile.pc'\" unpacked with wrong size!
fi
# end of 'makefile.pc'
fi
if test -f 'nansi.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nansi.doc'\"
else
echo shar: Extracting \"'nansi.doc'\" \(6967 characters\)
sed "s/^X//" >'nansi.doc' <<'END_OF_FILE'
XSYNOPSIS
X Include in \config.sys the line
X device=nansi.sys
X
XDESCRIPTION
X Nansi.sys is a console driver which understands ANSI control
X sequences. It has several advantages over ANSI.SYS (the driver
X supplied with DOS):
X 1. It supports new escape sequences (see below).
X 2. It provides MUCH faster output under certain conditions.
X 3. It supports the 43-line mode of the EGA.
X 4. The darned bell is now 1/4 second instead of 1/2 second long.
X
X What a console driver does:
X When you, for example, type
X C:> type foo.txt
X COMMAND.COM opens the file foo.txt, reads it, and writes it to
X the console driver, which puts it up on the screen.
X
X Both ansi.sys and nansi.sys use IBM Video BIOS to control the screen.
X However, nansi.sys bypasses BIOS if the screen is in a text mode; this
X allows much faster operation under certain conditions.
X
X While putting text up on the screen, (n)ansi.sys keeps a lookout for
X the escape character (chr(27), known as ESC); this character signals
X the start of a terminal control sequence.
X Terminal control sequences follow the format
X ESC [ param; param; ...; param cmd
X where
X ESC is the escape character chr$(27).
X [ is the left bracket character.
X param is an ASCII decimal number, or a string in quotes.
X cmd is a case-specific letter identifying the command.
X Usually, zero, one, or two parameters are given. If parameters
X are omitted, they usually default to 1; however, some commands
X (KKR and DKOCT) treat the no-parameter case specially.
X Spaces are not allowed between parameters.
X
X For example, both ESC[1;1H and ESC[H send the cursor to the home
X position (1,1), which is the upper left.
X
X Either single or double quotes may be used to quote a string.
X Each character inside a quoted string is equivalent to one numeric
X parameter. Quoted strings are normally used only for the Keyboard
X Key Reassignment command.
X
XControl Sequences
X The following table lists the sequences understood by nansi.sys.
X Differences between nansi.sys and the standard ansi.sys are marked
X with a vertical bar (|).
X
XCursor Positioning
XShort Long name Format Notes
XCUP cursor position ESC[y;xH Sets cursor position.
XHVP cursor position ESC[y;xf Same as CUP; not recommended.
XCUU cursor up ESC[nA n = # of lines to move
XCUD cursor down ESC[nB
XCUF cursor forward ESC[nC n = # of columns to move
XCUB cursor backward ESC[nD
XDSR Device Status, Report! ESC[6n Find out cursor position.
XCPR Cursor Position report ESC[y;xR Response to DSR, as if typed.
XSCP Save Cursor Position ESC[s Not nestable.
XRCP Restore Cursor Position ESC[u
X
XEditing
XED Erase in Display ESC[2J Clears screen.
XEL Erase in Line ESC[K Clears to end of line.
XIL | Insert Lines ESC[nL Inserts n blank lines at cursor line.
XDL | Delete Lines ESC[nM Deletes n lines including cursor line.
XICH | Insert Characters ESC[n@ Inserts n blank chars at cursor.
XDCH | Delete Characters ESC[nP Deletes n chars including cursor char.
X
X
XMode-Setting
XSGR Set Graphics Rendition ESC[n;n;...nm See character attribute table.
XSM Set Mode ESC[=nh See screen mode table.
XRM Reset Mode ESC[=nl See screen mode table.
XIBMKKR Keyboard Key Reass. ESC["string"p
X The first char of the string gives the key to redefine; the rest
X of the string is the key's new value.
X To specify unprintable chars, give the ASCII value of the char
X outside of quotes, as a normal parameter.
X IBM function keys are two byte strings; see the IBM Basic manual.
X For instance, ESC[0;";dir a:";13;p redefines function key 1 to
X have the value "dir a:" followed by the ENTER key.
X | If no parameters given, all keys are reset to their default values.
X
XDKOCT | Output char translate ESC[n;ny
X | When first char is encountered in output request, it is replaced with
X | the second char. This might be useful for previewing text before
X | sending it to a printer with a funny print wheel.
X | If no parameters are given, all chars are reset to normal.
X
X
XCharacter Attributes
X The Set Graphics Rendition command is used to select foreground
X and background colors or attributes.
X When you use multiple parameters, they are executed in sequence, and
X the effects are cumulative.
X Attrib code Value
X 0 All attributes off (normal white on black)
X 1 Bold
X 4 Underline
X 5 Blink
X 7 Reverse Video
X 8 Invisible (but why?)
X 30-37 foregnd blk/red/grn/yel/blu/magenta/cyan/white
X 40-47 background
X
XScreen Modes
X The IBM BIOS supports several video modes; the codes given in the
X BIOS documentation are used as parameters to the Set Mode command.
X | (In bitmap modes, the cursor is simulated with a small blob (^V).)
X Mode Code Value
X 0 text 40x25 Black & White
X 1 text 40x25 Color
X 2 text 80x25 Black & White
X 3 text 80x25 Color
X 4 bitmap 320x200 4 bits/pixel
X 5 bitmap 320x200 1 bit/pixel
X 6 bitmap 640x200 1 bit/pixel
X 7 (cursor wrap kludge)
X 13 (EGA) bitmap 320x200 4 bits/pixel ?
X 14 (EGA) bitmap 640x200 4 bits/pixel
X 16 (EGA) bitmap 640x350 4 bits/pixel
X Mode 7 is an unfortunate kludge; Setting mode 7 tells the cursor
X to wrap around to the next line when it passes the end of a line;
X Resetting mode 7 tells the cursor to not wrap, but rather stay put.
X | If your computer has the Enhanced Graphics Adaptor, modes between
X | 8 and 15 are also supported; see the EGA BIOS for info.
X | The EGA also lets you use a shorter character cell in text modes
X | in order to squeeze 43 lines of text out of the 25-line text modes.
X | To enter 43 line mode, set the desired 25-line text mode (0 to 3),
X | then Set Mode 43. For instance: ESC[=3h ESC[=43h.
X | To exit 43 line mode, set the desired 25-line text mode again.
X | Nansi.sys ignores mode 43 unless there is an EGA on your computer.
X
XFaster Output
X | Any program that sets the console to RAW mode, and buffers its
X | output properly, can achieve extremely high screen update speeds in
X | return for giving up the special functions of the keys ^C, ^S, and ^P.
X | See IOCTL in the MS-DOS 3.x Technical Reference for more info.
X Also, a small improvement in speed may be noticed with some
X programs that use the DOS console in normal mode, as this driver
X efficiently implements the (standard but undocumented) INT 29h
X most-favored-device putchar used by DOS.
X
XBUGS
X Insert and delete character do not work in graphics modes.
X Graphics mode writing is slow.
X The simulated cursor in graphics mode slows down single-char
X writes by a factor of 3; it should be disable-able.
X Does not support erase-to-end-of-screen and other useful functions.
X
XVersion
X This version, 2.2, created February 1986. Problems should
X be reported to Daniel Kegel, 1-60 CIT, Pasadena, CA 91126
X (or, after June 1986, 2648 169th Ave SE, Bellevue, Wa. 98008).
X Your suggestions for improvement would be most welcome.
X
XNOTE
X This program may be distributed for educational and personal use
X only. Commercial use is verboten; get in touch with the author.
END_OF_FILE
if test 6967 -ne `wc -c <'nansi.doc'`; then
echo shar: \"'nansi.doc'\" unpacked with wrong size!
fi
# end of 'nansi.doc'
fi
if test -f 'regen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'regen.c'\"
else
echo shar: Extracting \"'regen.c'\" \(3917 characters\)
sed "s/^X//" >'regen.c' <<'END_OF_FILE'
X/* regen.c */
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "player.h"
X
X/*
X regen()
X
X subroutine to regenerate player hp and spells
X */
Xregen()
X {
X register int i,flag;
X register long *d;
X d = c;
X#ifdef EXTRA
X d[MOVESMADE]++;
X#endif
X if (d[TIMESTOP]) { if(--d[TIMESTOP]<=0) bottomline(); return; } /* for stop time spell */
X flag=0;
X
X if (d[STRENGTH]<3) { d[STRENGTH]=3; flag=1; }
X if (d[HP] != d[HPMAX])
X if (d[REGENCOUNTER]-- <= 0) /* regenerate hit points */
X {
X d[REGENCOUNTER] = 22 + (d[HARDGAME]<<1) - d[LEVEL];
X if ((d[HP] += d[REGEN]) > d[HPMAX]) d[HP] = d[HPMAX];
X bottomhp();
X }
X
X if (d[SPELLS] < d[SPELLMAX]) /* regenerate spells */
X if (d[ECOUNTER]-- <= 0)
X {
X d[ECOUNTER] = 100+4*(d[HARDGAME]-d[LEVEL]-d[ENERGY]);
X d[SPELLS]++; bottomspell();
X }
X
X if (d[HERO]) if (--d[HERO]<=0) { for (i=0; i<6; i++) d[i] -= 10; flag=1; }
X if (d[ALTPRO]) if (--d[ALTPRO]<=0) { d[MOREDEFENSES]-=3; flag=1; }
X if (d[PROTECTIONTIME]) if (--d[PROTECTIONTIME]<=0) { d[MOREDEFENSES]-=2; flag=1; }
X if (d[DEXCOUNT]) if (--d[DEXCOUNT]<=0) { d[DEXTERITY]-=3; flag=1; }
X if (d[STRCOUNT]) if (--d[STRCOUNT]<=0) { d[STREXTRA]-=3; flag=1; }
X if (d[BLINDCOUNT]) if (--d[BLINDCOUNT]<=0) { cursors(); lprcat("\nThe blindness lifts "); beep(); }
X if (d[CONFUSE]) if (--d[CONFUSE]<=0) { cursors(); lprcat("\nYou regain your senses"); beep(); }
X if (d[GIANTSTR]) if (--d[GIANTSTR]<=0) { d[STREXTRA] -= 20; flag=1; }
X if (d[CHARMCOUNT]) if ((--d[CHARMCOUNT]) <= 0) flag=1;
X if (d[INVISIBILITY]) if ((--d[INVISIBILITY]) <= 0) flag=1;
X if (d[CANCELLATION]) if ((--d[CANCELLATION]) <= 0) flag=1;
X if (d[WTW]) if ((--d[WTW]) <= 0) flag=1;
X if (d[HASTESELF]) if ((--d[HASTESELF]) <= 0) flag=1;
X if (d[AGGRAVATE]) --d[AGGRAVATE];
X if (d[SCAREMONST]) if ((--d[SCAREMONST]) <= 0) flag=1;
X if (d[STEALTH]) if ((--d[STEALTH]) <= 0) flag=1;
X if (d[AWARENESS]) --d[AWARENESS];
X if (d[HOLDMONST]) if ((--d[HOLDMONST]) <= 0) flag=1;
X if (d[HASTEMONST]) --d[HASTEMONST];
X if (d[FIRERESISTANCE]) if ((--d[FIRERESISTANCE]) <= 0) flag=1;
X if (d[GLOBE]) if (--d[GLOBE]<=0) { d[MOREDEFENSES]-=10; flag=1; }
X if (d[SPIRITPRO]) if (--d[SPIRITPRO] <= 0) flag=1;
X if (d[UNDEADPRO]) if (--d[UNDEADPRO] <= 0) flag=1;
X if (d[HALFDAM]) if (--d[HALFDAM]<=0) { cursors(); lprcat("\nYou now feel better "); beep(); }
X if (d[SEEINVISIBLE])
X if (--d[SEEINVISIBLE]<=0)
X { monstnamelist[INVISIBLESTALKER] = floorc;
X if (!d[BLINDCOUNT]) {
X cursors();
X lprcat("\nYou feel your vision return to normal");
X beep();
X }
X }
X if (d[ITCHING])
X {
X if (d[ITCHING]>1)
X if ((d[WEAR]!= -1) || (d[SHIELD]!= -1))
X if (rnd(100)<50)
X {
X d[WEAR]=d[SHIELD]= -1; cursors();
X lprcat("\nThe hysteria of itching forces you to remove your armor!");
X beep(); recalc(); bottomline();
X }
X if (--d[ITCHING]<=0) { cursors(); lprcat("\nYou now feel the irritation subside!"); beep(); }
X }
X if (d[CLUMSINESS])
X {
X if (d[WIELD] != -1)
X if (d[CLUMSINESS]>1)
X if (item[playerx][playery]==0) /* only if nothing there */
X if (rnd(100)<33) /* drop your weapon due to clumsiness */
X drop_object((int)d[WIELD]);
X if (--d[CLUMSINESS]<=0) { cursors(); lprcat("\nYou now feel less awkward!"); beep(); }
X }
X if (flag) bottomline();
X }
END_OF_FILE
if test 3917 -ne `wc -c <'regen.c'`; then
echo shar: \"'regen.c'\" unpacked with wrong size!
fi
# end of 'regen.c'
fi
if test -f 'signal.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'signal.c'\"
else
echo shar: Extracting \"'signal.c'\" \(5478 characters\)
sed "s/^X//" >'signal.c' <<'END_OF_FILE'
X#include <signal.h>
X#include "header.h"
X#include "larndefs.h"
X
X#define BIT(a) (1<<((a)-1))
X
Xextern char savefilename[],wizard,predostuff,nosignal;
X
Xstatic s2choose() /* text to be displayed if ^C during intro screen */
X {
X cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
X lprcat(" to continue: "); lflush();
X }
X
Xstatic void cntlc() /* what to do for a ^C */
X {
X if (nosignal) return; /* don't do anything if inhibited */
X# ifndef MSDOS
X signal(SIGQUIT,SIG_IGN);
X# endif
X signal(SIGINT,SIG_IGN);
X quit(); if (predostuff==1) s2choose(); else showplayer();
X lflush();
X# ifndef MSDOS
X signal(SIGQUIT,cntlc);
X# endif
X signal(SIGINT,cntlc);
X }
X
X#ifndef MSDOS
X/*
X * subroutine to save the game if a hangup signal
X */
Xstatic sgam()
X {
X savegame(savefilename); wizard=1; died(-257); /* hangup signal */
X }
X#endif
X
X#ifdef SIGTSTP
Xstatic tstop() /* control Y */
X {
X if (nosignal) return; /* nothing if inhibited */
X lcreat((char*)0); clearvt100(); lflush(); signal(SIGTSTP,SIG_DFL);
X#ifdef SIGVTALRM
X /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
X sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
X#endif
X kill(getpid(),SIGTSTP);
X
X setupvt100(); signal(SIGTSTP,tstop);
X if (predostuff==1) s2choose(); else drawscreen();
X showplayer(); lflush();
X }
X#endif SIGTSTP
X
X/*
X * subroutine to issue the needed signal traps called from main()
X */
Xstatic void sigfpe() { sigpanic(SIGFPE); }
X# ifndef MSDOS
Xstatic sigbus() { sigpanic(SIGBUS); }
Xstatic sigill() { sigpanic(SIGILL); } static sigtrap() { sigpanic(SIGTRAP); }
Xstatic sigiot() { sigpanic(SIGIOT); } static sigemt() { sigpanic(SIGEMT); }
Xstatic sigsegv() { sigpanic(SIGSEGV); } static sigsys() { sigpanic(SIGSYS); }
Xstatic sigpipe() { sigpanic(SIGPIPE); } static sigterm() { sigpanic(SIGTERM); }
X# endif
X
Xsigsetup()
X {
X signal(SIGINT, cntlc);
X signal(SIGFPE, sigfpe);
X# ifndef MSDOS
X signal(SIGBUS, sigbus); signal(SIGQUIT, cntlc);
X signal(SIGKILL, SIG_IGN); signal(SIGHUP, sgam);
X signal(SIGILL, sigill); signal(SIGTRAP, sigtrap);
X signal(SIGIOT, sigiot); signal(SIGEMT, sigemt);
X signal(SIGSEGV, sigsegv); signal(SIGSYS, sigsys);
X signal(SIGPIPE, sigpipe); signal(SIGTERM, sigterm);
X#ifdef SIGTSTP
X signal(SIGTSTP,tstop); signal(SIGSTOP,tstop);
X#endif SIGTSTP
X# endif
X }
X
X#ifdef MSDOS
X#define NSIG 9
X#endif
X
X#ifdef VMS
X#define NSIG 16
X#endif
X
X#ifdef BSD /* for BSD UNIX? */
X
Xstatic char *signame[NSIG] = { "",
X"SIGHUP", /* 1 hangup */
X"SIGINT", /* 2 interrupt */
X"SIGQUIT", /* 3 quit */
X"SIGILL", /* 4 illegal instruction (not reset when caught) */
X"SIGTRAP", /* 5 trace trap (not reset when caught) */
X"SIGIOT", /* 6 IOT instruction */
X"SIGEMT", /* 7 EMT instruction */
X"SIGFPE", /* 8 floating point exception */
X"SIGKILL", /* 9 kill (cannot be caught or ignored) */
X"SIGBUS", /* 10 bus error */
X"SIGSEGV", /* 11 segmentation violation */
X"SIGSYS", /* 12 bad argument to system call */
X"SIGPIPE", /* 13 write on a pipe with no one to read it */
X"SIGALRM", /* 14 alarm clock */
X"SIGTERM", /* 15 software termination signal from kill */
X"SIGURG", /* 16 urgent condition on IO channel */
X"SIGSTOP", /* 17 sendable stop signal not from tty */
X"SIGTSTP", /* 18 stop signal from tty */
X"SIGCONT", /* 19 continue a stopped process */
X"SIGCHLD", /* 20 to parent on child stop or exit */
X"SIGTTIN", /* 21 to readers pgrp upon background tty read */
X"SIGTTOU", /* 22 like TTIN for output if (tp->t_local<OSTOP) */
X"SIGIO", /* 23 input/output possible signal */
X"SIGXCPU", /* 24 exceeded CPU time limit */
X"SIGXFSZ", /* 25 exceeded file size limit */
X"SIGVTALRM",/* 26 virtual time alarm */
X"SIGPROF", /* 27 profiling time alarm */
X"","","","" };
X
X#else BSD /* for system V? */
X
Xstatic char *signame[NSIG+1] = { "",
X"SIGHUP", /* 1 hangup */
X"SIGINT", /* 2 interrupt */
X"SIGQUIT", /* 3 quit */
X"SIGILL", /* 4 illegal instruction (not reset when caught) */
X"SIGTRAP", /* 5 trace trap (not reset when caught) */
X"SIGIOT", /* 6 IOT instruction */
X"SIGEMT", /* 7 EMT instruction */
X# ifdef MSDOS
X"SIGFPE"}; /* 8 floating point exception */
X# else MSDOS
X"SIGFPE", /* 8 floating point exception */
X"SIGKILL", /* 9 kill (cannot be caught or ignored) */
X"SIGBUS", /* 10 bus error */
X"SIGSEGV", /* 11 segmentation violation */
X"SIGSYS", /* 12 bad argument to system call */
X"SIGPIPE", /* 13 write on a pipe with no one to read it */
X"SIGALRM", /* 14 alarm clock */
X# ifdef VMS
X"SIGTERM"}; /* 15 software termination signal from kill */
X# else VMS
X"SIGTERM", /* 15 software termination signal from kill */
X"SIGUSR1", /* 16 user defines signal 1 */
X"SIGUSR2", /* 17 user defines signal 2 */
X"SIGCLD", /* 18 child death */
X"SIGPWR" }; /* 19 power fail */
X# endif VMS
X# endif MSDOS
X# endif BSD
X
X/*
X * routine to process a fatal error signal
X */
Xstatic sigpanic(sig)
Xint sig;
X{
X char buf[128];
X signal(sig,SIG_DFL);
X sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
X write(2,buf,strlen(buf)); sleep(2);
X sncbr();
X savegame(savefilename);
X# ifdef MSDOS
X exit(1);
X# else
X kill(getpid(),sig); /* this will terminate us */
X# endif
X}
END_OF_FILE
if test 5478 -ne `wc -c <'signal.c'`; then
echo shar: \"'signal.c'\" unpacked with wrong size!
fi
# end of 'signal.c'
fi
if test -f 'spheres.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'spheres.c'\"
else
echo shar: Extracting \"'spheres.c'\" \(6636 characters\)
sed "s/^X//" >'spheres.c' <<'END_OF_FILE'
X/*
X newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
X rmsphere(x,y) Function to delete a sphere of annihilation from list
X sphboom(x,y) Function to perform the effects of a sphere detonation
X movsphere() Function to look for and move spheres of annihilation
X*/
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
X/*
X * newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
X * int x,y,dir,lifetime;
X *
X * Enter with the coordinates of the sphere in x,y
X * the direction (0-8 diroffx format) in dir, and the lifespan of the
X * sphere in lifetime (in turns)
X * Returns the number of spheres currently in existence
X */
Xnewsphere(x,y,dir,life)
X int x,y,dir,life;
X {
X int m;
X struct sphere *sp;
X if (((sp=(struct sphere *)malloc(sizeof(struct sphere)))) == 0)
X return(c[SPHCAST]); /* can't malloc, therefore failure */
X if (dir>=9) dir=0; /* no movement if direction not found */
X if (level==0) vxy(&x,&y); /* don't go out of bounds */
X else
X {
X if (x<1) x=1; if (x>=MAXX-1) x=MAXX-2;
X if (y<1) y=1; if (y>=MAXY-1) y=MAXY-2;
X }
X if ((m=mitem[x][y]) >= DEMONLORD+4) /* demons dispel spheres */
X {
X show1cell(x,y); /* show the demon (ha ha) */
X cursors(); lprintf("\nThe %s dispels the sphere!",monster[m].name);
X beep(); rmsphere(x,y); /* remove any spheres that are here */
X return(c[SPHCAST]);
X }
X if (m==DISENCHANTRESS) /* disenchantress cancels spheres */
X {
X cursors(); lprintf("\nThe %s causes cancellation of the sphere!",monster[m].name); beep();
Xboom: sphboom(x,y); /* blow up stuff around sphere */
X rmsphere(x,y); /* remove any spheres that are here */
X return(c[SPHCAST]);
X }
X if (c[CANCELLATION]) /* cancellation cancels spheres */
X {
X cursors(); lprcat("\nAs the cancellation takes effect, you hear a great earth shaking blast!"); beep();
X goto boom;
X }
X if (item[x][y]==OANNIHILATION) /* collision of spheres detonates spheres */
X {
X cursors(); lprcat("\nTwo spheres of annihilation collide! You hear a great earth shaking blast!"); beep();
X rmsphere(x,y);
X goto boom;
X }
X if (playerx==x && playery==y) /* collision of sphere and player! */
X {
X cursors();
X lprcat("\nYou have been enveloped by the zone of nothingness!\n");
X beep(); rmsphere(x,y); /* remove any spheres that are here */
X nap(4000); died(258);
X }
X item[x][y]=OANNIHILATION; mitem[x][y]=0; know[x][y]=1;
X show1cell(x,y); /* show the new sphere */
X sp->x=x; sp->y=y; sp->lev=level; sp->dir=dir; sp->lifetime=life; sp->p=0;
X if (spheres==0) spheres=sp; /* if first node in the sphere list */
X else /* add sphere to beginning of linked list */
X {
X sp->p = spheres; spheres = sp;
X }
X return(++c[SPHCAST]); /* one more sphere in the world */
X }
X
X/*
X * rmsphere(x,y) Function to delete a sphere of annihilation from list
X * int x,y;
X *
X * Enter with the coordinates of the sphere (on current level)
X * Returns the number of spheres currently in existence
X */
Xrmsphere(x,y)
X int x,y;
X {
X register struct sphere *sp,*sp2=0;
X for (sp=spheres; sp; sp2=sp,sp=sp->p)
X if (level==sp->lev) /* is sphere on this level? */
X if ((x==sp->x) && (y==sp->y)) /* locate sphere at this location */
X {
X item[x][y]=mitem[x][y]=0; know[x][y]=1;
X show1cell(x,y); /* show the now missing sphere */
X --c[SPHCAST];
X if (sp==spheres) { sp2=sp; spheres=sp->p; free((char*)sp2); }
X else
X { sp2->p = sp->p; free((char*)sp); }
X break;
X }
X return(c[SPHCAST]); /* return number of spheres in the world */
X }
X
X/*
X * sphboom(x,y) Function to perform the effects of a sphere detonation
X * int x,y;
X *
X * Enter with the coordinates of the blast, Returns no value
X */
Xstatic sphboom(x,y)
X int x,y;
X {
X register int i,j;
X if (c[HOLDMONST]) c[HOLDMONST]=1;
X if (c[CANCELLATION]) c[CANCELLATION]=1;
X for (j=max(1,x-2); j<min(x+3,MAXX-1); j++)
X for (i=max(1,y-2); i<min(y+3,MAXY-1); i++)
X {
X item[j][i]=mitem[j][i]=0;
X show1cell(j,i);
X if (playerx==j && playery==i)
X {
X cursors(); beep();
X lprcat("\nYou were too close to the sphere!");
X nap(3000);
X died(283); /* player killed in explosion */
X }
X }
X }
X
X/*
X * movsphere() Function to look for and move spheres of annihilation
X *
X * This function works on the sphere linked list, first duplicating the list
X * (the act of moving changes the list), then processing each sphere in order
X * to move it. They eat anything in their way, including stairs, volcanic
X * shafts, potions, etc, except for upper level demons, who can dispel
X * spheres.
X * No value is returned.
X */
X#define SPHMAX 20 /* maximum number of spheres movsphere can handle */
Xmovsphere()
X {
X register int x,y,dir,len;
X register struct sphere *sp,*sp2;
X struct sphere sph[SPHMAX];
X
X /* first duplicate sphere list */
X for (sp=0,x=0,sp2=spheres; sp2; sp2=sp2->p) /* look through sphere list */
X if (sp2->lev == level) /* only if this level */
X {
X sph[x] = *sp2; sph[x++].p = 0; /* copy the struct */
X if (x>1) sph[x-2].p = &sph[x-1]; /* link pointers */
X }
X if (x) sp= sph; /* if any spheres, point to them */
X else return; /* no spheres */
X
X for (sp=sph; sp; sp=sp->p) /* look through sphere list */
X {
X x = sp->x; y = sp->y;
X if (item[x][y]!=OANNIHILATION) continue; /* not really there */
X if (--(sp->lifetime) < 0) /* has sphere run out of gas? */
X {
X rmsphere(x,y); /* delete sphere */
X continue;
X }
X switch(rnd((int)max(7,c[INTELLIGENCE]>>1))) /* time to move the sphere */
X {
X case 1:
X case 2: /* change direction to a random one */
X sp->dir = rnd(8);
X default: /* move in normal direction */
X dir = sp->dir; len = sp->lifetime;
X rmsphere(x,y);
X newsphere(x+diroffx[dir],y+diroffy[dir],dir,len);
X };
X }
X }
END_OF_FILE
if test 6636 -ne `wc -c <'spheres.c'`; then
echo shar: \"'spheres.c'\" unpacked with wrong size!
fi
# end of 'spheres.c'
fi
if test -f 'tgetstr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tgetstr.c'\"
else
echo shar: Extracting \"'tgetstr.c'\" \(6825 characters\)
sed "s/^X//" >'tgetstr.c' <<'END_OF_FILE'
X/************************************************************************
X * *
X * Copyright (c) 1982, Fred Fish *
X * All Rights Reserved *
X * *
X * This software and/or documentation is released for public *
X * distribution for personal, non-commercial use only. *
X * Limited rights to use, modify, and redistribute are hereby *
X * granted for non-commercial purposes, provided that all *
X * copyright notices remain intact and all changes are clearly *
X * documented. The author makes no warranty of any kind with *
X * respect to this product and explicitly disclaims any implied *
X * warranties of merchantability or fitness for any particular *
X * purpose. *
X * *
X ************************************************************************
X */
X
X
X/*
X * LIBRARY FUNCTION
X *
X * tgetstr extract string capability from termcap entry
X *
X * KEY WORDS
X *
X * termcap
X *
X * SYNOPSIS
X *
X * char *tgetstr(id,area)
X * char *id;
X * char **area;
X *
X * DESCRIPTION
X *
X * Gets the string capability for <id>, placing it in
X * the buffer at *area, and advancing *area to point
X * to next available storage.
X *
X * For example, if the following capabilities are
X * in the termcap file:
X *
X * ZZ=zzzz
X * YY=yyyyyy
X * WW=www
X *
X * then successive calls using YY, ZZ, and WW will
X * build the following buffer:
X *
X * yyyyyy0zzzz0www0
X *
X * The first call will return a pointer to yyyyyy, the
X * second will return a pointer to zzzz and the third
X * will return a pointer to www. Note that each
X * string is null terminated, as are all C strings.
X *
X * Characters preceded by the carot character (\136)
X * are mapped into the corresponding control character.
X * For example, the two character sequence ^A becomes
X * a single control-A (\001) character.
X *
X * The escape character is the normal C backslash and
X * the normal C escape sequences are recognized, along
X * with a special sequence for the ASCII escape character
X * (\033). The recognized sequences are:
X *
X * \E => '\033' (ASCII escape character)
X * \b => '\010' (ASCII backspace character)
X * \f => '\014' (ASCII form feed character)
X * \n => '\012' (ASCII newline/linefeed char)
X * \r => '\015' (ASCII carriage return char)
X * \t => '\011' (ASCII tab character)
X * \ddd => '\ddd' (arbitrary ASCII digit)
X * \x => 'x' (ordinary ASCII character)
X *
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#ifdef VMS
X# define index strchr
X#endif
X#ifdef ULTRIX
X# include <strings.h>
X#endif
X
Xextern char *_tcpbuf; /* Termcap entry buffer pointer */
X
X#ifdef MSDOS
X extern char *index();
X#endif
X
X/*
X * PSEUDO CODE
X *
X * Begin tgetstr
X * Initialize pointer to the termcap entry buffer.
X * While there is a field to process
X * Skip over the field separator character.
X * If this is the entry we want then
X * If the entry is not a string then
X * Return NULL.
X * Else
X * Transfer string and rtn pointer.
X * End if
X * End if
X * End while
X * Return NULL
X * End tgetstr
X *
X */
X
Xchar *tgetstr(id,area)
Xchar *id;
Xchar **area;
X{
X char *bp;
X char *decode();
X
X bp = _tcpbuf;
X while ((bp = index(bp,':')) != NULL) {
X bp++;
X if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
X if (*bp != NULL && *bp++ != '=') {
X return(NULL);
X } else {
X return(decode(bp,area));
X }
X }
X }
X return(NULL);
X}
X
X/*
X * INTERNAL FUNCTION
X *
X * decode transfer string capability, decoding escapes
X *
X * SYNOPSIS
X *
X * static char *decode(bp,area)
X * char *bp;
X * char **area;
X *
X * DESCRIPTION
X *
X * Transfers the string capability, up to the next ':'
X * character, or null, to the buffer pointed to by
X * the pointer in *area. Note that the initial
X * value of *area and *area is updated to point
X * to the next available location after the null
X * terminating the transfered string.
X *
X * BUGS
X *
X * There is no overflow checking done on the destination
X * buffer, so it better be large enough to hold
X * all expected strings.
X *
X */
X
X/*
X * PSEUDO CODE
X *
X * Begin decode
X * Initialize the transfer pointer.
X * While there is an input character left to process
X * Switch on input character
X * Case ESCAPE:
X * Decode and xfer the escaped sequence.
X * Break
X * Case CONTROLIFY:
X * Controlify and xfer the next character.
X * Advance the buffer pointer.
X * Break
X * Default:
X * Xfer a normal character.
X * End switch
X * End while
X * Null terminate the output string.
X * Remember where the output string starts.
X * Update the output buffer pointer.
X * Return pointer to the output string.
X * End decode
X *
X */
X
Xstatic char *decode(bp,area)
Xchar *bp;
Xchar **area;
X{
X char *cp, *bgn;
X char *do_esc();
X
X cp = *area;
X while (*bp != NULL && *bp != ':') {
X switch(*bp) {
X case '\\':
X bp = do_esc(cp++,++bp);
X break;
X case '^':
X *cp++ = *++bp & 037;
X bp++;
X break;
X default:
X *cp++ = *bp++;
X break;
X }
X }
X *cp++ = (char) NULL;
X bgn = *area;
X *area = cp;
X return(bgn);
X}
X
X/*
X * INTERNAL FUNCTION
X *
X * do_esc process an escaped sequence
X *
X * SYNOPSIS
X *
X * char *do_esc(out,in);
X * char *out;
X * char *in;
X *
X * DESCRIPTION
X *
X * Processes an escape sequence pointed to by
X * in, transfering it to location pointed to
X * by out, and updating the pointer to in.
X *
X */
X
X/*
X * PSEUDO CODE
X *
X * Begin do_esc
X * If the first character is not a NULL then
X * If is a digit then
X * Set value to zero.
X * For up to 3 digits
X * Accumulate the sum.
X * End for
X * Transfer the sum.
X * Else if character is in remap list then
X * Transfer the remapped character.
X * Advance the input pointer once.
X * Else
X * Simply transfer the character.
X * End if
X * End if
X * Return updated input pointer.
X * End do_esc
X *
X */
X
Xstatic char *maplist = {
X "E\033b\bf\fn\nr\rt\t"
X};
X
Xchar *do_esc(out,in)
Xchar *out;
Xchar *in;
X{
X int count;
X char ch;
X char *cp;
X
X if (*in != NULL) {
X if (isdigit(*in)) {
X ch = 0;
X for (count = 0; count < 3 && isdigit(*in); in++) {
X ch <<= 3;
X ch |= (*in - '0');
X }
X *out++ = ch;
X } else if ((cp = index(maplist,*in)) != NULL) {
X *out++ = *++cp;
X in++;
X } else {
X *out++ = *in++;
X }
X }
X return(in);
X}
END_OF_FILE
if test 6825 -ne `wc -c <'tgetstr.c'`; then
echo shar: \"'tgetstr.c'\" unpacked with wrong size!
fi
# end of 'tgetstr.c'
fi
if test -f 'vms.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vms.c'\"
else
echo shar: Extracting \"'vms.c'\" \(6704 characters\)
sed "s/^X//" >'vms.c' <<'END_OF_FILE'
X#ifdef VMS
X#include "header.h"
X
X#include <file.h>
X#include <stat.h>
X#include <stdio.h>
X#include <stsdef.h>
X#include <ssdef.h>
X#include <descrip.h>
X#include <iodef.h>
X#include <ttdef.h>
X#include <tt2def.h>
X
X/*
X * Read until end of file or until buffer is full.
X * don't let the vms read (which stops once per record)
X * fool the program.
X */
Xvread(fd, buf, size)
Xint fd;
Xchar *buf;
Xint size;
X{
X int csize; /* cumulative size */
X int isize; /* incremental size */
X
X csize = 0;
X do {
X isize = read(fd, buf, size);
X if (isize > 0) {
X csize += isize;
X buf += isize;
X size -= isize;
X }
X } while (isize > 0);
X return (csize);
X}
X
X#else VMS
X
X#ifndef vread /* if not done as a macro in header.h */
Xvread(fd, buf, size)
Xint fd;
Xchar *buf;
Xint size;
X{
X return (read(fd, buf, size));
X}
X#endif vread
X#endif VMS
X
X#ifdef VMS
X/*
X * Run a command in a subjob. Used for mailing the winners congratulations,
X * tax bills, etc. Used for the shell escape command (!). Conditionalized
X * for VMS wherever used (un*x has the right primitives).
X */
Xlong
Xoneliner(cstr)
Xchar *cstr;
X{
X struct dsc$descriptor cdsc;
X register long sts;
X register long pstat;
X
X cdsc.dsc$a_pointer = cstr;
X cdsc.dsc$w_length = strlen(cstr);
X cdsc.dsc$b_dtype = DSC$K_DTYPE_T;
X cdsc.dsc$b_class = DSC$K_CLASS_S;
X sts = LIB$SPAWN(&cdsc, 0, 0, 0, 0, 0, &pstat, 0, 0, 0, 0, 0);
X if (sts != SS$_NORMAL)
X return (sts);
X else
X return (pstat);
X}
X
X/*
X Data to convert the escape codes produced by VT style keypad keys to things
X that LARN will understand.
X*/
X#define MAX_KP_CONV 19
Xstruct
X {
X char *inp_str;
X char *out_str;
X } keypad_conv[MAX_KP_CONV] = { { "\x1BOp", "i" }, /* KP0 */
X { "\x1BOq", "b" }, /* KP1 */
X { "\x1BOr", "j" }, /* KP2 */
X { "\x1BOs", "n" }, /* KP3 */
X { "\x1BOt", "h" }, /* KP4 */
X { "\x1BOu", "." }, /* KP5 */
X { "\x1BOv", "l" }, /* KP6 */
X { "\x1BOw", "y" }, /* KP7 */
X { "\x1BOx", "k" }, /* KP8 */
X { "\x1BOy", "u" }, /* KP9 */
X { "\x1BOn", "." }, /* KP. */
X { "\x1BOl", "," }, /* KP, */
X { "\x1B[A", "K" }, /* uparrow */
X { "\x1B[B", "J" }, /* downarrow*/
X { "\x1B[C", "L" }, /* right arrow */
X { "\x1B[D", "H" }, /* left arrow */
X { "\x1BOP", "m" }, /* PF1 */
X { "\x1BOS", "@" }, /* PF4 */
X { "\x1B[23~", "\x1B" } /* (ESC) */
X };
X
X/*
X VMS-specific terminal character read. Gets a character from the terminal,
X translating keypad as necessary. Assumes VT-class terminals.
X*/
Xvms_ttgetch()
X {
X
X#define BUFFLEN 10
X
X char *i;
X int j;
X register int incount;
X static char buffer[BUFFLEN];
X static char *bufptr = buffer;
X static char *bufend = buffer;
X
X lflush(); /* be sure output buffer is flushed */
X
X /* Read the first char from the user
X */
X if (bufptr >= bufend)
X {
X bufptr = bufend = buffer;
X incount = vmsread(buffer, BUFFLEN, 0);
X while ( incount <= 0 )
X incount = vmsread(buffer, 1, 2);
X bufend = &buffer[incount];
X }
X
X /* If the first char was an ESCAPE, get the characters from an
X escape sequence (eg pressing a key that generates such a
X sequence). If it was a plain old escape, the vmsread() call
X will return TIMEOUT.
X */
X if (*bufptr == '\x1B' )
X {
X incount = vmsread( bufend, (BUFFLEN - 1), 0 );
X if (incount >= 0)
X bufend += incount ;
X }
X
X /* Make sure the buffer is zero-terminated, since vmsread()
X doesn't zero-terminate the characters read.
X */
X *bufend = '\0' ;
X
X /* run through the keypad conversion table to convert keypad
X keys (escape sequences) and other supported escape sequences
X to Larn command characters.
X */
X for ( j = 0; j < MAX_KP_CONV ; j++ )
X if (strcmp( &buffer, keypad_conv[j].inp_str ) == 0 )
X {
X strcpy( &buffer, keypad_conv[j].out_str );
X bufend = &buffer[strlen(&buffer)];
X break;
X }
X
X /* If after running through the table the first character is still
X ESCAPE, then we probably didn't get a match. Force unsupported
X keys that generate escape sequences to just return an ESCAPE.
X Effectively prevents key translations that generate escape
X sequences.
X */
X if (*bufptr == '\x1B' )
X {
X bufend = &buffer[1] ;
X }
X *bufend = '\0' ;
X
X if (*bufptr == '\r')
X *bufptr = '\n';
X
X return (*bufptr++ & 0xFF);
X }
X
Xtypedef struct
X {
X short int status;
X short int term_offset;
X short int terminator;
X short int term_size;
X } IOSTAB;
X
Xint vmsread(buffer, size, timeout)
Xchar *buffer;
Xint size;
Xint timeout;
X {
X
X#define TIMEOUT (-2)
X#define ERROR (-1)
X
X extern int iochan;
X
X register int status;
X IOSTAB iostab;
X static long termset[2] = { 0, 0 }; /* No terminator */
X
X status = SYS$QIOW(
X 0, /* Event flag */
X iochan, /* Input channel */
X IO$_READLBLK | IO$M_NOFILTR | IO$M_TIMED,
X /* Read, no echo, no translate */
X &iostab, /* I/O status block */
X NULL, /* AST block (none) */
X 0, /* AST parameter */
X buffer, /* P1 - input buffer */
X size, /* P2 - buffer length */
X timeout, /* P3 - timeout */
X &termset, /* P4 - terminator set */
X NULL, /* P5 - ignored (prompt buffer) */
X 0 /* P6 - ignored (prompt size) */
X );
X if (status == SS$_TIMEOUT)
X return (TIMEOUT);
X else if (status != SS$_NORMAL)
X return (ERROR);
X else
X {
X if ((status = iostab.term_offset + iostab.term_size) > 0)
X return (status);
X return (TIMEOUT);
X }
X }
X
X#endif VMS
END_OF_FILE
if test 6704 -ne `wc -c <'vms.c'`; then
echo shar: \"'vms.c'\" unpacked with wrong size!
fi
# end of 'vms.c'
fi
echo shar: End of archive 11 \(of 12\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 12 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