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