home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 3_1_3 / sys / amiga / winstr.c < prev   
Encoding:
C/C++ Source or Header  |  1993-07-08  |  10.1 KB  |  462 lines

  1. /*    SCCS Id: @(#)winstr.c    3.1    93/04/02 */
  2. /* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "amiga:windefs.h"
  6. #include "amiga:winext.h"
  7. #include "amiga:winproto.h"
  8.  
  9. /* Put a string into the indicated window using the indicated attribute */
  10.  
  11. void
  12. amii_putstr(window,attr,str)
  13.     winid window;
  14.     int attr;
  15.     const char *str;
  16. {
  17.     struct Window *w;
  18.     register struct amii_WinDesc *cw;
  19.     char *ob;
  20.     int i, j, n0, bottom, totalvis, wheight;
  21.  
  22. #ifdef    VIEWWINDOW
  23.     /* Never write text in MAP it would be too small to read */
  24.     if( window == WIN_MAP )
  25.     window = WIN_MESSAGE;
  26. #endif
  27.     /* Always try to avoid a panic when there is no window */
  28.     if( window == WIN_ERR )
  29.     {
  30.     window = WIN_BASE;
  31.     if( window == WIN_ERR )
  32.         window = WIN_BASE = amii_create_nhwindow( NHW_BASE );
  33.     }
  34.  
  35.     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  36.     {
  37.     flags.window_inited=0;
  38.     panic(winpanicstr,window, "putstr");
  39.     }
  40.  
  41.     w = cw->win;
  42.  
  43.     if(!str) return;
  44.     amiIDisplay->lastwin = window;    /* do we care??? */
  45.  
  46.     /* NHW_MENU windows are not opened immediately, so check if we
  47.      * have the window pointer yet
  48.      */
  49.  
  50.     if( w )
  51.     {
  52.     /* Force the drawing mode and pen colors */
  53.  
  54.     SetDrMd( w->RPort, JAM2 );
  55.     if( cw->type == NHW_STATUS )
  56.         SetAPen( w->RPort, attr ? C_WHITE : C_RED );
  57.     else if( cw->type == NHW_MESSAGE )
  58.         SetAPen( w->RPort, attr ? C_RED : C_WHITE );
  59.     else
  60.         SetAPen( w->RPort, attr ? C_RED : C_WHITE );
  61.     SetBPen( w->RPort, C_BLACK );
  62.     }
  63.     else if( cw->type != NHW_MENU && cw->type != NHW_TEXT )
  64.     {
  65.     panic( "NULL window pointer in putstr 2: %d", window );
  66.     }
  67.  
  68.     /* Okay now do the work for each type */
  69.  
  70.     switch(cw->type)
  71.     {
  72. #define MORE_FUDGE  10  /* 8 for --more--, 1 for preceeding sp, 1 for */
  73.         /* putstr pad */
  74.     case NHW_MESSAGE:
  75.         /* Calculate the bottom line */
  76.         bottom = amii_msgborder( w );
  77.  
  78.     wheight = ( w->Height - w->BorderTop -
  79.                 w->BorderBottom - 3 ) / w->RPort->TxHeight;
  80.     
  81.     if( attr != -1 && scrollmsg )
  82.     {
  83.         if( ++cw->disprows > wheight )
  84.         {
  85.         outmore( cw );
  86.         cw->disprows = 1; /* count this line... */
  87.         }
  88.         else
  89.         {
  90.         ScrollRaster( w->RPort, 0, w->RPort->TxHeight,
  91.             w->BorderLeft-1, w->BorderTop+1,
  92.             w->Width - w->BorderRight-1,
  93.             w->Height - w->BorderBottom - 1 );
  94.         }
  95.         amii_curs( WIN_MESSAGE, 1, bottom );
  96.     }
  97.  
  98.     strncpy( toplines, str, BUFSZ );
  99.     toplines[ BUFSZ - 1 ] = 0;
  100.  
  101.     /* For initial message to be visible, we need to explicitly position the
  102.      * cursor.  This flag, cw->curx == -1 is used elsewhere to force the
  103.      * cursor to be repositioned to the "bottom".
  104.      */
  105.     if( cw->curx == -1 )
  106.     {
  107.         amii_curs( WIN_MESSAGE, 1, bottom );
  108.         cw->curx = 0;
  109.     }
  110.  
  111.     /* If used all of history lines, move them down */
  112.  
  113.     if( cw->maxrow >= flags.msg_history )
  114.     {
  115.         if( cw->data[ 0 ] )
  116.         free( cw->data[ 0 ] );
  117.         memcpy( cw->data, &cw->data[ 1 ],
  118.         ( flags.msg_history - 1 ) * sizeof( char * ) );
  119.         cw->data[ flags.msg_history - 1 ] =
  120.                 (char *) alloc( strlen( toplines ) + 5 );
  121.         strcpy( cw->data[ i = flags.msg_history - 1 ] +
  122.                 SOFF + (scrollmsg!=0), toplines );
  123.     }
  124.     else
  125.     {
  126.         /* Otherwise, allocate a new one and copy the line in */
  127.         cw->data[ cw->maxrow ] = (char *)
  128.                     alloc( strlen( toplines ) + 5 );
  129.         strcpy( cw->data[ i = cw->maxrow++ ] +
  130.                 SOFF + (scrollmsg!=0), toplines );
  131.     }
  132.     cw->data[ i ][0] = 1;
  133.     cw->data[ i ][1] = attr;
  134.  
  135.     if( scrollmsg )
  136.         cw->data[ i ][2] = (cw->wflags & FLMSG_FIRST ) ? '>' : ' ';
  137.  
  138.     str = cw->data[i] + SOFF;
  139.     if( strlen(str) >= (cw->cols-MORE_FUDGE) )
  140.     {
  141.         int i;
  142.         char *p;
  143.  
  144.         while( strlen( str ) >= (cw->cols-MORE_FUDGE) )
  145.         {
  146.         for(p=(&str[ cw->cols ])-MORE_FUDGE; !isspace(*p) && p != str;)
  147.         {
  148.             --p;
  149.         }
  150.         if( p == str )
  151.             p = &str[ cw->cols ];
  152.         outsubstr( cw, str, i = (long)p-(long)str );
  153.         cw->curx += i;
  154.         amii_cl_end( cw, cw->curx );
  155.         str = p+1;
  156.         }
  157.  
  158.         if( *str )
  159.         {
  160.         outsubstr( cw, str, i = strlen( str ) );
  161.         cw->curx += i;
  162.         amii_cl_end( cw, cw->curx );
  163.         }
  164.     }
  165.     else
  166.     {
  167.         outsubstr( cw, str, i = strlen( str ) );
  168.         cw->curx += i;
  169.         amii_cl_end( cw, cw->curx );
  170.     }
  171.     cw->wflags &= ~FLMSG_FIRST;
  172.     for( totalvis = i = 0; i < cw->maxrow; ++i )
  173.     {
  174.         if( cw->data[i][1] == 0 )
  175.         ++totalvis;
  176.     }
  177.     if( scrollmsg )
  178.     {
  179.         SetPropInfo( w, &MsgScroll,
  180.           ( w->Height-w->BorderTop-w->BorderBottom ) / w->RPort->TxHeight,
  181.           totalvis, totalvis );
  182.     }
  183.     i = strlen( toplines + SOFF );
  184.     cw->maxcol = max( cw->maxcol, i );
  185.     cw->vwy = cw->maxrow;
  186.     break;
  187.  
  188.     case NHW_STATUS:
  189.     if( cw->data[ cw->cury ] == NULL )
  190.         panic( "NULL pointer for status window" );
  191.     ob = &cw->data[cw->cury][j = cw->curx];
  192.     if(flags.botlx) *ob = 0;
  193.  
  194.         /* Display when beam at top to avoid flicker... */
  195.     WaitTOF();
  196.     Text(w->RPort,str,strlen(str));
  197.     if( cw->cols > strlen( str ) )
  198.         TextSpaces( w->RPort, cw->cols - strlen( str ) );
  199.  
  200.     (void) strncpy(cw->data[cw->cury], str, cw->cols );
  201.     cw->data[cw->cury][cw->cols-1] = '\0'; /* null terminate */
  202.     cw->cury = (cw->cury+1) % 2;
  203.     cw->curx = 0;
  204.     break;
  205.  
  206.     case NHW_VIEWBOX:
  207.     case NHW_VIEW:
  208.     case NHW_MAP:
  209.     case NHW_BASE:
  210.     amii_curs(window, cw->curx+1, cw->cury);
  211.     Text(w->RPort,str,strlen(str));
  212.     cw->curx = 0;
  213.         /* CR-LF is automatic in these windows */
  214.     cw->cury++;
  215.     break;
  216.  
  217.     case NHW_MENU:
  218.     case NHW_TEXT:
  219.  
  220.     /* always grows one at a time, but alloc 12 at a time */
  221.  
  222.     if( cw->cury >= cw->rows || !cw->data ) {
  223.         char **tmp;
  224.  
  225.         /* Allocate 12 more rows */
  226.         cw->rows += 12;
  227.         tmp = (char**) alloc(sizeof(char*) * cw->rows);
  228.  
  229.         /* Copy the old lines */
  230.         for(i=0; i<cw->cury; i++)
  231.         tmp[i] = cw->data[i];
  232.  
  233.         if( cw->data )
  234.         free( cw->data );
  235.  
  236.         cw->data = tmp;
  237.  
  238.         /* Null out the unused entries. */
  239.         for(i=cw->cury; i<cw->rows; i++)
  240.         cw->data[i] = 0;
  241.     }
  242.  
  243.     if( !cw->data )
  244.         panic("no data storage");
  245.  
  246.         /* Shouldn't need to do this, but... */
  247.  
  248.     if( cw->data && cw->data[cw->cury] )
  249.         free( cw->data[cw->cury] );
  250.  
  251.     n0 = strlen(str)+1;
  252.     cw->data[cw->cury] = (char*) alloc(n0+SOFF);
  253.  
  254.         /* avoid nuls, for convenience */
  255.     cw->data[cw->cury][VATTR] = attr+1;
  256.     cw->data[cw->cury][SEL_ITEM] = 0;
  257.     Strcpy( cw->data[cw->cury] + SOFF, str);
  258.  
  259.     if(n0 > cw->maxcol) cw->maxcol = n0;
  260.     if(++cw->cury > cw->maxrow) cw->maxrow = cw->cury;
  261.     break;
  262.  
  263.     default:
  264.     panic("Invalid or unset window type in putstr()");
  265.     }
  266. }
  267.  
  268. int
  269. amii_msgborder( w )
  270.     struct Window *w;
  271. {
  272.     register int bottom;
  273.  
  274.     /* There is a one pixel border at the borders, so subtract two */
  275.     bottom = w->Height - w->BorderTop - w->BorderBottom - 2;
  276.     bottom /= w->RPort->TxHeight;
  277.     if( bottom > 0 )
  278.     --bottom;
  279.     return( bottom );
  280. }
  281.  
  282. void
  283. outmore( cw )
  284.     register struct amii_WinDesc *cw;
  285. {
  286.     struct Window *w = cw->win;
  287.  
  288.     if((cw->wflags & FLMAP_SKIP) == 0)
  289.     {
  290.     if( scrollmsg )
  291.     {
  292.         int bottom;
  293.  
  294.         bottom = amii_msgborder( w );
  295.  
  296.         ScrollRaster( w->RPort, 0, w->RPort->TxHeight,
  297.             w->BorderLeft-1, w->BorderTop+1,
  298.             w->Width - w->BorderRight-1,
  299.             w->Height - w->BorderBottom - 1 );
  300.         amii_curs( WIN_MESSAGE, 1, bottom );
  301.         Text( w->RPort, "--more--", 8 );
  302.     }
  303.     else
  304.         Text( w->RPort, " --more--", 9 );
  305.  
  306.     /* Make sure there are no events in the queue */
  307.     flushIDCMP( HackPort );
  308.  
  309.     /* Allow mouse clicks to clear --more-- */
  310.     WindowGetchar();
  311.     if( lastevent.type == WEKEY && lastevent.un.key == '\33' )
  312.         cw->wflags |= FLMAP_SKIP;
  313.     }
  314.     if( !scrollmsg )
  315.     {
  316.     amii_curs( WIN_MESSAGE, 1, 0 );
  317.     amii_cl_end( cw, cw->curx );
  318.     }
  319. }
  320.  
  321. void
  322. outsubstr( cw, str, len )
  323.     register struct amii_WinDesc *cw;
  324.     char *str;
  325.     int len;
  326. {
  327.     struct Window *w = cw->win;
  328.  
  329.     if( cw->curx )
  330.     {
  331.     /* Check if this string and --more-- fit, if not,
  332.      * then put out --more-- and wait for a key.
  333.      */
  334.     if( (len + MORE_FUDGE ) + cw->curx >= cw->cols )
  335.     {
  336.         if( !scrollmsg )
  337.         outmore( cw );
  338.     }
  339.     else if(topl_addspace)
  340.     {
  341.         /* Otherwise, move and put out a blank separator */
  342.         Text( w->RPort, spaces, 1 );
  343.         cw->curx += 1;
  344.     }
  345.     }
  346.  
  347.     Text(w->RPort,str,len);
  348. }
  349.  
  350. /* Put a graphics character onto the screen */
  351.  
  352. void
  353. amii_putsym( st, i, y, c )
  354.     winid st;
  355.     int i, y;
  356.     CHAR_P c;
  357. {
  358.     char buf[ 2 ];
  359.     amii_curs( st, i, y );
  360.     buf[ 0 ] = c;
  361.     buf[ 1 ] = 0;
  362.     amii_putstr( st, 0, buf );
  363. }
  364.  
  365. /* Add a line in the message window */
  366.  
  367. void
  368. amii_addtopl(s)
  369.     const char *s;
  370. {
  371.     amii_putstr(WIN_MESSAGE,0,s);   /* is this right? */
  372. }
  373.  
  374. void
  375. TextSpaces( rp, nr )
  376.     struct RastPort *rp;
  377.     int nr;
  378. {
  379.     if( nr < 1 )
  380.     return;
  381.  
  382.     while (nr > sizeof(spaces) - 1)
  383.     {
  384.     Text(rp, spaces, (long)sizeof(spaces) - 1);
  385.     nr -= sizeof(spaces) - 1;
  386.     }
  387.     if (nr > 0)
  388.     Text(rp, spaces, (long)nr);
  389. }
  390.  
  391. void
  392. amii_remember_topl()
  393. {
  394.     /* ignore for now.  I think this will be done automatically by
  395.      * the code writing to the message window, but I could be wrong.
  396.      */
  397. }
  398.  
  399. int
  400. amii_doprev_message()
  401. {
  402.     struct amii_WinDesc *cw;
  403.     struct Window *w;
  404.     char *str;
  405.  
  406.     if( WIN_MESSAGE == WIN_ERR ||
  407.     ( cw = amii_wins[ WIN_MESSAGE ] ) == NULL || ( w = cw->win ) == NULL )
  408.     {
  409.     panic(winpanicstr,WIN_MESSAGE, "doprev_message");
  410.     }
  411.  
  412.     /* When an interlaced/tall screen is in use, the scroll bar will be there */
  413.     if( scrollmsg )
  414.     {
  415.     struct Gadget *gd;
  416.     struct PropInfo *pip;
  417.     int hidden, topidx, i, total, wheight;
  418.  
  419.     for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  420.         gd = gd->NextGadget;
  421.  
  422.     if( gd )
  423.     {
  424.         pip = (struct PropInfo *)gd->SpecialInfo;
  425.         wheight = ( w->Height - w->BorderTop -
  426.                 w->BorderBottom - 2 ) / w->RPort->TxHeight;
  427.         hidden = max( cw->maxrow - wheight, 0 );
  428.         topidx = (((ULONG)hidden * pip->VertPot) + (MAXPOT/2)) >> 16;
  429.         for( total = i = 0; i < cw->maxrow; ++i )
  430.         {
  431.         if( cw->data[i][1] == 0 )
  432.             ++total;
  433.         }
  434.  
  435.         i = 0;
  436.         while( (--topidx) >= 0 && i < wheight/2 )
  437.         {
  438.         SetPropInfo( w, &MsgScroll, wheight, total, topidx );
  439.         DisplayData( WIN_MESSAGE, topidx, -1 );
  440.         ++i;
  441.         }
  442.     }
  443.     return(0);
  444.     }
  445.  
  446.     if( --cw->vwy < 0 )
  447.     {
  448.     cw->maxcol = 0;
  449.     DisplayBeep( NULL );
  450.     str = "\0\0No more history saved...";
  451.     }
  452.     else
  453.     str = cw->data[ cw->vwy ];
  454.  
  455.     amii_cl_end(cw, 0);
  456.     amii_curs( WIN_MESSAGE, 1, 0 );
  457.     Text(w->RPort,str+SOFF,strlen(str+SOFF));
  458.     cw->curx = cw->cols + 1;
  459.  
  460.     return( 0 );
  461. }
  462.