home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part24 < prev    next >
Encoding:
Internet Message Format  |  1993-01-31  |  58.7 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i024:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part24/108
  5. Message-ID: <4312@master.CNA.TEK.COM>
  6. Date: 29 Jan 93 20:44:32 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2457
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1581
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 24
  14. Archive-name: nethack31/Part24
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 24 (of 108)."
  27. # Contents:  sys/amiga/winami.c2 win/X11/winmisc.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:08:55 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'sys/amiga/winami.c2' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'sys/amiga/winami.c2'\"
  32. else
  33. echo shar: Extracting \"'sys/amiga/winami.c2'\" \(42959 characters\)
  34. sed "s/^X//" >'sys/amiga/winami.c2' <<'END_OF_FILE'
  35. Xstatic void
  36. Xoutmore( cw )
  37. X    register struct WinDesc *cw;
  38. X{
  39. X    struct Window *w = cw->win;
  40. X
  41. X    Text( w->RPort, " --more--", 9 );
  42. X    /* Allow mouse clicks to clean --more-- */
  43. X    WindowGetevent( );
  44. X    amii_curs( WIN_MESSAGE, 1, 0 );
  45. X    cw->curx = 0;
  46. X    amii_cl_end( cw, cw->curx );
  47. X}
  48. X
  49. Xstatic void
  50. Xoutsubstr( cw, str, len )
  51. X    register struct WinDesc *cw;
  52. X    char *str;
  53. X    int len;
  54. X{
  55. X    struct Window *w = cw->win;
  56. X
  57. X    if( cw->curx )
  58. X    {
  59. X    /* Check if this string and --more-- fit, if not,
  60. X     * then put out --more-- and wait for a key.
  61. X     */
  62. X    if( (len + MORE_FUDGE ) + cw->curx >= cw->cols )
  63. X    {
  64. X        outmore( cw );
  65. X    }
  66. X    else
  67. X    {
  68. X        /* Otherwise, move and put out a blank separator */
  69. X        Text( w->RPort, spaces, 1 );
  70. X        cw->curx += 1;
  71. X    }
  72. X    }
  73. X
  74. X    Text(w->RPort,str,len);
  75. X}
  76. X
  77. X/* Put a graphics character onto the screen */
  78. X
  79. Xvoid
  80. Xamii_putsym( st, i, y, c )
  81. X    winid st;
  82. X    int i, y;
  83. X    CHAR_P c;
  84. X{
  85. X    char buf[ 2 ];
  86. X    amii_curs( st, i, y );
  87. X    buf[ 0 ] = c;
  88. X    buf[ 1 ] = 0;
  89. X    amii_putstr( st, 0, buf );
  90. X}
  91. X
  92. X/* Clear the indicated window */
  93. X
  94. Xvoid
  95. Xamii_clear_nhwindow(win)
  96. X    register winid win;
  97. X{
  98. X    register struct WinDesc *cw;
  99. X    register struct Window *w;
  100. X
  101. X    if( win == WIN_ERR || ( cw = wins[win] ) == NULL )
  102. X    panic( winpanicstr, win, "clear_nhwindow" );
  103. X
  104. X    if( w = cw->win )
  105. X    SetDrMd( w->RPort, JAM2);
  106. X
  107. X    cursor_off( win );
  108. X
  109. X    /* should be: clear the rastport, reset x,y etc */
  110. X
  111. X    if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  112. X    {
  113. X    /* Window might not be opened yet */
  114. X
  115. X    if( w )
  116. X    {
  117. X        SetAPen( w->RPort, 0 );
  118. X        SetBPen( w->RPort, 0 );
  119. X        RectFill( w->RPort, w->BorderLeft, w->BorderTop,
  120. X          w->Width - w->BorderRight-1,
  121. X          w->Height - w->BorderBottom-1 );
  122. X        SetAPen( w->RPort, 1 );
  123. X    }
  124. X    }
  125. X    else if( w )
  126. X    {
  127. X    if( cw->type == NHW_MESSAGE )
  128. X    {
  129. X        amii_curs( win, 1, 0 );
  130. X        TextSpaces( w->RPort, cw->cols );
  131. X    }
  132. X    else
  133. X    {
  134. X        SetAPen( w->RPort, 0 );
  135. X        SetBPen( w->RPort, 0 );
  136. X        RectFill( w->RPort, w->BorderLeft, w->BorderTop,
  137. X          w->Width - w->BorderRight-1,
  138. X          w->Height - w->BorderBottom-1 );
  139. X        SetAPen( w->RPort, 1 );
  140. X    }
  141. X    }
  142. X
  143. X    cw->curx = cw->cury = 0;
  144. X    amii_curs( win, 1, 0 );
  145. X}
  146. X
  147. X/* Dismiss the window from the screen */
  148. X
  149. Xstatic void
  150. Xdismiss_nhwindow(win)
  151. X    register winid win;
  152. X{
  153. X    register struct Window *w;
  154. X    register struct WinDesc *cw;
  155. X
  156. X    if( win == WIN_ERR || ( cw = wins[win] ) == NULL )
  157. X    {
  158. X    panic(winpanicstr,win, "dismiss_nhwindow");
  159. X    }
  160. X
  161. X    w = cw->win;
  162. X
  163. X    if( w )
  164. X    {
  165. X    /* Map Window has this stuff attached to it. */
  166. X    if( win == WIN_MAP )
  167. X        ClearMenuStrip( w );
  168. X
  169. X    /* Close the window? */
  170. X
  171. X    CloseShWindow( w );
  172. X    cw->win = NULL;
  173. X
  174. X    if( cw->newwin )
  175. X        FreeNewWindow( (void *)cw->newwin );
  176. X    cw->newwin = NULL;
  177. X    }
  178. X
  179. X    if( cw->canresp )
  180. X    free( cw->canresp );
  181. X    cw->canresp = NULL;
  182. X
  183. X    if( cw->morestr )
  184. X    free( cw->morestr );
  185. X    cw->morestr = NULL;
  186. X
  187. X    cw->maxrow = cw->maxcol = 0;
  188. X}
  189. X
  190. Xvoid
  191. Xamii_exit_nhwindows(str)
  192. X    const char *str;
  193. X{
  194. X    /* Seems strange to have to do this... but we need the BASE window
  195. X     * left behind...
  196. X     */
  197. X    kill_nhwindows( 0 );
  198. X    if( str ) raw_print( str );
  199. X}
  200. X
  201. Xamii_nh_poskey(x, y, mod)
  202. X    int*x, *y, *mod;
  203. X{
  204. X    struct WinDesc *cw;
  205. X    WETYPE type;
  206. X    struct RastPort *rp;
  207. X    struct Window *w;
  208. X
  209. X    if( WIN_MAP != WIN_ERR && (cw = wins[ WIN_MAP ]) && ( w = cw->win ) )
  210. X    cursor_on( WIN_MAP );
  211. X    else
  212. X    panic( "no MAP window opened for nh_poskey\n" );
  213. X
  214. X    rp = w->RPort;
  215. X    while( 1 )
  216. X    {
  217. X    type = WindowGetevent( );
  218. X    if( type == WEMOUSE )
  219. X    {
  220. X        *mod = CLICK_1;
  221. X        if( lastevent.u.mouse.qual )
  222. X        *mod = 0;
  223. X
  224. X        /* X coordinates are 1 based, Y are zero based. */
  225. X        *x = ( (lastevent.u.mouse.x - w->BorderLeft) / txwidth ) + 1;
  226. X        *y = ( ( lastevent.u.mouse.y - w->BorderTop-txbaseline ) /
  227. X            txheight );
  228. X        return( 0 );
  229. X    }
  230. X    else if( type == WEKEY )
  231. X    {
  232. X        lastevent.type = WEUNK;
  233. X        return( lastevent.u.key );
  234. X    }
  235. X    }
  236. X}
  237. X
  238. Xint
  239. Xamii_nhgetch()
  240. X{
  241. X    int ch;
  242. X
  243. X    if( WIN_MAP != WIN_ERR && wins[ WIN_MAP ] )
  244. X    cursor_on( WIN_MAP );
  245. X    ch = WindowGetchar();
  246. X    return( ch );
  247. X}
  248. X
  249. Xvoid
  250. Xamii_get_nh_event()
  251. X{
  252. X    /* nothing now - later I have no idea.  Is this just a Mac hook? */
  253. X}
  254. X
  255. Xvoid
  256. Xamii_remember_topl()
  257. X{
  258. X    /* ignore for now.  I think this will be done automatically by
  259. X     * the code writing to the message window, but I could be wrong.
  260. X     */
  261. X}
  262. X
  263. Xint
  264. Xamii_doprev_message()
  265. X{
  266. X    struct WinDesc *cw;
  267. X    struct Window *w;
  268. X    char *str;
  269. X
  270. X    if( WIN_MESSAGE == WIN_ERR ||
  271. X        ( cw = wins[ WIN_MESSAGE ] ) == NULL || ( w = cw->win ) == NULL )
  272. X    {
  273. X    panic(winpanicstr,WIN_MESSAGE, "doprev_message");
  274. X    }
  275. X
  276. X    if( --cw->maxcol < 0 )
  277. X    {
  278. X    cw->maxcol = 0;
  279. X    DisplayBeep( NULL );
  280. X    str = "No more history saved...";
  281. X    }
  282. X    else
  283. X    str = cw->data[ cw->maxcol ];
  284. X
  285. X    amii_cl_end(cw, 0);
  286. X    amii_curs( WIN_MESSAGE, 1, 0 );
  287. X    Text(w->RPort,str,strlen(str));
  288. X    cw->curx = cw->cols + 1;
  289. X
  290. X    return( 0 );
  291. X}
  292. X
  293. Xvoid
  294. Xamii_display_nhwindow(win,blocking)
  295. X    winid win;
  296. X    boolean blocking;
  297. X{
  298. X    int i;
  299. X    static int lastwin = -1;
  300. X    struct Window *w;
  301. X    struct WinDesc *cw;
  302. X
  303. X    if( !Initialized )
  304. X    return;
  305. X    lastwin = win;
  306. X
  307. X    if( win == WIN_ERR || ( cw = wins[win] ) == NULL )
  308. X    panic(winpanicstr,win,"display_nhwindow");
  309. X
  310. X    if( cw->type == NHW_MAP || cw->type == NHW_STATUS ||
  311. X                        cw->type == NHW_MESSAGE )
  312. X    {
  313. X    return;
  314. X    }
  315. X
  316. X    if(cw->type==NHW_MESSAGE)
  317. X    flags.window_inited=TRUE;
  318. X
  319. X    /* should be:
  320. X    if type != map, WindowToFront
  321. X    if type == map && autoshow, unblock area around cursor
  322. X        (or something like that)
  323. X     */
  324. X
  325. X    w = cw->win;
  326. X    if( w )
  327. X    {
  328. X    WindowToFront( w );
  329. X    ActivateWindow( w );
  330. X    }
  331. X
  332. X    if( blocking && WIN_MAP != WIN_ERR && wins[ WIN_MAP ] )
  333. X    {
  334. X    flush_glyph_buffer( wins[ WIN_MAP ]->win );
  335. X    }
  336. X
  337. X    if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  338. X    {
  339. X    DoMenuScroll( win, blocking );
  340. X    }
  341. X    else if( cw->type==NHW_MAP )
  342. X    {
  343. X    end_glyphout( win );
  344. X    for( i = 0; i < MAXWIN; ++i )
  345. X    {
  346. X        if( cw = wins[i] )
  347. X        {
  348. X        if( cw->type == NHW_STATUS || cw->type == NHW_MESSAGE )
  349. X        {
  350. X            if( cw->win )
  351. X            {
  352. X            WindowToFront(cw->win);
  353. X            }
  354. X        }
  355. X        }
  356. X    }
  357. X
  358. X    /* Do more if it is time... */
  359. X    if( blocking == TRUE )
  360. X        outmore( wins[ win ] );
  361. X    }
  362. X}
  363. X
  364. Xvoid
  365. Xamii_display_file(fn, complain)
  366. Xconst char *fn;
  367. Xboolean complain;
  368. X{
  369. X    register struct WinDesc *cw;
  370. X    register int win;
  371. X    register FILE *fp;
  372. X    register char *t;
  373. X    register char buf[ 200 ];
  374. X
  375. X    if( fn == NULL )
  376. X    panic("NULL file name in display_file()");
  377. X
  378. X    if( ( fp = fopen( fn, "r" ) ) == NULL )
  379. X    {
  380. X    if (complain) {
  381. X        sprintf( buf, "Can't display %s: %s", fn,
  382. X#ifdef  __SASC_60
  383. X            __sys_errlist[ errno ]
  384. X#else
  385. X            sys_errlist[ errno ]
  386. X#endif
  387. X            );
  388. X        amii_addtopl( buf );
  389. X    }
  390. X    return;
  391. X    }
  392. X    win = amii_create_nhwindow( NHW_TEXT );
  393. X
  394. X    /* Set window title to file name */
  395. X    if( cw = wins[ win ] )
  396. X    cw->morestr = fn;
  397. X
  398. X    while( fgets( buf, sizeof( buf ), fp ) != NULL )
  399. X    {
  400. X    if( t = index( buf, '\n' ) )
  401. X        *t = 0;
  402. X    amii_putstr( win, 0, buf );
  403. X    }
  404. X    fclose( fp );
  405. X
  406. X    /* If there were lines in the file, display those lines */
  407. X
  408. X    if( wins[ win ]->cury > 0 )
  409. X    amii_display_nhwindow( win, TRUE );
  410. X
  411. X    amii_destroy_nhwindow( win );
  412. X}
  413. X
  414. Xvoid
  415. Xamii_curs(window, x, y)
  416. Xwinid window;
  417. Xregister int x, y;  /* not xchar: perhaps xchar is unsigned and
  418. X           curx-x would be unsigned as well */
  419. X{
  420. X    register struct WinDesc *cw;
  421. X    register struct Window *w;
  422. X    register struct RastPort *rp;
  423. X
  424. X    if( window == WIN_ERR || ( cw = wins[window] ) == NULL )
  425. X    panic(winpanicstr,  window, "curs");
  426. X    if( (w = cw->win) == NULL )
  427. X    {
  428. X    if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  429. X        return;
  430. X    else
  431. X        panic( "No window open yet in curs() for winid %d\n", window );
  432. X    }
  433. X    amiIDisplay->lastwin = window;
  434. X
  435. X    /* Make sure x is within bounds */
  436. X    if( x > 0 )
  437. X    --x;    /* column 0 is never used */
  438. X    else
  439. X    x = 0;
  440. X
  441. X    cw->curx = x;
  442. X    cw->cury = y;
  443. X#ifdef DEBUG
  444. X    if(x<0 || y<0 || y >= cw->rows || x >= cw->cols)
  445. X    {
  446. X    char *s = "[unknown type]";
  447. X    switch(cw->type)
  448. X    {
  449. X        case NHW_MESSAGE: s = "[topl window]"; break;
  450. X        case NHW_STATUS: s = "[status window]"; break;
  451. X        case NHW_MAP: s = "[map window]"; break;
  452. X        case NHW_MENU: s = "[menu window]"; break;
  453. X        case NHW_TEXT: s = "[text window]"; break;
  454. X    }
  455. X    impossible("bad curs positioning win %d %s (%d,%d)", window, s, x, y);
  456. X    return;
  457. X    }
  458. X#endif
  459. X    x += cw->offx;
  460. X    y += cw->offy;
  461. X
  462. X#ifdef CLIPPING
  463. X    if(clipping && window == WIN_MAP)
  464. X    {
  465. X    x -= clipx;
  466. X    y -= clipy;
  467. X    }
  468. X#endif
  469. X
  470. X    /* Output all saved output before doing cursor movements for MAP */
  471. X
  472. X    if( cw->type == NHW_MAP )
  473. X    flush_glyph_buffer( w );
  474. X
  475. X    /* Actually do it */
  476. X
  477. X    rp = w->RPort;
  478. X    if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  479. X    {
  480. X    Move( rp, (x * txwidth) + w->BorderLeft + 3,
  481. X        (y*(txheight+1) ) + w->RPort->TxBaseline + w->BorderTop + 1 );
  482. X    }
  483. X    else if( cw->type == NHW_MAP || cw->type == NHW_BASE )
  484. X    {
  485. X    /* These coordinate calculations must be synced with those
  486. X     * in flush_glyph_buffer() in amiwind.c.  curs_on_u() will
  487. X     * use this code, all other drawing occurs through the glyph
  488. X     * code.  In order for the cursor to appear on top of the hero,
  489. X     * the code must compute X,Y in the same manner relative to
  490. X     * the RastPort coordinates.
  491. X     */
  492. X    Move( rp, (x * txwidth) + w->BorderLeft,
  493. X            w->BorderTop + ( (y + 1) * txheight ) + txbaseline + 1 );
  494. X    }
  495. X    else if( cw->type == NHW_MESSAGE )
  496. X    {
  497. X    Move( rp, (x * txwidth) + w->BorderLeft + 2,
  498. X                        w->BorderTop + txbaseline + 3 );
  499. X    }
  500. X    else
  501. X    {
  502. X    Move( rp, (x * txwidth) + w->BorderLeft + 2,
  503. X                (y*txheight) + w->BorderTop + txbaseline + 2 );
  504. X    }
  505. X}
  506. X
  507. X/*
  508. X *  print_glyph
  509. X *
  510. X *  Print the glyph to the output device.  Don't flush the output device.
  511. X *
  512. X *  Since this is only called from show_glyph(), it is assumed that the
  513. X *  position and glyph are always correct (checked there)!
  514. X */
  515. X
  516. Xvoid
  517. Xamii_print_glyph(win,x,y,glyph)
  518. X    winid win;
  519. X    xchar x,y;
  520. X    int glyph;
  521. X{
  522. X    struct WinDesc *cw;
  523. X    uchar   ch;
  524. X    register int offset;
  525. X#ifdef TEXTCOLOR
  526. X    int     color;
  527. X    extern int zapcolors[];
  528. X
  529. X    if( win == WIN_ERR || (cw=wins[win]) == NULL || cw->type != NHW_MAP)
  530. X    panic(winpanicstr,win,"print_glyph");
  531. X
  532. X#define zap_color(n)  color = flags.use_color ? zapcolors[n] : NO_COLOR
  533. X#define cmap_color(n) color = flags.use_color ? defsyms[n].color : NO_COLOR
  534. X#define trap_color(n) color = flags.use_color ? \
  535. X        (((n) == WEB) ? defsyms[S_web ].color  : \
  536. X                defsyms[S_trap].color) : \
  537. X            NO_COLOR
  538. X#define obj_color(n)  color = flags.use_color ? objects[n].oc_color : NO_COLOR
  539. X#define mon_color(n)  color = flags.use_color ? mons[n].mcolor : NO_COLOR
  540. X#define pet_color(n)  color = flags.use_color ? mons[n].mcolor :          \
  541. X        /* If no color, try to hilite pets; black  */ \
  542. X        /* should be HI                */ \
  543. X            ((flags.hilite_pet) ? BLACK : NO_COLOR)
  544. X
  545. X# else /* no text color */
  546. X
  547. X#define zap_color(n)
  548. X#define cmap_color(n)
  549. X#define trap_color(n)
  550. X#define obj_color(n)
  551. X#define mon_color(n)
  552. X#define pet_color(n)
  553. X
  554. X#endif
  555. X
  556. X    /*
  557. X     *  Map the glyph back to a character.
  558. X     *
  559. X     *  Warning:  For speed, this makes an assumption on the order of
  560. X     *        offsets.  The order is set in display.h.
  561. X     */
  562. X    if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {  /* swallow */
  563. X    /* see swallow_to_glyph()in display.c */
  564. X    ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
  565. X    mon_color(offset >> 3);
  566. X    } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {       /* zap beam */
  567. X    ch = showsyms[S_vbeam + (offset & 0x3)];
  568. X    zap_color((offset >> 2));
  569. X    } else if( ( offset = (glyph - GLYPH_CMAP_OFF) ) >= 0 ) {   /* cmap */
  570. X    ch = showsyms[offset];
  571. X    cmap_color(offset);
  572. X    } else if ( ( offset = (glyph - GLYPH_TRAP_OFF) ) >= 0 ) {  /* trap */
  573. X    ch = (offset == WEB) ? showsyms[S_web] : showsyms[S_trap];
  574. X    trap_color(offset);
  575. X    } else if( ( offset = (glyph - GLYPH_OBJ_OFF) ) >= 0 ) {    /* object */
  576. X    ch = oc_syms[objects[offset].oc_class];
  577. X    obj_color(offset);
  578. X    } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {  /* a corpse */
  579. X    ch = oc_syms[objects[CORPSE].oc_class];
  580. X    mon_color(offset);
  581. X    } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {   /* a pet */
  582. X    ch = (uchar) monsyms[mons[offset].mlet];
  583. X    pet_color(offset);
  584. X    } else /*if( glyph_is_monster(glyph) )*/ {      /* a monster */
  585. X    ch = (uchar) monsyms[mons[glyph].mlet];
  586. X    mon_color(glyph);
  587. X    }
  588. X
  589. X    /* Move the cursor. */
  590. X#ifdef CLIPPING
  591. X    if (!win_curs(x, y)) return;
  592. X#else
  593. X    amii_curs(win,x,y+2);
  594. X#endif
  595. X
  596. X#ifdef TEXTCOLOR
  597. X    /* Turn off color if rogue level. */
  598. X# ifdef REINCARNATION
  599. X    if (Is_rogue_level(&u.uz))
  600. X    color = NO_COLOR;
  601. X#  endif
  602. X
  603. X    amiga_print_glyph(win,color,ch);
  604. X#else
  605. X    g_putch(ch);    /* print the character */
  606. X#endif
  607. X    cw->curx++;     /* one character over */
  608. X}
  609. X
  610. Xvoid
  611. XDoMenuScroll( win, blocking )
  612. X    int win, blocking;
  613. X{
  614. X    register struct Window *w;
  615. X    register struct NewWindow *nw;
  616. X    struct PropInfo *pip;
  617. X    register struct WinDesc *cw;
  618. X    struct IntuiMessage *imsg;
  619. X    struct Gadget *gd;
  620. X    register int wheight, xsize, ysize, aredone = 0;
  621. X    register int txwd, txh;
  622. X    long mics, secs, class, code;
  623. X    long oldmics = 0, oldsecs = 0;
  624. X    int aidx, oidx, topidx, hidden;
  625. X    char *t;
  626. X    SHORT mx, my;
  627. X    char title[ 100 ];
  628. X    int dosize = 1;
  629. X    struct Screen *scrn = HackScreen;
  630. X
  631. X    if( win == WIN_ERR || ( cw = wins[ win ] ) == NULL )
  632. X    panic(winpanicstr,win,"DoMenuScroll");
  633. X
  634. X    /* Check to see if we should open the window, should usually need to */
  635. X
  636. X    txwd = txwidth;
  637. X    txh = txheight + 1; /* +1 for interline space */
  638. X    w = cw->win;
  639. X    if( w == NULL )
  640. X    {
  641. X    /* Humm, there is only so much... */
  642. X    if( scrn )
  643. X         xsize = scrn->WBorLeft + scrn->WBorRight + MenuScroll.Width + 2;
  644. X    else
  645. X         xsize = 5 + 5 + MenuScroll.Width + 2;
  646. X    xsize += (txwd * cw->maxcol);
  647. X    if( xsize > amiIDisplay->xpix )
  648. X        xsize = amiIDisplay->xpix;
  649. X
  650. X        /* If next row not off window, use it, else use the bottom */
  651. X
  652. X    ysize = ( txh * cw->maxrow ) +          /* The text space */
  653. X      HackScreen->WBorTop + txheight + 1 +    /* Top border */
  654. X      HackScreen->WBorBottom + 1;     /* The bottom border */
  655. X    if( ysize > amiIDisplay->ypix )
  656. X        ysize = amiIDisplay->ypix;
  657. X
  658. X    /* Adjust the size of the menu scroll gadget */
  659. X
  660. X    nw = (void *)DupNewWindow( (void *)(&new_wins[ cw->type ].newwin) );
  661. X    cw->newwin = (void *)nw;
  662. X    if( nw == NULL )
  663. X        panic("No NewWindow Allocated" );
  664. X
  665. X    nw->Screen = HackScreen;
  666. X
  667. X    if( win == WIN_INVEN ){
  668. X        sprintf( title, "%s the %s's Inventory", plname, pl_character );
  669. X        nw->Title = title;
  670. X    }
  671. X    else if( cw->morestr )
  672. X        nw->Title = cw->morestr;
  673. X
  674. X    /* Adjust the window coordinates and size now that we know
  675. X     * how many items are to be displayed.
  676. X     */
  677. X
  678. X    nw->Width = xsize;
  679. X    nw->Height = ysize;
  680. X    nw->TopEdge = 0;
  681. X    if( cw->type == NHW_TEXT && ysize < amiIDisplay->ypix )
  682. X        nw->TopEdge += ( amiIDisplay->ypix - ysize ) / 2;
  683. X    nw->LeftEdge = amiIDisplay->xpix - xsize;
  684. X    if( cw->type == NHW_TEXT && xsize < amiIDisplay->xpix )
  685. X        nw->LeftEdge -= ( amiIDisplay->xpix - xsize ) / 2;
  686. X
  687. X
  688. X    /* Now, open the window */
  689. X    w = cw->win = OpenShWindow( (void *)nw );
  690. X
  691. X    if( w == NULL )    panic("No Window Opened For Menu" );
  692. X    }
  693. X
  694. X    /* Find the scroll gadget */
  695. X
  696. X    for( gd = w->FirstGadget; gd && gd->GadgetID != 1; gd = gd->NextGadget )
  697. X    continue;
  698. X
  699. X    if( !gd ) panic("Can't find scroll gadget" );
  700. X
  701. X    wheight = ( w->Height - w->BorderTop - w->BorderBottom ) / txh;
  702. X    cw->cols = ( w->Width - w->BorderLeft - w->BorderRight
  703. X        /* + MenuScroll.Width*/ ) / txwd;
  704. X    morc = 0;
  705. X    oidx = -1;
  706. X    topidx = 0;
  707. X
  708. X    /* Make the prop gadget the right size and place */
  709. X
  710. X    DisplayData( win, topidx, -1 );
  711. X
  712. X    SetPropInfo( w, gd, wheight, cw->maxrow, topidx );
  713. X    oldsecs = oldmics = 0;
  714. X
  715. X    while( !aredone )
  716. X    {
  717. X    /* Process window messages */
  718. X
  719. X    WaitPort( w->UserPort );
  720. X    while( imsg = (struct IntuiMessage * ) GetMsg( w->UserPort ) )
  721. X    {
  722. X        class = imsg->Class;
  723. X        code = imsg->Code;
  724. X        mics = imsg->Micros;
  725. X        secs = imsg->Seconds;
  726. X        gd = (struct Gadget *) imsg->IAddress;
  727. X        mx = imsg->MouseX;
  728. X        my = imsg->MouseY;
  729. X
  730. X        /* Only do our window or VANILLAKEY from other windows */
  731. X
  732. X        if( imsg->IDCMPWindow != w && class != VANILLAKEY &&
  733. X                            class != RAWKEY )
  734. X        {
  735. X        ReplyMsg( (struct Message *) imsg );
  736. X        continue;
  737. X        }
  738. X
  739. X        /* Do DeadKeyConvert() stuff if RAWKEY... */
  740. X        if( class == RAWKEY )
  741. X        {
  742. X        class = VANILLAKEY;
  743. X        code = ConvertKey( imsg );
  744. X        }
  745. X        ReplyMsg( (struct Message *) imsg );
  746. X
  747. X        switch( class )
  748. X        {
  749. X        case NEWSIZE:
  750. X            /* Ignore every other newsize, no action needed */
  751. X
  752. X            if( !dosize )
  753. X            {
  754. X            dosize = 1;
  755. X            break;
  756. X            }
  757. X
  758. X            /* Find the gadget */
  759. X
  760. X            for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  761. X            gd = gd->NextGadget;
  762. X
  763. X            if( !gd )
  764. X            panic("Can't find scroll gadget" );
  765. X
  766. X            wheight = ( w->Height - w->BorderTop -
  767. X                        w->BorderBottom - 1) / txh;
  768. X            cw->cols = ( w->Width -
  769. X                w->BorderLeft - w->BorderRight ) / txwd;
  770. X            if( wheight < 2 )
  771. X            wheight = 2;
  772. X
  773. X            /* Make the prop gadget the right size and place */
  774. X
  775. X            DisplayData( win, topidx, oidx );
  776. X            SetPropInfo( w, gd, wheight, cw->maxrow, topidx );
  777. X
  778. X            /* Force the window to a text line boundry <= to
  779. X             * what the user dragged it to.  This eliminates
  780. X             * having to clean things up on the bottom edge.
  781. X             */
  782. X
  783. X            SizeWindow( w, 0, ( wheight * txh) +
  784. X                w->BorderTop + w->BorderBottom + 1 - w->Height );
  785. X
  786. X            /* Don't do next NEWSIZE, we caused it */
  787. X            dosize = 0;
  788. X            oldsecs = oldmics = 0;
  789. X            break;
  790. X
  791. X        case VANILLAKEY:
  792. X#define CTRL(x)     ((x)-'@')
  793. X            if( code == CTRL('D') || code == CTRL('U') )
  794. X            {
  795. X            int endcnt, i;
  796. X
  797. X            for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  798. X                gd = gd->NextGadget;
  799. X
  800. X            if( !gd )
  801. X                panic("Can't find scroll gadget" );
  802. X
  803. X            endcnt = wheight / 2;
  804. X            if( endcnt == 0 )
  805. X                endcnt = 1;
  806. X
  807. X            for( i = 0; i < endcnt; ++i )
  808. X            {
  809. X                if( code == CTRL('D') )
  810. X                {
  811. X                if( topidx + wheight < cw->maxrow )
  812. X                    ++topidx;
  813. X                else
  814. X                    break;
  815. X                }
  816. X                else
  817. X                {
  818. X                if( topidx > 0 )
  819. X                    --topidx;
  820. X                else
  821. X                    break;
  822. X                }
  823. X
  824. X                /* Make prop gadget the right size and place */
  825. X
  826. X                DisplayData( win, topidx, oidx );
  827. X                SetPropInfo( w,gd, wheight, cw->maxrow, topidx );
  828. X            }
  829. X            oldsecs = oldmics = 0;
  830. X            }
  831. X            else if( code == '\b' )
  832. X            {
  833. X            for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  834. X                gd = gd->NextGadget;
  835. X
  836. X            if( !gd )
  837. X                panic("Can't find scroll gadget" );
  838. X
  839. X            if( topidx - wheight - 2 < 0 )
  840. X            {
  841. X                topidx = 0;
  842. X            }
  843. X            else
  844. X            {
  845. X                topidx -= wheight - 2;
  846. X            }
  847. X            DisplayData( win, topidx, oidx );
  848. X            SetPropInfo( w, gd, wheight, cw->maxrow, topidx );
  849. X            oldsecs = oldmics = 0;
  850. X            }
  851. X            else if( code == ' ' )
  852. X            {
  853. X            for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  854. X                gd = gd->NextGadget;
  855. X
  856. X            if( !gd )
  857. X                panic("Can't find scroll gadget" );
  858. X
  859. X            if( topidx + wheight >= cw->maxrow )
  860. X            {
  861. X                morc = 0;
  862. X                aredone = 1;
  863. X            }
  864. X            else
  865. X            {
  866. X                /*  If there are still lines to be seen */
  867. X
  868. X                if( cw->maxrow > topidx + wheight )
  869. X                {
  870. X                if( wheight > 2 )
  871. X                    topidx += wheight - 2;
  872. X                else
  873. X                    ++topidx;
  874. X                DisplayData( win, topidx, oidx );
  875. X                SetPropInfo( w, gd, wheight,
  876. X                            cw->maxrow, topidx );
  877. X                }
  878. X                oldsecs = oldmics = 0;
  879. X            }
  880. X            }
  881. X            else if( code == '\n' || code == '\r' )
  882. X            {
  883. X            for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  884. X                gd = gd->NextGadget;
  885. X
  886. X            if( !gd )
  887. X                panic("Can't find scroll gadget" );
  888. X
  889. X            /* If all line displayed, we are done */
  890. X
  891. X            if( topidx + wheight >= cw->maxrow )
  892. X            {
  893. X                morc = 0;
  894. X                aredone = 1;
  895. X            }
  896. X            else
  897. X            {
  898. X                /*  If there are still lines to be seen */
  899. X
  900. X                if( cw->maxrow > topidx + 1 )
  901. X                {
  902. X                ++topidx;
  903. X                DisplayData( win, topidx, oidx );
  904. X                SetPropInfo( w, gd, wheight,
  905. X                            cw->maxrow, topidx );
  906. X                }
  907. X                oldsecs = oldmics = 0;
  908. X            }
  909. X            }
  910. X            else if( cw->resp && index( cw->resp, code ) )
  911. X            {
  912. X            morc = code;
  913. X            aredone = 1;
  914. X            }
  915. X            else if( code == '\33' || code == 'q' || code == 'Q' )
  916. X            {
  917. X            morc = '\33';
  918. X            aredone = 1;
  919. X            }
  920. X            break;
  921. X
  922. X        case CLOSEWINDOW:
  923. X            aredone = 1;
  924. X            morc = '\33';
  925. X            break;
  926. X
  927. X        case GADGETUP:
  928. X            break;
  929. X
  930. X        case MOUSEMOVE:
  931. X            for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  932. X            gd = gd->NextGadget;
  933. X
  934. X            pip = (struct PropInfo *)gd->SpecialInfo;
  935. X            hidden = max( cw->maxrow - wheight, 0 );
  936. X            aidx = (((ULONG)hidden * pip->VertPot) + (MAXPOT/2)) >> 16;
  937. X            if( aidx != topidx )
  938. X            DisplayData( win, topidx = aidx, oidx );
  939. X            break;
  940. X
  941. X        case MOUSEBUTTONS:
  942. X            if( ( code == SELECTUP || code == SELECTDOWN ) &&
  943. X                            cw->type == NHW_MENU )
  944. X            {
  945. X            /* Which one is the mouse pointing at? */
  946. X
  947. X            aidx = (( (my - w->TopEdge) - w->BorderTop + 1 ) /
  948. X                            txh) + topidx;
  949. X
  950. X            /* If different lines, don't select double click */
  951. X
  952. X            if( aidx != oidx )
  953. X            {
  954. X                oldsecs = 0;
  955. X                oldmics = 0;
  956. X            }
  957. X
  958. X            /* If releasing, check for double click */
  959. X
  960. X            if( code == SELECTUP )
  961. X            {
  962. X                if( aidx == oidx )
  963. X                {
  964. X                if( DoubleClick( oldsecs,
  965. X                            oldmics, secs, mics ) )
  966. X                {
  967. X                    morc = cw->resp[ aidx ];
  968. X                    aredone = 1;
  969. X                }
  970. X                oldsecs = secs;
  971. X                oldmics = mics;
  972. X                }
  973. X            }
  974. X            else if( aidx < cw->maxrow && code == SELECTDOWN )
  975. X            {
  976. X                /* Remove old highlighting if visible */
  977. X
  978. X                if( oidx > topidx && oidx - topidx < wheight )
  979. X                {
  980. X                t = cw->data[ oidx ] + SOFF;
  981. X                amii_curs( win, 1, oidx - topidx );
  982. X                SetDrMd( w->RPort, JAM2 );
  983. X                SetAPen( w->RPort, C_WHITE );
  984. X                SetBPen( w->RPort, C_BLACK );
  985. X                Text( w->RPort, t, strlen( t ) );
  986. X                oidx = -1;
  987. X                }
  988. X
  989. X                t = cw->data[ aidx ];
  990. X                if( t[ SEL_ITEM ] == 1 )
  991. X                {
  992. X                oidx = aidx;
  993. X
  994. X                amii_curs( win, 1, aidx - topidx );
  995. X                SetDrMd( w->RPort, JAM2 );
  996. X                SetAPen( w->RPort, C_BLUE );
  997. X                SetBPen( w->RPort, C_WHITE );
  998. X                t += SOFF;
  999. X                Text( w->RPort, t, strlen( t ) );
  1000. X                }
  1001. X                else
  1002. X                {
  1003. X                DisplayBeep( NULL );
  1004. X                oldsecs = 0;
  1005. X                oldmics = 0;
  1006. X                }
  1007. X            }
  1008. X            }
  1009. X            else
  1010. X            {
  1011. X            DisplayBeep( NULL );
  1012. X            }
  1013. X            break;
  1014. X        }
  1015. X    }
  1016. X    }
  1017. X}
  1018. X
  1019. Xvoid
  1020. XDisplayData( win, start, where )
  1021. X    int win;
  1022. X    int start;
  1023. X    int where;
  1024. X{
  1025. X    register struct WinDesc *cw;
  1026. X    register struct Window *w;
  1027. X    register int i, len, wheight;
  1028. X    int col = -1;
  1029. X
  1030. X    if( win == WIN_ERR || !(cw = wins[win]) || !( w = cw->win ) )
  1031. X    {
  1032. X    panic( winpanicstr, win, "No Window in DisplayData" );
  1033. X    }
  1034. X
  1035. X    SetDrMd( w->RPort, JAM2 );
  1036. X    wheight = ( w->Height - w->BorderTop - w->BorderBottom ) / ( txheight + 1 );
  1037. X
  1038. X    for( i = start; i < start + wheight; ++i )
  1039. X    {
  1040. X    amii_curs( win, 1, i - start );
  1041. X
  1042. X    if( where == i )
  1043. X    {
  1044. X        if( col != 1 )
  1045. X        {
  1046. X        SetAPen( w->RPort, C_BLUE );
  1047. X        SetBPen( w->RPort, C_WHITE );
  1048. X        col = 1;
  1049. X        }
  1050. X    }
  1051. X    else if( col != 2 )
  1052. X    {
  1053. X        SetAPen( w->RPort, C_WHITE );
  1054. X        SetBPen( w->RPort, C_BLACK );
  1055. X        col = 2;
  1056. X    }
  1057. X
  1058. X    /* Next line out, truncate if too long */
  1059. X
  1060. X    len = 0;
  1061. X    if( i < cw->maxrow )
  1062. X    {
  1063. X        register char *t;
  1064. X
  1065. X        t = cw->data[ i ] + SOFF;
  1066. X        len = strlen( t );
  1067. X        if( len > cw->cols )
  1068. X        len = cw->cols;
  1069. X        Text( w->RPort, t, len );
  1070. X    }
  1071. X    amii_cl_end( cw, len );
  1072. X    }
  1073. X    return;
  1074. X}
  1075. X
  1076. Xvoid SetPropInfo( win, gad, vis, total, top )
  1077. X    register struct Window *win;
  1078. X    register struct Gadget *gad;
  1079. X    register long vis, total, top;
  1080. X{
  1081. X    register long hidden;
  1082. X    register int body, pot;
  1083. X
  1084. X    hidden = max( total-vis, 0 );
  1085. X
  1086. X    /* Force the last section to be just to the bottom */
  1087. X
  1088. X    if( top > hidden )
  1089. X    top = hidden;
  1090. X
  1091. X    /* Scale the body position. */
  1092. X    /* 2 lines overlap */
  1093. X
  1094. X    if( hidden > 0 && total != 0 )
  1095. X    body = (ULONG) ((vis - 2) * MAXBODY) / (total - 2);
  1096. X    else
  1097. X    body = MAXBODY;
  1098. X
  1099. X    if( hidden > 0 )
  1100. X    pot = (ULONG) (top * MAXPOT) / hidden;
  1101. X    else
  1102. X    pot = 0;
  1103. X
  1104. X    NewModifyProp( gad, win, NULL,
  1105. X                AUTOKNOB|FREEVERT, 0, pot, MAXBODY, body, 1 );
  1106. X}
  1107. X
  1108. Xvoid
  1109. Xkill_nhwindows( all )
  1110. X    register int all;
  1111. X{
  1112. X    register int i;
  1113. X    register struct WinDesc *cw;
  1114. X
  1115. X    /* Foreach open window in all of wins[], CloseShWindow, free memory */
  1116. X
  1117. X    for( i = 0; i < MAXWIN; ++i )
  1118. X    {
  1119. X    if( (cw = wins[ i ]) && (cw->type != NHW_BASE || all) )
  1120. X    {
  1121. X        CloseShWindow( cw->win );
  1122. X        free( cw );
  1123. X        wins[ i ] = NULL;
  1124. X    }
  1125. X    }
  1126. X}
  1127. X
  1128. Xvoid
  1129. Xamii_cl_end( cw, i )
  1130. X    register struct WinDesc *cw;
  1131. X    register int i;
  1132. X{
  1133. X    register struct Window *w = cw->win;
  1134. X    register int oy, ox;
  1135. X
  1136. X    if( !w )
  1137. X    panic("NULL window pointer in amii_cl_end()");
  1138. X
  1139. X    oy = w->RPort->cp_y;
  1140. X    ox = w->RPort->cp_x;
  1141. X
  1142. X    TextSpaces( w->RPort, cw->cols - i );
  1143. X
  1144. X    Move( w->RPort, ox, oy );
  1145. X}
  1146. X
  1147. Xvoid cursor_off( window )
  1148. X    winid window;
  1149. X{
  1150. X    register struct WinDesc *cw;
  1151. X    register struct Window *w;
  1152. X    register struct RastPort *rp;
  1153. X    int curx, cury;
  1154. X    long dmode;
  1155. X    short apen, bpen;
  1156. X    unsigned char ch;
  1157. X
  1158. X    if( window == WIN_ERR || ( cw = wins[window] ) == NULL )
  1159. X    {
  1160. X    /* tty does this differently - is this OK? */
  1161. X    flags.window_inited=0;
  1162. X    panic(winpanicstr,window, "cursor_off");
  1163. X    }
  1164. X
  1165. X    if( !(cw->flags & FLMAP_CURSUP ) )
  1166. X    return;
  1167. X    w = cw->win;
  1168. X
  1169. X    if( !w )
  1170. X    return;
  1171. X
  1172. X    cw->flags &= ~FLMAP_CURSUP;
  1173. X    rp = w->RPort;
  1174. X
  1175. X    /* Save the current information */
  1176. X    curx = rp->cp_x;
  1177. X    cury = rp->cp_y;
  1178. X    dmode = rp->DrawMode;
  1179. X    apen = rp->FgPen;
  1180. X    bpen = rp->BgPen;
  1181. X    SetAPen( rp, cw->curs_apen );
  1182. X    SetBPen( rp, cw->curs_bpen );
  1183. X    SetDrMd( rp, COMPLEMENT );
  1184. X
  1185. X    ch = CURSOR_CHAR;
  1186. X    Move( rp, cw->cursx, cw->cursy );
  1187. X    Text( rp, &ch, 1 );
  1188. X
  1189. X    /* Put back the other stuff */
  1190. X
  1191. X    Move( rp, curx, cury );
  1192. X    SetDrMd( rp, dmode );
  1193. X    SetAPen( rp, apen );
  1194. X    SetBPen( rp, bpen );
  1195. X}
  1196. X
  1197. Xvoid cursor_on( window )
  1198. X    winid window;
  1199. X{
  1200. X    register struct WinDesc *cw;
  1201. X    register struct Window *w;
  1202. X    register struct RastPort *rp;
  1203. X    unsigned char ch;
  1204. X    long dmode;
  1205. X    short apen, bpen;
  1206. X
  1207. X    if( window == WIN_ERR || ( cw = wins[window] ) == NULL )
  1208. X    {
  1209. X    /* tty does this differently - is this OK? */
  1210. X    flags.window_inited=0;
  1211. X    panic(winpanicstr,window, "cursor_on");
  1212. X    }
  1213. X
  1214. X    if( (cw->flags & FLMAP_CURSUP ) )
  1215. X    cursor_off( window );
  1216. X
  1217. X    w = cw->win;
  1218. X
  1219. X    if( !w )
  1220. X    return;
  1221. X
  1222. X    cw->flags |= FLMAP_CURSUP;
  1223. X    rp = w->RPort;
  1224. X
  1225. X    /* Save the current information */
  1226. X
  1227. X    cw->cursx = rp->cp_x;
  1228. X    cw->cursy = rp->cp_y;
  1229. X    apen = rp->FgPen;
  1230. X    bpen = rp->BgPen;
  1231. X    dmode = rp->DrawMode;
  1232. X    ch = CURSOR_CHAR;
  1233. X
  1234. X    /* Draw in complement mode. The cursor body will be C_WHITE */
  1235. X
  1236. X    cw->curs_apen = C_WHITE;
  1237. X    cw->curs_bpen = C_WHITE;
  1238. X    SetAPen( rp, cw->curs_apen );
  1239. X    SetBPen( rp, cw->curs_bpen );
  1240. X    SetDrMd( rp, COMPLEMENT );
  1241. X    Move( rp, cw->cursx, cw->cursy );
  1242. X    Text( rp, &ch, 1 );
  1243. X    Move( rp, cw->cursx, cw->cursy );
  1244. X
  1245. X    SetDrMd( rp, dmode );
  1246. X    SetAPen( rp, apen );
  1247. X    SetBPen( rp, bpen );
  1248. X}
  1249. X
  1250. Xvoid
  1251. Xamii_getret()
  1252. X{
  1253. X    register int c;
  1254. X
  1255. X    raw_print( "" );
  1256. X    raw_print( "Press Return..." );
  1257. X
  1258. X    c = 0;
  1259. X
  1260. X    while( c != '\n' && c != '\r' )
  1261. X    {
  1262. X    if( HackPort )
  1263. X        c = WindowGetchar();
  1264. X    else
  1265. X        c = getchar();
  1266. X    }
  1267. X    return;
  1268. X}
  1269. X
  1270. XUBYTE UNDOBUFFER[300];
  1271. XSHORT BorderVectors1[] = { 0,0, 57,0, 57,11, 0,11, 0,0 };
  1272. Xstruct Border Border1 = { -1,-1, 3,0,JAM1, 5, BorderVectors1, NULL };
  1273. Xstruct IntuiText IText1 = { 3,0,JAM2, 4,1, NULL, (UBYTE *)"Cancel", NULL };
  1274. Xstruct Gadget Gadget2 = {
  1275. X    NULL, 9,15, 56,10, NULL, RELVERIFY, BOOLGADGET, (APTR)&Border1,
  1276. X    NULL, &IText1, NULL, NULL, 1, NULL
  1277. X};
  1278. XUBYTE StrStringSIBuff[300];
  1279. Xstruct StringInfo StrStringSInfo = {
  1280. X    StrStringSIBuff, UNDOBUFFER, 0, 300, 0, 0,0,0,0,0, 0, 0, NULL
  1281. X};
  1282. XSHORT BorderVectors2[] = { 0,0, 439,0, 439,11, 0,11, 0,0 };
  1283. Xstruct Border Border2 = { -1,-1, 3,0,JAM1, 5, BorderVectors2, NULL };
  1284. Xstruct Gadget String = {
  1285. X    &Gadget2, 77,15, 438,10, NULL, RELVERIFY+STRINGCENTER, STRGADGET,
  1286. X    (APTR)&Border2, NULL, NULL, NULL, (APTR)&StrStringSInfo, 2, NULL
  1287. X};
  1288. X
  1289. X#define StrString \
  1290. X   ((char *)(((struct StringInfo *)(String.SpecialInfo))->Buffer))
  1291. X
  1292. Xstruct NewWindow StrWindow = {
  1293. X    57,74, 526,31, 0,1, GADGETUP+CLOSEWINDOW+ACTIVEWINDOW+VANILLAKEY,
  1294. X    WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
  1295. X    &String, NULL, NULL, NULL, NULL, 5,5, 0xffff,0xffff, CUSTOMSCREEN
  1296. X};
  1297. X
  1298. X/* Generate a requester for a string value. */
  1299. X
  1300. Xvoid amii_getlin(prompt,bufp)
  1301. X    const char *prompt;
  1302. X    char *bufp;
  1303. X{
  1304. X    getlind(prompt,bufp,0);
  1305. X}
  1306. X
  1307. X/* and with default */
  1308. Xvoid getlind(prompt,bufp, dflt)
  1309. X    const char *prompt;
  1310. X    char *bufp;
  1311. X    const char *dflt;
  1312. X{
  1313. X#ifndef TOPL_GETLINE
  1314. X    register struct Window *cwin;
  1315. X    register struct IntuiMessage *imsg;
  1316. X    register long class, code, qual;
  1317. X    register int aredone = 0;
  1318. X    register struct Gadget *gd;
  1319. X    static int once;
  1320. X
  1321. X    *StrString = 0;
  1322. X    if( dflt )
  1323. X    strcpy( StrString, dflt );
  1324. X    StrWindow.Title = (UBYTE *)prompt;
  1325. X    StrWindow.Screen = HackScreen;
  1326. X
  1327. X    if( !once )
  1328. X    {
  1329. X    if( bigscreen )
  1330. X        StrWindow.TopEdge = (HackScreen->Height/2) - (StrWindow.Height/2);
  1331. X    SetBorder( &String );
  1332. X    SetBorder( &Gadget2 );
  1333. X    once = 1;
  1334. X    }
  1335. X
  1336. X    if( ( cwin = OpenWindow( (void *)&StrWindow ) ) == NULL )
  1337. X    {
  1338. X    return;
  1339. X    }
  1340. X
  1341. X    while( !aredone )
  1342. X    {
  1343. X    WaitPort( cwin->UserPort );
  1344. X    while( ( imsg = (void *) GetMsg( cwin->UserPort ) ) != NULL )
  1345. X    {
  1346. X        class = imsg->Class;
  1347. X        code = imsg->Code;
  1348. X        qual = imsg->Qualifier;
  1349. X        gd = (struct Gadget *) imsg->IAddress;
  1350. X
  1351. X        switch( class )
  1352. X        {
  1353. X        case VANILLAKEY:
  1354. X            if( code == '\033' && (qual &
  1355. X                (IEQUALIFIER_LALT|IEQUALIFIER_RALT|
  1356. X                IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND) ) == 0 )
  1357. X            {
  1358. X            if( bufp )
  1359. X            {
  1360. X                bufp[0]='\033';
  1361. X                bufp[1]=0;
  1362. X            }
  1363. X            aredone = 1;
  1364. X            }
  1365. X            else
  1366. X            {
  1367. X            ActivateGadget( &String, cwin, NULL );
  1368. X            }
  1369. X            break;
  1370. X
  1371. X        case ACTIVEWINDOW:
  1372. X            ActivateGadget( &String, cwin, NULL );
  1373. X            break;
  1374. X
  1375. X        case GADGETUP:
  1376. X            switch( gd->GadgetID )
  1377. X            {
  1378. X            case 2:
  1379. X                aredone = 1;
  1380. X                if( bufp )
  1381. X                strcpy( bufp, StrString );
  1382. X                break;
  1383. X
  1384. X            case 1:
  1385. X                if( bufp )
  1386. X                {
  1387. X                bufp[0]='\033';
  1388. X                bufp[1]=0;
  1389. X                }
  1390. X                aredone = 1;
  1391. X                break;
  1392. X            }
  1393. X            break;
  1394. X
  1395. X        case CLOSEWINDOW:
  1396. X            if( bufp )
  1397. X            strcpy( bufp, StrString );
  1398. X            aredone = 1;
  1399. X            break;
  1400. X        }
  1401. X        ReplyMsg( (struct Message *) imsg );
  1402. X    }
  1403. X    }
  1404. X
  1405. X    CloseWindow( cwin );
  1406. X#else
  1407. X    struct WinDesc *cw;
  1408. X    struct Window *w;
  1409. X    int colx, ocolx, c;
  1410. X    char *obufp;
  1411. X
  1412. X    amii_clear_nhwindow( WIN_MESSAGE );
  1413. X    amii_putstr( WIN_MESSAGE, 0, prompt );
  1414. X    cw = wins[ WIN_MESSAGE ];
  1415. X    w = cw->win;
  1416. X    ocolx = colx = strlen( prompt ) + 1;
  1417. X
  1418. X    obufp = bufp;
  1419. X    while((c = WindowGetchar()) != EOF)
  1420. X    {
  1421. X    amii_curs( WIN_MESSAGE, colx, 0 );
  1422. X    if(c == '\033')
  1423. X    {
  1424. X        *obufp = c;
  1425. X        obufp[1] = 0;
  1426. X        return;
  1427. X    }
  1428. X    else if(c == '\b')
  1429. X    {
  1430. X        if(bufp != obufp)
  1431. X        {
  1432. X        bufp--;
  1433. X        amii_curs( WIN_MESSAGE, --colx, 0);
  1434. X        Text( w->RPort, "\177 ", 2 );
  1435. X        amii_curs( WIN_MESSAGE, colx, 0);
  1436. X        }
  1437. X        else
  1438. X        DisplayBeep( NULL );
  1439. X    }
  1440. X    else if( c == '\n' || c == '\r' )
  1441. X    {
  1442. X        *bufp = 0;
  1443. X        return;
  1444. X    }
  1445. X    else if(' ' <= c && c < '\177')
  1446. X    {
  1447. X        /* avoid isprint() - some people don't have it
  1448. X           ' ' is not always a printing char */
  1449. X        *bufp = c;
  1450. X        bufp[1] = 0;
  1451. X
  1452. X        Text( w->RPort, bufp, 1 );
  1453. X        Text( w->RPort, "\177", 1 );
  1454. X        if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
  1455. X        {
  1456. X        colx++;
  1457. X        bufp++;
  1458. X        }
  1459. X    }
  1460. X    else if(c == ('X'-64) || c == '\177')
  1461. X    {
  1462. X        amii_curs( WIN_MESSAGE, ocolx, 0 );
  1463. X        Text( w->RPort,
  1464. X        "                                                            ",
  1465. X        colx - ocolx );
  1466. X        amii_curs( WIN_MESSAGE, colx = ocolx, 0 );
  1467. X    } else
  1468. X        DisplayBeep( NULL );
  1469. X    }
  1470. X    *bufp = 0;
  1471. X#endif
  1472. X}
  1473. X
  1474. Xvoid amii_suspend_nhwindows( str )
  1475. X    char *str;
  1476. X{
  1477. X    if( HackScreen )
  1478. X    ScreenToBack( HackScreen );
  1479. X}
  1480. X
  1481. Xvoid amii_resume_nhwindows()
  1482. X{
  1483. X    if( HackScreen )
  1484. X    ScreenToFront( HackScreen );
  1485. X}
  1486. X
  1487. Xvoid amii_bell()
  1488. X{
  1489. X    DisplayBeep( NULL );
  1490. X}
  1491. X
  1492. X#define GADBLUEPEN      2
  1493. X#define GADREDPEN       3
  1494. X#define GADGREENPEN     4
  1495. X#define GADCOLOKAY      5
  1496. X#define GADCOLCANCEL    6
  1497. X
  1498. X#include "colorwin.c"
  1499. X
  1500. Xvoid
  1501. XEditColor()
  1502. X{
  1503. X    int i, done = 0, okay = 0;
  1504. X    long code, qual, class;
  1505. X    register struct Gadget *gd, *dgad;
  1506. X    register struct Window *nw;
  1507. X    register struct IntuiMessage *imsg;
  1508. X    register struct PropInfo *pip;
  1509. X    register struct Screen *scrn;
  1510. X    long aidx;
  1511. X    int msx, msy;
  1512. X    int curcol = 0, drag = 0;
  1513. X    int bxorx, bxory, bxxlen, bxylen;
  1514. X    UWORD colors[ 1L << DEPTH ];
  1515. X    static int once = 0;
  1516. X
  1517. X    bxylen = Col_NewWindowStructure1.Height -
  1518. X                ( Col_BluePen.TopEdge + Col_BluePen.Height + 6 );
  1519. X    bxxlen = Col_BluePen.Width;
  1520. X    bxorx = Col_BluePen.LeftEdge;
  1521. X    bxory = Col_BluePen.TopEdge + Col_BluePen.Height + 2;
  1522. X    scrn = HackScreen;
  1523. X
  1524. X    if( !once )
  1525. X    {
  1526. X    SetBorder( &Col_Okay );
  1527. X    SetBorder( &Col_Cancel );
  1528. X    once = 1;
  1529. X    }
  1530. X
  1531. X    for( i = 0; i < (1L << DEPTH); ++i )
  1532. X    {
  1533. X    colors[ i ] = GetRGB4( scrn->ViewPort.ColorMap, i );
  1534. X    }
  1535. X
  1536. X    Col_NewWindowStructure1.Screen = scrn;
  1537. X#ifdef  INTUI_NEW_LOOK
  1538. X    if( IntuitionBase->LibNode.lib_Version >= 37 )
  1539. X    {
  1540. X    ((struct PropInfo *)Col_BluePen.SpecialInfo)->Flags |= PROPNEWLOOK;
  1541. X    ((struct PropInfo *)Col_RedPen.SpecialInfo)->Flags |=  PROPNEWLOOK;
  1542. X    ((struct PropInfo *)Col_GreenPen.SpecialInfo)->Flags |= PROPNEWLOOK;
  1543. X    }
  1544. X#endif
  1545. X    nw = OpenWindow( (void *)&Col_NewWindowStructure1 );
  1546. X
  1547. X    DrawCol( nw, curcol, colors );
  1548. X    while( !done )
  1549. X    {
  1550. X    WaitPort( nw->UserPort );
  1551. X
  1552. X    while( imsg = (struct IntuiMessage * )GetMsg( nw->UserPort ) )
  1553. X    {
  1554. X        gd = (struct Gadget *)imsg->IAddress;
  1555. X        code = imsg->Code;
  1556. X        class = imsg->Class;
  1557. X        qual = imsg->Qualifier;
  1558. X        msx = imsg->MouseX;
  1559. X        msy = imsg->MouseY;
  1560. X
  1561. X        ReplyMsg( (struct Message *)imsg );
  1562. X
  1563. X        switch( class )
  1564. X        {
  1565. X        case VANILLAKEY:
  1566. X            if( code == 'v' && qual == AMIGALEFT )
  1567. X            okay = done = 1;
  1568. X            else if( code == 'b' && qual == AMIGALEFT )
  1569. X            okay = 0, done = 1;
  1570. X            else if( code == 'o' || code == 'O' )
  1571. X            okay = done = 1;
  1572. X            else if( code == 'c' || code == 'C' )
  1573. X            okay = 0, done = 1;
  1574. X            break;
  1575. X
  1576. X        case CLOSEWINDOW:
  1577. X            done = 1;
  1578. X            break;
  1579. X
  1580. X        case GADGETUP:
  1581. X            drag = 0;
  1582. X            if( gd->GadgetID == GADREDPEN ||
  1583. X                        gd->GadgetID == GADBLUEPEN ||
  1584. X                        gd->GadgetID == GADGREENPEN )
  1585. X            {
  1586. X            pip = (struct PropInfo *)gd->SpecialInfo;
  1587. X            aidx = pip->HorizPot / (MAXPOT/15);
  1588. X            aidx = aidx;
  1589. X            if( gd->GadgetID == GADREDPEN )
  1590. X            {
  1591. X                colors[ curcol ] =
  1592. X                ( colors[ curcol ] & ~0xf00 ) | (aidx << 8);
  1593. X                LoadRGB4( &scrn->ViewPort, colors, 1l << DEPTH );
  1594. X            }
  1595. X            else if( gd->GadgetID == GADBLUEPEN )
  1596. X            {
  1597. X                colors[ curcol ] =
  1598. X                    ( colors[ curcol ] & ~0xf ) | aidx;
  1599. X                LoadRGB4( &scrn->ViewPort, colors, 1l << DEPTH );
  1600. X            }
  1601. X            else if( gd->GadgetID == GADGREENPEN )
  1602. X            {
  1603. X                colors[ curcol ] =
  1604. X                ( colors[ curcol ] & ~0x0f0 ) | (aidx << 4);
  1605. X                LoadRGB4( &scrn->ViewPort, colors, 1l << DEPTH );
  1606. X            }
  1607. X            DispCol( nw, curcol, colors );
  1608. X            }
  1609. X            else if( gd->GadgetID == GADCOLOKAY )
  1610. X            {
  1611. X            done = 1;
  1612. X            okay = 1;
  1613. X            }
  1614. X            else if( gd->GadgetID == GADCOLCANCEL )
  1615. X            {
  1616. X            done = 1;
  1617. X            okay = 0;
  1618. X            }
  1619. X            break;
  1620. X
  1621. X        case GADGETDOWN:
  1622. X            drag = 1;
  1623. X            dgad = gd;
  1624. X            break;
  1625. X
  1626. X        case MOUSEMOVE:
  1627. X            if( !drag )
  1628. X            break;
  1629. X            pip = (struct PropInfo *)dgad->SpecialInfo;
  1630. X            aidx = pip->HorizPot / (MAXPOT/15);
  1631. X            aidx = aidx;
  1632. X            if( dgad->GadgetID == GADREDPEN )
  1633. X            {
  1634. X            colors[ curcol ] =
  1635. X                ( colors[ curcol ] & ~0xf00 ) | (aidx << 8);
  1636. X            LoadRGB4( &scrn->ViewPort, colors, 1l << DEPTH );
  1637. X            }
  1638. X            else if( dgad->GadgetID == GADBLUEPEN )
  1639. X            {
  1640. X            colors[ curcol ] = ( colors[ curcol ] & ~0xf ) | aidx;
  1641. X            LoadRGB4( &scrn->ViewPort, colors, 1l << DEPTH );
  1642. X            }
  1643. X            else if( dgad->GadgetID == GADGREENPEN )
  1644. X            {
  1645. X            colors[ curcol ] =
  1646. X                ( colors[ curcol ] & ~0x0f0 ) | (aidx << 4);
  1647. X            LoadRGB4( &scrn->ViewPort, colors, 1l << DEPTH );
  1648. X            }
  1649. X            DispCol( nw, curcol, colors );
  1650. X            break;
  1651. X
  1652. X        case MOUSEBUTTONS:
  1653. X            if( code == SELECTDOWN )
  1654. X            {
  1655. X            if( msy > bxory && msy < bxory + bxylen - 1 &&
  1656. X                msx > bxorx && msx < bxorx + bxxlen - 1 )
  1657. X            {
  1658. X                curcol = ( msx - bxorx )/(bxxlen / (1l << DEPTH));
  1659. X                DrawCol( nw, curcol, colors );
  1660. X            }
  1661. X            }
  1662. X            break;
  1663. X        }
  1664. X    }
  1665. X    }
  1666. X
  1667. X    if( okay )
  1668. X    {
  1669. X    for( i = 0; i < ( 1L << DEPTH ); ++i )
  1670. X        amii_curmap[ i ] = colors[ i ];
  1671. X    }
  1672. X
  1673. X    LoadRGB4( &scrn->ViewPort, amii_curmap, 1L << DEPTH );
  1674. X    CloseWindow( nw );
  1675. X}
  1676. X
  1677. X/* The colornames, and the default values for the pens */
  1678. Xstatic struct
  1679. X{
  1680. X    char *name, *defval;
  1681. X} colnames[] =
  1682. X{
  1683. X    "Black","(aaa)",
  1684. X    "White","(fff)",
  1685. X    "Brown","(620)",
  1686. X    "Cyan","(b08)",
  1687. X    "Green","(181)",
  1688. X    "Magenta","(c06)",
  1689. X    "Blue","(23e)",
  1690. X    "Red","(d00)",
  1691. X};
  1692. X
  1693. Xvoid
  1694. XDrawCol( w, idx, colors )
  1695. X    struct Window *w;
  1696. X    int idx;
  1697. X    UWORD *colors;
  1698. X{
  1699. X    int bxorx, bxory, bxxlen, bxylen;
  1700. X    int i, incx, incy, r, g, b;
  1701. X    long flags;
  1702. X
  1703. X    bxylen = Col_NewWindowStructure1.Height - Col_Okay.Height - 4 -
  1704. X            ( Col_BluePen.TopEdge + Col_BluePen.Height + 6 );
  1705. X    bxxlen = Col_BluePen.Width;
  1706. X    bxorx = Col_BluePen.LeftEdge;
  1707. X    bxory = Col_BluePen.TopEdge + Col_BluePen.Height + 2;
  1708. X
  1709. X    incx = bxxlen / (1L << DEPTH);
  1710. X    incy = bxylen - 2;
  1711. X
  1712. X    SetAPen( w->RPort, 1 );
  1713. X    SetBPen( w->RPort, 0 );
  1714. X    SetDrMd( w->RPort, JAM2 );
  1715. X    RectFill( w->RPort, bxorx, bxory, bxorx + bxxlen - 1, bxory + bxylen );
  1716. X    SetAPen( w->RPort, 0 );
  1717. X    RectFill( w->RPort, bxorx+2, bxory+1,
  1718. X                    bxorx + bxxlen - 4, bxory + bxylen - 1);
  1719. X
  1720. X    for( i = 0; i < (1L << DEPTH); ++i )
  1721. X    {
  1722. X    if( i == idx )
  1723. X        SetAPen( w->RPort, 1 );
  1724. X    else
  1725. X        SetAPen( w->RPort, 0 );
  1726. X    SetBPen( w->RPort, 0 );
  1727. X    SetDrMd( w->RPort, JAM2 );
  1728. X    RectFill( w->RPort, bxorx + 3 + (i*incx)+1, bxory + 2,
  1729. X                    bxorx + ((i+1)*incx)-2, bxory+bxylen - 2);
  1730. X
  1731. X    SetAPen( w->RPort, 0 );
  1732. X    SetBPen( w->RPort, 0 );
  1733. X    SetDrMd( w->RPort, JAM2 );
  1734. X    RectFill( w->RPort, bxorx + 3 + (i*incx)+2, bxory + 3,
  1735. X                    bxorx + ((i+1)*incx)-4, bxory+bxylen - 3);
  1736. X
  1737. X    SetAPen( w->RPort, i );
  1738. X    SetBPen( w->RPort, 0 );
  1739. X    SetDrMd( w->RPort, JAM2 );
  1740. X    RectFill( w->RPort, bxorx + 3 +(i*incx)+4, bxory + 4,
  1741. X                    bxorx + ((i+1)*incx)-6, bxory+bxylen - 4 );
  1742. X    }
  1743. X
  1744. X    DispCol( w, idx, colors );
  1745. X
  1746. X    r = (colors[ idx ] & 0xf00) >> 8;
  1747. X    g = (colors[ idx ] & 0x0f0) >> 4;
  1748. X    b = colors[ idx ] & 0x00f;
  1749. X
  1750. X    flags = AUTOKNOB|FREEHORIZ;
  1751. X#ifdef  INTUI_NEW_LOOK
  1752. X    if( IntuitionBase->LibNode.lib_Version >= 37 )
  1753. X    {
  1754. X    flags |= PROPNEWLOOK;
  1755. X    }
  1756. X#endif
  1757. X    NewModifyProp( &Col_RedPen, w, NULL, flags, (r * MAXPOT ) / 15, 0,
  1758. X                                MAXPOT/15, 0, 1 );
  1759. X    NewModifyProp( &Col_GreenPen, w, NULL, flags, (g * MAXPOT ) / 15, 0,
  1760. X                                MAXPOT/15, 0, 1 );
  1761. X    NewModifyProp( &Col_BluePen, w, NULL, flags, (b * MAXPOT ) / 15, 0,
  1762. X                                MAXPOT/15, 0, 1 );
  1763. X}
  1764. X
  1765. Xvoid
  1766. XDispCol( w, idx, colors )
  1767. X    struct Window *w;
  1768. X    int idx;
  1769. X    UWORD *colors;
  1770. X{
  1771. X    char buf[ 50 ];
  1772. X
  1773. X    Move( w->RPort, Col_Okay.LeftEdge + Col_Okay.Width +
  1774. X    txwidth, Col_Cancel.TopEdge + txbaseline + 2 );
  1775. X    sprintf( buf, "%s=%03x %s%s", colnames[idx].name, colors[idx],
  1776. X    colnames[idx].defval,
  1777. X    "        "+strlen(colnames[idx].name)+1 );
  1778. X    SetAPen( w->RPort, C_WHITE );
  1779. X    SetBPen( w->RPort, 0 );
  1780. X    SetDrMd( w->RPort, JAM2 );
  1781. X    Text( w->RPort, buf, strlen( buf ) );
  1782. X}
  1783. X
  1784. Xvoid
  1785. Xamii_setpens()
  1786. X{
  1787. X    /* If the pens are set in NetHack.cnf, we can get called before
  1788. X     * HackScreen has been opened...
  1789. X     */
  1790. X    if( HackScreen != NULL )
  1791. X    {
  1792. X    LoadRGB4( &HackScreen->ViewPort, amii_curmap, 1L << DEPTH );
  1793. X    }
  1794. X}
  1795. X
  1796. X/* Put a 3-D motif border around the gadget.  String gadgets or those
  1797. X * which do not have highlighting are rendered down.  Boolean gadgets
  1798. X * are rendered in the up position by default.
  1799. X */
  1800. X
  1801. Xvoid
  1802. XSetBorder( gd )
  1803. X    register struct Gadget *gd;
  1804. X{
  1805. X    register struct Border *bp;
  1806. X    register short *sp;
  1807. X    register int i, inc = -1, dec = -1;
  1808. X    int borders = 6;
  1809. X
  1810. X    /* Allocate two border structures one for up image and one for down
  1811. X     * image, plus vector arrays for the border lines.
  1812. X     */
  1813. X
  1814. X    if( gd->GadgetType == STRGADGET )
  1815. X    borders = 12;
  1816. X
  1817. X    if( ( bp = (struct Border *)alloc( ( ( sizeof( struct Border ) * 2 ) +
  1818. X            ( sizeof( short ) * borders ) ) * 2 ) ) == NULL )
  1819. X    {
  1820. X    return;
  1821. X    }
  1822. X
  1823. X    /* For a string gadget, we expand the border beyond the area where
  1824. X     * the text will be entered.
  1825. X     */
  1826. X
  1827. X    /* Remove any special rendering flags to avoid confusing intuition
  1828. X     */
  1829. X
  1830. X    gd->Flags &= ~(GADGHIGHBITS|GADGIMAGE);
  1831. X
  1832. X    sp = (short *)(bp + 4);
  1833. X    if( gd->GadgetType == STRGADGET || ( gd->GadgetType == BOOLGADGET &&
  1834. X                ( gd->Flags & GADGHIGHBITS ) == GADGHNONE ) )
  1835. X    {
  1836. X    sp[0] = -1;
  1837. X    sp[1] = gd->Height - 1;
  1838. X    sp[2] = -1;
  1839. X    sp[3] = -1;
  1840. X    sp[4] = gd->Width - 1;
  1841. X    sp[5] = -1;
  1842. X
  1843. X    sp[6] = gd->Width + 1;
  1844. X    sp[7] = -2;
  1845. X    sp[8] = gd->Width + 1;
  1846. X    sp[9] = gd->Height + 1;
  1847. X    sp[10] = -2;
  1848. X    sp[11] = gd->Height + 1;
  1849. X
  1850. X    sp[12] = -2;
  1851. X    sp[13] = gd->Height;
  1852. X    sp[14] = -2;
  1853. X    sp[15] = -2;
  1854. X    sp[16] = gd->Width;
  1855. X    sp[17] = -2;
  1856. X    sp[18] = gd->Width;
  1857. X    sp[19] = gd->Height;
  1858. X    sp[20] = -2;
  1859. X    sp[21] = gd->Height;
  1860. X
  1861. X    for( i = 0; i < 3; ++i )
  1862. X    {
  1863. X        bp[ i ].LeftEdge = bp[ i ].TopEdge = -1;
  1864. X        bp[ i ].FrontPen = ( i == 0 || i == 1 ) ? C_BROWN : C_WHITE;
  1865. X
  1866. X        /* Have to use JAM2 so that the old colors disappear. */
  1867. X        bp[ i ].BackPen = C_BLACK;
  1868. X        bp[ i ].DrawMode = JAM2;
  1869. X        bp[ i ].Count = ( i == 0 || i == 1 ) ? 3 : 5;
  1870. X        bp[ i ].XY = &sp[ i*6 ];
  1871. X        bp[ i ].NextBorder = ( i == 2 ) ? NULL : &bp[ i + 1 ];
  1872. X    }
  1873. X
  1874. X    /* bp[0] and bp[1] two pieces for the up image */
  1875. X    gd->GadgetRender = (APTR) bp;
  1876. X
  1877. X    /* No image change for select */
  1878. X    gd->SelectRender = (APTR) bp;
  1879. X
  1880. X    gd->LeftEdge++;
  1881. X    gd->TopEdge++;
  1882. X    gd->Flags |= GADGHCOMP;
  1883. X    }
  1884. X    else
  1885. X    {
  1886. X    /* Create the border vector values for up and left side, and
  1887. X     * also the lower and right side.
  1888. X     */
  1889. X
  1890. X    sp[0] = dec;
  1891. X    sp[1] = gd->Height + inc;
  1892. X    sp[2] = dec;
  1893. X    sp[3] = dec;
  1894. X    sp[4] = gd->Width + inc;
  1895. X    sp[5] = dec;
  1896. X
  1897. X    sp[6] = gd->Width + inc;
  1898. X    sp[7] = dec;
  1899. X    sp[8] = gd->Width + inc;
  1900. X    sp[9] = gd->Height + inc;
  1901. X    sp[10] = dec;
  1902. X    sp[11] = gd->Height + inc;
  1903. X
  1904. X    /* We are creating 4 sets of borders, the two sides of the
  1905. X     * rectangle share the border vectors with the opposite image,
  1906. X     * but specify different colors.
  1907. X     */
  1908. X
  1909. X    for( i = 0; i < 4; ++i )
  1910. X    {
  1911. X        bp[ i ].TopEdge = bp[ i ].LeftEdge = 0;
  1912. X
  1913. X        /* A GADGHNONE is always down */
  1914. X
  1915. X        if( gd->GadgetType == BOOLGADGET &&
  1916. X                ( gd->Flags & GADGHIGHBITS ) != GADGHNONE )
  1917. X        {
  1918. X        bp[ i ].FrontPen =
  1919. X                ( i == 1 || i == 2 ) ? C_BROWN : C_WHITE;
  1920. X        }
  1921. X        else
  1922. X        {
  1923. X        bp[ i ].FrontPen =
  1924. X                ( i == 1 || i == 3 ) ? C_WHITE : C_BROWN;
  1925. X        }
  1926. X
  1927. X        /* Have to use JAM2 so that the old colors disappear. */
  1928. X        bp[ i ].BackPen = C_BLACK;
  1929. X        bp[ i ].DrawMode = JAM2;
  1930. X        bp[ i ].Count = 3;
  1931. X        bp[ i ].XY = &sp[ 6 * ((i &1) != 0) ];
  1932. X        bp[ i ].NextBorder =
  1933. X                ( i == 1 || i == 3 ) ? NULL : &bp[ i + 1 ];
  1934. X    }
  1935. X
  1936. X    /* bp[0] and bp[1] two pieces for the up image */
  1937. X    gd->GadgetRender = (APTR) bp;
  1938. X
  1939. X    /* bp[2] and bp[3] two pieces for the down image */
  1940. X    gd->SelectRender = (APTR) (bp + 2);
  1941. X    gd->Flags |= GADGHIMAGE;
  1942. X    }
  1943. X}
  1944. X
  1945. X#ifdef  PORT_HELP
  1946. Xvoid
  1947. Xport_help()
  1948. X{
  1949. X    display_file( PORT_HELP, 1 );
  1950. X}
  1951. X#endif
  1952. X
  1953. X#endif /* AMIGA_INTUITION */
  1954. END_OF_FILE
  1955. if test 42959 -ne `wc -c <'sys/amiga/winami.c2'`; then
  1956.     echo shar: \"'sys/amiga/winami.c2'\" unpacked with wrong size!
  1957. fi
  1958. # end of 'sys/amiga/winami.c2'
  1959. fi
  1960. if test -f 'win/X11/winmisc.c' -a "${1}" != "-c" ; then 
  1961.   echo shar: Will not clobber existing file \"'win/X11/winmisc.c'\"
  1962. else
  1963. echo shar: Extracting \"'win/X11/winmisc.c'\" \(11918 characters\)
  1964. sed "s/^X//" >'win/X11/winmisc.c' <<'END_OF_FILE'
  1965. X/*    SCCS Id: @(#)winmisc.c    3.1    92/10/21    */
  1966. X/* Copyright (c) Dean Luick, 1992                  */
  1967. X/* NetHack may be freely redistributed.  See license for details. */
  1968. X
  1969. X/*
  1970. X * Misc. popup windows: player selection and extended commands.
  1971. X * 
  1972. X *     + Global functions: player_selection() and get_ext_cmd().
  1973. X */
  1974. X#include <X11/Intrinsic.h>
  1975. X#include <X11/StringDefs.h>
  1976. X#include <X11/Shell.h>
  1977. X#include <X11/Xaw/Command.h>
  1978. X#include <X11/Xaw/Form.h>
  1979. X#include <X11/Xaw/Label.h>
  1980. X#include <X11/Xaw/Cardinals.h>
  1981. X#include <X11/Xos.h>    /* for index() */
  1982. X
  1983. X#include "hack.h"
  1984. X#include "func_tab.h"
  1985. X#include "winX.h"
  1986. X
  1987. Xextern const char *roles[];    /* from u_init.c */
  1988. X
  1989. Xstatic Widget extended_command_popup;
  1990. Xstatic Widget extended_command_form;
  1991. Xstatic int extended_command_selected;    /* index of the selected command; */
  1992. Xstatic int ps_selected;            /* index of selected role */
  1993. X#define PS_RANDOM (-50)
  1994. X#define PS_QUIT   (-75)
  1995. X
  1996. Xstatic const char extended_command_translations[] =
  1997. X    "#override\n\
  1998. X     <Key>: ec_key()";
  1999. X
  2000. Xstatic const char player_select_translations[] =
  2001. X    "#override\n\
  2002. X     <Key>: ps_key()";
  2003. X
  2004. X
  2005. Xstatic Widget make_menu();
  2006. X
  2007. X
  2008. X/* Player Selection -------------------------------------------------------- */
  2009. X/* ARGSUSED */
  2010. Xstatic void
  2011. Xps_quit(w, client_data, call_data)
  2012. X    Widget w;
  2013. X    XtPointer client_data, call_data;
  2014. X{
  2015. X    ps_selected = PS_QUIT;
  2016. X    exit_x_event = TRUE;        /* leave event loop */
  2017. X}
  2018. X
  2019. X/* ARGSUSED */
  2020. Xstatic void
  2021. Xps_random(w, client_data, call_data)
  2022. X    Widget w;
  2023. X    XtPointer client_data, call_data;
  2024. X{
  2025. X    ps_selected = PS_RANDOM;
  2026. X    exit_x_event = TRUE;        /* leave event loop */
  2027. X}
  2028. X
  2029. X/* ARGSUSED */
  2030. Xstatic void
  2031. Xps_select(w, client_data, call_data)
  2032. X    Widget w;
  2033. X    XtPointer client_data, call_data;
  2034. X{
  2035. X    ps_selected = (int) client_data;
  2036. X    exit_x_event = TRUE;        /* leave event loop */
  2037. X}
  2038. X
  2039. X/* ARGSUSED */
  2040. Xvoid
  2041. Xps_key(w, event, params, num_params)
  2042. X    Widget w;
  2043. X    XEvent *event;
  2044. X    String *params;
  2045. X    Cardinal *num_params;
  2046. X{
  2047. X    char ch, *mark;
  2048. X
  2049. X    ch = key_event_to_char((XKeyEvent *) event);
  2050. X    if (ch == '\0') {    /* don't accept nul char/modifier event */
  2051. X    /* don't beep */
  2052. X    return;
  2053. X    }
  2054. X    mark = index(pl_classes, highc(ch));
  2055. X    if (!mark) {
  2056. X    X11_nhbell();        /* no such class */
  2057. X    return;
  2058. X    }
  2059. X    ps_selected = mark - pl_classes;
  2060. X    exit_x_event = TRUE;
  2061. X}
  2062. X
  2063. X
  2064. X/* Global functions ========================================================= */
  2065. Xvoid
  2066. XX11_player_selection()
  2067. X{
  2068. X    char buf[QBUFSZ];
  2069. X    char pc;
  2070. X    int num_roles;
  2071. X    Widget popup, player_form;
  2072. X
  2073. X    if ((pc = highc(pl_character[0])) != 0) {
  2074. X    if (index(pl_classes, pc)) goto got_suffix;
  2075. X    pl_character[0] = pc = 0;
  2076. X    }
  2077. X
  2078. X    for (num_roles = 0; roles[num_roles]; num_roles++)
  2079. X    ;    /* do nothing */
  2080. X
  2081. X    popup = make_menu("player_selection", "Choose a Role",
  2082. X        player_select_translations,
  2083. X        "quit", ps_quit,
  2084. X        "random", ps_random,
  2085. X        num_roles, roles, ps_select, &player_form);
  2086. X
  2087. X    ps_selected = 0;
  2088. X    positionpopup(popup);
  2089. X    nh_XtPopup(popup, XtGrabExclusive, player_form);
  2090. X
  2091. X    /* The callbacks will enable the event loop exit. */
  2092. X    (void) x_event(EXIT_ON_EXIT);
  2093. X
  2094. X    nh_XtPopdown(popup);
  2095. X    XtDestroyWidget(popup);
  2096. X
  2097. X    if (ps_selected == PS_QUIT) {
  2098. X    clearlocks();
  2099. X    X11_exit_nhwindows(NULL);
  2100. X    terminate(0);
  2101. X    }
  2102. X
  2103. X    if (ps_selected == PS_RANDOM) {
  2104. X    winid tmpwin;
  2105. X
  2106. X    ps_selected = rn2(strlen(pl_classes));
  2107. X    pc = pl_classes[ps_selected];
  2108. X    Sprintf(buf, "This game you will be %s.", an(roles[ps_selected]));
  2109. X
  2110. X    tmpwin = X11_create_nhwindow(NHW_TEXT);
  2111. X    X11_putstr(tmpwin, 0, "");
  2112. X    X11_putstr(tmpwin, 0, buf);
  2113. X    X11_putstr(tmpwin, 0, "");
  2114. X    X11_display_nhwindow(tmpwin, TRUE);
  2115. X    X11_destroy_nhwindow(tmpwin);
  2116. X
  2117. X    } else if (ps_selected < 0 || ps_selected >= num_roles) {
  2118. X    panic("player_selection: bad select value %d\n", ps_selected);
  2119. X    } else {
  2120. X    pc = pl_classes[ps_selected];
  2121. X    }
  2122. X
  2123. Xgot_suffix:
  2124. X    pl_character[0] = pc;
  2125. X}
  2126. X
  2127. X
  2128. Xvoid
  2129. XX11_get_ext_cmd(input)
  2130. X    char *input;
  2131. X{
  2132. X    extended_command_selected = -1;        /* reset selected value */
  2133. X
  2134. X    positionpopup(extended_command_popup);    /* center on cursor */
  2135. X    nh_XtPopup(extended_command_popup, XtGrabExclusive, extended_command_form);
  2136. X
  2137. X    /* The callbacks will enable the event loop exit. */
  2138. X    (void) x_event(EXIT_ON_EXIT);
  2139. X
  2140. X    if (extended_command_selected < 0)
  2141. X    *input = '\0';
  2142. X    else
  2143. X    Strcpy(input, extcmdlist[extended_command_selected].ef_txt);
  2144. X}
  2145. X
  2146. X/* End global functions ===================================================== */
  2147. X
  2148. X/* Extended Command -------------------------------------------------------- */
  2149. X/* ARGSUSED */
  2150. Xstatic void
  2151. Xextend_select(w, client_data, call_data)
  2152. X    Widget w;
  2153. X    XtPointer client_data, call_data;
  2154. X{
  2155. X    extended_command_selected = (int) client_data;
  2156. X    nh_XtPopdown(extended_command_popup);
  2157. X    exit_x_event = TRUE;        /* leave event loop */
  2158. X}
  2159. X
  2160. X/* ARGSUSED */
  2161. Xstatic void
  2162. Xextend_dismiss(w, client_data, call_data)
  2163. X    Widget w;
  2164. X    XtPointer client_data, call_data;
  2165. X{
  2166. X    extended_command_selected = -1;    /* dismiss */
  2167. X    nh_XtPopdown(extended_command_popup);
  2168. X    exit_x_event = TRUE;        /* leave event loop */
  2169. X}
  2170. X
  2171. X/* ARGSUSED */
  2172. Xstatic void
  2173. Xextend_help(w, client_data, call_data)
  2174. X    Widget w;
  2175. X    XtPointer client_data, call_data;
  2176. X{
  2177. X    /* We might need to make it known that we already have one listed. */
  2178. X    (void) doextlist();
  2179. X}
  2180. X
  2181. X/* ARGSUSED */
  2182. Xvoid
  2183. Xec_key(w, event, params, num_params)
  2184. X    Widget w;
  2185. X    XEvent *event;
  2186. X    String *params;
  2187. X    Cardinal *num_params;
  2188. X{
  2189. X    char ch;
  2190. X    int i, mark;
  2191. X
  2192. X    ch = key_event_to_char((XKeyEvent *) event);
  2193. X
  2194. X    if (ch == '\0') {    /* don't accept nul char/modifier event */
  2195. X    /* don't beep */
  2196. X    return;
  2197. X    }
  2198. X    if (index(quitchars, ch)) {
  2199. X    extended_command_selected = -1;    /* dismiss */
  2200. X    goto ec_key_done;
  2201. X    }
  2202. X
  2203. X    /*
  2204. X     * Note: this depends on the fact that the help option "?" is known
  2205. X     * to be last and not counted.
  2206. X     */
  2207. X    for (mark = -1, i = 0; extcmdlist[i].ef_txt; i++) {
  2208. X    if (extcmdlist[i].ef_txt[0] == '?') continue;
  2209. X
  2210. X    if (ch == extcmdlist[i].ef_txt[0]) {
  2211. X        if (mark != -1) {
  2212. X        X11_nhbell(); /* another command with the same first letter */
  2213. X        return;
  2214. X        }
  2215. X        mark = i;
  2216. X    }
  2217. X    }
  2218. X    if (mark == -1) {
  2219. X    X11_nhbell();
  2220. X    return;
  2221. X    }
  2222. X
  2223. X    /*
  2224. X     * It would be nice if we could set the selected command before
  2225. X     * we pop the window down....  Maybe when I figure out how to do
  2226. X     * it.
  2227. X     */
  2228. X    extended_command_selected = mark;
  2229. Xec_key_done:
  2230. X    nh_XtPopdown(extended_command_popup);
  2231. X    exit_x_event = TRUE;        /* leave event loop */
  2232. X}
  2233. X
  2234. X/*
  2235. X * Use our own home-brewed version menu because simpleMenu is designed to
  2236. X * be used from a menubox.
  2237. X */
  2238. Xvoid
  2239. Xinit_extended_commands_popup()
  2240. X{
  2241. X    int i, num_commands;
  2242. X    const char **command_list;
  2243. X
  2244. X    /* count commands */
  2245. X    for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++)
  2246. X    ;    /* do nothing */
  2247. X
  2248. X    /* If the last entry is "help", don't use it. */
  2249. X    if (strcmp(extcmdlist[num_commands-1].ef_txt, "?") == 0)
  2250. X    --num_commands;
  2251. X
  2252. X    command_list = (const char **) alloc(num_commands * sizeof(char *));
  2253. X
  2254. X    for (i = 0; i < num_commands; i++)
  2255. X    command_list[i] = extcmdlist[i].ef_txt;
  2256. X
  2257. X    extended_command_popup = make_menu("extended_commands",
  2258. X                "Extended Commands",
  2259. X                extended_command_translations,
  2260. X                "dismiss", extend_dismiss,
  2261. X                "help", extend_help,
  2262. X                num_commands, command_list, extend_select,
  2263. X                &extended_command_form);
  2264. X
  2265. X    free((char *)command_list);
  2266. X}
  2267. X
  2268. X/* ------------------------------------------------------------------------- */
  2269. X
  2270. X/*
  2271. X * Create a popup widget of the following form:
  2272. X * 
  2273. X *              popup_label
  2274. X *        ----------- ------------
  2275. X *         |left_name| |right_name|
  2276. X *        ----------- ------------
  2277. X *        ------------------------
  2278. X *        |    name1           |
  2279. X *        ------------------------
  2280. X *        ------------------------
  2281. X *        |    name2           |
  2282. X *        ------------------------
  2283. X *              .
  2284. X *              .
  2285. X *        ------------------------
  2286. X *        |    nameN           |
  2287. X *        ------------------------
  2288. X */
  2289. Xstatic Widget
  2290. Xmake_menu(popup_name, popup_label, popup_translations,
  2291. X        left_name, left_callback,
  2292. X        right_name, right_callback,
  2293. X        num_names, widget_names, name_callback, formp)
  2294. X    char       *popup_name;
  2295. X    char       *popup_label;
  2296. X    String       popup_translations;
  2297. X    char       *left_name;
  2298. X    XtCallbackProc left_callback;
  2299. X    char       *right_name;
  2300. X    XtCallbackProc right_callback;
  2301. X    int           num_names;
  2302. X    char       **widget_names;
  2303. X    XtCallbackProc name_callback;
  2304. X    Widget       *formp;    /* return */
  2305. X{
  2306. X    Widget popup, form, label, above, left, right;
  2307. X    Widget *commands, *curr;
  2308. X    int i;
  2309. X    Arg args[8];
  2310. X    Cardinal num_args;
  2311. X    Dimension width, max_width;
  2312. X    int distance, skip;
  2313. X
  2314. X
  2315. X    commands = (Widget *) alloc(num_names * sizeof(Widget));
  2316. X
  2317. X
  2318. X    num_args = 0;
  2319. X    XtSetArg(args[num_args], XtNallowShellResize, True);    num_args++;
  2320. X
  2321. X    popup = XtCreatePopupShell(popup_name,
  2322. X                transientShellWidgetClass,
  2323. X                toplevel, args, num_args);
  2324. X
  2325. X    num_args = 0;
  2326. X    XtSetArg(args[num_args], XtNtranslations,
  2327. X        XtParseTranslationTable(popup_translations));    num_args++;
  2328. X    *formp = form = XtCreateManagedWidget("menuform",
  2329. X                formWidgetClass,
  2330. X                popup,
  2331. X                args, num_args);
  2332. X
  2333. X    /* Get the default distance between objects in the form widget. */
  2334. X    num_args = 0;
  2335. X    XtSetArg(args[num_args], XtNdefaultDistance, &distance);    num_args++;
  2336. X    XtGetValues(form, args, num_args);
  2337. X
  2338. X    /*
  2339. X     * Create the label.
  2340. X     */
  2341. X    num_args = 0;
  2342. X    XtSetArg(args[num_args], XtNborderWidth, 0);    num_args++;
  2343. X    label = XtCreateManagedWidget(popup_label,
  2344. X                labelWidgetClass,
  2345. X                form,
  2346. X                args, num_args);
  2347. X
  2348. X    /*
  2349. X     * Create the left button.
  2350. X     */
  2351. X    num_args = 0;
  2352. X    XtSetArg(args[num_args], XtNfromVert, label);        num_args++;
  2353. X/*
  2354. X    XtSetArg(args[num_args], XtNshapeStyle,
  2355. X                XmuShapeRoundedRectangle);    num_args++;
  2356. X*/
  2357. X    left = XtCreateManagedWidget(left_name,
  2358. X            commandWidgetClass,
  2359. X            form,
  2360. X            args, num_args);
  2361. X    XtAddCallback(left, XtNcallback, left_callback, (XtPointer) 0);
  2362. X    skip = 3*distance;    /* triple the spacing */
  2363. X    if(!skip) skip = 3;
  2364. X
  2365. X    /*
  2366. X     * Create right button.
  2367. X     */
  2368. X    num_args = 0;
  2369. X    XtSetArg(args[num_args], XtNfromHoriz, left);        num_args++;
  2370. X    XtSetArg(args[num_args], XtNfromVert, label);        num_args++;
  2371. X/*
  2372. X    XtSetArg(args[num_args], XtNshapeStyle,
  2373. X                XmuShapeRoundedRectangle);    num_args++;
  2374. X*/
  2375. X    right = XtCreateManagedWidget(right_name,
  2376. X            commandWidgetClass,
  2377. X            form,
  2378. X            args, num_args);
  2379. X    XtAddCallback(right, XtNcallback, right_callback, (XtPointer) 0);
  2380. X
  2381. X
  2382. X    /*
  2383. X     * Create and place the command widgets.
  2384. X     */
  2385. X    for (i = 0, above = left, curr = commands; i < num_names;
  2386. X                    i++, above = *curr, curr++) {
  2387. X    num_args = 0;
  2388. X    XtSetArg(args[num_args], XtNfromVert, above);    num_args++;
  2389. X    if (i == 0) {
  2390. X        /* if first, we are farther apart */
  2391. X        XtSetArg(args[num_args], XtNvertDistance, skip);    num_args++;
  2392. X    }
  2393. X
  2394. X    *curr = XtCreateManagedWidget(widget_names[i],
  2395. X            commandWidgetClass,
  2396. X            form,
  2397. X            args, num_args);
  2398. X    XtAddCallback(*curr, XtNcallback, name_callback, (XtPointer) i);
  2399. X    }
  2400. X
  2401. X    /*
  2402. X     * Now find the largest width.  Start with the width dismiss + help
  2403. X     * buttons, since they are adjacent.
  2404. X     */
  2405. X    XtSetArg(args[0], XtNwidth, &max_width);
  2406. X    XtGetValues(left, args, ONE);
  2407. X    XtSetArg(args[0], XtNwidth, &width);
  2408. X    XtGetValues(right, args, ONE);
  2409. X    max_width = max_width + width + distance;
  2410. X
  2411. X    /* Next, the title. */
  2412. X    XtSetArg(args[0], XtNwidth, &width);
  2413. X    XtGetValues(label, args, ONE);
  2414. X    if (width > max_width) max_width = width;
  2415. X
  2416. X    /* Finally, the commands. */
  2417. X    for (i = 0, curr = commands; i < num_names; i++, curr++) {
  2418. X    XtSetArg(args[0], XtNwidth, &width);
  2419. X    XtGetValues(*curr, args, ONE);
  2420. X    if (width > max_width) max_width = width;
  2421. X    }
  2422. X
  2423. X    /*
  2424. X     * Finally, set all of the single line widgets to the largest width.
  2425. X     */
  2426. X    XtSetArg(args[0], XtNwidth, max_width);
  2427. X    XtSetValues(label, args, ONE);
  2428. X
  2429. X    for (i = 0, curr = commands; i < num_names; i++, curr++) {
  2430. X    XtSetArg(args[0], XtNwidth, max_width);
  2431. X    XtSetValues(*curr, args, ONE);
  2432. X    }
  2433. X
  2434. X    free((char *) commands);
  2435. X
  2436. X    XtRealizeWidget(popup);
  2437. X
  2438. X    return popup;
  2439. X}
  2440. END_OF_FILE
  2441. if test 11918 -ne `wc -c <'win/X11/winmisc.c'`; then
  2442.     echo shar: \"'win/X11/winmisc.c'\" unpacked with wrong size!
  2443. fi
  2444. # end of 'win/X11/winmisc.c'
  2445. fi
  2446. echo shar: End of archive 24 \(of 108\).
  2447. cp /dev/null ark24isdone
  2448. MISSING=""
  2449. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2450. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2451. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2452. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2453. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2454. 101 102 103 104 105 106 107 108 ; do
  2455.     if test ! -f ark${I}isdone ; then
  2456.     MISSING="${MISSING} ${I}"
  2457.     fi
  2458. done
  2459. if test "${MISSING}" = "" ; then
  2460.     echo You have unpacked all 108 archives.
  2461.     echo "Now execute 'rebuild.sh'"
  2462.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2463. else
  2464.     echo You still need to unpack the following archives:
  2465.     echo "        " ${MISSING}
  2466. fi
  2467. ##  End of shell archive.
  2468. exit 0
  2469.