Logo Search packages:      
Sourcecode: jnethack version File versions  Download package

winfuncs.c

/*    SCCS Id: @(#)winfuncs.c    3.1    96/02/16 */
/* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993,1996. */
/* NetHack may be freely redistributed.  See license for details. */

#include "NH:sys/amiga/windefs.h"
#include "NH:sys/amiga/winext.h"
#include "NH:sys/amiga/winproto.h"
#include "patchlevel.h"

extern struct TagItem scrntags[];

static BitMapHeader amii_bmhd;
static void cursor_common(struct RastPort *, int, int);

#ifdef      CLIPPING
int CO, LI;

/* Changing clipping region, skip clear of screen in overview window. */
int reclip;

/* Must be set to at least two or you will get stuck! */
int xclipbord = 4, yclipbord = 2;
#endif

int mxsize, mysize;
struct Rectangle amii_oldover;
struct Rectangle amii_oldmsg;

int amii_msgAPen;
int amii_msgBPen;
int amii_statAPen;
int amii_statBPen;
int amii_menuAPen;
int amii_menuBPen;
int amii_textAPen;
int amii_textBPen;
int amii_otherAPen;
int amii_otherBPen;
long amii_libvers = LIBRARY_FONT_VERSION;

void
ami_wininit_data( void )
{
    extern unsigned short amii_init_map[ AMII_MAXCOLORS ];
    extern unsigned short amiv_init_map[ AMII_MAXCOLORS ];
    if( !WINVERS_AMIV )
    {
# ifdef     TEXTCOLOR
      amii_numcolors = 8;
# else
      amii_numcolors = 4;
# endif
      amii_defpens[ 0 ] = C_BLACK;  /* DETAILPEN        */
      amii_defpens[ 1 ] = C_BLUE;   /* BLOCKPEN         */
      amii_defpens[ 2 ] = C_BROWN;  /* TEXTPEN          */
      amii_defpens[ 3 ] = C_WHITE;  /* SHINEPEN         */
      amii_defpens[ 4 ] = C_BLUE;   /* SHADOWPEN        */
      amii_defpens[ 5 ] = C_CYAN;   /* FILLPEN          */
      amii_defpens[ 6 ] = C_WHITE;  /* FILLTEXTPEN      */
      amii_defpens[ 7 ] = C_CYAN;   /* BACKGROUNDPEN    */
      amii_defpens[ 8 ] = C_RED;    /* HIGHLIGHTTEXTPEN */
      amii_defpens[ 9 ] = C_WHITE;  /* BARDETAILPEN     */
      amii_defpens[ 10 ] = C_CYAN;  /* BARBLOCKPEN      */
      amii_defpens[ 11 ] = C_BLUE;  /* BARTRIMPEN       */
      amii_defpens[ 12 ] = (unsigned short) ~0;

      amii_msgAPen = C_WHITE;
      amii_msgBPen = C_BLACK;
      amii_statAPen = C_WHITE;
      amii_statBPen = C_BLACK;
      amii_menuAPen = C_WHITE;
      amii_menuBPen = C_BLACK;
      amii_textAPen = C_WHITE;
      amii_textBPen = C_BLACK;
      amii_otherAPen = C_RED;
      amii_otherBPen = C_BLACK;

      mxsize = 8;
      mysize = 8;

      amii_libvers = LIBRARY_FONT_VERSION;
      memcpy( amii_initmap, amii_init_map, sizeof( amii_initmap ) );
    }
    else
    {
      mxsize = 16;
      mysize = 16;

      amii_numcolors = 16;

      amii_defpens[ 0 ] = C_BLACK;  /* DETAILPEN        */
      amii_defpens[ 1 ] = C_WHITE;  /* BLOCKPEN         */
      amii_defpens[ 2 ] = C_BLACK;  /* TEXTPEN          */
      amii_defpens[ 3 ] = C_CYAN;   /* SHINEPEN         */
      amii_defpens[ 4 ] = C_BLUE;   /* SHADOWPEN        */
      amii_defpens[ 5 ] = C_GREY;   /* FILLPEN          */
      amii_defpens[ 6 ] = C_RED;    /* FILLTEXTPEN      */
      amii_defpens[ 7 ] = C_GREY;   /* BACKGROUNDPEN    */
      amii_defpens[ 8 ] = C_RED;    /* HIGHLIGHTTEXTPEN */
      amii_defpens[ 9 ] = C_WHITE;  /* BARDETAILPEN     */
      amii_defpens[ 10 ] = C_GREY;  /* BARBLOCKPEN      */
      amii_defpens[ 11 ] = C_BLUE;  /* BARTRIMPEN       */
      amii_defpens[ 12 ] = ~0;

      amii_msgAPen = C_WHITE;
      amii_msgBPen = C_GREY;
      amii_statAPen = C_WHITE;
      amii_statBPen = C_GREY;
      amii_menuAPen = C_BLACK;
      amii_menuBPen = C_LTGREY;
      amii_textAPen = C_BLACK;
      amii_textBPen = C_LTGREY;
      amii_otherAPen = C_WHITE;
      amii_otherBPen = C_GREY;
      amii_libvers = LIBRARY_TILE_VERSION;

      memcpy( amii_initmap, amiv_init_map, sizeof( amii_initmap ) );
    }
#ifdef OPT_DISPMAP
    dispmap_sanity();
#endif
    memcpy(flags.amii_dripens,amii_defpens,sizeof(flags.amii_dripens));
}

# ifdef     INTUI_NEW_LOOK
struct Hook fillhook;
struct TagItem wintags[] =
{
      { WA_BackFill, (ULONG)&fillhook },
      { TAG_END, 0 },
};
# endif

void
amii_destroy_nhwindow(win)      /* just hide */
    register winid win;
{
    int i;
    int type;
    register struct amii_WinDesc *cw;

    if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
    {
      panic(winpanicstr,win,"destroy_nhwindow");
    }

    if( WINVERS_AMIV )
    {
      if( cw->type == NHW_MAP )
      {
          /* If inventory is up, close it now, it will be freed later */
          if( alwaysinvent && WIN_INVEN != WIN_ERR &&
                        amii_wins[ WIN_INVEN ] &&
                        amii_wins[ WIN_INVEN ]->win )
          {
            dismiss_nhwindow( WIN_INVEN );
          }

          /* Tear down overview window if it is up */
          if( WIN_OVER != WIN_ERR )
          {
            amii_destroy_nhwindow( WIN_OVER );
            WIN_OVER = WIN_ERR;
          }
      }
      else if( cw->type == NHW_OVER )
      {
          struct Window *w = amii_wins[ WIN_OVER ]->win;
          amii_oldover.MinX = w->LeftEdge;
          amii_oldover.MinY = w->TopEdge;
          amii_oldover.MaxX = w->Width;
          amii_oldover.MaxY = w->Height;

          if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
          {
            w = amii_wins[ WIN_MESSAGE ]->win;
            amii_oldmsg.MinX = w->LeftEdge;
            amii_oldmsg.MinY = w->TopEdge;
            amii_oldmsg.MaxX = w->Width;
            amii_oldmsg.MaxY = w->Height;
            SizeWindow( amii_wins[ WIN_MESSAGE ]->win,
                  (amiIDisplay->xpix -
                  amii_wins[ WIN_MESSAGE ]->win->LeftEdge) -
                  amii_wins[ WIN_MESSAGE ]->win->Width,
                  0 );
          }
      }
    }

    /* Tear down the Intuition stuff */
    dismiss_nhwindow(win);
    type = cw->type;

    if( cw->resp )    free( cw->resp );
    if( cw->canresp ) free( cw->canresp );
    if( cw->morestr ) free( cw->morestr );
    if( cw->hook ) free( cw->hook );
    cw->hook = NULL;

    if( cw->data && ( cw->type == NHW_MESSAGE ||
                      cw->type == NHW_MENU || cw->type == NHW_TEXT ) )
    {
      for( i = 0; i < cw->maxrow; ++i )
      {
          if( cw->data[ i ] )
            free( cw->data[ i ] );
      }
      free( cw->data );
    }

    free( cw );
    amii_wins[win] = NULL;

    /* Set globals to WIN_ERR for known one-of-a-kind windows. */
    if( win == WIN_MAP) WIN_MAP = WIN_ERR;
    else if( win == WIN_STATUS) WIN_STATUS = WIN_ERR;
    else if( win == WIN_MESSAGE) WIN_MESSAGE = WIN_ERR;
    else if( win == WIN_INVEN) WIN_INVEN = WIN_ERR;

}

#ifdef INTUI_NEW_LOOK
struct FillParams
{
      struct Layer *layer;
      struct Rectangle bounds;
      WORD offsetx;
      WORD offsety;
};

void
#ifndef _DCC
__interrupt
#endif
__saveds __asm
LayerFillHook(
    register __a0 struct Hook *hk,
    register __a2 struct RastPort *rp,
    register __a1 struct FillParams *fp )
{
    register long x, y, xmax, ymax;
    register int apen;

    switch( (int)hk->h_Data )
    {
    case NHW_STATUS:
      apen = amii_statBPen;
      break;
    case NHW_MESSAGE:
      apen = amii_msgBPen;
      break;
    case NHW_TEXT:
      apen = amii_textBPen;
      break;
    case NHW_MENU:
      apen = amii_menuBPen;
      break;
    case -2:
      apen = amii_otherBPen;
      break;
    case NHW_BASE:
    case NHW_MAP:
    case NHW_OVER:
    default:
      apen = C_BLACK;
      break;
    }

    x = fp->bounds.MinX;
    y = fp->bounds.MinY;
    xmax = fp->bounds.MaxX;
    ymax = fp->bounds.MaxY;

    SetAPen( rp, apen );
    SetBPen( rp, apen );
    SetDrMd( rp, JAM2 );
    RectFill( rp, x, y, xmax, ymax );
}
#endif


amii_create_nhwindow(type)
    register int type;
{
    register struct Window *w = NULL;
    register struct NewWindow *nw = NULL;
    register struct amii_WinDesc *wd = NULL;
    struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL;
    register int newid;
    int maph;

    maph = ( 22 * mxsize ) + HackScreen->WBorTop +
                  HackScreen->WBorBottom + HackFont->tf_YSize + 1 + 1;
    if( WIN_STATUS != WIN_ERR && amii_wins[ WIN_STATUS ] )
      stwin = amii_wins[ WIN_STATUS ]->win;

    if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
      msgwin = amii_wins[ WIN_MESSAGE ]->win;

    if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
      mapwin = amii_wins[ WIN_MAP ]->win;

    /* Create Port anytime that we need it */

    if( HackPort == NULL )
    {
      HackPort = CreatePort( NULL, 0 );
      if( !HackPort )
          panic( "no memory for msg port" );
    }

    nw = &new_wins[ type ].newwin;
    nw->Width = amiIDisplay->xpix;
    nw->Screen = HackScreen;

    if( WINVERS_AMIV )
    {
      nw->DetailPen = C_GREYBLUE;
      nw->BlockPen = C_WHITE;
    }
    else
    {
      nw->DetailPen = C_WHITE;
      nw->BlockPen = C_BLACK;
    }

    if( ( !WINVERS_AMIV && type == NHW_MAP ) || type == NHW_BASE )
    {
      nw->LeftEdge = 0;

      if( !WINVERS_AMIV && ( bigscreen && type == NHW_MAP ) )
      {
          nw->Height = maph;
          if( msgwin && stwin )
          {
            nw->TopEdge = msgwin->TopEdge + msgwin->Height +
                      ((stwin->TopEdge-
                      (msgwin->TopEdge + msgwin->Height)-maph))/2;
          }
          else
          {
            panic( "msgwin and stwin must open before map" );
          }
          nw->Width = HackScreen->Width;
      }
      else
      {
          nw->TopEdge = 1;
          nw->Height = amiIDisplay->ypix - nw->TopEdge;
      }
    }
    else if( type == NHW_MAP && WINVERS_AMIV )
    {
      struct Window *w;

      w = amii_wins[ WIN_MESSAGE ]->win;

      nw->LeftEdge = 0;
      nw->TopEdge = w->TopEdge + w->Height;
      nw->Width = amiIDisplay->xpix - nw->LeftEdge;
      w = amii_wins[ WIN_STATUS ]->win;
      nw->Height = w->TopEdge - nw->TopEdge;
      nw->MaxHeight = 0xffff;
      nw->MaxWidth = 0xffff;
      if( nw->TopEdge + nw->Height > amiIDisplay->ypix - 1 )
          nw->Height = amiIDisplay->ypix - nw->TopEdge - 1;
    }
    else if( type == NHW_STATUS )
    {
      if( !WINVERS_AMIV && ( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] ) )
          w = amii_wins[ WIN_MAP ]->win;
      else
      if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
          w = amii_wins[ WIN_BASE ]->win;
      else
          panic( "No window to base STATUS location from" );

      /* Expand the height of window by borders */
      nw->Height = (txheight * 2) + 4;
      if( WINVERS_AMIV || bigscreen )
          nw->Height += w->WScreen->WBorTop + w->WScreen->WBorBottom + txheight + 1;
      else
          nw->Title = 0;

      nw->TopEdge = amiIDisplay->ypix - nw->Height - 1;
      nw->LeftEdge = w->LeftEdge;
      if( nw->LeftEdge + nw->Width >= amiIDisplay->xpix )
          nw->LeftEdge = 0;
      if( nw->Width >= amiIDisplay->xpix - nw->LeftEdge )
          nw->Width = amiIDisplay->xpix - nw->LeftEdge;
    }
    else if( WINVERS_AMIV && type == NHW_OVER )
    {
      nw->Flags |= WINDOWSIZING|WINDOWDRAG|WINDOWCLOSE;
      nw->IDCMPFlags |= CLOSEWINDOW;
      /* Bring up window as half the width of the message window, and make
       * the message window change to one half the width...
       */
      if( amii_oldover.MaxX != 0 )
      {
          nw->LeftEdge = amii_oldover.MinX;
          nw->TopEdge = amii_oldover.MinY;
          nw->Width = amii_oldover.MaxX;
          nw->Height = amii_oldover.MaxY;
          ChangeWindowBox( amii_wins[ WIN_MESSAGE ]->win,
                  amii_oldmsg.MinX, amii_oldmsg.MinY,
                  amii_oldmsg.MaxX, amii_oldmsg.MaxY );
      }
      else
      {
          nw->LeftEdge = (amii_wins[ WIN_MESSAGE ]->win->Width*4)/9;
          nw->TopEdge = amii_wins[ WIN_MESSAGE ]->win->TopEdge;
          nw->Width = amiIDisplay->xpix - nw->LeftEdge;
          nw->Height = amii_wins[ WIN_MESSAGE ]->win->Height;
          SizeWindow( amii_wins[ WIN_MESSAGE ]->win,
                nw->LeftEdge - amii_wins[ WIN_MESSAGE ]->win->Width, 0 );
      }
    }
    else if( type == NHW_MESSAGE )
    {
      if( !WINVERS_AMIV && ( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] ) )
          w = amii_wins[ WIN_MAP ]->win;
      else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
          w = amii_wins[ WIN_BASE ]->win;
      else
          panic( "No window to base STATUS location from" );

      nw->TopEdge = 1;
      if( !WINVERS_AMIV && ( ( HackScreen->Height - 1 -
            ( ( TextsFont->tf_YSize +
                HackScreen->WBorTop + 1 + HackScreen->WBorBottom ) * 2 ) -
            ( ( TextsFont->tf_YSize + 1 ) * 2 ) - 2 ) - maph <
                TextsFont->tf_YSize + 3 ) )
      {
          scrollmsg = 0;
      }
      if( scrollmsg )
      {
          nw->FirstGadget = &MsgScroll;
          if( WINVERS_AMIV )
          {
            nw->Height = TextsFont->tf_YSize + HackScreen->WBorTop + 3 +
                        HackScreen->WBorBottom;
            if( bigscreen )
                nw->Height += ( TextsFont->tf_YSize * 10 );
            else
                nw->Height += ( TextsFont->tf_YSize * 3 );
          }
          else
          {
            nw->Height = HackScreen->Height - 1 -
                /* Size of all borders for bigscreen */
                ( ( TextsFont->tf_YSize + HackScreen->WBorTop + 1 +
                                  HackScreen->WBorBottom ) * 2 ) -
                /* Text space in status window */
                ( ( TextsFont->tf_YSize + 1 ) * 2 ) - 2 -
                maph;
          }
          nw->Flags |= WINDOWSIZING|WINDOWDRAG;
      }
      else
      {
          nw->Height = HackScreen->WBorTop + 1 +
            ((txheight+1)*(1+(scrollmsg != 0))) + 1 + HackScreen->WBorBottom;
      }
#ifdef  INTUI_NEW_LOOK
      if( IntuitionBase->LibNode.lib_Version >= 37 )
      {
          MsgPropScroll.Flags |= PROPNEWLOOK;
      }
#endif
    }

    nw->IDCMPFlags |= MENUPICK;

    /* Check if there is "Room" for all this stuff... */
    if( ( WINVERS_AMIV || bigscreen ) &&
      type != NHW_BASE )
    {
      nw->Flags &= ~( BORDERLESS | BACKDROP );

      if( WINVERS_AMIV )
      {
          if( type == NHW_STATUS )
          {
            nw->Flags &= ~( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING );
            nw->IDCMPFlags &= ~NEWSIZE;
          }
          else
          {
            nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING );
            nw->IDCMPFlags |= NEWSIZE;
          }
      }
      else
      {
          if( HackScreen->Width < 657 )
          {
            nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH );
          }
          else
          {
            nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT );
            if( type == NHW_MAP )
                nw->Flags |= WINDOWSIZING;
          }
      }
    }

    /* No titles on a hires only screen */
    if( !bigscreen )
      nw->Title = 0;

    wd = (struct amii_WinDesc *)alloc(sizeof(struct amii_WinDesc));
    memset( wd, 0, sizeof( struct amii_WinDesc ) );

    if( WINVERS_AMIV )
    {
      /* Special backfill for these types of layers */
      switch( type )
      {
      case NHW_MESSAGE:
      case NHW_STATUS:
      case NHW_TEXT:
      case NHW_MENU:
      case NHW_BASE:
      case NHW_OVER:
      case NHW_MAP:
          if( wd )
          {
            fillhook.h_Entry = (ULONG(*)())LayerFillHook;
            fillhook.h_Data = (void *)type;
            fillhook.h_SubEntry = 0;
            wd->hook = alloc( sizeof( fillhook ) );
            memcpy( wd->hook, &fillhook, sizeof( fillhook ) );
            memcpy( wd->wintags, wintags, sizeof( wd->wintags) );
            wd->wintags[0].ti_Data = (long)wd->hook;
            nw->Extension = (void *)wd->wintags;
          }
          break;
      }
    }

    /* Don't open MENU or TEXT windows yet */

    if( type == NHW_MENU || type == NHW_TEXT )
      w = NULL;
    else
      w=OpenShWindow( (void *)nw );

    if( w == NULL && type != NHW_MENU && type != NHW_TEXT )
    {
      char buf[ 100 ];

      sprintf( buf, "nw type (%d) dims l: %d, t: %d, w: %d, h: %d",
            type,
            nw->LeftEdge, nw->TopEdge,
            nw->Width, nw->Height );
      raw_print( buf );
      panic("bad openwin %d",type);
    }

    /* Check for an empty slot */

    for(newid = 0; newid<MAXWIN + 1; newid++)
    {
      if(amii_wins[newid] == 0)
          break;
    }

    if(newid==MAXWIN+1)
      panic("time to write re-alloc code\n");

    /* Set wincnt accordingly */

    if( newid > wincnt )
      wincnt = newid;

    /* Do common initialization */

    amii_wins[newid] = wd;

    wd->newwin = NULL;
    wd->win = w;
    wd->type = type;
    wd->wflags = 0;
    wd->active = FALSE;
    wd->curx=wd->cury = 0;
    wd->resp = wd->canresp = wd->morestr = 0;   /* CHECK THESE */
    wd->maxrow = new_wins[type].maxrow;
    wd->maxcol = new_wins[type].maxcol;

    if( type != NHW_TEXT && type != NHW_MENU )
    {
      if( TextsFont && ( type == NHW_MESSAGE || type == NHW_STATUS ) )
      {
          SetFont(w->RPort, TextsFont);
          txheight = w->RPort->TxHeight;
          txwidth = w->RPort->TxWidth;
          txbaseline = w->RPort->TxBaseline;
          if( type == NHW_MESSAGE )
          {
            if (scrollmsg )
            {
                if( WINVERS_AMIV )
                {
                  WindowLimits( w, 100, w->BorderTop +
                        w->BorderBottom +
                        ((txheight+1)*2) + 1, 0, 0 );
                }
                else
                {
                  WindowLimits( w, w->Width, w->BorderTop +
                        w->BorderBottom +
                        ((txheight+1)*2) + 1, 0, 0 );
                }
            }
            else
            {
                WindowLimits( w, w->Width, w->BorderTop +
                        w->BorderBottom +
                        txheight + 2, 0, 0 );
            }
          }
      }
#ifdef HACKFONT
      else if( HackFont )
          SetFont(w->RPort, HackFont);
#endif
    }

    /* Text and menu windows are not opened yet */
    if( w )
    {
      wd->rows = ( w->Height - w->BorderTop -
          w->BorderBottom - 2 ) / w->RPort->TxHeight;
      wd->cols = ( w->Width - w->BorderLeft -
          w->BorderRight - 2 ) / w->RPort->TxWidth;
    }

    /* Okay, now do the individual type initialization */

    switch(type)
    {
      /* History lines for MESSAGE windows are stored in cw->data[?].
       * maxcol and maxrow are used as cursors.  maxrow is the count
       * of the number of history lines stored.  maxcol is the cursor
       * to the last line that was displayed by ^P.
       */
      case NHW_MESSAGE:
          SetMenuStrip(w, HackMenu);
          if( WINVERS_AMIV )
            if(iflags.msg_history<20)iflags.msg_history=20;
          else
            if(iflags.msg_history<40)iflags.msg_history=40;

          if(iflags.msg_history>400)iflags.msg_history=400;
          iflags.window_inited=TRUE;
          wd->data = (char **)alloc( iflags.msg_history*sizeof( char * ) );
          memset( wd->data, 0, iflags.msg_history * sizeof( char * ) );
          wd->maxrow = wd->maxcol = 0;
          /* Indicate that we have not positioned the cursor yet */
          wd->curx = -1;
          break;

          /* A MENU contains a list of lines in wd->data[?].  These
           * lines are created in amii_putstr() by reallocating the size
           * of wd->data to hold enough (char *)'s.  wd->rows is the
           * number of (char *)'s allocated.  wd->maxrow is the number
           * used.  wd->maxcol is used to track how wide the menu needs
           * to be.  wd->resp[x] contains the characters that correspond
           * to selecting wd->data[x].  wd->resp[x] corresponds to
           * wd->data[x] for any x. Elements of wd->data[?] that are not
           * valid selections have the corresponding element of
           * wd->resp[] set to a value of '\01';  i.e. a ^A which is
           * not currently a valid keystroke for responding to any
           * MENU or TEXT window.
           */
      case NHW_MENU:
          wd->resp=(char*)alloc(256);
          wd->resp[0]=0;
          wd->rows = wd->maxrow = 0;
          wd->cols = wd->maxcol = 0;
          wd->data = NULL;
          break;

          /* See the explanation of MENU above.  Except, wd->resp[] is not
           * used for TEXT windows since there is no selection of a
           * a line performed/allowed.  The window is always full
           * screen width.
           */
      case NHW_TEXT:
          wd->rows = wd->maxrow = 0;
          wd->cols = wd->maxcol = amiIDisplay->cols;
          wd->data = NULL;
          wd->morestr = NULL;
          break;

          /* The status window has only two lines.  These are stored in
           * wd->data[], and here we allocate the space for them.
           */
      case NHW_STATUS:
          SetMenuStrip(w, HackMenu);
          /* wd->cols is the number of characters which fit across the
           * screen.
           */
          wd->data=(char **)alloc(3*sizeof(char *));
          wd->data[0] = (char *)alloc(wd->cols + 10);
          wd->data[1] = (char *)alloc(wd->cols + 10);
          wd->data[2] = NULL;
          break;

          /* NHW_OVER does not use wd->data[] or the other text
           * manipulating members of the amii_WinDesc structure.
           */
      case NHW_OVER:
          SetMenuStrip(w, HackMenu);
          break;

          /* NHW_MAP does not use wd->data[] or the other text
           * manipulating members of the amii_WinDesc structure.
           */
      case NHW_MAP:
          SetMenuStrip(w, HackMenu);
          if( WINVERS_AMIV )
          {
            extern struct TextFont *RogueFont;
            CO = (w->Width-w->BorderLeft-w->BorderRight)/mxsize;
            LI = (w->Height-w->BorderTop-w->BorderBottom)/mysize;
            amii_setclipped();
            SetFont( w->RPort, RogueFont);
            SetAPen( w->RPort, C_WHITE);  /* XXX not sufficient */
            SetBPen( w->RPort, C_BLACK);
            SetDrMd( w->RPort, JAM2);
          }
          else
          {
            if( HackFont )
                SetFont( w->RPort, HackFont );
          }
          break;

          /* The base window must exist until CleanUp() deletes it. */
      case NHW_BASE:
          SetMenuStrip(w, HackMenu);
          /* Make our requesters come to our screen */
          {
            register struct Process *myProcess =
                              (struct Process *) FindTask(NULL);
            pr_WindowPtr = (struct Window *)(myProcess->pr_WindowPtr);
            myProcess->pr_WindowPtr = (APTR) w;
          }

          /* Need this for RawKeyConvert() */

          ConsoleIO.io_Data = (APTR) w;
          ConsoleIO.io_Length = sizeof( struct Window );
          ConsoleIO.io_Message.mn_ReplyPort = CreatePort(NULL, 0L);
          if( OpenDevice("console.device", -1L,
                        (struct IORequest *) &ConsoleIO, 0L) != 0)
          {
            Abort(AG_OpenDev | AO_ConsoleDev);
          }

          ConsoleDevice = (struct Library *) ConsoleIO.io_Device;

          KbdBuffered = 0;

#ifdef HACKFONT
          if( TextsFont )
            SetFont( w->RPort, TextsFont );
          else if( HackFont )
            SetFont( w->RPort, HackFont );
#endif
          txwidth = w->RPort->TxWidth;
          txheight = w->RPort->TxHeight;
          txbaseline = w->RPort->TxBaseline;
          break;

      default:
          panic("bad create_nhwindow( %d )\n",type);
          return WIN_ERR;
    }

    return( newid );
}

/* Initialize the windowing environment */

void
amii_init_nhwindows(argcp,argv)
    int *argcp;
    char **argv;
{
    int i;
    struct Screen *wbscr;
    int forcenobig = 0;

    if( HackScreen )
      panic( "init_nhwindows() called twice", 0 );

      /* run args & set bigscreen from -L(1)/-l(-1) */
    {
      int lclargc = *argcp;
      int t;
      char **argv_in = argv;
      char **argv_out = argv;

      for(t=1;t<=lclargc;t++){
          if(!strcmp("-L",*argv_in) || !strcmp("-l",*argv_in)){
            bigscreen = (*argv_in[1]=='l') ? -1 : 1;
            /* and eat the flag */
            (*argcp)--;
          } else {
            *argv_out = *argv_in;   /* keep the flag */
            argv_out++;
          }
          argv_in++;
      }
      *argv_out = 0;
    }

    WIN_MESSAGE = WIN_ERR;
    WIN_MAP = WIN_ERR;
    WIN_STATUS = WIN_ERR;
    WIN_INVEN = WIN_ERR;
    WIN_BASE = WIN_ERR;
    WIN_OVER = WIN_ERR;

    if ( (IntuitionBase = (struct IntuitionBase *)
        OpenLibrary("intuition.library", amii_libvers )) == NULL)
    {
      Abort(AG_OpenLib | AO_Intuition);
    }

    if ( (GfxBase = (struct GfxBase *)
            OpenLibrary("graphics.library", amii_libvers )) == NULL)
    {
      Abort(AG_OpenLib | AO_GraphicsLib);
    }

    if( WINVERS_AMIV && (LayersBase = (struct Library *)
            OpenLibrary("layers.library", amii_libvers )) == NULL)
    {
      Abort(AG_OpenLib | AO_LayersLib);
    }

    amiIDisplay=(struct amii_DisplayDesc *)alloc(sizeof(struct amii_DisplayDesc));
    memset( amiIDisplay, 0, sizeof( struct amii_DisplayDesc ) );

    /* Use Intuition sizes for overscan screens... */

    amiIDisplay->xpix = 0;
#ifdef      INTUI_NEW_LOOK
    if( IntuitionBase->LibNode.lib_Version >= 37 )
    {
      if( wbscr = LockPubScreen( "Workbench" ) )
      {
          amiIDisplay->xpix = wbscr->Width;
          amiIDisplay->ypix = wbscr->Height;
          UnlockPubScreen( NULL, wbscr );
      }
    }
#endif
    if( amiIDisplay->xpix == 0 )
    {
      amiIDisplay->ypix = GfxBase->NormalDisplayRows;
      amiIDisplay->xpix = GfxBase->NormalDisplayColumns;
    }

    amiIDisplay->cols = amiIDisplay->xpix / FONTWIDTH;

    amiIDisplay->toplin=0;
    amiIDisplay->rawprint=0;
    amiIDisplay->lastwin=0;

    if( bigscreen == 0 )
    {
      if( ( GfxBase->ActiView->ViewPort->Modes & LACE ) == LACE )
      {
          amiIDisplay->ypix *= 2;
          NewHackScreen.ViewModes |= LACE;
          bigscreen = 1;
      }
      else if( GfxBase->NormalDisplayRows >= 300 )
      {
          bigscreen = 1;
      }
    }
    else if( bigscreen == -1 )
    {
      bigscreen = 0;
      forcenobig = 1;
    }
    else if( bigscreen )
    {
      /* If bigscreen requested and we don't have enough rows in
       * noninterlaced mode, switch to interlaced...
       */
      if( GfxBase->NormalDisplayRows < 300 )
      {
          amiIDisplay->ypix *= 2;
          NewHackScreen.ViewModes |= LACE;
      }
    }

    if( !bigscreen )
    {
      scrollmsg = 0;
      alwaysinvent = 0;
    }
    amiIDisplay->rows = amiIDisplay->ypix / FONTHEIGHT;

#ifdef HACKFONT
    /*
     *  Load the fonts that we need.
     */

    if( DiskfontBase =
            OpenLibrary( "diskfont.library", amii_libvers  ) )
    {
      Hack80.ta_Name -= SIZEOF_DISKNAME;
      HackFont = OpenDiskFont( &Hack80 );
      Hack80.ta_Name += SIZEOF_DISKNAME;

      /* Textsfont13 is filled in with "FONT=" settings. The default is
       * courier/13.
       */
      TextsFont = NULL;
      if( bigscreen )
          TextsFont = OpenDiskFont( &TextsFont13 );

      /* Try hack/8 for texts if no user specified font */
      if( TextsFont == NULL )
      {
          Hack80.ta_Name -= SIZEOF_DISKNAME;
          TextsFont = OpenDiskFont( &Hack80 );
          Hack80.ta_Name += SIZEOF_DISKNAME;
      }

      /* If no fonts, make everything topaz 8 for non-view windows.
       */
      Hack80.ta_Name = "topaz.font";
      RogueFont = OpenFont( &Hack80 );
      if(!RogueFont) panic("Can't get topaz:8");
      if( !HackFont || !TextsFont )
      {
          if( !HackFont )
          {
            HackFont = OpenFont( &Hack80 );
            if( !HackFont )
                panic( "Can't get a map font, topaz:8" );
          }

          if( !TextsFont )
          {
            TextsFont = OpenFont( &Hack80 );
            if( !TextsFont )
                panic( "Can't open text font" );
          }
      }
      CloseLibrary(DiskfontBase);
      DiskfontBase = NULL;
    }
#endif

    /* This is the size screen we want to open, within reason... */

    NewHackScreen.Width = max( WIDTH, amiIDisplay->xpix );
    NewHackScreen.Height = max( SCREENHEIGHT, amiIDisplay->ypix );
    {
      static char fname[18];
      sprintf(fname,"NetHack %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
      NewHackScreen.DefaultTitle=fname;
    }
    NewHackScreen.BlockPen = C_BLACK;
#ifdef      INTUI_NEW_LOOK
    if( IntuitionBase->LibNode.lib_Version >= 37 )
    {
      int i;
      struct DimensionInfo dims;
      DisplayInfoHandle handle;
      struct DisplayInfo disp;
      ULONG modeid = DEFAULT_MONITOR_ID|HIRES_KEY;

      NewHackScreen.Width = STDSCREENWIDTH;
      NewHackScreen.Height = STDSCREENHEIGHT;

      if( forcenobig == 0 )
      {
          wbscr = LockPubScreen( "Workbench" );
          if( ( wbscr = LockPubScreen( "Workbench" ) ) != NULL ||
            ( wbscr = LockPubScreen( NULL ) ) != NULL )
          {
            /* Get the default pub screen's size */
            modeid = GetVPModeID( &wbscr->ViewPort );
            if( modeid == INVALID_ID ||
                ModeNotAvailable( modeid ) ||
                ( handle = FindDisplayInfo( modeid ) ) == NULL ||
                GetDisplayInfoData( handle, (char *)&dims, sizeof( dims ),
                  DTAG_DIMS, modeid ) <= 0 ||
                GetDisplayInfoData( handle, (char *)&disp, sizeof( disp ),
                  DTAG_DISP, modeid ) <= 0 )
            {
                modeid = DEFAULT_MONITOR_ID|HIRES_KEY;
                /* If the display database seems to not work, use the screen
                 * dimensions
                 */
                NewHackScreen.Height = wbscr->Height;
                NewHackScreen.Width = wbscr->Width;
            
                /*
                 * Request LACE if it looks laced.  For 2.1/3.0, we will get
                 * promoted to the users choice of modes (if promotion is allowed)
                 * If the user is using a dragable screen, things will get hosed
                 * but that is life...
                 */
                if( wbscr->ViewPort.Modes & LACE )
                  NewHackScreen.ViewModes |= LACE;
                modeid = -1;
            }
            else
            {
                /* Use the display database to get the correct information */
                if( disp.PropertyFlags & DIPF_IS_LACE )
                  NewHackScreen.ViewModes |= LACE;
                NewHackScreen.Height = dims.StdOScan.MaxY;
                NewHackScreen.Width = dims.StdOScan.MaxX;
            }
            NewHackScreen.TopEdge = 0;
            NewHackScreen.LeftEdge = 0;

            UnlockPubScreen( NULL, wbscr );
          }
      }

      for( i = 0; scrntags[i].ti_Tag != TAG_DONE; ++i )
      {
          switch( scrntags[i].ti_Tag )
          {
            case SA_DisplayID:
                if( !amii_scrnmode || ModeNotAvailable( amii_scrnmode ) )
                {
                  if( ModeNotAvailable( modeid ) )
                  {
                      scrntags[i].ti_Tag = TAG_IGNORE;
                      break;
                  }
                  else
                      scrntags[i].ti_Data = (long)modeid;
                }
                else
                  modeid = scrntags[i].ti_Data = (long)amii_scrnmode;
                if( ( handle = FindDisplayInfo( modeid ) ) != NULL &&
                  GetDisplayInfoData( handle, (char *)&dims, sizeof( dims ),
                      DTAG_DIMS, modeid ) > 0 &&
                  GetDisplayInfoData( handle, (char *)&disp, sizeof( disp ),
                      DTAG_DISP, modeid ) > 0 )
                {
                  if( disp.PropertyFlags & DIPF_IS_LACE )
                      NewHackScreen.ViewModes |= LACE;
                  NewHackScreen.Height = dims.StdOScan.MaxY;
                  NewHackScreen.Width = dims.StdOScan.MaxX;
                }
                break;

            case SA_Pens:
                scrntags[i].ti_Data = (long)flags.amii_dripens;
                break;
          }
      }
    }
#endif

    if( WINVERS_AMIV )
    {
            /* swap the menu colors around */
      struct Menu *mp = HackMenu;
      while(mp){
            struct MenuItem *mip = mp->FirstItem;
            while(mip){
                  ((struct IntuiText *)mip->ItemFill)->FrontPen = C_BLACK;
                  ((struct IntuiText *)mip->ItemFill)->BackPen = C_WHITE;
                  mip = mip->NextItem;
            }
            mp = mp->NextMenu;
      }

      amii_bmhd = ReadTileImageFiles( );
      memcpy(flags.amii_curmap,amii_initmap,sizeof(flags.amii_curmap));
    }
    else
    {
      memcpy( amii_initmap, amii_init_map, sizeof( amii_initmap ) );
      memcpy(flags.amii_curmap,amii_initmap,sizeof(flags.amii_curmap));
    }

    /* Find out how deep the screen needs to be, 32 planes is enough! */
    for( i = 0; i < 32; ++i )
    {
      if( ( 1L << i ) >= amii_numcolors )
          break;
    }

    NewHackScreen.Depth = i;

    /* While openscreen fails try fewer colors to see if that is the problem. */
    while( ( HackScreen = OpenScreen( (void *)&NewHackScreen ) ) == NULL )
    {
#ifdef      TEXTCOLOR
      if( --NewHackScreen.Depth < 3 )
#else
      if( --NewHackScreen.Depth < 2 )
#endif
          Abort( AN_OpenScreen & ~AT_DeadEnd );
    }
    amii_numcolors = 1L << NewHackScreen.Depth;
    if( HackScreen->Height > 300 && forcenobig == 0 )
      bigscreen = 1;
    else
      bigscreen = 0;

#ifdef  INTUI_NEW_LOOK
    if( IntuitionBase->LibNode.lib_Version >= 37 )
      PubScreenStatus( HackScreen, 0 );
#endif

    amiIDisplay->ypix = HackScreen->Height;
    amiIDisplay->xpix = HackScreen->Width;

    LoadRGB4(&HackScreen->ViewPort, flags.amii_curmap, amii_numcolors );

    /* Display the copyright etc... */

    if( WIN_BASE == WIN_ERR )
      WIN_BASE = amii_create_nhwindow( NHW_BASE );
    amii_clear_nhwindow( WIN_BASE );
    amii_putstr( WIN_BASE, 0, "" );
    amii_putstr( WIN_BASE, 0, "" );
    amii_putstr( WIN_BASE, 0, "" );
    amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_A);
    amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_B);
    amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_C);
    amii_putstr( WIN_BASE, 0, "");

    Initialized = 1;
}

void
amii_sethipens( struct Window *w, int type, int attr )
{
    switch( type )
    {
      default:
          SetAPen( w->RPort, attr ? C_RED : amii_otherAPen );
          SetBPen( w->RPort, C_BLACK );
          break;
      case NHW_STATUS:
          SetAPen( w->RPort, attr ? C_WHITE : amii_statAPen );
          SetBPen( w->RPort, amii_statBPen );
          break;
      case NHW_MESSAGE:
          SetAPen( w->RPort, attr ? C_WHITE : amii_msgAPen );
          SetBPen( w->RPort, amii_msgBPen );
          break;
      case NHW_MENU:
          SetAPen( w->RPort, attr ? C_BLACK : amii_menuAPen );
          SetBPen( w->RPort, amii_menuBPen );
          break;
      case NHW_TEXT:
          SetAPen( w->RPort, attr ? C_BLACK : amii_textAPen );
          SetBPen( w->RPort, amii_textBPen );
      case -2:
          SetBPen( w->RPort, amii_otherBPen );
          SetAPen( w->RPort, attr ? C_RED : amii_otherAPen );
          break;
    }
}

void
amii_setfillpens( struct Window *w, int type )
{
    switch( type )
    {
    case NHW_MESSAGE:
      SetAPen( w->RPort, amii_msgBPen );
      SetBPen( w->RPort, amii_msgBPen );
      break;
    case NHW_STATUS:
      SetAPen( w->RPort, amii_statBPen );
      SetBPen( w->RPort, amii_statBPen );
      break;
    case NHW_MENU:
      SetAPen( w->RPort, amii_menuBPen );
      SetBPen( w->RPort, amii_menuBPen );
      break;
    case NHW_TEXT:
      SetAPen( w->RPort, amii_textBPen );
      SetBPen( w->RPort, amii_textBPen );
      break;
    case NHW_MAP:
    case NHW_BASE:
    case NHW_OVER:
    default:
      SetAPen( w->RPort, C_BLACK );
      SetBPen( w->RPort, C_BLACK );
      break;
    case -2:
      SetAPen( w->RPort, amii_otherBPen );
      SetBPen( w->RPort, amii_otherBPen );
      break;
    }
}

void
amii_setdrawpens( struct Window *w, int type )
{
    switch( type )
    {
    case NHW_MESSAGE:
      SetAPen( w->RPort, amii_msgAPen );
      SetBPen( w->RPort, amii_msgBPen );
      break;
    case NHW_STATUS:
      SetAPen( w->RPort, amii_statAPen );
      SetBPen( w->RPort, amii_statBPen );
      break;
    case NHW_MENU:
      SetAPen( w->RPort, amii_menuAPen );
      SetBPen( w->RPort, amii_menuBPen );
      break;
    case NHW_TEXT:
      SetAPen( w->RPort, amii_textAPen );
      SetBPen( w->RPort, amii_textBPen );
      break;
    case NHW_MAP:
    case NHW_BASE:
    case NHW_OVER:
      SetAPen( w->RPort, C_WHITE );
      SetBPen( w->RPort, C_BLACK );
      break;
    default:
      SetAPen( w->RPort, amii_otherAPen );
      SetBPen( w->RPort, amii_otherBPen );
      break;
    }
}

/* Clear the indicated window */

void
amii_clear_nhwindow(win)
    register winid win;
{
    register struct amii_WinDesc *cw;
    register struct Window *w;

    if( reclip == 2 ) return;

    if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
      panic( winpanicstr, win, "clear_nhwindow" );

    /* Clear the overview window too if it is displayed */
    if( WINVERS_AMIV && ( cw->type == WIN_MAP && WIN_OVER != WIN_ERR && reclip == 0 ) )
    {
      amii_clear_nhwindow( WIN_OVER );
    }

    if( w = cw->win )
      SetDrMd( w->RPort, JAM2);
    else
        return;

    if( (cw->wflags & FLMAP_CURSUP ) )
    {
      if( cw->type != NHW_MAP )
          cursor_off( win );
      else
          cw->wflags &= ~FLMAP_CURSUP;
    }

    amii_setfillpens( w, cw->type );
    SetDrMd( w->RPort, JAM2 );

    if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
    {
      RectFill( w->RPort, w->BorderLeft, w->BorderTop,
        w->Width - w->BorderRight-1,
        w->Height - w->BorderBottom-1 );
    }
    else
    {
      if( cw->type == NHW_MESSAGE )
      {
          amii_curs( win, 1, 0 );
          if( !scrollmsg )
            TextSpaces( w->RPort, cw->cols );
      }
      else
      {
          RectFill( w->RPort, w->BorderLeft, w->BorderTop,
            w->Width - w->BorderRight-1,
            w->Height - w->BorderBottom-1 );
      }
    }

    cw->cury = 0;
    cw->curx = 0;
    amii_curs( win, 1, 0 );
}

/* Dismiss the window from the screen */

void
dismiss_nhwindow(win)
    register winid win;
{
    register struct Window *w;
    register struct amii_WinDesc *cw;

    if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
    {
      panic(winpanicstr,win, "dismiss_nhwindow");
    }

    w = cw->win;

    if( w )
    {
      /* All windows have this stuff attached to them. */
      if(   cw->type == NHW_MAP ||
            cw->type == NHW_OVER ||
            cw->type == NHW_BASE ||
            cw->type == NHW_MESSAGE ||
            cw->type == NHW_STATUS )
      {
          ClearMenuStrip( w );
      }

      /* Save where user like inventory to appear */
      if( win == WIN_INVEN )
      {
          lastinvent.MinX = w->LeftEdge;
          lastinvent.MinY = w->TopEdge;
          lastinvent.MaxX = w->Width;
          lastinvent.MaxY = w->Height;
      }

      /* Close the window */
      CloseShWindow( w );
      cw->win = NULL;

      /* Free copy of NewWindow structure for TEXT/MENU windows. */
      if( cw->newwin )
          FreeNewWindow( (void *)cw->newwin );
      cw->newwin = NULL;
    }
}

void
amii_exit_nhwindows(str)
    const char *str;
{
    /* Seems strange to have to do this... but we need the BASE window
     * left behind...
     */
    kill_nhwindows( 0 );
    if( WINVERS_AMIV )
      FreeTileImageFiles( );

    if( str )
    {
      raw_print( "" );  /* be sure we're not under the top margin */
      raw_print( str );
    }
}

void
amii_display_nhwindow(win,blocking)
    winid win;
    boolean blocking;
{
    menu_item *mip;
    int cnt;
    static int lastwin = -1;
    struct amii_WinDesc *cw;

    if( !Initialized )
      return;
    lastwin = win;

    if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
      panic(winpanicstr,win,"display_nhwindow");

    if( cw->type == NHW_MESSAGE )
      cw->wflags &= ~FLMAP_SKIP;

    if( cw->type == NHW_MESSAGE || cw->type == NHW_STATUS )
      return;

    if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
    {
      flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
    }

    if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
    {
      cnt = DoMenuScroll( win, blocking, PICK_ONE, &mip );
    }
    else if( cw->type==NHW_MAP )
    {
      amii_end_glyphout( win );
      /* Do more if it is time... */
      if( blocking == TRUE && amii_wins[ WIN_MESSAGE ]->curx )
      {
          outmore( amii_wins[ WIN_MESSAGE ] );
      }
    }
}

void
amii_curs(window, x, y)
winid window;
register int x, y;  /* not xchar: perhaps xchar is unsigned and
             curx-x would be unsigned as well */
{
    register struct amii_WinDesc *cw;
    register struct Window *w;
    register struct RastPort *rp;

    if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
      panic(winpanicstr,  window, "curs");
    if( (w = cw->win) == NULL )
    {
      if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
          return;
      else
          panic( "No window open yet in curs() for winid %d\n", window );
    }
    amiIDisplay->lastwin = window;

    /* Make sure x is within bounds */
    if( x > 0 )
      --x;    /* column 0 is never used */
    else
      x = 0;

    cw->curx = x;
    cw->cury = y;

#ifdef DEBUG
    if( x<0 || y<0 || y >= cw->rows || x >= cw->cols )
    {
      char *s = "[unknown type]";
      switch(cw->type)
      {
          case NHW_MESSAGE: s = "[topl window]"; break;
          case NHW_STATUS: s = "[status window]"; break;
          case NHW_MAP: s = "[map window]"; break;
          case NHW_MENU: s = "[menu window]"; break;
          case NHW_TEXT: s = "[text window]"; break;
          case NHW_BASE: s = "[base window]"; break;
          case NHW_OVER: s = "[overview window]"; break;
      }
      impossible("bad curs positioning win %d %s (%d,%d)", window, s, x, y);
      return;
    }
#endif

#ifdef CLIPPING
    if(clipping && cw->type == NHW_MAP)
    {
      x -= clipx;
      y -= clipy;
    }
#endif

    /* Output all saved output before doing cursor movements for MAP */

    if( cw->type == NHW_MAP )
    {
      flush_glyph_buffer( w );
    }

    /* Actually do it */

    rp = w->RPort;
    if( cw->type == NHW_MENU )
    {
      if( WINVERS_AMIV )
      {
          if( window == WIN_INVEN )
          {
            Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1 + pictdata.xsize + 4,
                (y * max(rp->TxHeight,pictdata.ysize + 3) ) +
                 rp->TxBaseline + pictdata.ysize - rp->TxHeight + w->BorderTop + 4 );
          }
          else
          {
            Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
                (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1 );
          }
      }
      else
      {
          Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
            (y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
      }
    }
    else if( cw->type == NHW_TEXT )
    {
      Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
          (y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
    }
    else if( cw->type == NHW_MAP || cw->type == NHW_BASE )
    {
      /* These coordinate calculations must be synced with those
       * in flush_glyph_buffer() in winchar.c.  curs_on_u() will
       * use this code, all other drawing occurs through the glyph
       * code.  In order for the cursor to appear on top of the hero,
       * the code must compute X,Y in the same manner relative to
       * the RastPort coordinates.
       *
       * y = w->BorderTop + (g_nodes[i].y-1) * rp->TxHeight +
       *   rp->TxBaseline + 1;
       * x = g_nodes[i].x * rp->TxWidth + w->BorderLeft;
       */

      if( WINVERS_AMIV )
      {
          if( cw->type == NHW_MAP )
          {
            if(Is_rogue_level(&u.uz)){
#if 0
int qqx= (x * w->RPort->TxWidth) + w->BorderLeft;
int qqy= w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1;
printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy);
#endif
            SetAPen(w->RPort,C_WHITE); /* XXX should be elsewhere (was 4)*/
            Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
                  w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1 );
            } else {
            Move( rp, (x * mxsize) + w->BorderLeft,
                        w->BorderTop + ( (y+1) * mysize ) + 1 );
            }
          }
          else
          {
            Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
                      w->BorderTop + ( (y + 1) * w->RPort->TxHeight ) +
                      w->RPort->TxBaseline + 1 );
          }
      }
      else
      {
          Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
                  w->BorderTop + ( (y + 1) * w->RPort->TxHeight ) +
                  w->RPort->TxBaseline + 1 );
      }
    }
    else if( WINVERS_AMIV && cw->type == NHW_OVER )
    {
      Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
                  w->BorderTop + w->RPort->TxBaseline + 3 );
    }
    else if( cw->type == NHW_MESSAGE && !scrollmsg )
    {
      Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
                  w->BorderTop + w->RPort->TxBaseline + 3 );
    }
    else if( cw->type == NHW_STATUS )
    {
      Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
                  (y*(w->RPort->TxHeight+1)) + w->BorderTop +
                  w->RPort->TxBaseline + 1 );
    }
    else
    {
      Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
                  (y*w->RPort->TxHeight) + w->BorderTop +
                  w->RPort->TxBaseline + 1 );
    }
}

void
amii_set_text_font( name, size )
    char *name;
    int size;
{
    register int i;
    register struct amii_WinDesc *cw;
    int osize = TextsFont13.ta_YSize;
    static char nname[ 100 ];

    strncpy( nname, name, sizeof( nname ) - 1 );
    nname[ sizeof( nname ) - 1 ] = 0;

    TextsFont13.ta_Name = nname;
    TextsFont13.ta_YSize = size;

    /* No alternate text font allowed for 640x269 or smaller */
    if( !HackScreen || !bigscreen )
      return;

    /* Look for windows to set, and change them */

    if( DiskfontBase =
            OpenLibrary( "diskfont.library", amii_libvers  ) )
    {
      TextsFont = OpenDiskFont( &TextsFont13 );
      for( i = 0; TextsFont && i < MAXWIN; ++i )
      {
          if( (cw = amii_wins[ i ]) && cw->win != NULL )
          {
            switch( cw->type )
            {
            case NHW_STATUS:
                MoveWindow( cw->win, 0, -( size - osize ) * 2 );
                SizeWindow( cw->win, 0, ( size - osize ) * 2 );
                SetFont( cw->win->RPort, TextsFont );
                break;
            case NHW_MESSAGE:
            case NHW_MAP:
            case NHW_BASE:
            case NHW_OVER:
                SetFont( cw->win->RPort, TextsFont );
                break;
            }
          }
      }
    }
    CloseLibrary(DiskfontBase);
    DiskfontBase = NULL;
}

void
kill_nhwindows( all )
    register int all;
{
    register int i;
    register struct amii_WinDesc *cw;

    /* Foreach open window in all of amii_wins[], CloseShWindow, free memory */

    for( i = 0; i < MAXWIN; ++i )
    {
      if( (cw = amii_wins[ i ]) && (cw->type != NHW_BASE || all) )
      {
          amii_destroy_nhwindow( i );
      }
    }
}

void
amii_cl_end( cw, curs_pos )
    register struct amii_WinDesc *cw;
    register int curs_pos;
{
    register struct Window *w = cw->win;
    register int oy, ox;

    if( !w )
      panic("NULL window pointer in amii_cl_end()");

    oy = w->RPort->cp_y;
    ox = w->RPort->cp_x;

    TextSpaces( w->RPort, cw->cols - curs_pos );

    Move( w->RPort, ox, oy );
}

void
cursor_off( window )
    winid window;
{
    register struct amii_WinDesc *cw;
    register struct Window *w;
    register struct RastPort *rp;
    int curx, cury;
    int x, y;
    long dmode;
    short apen, bpen;
    unsigned char ch;

    if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
    {
      iflags.window_inited=0;
      panic(winpanicstr,window, "cursor_off");
    }

    if( !(cw->wflags & FLMAP_CURSUP ) )
      return;

    w = cw->win;

    if( !w )
      return;

    cw->wflags &= ~FLMAP_CURSUP;
    rp = w->RPort;

    /* Save the current information */
    curx = rp->cp_x;
    cury = rp->cp_y;
    x = cw->cursx;
    y = cw->cursy;
    dmode = rp->DrawMode;
    apen = rp->FgPen;
    bpen = rp->BgPen;
    SetAPen( rp, cw->curs_apen );
    SetBPen( rp, cw->curs_bpen );
    SetDrMd( rp, COMPLEMENT );
/*printf("CURSOR OFF: %d %d\n",x,y);*/

    if( WINVERS_AMIV && cw->type == NHW_MAP)
    {
      cursor_common(rp, x, y);
      if(Is_rogue_level(&u.uz))
          Move(rp,curx,cury);
    }
    else
    {
      ch = CURSOR_CHAR;
      Move( rp, x, y );
      Text( rp, &ch, 1 );

      /* Put back the other stuff */

      Move( rp, curx, cury );
    }
    SetDrMd( rp, dmode );
    SetAPen( rp, apen );
    SetBPen( rp, bpen );
}

void
cursor_on( window )
    winid window;
{
    int x, y;
    register struct amii_WinDesc *cw;
    register struct Window *w;
    register struct RastPort *rp;
    unsigned char ch;
    long dmode;
    short apen, bpen;

    if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
    {
      /* tty does this differently - is this OK? */
      iflags.window_inited=0;
      panic(winpanicstr,window, "cursor_on");
    }

/*printf("CURSOR ON: %d %d\n",cw->win->RPort->cp_x, cw->win->RPort->cp_y);*/
    if( (cw->wflags & FLMAP_CURSUP ) )
      cursor_off( window );

    w = cw->win;

    if( !w )
      return;

    cw->wflags |= FLMAP_CURSUP;
    rp = w->RPort;

    /* Save the current information */

#ifdef      DISPMAP
    if( WINVERS_AMIV && cw->type == NHW_MAP && !Is_rogue_level(&u.uz))
      x = cw->cursx = (rp->cp_x & -8) + 8;
    else
#endif
      x = cw->cursx = rp->cp_x;
    y = cw->cursy = rp->cp_y;
    apen = rp->FgPen;
    bpen = rp->BgPen;
    dmode = rp->DrawMode;

    /* Draw in complement mode. The cursor body will be C_WHITE */

    cw->curs_apen = C_RED;
    cw->curs_bpen = C_RED;
    SetAPen( rp, cw->curs_apen );
    SetBPen( rp, cw->curs_bpen );
    SetDrMd( rp, COMPLEMENT );
    if( WINVERS_AMIV && cw->type == NHW_MAP)
    {
      cursor_common(rp, x, y);
    }
    else
    {
      Move( rp, x, y );
      ch = CURSOR_CHAR;
      Text( rp, &ch, 1 );
      Move( rp, x, y );
    }

    SetDrMd( rp, dmode );
    SetAPen( rp, apen );
    SetBPen( rp, bpen );
}

static void
cursor_common(rp, x, y)
      struct RastPort *rp;
      int x,y;
{
    int x1,x2,y1,y2;

    if(Is_rogue_level(&u.uz)){
      x1 = x-2;         y1 = y-rp->TxHeight;
      x2 = x+rp->TxWidth+1;   y2 = y+3;
/*printf("COMM: (%d %d) (%d %d)  (%d %d) (%d %d)\n",x1,y1,x2,y2,x1+2,y1+2,x2-2,y2-2);*/
    } else {
      x1 = x;                 y1 = y-mysize-1;
      x2 = x+mxsize-1;  y2 = y-2;
      RectFill(rp, x1, y1, x2, y2);
    }

    RectFill(rp, x1+2, y1+2, x2-2, y2-2);
}

void amii_suspend_nhwindows( str )
    const char *str;
{
    if( HackScreen )
      ScreenToBack( HackScreen );
}

void amii_resume_nhwindows()
{
    if( HackScreen )
      ScreenToFront( HackScreen );
}

void amii_bell()
{
    DisplayBeep( NULL );
}

void
removetopl(cnt)
      int cnt;
{
    struct amii_WinDesc *cw=amii_wins[WIN_MESSAGE];
                              /* NB - this is sufficient for
                               * yn_function, but that's it
                               */
    if(cw->curx < cnt)cw->curx=0;
    else cw->curx -= cnt;

    amii_curs(WIN_MESSAGE, cw->curx+1, cw->cury);
    amii_cl_end(cw, cw->curx);
}
/*#endif /* AMIGA_INTUITION */

#ifdef  PORT_HELP
void
port_help()
{
    display_file( PORT_HELP, 1 );
}
#endif

/*
 *  print_glyph
 *
 *  Print the glyph to the output device.  Don't flush the output device.
 *
 *  Since this is only called from show_glyph(), it is assumed that the
 *  position and glyph are always correct (checked there)!
 */

void
amii_print_glyph(win,x,y,glyph)
    winid win;
    xchar x,y;
    int glyph;
{
    struct amii_WinDesc *cw;
    uchar   ch;
    register int offset;
#ifdef TEXTCOLOR
    int     color;
#endif
    extern int zapcolors[];

    /* In order for the overview window to work, we can not clip here */
    if( !WINVERS_AMIV )
    {
#ifdef      CLIPPING
      /* If point not in visible part of window just skip it */
      if( clipping )
      {
          if( x <= clipx || y < clipy || x >= clipxmax || y >= clipymax )
            return;
      }
#endif
    }

    if( win == WIN_ERR || (cw=amii_wins[win]) == NULL || cw->type != NHW_MAP)
    {
      panic(winpanicstr,win,"amii_print_glyph");
    }

#if 0
{
static int x=-1;
if(u.uz.dlevel != x){
 fprintf(stderr,"lvlchg: %d (%d)\n",u.uz.dlevel,Is_rogue_level(&u.uz));
 x = u.uz.dlevel;
}
}
#endif
    if(
      WINVERS_AMIV
#ifdef REINCARNATION
      && !Is_rogue_level(&u.uz)
#endif
    )
    {
      amii_curs(win,x,y);
      amiga_print_glyph(win,0,glyph);
    }
    else          /* AMII, or Rogue level in either version */
    {
#ifdef TEXTCOLOR
#define zap_color(n)  color = iflags.use_color ? zapcolors[n] : NO_COLOR
#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR
#define obj_color(n)  color = iflags.use_color ? objects[n].oc_color : NO_COLOR
#define mon_color(n)  color = iflags.use_color ? mons[n].mcolor : NO_COLOR
#define pet_color(n)  color = iflags.use_color ? mons[n].mcolor :          \
            /* If no color, try to hilite pets; black  */ \
            /* should be HI                */ \
                ((iflags.hilite_pet) ? CLR_BLACK : NO_COLOR)

# else /* no text color */

#define zap_color(n)
#define cmap_color(n)
#define obj_color(n)
#define mon_color(n)
#define pet_color(n)

#endif

      /*
       *  Map the glyph back to a character.
       *
       *  Warning:  For speed, this makes an assumption on the order of
       *        offsets.  The order is set in display.h.
       */
      if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {  /* swallow */
          /* see swallow_to_glyph()in display.c */
          ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
          mon_color(offset >> 3);
      } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {       /* zap beam */
          ch = showsyms[S_vbeam + (offset & 0x3)];
          zap_color((offset >> 2));
      } else if( ( offset = (glyph - GLYPH_CMAP_OFF) ) >= 0 ) {   /* cmap */
          ch = showsyms[offset];
          cmap_color(offset);
      } else if( ( offset = (glyph - GLYPH_OBJ_OFF) ) >= 0 ) {    /* object */
          ch = oc_syms[objects[offset].oc_class];
          obj_color(offset);
      } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {  /* a corpse */
          ch = oc_syms[objects[CORPSE].oc_class];
          mon_color(offset);
      } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {   /* a pet */
          ch = (uchar) monsyms[mons[offset].mlet];
          pet_color(offset);
      } else /*if( glyph_is_monster(glyph) )*/ {      /* a monster */
          ch = (uchar) monsyms[mons[glyph].mlet];
          mon_color(glyph);
      }
                        /* XXX next if should be ifdef REINCARNATION */
      if( WINVERS_AMIV ){                 /* implies Rogue level here */
          amii_curs(win,x,y);
          amiga_print_glyph(win,NO_COLOR,ch + 10000);
      } else {
            /* Move the cursor. */
          amii_curs(win,x,y+2);

#ifdef TEXTCOLOR
            /* Turn off color if rogue level. */
# ifdef REINCARNATION
          if (Is_rogue_level(&u.uz))
            color = NO_COLOR;
#  endif

          amiga_print_glyph(win,color,ch);
#else
          g_putch(ch);    /* print the character */
#endif
          cw->curx++;     /* one character over */
      }
    }
}

/* Make sure the user sees a text string when no windowing is available */

void
amii_raw_print(s)
    register const char *s;
{
    int argc = 0;

    if( !s )
      return;
    if(amiIDisplay)
      amiIDisplay->rawprint++;

    if( Initialized == 0 && WIN_BASE == WIN_ERR )
          init_nhwindows(&argc, (char **)0);

    if( amii_rawprwin != WIN_ERR )
      amii_putstr( amii_rawprwin, 0, s );
    else if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
      amii_putstr( WIN_MAP, 0, s );
    else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
      amii_putstr( WIN_BASE, 0, s );
    else
    {
      puts( s);
      fflush(stdout);
    }
}

/* Make sure the user sees a bold text string when no windowing
 * is available
 */

void
amii_raw_print_bold(s)
    register const char *s;
{
    int argc = 0;

    if( !s )
      return;

    if(amiIDisplay)
      amiIDisplay->rawprint++;

    if( Initialized == 0 && WIN_BASE == WIN_ERR )
          init_nhwindows(&argc, (char **)0);

    if( amii_rawprwin != WIN_ERR )
      amii_putstr( amii_rawprwin, 1, s );
    else if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
      amii_putstr( WIN_MAP, 1, s );
    else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
      amii_putstr( WIN_BASE, 1, s );
    else
    {
      printf("\33[1m%s\33[0m\n",s);
      fflush(stdout);
    }
}

/* Rebuild/update the inventory if the window is up.
 */
void
amii_update_inventory()
{
    register struct amii_WinDesc *cw;

    if( WIN_INVEN != WIN_ERR && ( cw = amii_wins[ WIN_INVEN ] ) &&
                        cw->type == NHW_MENU && cw->win )
    {
      display_inventory( NULL, FALSE );
    }
}

/* Humm, doesn't really do anything useful */

void
amii_mark_synch()
{
    if(!amiIDisplay)
      fflush(stderr);
/* anything else?  do we need this much? */
}

/* Wait for everything to sync.  Nothing is asynchronous, so we just
 * ask for a key to be pressed.
 */
void
amii_wait_synch()
{
    if(!amiIDisplay || amiIDisplay->rawprint)
    {
      if(amiIDisplay) amiIDisplay->rawprint=0;
    }
    else
    {
      if( WIN_MAP != WIN_ERR )
      {
          display_nhwindow(WIN_MAP,TRUE);
          flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
      }
    }
}

void
amii_setclipped()
{
#ifdef      CLIPPING
    clipping = TRUE;
    clipx=clipy=0;
    clipxmax=CO;
    clipymax=LI;
/* some of this is now redundant with top of amii_cliparound XXX */
#endif
}

/* XXX still to do: suppress scrolling if we violate the boundary but the
 * edge of the map is already displayed
 */
void
amii_cliparound(x,y)
    register int x,y;
{
    extern boolean restoring;
#ifdef      CLIPPING
    int oldx = clipx, oldy = clipy;
    int oldxmax = clipxmax, oldymax = clipymax;
    int COx, LIx;
#define     SCROLLCNT   3     /* Get there in 3 moves... */
    int scrollcnt = SCROLLCNT;      /* ...or 1 if we changed level */
    if (!clipping)
      return;

    if(Is_rogue_level(&u.uz)){
      struct Window *w = amii_wins[WIN_MAP]->win;
      struct RastPort *rp = w->RPort;

      COx = (w->Width-w->BorderLeft-w->BorderRight)/rp->TxWidth;
      LIx = (w->Height-w->BorderTop-w->BorderBottom)/rp->TxHeight;
    }else{
      COx = CO;
      LIx = LI;
    }
            /*
             * On a level change, move the clipping region so that for a
             * reasonablely large window extra motion is avoided; for
             * the rogue level hopefully this means no motion at all.
             */
    {
      static d_level saved_level = {127,127};         /* XXX */

      if(!on_level(&u.uz, &saved_level)){
          scrollcnt = 1;      /* jump with blanking */
          clipx=clipy=0;
          clipxmax = COx; clipymax = LIx;
          saved_level = u.uz;       /* save as new current level */
      }
    }

    if (x <= clipx + xclipbord ) {
      clipx = max(0, x - (clipxmax - clipx)/2 );
      clipxmax = clipx + COx;
    }
    else if (x > clipxmax - xclipbord ) {
      clipxmax = min(COLNO, clipxmax + (clipxmax - clipx)/2 );
      clipx = clipxmax - COx;
    }

    if (y <= clipy + yclipbord ) {
      clipy = max(0, y - (clipymax - clipy) / 2);
      clipymax = clipy + LIx;
    }
    else if (y > clipymax - yclipbord ) {
      clipymax = min(ROWNO, clipymax + (clipymax - clipy) / 2);
      clipy = clipymax - LIx;
    }

    reclip = 1;
    if (clipx != oldx || clipy != oldy || clipxmax != oldxmax || clipymax != oldymax )
    {
#ifndef NOSCROLLRASTER
      struct Window *w = amii_wins[ WIN_MAP ]->win;
      struct RastPort *rp = w->RPort;
      int xdelta, ydelta, xmod, ymod, i;
      int incx, incy, mincx, mincy;
      int savex, savey, savexmax, saveymax;
      int scrx, scry;

      if(Is_rogue_level(&u.uz)){
          scrx = rp->TxWidth;
          scry = rp->TxHeight;
      } else {
          scrx = mxsize;
          scry = mysize;
      }

      /* Ask that the glyph routines not draw the overview window */
      reclip = 2;
      cursor_off( WIN_MAP );

      /* Compute how far we are moving in terms of tiles */
      mincx = clipx - oldx ;
      mincy = clipy - oldy ;

      /* How many tiles to get there in SCROLLCNT moves */
      incx = ( clipx - oldx )/scrollcnt;
      incy = ( clipy - oldy )/scrollcnt;

      /* If less than SCROLLCNT tiles, then move by 1 tile if moving at all */
      if( incx == 0 ) incx = (mincx != 0);
      if( incy == 0 ) incy = (mincy != 0);

      /* Get count of pixels to move each iteration and final pixel count */
      xdelta = ((clipx-oldx )*scrx) / scrollcnt;
      xmod = ((clipx-oldx )*scrx) % scrollcnt;
      ydelta = ((clipy-oldy )*scry) / scrollcnt;
      ymod = ((clipy-oldy )*scry) % scrollcnt;

      /* Preserve the final move location */
      savex = clipx;
      savey = clipy;
      saveymax = clipymax;
      savexmax = clipxmax;

      /*
       * Set clipping rectangle to be just the region that will be exposed so
       * that drawing will be faster
       */
      if( xdelta < 0 )
      {
          clipx = oldx;
          clipxmax = clipx + incx;
      }
      else if( xdelta > 0 )
      {
          clipxmax = oldxmax;
          clipx = clipxmax - incx;
      }
      else
      {
          clipx = oldx;
          clipxmax = oldxmax;
      }

      if( ydelta < 0 )
      {
          clipy = oldy;
          clipymax = clipy + incy;
      }
      else if( ydelta > 0 )
      {
          clipymax = oldymax;
          clipy = clipymax - incy;
      }
      else
      {
          clipy = oldy;
          clipymax = oldymax;
      }

      /* Now, in scrollcnt moves, move the picture toward the final view */
      for( i = 0; i < scrollcnt; ++i )
      {
#ifdef      DISPMAP
          if( i == scrollcnt - 1 && (xmod != 0 || ymod != 0) &&
                  (xdelta != 0 || ydelta != 0) )
          {
            incx += (clipx - oldx)%scrollcnt;
            incy += (clipy - oldy)%scrollcnt;
            xdelta += xmod;
            ydelta += ymod;
          }
#endif
          /* Scroll the raster if we are scrolling */
          if( xdelta != 0 || ydelta != 0 )
          {
            ScrollRaster( rp, xdelta, ydelta,
                      w->BorderLeft, w->BorderTop,
                      w->Width - w->BorderRight - 1,
                      w->Height - w->BorderBottom - 1 );

            if( mincx == 0 ) incx = 0;
            else mincx -= incx;

            clipx += incx;
            clipxmax += incx;

            if( mincy == 0 ) incy = 0;
            else mincy -= incy;

            clipy += incy;
            clipymax += incy;

            /* Draw the exposed portion */
            if (on_level(&u.uz0, &u.uz) && !restoring)
                (void) doredraw();
            flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
          }
      }

      clipx = savex;
      clipy = savey;
      clipymax = saveymax;
      clipxmax = savexmax;
#endif
      if (on_level(&u.uz0, &u.uz) && !restoring && moves > 1)
          (void) doredraw();
      flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
    }
    reclip = 0;
#endif
}

void
flushIDCMP( port )
      struct MsgPort *port;
{
      struct Message *msg;
      while( msg = GetMsg( port ) )
            ReplyMsg( msg );
}

Generated by  Doxygen 1.6.0   Back to index