1 /*    SCCS Id: @(#)winfuncs.c    3.1    2000/01/12 */
2 /* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993,1996. */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include "NH:sys/amiga/windefs.h"
6 #include "NH:sys/amiga/winext.h"
7 #include "NH:sys/amiga/winproto.h"
8 #include "patchlevel.h"
9 
10 extern struct TagItem scrntags[];
11 
12 static BitMapHeader amii_bmhd;
13 static void cursor_common(struct RastPort *, int, int);
14 
15 #ifdef	CLIPPING
16 int CO, LI;
17 
18 /* Changing clipping region, skip clear of screen in overview window. */
19 int reclip;
20 
21 /* Must be set to at least two or you will get stuck! */
22 int xclipbord = 4, yclipbord = 2;
23 #endif
24 
25 int mxsize, mysize;
26 struct Rectangle amii_oldover;
27 struct Rectangle amii_oldmsg;
28 
29 int amii_msgAPen;
30 int amii_msgBPen;
31 int amii_statAPen;
32 int amii_statBPen;
33 int amii_menuAPen;
34 int amii_menuBPen;
35 int amii_textAPen;
36 int amii_textBPen;
37 int amii_otherAPen;
38 int amii_otherBPen;
39 long amii_libvers = LIBRARY_FONT_VERSION;
40 
41 void
ami_wininit_data(void)42 ami_wininit_data( void )
43 {
44     extern unsigned short amii_init_map[ AMII_MAXCOLORS ];
45     extern unsigned short amiv_init_map[ AMII_MAXCOLORS ];
46     if( !WINVERS_AMIV )
47     {
48 # ifdef	TEXTCOLOR
49 	amii_numcolors = 8;
50 # else
51 	amii_numcolors = 4;
52 # endif
53 	amii_defpens[ 0 ] = C_BLACK;	/* DETAILPEN        */
54 	amii_defpens[ 1 ] = C_BLUE; 	/* BLOCKPEN         */
55 	amii_defpens[ 2 ] = C_BROWN;	/* TEXTPEN          */
56 	amii_defpens[ 3 ] = C_WHITE;	/* SHINEPEN         */
57 	amii_defpens[ 4 ] = C_BLUE;	/* SHADOWPEN        */
58 	amii_defpens[ 5 ] = C_CYAN;	/* FILLPEN          */
59 	amii_defpens[ 6 ] = C_WHITE;	/* FILLTEXTPEN      */
60 	amii_defpens[ 7 ] = C_CYAN;	/* BACKGROUNDPEN    */
61 	amii_defpens[ 8 ] = C_RED;	/* HIGHLIGHTTEXTPEN */
62 	amii_defpens[ 9 ] = C_WHITE;	/* BARDETAILPEN     */
63 	amii_defpens[ 10 ] = C_CYAN;	/* BARBLOCKPEN      */
64 	amii_defpens[ 11 ] = C_BLUE;	/* BARTRIMPEN       */
65 	amii_defpens[ 12 ] = (unsigned short) ~0;
66 
67 	amii_msgAPen = C_WHITE;
68 	amii_msgBPen = C_BLACK;
69 	amii_statAPen = C_WHITE;
70 	amii_statBPen = C_BLACK;
71 	amii_menuAPen = C_WHITE;
72 	amii_menuBPen = C_BLACK;
73 	amii_textAPen = C_WHITE;
74 	amii_textBPen = C_BLACK;
75 	amii_otherAPen = C_RED;
76 	amii_otherBPen = C_BLACK;
77 
78 	mxsize = 8;
79 	mysize = 8;
80 
81 	amii_libvers = LIBRARY_FONT_VERSION;
82 	memcpy( amii_initmap, amii_init_map, sizeof( amii_initmap ) );
83     }
84     else
85     {
86 	mxsize = 16;
87 	mysize = 16;
88 
89 	amii_numcolors = 16;
90 
91 	amii_defpens[ 0 ] = C_BLACK;	/* DETAILPEN        */
92 	amii_defpens[ 1 ] = C_WHITE;	/* BLOCKPEN         */
93 	amii_defpens[ 2 ] = C_BLACK;	/* TEXTPEN          */
94 	amii_defpens[ 3 ] = C_CYAN;	/* SHINEPEN         */
95 	amii_defpens[ 4 ] = C_BLUE;	/* SHADOWPEN        */
96 	amii_defpens[ 5 ] = C_GREYBLUE;	/* FILLPEN          */
97 	amii_defpens[ 6 ] = C_LTGREY;	/* FILLTEXTPEN      */
98 	amii_defpens[ 7 ] = C_GREYBLUE;	/* BACKGROUNDPEN    */
99 	amii_defpens[ 8 ] = C_RED;	/* HIGHLIGHTTEXTPEN */
100 	amii_defpens[ 9 ] = C_WHITE;	/* BARDETAILPEN     */
101 	amii_defpens[ 10] = C_GREYBLUE;	/* BARBLOCKPEN      */
102 	amii_defpens[ 11] = C_BLUE;	/* BARTRIMPEN       */
103 	amii_defpens[ 12] = (unsigned short) ~0;
104 
105 	amii_msgAPen = C_WHITE;
106 	amii_msgBPen = C_GREYBLUE;
107 	amii_statAPen = C_WHITE;
108 	amii_statBPen = C_GREYBLUE;
109 	amii_menuAPen = C_BLACK;
110 	amii_menuBPen = C_LTGREY;
111 	amii_textAPen = C_BLACK;
112 	amii_textBPen = C_LTGREY;
113 	amii_otherAPen = C_RED;
114 	amii_otherBPen = C_BLACK;
115 	amii_libvers = LIBRARY_TILE_VERSION;
116 
117 	memcpy( amii_initmap, amiv_init_map, sizeof( amii_initmap ) );
118     }
119 #ifdef OPT_DISPMAP
120     dispmap_sanity();
121 #endif
122     memcpy(flags.amii_dripens,amii_defpens,sizeof(flags.amii_dripens));
123 }
124 
125 # ifdef	INTUI_NEW_LOOK
126 struct Hook fillhook;
127 struct TagItem wintags[] =
128 {
129 	{ WA_BackFill, (ULONG)&fillhook },
130 	{ TAG_END, 0 },
131 };
132 # endif
133 
134 void
amii_destroy_nhwindow(win)135 amii_destroy_nhwindow(win)      /* just hide */
136     register winid win;
137 {
138     int i;
139     int type;
140     register struct amii_WinDesc *cw;
141 
142     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
143     {
144 	panic(winpanicstr,win,"destroy_nhwindow");
145     }
146 
147     if( WINVERS_AMIV )
148     {
149 	if( cw->type == NHW_MAP )
150 	{
151 	    /* If inventory is up, close it now, it will be freed later */
152 	    if( alwaysinvent && WIN_INVEN != WIN_ERR &&
153 				amii_wins[ WIN_INVEN ] &&
154 				amii_wins[ WIN_INVEN ]->win )
155 	    {
156 		dismiss_nhwindow( WIN_INVEN );
157 	    }
158 
159 	    /* Tear down overview window if it is up */
160 	    if( WIN_OVER != WIN_ERR )
161 	    {
162 		amii_destroy_nhwindow( WIN_OVER );
163 		WIN_OVER = WIN_ERR;
164 	    }
165 	}
166 	else if( cw->type == NHW_OVER )
167 	{
168 	    struct Window *w = amii_wins[ WIN_OVER ]->win;
169 	    amii_oldover.MinX = w->LeftEdge;
170 	    amii_oldover.MinY = w->TopEdge;
171 	    amii_oldover.MaxX = w->Width;
172 	    amii_oldover.MaxY = w->Height;
173 
174 	    if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
175 	    {
176 		w = amii_wins[ WIN_MESSAGE ]->win;
177 		amii_oldmsg.MinX = w->LeftEdge;
178 		amii_oldmsg.MinY = w->TopEdge;
179 		amii_oldmsg.MaxX = w->Width;
180 		amii_oldmsg.MaxY = w->Height;
181 		SizeWindow( amii_wins[ WIN_MESSAGE ]->win,
182 			(amiIDisplay->xpix -
183 			amii_wins[ WIN_MESSAGE ]->win->LeftEdge) -
184 			amii_wins[ WIN_MESSAGE ]->win->Width,
185 			0 );
186 	    }
187 	}
188     }
189 
190     /* Tear down the Intuition stuff */
191     dismiss_nhwindow(win);
192     type = cw->type;
193 
194     if( cw->resp )    free( cw->resp );
195     if( cw->canresp ) free( cw->canresp );
196     if( cw->morestr ) free( cw->morestr );
197     if( cw->hook ) free( cw->hook );
198     cw->hook = NULL;
199 
200     if( cw->data && ( cw->type == NHW_MESSAGE ||
201 			    cw->type == NHW_MENU || cw->type == NHW_TEXT ) )
202     {
203 	for( i = 0; i < cw->maxrow; ++i )
204 	{
205 	    if( cw->data[ i ] )
206 		free( cw->data[ i ] );
207 	}
208 	free( cw->data );
209     }
210 
211     free( cw );
212     amii_wins[win] = NULL;
213 
214     /* Set globals to WIN_ERR for known one-of-a-kind windows. */
215     if( win == WIN_MAP) WIN_MAP = WIN_ERR;
216     else if( win == WIN_STATUS) WIN_STATUS = WIN_ERR;
217     else if( win == WIN_MESSAGE) WIN_MESSAGE = WIN_ERR;
218     else if( win == WIN_INVEN) WIN_INVEN = WIN_ERR;
219 
220 }
221 
222 #ifdef INTUI_NEW_LOOK
223 struct FillParams
224 {
225 	struct Layer *layer;
226 	struct Rectangle bounds;
227 	WORD offsetx;
228 	WORD offsety;
229 };
230 
231 void
232 #ifndef _DCC
233 __interrupt
234 #endif
235 __saveds __asm
LayerFillHook(register __a0 struct Hook * hk,register __a2 struct RastPort * rp,register __a1 struct FillParams * fp)236 LayerFillHook(
237     register __a0 struct Hook *hk,
238     register __a2 struct RastPort *rp,
239     register __a1 struct FillParams *fp )
240 {
241     register long x, y, xmax, ymax;
242     register int apen;
243     struct RastPort rptmp;
244 
245     memcpy(&rptmp, rp, sizeof(struct RastPort));
246     rptmp.Layer = NULL;
247 
248     switch( (int)hk->h_Data )
249     {
250     case NHW_STATUS:
251 	apen = amii_statBPen;
252 	break;
253     case NHW_MESSAGE:
254 	apen = amii_msgBPen;
255 	break;
256     case NHW_TEXT:
257 	apen = amii_textBPen;
258 	break;
259     case NHW_MENU:
260 	apen = amii_menuBPen;
261 	break;
262     case -2:
263 	apen = amii_otherBPen;
264 	break;
265     case NHW_BASE:
266     case NHW_MAP:
267     case NHW_OVER:
268     default:
269 	apen = C_BLACK;
270 	break;
271     }
272 
273     x = fp->bounds.MinX;
274     y = fp->bounds.MinY;
275     xmax = fp->bounds.MaxX;
276     ymax = fp->bounds.MaxY;
277 
278     SetAPen(&rptmp, apen);
279     SetBPen(&rptmp, apen);
280     SetDrMd(&rptmp, JAM2);
281     RectFill(&rptmp, x, y, xmax, ymax);
282 }
283 #endif
284 
285 
amii_create_nhwindow(type)286 amii_create_nhwindow(type)
287     register int type;
288 {
289     register struct Window *w = NULL;
290     register struct NewWindow *nw = NULL;
291     register struct amii_WinDesc *wd = NULL;
292     struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL;
293     register int newid;
294     int maph, stath, scrfontysize;
295 
296     scrfontysize = HackScreen->Font->ta_YSize;
297 
298     /*
299      * Initial mapwindow height, this might change later in tilemode
300      * and low screen
301      */
302     maph = ( 21 * mxsize ) + 2 + (bigscreen ?
303 	HackScreen->WBorTop + HackScreen->WBorBottom + scrfontysize + 1 : 0);
304 
305     /* Status window height, avoids having to calculate many times */
306     stath = txheight * 2 + 2 + (WINVERS_AMIV || bigscreen ?
307 	HackScreen->WBorTop + HackScreen->WBorBottom +
308 	( bigscreen ? scrfontysize + 1 : 0 ) : 0);
309 
310     if( WIN_STATUS != WIN_ERR && amii_wins[ WIN_STATUS ] )
311 	stwin = amii_wins[ WIN_STATUS ]->win;
312 
313     if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
314 	msgwin = amii_wins[ WIN_MESSAGE ]->win;
315 
316     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
317 	mapwin = amii_wins[ WIN_MAP ]->win;
318 
319     /* Create Port anytime that we need it */
320 
321     if( HackPort == NULL )
322     {
323 	HackPort = CreatePort( NULL, 0 );
324 	if( !HackPort )
325 	    panic( "no memory for msg port" );
326     }
327 
328     nw = &new_wins[ type ].newwin;
329     nw->Width = amiIDisplay->xpix;
330     nw->Screen = HackScreen;
331 
332     if( WINVERS_AMIV )
333     {
334 	nw->DetailPen = C_WHITE;
335 	nw->BlockPen = C_GREYBLUE;
336     }
337     else
338     {
339 	nw->DetailPen = C_WHITE;
340 	nw->BlockPen = C_BLACK;
341     }
342 
343     if ( type == NHW_BASE ) {
344 	nw->LeftEdge = 0;
345 	nw->TopEdge = HackScreen->BarHeight+1;
346 	nw->Width = HackScreen->Width;
347 	nw->Height = HackScreen->Height - nw->TopEdge;
348     } else if( !WINVERS_AMIV && type == NHW_MAP ) {
349 	nw->LeftEdge = 0;
350 	nw->Height = maph;
351 
352 	if( msgwin && stwin ) {
353 	    nw->TopEdge = stwin->TopEdge - maph;
354 	} else {
355 	    panic( "msgwin and stwin must open before map" );
356 	}
357 	if (nw->TopEdge < 0)
358 	    panic( "Too small screen to fit map" );
359     }
360     else if( type == NHW_MAP && WINVERS_AMIV )
361     {
362 	struct Window *w;
363 
364 	w = amii_wins[ WIN_MESSAGE ]->win;
365 	nw->LeftEdge = 0;
366 	nw->TopEdge = w->TopEdge + w->Height;
367 	nw->Width = amiIDisplay->xpix - nw->LeftEdge;
368 
369 	w = amii_wins[ WIN_STATUS ]->win;
370 	nw->Height = w->TopEdge - nw->TopEdge;
371 	nw->MaxHeight = 0xffff;
372 	nw->MaxWidth = 0xffff;
373 
374 	if( nw->TopEdge + nw->Height > amiIDisplay->ypix - 1 )
375 	    nw->Height = amiIDisplay->ypix - nw->TopEdge - 1;
376     }
377     else if( type == NHW_STATUS )
378     {
379 	if( !WINVERS_AMIV && ( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] ) )
380 	    w = amii_wins[ WIN_MAP ]->win;
381 	else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
382 	    w = amii_wins[ WIN_BASE ]->win;
383 	else
384 	    panic( "No window to base STATUS location from" );
385 
386 	nw->Height = stath;
387 	nw->TopEdge = amiIDisplay->ypix - nw->Height;
388 	nw->LeftEdge = w->LeftEdge;
389 
390 	if( nw->LeftEdge + nw->Width >= amiIDisplay->xpix )
391 	    nw->LeftEdge = 0;
392 
393 	if( nw->Width >= amiIDisplay->xpix - nw->LeftEdge )
394 	    nw->Width = amiIDisplay->xpix - nw->LeftEdge;
395     }
396     else if( WINVERS_AMIV && type == NHW_OVER )
397     {
398 	nw->Flags |= WINDOWSIZING|WINDOWDRAG|WINDOWCLOSE;
399 	nw->IDCMPFlags |= CLOSEWINDOW;
400 	/* Bring up window as half the width of the message window, and make
401 	 * the message window change to one half the width...
402 	 */
403 	if( amii_oldover.MaxX != 0 )
404 	{
405 	    nw->LeftEdge = amii_oldover.MinX;
406 	    nw->TopEdge = amii_oldover.MinY;
407 	    nw->Width = amii_oldover.MaxX;
408 	    nw->Height = amii_oldover.MaxY;
409 	    ChangeWindowBox( amii_wins[ WIN_MESSAGE ]->win,
410 			amii_oldmsg.MinX, amii_oldmsg.MinY,
411 			amii_oldmsg.MaxX, amii_oldmsg.MaxY );
412 	}
413 	else
414 	{
415 	    nw->LeftEdge = (amii_wins[ WIN_MESSAGE ]->win->Width*4)/9;
416 	    nw->TopEdge = amii_wins[ WIN_MESSAGE ]->win->TopEdge;
417 	    nw->Width = amiIDisplay->xpix - nw->LeftEdge;
418 	    nw->Height = amii_wins[ WIN_MESSAGE ]->win->Height;
419 	    SizeWindow( amii_wins[ WIN_MESSAGE ]->win,
420 		    nw->LeftEdge - amii_wins[ WIN_MESSAGE ]->win->Width, 0 );
421 	}
422     }
423     else if( type == NHW_MESSAGE )
424     {
425 	if( !WINVERS_AMIV && ( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] ) )
426 	    w = amii_wins[ WIN_MAP ]->win;
427 	else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
428 	    w = amii_wins[ WIN_BASE ]->win;
429 	else
430 	    panic( "No window to base STATUS location from" );
431 
432 	nw->TopEdge = bigscreen ? HackScreen->BarHeight+1 : 0;
433 
434 	/* Assume highest possible message window */
435 	nw->Height = HackScreen->Height - nw->TopEdge - maph - stath;
436 
437 	/* In tilemode we can cope with this */
438 	if (WINVERS_AMIV && nw->Height < 0)
439 	    nw->Height = 0;
440 
441 	/* If in fontmode messagewindow is too small, open it with 3 lines
442 	   and overlap it with map */
443 	if (nw->Height < txheight+2) {
444 	    nw->Height = txheight*4 + 3 + HackScreen->WBorTop + HackScreen->WBorBottom;
445 	}
446 
447 	if ((nw->Height-2)/txheight < 3) {
448 	    scrollmsg = 0;
449 	    nw->Title = 0;
450 	} else {
451 	    nw->FirstGadget = &MsgScroll;
452 	    nw->Flags |= WINDOWSIZING|WINDOWDRAG;
453 	    nw->Flags &= ~BORDERLESS;
454 
455 	    if( WINVERS_AMIV || nw->Height == 0) {
456 		if( WINVERS_AMIV ) {
457 		    nw->Height = TextsFont->tf_YSize + HackScreen->WBorTop + 3 +
458 				HackScreen->WBorBottom;
459 		    if( bigscreen )
460 			nw->Height += ( txheight * 6 );
461 		    else
462 			nw->Height += ( txheight * 3 );
463 		}
464 		else
465 		{
466 		    nw->Height = HackScreen->Height - nw->TopEdge - stath - maph;
467 		}
468 	    }
469 	}
470 
471 	/* Do we have room for larger message window ?
472 	 * This is possible if we can show full height map in tile
473 	 * mode	with default scaling.
474 	 */
475 	if (nw->Height + stath + maph < HackScreen->Height - nw->TopEdge )
476 	    nw->Height = HackScreen->Height - nw->TopEdge - 1 - maph - stath;
477 
478 #ifdef  INTUI_NEW_LOOK
479 	if( IntuitionBase->LibNode.lib_Version >= 37 )
480 	{
481 	    MsgPropScroll.Flags |= PROPNEWLOOK;
482 	}
483 #endif
484     }
485 
486     nw->IDCMPFlags |= MENUPICK;
487 
488     /* Check if there is "Room" for all this stuff... */
489     if( ( WINVERS_AMIV || bigscreen ) &&
490 	type != NHW_BASE )
491     {
492 	nw->Flags &= ~( BORDERLESS | BACKDROP );
493 
494 	if( WINVERS_AMIV )
495 	{
496 	    if( type == NHW_STATUS )
497 	    {
498 		nw->Flags &= ~( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING );
499 		nw->IDCMPFlags &= ~NEWSIZE;
500 	    }
501 	    else
502 	    {
503 		nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING );
504 		nw->IDCMPFlags |= NEWSIZE;
505 	    }
506 	}
507 	else
508 	{
509 	    if( HackScreen->Width < 657 )
510 	    {
511 		nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH );
512 	    }
513 	    else
514 	    {
515 		nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT );
516 	    }
517 	}
518     }
519 
520     if ( WINVERS_AMII && type == NHW_MAP )
521 	nw->Flags &= ~WINDOWSIZING;
522 
523     if ( type == NHW_MESSAGE && scrollmsg ) {
524 	nw->Flags |= WINDOWDRAG|WINDOWDEPTH|SIZEBRIGHT|WINDOWSIZING;
525 	nw->Flags &= ~BORDERLESS;
526     }
527 
528     /* No titles on a hires only screen except for messagewindow */
529     if( !(WINVERS_AMIV && type == NHW_MAP) && !bigscreen && type != NHW_MESSAGE )
530 	nw->Title = 0;
531 
532     wd = (struct amii_WinDesc *)alloc(sizeof(struct amii_WinDesc));
533     memset( wd, 0, sizeof( struct amii_WinDesc ) );
534 
535     /* Both, since user may have changed the pen settings so respect those */
536     if( WINVERS_AMII || WINVERS_AMIV )
537     {
538 	/* Special backfill for these types of layers */
539 	switch( type )
540 	{
541 	case NHW_MESSAGE:
542 	case NHW_STATUS:
543 	case NHW_TEXT:
544 	case NHW_MENU:
545 	case NHW_BASE:
546 	case NHW_OVER:
547 	case NHW_MAP:
548 	    if( wd )
549 	    {
550 		fillhook.h_Entry = (ULONG(*)())LayerFillHook;
551 		fillhook.h_Data = (void *)type;
552 		fillhook.h_SubEntry = 0;
553 		wd->hook = alloc( sizeof( fillhook ) );
554 		memcpy( wd->hook, &fillhook, sizeof( fillhook ) );
555 		memcpy( wd->wintags, wintags, sizeof( wd->wintags) );
556 		wd->wintags[0].ti_Data = (long)wd->hook;
557 		nw->Extension = (void *)wd->wintags;
558 	    }
559 	    break;
560 	}
561     }
562 
563     /* Don't open MENU or TEXT windows yet */
564 
565     if( type == NHW_MENU || type == NHW_TEXT )
566 	w = NULL;
567     else
568 	w=OpenShWindow( (void *)nw );
569 
570     if( w == NULL && type != NHW_MENU && type != NHW_TEXT )
571     {
572 	char buf[ 100 ];
573 
574 	sprintf( buf, "nw type (%d) dims l: %d, t: %d, w: %d, h: %d",
575 		type,
576 		nw->LeftEdge, nw->TopEdge,
577 		nw->Width, nw->Height );
578 	raw_print( buf );
579 	panic("bad openwin %d",type);
580     }
581 
582     /* Check for an empty slot */
583 
584     for(newid = 0; newid<MAXWIN + 1; newid++)
585     {
586 	if(amii_wins[newid] == 0)
587 	    break;
588     }
589 
590     if(newid==MAXWIN+1)
591 	panic("time to write re-alloc code\n");
592 
593     /* Set wincnt accordingly */
594 
595     if( newid > wincnt )
596 	wincnt = newid;
597 
598     /* Do common initialization */
599 
600     amii_wins[newid] = wd;
601 
602     wd->newwin = NULL;
603     wd->win = w;
604     wd->type = type;
605     wd->wflags = 0;
606     wd->active = FALSE;
607     wd->curx=wd->cury = 0;
608     wd->resp = wd->canresp = wd->morestr = 0;   /* CHECK THESE */
609     wd->maxrow = new_wins[type].maxrow;
610     wd->maxcol = new_wins[type].maxcol;
611 
612     if( type != NHW_TEXT && type != NHW_MENU )
613     {
614 	if( TextsFont && ( type == NHW_MESSAGE || type == NHW_STATUS ) )
615 	{
616 	    SetFont(w->RPort, TextsFont);
617 	    txheight = w->RPort->TxHeight;
618 	    txwidth = w->RPort->TxWidth;
619 	    txbaseline = w->RPort->TxBaseline;
620 	    if( type == NHW_MESSAGE )
621 	    {
622 		if (scrollmsg )
623 		{
624 		    if( WINVERS_AMIV )
625 		    {
626 			WindowLimits( w, 100, w->BorderTop +
627 				w->BorderBottom +
628 				((txheight+1)*2) + 1, 0, 0 );
629 		    }
630 		    else
631 		    {
632 			WindowLimits( w, w->Width, w->BorderTop +
633 				w->BorderBottom +
634 				((txheight+1)*2) + 1, 0, 0 );
635 		    }
636 		}
637 		else
638 		{
639 		    WindowLimits( w, w->Width, w->BorderTop +
640 				w->BorderBottom +
641 				txheight + 2, 0, 0 );
642 		}
643 	    }
644 	}
645 #ifdef HACKFONT
646 	else if( HackFont )
647 	    SetFont(w->RPort, HackFont);
648 #endif
649     }
650 
651     /* Text and menu windows are not opened yet */
652     if( w )
653     {
654 	wd->rows = ( w->Height - w->BorderTop -
655 	    w->BorderBottom - 2 ) / w->RPort->TxHeight;
656 	wd->cols = ( w->Width - w->BorderLeft -
657 	    w->BorderRight - 2 ) / w->RPort->TxWidth;
658     }
659 
660     /* Okay, now do the individual type initialization */
661 
662     switch(type)
663     {
664 	/* History lines for MESSAGE windows are stored in cw->data[?].
665 	 * maxcol and maxrow are used as cursors.  maxrow is the count
666 	 * of the number of history lines stored.  maxcol is the cursor
667 	 * to the last line that was displayed by ^P.
668 	 */
669 	case NHW_MESSAGE:
670 	    SetMenuStrip(w, MenuStrip);
671 	    iflags.msg_history = wd->rows*10;
672 	    if (iflags.msg_history < 40)
673 		iflags.msg_history = 40;
674 	    if (iflags.msg_history > 400)
675 		iflags.msg_history = 400;
676 	    iflags.window_inited=TRUE;
677 	    wd->data = (char **)alloc( iflags.msg_history*sizeof( char * ) );
678 	    memset( wd->data, 0, iflags.msg_history * sizeof( char * ) );
679 	    wd->maxrow = wd->maxcol = 0;
680 	    /* Indicate that we have not positioned the cursor yet */
681 	    wd->curx = -1;
682 	    break;
683 
684 	    /* A MENU contains a list of lines in wd->data[?].  These
685 	     * lines are created in amii_putstr() by reallocating the size
686 	     * of wd->data to hold enough (char *)'s.  wd->rows is the
687 	     * number of (char *)'s allocated.  wd->maxrow is the number
688 	     * used.  wd->maxcol is used to track how wide the menu needs
689 	     * to be.  wd->resp[x] contains the characters that correspond
690 	     * to selecting wd->data[x].  wd->resp[x] corresponds to
691 	     * wd->data[x] for any x. Elements of wd->data[?] that are not
692 	     * valid selections have the corresponding element of
693 	     * wd->resp[] set to a value of '\01';  i.e. a ^A which is
694 	     * not currently a valid keystroke for responding to any
695 	     * MENU or TEXT window.
696 	     */
697 	case NHW_MENU:
698 	    wd->resp=(char*)alloc(256);
699 	    wd->resp[0]=0;
700 	    wd->rows = wd->maxrow = 0;
701 	    wd->cols = wd->maxcol = 0;
702 	    wd->data = NULL;
703 	    break;
704 
705 	    /* See the explanation of MENU above.  Except, wd->resp[] is not
706 	     * used for TEXT windows since there is no selection of a
707 	     * a line performed/allowed.  The window is always full
708 	     * screen width.
709 	     */
710 	case NHW_TEXT:
711 	    wd->rows = wd->maxrow = 0;
712 	    wd->cols = wd->maxcol = amiIDisplay->cols;
713 	    wd->data = NULL;
714 	    wd->morestr = NULL;
715 	    break;
716 
717 	    /* The status window has only two lines.  These are stored in
718 	     * wd->data[], and here we allocate the space for them.
719 	     */
720 	case NHW_STATUS:
721 	    SetMenuStrip(w, MenuStrip);
722 	    /* wd->cols is the number of characters which fit across the
723 	     * screen.
724 	     */
725 	    wd->data=(char **)alloc(3*sizeof(char *));
726 	    wd->data[0] = (char *)alloc(wd->cols + 10);
727 	    wd->data[1] = (char *)alloc(wd->cols + 10);
728 	    wd->data[2] = NULL;
729 	    break;
730 
731 	    /* NHW_OVER does not use wd->data[] or the other text
732 	     * manipulating members of the amii_WinDesc structure.
733 	     */
734 	case NHW_OVER:
735 	    SetMenuStrip(w, MenuStrip);
736 	    break;
737 
738 	    /* NHW_MAP does not use wd->data[] or the other text
739 	     * manipulating members of the amii_WinDesc structure.
740 	     */
741 	case NHW_MAP:
742 	    SetMenuStrip(w, MenuStrip);
743 	    if( WINVERS_AMIV )
744 	    {
745 		extern struct TextFont *RogueFont;
746 		CO = (w->Width-w->BorderLeft-w->BorderRight)/mxsize;
747 		LI = (w->Height-w->BorderTop-w->BorderBottom)/mysize;
748 		amii_setclipped();
749 		SetFont( w->RPort, RogueFont);
750 		SetAPen( w->RPort, C_WHITE);	/* XXX not sufficient */
751 		SetBPen( w->RPort, C_BLACK);
752 		SetDrMd( w->RPort, JAM2);
753 	    }
754 	    else
755 	    {
756 		if( HackFont )
757 		    SetFont( w->RPort, HackFont );
758 	    }
759 	    break;
760 
761 	    /* The base window must exist until CleanUp() deletes it. */
762 	case NHW_BASE:
763 	    SetMenuStrip(w, MenuStrip);
764 	    /* Make our requesters come to our screen */
765 	    {
766 		register struct Process *myProcess =
767 					(struct Process *) FindTask(NULL);
768 		pr_WindowPtr = (struct Window *)(myProcess->pr_WindowPtr);
769 		myProcess->pr_WindowPtr = (APTR) w;
770 	    }
771 
772 	    /* Need this for RawKeyConvert() */
773 
774 	    ConsoleIO.io_Data = (APTR) w;
775 	    ConsoleIO.io_Length = sizeof( struct Window );
776 	    ConsoleIO.io_Message.mn_ReplyPort = CreatePort(NULL, 0L);
777 	    if( OpenDevice("console.device", -1L,
778 				(struct IORequest *) &ConsoleIO, 0L) != 0)
779 	    {
780 		Abort(AG_OpenDev | AO_ConsoleDev);
781 	    }
782 
783 	    ConsoleDevice = (struct Library *) ConsoleIO.io_Device;
784 
785 	    KbdBuffered = 0;
786 
787 #ifdef HACKFONT
788 	    if( TextsFont )
789 		SetFont( w->RPort, TextsFont );
790 	    else if( HackFont )
791 		SetFont( w->RPort, HackFont );
792 #endif
793 	    txwidth = w->RPort->TxWidth;
794 	    txheight = w->RPort->TxHeight;
795 	    txbaseline = w->RPort->TxBaseline;
796 	    break;
797 
798 	default:
799 	    panic("bad create_nhwindow( %d )\n",type);
800 	    return WIN_ERR;
801     }
802 
803     return( newid );
804 }
805 
806 /* Initialize the windowing environment */
807 
808 void
amii_init_nhwindows(argcp,argv)809 amii_init_nhwindows(argcp,argv)
810     int *argcp;
811     char **argv;
812 {
813     int i;
814     struct Screen *wbscr;
815     int forcenobig = 0;
816 
817     if( HackScreen )
818 	panic( "init_nhwindows() called twice", 0 );
819 
820 	/* run args & set bigscreen from -L(1)/-l(-1) */
821     {
822 	int lclargc = *argcp;
823 	int t;
824 	char **argv_in = argv;
825 	char **argv_out = argv;
826 
827 	for(t=1;t<=lclargc;t++){
828 	    if(!strcmp("-L",*argv_in) || !strcmp("-l",*argv_in)){
829 		bigscreen = (*argv_in[1]=='l') ? -1 : 1;
830 		/* and eat the flag */
831 		(*argcp)--;
832 	    } else {
833 		*argv_out = *argv_in;	/* keep the flag */
834 		argv_out++;
835 	    }
836 	    argv_in++;
837 	}
838 	*argv_out = 0;
839     }
840 
841     WIN_MESSAGE = WIN_ERR;
842     WIN_MAP = WIN_ERR;
843     WIN_STATUS = WIN_ERR;
844     WIN_INVEN = WIN_ERR;
845     WIN_BASE = WIN_ERR;
846     WIN_OVER = WIN_ERR;
847 
848     if ( (IntuitionBase = (struct IntuitionBase *)
849 	  OpenLibrary("intuition.library", amii_libvers )) == NULL)
850     {
851 	Abort(AG_OpenLib | AO_Intuition);
852     }
853 
854     if ( (GfxBase = (struct GfxBase *)
855 	      OpenLibrary("graphics.library", amii_libvers )) == NULL)
856     {
857 	Abort(AG_OpenLib | AO_GraphicsLib);
858     }
859 
860     if( WINVERS_AMIV && (LayersBase = (struct Library *)
861 		OpenLibrary("layers.library", amii_libvers )) == NULL)
862     {
863 	Abort(AG_OpenLib | AO_LayersLib);
864     }
865 
866     amiIDisplay=(struct amii_DisplayDesc *)alloc(sizeof(struct amii_DisplayDesc));
867     memset( amiIDisplay, 0, sizeof( struct amii_DisplayDesc ) );
868 
869     /* Use Intuition sizes for overscan screens... */
870 
871     amiIDisplay->xpix = 0;
872 #ifdef	INTUI_NEW_LOOK
873     if( IntuitionBase->LibNode.lib_Version >= 37 )
874     {
875 	if( wbscr = LockPubScreen( "Workbench" ) )
876 	{
877 	    amiIDisplay->xpix = wbscr->Width;
878 	    amiIDisplay->ypix = wbscr->Height;
879 	    UnlockPubScreen( NULL, wbscr );
880 	}
881     }
882 #endif
883     if( amiIDisplay->xpix == 0 )
884     {
885 	amiIDisplay->ypix = GfxBase->NormalDisplayRows;
886 	amiIDisplay->xpix = GfxBase->NormalDisplayColumns;
887     }
888 
889     amiIDisplay->cols = amiIDisplay->xpix / FONTWIDTH;
890 
891     amiIDisplay->toplin=0;
892     amiIDisplay->rawprint=0;
893     amiIDisplay->lastwin=0;
894 
895     if( bigscreen == 0 )
896     {
897 	if( ( GfxBase->ActiView->ViewPort->Modes & LACE ) == LACE )
898 	{
899 	    amiIDisplay->ypix *= 2;
900 	    NewHackScreen.ViewModes |= LACE;
901 	    bigscreen = 1;
902 	}
903 	else if( GfxBase->NormalDisplayRows >= 300 )
904 	{
905 	    bigscreen = 1;
906 	}
907     }
908     else if( bigscreen == -1 )
909     {
910 	bigscreen = 0;
911 	forcenobig = 1;
912     }
913     else if( bigscreen )
914     {
915 	/* If bigscreen requested and we don't have enough rows in
916 	 * noninterlaced mode, switch to interlaced...
917 	 */
918 	if( GfxBase->NormalDisplayRows < 300 )
919 	{
920 	    amiIDisplay->ypix *= 2;
921 	    NewHackScreen.ViewModes |= LACE;
922 	}
923     }
924 
925     if( !bigscreen )
926     {
927     	alwaysinvent = 0;
928     }
929     amiIDisplay->rows = amiIDisplay->ypix / FONTHEIGHT;
930 
931 #ifdef HACKFONT
932     /*
933      *  Load the fonts that we need.
934      */
935 
936     if( DiskfontBase =
937 		OpenLibrary( "diskfont.library", amii_libvers  ) )
938     {
939 	Hack80.ta_Name -= SIZEOF_DISKNAME;
940 	HackFont = OpenDiskFont( &Hack80 );
941 	Hack80.ta_Name += SIZEOF_DISKNAME;
942 
943 	/* Textsfont13 is filled in with "FONT=" settings. The default is
944 	 * courier/13.
945 	 */
946 	TextsFont = NULL;
947 	if( bigscreen )
948 	    TextsFont = OpenDiskFont( &TextsFont13 );
949 
950 	/* Try hack/8 for texts if no user specified font */
951 	if( TextsFont == NULL )
952 	{
953 	    Hack80.ta_Name -= SIZEOF_DISKNAME;
954 	    TextsFont = OpenDiskFont( &Hack80 );
955 	    Hack80.ta_Name += SIZEOF_DISKNAME;
956 	}
957 
958 	/* If no fonts, make everything topaz 8 for non-view windows.
959 	 */
960 	Hack80.ta_Name = "topaz.font";
961 	RogueFont = OpenFont( &Hack80 );
962 	if(!RogueFont) panic("Can't get topaz:8");
963 	if( !HackFont || !TextsFont )
964 	{
965 	    if( !HackFont )
966 	    {
967 		HackFont = OpenFont( &Hack80 );
968 		if( !HackFont )
969 		    panic( "Can't get a map font, topaz:8" );
970 	    }
971 
972 	    if( !TextsFont )
973 	    {
974 		TextsFont = OpenFont( &Hack80 );
975 		if( !TextsFont )
976 		    panic( "Can't open text font" );
977 	    }
978 	}
979 	CloseLibrary(DiskfontBase);
980 	DiskfontBase = NULL;
981     }
982 #endif
983 
984     /* This is the size screen we want to open, within reason... */
985 
986     NewHackScreen.Width = max( WIDTH, amiIDisplay->xpix );
987     NewHackScreen.Height = max( SCREENHEIGHT, amiIDisplay->ypix );
988     {
989 	static char fname[18];
990 	sprintf(fname,"NetHack %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
991 	NewHackScreen.DefaultTitle=fname;
992     }
993 #if 0
994     NewHackScreen.BlockPen = C_BLACK;
995     NewHackScreen.DetailPen = C_WHITE;
996 #endif
997 #ifdef	INTUI_NEW_LOOK
998     if( IntuitionBase->LibNode.lib_Version >= 37 )
999     {
1000     	int i;
1001 	struct DimensionInfo dims;
1002 	DisplayInfoHandle handle;
1003 	struct DisplayInfo disp;
1004 	ULONG modeid = DEFAULT_MONITOR_ID|HIRES_KEY;
1005 
1006 	NewHackScreen.Width = STDSCREENWIDTH;
1007 	NewHackScreen.Height = STDSCREENHEIGHT;
1008 
1009 	if( forcenobig == 0 )
1010 	{
1011 	    if( ( wbscr = LockPubScreen( "Workbench" ) ) != NULL ||
1012 		( wbscr = LockPubScreen( NULL ) ) != NULL )
1013 	    {
1014 		/* Get the default pub screen's size */
1015 		modeid = GetVPModeID( &wbscr->ViewPort );
1016 		if( modeid == INVALID_ID ||
1017 		    ModeNotAvailable( modeid ) ||
1018 		    ( handle = FindDisplayInfo( modeid ) ) == NULL ||
1019 		    GetDisplayInfoData( handle, (char *)&dims, sizeof( dims ),
1020 			DTAG_DIMS, modeid ) <= 0 ||
1021 		    GetDisplayInfoData( handle, (char *)&disp, sizeof( disp ),
1022 			DTAG_DISP, modeid ) <= 0 )
1023 		{
1024 		    modeid = DEFAULT_MONITOR_ID|HIRES_KEY;
1025 		    /* If the display database seems to not work, use the screen
1026 		     * dimensions
1027 		     */
1028 		    NewHackScreen.Height = wbscr->Height;
1029 		    NewHackScreen.Width = wbscr->Width;
1030 
1031 		    /*
1032 		     * Request LACE if it looks laced.  For 2.1/3.0, we will get
1033 		     * promoted to the users choice of modes (if promotion is allowed)
1034 		     * If the user is using a dragable screen, things will get hosed
1035 		     * but that is life...
1036 		     */
1037 		    if( wbscr->ViewPort.Modes & LACE )
1038 			NewHackScreen.ViewModes |= LACE;
1039 		    modeid = -1;
1040 		}
1041 		else
1042 		{
1043 		    /* Use the display database to get the correct information */
1044 		    if( disp.PropertyFlags & DIPF_IS_LACE )
1045 			NewHackScreen.ViewModes |= LACE;
1046 		    NewHackScreen.Height = dims.StdOScan.MaxY;
1047 		    NewHackScreen.Width = dims.StdOScan.MaxX;
1048 		}
1049 		NewHackScreen.TopEdge = 0;
1050 		NewHackScreen.LeftEdge = 0;
1051 
1052 		UnlockPubScreen( NULL, wbscr );
1053 	    }
1054 	}
1055 
1056 	for( i = 0; scrntags[i].ti_Tag != TAG_DONE; ++i )
1057 	{
1058 	    switch( scrntags[i].ti_Tag )
1059 	    {
1060 		case SA_DisplayID:
1061 		    if( !amii_scrnmode || ModeNotAvailable( amii_scrnmode ) )
1062 		    {
1063 			if( ModeNotAvailable( modeid ) )
1064 			{
1065 			    scrntags[i].ti_Tag = TAG_IGNORE;
1066 			    break;
1067 			}
1068 			else
1069 			    scrntags[i].ti_Data = (long)modeid;
1070 		    }
1071 		    else
1072 			modeid = scrntags[i].ti_Data = (long)amii_scrnmode;
1073 		    if( ( handle = FindDisplayInfo( modeid ) ) != NULL &&
1074 			GetDisplayInfoData( handle, (char *)&dims, sizeof( dims ),
1075 			    DTAG_DIMS, modeid ) > 0 &&
1076 			GetDisplayInfoData( handle, (char *)&disp, sizeof( disp ),
1077 			    DTAG_DISP, modeid ) > 0 )
1078 		    {
1079 			if( disp.PropertyFlags & DIPF_IS_LACE )
1080 			    NewHackScreen.ViewModes |= LACE;
1081 			NewHackScreen.Height = dims.StdOScan.MaxY;
1082 			NewHackScreen.Width = dims.StdOScan.MaxX;
1083 		    }
1084 		    break;
1085 
1086 		case SA_Pens:
1087 		    scrntags[i].ti_Data = (long)flags.amii_dripens;
1088 		    break;
1089 	    }
1090 	}
1091     }
1092 #endif
1093 
1094     if( WINVERS_AMIV )
1095 	amii_bmhd = ReadTileImageFiles( );
1096     else
1097 	memcpy( amii_initmap, amii_init_map, sizeof( amii_initmap ) );
1098     memcpy(flags.amii_curmap,amii_initmap,sizeof(flags.amii_curmap));
1099 
1100     /* Find out how deep the screen needs to be, 32 planes is enough! */
1101     for( i = 0; i < 32; ++i )
1102     {
1103 	if( ( 1L << i ) >= amii_numcolors )
1104 	    break;
1105     }
1106 
1107     NewHackScreen.Depth = i;
1108 
1109     /* If for some reason Height/Width became smaller than the required,
1110 	have the required one */
1111     if (NewHackScreen.Height < SCREENHEIGHT)
1112 	NewHackScreen.Height = SCREENHEIGHT;
1113     if (NewHackScreen.Width < WIDTH)
1114 	NewHackScreen.Width = WIDTH;
1115 #ifdef HACKFONT
1116     i = max(TextsFont->tf_XSize, HackFont->tf_XSize);
1117     if (NewHackScreen.Width < 80*i+4)
1118 	NewHackScreen.Width = 80*i+4;
1119 #endif
1120 
1121     /* While openscreen fails try fewer colors to see if that is the problem. */
1122     while( ( HackScreen = OpenScreen( (void *)&NewHackScreen ) ) == NULL )
1123     {
1124 #ifdef	TEXTCOLOR
1125 	if( --NewHackScreen.Depth < 3 )
1126 #else
1127 	if( --NewHackScreen.Depth < 2 )
1128 #endif
1129 	    Abort( AN_OpenScreen & ~AT_DeadEnd );
1130     }
1131     amii_numcolors = 1L << NewHackScreen.Depth;
1132     if( HackScreen->Height > 300 && forcenobig == 0 )
1133 	bigscreen = 1;
1134     else
1135 	bigscreen = 0;
1136 
1137 #ifdef  INTUI_NEW_LOOK
1138     if( IntuitionBase->LibNode.lib_Version >= 37 )
1139 	PubScreenStatus( HackScreen, 0 );
1140 #endif
1141 
1142     amiIDisplay->ypix = HackScreen->Height;
1143     amiIDisplay->xpix = HackScreen->Width;
1144 
1145     LoadRGB4(&HackScreen->ViewPort, flags.amii_curmap, amii_numcolors );
1146 
1147     VisualInfo = GetVisualInfo(HackScreen, TAG_END);
1148     MenuStrip = CreateMenus(GTHackMenu, TAG_END);
1149     LayoutMenus(MenuStrip, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_END);
1150 
1151     /* Display the copyright etc... */
1152 
1153     if( WIN_BASE == WIN_ERR )
1154 	WIN_BASE = amii_create_nhwindow( NHW_BASE );
1155     amii_clear_nhwindow( WIN_BASE );
1156     amii_putstr( WIN_BASE, 0, "" );
1157     amii_putstr( WIN_BASE, 0, "" );
1158     amii_putstr( WIN_BASE, 0, "" );
1159     amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_A);
1160     amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_B);
1161     amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_C);
1162     amii_putstr( WIN_BASE, 0, "");
1163 
1164     Initialized = 1;
1165 }
1166 
1167 void
amii_sethipens(struct Window * w,int type,int attr)1168 amii_sethipens( struct Window *w, int type, int attr )
1169 {
1170     switch( type )
1171     {
1172 	default:
1173 	    SetAPen( w->RPort, attr ? C_RED : amii_otherAPen );
1174 	    SetBPen( w->RPort, C_BLACK );
1175 	    break;
1176 	case NHW_STATUS:
1177 	    SetAPen( w->RPort, attr ? C_WHITE : amii_statAPen );
1178 	    SetBPen( w->RPort, amii_statBPen );
1179 	    break;
1180 	case NHW_MESSAGE:
1181 	    SetAPen( w->RPort, attr ? C_WHITE : amii_msgAPen );
1182 	    SetBPen( w->RPort, amii_msgBPen );
1183 	    break;
1184 	case NHW_MENU:
1185 	    SetAPen( w->RPort, attr ? C_BLACK : amii_menuAPen );
1186 	    SetBPen( w->RPort, amii_menuBPen );
1187 	    break;
1188 	case NHW_TEXT:
1189 	    SetAPen( w->RPort, attr ? C_BLACK : amii_textAPen );
1190 	    SetBPen( w->RPort, amii_textBPen );
1191 	case -2:
1192 	    SetBPen( w->RPort, amii_otherBPen );
1193 	    SetAPen( w->RPort, attr ? C_RED : amii_otherAPen );
1194 	    break;
1195     }
1196 }
1197 
1198 void
amii_setfillpens(struct Window * w,int type)1199 amii_setfillpens( struct Window *w, int type )
1200 {
1201     switch( type )
1202     {
1203     case NHW_MESSAGE:
1204 	SetAPen( w->RPort, amii_msgBPen );
1205 	SetBPen( w->RPort, amii_msgBPen );
1206 	break;
1207     case NHW_STATUS:
1208 	SetAPen( w->RPort, amii_statBPen );
1209 	SetBPen( w->RPort, amii_statBPen );
1210 	break;
1211     case NHW_MENU:
1212 	SetAPen( w->RPort, amii_menuBPen );
1213 	SetBPen( w->RPort, amii_menuBPen );
1214 	break;
1215     case NHW_TEXT:
1216 	SetAPen( w->RPort, amii_textBPen );
1217 	SetBPen( w->RPort, amii_textBPen );
1218 	break;
1219     case NHW_MAP:
1220     case NHW_BASE:
1221     case NHW_OVER:
1222     default:
1223 	SetAPen( w->RPort, C_BLACK );
1224 	SetBPen( w->RPort, C_BLACK );
1225 	break;
1226     case -2:
1227 	SetAPen( w->RPort, amii_otherBPen );
1228 	SetBPen( w->RPort, amii_otherBPen );
1229 	break;
1230     }
1231 }
1232 
1233 void
amii_setdrawpens(struct Window * w,int type)1234 amii_setdrawpens( struct Window *w, int type )
1235 {
1236     switch( type )
1237     {
1238     case NHW_MESSAGE:
1239 	SetAPen( w->RPort, amii_msgAPen );
1240 	SetBPen( w->RPort, amii_msgBPen );
1241 	break;
1242     case NHW_STATUS:
1243 	SetAPen( w->RPort, amii_statAPen );
1244 	SetBPen( w->RPort, amii_statBPen );
1245 	break;
1246     case NHW_MENU:
1247 	SetAPen( w->RPort, amii_menuAPen );
1248 	SetBPen( w->RPort, amii_menuBPen );
1249 	break;
1250     case NHW_TEXT:
1251 	SetAPen( w->RPort, amii_textAPen );
1252 	SetBPen( w->RPort, amii_textBPen );
1253 	break;
1254     case NHW_MAP:
1255     case NHW_BASE:
1256     case NHW_OVER:
1257 	SetAPen( w->RPort, C_WHITE );
1258 	SetBPen( w->RPort, C_BLACK );
1259 	break;
1260     default:
1261 	SetAPen( w->RPort, amii_otherAPen );
1262 	SetBPen( w->RPort, amii_otherBPen );
1263 	break;
1264     }
1265 }
1266 
1267 /* Clear the indicated window */
1268 
1269 void
amii_clear_nhwindow(win)1270 amii_clear_nhwindow(win)
1271     register winid win;
1272 {
1273     register struct amii_WinDesc *cw;
1274     register struct Window *w;
1275 
1276     if( reclip == 2 ) return;
1277 
1278     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
1279 	panic( winpanicstr, win, "clear_nhwindow" );
1280 
1281     /* Clear the overview window too if it is displayed */
1282     if( WINVERS_AMIV && ( cw->type == WIN_MAP && WIN_OVER != WIN_ERR && reclip == 0 ) )
1283     {
1284 	amii_clear_nhwindow( WIN_OVER );
1285     }
1286 
1287     if( w = cw->win )
1288 	SetDrMd( w->RPort, JAM2);
1289     else
1290         return;
1291 
1292     if( (cw->wflags & FLMAP_CURSUP ) )
1293     {
1294 	if( cw->type != NHW_MAP )
1295 	    cursor_off( win );
1296 	else
1297 	    cw->wflags &= ~FLMAP_CURSUP;
1298     }
1299 
1300     amii_setfillpens( w, cw->type );
1301     SetDrMd( w->RPort, JAM2 );
1302 
1303     if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
1304     {
1305 	RectFill( w->RPort, w->BorderLeft, w->BorderTop,
1306 	  w->Width - w->BorderRight-1,
1307 	  w->Height - w->BorderBottom-1 );
1308     }
1309     else
1310     {
1311 	if( cw->type == NHW_MESSAGE )
1312 	{
1313 	    amii_curs( win, 1, 0 );
1314 	    if( !scrollmsg )
1315 		TextSpaces( w->RPort, cw->cols );
1316 	}
1317 	else
1318 	{
1319 	    RectFill( w->RPort, w->BorderLeft, w->BorderTop,
1320 	      w->Width - w->BorderRight-1,
1321 	      w->Height - w->BorderBottom-1 );
1322 	}
1323     }
1324 
1325     cw->cury = 0;
1326     cw->curx = 0;
1327     amii_curs( win, 1, 0 );
1328 }
1329 
1330 /* Dismiss the window from the screen */
1331 
1332 void
dismiss_nhwindow(win)1333 dismiss_nhwindow(win)
1334     register winid win;
1335 {
1336     register struct Window *w;
1337     register struct amii_WinDesc *cw;
1338 
1339     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
1340     {
1341 	panic(winpanicstr,win, "dismiss_nhwindow");
1342     }
1343 
1344     w = cw->win;
1345 
1346     if( w )
1347     {
1348 	/* All windows have this stuff attached to them. */
1349 	if(	cw->type == NHW_MAP ||
1350 		cw->type == NHW_OVER ||
1351 		cw->type == NHW_BASE ||
1352 		cw->type == NHW_MESSAGE ||
1353 		cw->type == NHW_STATUS )
1354 	{
1355 	    ClearMenuStrip( w );
1356 	}
1357 
1358 	/* Save where user like inventory to appear */
1359 	if( win == WIN_INVEN )
1360 	{
1361 	    lastinvent.MinX = w->LeftEdge;
1362 	    lastinvent.MinY = w->TopEdge;
1363 	    lastinvent.MaxX = w->Width;
1364 	    lastinvent.MaxY = w->Height;
1365 	}
1366 
1367 	/* Close the window */
1368 	CloseShWindow( w );
1369 	cw->win = NULL;
1370 
1371 	/* Free copy of NewWindow structure for TEXT/MENU windows. */
1372 	if( cw->newwin )
1373 	    FreeNewWindow( (void *)cw->newwin );
1374 	cw->newwin = NULL;
1375     }
1376 }
1377 
1378 void
amii_exit_nhwindows(str)1379 amii_exit_nhwindows(str)
1380     const char *str;
1381 {
1382     /* Seems strange to have to do this... but we need the BASE window
1383      * left behind...
1384      */
1385     kill_nhwindows( 0 );
1386     if( WINVERS_AMIV )
1387 	FreeTileImageFiles( );
1388 
1389     if( str )
1390     {
1391 	raw_print( "" );	/* be sure we're not under the top margin */
1392 	raw_print( str );
1393     }
1394 }
1395 
1396 void
amii_display_nhwindow(win,blocking)1397 amii_display_nhwindow(win,blocking)
1398     winid win;
1399     boolean blocking;
1400 {
1401     menu_item *mip;
1402     int cnt;
1403     static int lastwin = -1;
1404     struct amii_WinDesc *cw;
1405 
1406     if( !Initialized )
1407 	return;
1408     lastwin = win;
1409 
1410     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
1411 	panic(winpanicstr,win,"display_nhwindow");
1412 
1413     if( cw->type == NHW_MESSAGE )
1414 	cw->wflags &= ~FLMAP_SKIP;
1415 
1416     if( cw->type == NHW_MESSAGE || cw->type == NHW_STATUS )
1417 	return;
1418 
1419     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
1420     {
1421 	flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
1422     }
1423 
1424     if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
1425     {
1426 	cnt = DoMenuScroll( win, blocking, PICK_ONE, &mip );
1427     }
1428     else if( cw->type==NHW_MAP )
1429     {
1430 	amii_end_glyphout( win );
1431 	/* Do more if it is time... */
1432 	if( blocking == TRUE && amii_wins[ WIN_MESSAGE ]->curx )
1433 	{
1434 	    outmore( amii_wins[ WIN_MESSAGE ] );
1435 	}
1436     }
1437 }
1438 
1439 void
amii_curs(window,x,y)1440 amii_curs(window, x, y)
1441 winid window;
1442 register int x, y;  /* not xchar: perhaps xchar is unsigned and
1443 	       curx-x would be unsigned as well */
1444 {
1445     register struct amii_WinDesc *cw;
1446     register struct Window *w;
1447     register struct RastPort *rp;
1448 
1449     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
1450 	panic(winpanicstr,  window, "curs");
1451     if( (w = cw->win) == NULL )
1452     {
1453 	if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
1454 	    return;
1455 	else
1456 	    panic( "No window open yet in curs() for winid %d\n", window );
1457     }
1458     amiIDisplay->lastwin = window;
1459 
1460     /* Make sure x is within bounds */
1461     if( x > 0 )
1462 	--x;    /* column 0 is never used */
1463     else
1464 	x = 0;
1465 
1466     cw->curx = x;
1467     cw->cury = y;
1468 
1469 #ifdef DEBUG
1470     if( x<0 || y<0 || y >= cw->rows || x >= cw->cols )
1471     {
1472 	char *s = "[unknown type]";
1473 	switch(cw->type)
1474 	{
1475 	    case NHW_MESSAGE: s = "[topl window]"; break;
1476 	    case NHW_STATUS: s = "[status window]"; break;
1477 	    case NHW_MAP: s = "[map window]"; break;
1478 	    case NHW_MENU: s = "[menu window]"; break;
1479 	    case NHW_TEXT: s = "[text window]"; break;
1480 	    case NHW_BASE: s = "[base window]"; break;
1481 	    case NHW_OVER: s = "[overview window]"; break;
1482 	}
1483 	impossible("bad curs positioning win %d %s (%d,%d)", window, s, x, y);
1484 	return;
1485     }
1486 #endif
1487 
1488 #ifdef CLIPPING
1489     if(clipping && cw->type == NHW_MAP)
1490     {
1491 	x -= clipx;
1492 	y -= clipy;
1493     }
1494 #endif
1495 
1496     /* Output all saved output before doing cursor movements for MAP */
1497 
1498     if( cw->type == NHW_MAP )
1499     {
1500 	flush_glyph_buffer( w );
1501     }
1502 
1503     /* Actually do it */
1504 
1505     rp = w->RPort;
1506     if( cw->type == NHW_MENU )
1507     {
1508 	if( WINVERS_AMIV )
1509 	{
1510 	    if( window == WIN_INVEN )
1511 	    {
1512 		Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1 + pictdata.xsize + 4,
1513 		    (y * max(rp->TxHeight,pictdata.ysize + 3) ) +
1514 		     rp->TxBaseline + pictdata.ysize - rp->TxHeight + w->BorderTop + 4 );
1515 	    }
1516 	    else
1517 	    {
1518 		Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
1519 		    (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1 );
1520 	    }
1521 	}
1522 	else
1523 	{
1524 	    Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
1525 		(y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
1526 	}
1527     }
1528     else if( cw->type == NHW_TEXT )
1529     {
1530 	Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
1531 	    (y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
1532     }
1533     else if( cw->type == NHW_MAP || cw->type == NHW_BASE )
1534     {
1535 	/* These coordinate calculations must be synced with those
1536 	 * in flush_glyph_buffer() in winchar.c.  curs_on_u() will
1537 	 * use this code, all other drawing occurs through the glyph
1538 	 * code.  In order for the cursor to appear on top of the hero,
1539 	 * the code must compute X,Y in the same manner relative to
1540 	 * the RastPort coordinates.
1541 	 *
1542 	 * y = w->BorderTop + (g_nodes[i].y-2) * rp->TxHeight +
1543 	 *   rp->TxBaseline + 1;
1544 	 * x = g_nodes[i].x * rp->TxWidth + w->BorderLeft;
1545 	 */
1546 
1547 	if( WINVERS_AMIV )
1548 	{
1549 	    if( cw->type == NHW_MAP )
1550 	    {
1551 	      if(Is_rogue_level(&u.uz)){
1552 #if 0
1553 int qqx= (x * w->RPort->TxWidth) + w->BorderLeft;
1554 int qqy= w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1;
1555 printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy);
1556 #endif
1557 		SetAPen(w->RPort,C_WHITE); /* XXX should be elsewhere (was 4)*/
1558 		Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
1559 			w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1 );
1560 	      } else {
1561 		Move( rp, (x * mxsize) + w->BorderLeft,
1562 				w->BorderTop + ( (y+1) * mysize ) + 1 );
1563 	      }
1564 	    }
1565 	    else
1566 	    {
1567 		Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
1568 			    w->BorderTop + ( (y + 1) * w->RPort->TxHeight ) +
1569 			    w->RPort->TxBaseline + 1 );
1570 	    }
1571 	}
1572 	else
1573 	{
1574 	    Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
1575 			w->BorderTop + ( y * w->RPort->TxHeight ) +
1576 			w->RPort->TxBaseline + 1 );
1577 	}
1578     }
1579     else if( WINVERS_AMIV && cw->type == NHW_OVER )
1580     {
1581 	Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
1582 			w->BorderTop + w->RPort->TxBaseline + 3 );
1583     }
1584     else if( cw->type == NHW_MESSAGE && !scrollmsg )
1585     {
1586 	Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
1587 			w->BorderTop + w->RPort->TxBaseline + 3 );
1588     }
1589     else if( cw->type == NHW_STATUS )
1590     {
1591 	Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
1592 			(y*(w->RPort->TxHeight+1)) + w->BorderTop +
1593 			w->RPort->TxBaseline + 1 );
1594     }
1595     else
1596     {
1597 	Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
1598 			(y*w->RPort->TxHeight) + w->BorderTop +
1599 			w->RPort->TxBaseline + 1 );
1600     }
1601 }
1602 
1603 void
amii_set_text_font(name,size)1604 amii_set_text_font( name, size )
1605     char *name;
1606     int size;
1607 {
1608     register int i;
1609     register struct amii_WinDesc *cw;
1610     int osize = TextsFont13.ta_YSize;
1611     static char nname[ 100 ];
1612 
1613     strncpy( nname, name, sizeof( nname ) - 1 );
1614     nname[ sizeof( nname ) - 1 ] = 0;
1615 
1616     TextsFont13.ta_Name = nname;
1617     TextsFont13.ta_YSize = size;
1618 
1619     /* No alternate text font allowed for 640x269 or smaller */
1620     if( !HackScreen || !bigscreen )
1621 	return;
1622 
1623     /* Look for windows to set, and change them */
1624 
1625     if( DiskfontBase =
1626 		OpenLibrary( "diskfont.library", amii_libvers  ) )
1627     {
1628 	TextsFont = OpenDiskFont( &TextsFont13 );
1629 	for( i = 0; TextsFont && i < MAXWIN; ++i )
1630 	{
1631 	    if( (cw = amii_wins[ i ]) && cw->win != NULL )
1632 	    {
1633 	    	switch( cw->type )
1634 	    	{
1635 	    	case NHW_STATUS:
1636 		    MoveWindow( cw->win, 0, -( size - osize ) * 2 );
1637 		    SizeWindow( cw->win, 0, ( size - osize ) * 2 );
1638 		    SetFont( cw->win->RPort, TextsFont );
1639 		    break;
1640 	    	case NHW_MESSAGE:
1641 	    	case NHW_MAP:
1642 	    	case NHW_BASE:
1643 	    	case NHW_OVER:
1644 		    SetFont( cw->win->RPort, TextsFont );
1645 		    break;
1646 	    	}
1647 	    }
1648 	}
1649     }
1650     CloseLibrary(DiskfontBase);
1651     DiskfontBase = NULL;
1652 }
1653 
1654 void
kill_nhwindows(all)1655 kill_nhwindows( all )
1656     register int all;
1657 {
1658     register int i;
1659     register struct amii_WinDesc *cw;
1660 
1661     /* Foreach open window in all of amii_wins[], CloseShWindow, free memory */
1662 
1663     for( i = 0; i < MAXWIN; ++i )
1664     {
1665 	if( (cw = amii_wins[ i ]) && (cw->type != NHW_BASE || all) )
1666 	{
1667 	    amii_destroy_nhwindow( i );
1668 	}
1669     }
1670 }
1671 
1672 void
amii_cl_end(cw,curs_pos)1673 amii_cl_end( cw, curs_pos )
1674     register struct amii_WinDesc *cw;
1675     register int curs_pos;
1676 {
1677     register struct Window *w = cw->win;
1678     register int oy, ox;
1679 
1680     if( !w )
1681 	panic("NULL window pointer in amii_cl_end()");
1682 
1683     oy = w->RPort->cp_y;
1684     ox = w->RPort->cp_x;
1685 
1686     TextSpaces( w->RPort, cw->cols - curs_pos );
1687 
1688     Move( w->RPort, ox, oy );
1689 }
1690 
1691 void
cursor_off(window)1692 cursor_off( window )
1693     winid window;
1694 {
1695     register struct amii_WinDesc *cw;
1696     register struct Window *w;
1697     register struct RastPort *rp;
1698     int curx, cury;
1699     int x, y;
1700     long dmode;
1701     short apen, bpen;
1702     unsigned char ch;
1703 
1704     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
1705     {
1706 	iflags.window_inited=0;
1707 	panic(winpanicstr,window, "cursor_off");
1708     }
1709 
1710     if( !(cw->wflags & FLMAP_CURSUP ) )
1711 	return;
1712 
1713     w = cw->win;
1714 
1715     if( !w )
1716 	return;
1717 
1718     cw->wflags &= ~FLMAP_CURSUP;
1719     rp = w->RPort;
1720 
1721     /* Save the current information */
1722     curx = rp->cp_x;
1723     cury = rp->cp_y;
1724     x = cw->cursx;
1725     y = cw->cursy;
1726     dmode = rp->DrawMode;
1727     apen = rp->FgPen;
1728     bpen = rp->BgPen;
1729     SetAPen( rp, cw->curs_apen );
1730     SetBPen( rp, cw->curs_bpen );
1731     SetDrMd( rp, COMPLEMENT );
1732 /*printf("CURSOR OFF: %d %d\n",x,y);*/
1733 
1734     if( WINVERS_AMIV && cw->type == NHW_MAP)
1735     {
1736 	cursor_common(rp, x, y);
1737 	if(Is_rogue_level(&u.uz))
1738 	    Move(rp,curx,cury);
1739     }
1740     else
1741     {
1742 	ch = CURSOR_CHAR;
1743 	Move( rp, x, y );
1744 	Text( rp, &ch, 1 );
1745 
1746 	/* Put back the other stuff */
1747 
1748 	Move( rp, curx, cury );
1749     }
1750     SetDrMd( rp, dmode );
1751     SetAPen( rp, apen );
1752     SetBPen( rp, bpen );
1753 }
1754 
1755 void
cursor_on(window)1756 cursor_on( window )
1757     winid window;
1758 {
1759     int x, y;
1760     register struct amii_WinDesc *cw;
1761     register struct Window *w;
1762     register struct RastPort *rp;
1763     unsigned char ch;
1764     long dmode;
1765     short apen, bpen;
1766 
1767     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
1768     {
1769 	/* tty does this differently - is this OK? */
1770 	iflags.window_inited=0;
1771 	panic(winpanicstr,window, "cursor_on");
1772     }
1773 
1774 /*printf("CURSOR ON: %d %d\n",cw->win->RPort->cp_x, cw->win->RPort->cp_y);*/
1775     if( (cw->wflags & FLMAP_CURSUP ) )
1776 	cursor_off( window );
1777 
1778     w = cw->win;
1779 
1780     if( !w )
1781 	return;
1782 
1783     cw->wflags |= FLMAP_CURSUP;
1784     rp = w->RPort;
1785 
1786     /* Save the current information */
1787 
1788 #ifdef	DISPMAP
1789     if( WINVERS_AMIV && cw->type == NHW_MAP && !Is_rogue_level(&u.uz))
1790 	x = cw->cursx = (rp->cp_x & -8) + 8;
1791     else
1792 #endif
1793 	x = cw->cursx = rp->cp_x;
1794     y = cw->cursy = rp->cp_y;
1795     apen = rp->FgPen;
1796     bpen = rp->BgPen;
1797     dmode = rp->DrawMode;
1798 
1799     /* Draw in complement mode. The cursor body will be C_WHITE */
1800 
1801     cw->curs_apen = C_RED;
1802     cw->curs_bpen = C_RED;
1803     SetAPen( rp, cw->curs_apen );
1804     SetBPen( rp, cw->curs_bpen );
1805     SetDrMd( rp, COMPLEMENT );
1806     if( WINVERS_AMIV && cw->type == NHW_MAP)
1807     {
1808 	cursor_common(rp, x, y);
1809     }
1810     else
1811     {
1812 	Move( rp, x, y );
1813 	ch = CURSOR_CHAR;
1814 	Text( rp, &ch, 1 );
1815 	Move( rp, x, y );
1816     }
1817 
1818     SetDrMd( rp, dmode );
1819     SetAPen( rp, apen );
1820     SetBPen( rp, bpen );
1821 }
1822 
1823 static void
cursor_common(rp,x,y)1824 cursor_common(rp, x, y)
1825 	struct RastPort *rp;
1826 	int x,y;
1827 {
1828     int x1,x2,y1,y2;
1829 
1830     if(Is_rogue_level(&u.uz)){
1831 	x1 = x-2;		y1 = y-rp->TxHeight;
1832 	x2 = x+rp->TxWidth+1;	y2 = y+3;
1833 /*printf("COMM: (%d %d) (%d %d)  (%d %d) (%d %d)\n",x1,y1,x2,y2,x1+2,y1+2,x2-2,y2-2);*/
1834     } else {
1835 	x1 = x;			y1 = y-mysize-1;
1836 	x2 = x+mxsize-1;	y2 = y-2;
1837 	RectFill(rp, x1, y1, x2, y2);
1838     }
1839 
1840     RectFill(rp, x1+2, y1+2, x2-2, y2-2);
1841 }
1842 
amii_suspend_nhwindows(str)1843 void amii_suspend_nhwindows( str )
1844     const char *str;
1845 {
1846     if( HackScreen )
1847 	ScreenToBack( HackScreen );
1848 }
1849 
amii_resume_nhwindows()1850 void amii_resume_nhwindows()
1851 {
1852     if( HackScreen )
1853 	ScreenToFront( HackScreen );
1854 }
1855 
amii_bell()1856 void amii_bell()
1857 {
1858     DisplayBeep( NULL );
1859 }
1860 
1861 void
removetopl(cnt)1862 removetopl(cnt)
1863 	int cnt;
1864 {
1865     struct amii_WinDesc *cw=amii_wins[WIN_MESSAGE];
1866 					/* NB - this is sufficient for
1867 					 * yn_function, but that's it
1868 					 */
1869     if(cw->curx < cnt)cw->curx=0;
1870     else cw->curx -= cnt;
1871 
1872     amii_curs(WIN_MESSAGE, cw->curx+1, cw->cury);
1873     amii_cl_end(cw, cw->curx);
1874 }
1875 /*#endif /* AMIGA_INTUITION */
1876 
1877 #ifdef  PORT_HELP
1878 void
port_help()1879 port_help()
1880 {
1881     display_file( PORT_HELP, 1 );
1882 }
1883 #endif
1884 
1885 /*
1886  *  print_glyph
1887  *
1888  *  Print the glyph to the output device.  Don't flush the output device.
1889  *
1890  *  Since this is only called from show_glyph(), it is assumed that the
1891  *  position and glyph are always correct (checked there)!
1892  */
1893 
1894 void
amii_print_glyph(win,x,y,glyph)1895 amii_print_glyph(win,x,y,glyph)
1896     winid win;
1897     xchar x,y;
1898     int glyph;
1899 {
1900     struct amii_WinDesc *cw;
1901     uchar   ch;
1902     register int offset;
1903 #ifdef TEXTCOLOR
1904     int     color;
1905 #endif
1906     extern int zapcolors[];
1907 
1908     /* In order for the overview window to work, we can not clip here */
1909     if( !WINVERS_AMIV )
1910     {
1911 #ifdef	CLIPPING
1912 	/* If point not in visible part of window just skip it */
1913 	if( clipping )
1914 	{
1915 	    if( x <= clipx || y < clipy || x >= clipxmax || y >= clipymax )
1916 		return;
1917 	}
1918 #endif
1919     }
1920 
1921     if( win == WIN_ERR || (cw=amii_wins[win]) == NULL || cw->type != NHW_MAP)
1922     {
1923 	panic(winpanicstr,win,"amii_print_glyph");
1924     }
1925 
1926 #if 0
1927 {
1928 static int x=-1;
1929 if(u.uz.dlevel != x){
1930  fprintf(stderr,"lvlchg: %d (%d)\n",u.uz.dlevel,Is_rogue_level(&u.uz));
1931  x = u.uz.dlevel;
1932 }
1933 }
1934 #endif
1935     if(
1936 	WINVERS_AMIV
1937 #ifdef REINCARNATION
1938 	&& !Is_rogue_level(&u.uz)
1939 #endif
1940     )
1941     {
1942 	amii_curs(win,x,y);
1943 	amiga_print_glyph(win,0,glyph);
1944     }
1945     else		/* AMII, or Rogue level in either version */
1946     {
1947 #ifdef TEXTCOLOR
1948 #define zap_color(n)  color = iflags.use_color ? zapcolors[n] : NO_COLOR
1949 #define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR
1950 #define obj_color(n)  color = iflags.use_color ? objects[n].oc_color : NO_COLOR
1951 #define mon_color(n)  color = iflags.use_color ? mons[n].mcolor : NO_COLOR
1952 #define invis_color(n) color = NO_COLOR
1953 #define pet_color(n)  color = iflags.use_color ? mons[n].mcolor :          \
1954 		/* If no color, try to hilite pets; black  */ \
1955 		/* should be HI                */ \
1956 		    ((iflags.hilite_pet) ? CLR_BLACK : NO_COLOR)
1957 # define warn_color(n) color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR
1958 # else /* no text color */
1959 
1960 #define zap_color(n)
1961 #define cmap_color(n)
1962 #define obj_color(n)
1963 #define mon_color(n)
1964 #define invis_color(n)
1965 #define pet_color(n)
1966 #define warn_color(n)
1967 #endif
1968 
1969 	/*
1970 	 *  Map the glyph back to a character.
1971 	 *
1972 	 *  Warning:  For speed, this makes an assumption on the order of
1973 	 *        offsets.  The order is set in display.h.
1974 	 */
1975 	if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) {	/* a warning flash */
1976 	    ch = warnsyms[offset];
1977 	    warn_color(offset);
1978 	} else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {  /* swallow */
1979 	    /* see swallow_to_glyph()in display.c */
1980 	    ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
1981 	    mon_color(offset >> 3);
1982 	} else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {       /* zap beam */
1983 	    ch = showsyms[S_vbeam + (offset & 0x3)];
1984 	    zap_color((offset >> 2));
1985 	} else if( ( offset = (glyph - GLYPH_CMAP_OFF) ) >= 0 ) {   /* cmap */
1986 	    ch = showsyms[offset];
1987 	    cmap_color(offset);
1988 	} else if( ( offset = (glyph - GLYPH_OBJ_OFF) ) >= 0 ) {    /* object */
1989 	    ch = oc_syms[objects[offset].oc_class];
1990 	    obj_color(offset);
1991 	} else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* a ridden monster */
1992 	    ch = (uchar) monsyms[mons[offset].mlet];
1993 	    mon_color(offset);
1994 	} else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {  /* a corpse */
1995 	    ch = oc_syms[objects[CORPSE].oc_class];
1996 	    mon_color(offset);
1997 	} else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* a detected monster */
1998 	    ch = (uchar) monsyms[mons[offset].mlet];
1999 	    mon_color(offset);
2000 	} else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) {	/* invisible */
2001 	    ch = DEF_INVISIBLE;
2002 	    invis_color(offset);
2003 	} else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {   /* a pet */
2004 	    ch = (uchar) monsyms[mons[offset].mlet];
2005 	    pet_color(offset);
2006 	} else /*if( glyph_is_monster(glyph) )*/ {      /* a monster */
2007 	    ch = (uchar) monsyms[mons[glyph].mlet];
2008 	    mon_color(glyph);
2009 	}
2010 				/* XXX next if should be ifdef REINCARNATION */
2011 	if( WINVERS_AMIV ){			/* implies Rogue level here */
2012 	    amii_curs(win,x,y);
2013 	    amiga_print_glyph(win,NO_COLOR,ch + 10000);
2014 	} else {
2015 		/* Move the cursor. */
2016 	    amii_curs(win,x,y+2);
2017 
2018 #ifdef TEXTCOLOR
2019 		/* Turn off color if rogue level. */
2020 # ifdef REINCARNATION
2021 	    if (Is_rogue_level(&u.uz))
2022 		color = NO_COLOR;
2023 #  endif
2024 
2025 	    amiga_print_glyph(win,color,ch);
2026 #else
2027 	    g_putch(ch);    /* print the character */
2028 #endif
2029 	    cw->curx++;     /* one character over */
2030 	}
2031     }
2032 }
2033 
2034 /* Make sure the user sees a text string when no windowing is available */
2035 
2036 void
amii_raw_print(s)2037 amii_raw_print(s)
2038     register const char *s;
2039 {
2040     int argc = 0;
2041 
2042     if( !s )
2043 	return;
2044     if(amiIDisplay)
2045 	amiIDisplay->rawprint++;
2046 
2047     if (!Initialized) { /* Not yet screen open ... */
2048         puts(s);
2049         fflush(stdout);
2050         return;
2051     }
2052 
2053     if( Initialized == 0 && WIN_BASE == WIN_ERR )
2054 	    init_nhwindows(&argc, (char **)0);
2055 
2056     if( amii_rawprwin != WIN_ERR )
2057 	amii_putstr( amii_rawprwin, 0, s );
2058     else if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
2059 	amii_putstr( WIN_MAP, 0, s );
2060     else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
2061 	amii_putstr( WIN_BASE, 0, s );
2062     else
2063     {
2064 	puts( s);
2065 	fflush(stdout);
2066     }
2067 }
2068 
2069 /* Make sure the user sees a bold text string when no windowing
2070  * is available
2071  */
2072 
2073 void
amii_raw_print_bold(s)2074 amii_raw_print_bold(s)
2075     register const char *s;
2076 {
2077     int argc = 0;
2078 
2079     if( !s )
2080 	return;
2081 
2082     if(amiIDisplay)
2083 	amiIDisplay->rawprint++;
2084 
2085     if (!Initialized) { /* Not yet screen open ... */
2086         puts(s);
2087         fflush(stdout);
2088         return;
2089     }
2090 
2091     if( Initialized == 0 && WIN_BASE == WIN_ERR )
2092 	    init_nhwindows(&argc, (char **)0);
2093 
2094     if( amii_rawprwin != WIN_ERR )
2095 	amii_putstr( amii_rawprwin, 1, s );
2096     else if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
2097 	amii_putstr( WIN_MAP, 1, s );
2098     else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
2099 	amii_putstr( WIN_BASE, 1, s );
2100     else
2101     {
2102 	printf("\33[1m%s\33[0m\n",s);
2103 	fflush(stdout);
2104     }
2105 }
2106 
2107 /* Rebuild/update the inventory if the window is up.
2108  */
2109 void
amii_update_inventory()2110 amii_update_inventory()
2111 {
2112     register struct amii_WinDesc *cw;
2113 
2114     if( WIN_INVEN != WIN_ERR && ( cw = amii_wins[ WIN_INVEN ] ) &&
2115 				cw->type == NHW_MENU && cw->win )
2116     {
2117 	display_inventory( NULL, FALSE );
2118     }
2119 }
2120 
2121 /* Humm, doesn't really do anything useful */
2122 
2123 void
amii_mark_synch()2124 amii_mark_synch()
2125 {
2126     if(!amiIDisplay)
2127 	fflush(stderr);
2128 /* anything else?  do we need this much? */
2129 }
2130 
2131 /* Wait for everything to sync.  Nothing is asynchronous, so we just
2132  * ask for a key to be pressed.
2133  */
2134 void
amii_wait_synch()2135 amii_wait_synch()
2136 {
2137     if(!amiIDisplay || amiIDisplay->rawprint)
2138     {
2139 	if(amiIDisplay) amiIDisplay->rawprint=0;
2140     }
2141     else
2142     {
2143 	if( WIN_MAP != WIN_ERR )
2144 	{
2145 	    display_nhwindow(WIN_MAP,TRUE);
2146 	    flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
2147 	}
2148     }
2149 }
2150 
2151 void
amii_setclipped()2152 amii_setclipped()
2153 {
2154 #ifdef	CLIPPING
2155     clipping = TRUE;
2156     clipx=clipy=0;
2157     clipxmax=CO;
2158     clipymax=LI;
2159 /* some of this is now redundant with top of amii_cliparound XXX */
2160 #endif
2161 }
2162 
2163 /* XXX still to do: suppress scrolling if we violate the boundary but the
2164  * edge of the map is already displayed
2165  */
2166 void
amii_cliparound(x,y)2167 amii_cliparound(x,y)
2168     register int x,y;
2169 {
2170     extern boolean restoring;
2171 #ifdef	CLIPPING
2172     int oldx = clipx, oldy = clipy;
2173     int oldxmax = clipxmax, oldymax = clipymax;
2174     int COx, LIx;
2175 #define	SCROLLCNT	1	/* Get there in 3 moves... */
2176     int scrollcnt = SCROLLCNT;	/* ...or 1 if we changed level */
2177     if (!clipping)		/* And 1 in anycase, cleaner, simpler, quicker */
2178 	return;
2179 
2180     if(Is_rogue_level(&u.uz)){
2181 	struct Window *w = amii_wins[WIN_MAP]->win;
2182 	struct RastPort *rp = w->RPort;
2183 
2184 	COx = (w->Width-w->BorderLeft-w->BorderRight)/rp->TxWidth;
2185 	LIx = (w->Height-w->BorderTop-w->BorderBottom)/rp->TxHeight;
2186     }else{
2187 	COx = CO;
2188 	LIx = LI;
2189     }
2190 		/*
2191 		 * On a level change, move the clipping region so that for a
2192 		 * reasonablely large window extra motion is avoided; for
2193 		 * the rogue level hopefully this means no motion at all.
2194 		 */
2195     {
2196 	static d_level saved_level = {127,127};		/* XXX */
2197 
2198 	if(!on_level(&u.uz, &saved_level)){
2199 	    scrollcnt = 1;	/* jump with blanking */
2200 	    clipx=clipy=0;
2201 	    clipxmax = COx; clipymax = LIx;
2202 	    saved_level = u.uz;		/* save as new current level */
2203 	}
2204     }
2205 
2206     if (x <= clipx + xclipbord ) {
2207 	clipx = max(0, x - (clipxmax - clipx)/2 );
2208 	clipxmax = clipx + COx;
2209     }
2210     else if (x > clipxmax - xclipbord ) {
2211 	clipxmax = min(COLNO, x + (clipxmax - clipx)/2 );
2212 	clipx = clipxmax - COx;
2213     }
2214 
2215     if (y <= clipy + yclipbord ) {
2216 	clipy = max(0, y - (clipymax - clipy) / 2);
2217 	clipymax = clipy + LIx;
2218     }
2219     else if (y > clipymax - yclipbord ) {
2220 	clipymax = min(ROWNO, y + (clipymax - clipy) / 2);
2221 	clipy = clipymax - LIx;
2222     }
2223 
2224     reclip = 1;
2225     if (clipx != oldx || clipy != oldy || clipxmax != oldxmax || clipymax != oldymax )
2226     {
2227 #ifndef NOSCROLLRASTER
2228     	struct Window *w = amii_wins[ WIN_MAP ]->win;
2229     	struct RastPort *rp = w->RPort;
2230     	int xdelta, ydelta, xmod, ymod, i;
2231     	int incx, incy, mincx, mincy;
2232     	int savex, savey, savexmax, saveymax;
2233 	int scrx, scry;
2234 
2235 	if(Is_rogue_level(&u.uz)){
2236 	    scrx = rp->TxWidth;
2237 	    scry = rp->TxHeight;
2238 	} else {
2239 	    scrx = mxsize;
2240 	    scry = mysize;
2241 	}
2242 
2243 	/* Ask that the glyph routines not draw the overview window */
2244 	reclip = 2;
2245 	cursor_off( WIN_MAP );
2246 
2247 	/* Compute how far we are moving in terms of tiles */
2248 	mincx = clipx - oldx ;
2249 	mincy = clipy - oldy ;
2250 
2251 	/* How many tiles to get there in SCROLLCNT moves */
2252 	incx = ( clipx - oldx )/scrollcnt;
2253 	incy = ( clipy - oldy )/scrollcnt;
2254 
2255 	/* If less than SCROLLCNT tiles, then move by 1 tile if moving at all */
2256 	if( incx == 0 ) incx = (mincx != 0);
2257 	if( incy == 0 ) incy = (mincy != 0);
2258 
2259 	/* Get count of pixels to move each iteration and final pixel count */
2260     	xdelta = ((clipx-oldx )*scrx) / scrollcnt;
2261     	xmod = ((clipx-oldx )*scrx) % scrollcnt;
2262     	ydelta = ((clipy-oldy )*scry) / scrollcnt;
2263     	ymod = ((clipy-oldy )*scry) % scrollcnt;
2264 
2265 	/* Preserve the final move location */
2266     	savex = clipx;
2267      	savey = clipy;
2268 	saveymax = clipymax;
2269 	savexmax = clipxmax;
2270 
2271 	/*
2272 	 * Set clipping rectangle to be just the region that will be exposed so
2273 	 * that drawing will be faster
2274 	 */
2275 #if 0	/* Doesn't seem to work quite the way it should */
2276 	/* In some cases hero is 'centered' offscreen */
2277 	if( xdelta < 0 )
2278 	{
2279 	    clipx = oldx;
2280 	    clipxmax = clipx + incx;
2281 	}
2282 	else if( xdelta > 0 )
2283 	{
2284 	    clipxmax = oldxmax;
2285 	    clipx = clipxmax - incx;
2286 	}
2287 	else
2288 	{
2289 	    clipx = oldx;
2290 	    clipxmax = oldxmax;
2291 	}
2292 
2293 	if( ydelta < 0 )
2294 	{
2295 	    clipy = oldy;
2296 	    clipymax = clipy + incy;
2297 	}
2298 	else if( ydelta > 0 )
2299 	{
2300 	    clipymax = oldymax;
2301 	    clipy = clipymax - incy;
2302 	}
2303 	else
2304 	{
2305 	    clipy = oldy;
2306 	    clipymax = oldymax;
2307 	}
2308 #endif
2309 	/* Now, in scrollcnt moves, move the picture toward the final view */
2310     	for( i = 0; i < scrollcnt; ++i )
2311     	{
2312 #ifdef	DISPMAP
2313 	    if( i == scrollcnt - 1 && (xmod != 0 || ymod != 0) &&
2314 			(xdelta != 0 || ydelta != 0) )
2315 	    {
2316 		incx += (clipx - oldx)%scrollcnt;
2317 		incy += (clipy - oldy)%scrollcnt;
2318 		xdelta += xmod;
2319 		ydelta += ymod;
2320 	    }
2321 #endif
2322 	    /* Scroll the raster if we are scrolling */
2323 	    if( xdelta != 0 || ydelta != 0 )
2324 	    {
2325 		ScrollRaster( rp, xdelta, ydelta,
2326 			    w->BorderLeft, w->BorderTop,
2327 			    w->Width - w->BorderRight - 1,
2328 			    w->Height - w->BorderBottom - 1 );
2329 
2330 		if( mincx == 0 ) incx = 0;
2331 		else mincx -= incx;
2332 
2333 		clipx += incx;
2334 		clipxmax += incx;
2335 
2336 		if( mincy == 0 ) incy = 0;
2337 		else mincy -= incy;
2338 
2339 		clipy += incy;
2340 		clipymax += incy;
2341 
2342 		/* Draw the exposed portion */
2343 		if (on_level(&u.uz0, &u.uz) && !restoring)
2344 		    (void) doredraw();
2345 		flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
2346 	    }
2347     	}
2348 
2349     	clipx = savex;
2350      	clipy = savey;
2351 	clipymax = saveymax;
2352 	clipxmax = savexmax;
2353 #endif
2354 	if (on_level(&u.uz0, &u.uz) && !restoring && moves > 1)
2355 	    (void) doredraw();
2356 	flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
2357     }
2358     reclip = 0;
2359 #endif
2360 }
2361 
2362 void
flushIDCMP(port)2363 flushIDCMP( port )
2364 	struct MsgPort *port;
2365 {
2366 	struct Message *msg;
2367 	while( msg = GetMsg( port ) )
2368 		ReplyMsg( msg );
2369 }
2370