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

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

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



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 38 (of 56)."
# Contents:  UPDATE5 amiga/amiwind.c src/termcap.c src/u_init.c
# Wrapped by billr@saab on Wed Jul 11 17:11:48 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'UPDATE5' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'UPDATE5'\"
else
echo shar: Extracting \"'UPDATE5'\" \(2225 characters\)
sed "s/^X//" >'UPDATE5' <<'END_OF_FILE'
X--------
XUPDATE 5
X--------
X
XOld bones and save files should at least be syntactically correct this time,
Xbut you should still throw them out if you don't want to be confronted with
Xmonsters permanently masquerading as different monsters (since some of the
Xmonsters' letters have changed).
X
X
XNote that the posted shop fix was a stopgap patch, not an official patch, so
Xit should be reversed before applying these patches.  If you do not reverse 
Xit, probably nothing worse than a failure of one shk.c band will happen this
Xtime.  In general, however, you will have to do considerable hand-patching if
Xyou leave intermediate patches in.
X
X
XThe major bug fix in Patch 5 is moving the color definitions to color.h, thus
Xbreaking the annoying dependency loop when bootstrapping NetHack.
X
XPatch 5 contains Johnny Lee's provision of a port to the Macintosh.  The 
XMacintosh files live in a new subdirectory, 'mac'.  We know that many of you
Xwere waiting for a Mac port, and for you we are happy to have it.
X
XBasic support for several new other compilers or machines (see README), but 
Xthese probably need some more tweaking.
X
XA major new feature in Patch 5 is timed-out eating, i.e., being able to be
Xinterrupted while eating by monsters attack.  Mike Stephenson provided the 
Xbasic structure for dealing with partially eaten food.  We believe that the
Xonly remaining flaws in this code are occasional non-optimal messages which
Xare generated by it (we are working on correcting this).
X
XIncorrect iron ball behavior and bugs in the iron ball code were 
Xsystematically corrected by Kevin Darcy who communicated with us about it
Xand mailed us his patches.  (Yes, Kevin, as you can see, it went in, and 
Xwith only one minor change.)  
X
XThere were other, smaller, patches which were mailed to us and which were
Ximplemented.  To repeat:  we are very happy to receive bug-fixing patches
Xand code-enhancement patches.  But please do as Kevin did, namely, tell us
Xabout it in advance.
X
XDifficulties with dropping objects in shops, burning to death in hell, 
Xwielding amulets, pets eating corpses were fixed.  So were scores of other
Xsmall but annoying bugs.
X
XMICROPORT_BUG was added to cater to compilers that don't like large 
Xstructures.
X
END_OF_FILE
if test 2225 -ne `wc -c <'UPDATE5'`; then
    echo shar: \"'UPDATE5'\" unpacked with wrong size!
fi
# end of 'UPDATE5'
fi
if test -f 'amiga/amiwind.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/amiwind.c'\"
else
echo shar: Extracting \"'amiga/amiwind.c'\" \(17495 characters\)
sed "s/^X//" >'amiga/amiwind.c' <<'END_OF_FILE'
X/*
X *  amiwind.c	(C) Copyright 1989 by Olaf Seibert (KosmoSoft)
X */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X *  Here is some very Amiga specific stuff, dealing with
X *  screens, windows, menus, and input via IntuiMessages.
X */
X
X#include "hack.h"
X
X#undef TRUE
X#undef FALSE
X#undef COUNT
X#undef NULL
X
X#include <exec/types.h>
X#include <exec/alerts.h>
X#include <exec/io.h>
X#include <exec/devices.h>
X#include <devices/console.h>
X#include <devices/conunit.h>
X#include <intuition/intuition.h>
X#include <libraries/dosextens.h>
X
X#ifdef LATTICE
X#include <dos.h>
X#include <proto/exec.h>
X#include <proto/graphics.h>
X#include <proto/intuition.h>
X#include <proto/diskfont.h>
X#include <proto/console.h>
X#endif
X
X#include "Amiga:amimenu.c"
X
X/*
X * Versions we need of various libraries.  We can't use LIBRARY_VERSION
X * as defined in <exec/types.h> because some of the libraries we need
X * don't have that version number in the 1.2 ROM.
X */
X
X#define INTUITION_VERSION 33L
X#define GRAPHICS_VERSION  33L
X#define DISKFONT_VERSION  34L
X#define ICON_VERSION	  34L
X
X/*  First, external declarations... */
X
Xextern struct Library *IconBase;
Xstruct Library *ConsoleDevice;
X
X#ifdef AZTEC_C
Xvoid FDECL(Alert, (long, char *));
Xvoid NDECL(Forbid);
Xvoid NDECL(Permit);
Xstruct Process *FDECL(FindTask, (char *));
Xstruct Library *FDECL(OpenLibrary, (char *, long));
Xvoid FDECL(CloseLibrary, (struct Library *));
Xstruct Message *FDECL(GetMsg, (struct MsgPort *));
Xvoid FDECL(ReplyMsg, (struct Message *));
Xlong FDECL(OpenDevice, (char *, long, struct IORequest *, long));
Xvoid FDECL(CloseDevice, (struct IORequest *));
Xlong FDECL(DoIO, (struct IORequest *));
Xstruct TextFont *FDECL(OpenDiskFont, (struct TextAttr *));
Xstruct TextFont *FDECL(OpenFont, (struct TextAttr *));
Xvoid FDECL(CloseFont, (struct TextFont *));
Xvoid FDECL(LoadRGB4, (struct ViewPort *, unsigned short *, long));
Xlong FDECL(SetFont, (struct RastPort *, struct TextFont*));
Xstruct MsgPort *FDECL(CreatePort, (char *, long));
Xvoid FDECL(DeletePort, (struct MsgPort *));
Xstruct Screen *FDECL(OpenScreen, (struct NewScreen *));
Xstruct Window *FDECL(OpenWindow, (struct NewWindow *));
Xvoid FDECL(CloseWindow, (struct Window *));
Xvoid FDECL(SetMenuStrip, (struct Window *, struct Menu *));
Xvoid FDECL(ClearMenuStrip, (struct Window *));
Xstruct MenuItem *FDECL(ItemAddress, (struct Menu *, long));
Xlong FDECL(RawKeyConvert, (struct InputEvent *, char *, long, struct KeyMap *));
X#endif
X
Xstatic int NDECL(BufferGetchar);
Xstatic void FDECL(ConvertKey, (register struct IntuiMessage *));
Xstatic void FDECL(ProcessMessage, (register struct IntuiMessage *));
X#ifdef AMIFLUSH
Xstatic struct Message *FDECL(GetFMsg,(struct MsgPort *));
X#endif
Xvoid NDECL(Initialize);
X
X/*  Now our own variables */
X
Xstruct Library *IntuitionBase;
Xstruct Screen *HackScreen;
Xstruct Window *HackWindow;
Xstruct Window *pr_WindowPtr;
Xstruct IOStdReq ConsoleIO;
Xchar Initialized = 0;
X
X#ifdef HACKFONT
Xstruct Library *GfxBase;
Xstruct Library *DiskfontBase;
X#endif
X
Xextern struct Library *ConsoleDevice;
X
X#define CSI	    '\x9b'
X#define NO_CHAR     -1
X#define RAWHELP     0x5F	/* Rawkey code of the HELP key */
X
X/*
X *  It is assumed that all multiple-character outputs are
X *  at most CONBUFFER characters each.
X */
X
X#define CONBUFFER   512
Xstatic char ConsoleBuffer[CONBUFFER];
Xstatic unsigned short Buffered;
X
X#define KBDBUFFER   10
Xstatic unsigned char KbdBuffer[KBDBUFFER];
Xstatic unsigned char KbdBuffered;
X
X#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = ch)
X
X/*
X *  It seems Intuition won't OpenDiskFont our diskFont, so we get the
X *  closest match, which is of course topaz/8. (and if not, it is still
X *  an 8-pixel font, so everything still looks ok)
X */
X
X#ifdef HACKFONT
X
Xstruct TextFont *HackFont;
XUBYTE FontName[] = "NetHack:hack.font";
X#define 	    SIZEOF_DISKNAME	8
X
X#endif
X
Xstruct TextAttr Hack80 = {
X#ifdef HACKFONT
X    &FontName[SIZEOF_DISKNAME],
X#else
X    (UBYTE *) "topaz.font",
X#endif
X    TOPAZ_EIGHTY, FS_NORMAL, FPF_DISKFONT | FPF_ROMFONT
X};
X
X#define BARHEIGHT	11
X#define WINDOWHEIGHT	192
X#define WIDTH		640
X
X#ifdef TEXTCOLOR
X#define DEPTH       3
Xstatic unsigned short palette[] = {
X	0x0000,	/* Black   */
X	0x0DDD, /* White   */
X    	0x0C75, /* Brown   */
X	0x0B08,	/* Cyan    */
X	0x00B0,	/* Green   */
X	0x0F08,	/* Magenta */
X	0x055F,	/* Blue    */
X	0x0F00,	/* Red     */
X};
X#else
X#define DEPTH		2
X#endif
X
Xstruct NewScreen NewHackScreen = {
X    0, 0, WIDTH, BARHEIGHT + WINDOWHEIGHT, DEPTH,
X    0, 1,     /* DetailPen, BlockPen */
X    HIRES,
X    CUSTOMSCREEN,
X    &Hack80,  /* Font */
X    (UBYTE *) " NetHack 3.0 - Ported by Olaf Seibert (KosmoSoft)",
X    NULL,     /* Gadgets */
X    NULL,     /* CustomBitmap */
X};
X
Xstruct NewWindow NewHackWindow = {
X    /* left, top, width, height, detailpen, blockpen */
X    0, BARHEIGHT, WIDTH, WINDOWHEIGHT, -1, -1,
X    RAWKEY | MENUPICK
X#ifdef MAIL
X		      | DISKINSERTED
X#endif
X    , BORDERLESS | BACKDROP | ACTIVATE,
X    NULL, NULL, NULL,
X    NULL, NULL, -1,-1,-1,-1, CUSTOMSCREEN
X};
X
Xstatic int BufferGetchar()
X{
X    register unsigned char *from, *to;
X    register int c;
X    register short i;
X
X    if (KbdBuffered) {
X	c = KbdBuffer[0];
X	KbdBuffered--;
X	to = KbdBuffer;
X	from = to + 1;
X	/* Move the remaining characters */
X	for (i = KbdBuffered; i > 0; i--) {
X	    *to++ = *from++;
X	}
X	return c;
X    }
X
X    return NO_CHAR;
X}
X
X/*
X *  This should remind you remotely of DeadKeyConvert,
X *  but we are cheating a bit.
X *  We want complete control over the numeric keypad, and no
X *  dead keys... (they are assumed to be on Alted keys)
X *  Also assumed is that the IntuiMessage is of type RAWKEY.
X *  For some reason, IECODE_UP_PREFIX events seem to be lost when they
X *  occur while our console window is inactive. This is particulary
X *  troublesome with qualifier keys... Is this because I never
X *  RawKeyConvert those events???
X */
X
Xstatic void ConvertKey(message)
Xregister struct IntuiMessage *message;
X{
X    static struct InputEvent theEvent;
X    static char       numpad[] = "bjnh.lyku";
X    static char  ctrl_numpad[] = "\x02\x0A\x0E\x08.\x0C\x19\x0B\x15";
X    static char shift_numpad[] = "BJNH.LYKU";
X
X    unsigned char buffer[1];
X    register char length;
X    register ULONG qualifier = message->Qualifier;
X    char numeric_pad, shift, control, alt;
X
X    control = (qualifier &  IEQUALIFIER_CONTROL) != 0;
X    shift   = (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0;
X    alt     = (qualifier & (IEQUALIFIER_LALT   | IEQUALIFIER_RALT  )) != 0;
X    /* Allow ALT to function as a META key ... */
X    qualifier &= ~(IEQUALIFIER_LALT | IEQUALIFIER_RALT);
X    numeric_pad = (qualifier & IEQUALIFIER_NUMERICPAD) != 0;
X
X    /*
X     *	Shortcut for HELP and arrow keys. I suppose this is allowed.
X     *	The defines are in intuition/intuition.h, and the keys don't
X     *	serve 'text' input, normally. Also, parsing their escape
X     *	sequences is such a mess...
X     */
X
X    switch (message->Code) {
X    case RAWHELP:
X	length = '?';
X	goto no_arrow;
X    case CURSORLEFT:
X	length = 'h'; goto arrow;
X    case CURSORDOWN:
X	length = 'j'; goto arrow;
X    case CURSORUP:
X	length = 'k'; goto arrow;
X    case CURSORRIGHT:
X	length = 'l';
X    arrow:
X	if (!flags.num_pad)	/* Give digits if set, letters otherwise */
X	    goto wasarrow;
X    no_arrow:
X	BufferQueueChar(length);
X	return;
X    }
X
X#ifdef BETA
X    if (!ConsoleDevice) { /* Should never happen */
X	Abort(AG_IOError | AO_ConsoleDev);
X	return;
X    }
X#endif
X
X    theEvent.ie_Class = IECLASS_RAWKEY;
X    theEvent.ie_Code = message->Code;
X    theEvent.ie_Qualifier = numeric_pad ? IEQUALIFIER_NUMERICPAD :
X					  qualifier;
X    theEvent.ie_EventAddress = (APTR) *(message->IAddress);
X
X    length = RawKeyConvert(&theEvent, buffer, (long) sizeof(buffer), NULL);
X
X    if (length == 1) {   /* Plain ASCII character */
X	length = buffer[0];
X	if (!flags.num_pad && numeric_pad && length >= '1' && length <= '9') {
Xwasarrow:
X	    length -= '1';
X	    if (control) {
X		length = ctrl_numpad[length];
X	    } else if (shift) {
X		length = shift_numpad[length];
X	    } else {
X		length = numpad[length];
X	    }
X	}
X	if (alt)
X	    length |= 0x80;
X	BufferQueueChar(length);
X    } /* else shift, ctrl, alt, amiga, F-key, shift-tab, etc */
X}
X
X/*
X *  Process an incoming IntuiMessage.
X *  It would certainly look nicer if this could be done using a
X *  PA_SOFTINT message port, but we cannot call RawKeyConvert()
X *  during a software interrupt.
X *  Anyway, kbhit() is called often enough, and usually gets
X *  ahead of input demands, when the user types ahead.
X */
X
Xstatic void ProcessMessage(message)
Xregister struct IntuiMessage *message;
X{
X    switch(message->Class) {
X    case MENUPICK:
X	{
X	    USHORT thismenu;
X	    struct MenuItem *item = NULL;
X
X	    thismenu = message->Code;
X	    while (thismenu != MENUNULL) {
X		item = ItemAddress(HackMenu, (ULONG) thismenu);
X		if (KbdBuffered < KBDBUFFER)
X		    BufferQueueChar(item->Command); /* Unused: No COMMSEQ */
X		thismenu = item->NextSelect;
X	    }
X	}
X	break;
X    case RAWKEY:
X	if (!(message->Code & IECODE_UP_PREFIX))
X	    ConvertKey(message);    /* May queue multiple characters */
X	break;			    /* but doesn't do that yet       */
X#ifdef MAIL
X    case DISKINSERTED:
X	{
X	    extern int mustgetmail;
X
X	    if (mustgetmail < 0)
X		mustgetmail = rn1(100,50);
X	}
X#endif
X    }
X    ReplyMsg((struct Message *) message);
X}
X
X/*
X *  Get all incoming messages and fill up the keyboard buffer,
X *  thus allowing Intuition to (maybe) free up the IntuiMessages.
X *  Return when no more messages left, or keyboard buffer half full.
X *  We need to do this since there is no one-to-one correspondence
X *  between characters and incoming messages.
X */
X
Xint kbhit()
X{
X    register struct IntuiMessage *message;
X
X    while( (KbdBuffered < KBDBUFFER / 2) &&
X#ifdef AMIFLUSH
X	    (message = (struct IntuiMessage *) GetFMsg(HackWindow->UserPort)))
X#else
X	    (message = (struct IntuiMessage *) GetMsg(HackWindow->UserPort)) )
X#endif
X	ProcessMessage(message);
X
X    return (int) KbdBuffered;
X}
X
X/*
X *  Get a character from the keyboard buffer, waiting if
X *  not available.
X */
X
Xint WindowGetchar()
X{
X    while (!kbhit()) {
X	WaitPort(HackWindow->UserPort);
X    }
X    return BufferGetchar();
X}
X
X/*
X *  Flush the output waiting in the console output buffer.
X */
X
Xvoid WindowFlush()
X{
X#ifdef BETA
X    if (!ConsoleDevice) { /* Should never happen */
X	Abort(AG_IOError | AO_ConsoleDev);
X	return;
X    }
X#endif
X
X    if (Buffered) {
X	ConsoleIO.io_Command = CMD_WRITE;
X	ConsoleIO.io_Data = (APTR)ConsoleBuffer;
X	ConsoleIO.io_Length = Buffered;
X	DoIO((struct IORequest *) &ConsoleIO);
X	Buffered = 0;
X    }
X}
X
X/*
X *  Queue a single character for output to the console screen.
X */
X
Xvoid WindowPutchar(c)
Xchar c;
X{
X    if (Buffered >= CONBUFFER)
X	WindowFlush();
X
X    ConsoleBuffer[Buffered++] = c;
X}
X
X/*
X *  Queue an entire string for output to the console screen,
X *  flushing the existing characters first, if necessary.
X *  Do not append a newline.
X */
X
Xvoid WindowFPuts(string)
Xchar *string;
X{
X    register int len = strlen(string);
X
X    if (len + Buffered >= CONBUFFER)
X	WindowFlush();
X
X    strcpy(ConsoleBuffer + Buffered, string);
X    Buffered += len;
X}
X
X/*
X *  Queue an entire string for output to the console screen,
X *  flushing the existing characters first, if necessary.
X *  Append a newline.
X */
X
Xvoid WindowPuts(string)
Xchar *string;
X{
X    WindowFPuts(string);
X    WindowPutchar('\n');
X}
X
X/*
X *  Queue a formatted string for output to the console screen,
X *  flushing the existing characters first, if necessary.
X */
X
X/*VARARGS1*/
X#if defined(USE_STDARG) || defined(USE_VARARGS)
Xvoid
XWindowPrintf VA_DECL(char *, fmt)
X    VA_START(fmt);
X    VA_INIT(fmt, char *);
X    WindowFlush();  /* Don't know if all will fit */
X    vsprintf(ConsoleBuffer, fmt, VA_ARGS);
X    ConsoleIO.io_Command = CMD_WRITE;
X    ConsoleIO.io_Data = (APTR)ConsoleBuffer;
X    ConsoleIO.io_Length = -1;
X    DoIO((struct IORequest *) &ConsoleIO);
X    VA_END();
X}
X#else
Xvoid WindowPrintf(fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
Xchar *fmt;
Xlong args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9;
X{
X# ifdef AZTEC_36 	/* Efficient but not portable */
X    format(WindowPutchar, fmt, &args);
X#else
X    WindowFlush();  /* Don't know if all will fit */
X    sprintf(ConsoleBuffer, fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
X    ConsoleIO.io_Command = CMD_WRITE;
X    ConsoleIO.io_Data = (APTR)ConsoleBuffer;
X    ConsoleIO.io_Length = -1;
X    DoIO((struct IORequest *) &ConsoleIO);
X#endif
X}
X#endif
X
X/*
X *  Clean up everything. But before we do, ask the user to hit return
X *  when there is something that s/he should read.
X */
X
Xvoid CleanUp()
X{
X    /* Clean up resources */
X    if (ConsoleIO.io_Device) {
X	register struct ConUnit *cu;
X
X	cu = (struct ConUnit *)ConsoleIO.io_Unit;
X	if (cu->cu_XCCP != 1 || cu->cu_YCCP != 1)
X	    getret();
X
X	CloseDevice((struct IORequest *) &ConsoleIO);
X	ConsoleDevice = NULL;
X    }
X    if (ConsoleIO.io_Message.mn_ReplyPort)
X	DeletePort(ConsoleIO.io_Message.mn_ReplyPort);
X    if (HackWindow) {
X	register struct IntuiMessage *msg;
X
X	((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr;
X	ClearMenuStrip(HackWindow);
X	Forbid();
X	while (msg = (struct IntuiMessage *) GetMsg(HackWindow->UserPort))
X	    ReplyMsg((struct Message *) msg);
X	CloseWindow(HackWindow);
X	Permit();
X	HackWindow = NULL;
X    }
X    if (HackScreen) {
X	CloseScreen(HackScreen);
X	HackScreen = NULL;
X    }
X    if (IconBase) {
X	CloseLibrary(IconBase);
X	IconBase = NULL;
X    }
X#ifdef HACKFONT
X    if (HackFont) {
X	CloseFont(HackFont);
X	HackFont = NULL;
X    }
X    if (DiskfontBase) {
X	CloseLibrary(DiskfontBase);
X	DiskfontBase = NULL;
X    }
X    if (GfxBase) {
X	CloseLibrary(GfxBase);
X	GfxBase = NULL;
X    }
X#endif
X    if (IntuitionBase) {
X	CloseLibrary(IntuitionBase);
X	IntuitionBase = NULL;
X    }
X
X    Initialized = 0;
X}
X
Xvoid Abort(rc)
Xlong rc;
X{
X#ifdef CHDIR
X    extern char orgdir[];
X    chdir(orgdir);
X#endif
X    if (Initialized && ConsoleDevice) {
X	printf("\n\nAbort with alert code %08lx...\n", rc);
X	getret();
X    } else
X	Alert(rc, 0L);
X#ifdef LATTICE
X	{
X/*	__emit(0x4afc);		/* illegal instruction */
X	__emit(0x40fc);		/* divide by */
X	__emit(0x0000);		/*  #0	*/
X		/* NOTE: don't move CleanUp() above here - */
X		/* it is too likely to kill the system     */
X		/* before it can get the SnapShot out, if  */
X		/* there is something really wrong.	   */
X__builtin_printf("abort botch");				/* (KL)TEMP */
X	}
X#endif
X    CleanUp();
X#undef exit
X#ifdef AZTEC_C
X    _abort();
X#endif
X    exit((int) rc);
X}
X
X/*
X *  Open everything we need.
X */
X
Xvoid Initialize()
X{
X    if (Initialized)
X	return;
X
X    if ( (IntuitionBase = OpenLibrary("intuition.library", INTUITION_VERSION))
X	  == NULL)
X	Abort(AG_OpenLib | AO_Intuition);
X
X#ifdef HACKFONT
X
X    if ( (GfxBase = OpenLibrary("graphics.library", GRAPHICS_VERSION)) == NULL)
X	Abort(AG_OpenLib | AO_GraphicsLib);
X
X    /*
X     *	Force our own font to be loaded, if possible.
X     *	If we can open diskfont.library, but not our font, we can close
X     *	the diskfont.library again since it just wastes memory.
X     *	Even if we can open the font, we don't need the diskfont.library
X     *	anymore, since CloseFont is a graphics.library function.
X     */
X
X    if ((HackFont = OpenFont(&Hack80)) == NULL) {
X	if (DiskfontBase = OpenLibrary("diskfont.library", DISKFONT_VERSION)) {
X	    Hack80.ta_Name -= SIZEOF_DISKNAME;
X	    HackFont = OpenDiskFont(&Hack80);
X	    Hack80.ta_Name += SIZEOF_DISKNAME;
X	    CloseLibrary(DiskfontBase);
X	    DiskfontBase = NULL;
X	}
X    }
X#endif
X
X    /* if ( (IconBase = OpenLibrary("icon.library", ICON_VERSION)) == NULL)
X	Abort(AG_OpenLib | AO_IconLib); */
X
X    /*
X     *	Now Intuition is supposed to use our HackFont for the screen,
X     *	since we have a corresponding TextAttr, but it *doesn't*.
X     *	So, we need to do a SetFont() a bit later on.
X     */
X    if ( (HackScreen = OpenScreen(&NewHackScreen)) == NULL)
X	Abort(AN_OpenScreen & ~AT_DeadEnd);
X
X#ifdef TEXTCOLOR
X    LoadRGB4(&HackScreen->ViewPort, palette, 8L);
X#endif
X
X    NewHackWindow.Screen = HackScreen;
X
X    if ( (HackWindow = OpenWindow(&NewHackWindow)) == NULL)
X	Abort(AN_OpenWindow & ~AT_DeadEnd);
X
X    SetMenuStrip(HackWindow, HackMenu);
X    {
X	register struct Process *myProcess = (struct Process *) FindTask(NULL);
X	pr_WindowPtr = (struct Window *)myProcess->pr_WindowPtr;
X	myProcess->pr_WindowPtr = (APTR) HackWindow;
X    }
X#ifdef HACKFONT
X    if (HackFont)
X	SetFont(HackWindow->RPort, HackFont);
X#endif
X
X    ConsoleIO.io_Data = (APTR) HackWindow;
X    ConsoleIO.io_Length = sizeof(*HackWindow);
X    ConsoleIO.io_Message.mn_ReplyPort = CreatePort(NULL, 0L);
X    if (OpenDevice("console.device", 0L, (struct IORequest *) &ConsoleIO, 0L) != 0)
X	Abort(AG_OpenDev | AO_ConsoleDev);
X
X    ConsoleDevice = (struct Library *) ConsoleIO.io_Device;
X
X    Buffered = 0;
X    KbdBuffered = 0;
X
X    /* set CRMOD on */
X    WindowFPuts("\23320h");
X
X    Initialized = 1;
X}
X
X#ifdef AMIFLUSH
X/* This routine adapted from AmigaMail IV-37 by Michael Sinz */
Xstatic struct Message *
XGetFMsg(port)
X	struct MsgPort *port;
X	{
X	struct IntuiMessage *msg,*succ,*succ1;
X
X	if(msg=(struct IntuiMessage *)GetMsg(port)){
X		if(!flags.amiflush)return(msg);
X		if(msg->Class==RAWKEY){
X			Forbid();
X			succ=(struct IntuiMessage *)(port->mp_MsgList.lh_Head);
X			while(succ1=(struct IntuiMessage *)
X				 (succ->ExecMessage.mn_Node.ln_Succ)){
X				if(succ->Class==RAWKEY){
X					Remove((struct Node *)succ);
X					ReplyMsg((struct Message *)succ);
X				}
X				succ=succ1;
X			}
X			Permit();
X		}
X	}
X	return(msg);
X}
X#endif
END_OF_FILE
if test 17495 -ne `wc -c <'amiga/amiwind.c'`; then
    echo shar: \"'amiga/amiwind.c'\" unpacked with wrong size!
fi
# end of 'amiga/amiwind.c'
fi
if test -f 'src/termcap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/termcap.c'\"
else
echo shar: Extracting \"'src/termcap.c'\" \(17330 characters\)
sed "s/^X//" >'src/termcap.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)termcap.c	3.0	88/11/20
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#define MONATTK_H	/* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include "hack.h"	/* for ROWNO, COLNO, *HI, *HE, *AS, *AE */
X
X#include <ctype.h>	/* for isdigit() */
X
X#include "termcap.h"
X
X#if (!defined(SYSV) && !defined(HPUX)) || defined(TOS) || defined(UNIXPC)
X# ifndef LINT
Xextern			/* it is defined in libtermlib (libtermcap) */
X# endif
X	short ospeed;	/* terminal baudrate; used by tputs */
X#else
Xshort	ospeed = 0;	/* gets around "not defined" error message */
X#endif
X
X
X#ifdef MICROPORT_286_BUG
X#define Tgetstr(key) (tgetstr(key,tbuf))
X#else
X#define Tgetstr(key) (tgetstr(key,&tbufptr))
X#endif /* MICROPORT_286_BUG **/
X
XSTATIC_DCL void FDECL(nocmov, (int, int));
X#ifdef TEXTCOLOR
X# ifdef TERMLIB
X#  ifdef OVLB
Xstatic void NDECL(init_hilite);
X#  endif /* OVLB */
X# endif
X#endif
X
XSTATIC_VAR char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
XSTATIC_VAR char *VS, *VE, *US, *UE;
XSTATIC_VAR char *MR, *ME;
X#if 0
XSTATIC_VAR char *MB, *MH;
XSTATIC_VAR char *MD;     /* may already be in use below */
X#endif
X#ifdef TERMLIB
X# ifdef TEXTCOLOR
XSTATIC_VAR char *MD;
X# endif
XSTATIC_VAR int SG;
X#ifdef OVLB
XSTATIC_OVL char PC = '\0';
X#else /* OVLB */
XSTATIC_DCL char PC;
X#endif /* OVLB */
XSTATIC_VAR char tbuf[512];
X#endif
X
X#ifdef OVLB
Xstatic char nullstr[] = "";
X#endif /* OVLB */
X
X#ifndef TERMLIB
XSTATIC_VAR char tgotobuf[20];
X# ifdef TOS
X#define tgoto(fmt, x, y)	(Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf)
X# else
X#define tgoto(fmt, x, y)	(Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
X# endif
X#endif /* TERMLIB */
X
X#ifdef OVLB
X
Xvoid
Xstartup()
X{
X#ifdef TERMLIB
X	register const char *term;
X	register char *tptr;
X	char *tbufptr, *pc;
X#endif
X	register int i;
X
X#ifdef TERMLIB
X# ifdef VMS
X	term = getenv("EMACS_TERM");
X	if (!term)
X	    term = getenv("NETHACK_TERM");
X	if (!term)
X# endif
X	term = getenv("TERM");
X#endif
X	/* Set the default map symbols */
X	(void) memcpy((genericptr_t) showsyms, 
X		(genericptr_t) defsyms, sizeof showsyms);
X
X
X#ifdef TERMLIB
X	if(!term)
X#endif
X#if defined(TOS) && defined(__GNUC__) && defined(TERMLIB)
X		term = "builtin";		/* library has a default */
X#else
X# ifdef MACOS
X	/* dummy termcap for the Mac */
X	HO = "\033[H";
X	CL = "\033[2J";     /* a pseudo-ANSI termcap */
X	CE = "\033[K";
X	CM = "\033[%d;%dH"; /* not used */
X	UP = "\033[A";
X	ND = "\033[C";
X	XD = "\033[B";
X 	BC = "\033[D";
X 	TI = TE = SE = UE = US = HE = "\033[0m";
X 	SO = "\033[1m";
X 	AS = VS = VE = AE = "";
X 	CO = COLNO;
X 	LI = ROWNO + 3;
X 	/* use special font ? */
X	{
X 	   extern short macflags;
X 	   if (macflags & fUseCustomFont)
X	    {
X		Handle  theRes;
X		unsigned char   *sym;
X		short   i;
X
X		sym = &showsyms[S_stone];
X		theRes = GetResource(HACK_DATA,102);
X		HLock(theRes);
X		strncpy((char *)sym,(char *)(*theRes),32);
X		HUnlock(theRes);
X		ReleaseResource(theRes);
X	    }
X	}
X#  ifdef TEXTCOLOR
X	for (i = 0; i < MAXCOLORS; i++) {
X	    hilites[i] = (char *) alloc(sizeof("E[cc"));
X	    Sprintf(hilites[i], "\033[c%c", (char)(i+'a'));
X	}
X#  endif
X# else /* MACOS */
X# ifdef ANSI_DEFAULT
X#  ifdef TOS
X	{
X		CO = 80; LI = 25;
X		TI = VS = VE = TE = "";
X		HO = "\033H";
X		CL = "\033E";		/* the VT52 termcap */
X		CE = "\033K";
X		UP = "\033A";
X		CM = "\033Y%c%c";	/* used with function tgoto() */
X		ND = "\033C";
X		XD = "\033B";
X		BC = "\033D";
X		SO = "\033p";
X		SE = "\033q";
X		HI = "\033p";
X#ifdef TEXTCOLOR
X		HE = "\033q\033b\017";
X		for (i = 0; i < SIZE(hilites); i++) {
X			hilites[i] = (char *) alloc(sizeof("Eb1"));
X			Sprintf(hilites[i], (i%4)?"\033b%c" : "\033p", i);
X		}
X#else
X		HE = "\033q";
X#endif
X	}
X#  else /* TOS */
X	{
X#   ifdef DGK
X		get_scr_size();
X		if(CO < COLNO || LI < ROWNO+3)
X			setclipped();
X#   endif
X		HO = "\033[H";
X		CL = "\033[2J";		/* the ANSI termcap */
X/*		CD = "\033[J"; */
X		CE = "\033[K";
X#   ifndef TERMLIB
X		CM = "\033[%d;%dH";
X#   else
X		CM = "\033[%i%d;%dH";
X#   endif
X		UP = "\033[A";
X		ND = "\033[C";
X		XD = "\033[B";
X#   ifdef MSDOS	/* backspaces are non-destructive */
X		BC = "\b";
X#   else
X		BC = "\033[D";
X#   endif
X		HI = SO = "\033[1m";
X		US = "\033[4m";
X		MR = "\033[7m";
X		TI = HE = SE = UE = ME = "\033[0m";
X		/* strictly, SE should be 2, and UE should be 24,
X		   but we can't trust all ANSI emulators to be
X		   that complete.  -3. */
X#   if !defined(MSDOS) || (defined(TERMLIB) && defined(AMIGA))
X		AS = "\016";
X		AE = "\017";
X#   endif
X		TE = VS = VE = "";
X#   ifdef TEXTCOLOR
X		for (i = 0; i < MAXCOLORS / 2; i++) {
X			hilites[i] = (char *) alloc(sizeof("\033[0;3%dm"));
X			hilites[i+BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm"));
X#    ifdef MSDOS
X			Sprintf(hilites[i], (i == BLUE ? "\033[1;3%dm" : "\033[0;3%dm"), i);
X#    else
X			Sprintf(hilites[i], "\033[0;3%dm", i);
X#    endif
X			Sprintf(hilites[i+BRIGHT], "\033[1;3%dm", i);
X		}
X#   endif
X		return;
X	}
X#  endif /* TOS */
X# else
X		error("Can't get TERM.");
X# endif /* ANSI_DEFAULT */
X# endif /* MACOS */
X#endif /* __GNUC__ && TOS && TERMCAP */
X#ifdef TERMLIB
X	tptr = (char *) alloc(1024);
X
X	tbufptr = tbuf;
X	if(!strncmp(term, "5620", 4))
X		flags.nonull = 1;	/* this should be a termcap flag */
X	if(tgetent(tptr, term) < 1)
X		error("Unknown terminal type: %s.", term);
X	if(pc = Tgetstr("pc"))
X		PC = *pc;
X# ifdef TERMINFO
X	if(!(BC = Tgetstr("le"))) {	
X# else
X	if(!(BC = Tgetstr("bc"))) {	
X# endif
X# if !defined(MINIMAL_TERM) && !defined(HISX)
X		if(!tgetflag("bs"))
X			error("Terminal must backspace.");
X# endif
X		BC = tbufptr;
X		tbufptr += 2;
X		*BC = '\b';
X	}
X# ifdef MINIMAL_TERM
X	HO = NULL;
X# else
X	HO = Tgetstr("ho");
X# endif
X	/*
X	 * LI and CO are set in ioctl.c via a TIOCGWINSZ if available.  If
X	 * the kernel has values for either we should use them rather than
X	 * the values from TERMCAP ...
X	 */
X# ifndef DGK
X	if (!CO) CO = tgetnum("co");
X	if (!LI) LI = tgetnum("li");
X# else
X#  if defined(TOS) && defined(__GNUC__)
X	if (!strcmp(term, "builtin"))
X		get_scr_size();
X	else {
X#  endif
X	CO = tgetnum("co");
X	LI = tgetnum("li");
X	if (!LI || !CO)			/* if we don't override it */
X		get_scr_size();
X#  if defined(TOS) && defined(__GNUC__)
X	}
X#  endif
X# endif
X	if(CO < COLNO || LI < ROWNO+3)
X		setclipped();
X	if(!(CL = Tgetstr("cl")))
X		error("Hack needs CL.");
X	ND = Tgetstr("nd");
X	if(tgetflag("os"))
X		error("Hack can't have OS.");
X	CE = Tgetstr("ce");
X	UP = Tgetstr("up");
X	/* It seems that xd is no longer supported, and we should use
X	   a linefeed instead; unfortunately this requires resetting
X	   CRMOD, and many output routines will have to be modified
X	   slightly. Let's leave that till the next release. */
X	XD = Tgetstr("xd");
X/* not: 		XD = Tgetstr("do"); */
X	if(!(CM = Tgetstr("cm"))) {
X		if(!UP && !HO)
X			error("Hack needs CM or UP or HO.");
X		Printf("Playing hack on terminals without cm is suspect...\n");
X		getret();
X	}
X	SO = Tgetstr("so");
X	SE = Tgetstr("se");
X	US = Tgetstr("us");
X	UE = Tgetstr("ue");
X	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */
X	if(!SO || !SE || (SG > 0)) SO = SE = US = UE = nullstr;
X	TI = Tgetstr("ti");
X	TE = Tgetstr("te");
X	VS = VE = nullstr;
X# ifdef TERMINFO
X	VS = Tgetstr("eA");	/* enable graphics */
X# endif
X# if 0
X	MB = Tgetstr("mb");	/* blink */
X	MD = Tgetstr("md");	/* boldface */
X	MH = Tgetstr("mh");	/* dim */
X# endif
X	MR = Tgetstr("mr");	/* reverse */
X	ME = Tgetstr("me");
X
X	/* Get rid of padding numbers for HI and HE.  Hope they
X	 * aren't really needed!!!  HI and HE are ouputted to the
X	 * pager as a string - so how can you send it NULLS???
X	 *  -jsb
X	 */
X	    HI = (char *) alloc((unsigned)(strlen(SO)+1));
X	    HE = (char *) alloc((unsigned)(strlen(SE)+1));
X	    i = 0;
X	    while(isdigit(SO[i])) i++;
X	    Strcpy(HI, &SO[i]);
X	    i = 0;
X	    while(isdigit(SE[i])) i++;
X	    Strcpy(HE, &SE[i]);
X	AS = Tgetstr("as");
X	AE = Tgetstr("ae");
X	CD = Tgetstr("cd");
X# ifdef TEXTCOLOR
X	MD = Tgetstr("md");
X# endif
X	set_whole_screen();		/* uses LI and CD */
X	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
X	free((genericptr_t)tptr);
X# ifdef TEXTCOLOR
X	init_hilite();
X#  if defined(TOS) && defined(__GNUC__)
X	if (!strcmp(term, "builtin"))
X		HE="\033q\033b3\033c0";	/* to turn off colors, too */
X#  endif
X# endif
X#endif /* TERMLIB */
X}
X
Xvoid
Xstart_screen()
X{
X	xputs(TI);
X	xputs(VS);
X	if (flags.DECgraphics) {
X		/* select the line-drawing character set as the alternate
X		 * character set
X		 * do not select NA ASCII as the primary character set
X		 * since people may reasonably be using the UK set
X		 */
X		xputs("\033)0");
X		/* 'as' and 'ae' are missing from some termcaps */
X		if (!AS) AS = "\016";  /* ^N */
X		if (!AE) AE = "\017";  /* ^O */
X	}
X}
X
Xvoid
Xend_screen()
X{
X	clear_screen();
X	xputs(VE);
X	xputs(TE);
X}
X
X/* Cursor movements */
X
X#endif /* OVLB */
X#ifdef OVL0
X
X#ifdef CLIPPING
X/* if (x,y) is currently viewable, move the cursor there and return TRUE */
Xboolean
Xwin_curs(x, y)
Xint x, y;
X{
X	if (clipping && (x<=clipx || x>=clipxmax || y<=clipy || y>=clipymax))
X		return FALSE;
X	y -= clipy;
X	x -= clipx;
X	curs(x, y+2);
X	return TRUE;
X}
X#endif
X
X#endif /* OVLB */
X#ifdef OVLB
Xvoid
Xcurs(x, y)
Xregister int x, y;	/* not xchar: perhaps xchar is unsigned and
X			   curx-x would be unsigned as well */
X{
X	if (y == cury && x == curx)
X		return;
X	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */
X		cmov(x, y);			/* bunker!wtm */
X		return;
X	}
X	if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
X		nocmov(x, y);
X	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
X		(void) putchar('\r');
X		curx = 1;
X		nocmov(x, y);
X	} else if(!CM) {
X		nocmov(x, y);
X	} else
X		cmov(x, y);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X/* Note to OVLx tinkerers.  The placement of this overlay controls the location
X   of the function xputc().  This function is not currnently in trampoli.[ch]
X   files for what is deemed to be performance reasons.  If this define is moved
X   and or xputc() is taken out of the ROOT overlay, then action must be taken
X   in trampoli.[ch]. */
X
XSTATIC_OVL void
Xnocmov(x, y)
Xint x,y;
X{
X	if (cury > y) {
X		if(UP) {
X			while (cury > y) {	/* Go up. */
X				xputs(UP);
X				cury--;
X			}
X		} else if(CM) {
X			cmov(x, y);
X		} else if(HO) {
X			home();
X			curs(x, y);
X		} /* else impossible("..."); */
X	} else if (cury < y) {
X		if(XD) {
X			while(cury < y) {
X				xputs(XD);
X				cury++;
X			}
X		} else if(CM) {
X			cmov(x, y);
X		} else {
X			while(cury < y) {
X				xputc('\n');
X				curx = 1;
X				cury++;
X			}
X		}
X	}
X	if (curx < x) {		/* Go to the right. */
X		if(!ND) cmov(x, y); else	/* bah */
X			/* should instead print what is there already */
X		while (curx < x) {
X			xputs(ND);
X			curx++;
X		}
X	} else if (curx > x) {
X		while (curx > x) {	/* Go to the left. */
X			xputs(BC);
X			curx--;
X		}
X	}
X}
X
Xvoid
Xcmov(x, y)
Xregister int x, y;
X{
X#ifdef MACOS
X	mcurs(x-1, y-1);
X#else
X	xputs(tgoto(CM, x-1, y-1));
X#endif
X	cury = y;
X	curx = x;
X}
X
X/* See note at OVLx ifdef above.   xputc() is a special function. */
Xvoid
Xxputc(c)
Xchar c;
X{
X#ifdef MACOS
X	mputc(c);
X#else
X	(void) fputc(c, stdout);
X#endif
X}
X
Xvoid
Xxputs(s)
Xconst char *s;
X{
X#ifndef MACOS
X# ifndef TERMLIB
X	(void) fputs(s, stdout);
X# else
X#  ifdef __STDC__
X	tputs(s, 1, (int (*)())xputc);
X#  else
X	tputs(s, 1, xputc);
X#  endif
X# endif
X#else
X	mputs(s);
X#endif
X}
X
Xvoid
Xcl_end() {
X	if(CE)
X		xputs(CE);
X	else {	/* no-CE fix - free after Harold Rynes */
X		/* this looks terrible, especially on a slow terminal
X		   but is better than nothing */
X		register int cx = curx, cy = cury;
X
X		while(curx < CO) {
X			xputc(' ');
X			curx++;
X		}
X		curs(cx, cy);
X	}
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xclear_screen() {
X	xputs(CL);
X	home();
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xvoid
Xhome()
X{
X	if(HO)
X		xputs(HO);
X	else if(CM)
X		xputs(tgoto(CM, 0, 0));
X	else
X		curs(1, 1);	/* using UP ... */
X	curx = cury = 1;
X}
X
Xvoid
Xstandoutbeg()
X{
X	if(SO) xputs(SO);
X}
X
Xvoid
Xstandoutend()
X{
X	if(SE) xputs(SE);
X}
X
Xvoid
Xrevbeg()
X{
X	if(MR) xputs(MR);
X}
X
X#if 0	/* if you need one of these, uncomment it (here and in extern.h) */
Xvoid
Xboldbeg()
X{
X	if(MD) xputs(MD);
X}
X
Xvoid
Xblinkbeg()
X{
X	if(MB) xputs(MB);
X}
X
Xvoid
Xdimbeg()
X/* not in most termcap entries */
X{
X	if(MH) xputs(MH);
X}
X#endif
X
Xvoid
Xm_end()
X{
X	if(ME) xputs(ME);
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xbacksp()
X{
X	xputs(BC);
X}
X
Xvoid
Xbell()
X{
X	if (flags.silent) return;
X	(void) putchar('\007');		/* curx does not change */
X	(void) fflush(stdout);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
X#ifdef ASCIIGRAPH
Xvoid
Xgraph_on() {
X	if (AS) xputs(AS);
X}
X
Xvoid
Xgraph_off() {
X	if (AE) xputs(AE);
X}
X#endif
X
X#endif /* OVL0 */
X#ifdef OVL1
X
X#if !defined(MSDOS) && !defined(MACOS)
X# ifdef VMS
Xstatic const short tmspc10[] = {		/* from termcap */
X	0, 2000, 1333, 909, 743, 666, 333, 166, 83, 55, 50, 41, 27, 20, 13, 10,
X	5
X};
X# else
Xstatic const short tmspc10[] = {		/* from termcap */
X	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
X};
X# endif
X#endif
X
Xvoid
Xdelay_output() {
X	/* delay 50 ms - could also use a 'nap'-system call */
X	/* BUG: if the padding character is visible, as it is on the 5620
X	   then this looks terrible. */
X#if defined(MSDOS) || defined(MACOS)
X	/* simulate the delay with "cursor here" */
X	register int i;
X	for (i = 0; i < 3; i++) {
X		cmov(curx, cury);
X		(void) fflush(stdout);
X	}
X#else /* MSDOS || MACOS */
X	if(!flags.nonull)
X# ifdef TERMINFO
X		/* cbosgd!cbcephus!pds for SYS V R2 */
X#  ifdef __STDC__
X		tputs("$<50>", 1, (int (*)())xputc);
X#  else
X		tputs("$<50>", 1, xputc);
X#  endif
X# else
X#  ifdef __STDC__
X		tputs("50", 1, (int (*)())xputc);
X#  else
X		tputs("50", 1, xputc);
X#  endif
X# endif
X
X	else if(ospeed > 0 && ospeed < SIZE(tmspc10)) if(CM) {
X		/* delay by sending cm(here) an appropriate number of times */
X		register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
X		register int i = 500 + tmspc10[ospeed]/2;
X
X		while(i > 0) {
X			cmov(curx, cury);
X			i -= cmlen*tmspc10[ospeed];
X		}
X	}
X#endif /* MSDOS || MACOS */
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xvoid
Xcl_eos()			/* free after Robert Viduya */
X{				/* must only be called with curx = 1 */
X
X	if(CD)
X		xputs(CD);
X	else {
X		register int cx = curx, cy = cury;
X		while(cury <= LI-2) {
X			cl_end();
X			xputc('\n');
X			curx = 1;
X			cury++;
X		}
X		cl_end();
X		curs(cx, cy);
X	}
X}
X
X#if defined(TEXTCOLOR) && defined(TERMLIB)
X# ifdef UNIX
X/*
X * Sets up color highlighting, using terminfo(4) escape sequences (highlight
X * code found in pri.c).  It is assumed that the background color is black.
X */
X/* terminfo indexes for the basic colors it guarantees */
X#define COLOR_BLACK   1		/* fake out to avoid black on black */
X#define COLOR_BLUE    1
X#define COLOR_GREEN   2
X#define COLOR_CYAN    3
X#define COLOR_RED     4
X#define COLOR_MAGENTA 5
X#define COLOR_YELLOW  6
X#define COLOR_WHITE   7
X
X/* map ANSI RGB to terminfo BGR */
Xconst int ti_map[8] = {
X	COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
X	COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE };
X
Xstatic void
Xinit_hilite()
X{
X	register int c;
X#  ifdef TERMINFO
X	char *setf, *scratch;
X	extern char *tparm();
X#  endif
X
X	for (c = 0; c < MAXCOLORS; c++)
X		hilites[c] = HI;
X
X#  ifdef TERMINFO
X	if (tgetnum("Co") < 8 || (setf = tgetstr("Sf", 0)) == NULL)
X		return;
X
X	for (c = 0; c < MAXCOLORS / 2; c++) {
X  		scratch = tparm(setf, ti_map[c]);
X		hilites[c] = (char *) alloc(strlen(scratch) + 1);
X		hilites[c+BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1);
X		Strcpy(hilites[c], scratch);
X		Strcpy(hilites[c+BRIGHT], MD);
X		Strcat(hilites[c+BRIGHT], scratch);
X	}
X#  endif
X}
X
X# else /* UNIX */
X
X/*
X * Sets up highlighting sequences, using ANSI escape sequences (highlight code
X * found in pri.c).  The termcap entry for HI (from SO) is scanned to find the
X * background color.
X */
X
Xstatic void
Xinit_hilite()
X{
X#  ifdef TOS
X	int c;
X#  else
X	int backg = BLACK, foreg = WHITE, len;
X	register int c, color;
X#  endif
X
X	for (c = 0; c < SIZE(hilites); c++)
X		hilites[c] = HI;
X
X#  ifdef TOS
X	hilites[BROWN] = "\033b0\033c1";
X	hilites[RED] = "\033b1";
X	hilites[MAGENTA] = hilites[MAGENTA|BRIGHT] = "\033b1\033c2";
X	hilites[CYAN] = hilites[CYAN|BRIGHT] = "\033b3\033c2";
X	hilites[BLUE] = hilites[BLUE|BRIGHT] = "\033b2";
X	hilites[GREEN] = hilites[GREEN|BRIGHT] = "\033b2\033c3";
X	hilites[GRAY] = "\033b3\033c0";
X	hilites[ORANGE_COLORED] = "\033b3\033c1";
X	hilites[YELLOW] = "\033b1\033c3";
X	hilites[WHITE] = "\033b0\033c3";
X#  else /* TOS */
X	/* find the background color, HI[len] == 'm' */
X	len = strlen(HI) - 1;
X
X	if (HI[len] != 'm' || len < 3) return;
X
X	c = 2;
X	while (c < len) {
X	    if ((color = atoi(&HI[c])) == 0) {
X		/* this also catches errors */
X		foreg = WHITE; backg = BLACK;
X	    /*
X	    } else if (color == 1) {
X		foreg |= BRIGHT;
X	    */
X	    } else if (color >= 30 && color <= 37) {
X		foreg = color - 30;
X	    } else if (color >= 40 && color <= 47) {
X		backg = color - 40;
X	    }
X	    while (isdigit(HI[++c]));
X	    c++;
X	}
X
X	for (c = 0; c < MAXCOLORS / 2; c++)
X	    /* avoid invisibility */
X	    if (foreg != c && backg != c) {
X		hilites[c] = (char *) alloc(sizeof("\033[0;3%d;4%dm"));
X		hilites[c+BRIGHT] = (char *) alloc(sizeof("\033[1;3%d;4%dm"));
X#ifdef MSDOS    /* brighten low-visibility colors */
X		if (c == BLUE)
X		    Sprintf(hilites[c], "\033[1;3%d;4%dm", c, backg);
X		else
X#endif
X		Sprintf(hilites[c], "\033[0;3%d;4%dm", c, backg);
X		Sprintf(hilites[c+BRIGHT], "\033[1;3%d;4%dm", c, backg);
X	    }
X#  endif /* TOS */
X}
X# endif /* UNIX */
X#endif /* TEXTCOLOR */
X
X#endif /* OVLB */
END_OF_FILE
if test 17330 -ne `wc -c <'src/termcap.c'`; then
    echo shar: \"'src/termcap.c'\" unpacked with wrong size!
fi
# end of 'src/termcap.c'
fi
if test -f 'src/u_init.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/u_init.c'\"
else
echo shar: Extracting \"'src/u_init.c'\" \(18113 characters\)
sed "s/^X//" >'src/u_init.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)u_init.c	3.0	89/11/15
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
Xstruct trobj {
X	unsigned short int trotyp;
X	schar trspe;
X	char trolet;
X	Bitfield(trquan,6);
X	Bitfield(trknown,1);
X	Bitfield(trbless,2);
X};
X
Xstatic void FDECL(ini_inv, (struct trobj *));
Xstatic void FDECL(knows_class,(CHAR_P));
Xstatic int FDECL(role_index,(CHAR_P));
X
X#define	UNDEF_TYP	0
X#define	UNDEF_SPE	'\177'
X#define	UNDEF_BLESS	2
X
Xconst char *(roles[]) = {	/* must all have distinct first letter */
X			/* roles[2] and [6] are changed for females */
X			/* in all cases, the corresponding male and female */
X			/* roles must start with the same letter */
X	"Archeologist", "Barbarian", "Cave-man", "Elf", "Healer", "Knight",
X	"Priest", "Rogue", "Samurai", "Tourist", "Valkyrie", "Wizard"
X};
X
Xconst char *pl_classes = "ABCEHKPRSTVW";
X
Xstruct you zerou;
X
Xstruct trobj Cave_man[] = {
X#define C_ARROWS	2
X	{ CLUB, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ BOW, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS },	/* quan is variable */
X	{ LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Barbarian[] = {
X	{ TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ AXE, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ RING_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ FOOD_RATION, 0, FOOD_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Knight[] = {
X	{ LONG_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ SPEAR, 2, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ RING_MAIL, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ HELMET, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ SMALL_SHIELD, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ LEATHER_GLOVES, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Elf[] = {
X#define E_ARROWS	2
X#define E_ARMOR		3
X#ifdef TOLKIEN
X	{ ELVEN_SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ ELVEN_BOW, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ ELVEN_ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS },
X	{ UNDEF_TYP, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ LEMBAS_WAFER, 0, FOOD_SYM, 2, 1, 0 },
X#else
X	{ SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ BOW, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS },
X	{ ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ FOOD_RATION, 0, FOOD_SYM, 2, 1, 0 },
X#endif
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Valkyrie[] = {
X	{ LONG_SWORD, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ DAGGER, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ SMALL_SHIELD, 3, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ FOOD_RATION, 0, FOOD_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Healer[] = {
X	{ SCALPEL, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ LEATHER_GLOVES, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ STETHOSCOPE, 0, TOOL_SYM, 1, 1, 0 },
X	{ POT_HEALING, 0, POTION_SYM, 4, 1, UNDEF_BLESS },
X	{ POT_EXTRA_HEALING, 0, POTION_SYM, 4, 1, UNDEF_BLESS },
X	{ WAN_SLEEP, UNDEF_SPE, WAND_SYM, 1, 1, UNDEF_BLESS },
X#ifdef SPELLS
X	/* always blessed, so it's guaranteed readable */
X	{ SPE_HEALING, 0, SPBOOK_SYM, 1, 1, 1 },
X	{ SPE_EXTRA_HEALING, 0, SPBOOK_SYM, 1, 1, 1 },
X#endif
X	{ APPLE, 0, FOOD_SYM, 5, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Archeologist[] = {
X	/* if adventure has a name...  idea from tan@uvm-gen */
X	{ BULLWHIP, 2, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ FEDORA, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ FOOD_RATION, 0, FOOD_SYM, 3, 1, 0 },
X	{ PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 1, UNDEF_BLESS },
X	{ TINNING_KIT, 0, TOOL_SYM, 1, 1, UNDEF_BLESS },
X	{ SACK, 0, TOOL_SYM, 1, 0, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Tinopener[] = {
X	{ TIN_OPENER, 0, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Magicmarker[] = {
X	{ MAGIC_MARKER, UNDEF_SPE, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Lamp[] = {
X	{ LAMP, 5, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
X#ifndef HARD
Xstruct trobj Saving[] = {
X	{ AMULET_OF_LIFE_SAVING, 0, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X#endif
X
X#ifdef EXPLORE_MODE
Xstruct trobj Wishing[] = {
X	{ WAN_WISHING, 3, WAND_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X#endif
X
X#ifdef WALKIES
Xstruct trobj Leash[] = {
X	{ LEASH, 0, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X#endif
X
Xstruct trobj Blindfold[] = {
X	{ BLINDFOLD, 0, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Tourist[] = {
X#define	T_DARTS		0
X	{ DART, 2, WEAPON_SYM, 25, 1, UNDEF_BLESS },	/* quan is variable */
X	{ UNDEF_TYP, UNDEF_SPE, FOOD_SYM, 10, 1, 0 },
X	{ POT_EXTRA_HEALING, 0, POTION_SYM, 2, 1, UNDEF_BLESS },
X	{ SCR_MAGIC_MAPPING, 0, SCROLL_SYM, 4, 1, UNDEF_BLESS },
X	{ EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1, 0 },
X#ifdef SHIRT
X	{ HAWAIIAN_SHIRT, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X#endif
X	{ CREDIT_CARD, 0, TOOL_SYM, 1, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Rogue[] = {
X#define R_DAGGERS	1
X	{ SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ DAGGER, 0, WEAPON_SYM, 10, 1, 0 },	/* quan is variable */
X	{ LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ POT_SICKNESS, 0, POTION_SYM, 1, 1, 0 },
X	{ LOCK_PICK, 9, TOOL_SYM, 1, 1, 0 },
X	{ SACK, 0, TOOL_SYM, 1, 0, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Wizard[] = {
X#define W_MULTSTART	2
X#ifdef SPELLS
X#  define W_MULTEND	6
X#else
X#  define W_MULTEND	5
X#endif
X	{ ATHAME, 1, WEAPON_SYM, 1, 1, 1 },	/* for dealing with ghosts */
X	{ CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ UNDEF_TYP, UNDEF_SPE, WAND_SYM, 1, 1, UNDEF_BLESS },
X	{ UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 1, UNDEF_BLESS },
X	{ UNDEF_TYP, UNDEF_SPE, POTION_SYM, 3, 1, UNDEF_BLESS },
X	{ UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 1, UNDEF_BLESS },
X#ifdef SPELLS
X	{ UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 1, 1, UNDEF_BLESS },
X#endif
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct	trobj	Samurai[] = {
X	{ KATANA, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X	{ SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },	/* the wakizashi */
X	{ SHURIKEN, 0, WEAPON_SYM, 9, 1, UNDEF_BLESS },        /* quan is variable */
X	{ SPLINT_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ FORTUNE_COOKIE, 0, FOOD_SYM, 3, 1, 0 },
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct	trobj	Priest[] = {
X	{ MACE, 1, WEAPON_SYM, 1, 1, 1 },
X	{ CHAIN_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ SMALL_SHIELD, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X	{ POT_WATER, 0, POTION_SYM, 4, 1, 1 },	/* holy water */
X	{ CLOVE_OF_GARLIC, 0, FOOD_SYM, 1, 1, 0 },
X#ifdef SPELLS
X	{ UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 1, UNDEF_BLESS },
X#endif
X	{ 0, 0, 0, 0, 0, 0 }
X};
X
Xstatic void
Xknows_class(sym)
Xregister char sym;
X{
X	register unsigned ct;
X	for (ct = 1; ct <= NROFOBJECTS; ct++)
X		if (objects[ct].oc_olet == sym) {
X			makeknown(ct);
X			objects[ct].oc_descr = NULL;	/* not a "discovery" */
X		}
X}
X
Xstatic int
Xrole_index(pc)
Xchar pc;
X{
X	register const char *cp;
X
X	if(cp = index(pl_classes, pc))
X		return(cp - pl_classes);
X	return(-1);
X}
X
Xvoid
Xu_init()
X{
X	register int i;
X	char pick, pc;
X#ifdef __GNULINT__
X	pick = i = 0;	/* prevent "used before set" warnings */
X#endif
X	Printf("\nNetHack, Copyright 1985, 1986, 1987, 1988, 1989, 1990.");
X	Printf("\n         By Stichting Mathematisch Centrum and M. Stephenson.");
X	Printf("\n         See license for details.\n\n");
X
X	if(flags.female)  {	/* should have been set in NETHACKOPTIONS */
X		roles[2] = "Cave-woman";
X		roles[6] = "Priestess";
X	}
X
X	if(pc = pl_character[0]) {
X		if('a' <= pc && pc <= 'z') pc += 'A'-'a';
X		if((i = role_index(pc)) >= 0)
X			goto got_suffix;
X		Printf("\nUnknown role: %c\n", pc);
X		pl_character[0] = pc = 0;
X	}
X
X#ifndef MACOS
X
X	Printf("\nShall I pick a character for you? [Y,N, or Q(quit)] ");
X
X	while(!index("yYnNqQ", (pick = readchar())) && !index(quitchars, pick))
X		bell();
X
X	if(index(quitchars, pick)) pick = 'Y';
X	else if('a' <= pick && pick <= 'z') pick += 'A'-'a';
X
X	Printf("%c\n", pick);		/* echo */
X
X	if (pick == 'Q') {
X		clearlocks();
X		settty(NULL);
X		exit(0);
X	}
X
X	if (pick == 'Y')
X		goto beginner;
X
X	Printf("\nWhat kind of character are you:\n\n");
X	Printf(" 	 %s,", An(roles[0]));
X	for(i = 1; i < SIZE(roles); i++) {
X		Printf(" %s", an(roles[i]));
X		if((((i + 1) % 4) == 0) && (i != SIZE(roles) -1)) 
X			Printf(",\n        ");
X		else if(i < SIZE(roles) - 2)	Printf(",");
X		if(i == SIZE(roles) - 2)	Printf(" or");
X	}
X	Printf("?\n         [");
X	for(i = 0; i < SIZE(roles); i++) Printf("%c,", pl_classes[i]);
X	Printf(" or Q] ");
X
X	while(pc = readchar()) {
X		if('a' <= pc && pc <= 'z') pc += 'A'-'a';
X		if (pc == 'Q') {
X			clearlocks();
X			settty(NULL);
X			exit(0);
X		}
X		if((i = role_index(pc)) >= 0) {
X			Printf("%c\n", pc);	/* echo */
X			(void) fflush(stdout);	/* should be seen */
X			break;
X		}
X		if(pc == '\n') break;
X		bell();
X	}
X	if(pc == '\n')	pc = 0;
X
X#else
X	flags.wantspace = FALSE;
X#endif /* MACOS */
X
Xbeginner:
X	if(!pc) {
X		i = rn2(SIZE(roles));
X		pc = pl_classes[i];
X		Printf("\nThis game you will be %s.\n", an(roles[i]));
X		getret();
X		/* give him some feedback in case mklev takes much time */
X		(void) putchar('\n');
X		(void) fflush(stdout);
X	}
X
Xgot_suffix:
X
X	(void) strncpy(pl_character, roles[i], PL_CSIZ-1);
X	pl_character[PL_CSIZ-1] = 0;
X	flags.beginner = 1;
X	u = zerou;
X	u.usym = S_HUMAN;
X	u.umoved = FALSE;
X	u.ugrave_arise = -1;
X
X	u.ulevel = 0;	/* set up some of the initial attributes */
X	u.uhp = u.uhpmax = newhp();
X	adjabil(0,1);
X	u.ulevel = 1;
X
X	u.uluck  = u.moreluck = 0;
X	init_uhunger();
X	uarm = uarmc = uarmh = uarms = uarmg = uarmf =
X#ifdef SHIRT
X	uarmu =
X#endif
X	uwep = uball = uchain = uleft = uright = 0;
X
X#ifdef SPELLS
X	u.uen = u.uenmax = 1;
X	for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL;
X#endif
X#ifdef THEOLOGY
X	u.ublesscnt = 300;			/* no prayers just yet */
X	u.ublessed = 0;				/* not worthy yet */
X	u.ugangr   = 0;				/* gods not angry */
X#endif
X#if defined(THEOLOGY) && defined(ELBERETH)
X	u.uhand_of_elbereth = 0;
X#endif
X#ifdef MEDUSA
X	u.ukilled_medusa = 0;
X#endif
X#ifdef HARD
X	u.udemigod = u.udg_cnt = 0;		/* not a demi-god yet... */
X#endif
X#ifdef POLYSELF
X	u.umonnum = u.ulycn = -1;
X	u.mh = u.mhmax = u.mtimedone = 0;
X	set_uasmon();
X#endif
X	switch(pc) {
X	/* pc will always be in uppercase by this point */
X	case 'C':
X		Cave_man[C_ARROWS].trquan = 12 + rnd(30);
X		ini_inv(Cave_man);
X		break;
X	case 'T':
X		Tourist[T_DARTS].trquan = 20 + rnd(20);
X		u.ugold = u.ugold0 = rnd(1000);
X		ini_inv(Tourist);
X		if(!rn2(25)) ini_inv(Tinopener);
X		else if(!rn2(25)) ini_inv(Magicmarker);
X#ifdef WALKIES
X		else if(!rn2(25)) ini_inv(Leash);
X#endif
X		break;
X	case 'R':
X		Rogue[R_DAGGERS].trquan = 5 + rnd(10);
X		u.ugold = u.ugold0 = 0;
X		ini_inv(Rogue);
X		if(!rn2(5)) ini_inv(Blindfold);
X		makeknown(SACK);
X		break;
X	case 'W':
X#ifdef SPELLS
X		u.uen = u.uenmax += rn2(4);
X#endif
X		ini_inv(Wizard);
X		if(!rn2(5)) ini_inv(Magicmarker);
X		if(!rn2(5)) ini_inv(Blindfold);
X		break;
X	case 'A':
X		ini_inv(Archeologist);
X		if(!rn2(10)) ini_inv(Tinopener);
X		else if(!rn2(4)) ini_inv(Lamp);
X		else if(!rn2(10)) ini_inv(Magicmarker);
X		knows_class(GEM_SYM);
X		makeknown(SACK);
X		/* We can't set trknown for it, then it'd be "uncursed"
X		 * sack...
X		 */
X		break;
X	case 'E':
X		Elf[E_ARROWS].trquan = 15+rnd(20);
X#ifdef TOLKIEN
X		Elf[E_ARMOR].trotyp = ((rn2(100) >= 50)
X				 ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
X			/* rn2(100) > 50 necessary because some random number
X			 * generators are bad enough to seriously skew the
X			 * results if we use rn2(2)...  --KAA
X			 */
X#endif
X		ini_inv(Elf);
X		if(!rn2(5)) ini_inv(Blindfold);
X		else if(!rn2(6)) ini_inv(Lamp);
X#ifdef TOLKIEN
X		/* makeknown(ELVEN_SHORT_SWORD);
X		 * no need to do this since the initial inventory contains one,
X		 * so ini_inv already did it for us
X		 */
X		objects[ELVEN_SHORT_SWORD].oc_descr = NULL;
X		/* makeknown(ELVEN_ARROW); */
X		objects[ELVEN_ARROW].oc_descr = NULL;
X		/* makeknown(ELVEN_BOW); */
X		objects[ELVEN_BOW].oc_descr = NULL;
X		makeknown(ELVEN_SPEAR);
X		objects[ELVEN_SPEAR].oc_descr = NULL;
X		makeknown(ELVEN_DAGGER);
X		objects[ELVEN_DAGGER].oc_descr = NULL;
X		makeknown(ELVEN_BROADSWORD);
X		objects[ELVEN_BROADSWORD].oc_descr = NULL;
X#endif
X		makeknown(ELVEN_CLOAK);
X		objects[ELVEN_CLOAK].oc_descr = NULL;
X		break;
X	case 'V':
X		flags.female = TRUE;
X		ini_inv(Valkyrie);
X		if(!rn2(6)) ini_inv(Lamp);
X		knows_class(WEAPON_SYM);
X		break;
X	case 'H':
X		u.ugold = u.ugold0 = rnd(1000)+1000;
X		ini_inv(Healer);
X		if(!rn2(25)) ini_inv(Lamp);
X		break;
X	case 'K':
X		ini_inv(Knight);
X		knows_class(WEAPON_SYM);
X		break;
X	case 'B':
X		ini_inv(Barbarian);
X		if(!rn2(6)) ini_inv(Lamp);
X		knows_class(WEAPON_SYM);
X		break;
X	case 'S':
X		ini_inv(Samurai);
X		if(!rn2(5)) ini_inv(Blindfold);
X		knows_class(WEAPON_SYM);
X		break;
X	case 'P':
X#ifdef SPELLS
X		u.uen = u.uenmax += rn2(4);
X#endif
X		ini_inv(Priest);
X		if(!rn2(10)) ini_inv(Magicmarker);
X		else if(!rn2(10)) ini_inv(Lamp);
X		break;
X
X	default:	/* impossible */
X		break;
X	}
X#ifndef HARD
X	ini_inv(Saving);	/* give beginners an extra chance */
X#endif
X#ifdef EXPLORE_MODE
X	if (discover)
X		ini_inv(Wishing);
X#endif
X	find_ac();			/* get initial ac value */
X	init_attr((pick != 'Y') ? 75 : 77);	/* init attribute values */
X	max_rank_sz();			/* set max str size for class ranks */
X/*
X *	Do we really need this?
X */
X	for(i = 0; i < A_MAX; i++)
X	    if(!rn2(20)) {
X		register int xd = rn2(7) - 2;	/* biased variation */
X		adjattrib(i, xd, TRUE);
X		if (ABASE(i) < AMAX(i)) AMAX(i) = ABASE(i);
X	    }
X
X	/* make sure he can carry all he has - especially for T's */
X	while(inv_weight() > 0)
X		adjattrib(A_STR, 1, TRUE);
X
X#ifdef THEOLOGY
X	u.ualignbase[0] = u.ualignbase[1] = u.ualigntyp;
X#endif
X}
X
Xstatic void
Xini_inv(trop)
Xregister struct trobj *trop;
X{
X	struct obj *obj;
X	while(trop->trolet) {
X		boolean undefined = (trop->trotyp == UNDEF_TYP);
X
X		if (!undefined)
X			obj = mksobj((int)trop->trotyp,FALSE);
X		else obj = mkobj(trop->trolet,FALSE);
X
X		/* For random objects, do not create certain overly powerful
X		 * items: wand of wishing, ring of levitation, or the
X		 * polymorph/polymorph control combination.  Specific objects,
X		 * i.e. the discovery wishing, are still OK.
X		 * Also, don't get a couple of really useless items.  (Note:
X		 * punishment isn't "useless".  Some players who start out with
X		 * one will immediately read it and use the iron ball as a
X		 * weapon.)
X		 */
X		if (undefined) {
X#ifdef POLYSELF
X			static unsigned NEARDATA nocreate = STRANGE_OBJECT;
X#  ifdef SPELLS
X			static unsigned NEARDATA nocreate2 = STRANGE_OBJECT;
X#  endif
X#endif
X			static unsigned NEARDATA nocreate3 = STRANGE_OBJECT;
X
X			while(obj->otyp == WAN_WISHING
X#ifdef POLYSELF
X				|| obj->otyp == nocreate
X#  ifdef SPELLS
X				|| obj->otyp == nocreate2
X#  endif
X#endif
X				|| obj->otyp == nocreate3
X#ifdef ELBERETH
X				|| obj->otyp == RIN_LEVITATION
X#endif
X				/* 'useless' items */
X				|| obj->otyp == POT_HALLUCINATION
X				|| obj->otyp == SCR_AMNESIA
X				|| obj->otyp == SCR_FIRE
X				|| obj->otyp == RIN_AGGRAVATE_MONSTER
X				|| obj->otyp == RIN_HUNGER
X				|| obj->otyp == WAN_NOTHING
X							) {
X				free((genericptr_t) obj);
X				obj = mkobj(trop->trolet, FALSE);
X			}
X
X			/* Don't start with +0 or negative rings */
X			if(objects[obj->otyp].oc_charged && obj->spe <= 0)
X				obj->spe = rne(3);
X
X			/* Heavily relies on the fact that 1) we create wands
X			 * before rings, 2) that we create rings before
X			 * spellbooks, and that 3) not more than 1 object of a
X			 * particular symbol is to be prohibited.  (For more
X			 * objects, we need more nocreate variables...)
X			 */
X#ifdef POLYSELF
X			switch (obj->otyp) {
X			    case WAN_POLYMORPH:
X			    case RIN_POLYMORPH:
X				nocreate = RIN_POLYMORPH_CONTROL;
X				break;
X			    case RIN_POLYMORPH_CONTROL:
X				nocreate = RIN_POLYMORPH;
X#  ifdef SPELLS
X				nocreate2 = SPE_POLYMORPH;
X#  endif /* SPELLS */
X			}
X#endif /* POLYSELF */
X			/* Don't have 2 of the same ring */
X			if (obj->olet == RING_SYM)
X				nocreate3 = obj->otyp;
X		}
X
X		obj->bknown = trop->trknown;
X		if(objects[obj->otyp].oc_uses_known) obj->known = trop->trknown;
X		/* not obj->dknown = 1; - let him look at it at least once */
X		obj->cursed = 0;
X		if(obj->olet == TOOL_SYM){ /* problem with multiple tools */
X			obj->quan = 1;     /* might be > because of grenades */
X		}
X		if(obj->olet == WEAPON_SYM) {
X			obj->quan = trop->trquan;
X			trop->trquan = 1;
X		}
X		if(obj->olet == FOOD_SYM && undefined) {
X			obj->known = 1;
X			/* needed for tins and eggs; harmless otherwise */
X			obj->bknown = 1;
X		}
X		/*
X		 * The below lines not needed because they don't correspond
X		 * to any actual inventory; nobody gets random tools.
X		else if(obj->olet == TOOL_SYM && undefined) {
X			obj->bknown = (obj->otyp != BAG_OF_TRICKS
X				&& obj->otyp != SACK
X				&& obj->otyp != CHEST
X				&& obj->otyp != LARGE_BOX
X				&& obj->otyp != ICE_BOX);
X		}
X		*/
X		if(trop->trspe != UNDEF_SPE)
X			obj->spe = trop->trspe;
X		if(trop->trbless != UNDEF_BLESS)
X			obj->blessed = trop->trbless;
X
X		if (!Is_container(obj))
X			obj->owt = weight(obj);
X			/* defined after setting otyp+quan */
X		obj = addinv(obj);
X
X		/* Make the type known if necessary */
X		if (objects[obj->otyp].oc_descr && obj->known)
X		    	makeknown(obj->otyp);
X
X		if(obj->olet == ARMOR_SYM){
X			if (is_shield(obj) && !uarms)
X				setworn(obj, W_ARMS);
X			else if (is_helmet(obj) && !uarmh)
X				setworn(obj, W_ARMH);
X			else if (is_gloves(obj) && !uarmg)
X				setworn(obj, W_ARMG);
X#ifdef SHIRT
X			else if (obj->otyp == HAWAIIAN_SHIRT && !uarmu)
X				setworn(obj, W_ARMU);
X#endif
X			else if (is_cloak(obj) && !uarmc)
X				setworn(obj, W_ARMC);
X			else if (is_boots(obj) && !uarmf)
X				setworn(obj, W_ARMF);
X			else if (!uarm)
X				setworn(obj, W_ARM);
X		}
X		/* below changed by GAN 01/09/87 to allow wielding of
X		 * pick-axe or can-opener if there is no weapon
X		 */
X		if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
X		   obj->otyp == TIN_OPENER)
X			if(!uwep) setuwep(obj);
X#ifndef PYRAMID_BUG
X		if(--trop->trquan) continue;	/* make a similar object */
X#else
X		if(trop->trquan) {		/* check if zero first */
X			--trop->trquan;
X			if(trop->trquan)
X				continue;	/* make a similar object */
X		}
X#endif
X		trop++;
X	}
X}
X
Xvoid
Xplnamesuffix() {
X	register char *p;
X	if(p = rindex(plname, '-')) {
X		*p = 0;
X		pl_character[0] = p[1];
X		pl_character[1] = 0;
X		if(!plname[0]) {
X			askname();
X			plnamesuffix();
X		}
X	}
X}
END_OF_FILE
if test 18113 -ne `wc -c <'src/u_init.c'`; then
    echo shar: \"'src/u_init.c'\" unpacked with wrong size!
fi
# end of 'src/u_init.c'
fi
echo shar: End of archive 38 \(of 56\).
cp /dev/null ark38isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 56 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0