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