1 /* aNetHack 0.0.1 winfuncs.c $ANH-Date: 1433806596 2015/06/08 23:36:36 $ $ANH-Branch: master $:$ANH-Revision: 1.15 $ */
2 /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996.
4 /* aNetHack may be freely redistributed. See license for details. */
6 #include "NH:sys/amiga/windefs.h"
7 #include "NH:sys/amiga/winext.h"
8 #include "NH:sys/amiga/winproto.h"
9 #include "patchlevel.h"
12 extern struct TagItem scrntags
[];
14 static BitMapHeader amii_bmhd
;
15 static void cursor_common(struct RastPort
*, int, int);
20 /* Changing clipping region, skip clear of screen in overview window. */
23 /* Must be set to at least two or you will get stuck! */
24 int xclipbord
= 4, yclipbord
= 2;
28 struct Rectangle amii_oldover
;
29 struct Rectangle amii_oldmsg
;
31 extern struct TextFont
*RogueFont
;
43 long amii_libvers
= LIBRARY_FONT_VERSION
;
49 extern unsigned short amii_init_map
[AMII_MAXCOLORS
];
50 extern unsigned short amiv_init_map
[AMII_MAXCOLORS
];
61 amii_defpens
[0] = C_BLACK
; /* DETAILPEN */
62 amii_defpens
[1] = C_BLUE
; /* BLOCKPEN */
63 amii_defpens
[2] = C_BROWN
; /* TEXTPEN */
64 amii_defpens
[3] = C_WHITE
; /* SHINEPEN */
65 amii_defpens
[4] = C_BLUE
; /* SHADOWPEN */
66 amii_defpens
[5] = C_CYAN
; /* FILLPEN */
67 amii_defpens
[6] = C_WHITE
; /* FILLTEXTPEN */
68 amii_defpens
[7] = C_CYAN
; /* BACKGROUNDPEN */
69 amii_defpens
[8] = C_RED
; /* HIGHLIGHTTEXTPEN */
70 amii_defpens
[9] = C_WHITE
; /* BARDETAILPEN */
71 amii_defpens
[10] = C_CYAN
; /* BARBLOCKPEN */
72 amii_defpens
[11] = C_BLUE
; /* BARTRIMPEN */
73 amii_defpens
[12] = (unsigned short) ~0;
75 amii_msgAPen
= C_WHITE
;
76 amii_msgBPen
= C_BLACK
;
77 amii_statAPen
= C_WHITE
;
78 amii_statBPen
= C_BLACK
;
79 amii_menuAPen
= C_WHITE
;
80 amii_menuBPen
= C_BLACK
;
81 amii_textAPen
= C_WHITE
;
82 amii_textBPen
= C_BLACK
;
83 amii_otherAPen
= C_RED
;
84 amii_otherBPen
= C_BLACK
;
89 amii_libvers
= LIBRARY_FONT_VERSION
;
90 memcpy(amii_initmap
, amii_init_map
, sizeof(amii_initmap
));
97 amii_defpens
[0] = C_BLACK
; /* DETAILPEN */
98 amii_defpens
[1] = C_WHITE
; /* BLOCKPEN */
99 amii_defpens
[2] = C_BLACK
; /* TEXTPEN */
100 amii_defpens
[3] = C_CYAN
; /* SHINEPEN */
101 amii_defpens
[4] = C_BLUE
; /* SHADOWPEN */
102 amii_defpens
[5] = C_GREYBLUE
; /* FILLPEN */
103 amii_defpens
[6] = C_LTGREY
; /* FILLTEXTPEN */
104 amii_defpens
[7] = C_GREYBLUE
; /* BACKGROUNDPEN */
105 amii_defpens
[8] = C_RED
; /* HIGHLIGHTTEXTPEN */
106 amii_defpens
[9] = C_WHITE
; /* BARDETAILPEN */
107 amii_defpens
[10] = C_GREYBLUE
; /* BARBLOCKPEN */
108 amii_defpens
[11] = C_BLUE
; /* BARTRIMPEN */
109 amii_defpens
[12] = (unsigned short) ~0;
111 amii_msgAPen
= C_WHITE
;
112 amii_msgBPen
= C_GREYBLUE
;
113 amii_statAPen
= C_WHITE
;
114 amii_statBPen
= C_GREYBLUE
;
115 amii_menuAPen
= C_BLACK
;
116 amii_menuBPen
= C_LTGREY
;
117 amii_textAPen
= C_BLACK
;
118 amii_textBPen
= C_LTGREY
;
119 amii_otherAPen
= C_RED
;
120 amii_otherBPen
= C_BLACK
;
121 amii_libvers
= LIBRARY_TILE_VERSION
;
123 memcpy(amii_initmap
, amiv_init_map
, sizeof(amii_initmap
));
128 memcpy(sysflags
.amii_dripens
, amii_defpens
,
129 sizeof(sysflags
.amii_dripens
));
132 #ifdef INTUI_NEW_LOOK
133 struct Hook SM_FilterHook
;
134 struct Hook fillhook
;
135 struct TagItem wintags
[] = {
136 { WA_BackFill
, (ULONG
) &fillhook
},
137 { WA_PubScreenName
, (ULONG
) "aNetHack" },
142 void amii_destroy_nhwindow(win
) /* just hide */
147 register struct amii_WinDesc
*cw
;
149 if (win
== WIN_ERR
|| (cw
= amii_wins
[win
]) == NULL
) {
150 panic(winpanicstr
, win
, "destroy_nhwindow");
154 if (cw
->type
== NHW_MAP
) {
155 /* If inventory is up, close it now, it will be freed later */
156 if (alwaysinvent
&& WIN_INVEN
!= WIN_ERR
&& amii_wins
[WIN_INVEN
]
157 && amii_wins
[WIN_INVEN
]->win
) {
158 dismiss_nhwindow(WIN_INVEN
);
161 /* Tear down overview window if it is up */
162 if (WIN_OVER
!= WIN_ERR
) {
163 amii_destroy_nhwindow(WIN_OVER
);
166 } else if (cw
->type
== NHW_OVER
) {
167 struct Window
*w
= amii_wins
[WIN_OVER
]->win
;
168 amii_oldover
.MinX
= w
->LeftEdge
;
169 amii_oldover
.MinY
= w
->TopEdge
;
170 amii_oldover
.MaxX
= w
->Width
;
171 amii_oldover
.MaxY
= w
->Height
;
173 if (WIN_MESSAGE
!= WIN_ERR
&& amii_wins
[WIN_MESSAGE
]) {
174 w
= amii_wins
[WIN_MESSAGE
]->win
;
175 amii_oldmsg
.MinX
= w
->LeftEdge
;
176 amii_oldmsg
.MinY
= w
->TopEdge
;
177 amii_oldmsg
.MaxX
= w
->Width
;
178 amii_oldmsg
.MaxY
= w
->Height
;
179 SizeWindow(amii_wins
[WIN_MESSAGE
]->win
,
181 - amii_wins
[WIN_MESSAGE
]->win
->LeftEdge
)
182 - amii_wins
[WIN_MESSAGE
]->win
->Width
,
188 /* Tear down the Intuition stuff */
189 dismiss_nhwindow(win
);
209 if (cw
->data
&& (cw
->type
== NHW_MESSAGE
|| cw
->type
== NHW_MENU
210 || cw
->type
== NHW_TEXT
)) {
211 for (i
= 0; i
< cw
->maxrow
; ++i
) {
219 amii_wins
[win
] = NULL
;
221 /* Set globals to WIN_ERR for known one-of-a-kind windows. */
224 else if (win
== WIN_STATUS
)
225 WIN_STATUS
= WIN_ERR
;
226 else if (win
== WIN_MESSAGE
)
227 WIN_MESSAGE
= WIN_ERR
;
228 else if (win
== WIN_INVEN
)
232 #ifdef INTUI_NEW_LOOK
235 struct Rectangle bounds
;
242 void PPC_LayerFillHook(void);
243 struct EmulLibEntry LayerFillHook
= { TRAP_LIB
, 0,
244 (void (*)(void)) PPC_LayerFillHook
};
246 PPC_LayerFillHook(void)
248 struct Hook
*hk
= (struct Hook
*) REG_A0
;
249 struct RastPort
*rp
= (struct RastPort
*) REG_A2
;
250 struct FillParams
*fp
= (struct FillParams
*) REG_A1
;
255 register struct Hook
*hk
asm("a0");
256 register struct RastPort
*rp
asm("a2");
257 register struct FillParams
*fp
asm("a1");
264 __saveds __asm
LayerFillHook(register __a0
struct Hook
*hk
,
265 register __a2
struct RastPort
*rp
,
266 register __a1
struct FillParams
*fp
)
270 register long x
, y
, xmax
, ymax
;
272 struct RastPort rptmp
;
274 memcpy(&rptmp
, rp
, sizeof(struct RastPort
));
277 switch ((int) hk
->h_Data
) {
279 apen
= amii_statBPen
;
285 apen
= amii_textBPen
;
288 apen
= amii_menuBPen
;
291 apen
= amii_otherBPen
;
303 xmax
= fp
->bounds
.MaxX
;
304 ymax
= fp
->bounds
.MaxY
;
306 SetAPen(&rptmp
, apen
);
307 SetBPen(&rptmp
, apen
);
308 SetDrMd(&rptmp
, JAM2
);
309 RectFill(&rptmp
, x
, y
, xmax
, ymax
);
313 amii_create_nhwindow(type
) register int type
;
315 register struct Window
*w
= NULL
;
316 register struct NewWindow
*nw
= NULL
;
317 register struct amii_WinDesc
*wd
= NULL
;
318 struct Window
*mapwin
= NULL
, *stwin
= NULL
, *msgwin
= NULL
;
320 int maph
, stath
, scrfontysize
;
322 scrfontysize
= HackScreen
->Font
->ta_YSize
;
325 * Initial mapwindow height, this might change later in tilemode
328 maph
= (21 * mxsize
) + 2
330 ? HackScreen
->WBorTop
+ HackScreen
->WBorBottom
334 /* Status window height, avoids having to calculate many times */
336 txheight
* 2 + 2 + (WINVERS_AMIV
|| bigscreen
337 ? HackScreen
->WBorTop
+ HackScreen
->WBorBottom
338 + (bigscreen
? scrfontysize
+ 1 : 0)
341 if (WIN_STATUS
!= WIN_ERR
&& amii_wins
[WIN_STATUS
])
342 stwin
= amii_wins
[WIN_STATUS
]->win
;
344 if (WIN_MESSAGE
!= WIN_ERR
&& amii_wins
[WIN_MESSAGE
])
345 msgwin
= amii_wins
[WIN_MESSAGE
]->win
;
347 if (WIN_MAP
!= WIN_ERR
&& amii_wins
[WIN_MAP
])
348 mapwin
= amii_wins
[WIN_MAP
]->win
;
350 /* Create Port anytime that we need it */
352 if (HackPort
== NULL
) {
353 HackPort
= CreateMsgPort();
355 panic("no memory for msg port");
358 nw
= &new_wins
[type
].newwin
;
359 nw
->Width
= amiIDisplay
->xpix
;
360 nw
->Screen
= HackScreen
;
363 nw
->DetailPen
= C_WHITE
;
364 nw
->BlockPen
= C_GREYBLUE
;
366 nw
->DetailPen
= C_WHITE
;
367 nw
->BlockPen
= C_BLACK
;
370 if (type
== NHW_BASE
) {
372 nw
->TopEdge
= HackScreen
->BarHeight
+ 1;
373 nw
->Width
= HackScreen
->Width
;
374 nw
->Height
= HackScreen
->Height
- nw
->TopEdge
;
375 } else if (!WINVERS_AMIV
&& type
== NHW_MAP
) {
379 if (msgwin
&& stwin
) {
380 nw
->TopEdge
= stwin
->TopEdge
- maph
;
382 panic("msgwin and stwin must open before map");
385 panic("Too small screen to fit map");
386 } else if (type
== NHW_MAP
&& WINVERS_AMIV
) {
389 w
= amii_wins
[WIN_MESSAGE
]->win
;
391 nw
->TopEdge
= w
->TopEdge
+ w
->Height
;
392 nw
->Width
= amiIDisplay
->xpix
- nw
->LeftEdge
;
394 w
= amii_wins
[WIN_STATUS
]->win
;
395 nw
->Height
= w
->TopEdge
- nw
->TopEdge
;
396 nw
->MaxHeight
= 0xffff;
397 nw
->MaxWidth
= 0xffff;
399 if (nw
->TopEdge
+ nw
->Height
> amiIDisplay
->ypix
- 1)
400 nw
->Height
= amiIDisplay
->ypix
- nw
->TopEdge
- 1;
401 } else if (type
== NHW_STATUS
) {
402 if (!WINVERS_AMIV
&& (WIN_MAP
!= WIN_ERR
&& amii_wins
[WIN_MAP
]))
403 w
= amii_wins
[WIN_MAP
]->win
;
404 else if (WIN_BASE
!= WIN_ERR
&& amii_wins
[WIN_BASE
])
405 w
= amii_wins
[WIN_BASE
]->win
;
407 panic("No window to base STATUS location from");
410 nw
->TopEdge
= amiIDisplay
->ypix
- nw
->Height
;
411 nw
->LeftEdge
= w
->LeftEdge
;
413 if (nw
->LeftEdge
+ nw
->Width
>= amiIDisplay
->xpix
)
416 if (nw
->Width
>= amiIDisplay
->xpix
- nw
->LeftEdge
)
417 nw
->Width
= amiIDisplay
->xpix
- nw
->LeftEdge
;
418 } else if (WINVERS_AMIV
&& type
== NHW_OVER
) {
419 nw
->Flags
|= WINDOWSIZING
| WINDOWDRAG
| WINDOWCLOSE
;
420 nw
->IDCMPFlags
|= CLOSEWINDOW
;
421 /* Bring up window as half the width of the message window, and make
422 * the message window change to one half the width...
424 if (amii_oldover
.MaxX
!= 0) {
425 nw
->LeftEdge
= amii_oldover
.MinX
;
426 nw
->TopEdge
= amii_oldover
.MinY
;
427 nw
->Width
= amii_oldover
.MaxX
;
428 nw
->Height
= amii_oldover
.MaxY
;
429 ChangeWindowBox(amii_wins
[WIN_MESSAGE
]->win
, amii_oldmsg
.MinX
,
430 amii_oldmsg
.MinY
, amii_oldmsg
.MaxX
,
433 nw
->LeftEdge
= (amii_wins
[WIN_MESSAGE
]->win
->Width
* 4) / 9;
434 nw
->TopEdge
= amii_wins
[WIN_MESSAGE
]->win
->TopEdge
;
435 nw
->Width
= amiIDisplay
->xpix
- nw
->LeftEdge
;
436 nw
->Height
= amii_wins
[WIN_MESSAGE
]->win
->Height
;
437 SizeWindow(amii_wins
[WIN_MESSAGE
]->win
,
438 nw
->LeftEdge
- amii_wins
[WIN_MESSAGE
]->win
->Width
, 0);
440 } else if (type
== NHW_MESSAGE
) {
441 if (!WINVERS_AMIV
&& (WIN_MAP
!= WIN_ERR
&& amii_wins
[WIN_MAP
]))
442 w
= amii_wins
[WIN_MAP
]->win
;
443 else if (WIN_BASE
!= WIN_ERR
&& amii_wins
[WIN_BASE
])
444 w
= amii_wins
[WIN_BASE
]->win
;
446 panic("No window to base STATUS location from");
448 nw
->TopEdge
= bigscreen
? HackScreen
->BarHeight
+ 1 : 0;
450 /* Assume highest possible message window */
451 nw
->Height
= HackScreen
->Height
- nw
->TopEdge
- maph
- stath
;
453 /* In tilemode we can cope with this */
454 if (WINVERS_AMIV
&& nw
->Height
< 0)
457 /* If in fontmode messagewindow is too small, open it with 3 lines
458 and overlap it with map */
459 if (nw
->Height
< txheight
+ 2) {
460 nw
->Height
= txheight
* 4 + 3 + HackScreen
->WBorTop
461 + HackScreen
->WBorBottom
;
464 if ((nw
->Height
- 2) / txheight
< 3) {
468 nw
->FirstGadget
= &MsgScroll
;
469 nw
->Flags
|= WINDOWSIZING
| WINDOWDRAG
;
470 nw
->Flags
&= ~BORDERLESS
;
472 if (WINVERS_AMIV
|| nw
->Height
== 0) {
474 nw
->Height
= TextsFont
->tf_YSize
+ HackScreen
->WBorTop
+ 3
475 + HackScreen
->WBorBottom
;
477 nw
->Height
+= (txheight
* 6);
479 nw
->Height
+= (txheight
* 3);
482 HackScreen
->Height
- nw
->TopEdge
- stath
- maph
;
487 /* Do we have room for larger message window ?
488 * This is possible if we can show full height map in tile
489 * mode with default scaling.
491 if (nw
->Height
+ stath
+ maph
< HackScreen
->Height
- nw
->TopEdge
)
492 nw
->Height
= HackScreen
->Height
- nw
->TopEdge
- 1 - maph
- stath
;
494 #ifdef INTUI_NEW_LOOK
495 if (IntuitionBase
->LibNode
.lib_Version
>= 37) {
496 MsgPropScroll
.Flags
|= PROPNEWLOOK
;
497 PropScroll
.Flags
|= PROPNEWLOOK
;
502 nw
->IDCMPFlags
|= MENUPICK
;
504 /* Check if there is "Room" for all this stuff... */
505 if ((WINVERS_AMIV
|| bigscreen
) && type
!= NHW_BASE
) {
506 nw
->Flags
&= ~(BORDERLESS
| BACKDROP
);
509 if (type
== NHW_STATUS
) {
511 ~(WINDOWDRAG
| WINDOWDEPTH
| SIZEBRIGHT
| WINDOWSIZING
);
512 nw
->IDCMPFlags
&= ~NEWSIZE
;
515 (WINDOWDRAG
| WINDOWDEPTH
| SIZEBRIGHT
| WINDOWSIZING
);
516 nw
->IDCMPFlags
|= NEWSIZE
;
519 if (HackScreen
->Width
< 657) {
520 nw
->Flags
|= (WINDOWDRAG
| WINDOWDEPTH
);
522 nw
->Flags
|= (WINDOWDRAG
| WINDOWDEPTH
| SIZEBRIGHT
);
527 if (WINVERS_AMII
&& type
== NHW_MAP
)
528 nw
->Flags
&= ~WINDOWSIZING
;
530 if (type
== NHW_MESSAGE
&& scrollmsg
) {
531 nw
->Flags
|= WINDOWDRAG
| WINDOWDEPTH
| SIZEBRIGHT
| WINDOWSIZING
;
532 nw
->Flags
&= ~BORDERLESS
;
535 /* No titles on a hires only screen except for messagewindow */
536 if (!(WINVERS_AMIV
&& type
== NHW_MAP
) && !bigscreen
537 && type
!= NHW_MESSAGE
)
540 wd
= (struct amii_WinDesc
*) alloc(sizeof(struct amii_WinDesc
));
541 memset(wd
, 0, sizeof(struct amii_WinDesc
));
543 /* Both, since user may have changed the pen settings so respect those */
544 if (WINVERS_AMII
|| WINVERS_AMIV
) {
545 /* Special backfill for these types of layers */
556 fillhook
.h_Entry
= (void *) &LayerFillHook
;
558 fillhook
.h_Entry
= (ULONG (*) ()) LayerFillHook
;
560 fillhook
.h_Data
= (void *) type
;
561 fillhook
.h_SubEntry
= 0;
562 wd
->hook
= alloc(sizeof(fillhook
));
563 memcpy(wd
->hook
, &fillhook
, sizeof(fillhook
));
564 memcpy(wd
->wintags
, wintags
, sizeof(wd
->wintags
));
565 wd
->wintags
[0].ti_Data
= (long) wd
->hook
;
566 nw
->Extension
= (void *) wd
->wintags
;
572 /* Don't open MENU or TEXT windows yet */
574 if (type
== NHW_MENU
|| type
== NHW_TEXT
)
577 w
= OpenShWindow((void *) nw
);
579 if (w
== NULL
&& type
!= NHW_MENU
&& type
!= NHW_TEXT
) {
582 sprintf(buf
, "nw type (%d) dims l: %d, t: %d, w: %d, h: %d", type
,
583 nw
->LeftEdge
, nw
->TopEdge
, nw
->Width
, nw
->Height
);
585 panic("bad openwin %d", type
);
588 /* Check for an empty slot */
590 for (newid
= 0; newid
< MAXWIN
+ 1; newid
++) {
591 if (amii_wins
[newid
] == 0)
595 if (newid
== MAXWIN
+ 1)
596 panic("time to write re-alloc code\n");
598 /* Set wincnt accordingly */
603 /* Do common initialization */
605 amii_wins
[newid
] = wd
;
612 wd
->curx
= wd
->cury
= 0;
613 wd
->resp
= wd
->canresp
= wd
->morestr
= 0; /* CHECK THESE */
614 wd
->maxrow
= new_wins
[type
].maxrow
;
615 wd
->maxcol
= new_wins
[type
].maxcol
;
617 if (type
!= NHW_TEXT
&& type
!= NHW_MENU
) {
618 if (TextsFont
&& (type
== NHW_MESSAGE
|| type
== NHW_STATUS
)) {
619 SetFont(w
->RPort
, TextsFont
);
620 txheight
= w
->RPort
->TxHeight
;
621 txwidth
= w
->RPort
->TxWidth
;
622 txbaseline
= w
->RPort
->TxBaseline
;
623 if (type
== NHW_MESSAGE
) {
626 WindowLimits(w
, 100, w
->BorderTop
+ w
->BorderBottom
627 + ((txheight
+ 1) * 2) + 1,
630 WindowLimits(w
, w
->Width
,
631 w
->BorderTop
+ w
->BorderBottom
632 + ((txheight
+ 1) * 2) + 1,
636 WindowLimits(w
, w
->Width
, w
->BorderTop
+ w
->BorderBottom
642 if (type
!= NHW_MAP
) {
643 SetFont(w
->RPort
, TextsFont
);
647 SetFont(w
->RPort
, HackFont
);
651 /* Text and menu windows are not opened yet */
653 wd
->rows
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2)
654 / w
->RPort
->TxHeight
;
655 wd
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 2)
659 /* Okay, now do the individual type initialization */
662 /* History lines for MESSAGE windows are stored in cw->data[?].
663 * maxcol and maxrow are used as cursors. maxrow is the count
664 * of the number of history lines stored. maxcol is the cursor
665 * to the last line that was displayed by ^P.
668 SetMenuStrip(w
, MenuStrip
);
669 MsgScroll
.TopEdge
= HackScreen
->WBorTop
+ scrfontysize
+ 1;
670 iflags
.msg_history
= wd
->rows
* 10;
671 if (iflags
.msg_history
< 40)
672 iflags
.msg_history
= 40;
673 if (iflags
.msg_history
> 400)
674 iflags
.msg_history
= 400;
675 iflags
.window_inited
= TRUE
;
676 wd
->data
= (char **) alloc(iflags
.msg_history
* sizeof(char *));
677 memset(wd
->data
, 0, iflags
.msg_history
* sizeof(char *));
678 wd
->maxrow
= wd
->maxcol
= 0;
679 /* Indicate that we have not positioned the cursor yet */
683 /* A MENU contains a list of lines in wd->data[?]. These
684 * lines are created in amii_putstr() by reallocating the size
685 * of wd->data to hold enough (char *)'s. wd->rows is the
686 * number of (char *)'s allocated. wd->maxrow is the number
687 * used. wd->maxcol is used to track how wide the menu needs
688 * to be. wd->resp[x] contains the characters that correspond
689 * to selecting wd->data[x]. wd->resp[x] corresponds to
690 * wd->data[x] for any x. Elements of wd->data[?] that are not
691 * valid selections have the corresponding element of
692 * wd->resp[] set to a value of '\01'; i.e. a ^A which is
693 * not currently a valid keystroke for responding to any
694 * MENU or TEXT window.
697 MenuScroll
.TopEdge
= HackScreen
->WBorTop
+ scrfontysize
+ 1;
698 wd
->resp
= (char *) alloc(256);
700 wd
->rows
= wd
->maxrow
= 0;
701 wd
->cols
= wd
->maxcol
= 0;
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
711 MenuScroll
.TopEdge
= HackScreen
->WBorTop
+ scrfontysize
+ 1;
712 wd
->rows
= wd
->maxrow
= 0;
713 wd
->cols
= wd
->maxcol
= amiIDisplay
->cols
;
718 /* The status window has only two lines. These are stored in
719 * wd->data[], and here we allocate the space for them.
722 SetMenuStrip(w
, MenuStrip
);
723 /* wd->cols is the number of characters which fit across the
726 wd
->data
= (char **) alloc(3 * sizeof(char *));
727 wd
->data
[0] = (char *) alloc(wd
->cols
+ 10);
728 wd
->data
[1] = (char *) alloc(wd
->cols
+ 10);
732 /* NHW_OVER does not use wd->data[] or the other text
733 * manipulating members of the amii_WinDesc structure.
736 SetMenuStrip(w
, MenuStrip
);
739 /* NHW_MAP does not use wd->data[] or the other text
740 * manipulating members of the amii_WinDesc structure.
743 SetMenuStrip(w
, MenuStrip
);
745 CO
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
) / mxsize
;
746 LI
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
) / mysize
;
748 SetFont(w
->RPort
, RogueFont
);
749 SetAPen(w
->RPort
, C_WHITE
); /* XXX not sufficient */
750 SetBPen(w
->RPort
, C_BLACK
);
751 SetDrMd(w
->RPort
, JAM2
);
754 SetFont(w
->RPort
, HackFont
);
758 /* The base window must exist until CleanUp() deletes it. */
760 SetMenuStrip(w
, MenuStrip
);
761 /* Make our requesters come to our screen */
763 register struct Process
*myProcess
=
764 (struct Process
*) FindTask(NULL
);
765 pr_WindowPtr
= (struct Window
*) (myProcess
->pr_WindowPtr
);
766 myProcess
->pr_WindowPtr
= (APTR
) w
;
769 /* Need this for RawKeyConvert() */
771 ConsoleIO
.io_Data
= (APTR
) w
;
772 ConsoleIO
.io_Length
= sizeof(struct Window
);
773 ConsoleIO
.io_Message
.mn_ReplyPort
= CreateMsgPort();
774 if (OpenDevice("console.device", -1L, (struct IORequest
*) &ConsoleIO
,
776 Abort(AG_OpenDev
| AO_ConsoleDev
);
779 ConsoleDevice
= (struct Library
*) ConsoleIO
.io_Device
;
785 SetFont(w
->RPort
, TextsFont
);
787 SetFont(w
->RPort
, HackFont
);
789 txwidth
= w
->RPort
->TxWidth
;
790 txheight
= w
->RPort
->TxHeight
;
791 txbaseline
= w
->RPort
->TxBaseline
;
795 panic("bad create_nhwindow( %d )\n", type
);
804 int PPC_SM_Filter(void);
805 struct EmulLibEntry SM_Filter
= { TRAP_LIB
, 0,
806 (int (*)(void)) PPC_SM_Filter
};
810 struct Hook
*hk
= (struct Hook
*) REG_A0
;
811 ULONG modeID
= (ULONG
) REG_A1
;
812 struct ScreenModeRequester
*smr
= (struct ScreenModeRequester
*) REG_A2
;
817 register struct Hook
*hk
asm("a0");
818 register ULONG modeID
asm("a1");
819 register struct ScreenModeRequester
*smr
asm("a2");
826 __saveds __asm
SM_Filter(
827 register __a0
struct Hook
*hk
, register __a1 ULONG modeID
,
828 register __a2
struct ScreenModeRequester
*smr
)
831 struct DimensionInfo dims
;
832 struct DisplayInfo disp
;
833 DisplayInfoHandle handle
;
834 handle
= FindDisplayInfo(modeID
);
836 GetDisplayInfoData(handle
, (char *) &dims
, sizeof(dims
), DTAG_DIMS
,
838 GetDisplayInfoData(handle
, (char *) &disp
, sizeof(disp
), DTAG_DISP
,
840 if (!disp
.NotAvailable
&& dims
.MaxDepth
<= 8
841 && dims
.StdOScan
.MaxX
>= WIDTH
- 1
842 && dims
.StdOScan
.MaxY
>= SCREENHEIGHT
- 1) {
849 /* Initialize the windowing environment */
852 amii_init_nhwindows(argcp
, argv
)
857 struct Screen
*wbscr
;
861 panic("init_nhwindows() called twice", 0);
863 /* run args & set bigscreen from -L(1)/-l(-1) */
865 int lclargc
= *argcp
;
867 char **argv_in
= argv
;
868 char **argv_out
= argv
;
870 for (t
= 1; t
<= lclargc
; t
++) {
871 if (!strcmp("-L", *argv_in
) || !strcmp("-l", *argv_in
)) {
872 bigscreen
= (*argv_in
[1] == 'l') ? -1 : 1;
873 /* and eat the flag */
876 *argv_out
= *argv_in
; /* keep the flag */
884 WIN_MESSAGE
= WIN_ERR
;
886 WIN_STATUS
= WIN_ERR
;
891 if ((IntuitionBase
= (struct IntuitionBase
*) OpenLibrary(
892 "intuition.library", amii_libvers
)) == NULL
) {
893 Abort(AG_OpenLib
| AO_Intuition
);
896 if ((GfxBase
= (struct GfxBase
*) OpenLibrary("graphics.library",
897 amii_libvers
)) == NULL
) {
898 Abort(AG_OpenLib
| AO_GraphicsLib
);
901 if ((LayersBase
= (struct Library
*) OpenLibrary("layers.library",
902 amii_libvers
)) == NULL
) {
903 Abort(AG_OpenLib
| AO_LayersLib
);
906 if ((GadToolsBase
= OpenLibrary("gadtools.library", amii_libvers
))
908 Abort(AG_OpenLib
| AO_GadTools
);
911 if ((AslBase
= OpenLibrary("asl.library", amii_libvers
)) == NULL
) {
916 (struct amii_DisplayDesc
*) alloc(sizeof(struct amii_DisplayDesc
));
917 memset(amiIDisplay
, 0, sizeof(struct amii_DisplayDesc
));
919 /* Use Intuition sizes for overscan screens... */
921 amiIDisplay
->xpix
= 0;
922 #ifdef INTUI_NEW_LOOK
923 if (IntuitionBase
->LibNode
.lib_Version
>= 37) {
924 if (wbscr
= LockPubScreen("Workbench")) {
925 amiIDisplay
->xpix
= wbscr
->Width
;
926 amiIDisplay
->ypix
= wbscr
->Height
;
927 UnlockPubScreen(NULL
, wbscr
);
931 if (amiIDisplay
->xpix
== 0) {
932 amiIDisplay
->ypix
= GfxBase
->NormalDisplayRows
;
933 amiIDisplay
->xpix
= GfxBase
->NormalDisplayColumns
;
936 amiIDisplay
->cols
= amiIDisplay
->xpix
/ FONTWIDTH
;
938 amiIDisplay
->toplin
= 0;
939 amiIDisplay
->rawprint
= 0;
940 amiIDisplay
->lastwin
= 0;
942 if (bigscreen
== 0) {
943 if ((GfxBase
->ActiView
->ViewPort
->Modes
& LACE
) == LACE
) {
944 amiIDisplay
->ypix
*= 2;
945 NewHackScreen
.ViewModes
|= LACE
;
947 } else if (GfxBase
->NormalDisplayRows
>= 300
948 || amiIDisplay
->ypix
>= 300) {
951 } else if (bigscreen
== -1) {
954 } else if (bigscreen
) {
955 /* If bigscreen requested and we don't have enough rows in
956 * noninterlaced mode, switch to interlaced...
958 if (GfxBase
->NormalDisplayRows
< 300) {
959 amiIDisplay
->ypix
*= 2;
960 NewHackScreen
.ViewModes
|= LACE
;
967 amiIDisplay
->rows
= amiIDisplay
->ypix
/ FONTHEIGHT
;
971 * Load the fonts that we need.
974 if (DiskfontBase
= OpenLibrary("diskfont.library", amii_libvers
)) {
975 Hack80
.ta_Name
-= SIZEOF_DISKNAME
;
976 HackFont
= OpenDiskFont(&Hack80
);
977 Hack80
.ta_Name
+= SIZEOF_DISKNAME
;
979 /* Textsfont13 is filled in with "FONT=" settings. The default is
984 TextsFont
= OpenDiskFont(&TextsFont13
);
986 /* Try hack/8 for texts if no user specified font */
987 if (TextsFont
== NULL
) {
988 Hack80
.ta_Name
-= SIZEOF_DISKNAME
;
989 TextsFont
= OpenDiskFont(&Hack80
);
990 Hack80
.ta_Name
+= SIZEOF_DISKNAME
;
993 /* If no fonts, make everything topaz 8 for non-view windows.
995 Hack80
.ta_Name
= "topaz.font";
996 RogueFont
= OpenFont(&Hack80
);
998 panic("Can't get topaz:8");
999 if (!HackFont
|| !TextsFont
) {
1001 HackFont
= OpenFont(&Hack80
);
1003 panic("Can't get a map font, topaz:8");
1007 TextsFont
= OpenFont(&Hack80
);
1009 panic("Can't open text font");
1012 CloseLibrary(DiskfontBase
);
1013 DiskfontBase
= NULL
;
1017 /* Adjust getlin window size to font */
1020 extern SHORT BorderVectors1
[];
1021 extern SHORT BorderVectors2
[];
1022 extern struct Gadget Gadget2
;
1023 extern struct Gadget String
;
1024 extern struct NewWindow StrWindow
;
1025 BorderVectors1
[2] +=
1026 (TextsFont
->tf_XSize
- 8) * 6; /* strlen("Cancel") == 6 */
1027 BorderVectors1
[4] += (TextsFont
->tf_XSize
- 8) * 6;
1028 BorderVectors1
[5] += TextsFont
->tf_YSize
- 8;
1029 BorderVectors1
[7] += TextsFont
->tf_YSize
- 8;
1030 BorderVectors2
[2] += (TextsFont
->tf_XSize
- 8) * 6;
1031 BorderVectors2
[4] += (TextsFont
->tf_XSize
- 8) * 6;
1032 BorderVectors2
[5] += TextsFont
->tf_YSize
- 8;
1033 BorderVectors2
[7] += TextsFont
->tf_YSize
- 8;
1034 Gadget2
.TopEdge
+= TextsFont
->tf_YSize
- 8;
1035 Gadget2
.Width
+= (TextsFont
->tf_XSize
- 8) * 6;
1036 Gadget2
.Height
+= TextsFont
->tf_YSize
- 8;
1037 String
.LeftEdge
+= (TextsFont
->tf_XSize
- 8) * 6;
1038 String
.TopEdge
+= TextsFont
->tf_YSize
- 8;
1039 String
.Width
+= TextsFont
->tf_XSize
- 8;
1040 String
.Height
+= TextsFont
->tf_YSize
- 8;
1041 StrWindow
.Width
+= (TextsFont
->tf_XSize
- 8) * 7;
1043 (TextsFont
->tf_YSize
- 8) * 2; /* Titlebar + 1 row of gadgets */
1046 /* This is the size screen we want to open, within reason... */
1048 NewHackScreen
.Width
= max(WIDTH
, amiIDisplay
->xpix
);
1049 NewHackScreen
.Height
= max(SCREENHEIGHT
, amiIDisplay
->ypix
);
1051 static char fname
[18];
1052 sprintf(fname
, "aNetHack %d.%d.%d", VERSION_MAJOR
, VERSION_MINOR
,
1054 NewHackScreen
.DefaultTitle
= fname
;
1057 NewHackScreen
.BlockPen
= C_BLACK
;
1058 NewHackScreen
.DetailPen
= C_WHITE
;
1060 #ifdef INTUI_NEW_LOOK
1061 if (IntuitionBase
->LibNode
.lib_Version
>= 37) {
1063 struct DimensionInfo dims
;
1064 DisplayInfoHandle handle
;
1065 struct DisplayInfo disp
;
1066 ULONG modeid
= DEFAULT_MONITOR_ID
| HIRES_KEY
;
1068 NewHackScreen
.Width
= STDSCREENWIDTH
;
1069 NewHackScreen
.Height
= STDSCREENHEIGHT
;
1073 NewHackScreen
.Font
= &TextsFont13
;
1077 if (amii_scrnmode
== 0xffffffff) {
1078 struct ScreenModeRequester
*SMR
;
1080 SM_FilterHook
.h_Entry
= (void *) &SM_Filter
;
1082 SM_FilterHook
.h_Entry
= (ULONG (*) ()) SM_Filter
;
1084 SM_FilterHook
.h_Data
= 0;
1085 SM_FilterHook
.h_SubEntry
= 0;
1086 SMR
= AllocAslRequest(ASL_ScreenModeRequest
, NULL
);
1087 if (AslRequestTags(SMR
, ASLSM_FilterFunc
, (ULONG
) &SM_FilterHook
,
1089 amii_scrnmode
= SMR
->sm_DisplayID
;
1092 FreeAslRequest(SMR
);
1095 if (forcenobig
== 0) {
1096 if ((wbscr
= LockPubScreen("Workbench")) != NULL
1097 || (wbscr
= LockPubScreen(NULL
)) != NULL
) {
1098 /* Get the default pub screen's size */
1099 modeid
= GetVPModeID(&wbscr
->ViewPort
);
1100 if (modeid
== INVALID_ID
|| ModeNotAvailable(modeid
)
1101 || (handle
= FindDisplayInfo(modeid
)) == NULL
1102 || GetDisplayInfoData(handle
, (char *) &dims
,
1103 sizeof(dims
), DTAG_DIMS
,
1105 || GetDisplayInfoData(handle
, (char *) &disp
,
1106 sizeof(disp
), DTAG_DISP
,
1108 modeid
= DEFAULT_MONITOR_ID
| HIRES_KEY
;
1109 /* If the display database seems to not work, use the
1113 NewHackScreen
.Height
= wbscr
->Height
;
1114 NewHackScreen
.Width
= wbscr
->Width
;
1117 * Request LACE if it looks laced. For 2.1/3.0, we will
1119 * promoted to the users choice of modes (if promotion is
1121 * If the user is using a dragable screen, things will get
1123 * but that is life...
1125 if (wbscr
->ViewPort
.Modes
& LACE
)
1126 NewHackScreen
.ViewModes
|= LACE
;
1129 /* Use the display database to get the correct information
1131 if (disp
.PropertyFlags
& DIPF_IS_LACE
)
1132 NewHackScreen
.ViewModes
|= LACE
;
1133 NewHackScreen
.Height
= dims
.StdOScan
.MaxY
+ 1;
1134 NewHackScreen
.Width
= dims
.StdOScan
.MaxX
+ 1;
1136 NewHackScreen
.TopEdge
= 0;
1137 NewHackScreen
.LeftEdge
= 0;
1139 UnlockPubScreen(NULL
, wbscr
);
1143 for (i
= 0; scrntags
[i
].ti_Tag
!= TAG_DONE
; ++i
) {
1144 switch (scrntags
[i
].ti_Tag
) {
1146 if (!amii_scrnmode
|| ModeNotAvailable(amii_scrnmode
)) {
1147 if (ModeNotAvailable(modeid
)) {
1148 scrntags
[i
].ti_Tag
= TAG_IGNORE
;
1151 scrntags
[i
].ti_Data
= (long) modeid
;
1153 modeid
= scrntags
[i
].ti_Data
= (long) amii_scrnmode
;
1154 if ((handle
= FindDisplayInfo(modeid
)) != NULL
1155 && GetDisplayInfoData(handle
, (char *) &dims
,
1156 sizeof(dims
), DTAG_DIMS
, modeid
) > 0
1157 && GetDisplayInfoData(handle
, (char *) &disp
,
1158 sizeof(disp
), DTAG_DISP
,
1160 if (disp
.PropertyFlags
& DIPF_IS_LACE
)
1161 NewHackScreen
.ViewModes
|= LACE
;
1162 NewHackScreen
.Height
= dims
.StdOScan
.MaxY
+ 1;
1163 NewHackScreen
.Width
= dims
.StdOScan
.MaxX
+ 1;
1168 scrntags
[i
].ti_Data
= (long) sysflags
.amii_dripens
;
1176 amii_bmhd
= ReadTileImageFiles();
1178 memcpy(amii_initmap
, amii_init_map
, sizeof(amii_initmap
));
1179 memcpy(sysflags
.amii_curmap
, amii_initmap
, sizeof(sysflags
.amii_curmap
));
1181 /* Find out how deep the screen needs to be, 32 planes is enough! */
1182 for (i
= 0; i
< 32; ++i
) {
1183 if ((1L << i
) >= amii_numcolors
)
1187 NewHackScreen
.Depth
= i
;
1189 /* If for some reason Height/Width became smaller than the required,
1190 have the required one */
1191 if (NewHackScreen
.Height
< SCREENHEIGHT
)
1192 NewHackScreen
.Height
= SCREENHEIGHT
;
1193 if (NewHackScreen
.Width
< WIDTH
)
1194 NewHackScreen
.Width
= WIDTH
;
1196 i
= max(TextsFont
->tf_XSize
, HackFont
->tf_XSize
);
1197 if (NewHackScreen
.Width
< 80 * i
+ 4)
1198 NewHackScreen
.Width
= 80 * i
+ 4;
1201 /* While openscreen fails try fewer colors to see if that is the problem.
1203 while ((HackScreen
= OpenScreen((void *) &NewHackScreen
)) == NULL
) {
1205 if (--NewHackScreen
.Depth
< 3)
1207 if (--NewHackScreen
.Depth
< 2)
1209 Abort(AN_OpenScreen
& ~AT_DeadEnd
);
1211 amii_numcolors
= 1L << NewHackScreen
.Depth
;
1212 if (HackScreen
->Height
> 300 && forcenobig
== 0)
1217 #ifdef INTUI_NEW_LOOK
1218 if (IntuitionBase
->LibNode
.lib_Version
>= 37)
1219 PubScreenStatus(HackScreen
, 0);
1222 amiIDisplay
->ypix
= HackScreen
->Height
;
1223 amiIDisplay
->xpix
= HackScreen
->Width
;
1225 LoadRGB4(&HackScreen
->ViewPort
, sysflags
.amii_curmap
, amii_numcolors
);
1227 VisualInfo
= GetVisualInfo(HackScreen
, TAG_END
);
1228 MenuStrip
= CreateMenus(GTHackMenu
, TAG_END
);
1229 LayoutMenus(MenuStrip
, VisualInfo
, GTMN_NewLookMenus
, TRUE
, TAG_END
);
1231 /* Display the copyright etc... */
1233 if (WIN_BASE
== WIN_ERR
)
1234 WIN_BASE
= amii_create_nhwindow(NHW_BASE
);
1235 amii_clear_nhwindow(WIN_BASE
);
1236 amii_putstr(WIN_BASE
, 0, "");
1237 amii_putstr(WIN_BASE
, 0, "");
1238 amii_putstr(WIN_BASE
, 0, "");
1239 amii_putstr(WIN_BASE
, 0, COPYRIGHT_BANNER_A
);
1240 amii_putstr(WIN_BASE
, 0, COPYRIGHT_BANNER_B
);
1241 amii_putstr(WIN_BASE
, 0, COPYRIGHT_BANNER_C
);
1242 amii_putstr(WIN_BASE
, 0, COPYRIGHT_BANNER_D
);
1243 amii_putstr(WIN_BASE
, 0, "");
1249 amii_sethipens(struct Window
*w
, int type
, int attr
)
1253 SetAPen(w
->RPort
, attr
? C_RED
: amii_otherAPen
);
1254 SetBPen(w
->RPort
, C_BLACK
);
1257 SetAPen(w
->RPort
, attr
? C_WHITE
: amii_statAPen
);
1258 SetBPen(w
->RPort
, amii_statBPen
);
1261 SetAPen(w
->RPort
, attr
? C_WHITE
: amii_msgAPen
);
1262 SetBPen(w
->RPort
, amii_msgBPen
);
1265 SetAPen(w
->RPort
, attr
? C_BLACK
: amii_menuAPen
);
1266 SetBPen(w
->RPort
, amii_menuBPen
);
1269 SetAPen(w
->RPort
, attr
? C_BLACK
: amii_textAPen
);
1270 SetBPen(w
->RPort
, amii_textBPen
);
1272 SetBPen(w
->RPort
, amii_otherBPen
);
1273 SetAPen(w
->RPort
, attr
? C_RED
: amii_otherAPen
);
1279 amii_setfillpens(struct Window
*w
, int type
)
1283 SetAPen(w
->RPort
, amii_msgBPen
);
1284 SetBPen(w
->RPort
, amii_msgBPen
);
1287 SetAPen(w
->RPort
, amii_statBPen
);
1288 SetBPen(w
->RPort
, amii_statBPen
);
1291 SetAPen(w
->RPort
, amii_menuBPen
);
1292 SetBPen(w
->RPort
, amii_menuBPen
);
1295 SetAPen(w
->RPort
, amii_textBPen
);
1296 SetBPen(w
->RPort
, amii_textBPen
);
1302 SetAPen(w
->RPort
, C_BLACK
);
1303 SetBPen(w
->RPort
, C_BLACK
);
1306 SetAPen(w
->RPort
, amii_otherBPen
);
1307 SetBPen(w
->RPort
, amii_otherBPen
);
1313 amii_setdrawpens(struct Window
*w
, int type
)
1317 SetAPen(w
->RPort
, amii_msgAPen
);
1318 SetBPen(w
->RPort
, amii_msgBPen
);
1321 SetAPen(w
->RPort
, amii_statAPen
);
1322 SetBPen(w
->RPort
, amii_statBPen
);
1325 SetAPen(w
->RPort
, amii_menuAPen
);
1326 SetBPen(w
->RPort
, amii_menuBPen
);
1329 SetAPen(w
->RPort
, amii_textAPen
);
1330 SetBPen(w
->RPort
, amii_textBPen
);
1335 SetAPen(w
->RPort
, C_WHITE
);
1336 SetBPen(w
->RPort
, C_BLACK
);
1339 SetAPen(w
->RPort
, amii_otherAPen
);
1340 SetBPen(w
->RPort
, amii_otherBPen
);
1345 /* Clear the indicated window */
1348 amii_clear_nhwindow(win
)
1351 register struct amii_WinDesc
*cw
;
1352 register struct Window
*w
;
1357 if (win
== WIN_ERR
|| (cw
= amii_wins
[win
]) == NULL
)
1358 panic(winpanicstr
, win
, "clear_nhwindow");
1360 /* Clear the overview window too if it is displayed */
1362 && (cw
->type
== WIN_MAP
&& WIN_OVER
!= WIN_ERR
&& reclip
== 0)) {
1363 amii_clear_nhwindow(WIN_OVER
);
1367 SetDrMd(w
->RPort
, JAM2
);
1371 if ((cw
->wflags
& FLMAP_CURSUP
)) {
1372 if (cw
->type
!= NHW_MAP
)
1375 cw
->wflags
&= ~FLMAP_CURSUP
;
1378 amii_setfillpens(w
, cw
->type
);
1379 SetDrMd(w
->RPort
, JAM2
);
1381 if (cw
->type
== NHW_MENU
|| cw
->type
== NHW_TEXT
) {
1382 RectFill(w
->RPort
, w
->BorderLeft
, w
->BorderTop
,
1383 w
->Width
- w
->BorderRight
- 1,
1384 w
->Height
- w
->BorderBottom
- 1);
1386 if (cw
->type
== NHW_MESSAGE
) {
1387 amii_curs(win
, 1, 0);
1389 TextSpaces(w
->RPort
, cw
->cols
);
1391 RectFill(w
->RPort
, w
->BorderLeft
, w
->BorderTop
,
1392 w
->Width
- w
->BorderRight
- 1,
1393 w
->Height
- w
->BorderBottom
- 1);
1399 amii_curs(win
, 1, 0);
1402 /* Dismiss the window from the screen */
1405 dismiss_nhwindow(win
)
1408 register struct Window
*w
;
1409 register struct amii_WinDesc
*cw
;
1411 if (win
== WIN_ERR
|| (cw
= amii_wins
[win
]) == NULL
) {
1412 panic(winpanicstr
, win
, "dismiss_nhwindow");
1418 /* All windows have this stuff attached to them. */
1419 if (cw
->type
== NHW_MAP
|| cw
->type
== NHW_OVER
1420 || cw
->type
== NHW_BASE
|| cw
->type
== NHW_MESSAGE
1421 || cw
->type
== NHW_STATUS
) {
1425 /* Save where user like inventory to appear */
1426 if (win
== WIN_INVEN
) {
1427 lastinvent
.MinX
= w
->LeftEdge
;
1428 lastinvent
.MinY
= w
->TopEdge
;
1429 lastinvent
.MaxX
= w
->Width
;
1430 lastinvent
.MaxY
= w
->Height
;
1433 /* Close the window */
1437 /* Free copy of NewWindow structure for TEXT/MENU windows. */
1439 FreeNewWindow((void *) cw
->newwin
);
1445 amii_exit_nhwindows(str
)
1448 /* Seems strange to have to do this... but we need the BASE window
1453 FreeTileImageFiles();
1456 raw_print(""); /* be sure we're not under the top margin */
1462 amii_display_nhwindow(win
, blocking
)
1468 static int lastwin
= -1;
1469 struct amii_WinDesc
*cw
;
1475 if (win
== WIN_ERR
|| (cw
= amii_wins
[win
]) == NULL
)
1476 panic(winpanicstr
, win
, "display_nhwindow");
1478 if (cw
->type
== NHW_MESSAGE
)
1479 cw
->wflags
&= ~FLMAP_SKIP
;
1481 if (cw
->type
== NHW_MESSAGE
|| cw
->type
== NHW_STATUS
)
1484 if (WIN_MAP
!= WIN_ERR
&& amii_wins
[WIN_MAP
]) {
1485 flush_glyph_buffer(amii_wins
[WIN_MAP
]->win
);
1488 if (cw
->type
== NHW_MENU
|| cw
->type
== NHW_TEXT
) {
1489 cnt
= DoMenuScroll(win
, blocking
, PICK_ONE
, &mip
);
1490 } else if (cw
->type
== NHW_MAP
) {
1491 amii_end_glyphout(win
);
1492 /* Do more if it is time... */
1493 if (blocking
== TRUE
&& amii_wins
[WIN_MESSAGE
]->curx
) {
1494 outmore(amii_wins
[WIN_MESSAGE
]);
1500 amii_curs(window
, x
, y
)
1502 register int x
, y
; /* not xchar: perhaps xchar is unsigned and
1503 curx-x would be unsigned as well */
1505 register struct amii_WinDesc
*cw
;
1506 register struct Window
*w
;
1507 register struct RastPort
*rp
;
1509 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
)
1510 panic(winpanicstr
, window
, "curs");
1511 if ((w
= cw
->win
) == NULL
) {
1512 if (cw
->type
== NHW_MENU
|| cw
->type
== NHW_TEXT
)
1515 panic("No window open yet in curs() for winid %d\n", window
);
1517 amiIDisplay
->lastwin
= window
;
1519 /* Make sure x is within bounds */
1521 --x
; /* column 0 is never used */
1529 if (x
< 0 || y
< 0 || y
>= cw
->rows
|| x
>= cw
->cols
) {
1530 char *s
= "[unknown type]";
1533 s
= "[topl window]";
1536 s
= "[status window]";
1542 s
= "[menu window]";
1545 s
= "[text window]";
1548 s
= "[base window]";
1551 s
= "[overview window]";
1554 impossible("bad curs positioning win %d %s (%d,%d)", window
, s
, x
, y
);
1560 if (clipping
&& cw
->type
== NHW_MAP
) {
1566 /* Output all saved output before doing cursor movements for MAP */
1568 if (cw
->type
== NHW_MAP
) {
1569 flush_glyph_buffer(w
);
1572 /* Actually do it */
1575 if (cw
->type
== NHW_MENU
) {
1577 if (window
== WIN_INVEN
) {
1578 Move(rp
, (x
* rp
->TxWidth
) + w
->BorderLeft
+ 1
1579 + pictdata
.xsize
+ 4,
1580 (y
* max(rp
->TxHeight
, pictdata
.ysize
+ 3))
1581 + rp
->TxBaseline
+ pictdata
.ysize
- rp
->TxHeight
1582 + w
->BorderTop
+ 4);
1584 Move(rp
, (x
* rp
->TxWidth
) + w
->BorderLeft
+ 1,
1585 (y
* rp
->TxHeight
) + rp
->TxBaseline
+ w
->BorderTop
+ 1);
1588 Move(rp
, (x
* rp
->TxWidth
) + w
->BorderLeft
+ 1,
1589 (y
* rp
->TxHeight
) + rp
->TxBaseline
+ w
->BorderTop
+ 1);
1591 } else if (cw
->type
== NHW_TEXT
) {
1592 Move(rp
, (x
* rp
->TxWidth
) + w
->BorderLeft
+ 1,
1593 (y
* rp
->TxHeight
) + rp
->TxBaseline
+ w
->BorderTop
+ 1);
1594 } else if (cw
->type
== NHW_MAP
|| cw
->type
== NHW_BASE
) {
1595 /* These coordinate calculations must be synced with those
1596 * in flush_glyph_buffer() in winchar.c. curs_on_u() will
1597 * use this code, all other drawing occurs through the glyph
1598 * code. In order for the cursor to appear on top of the hero,
1599 * the code must compute X,Y in the same manner relative to
1600 * the RastPort coordinates.
1602 * y = w->BorderTop + (g_nodes[i].y-2) * rp->TxHeight +
1603 * rp->TxBaseline + 1;
1604 * x = g_nodes[i].x * rp->TxWidth + w->BorderLeft;
1608 if (cw
->type
== NHW_MAP
) {
1609 if (Is_rogue_level(&u
.uz
)) {
1611 int qqx
= (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
;
1612 int qqy
= w
->BorderTop
+ ( (y
+1) * w
->RPort
->TxHeight
) + 1;
1613 printf("pos: (%d,%d)->(%d,%d)\n",x
,y
,qqx
,qqy
);
1616 C_WHITE
); /* XXX should be elsewhere (was 4)*/
1617 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
,
1618 w
->BorderTop
+ ((y
+ 1) * w
->RPort
->TxHeight
) + 1);
1620 Move(rp
, (x
* mxsize
) + w
->BorderLeft
,
1621 w
->BorderTop
+ ((y
+ 1) * mysize
) + 1);
1624 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
,
1625 w
->BorderTop
+ ((y
+ 1) * w
->RPort
->TxHeight
)
1626 + w
->RPort
->TxBaseline
+ 1);
1629 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
,
1630 w
->BorderTop
+ (y
* w
->RPort
->TxHeight
)
1631 + w
->RPort
->TxBaseline
+ 1);
1633 } else if (WINVERS_AMIV
&& cw
->type
== NHW_OVER
) {
1634 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
+ 2,
1635 w
->BorderTop
+ w
->RPort
->TxBaseline
+ 3);
1636 } else if (cw
->type
== NHW_MESSAGE
&& !scrollmsg
) {
1637 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
+ 2,
1638 w
->BorderTop
+ w
->RPort
->TxBaseline
+ 3);
1639 } else if (cw
->type
== NHW_STATUS
) {
1640 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
+ 2,
1641 (y
* (w
->RPort
->TxHeight
+ 1)) + w
->BorderTop
1642 + w
->RPort
->TxBaseline
+ 1);
1644 Move(rp
, (x
* w
->RPort
->TxWidth
) + w
->BorderLeft
+ 2,
1645 (y
* w
->RPort
->TxHeight
) + w
->BorderTop
+ w
->RPort
->TxBaseline
1651 amii_set_text_font(name
, size
)
1656 register struct amii_WinDesc
*cw
;
1657 int osize
= TextsFont13
.ta_YSize
;
1658 static char nname
[100];
1660 strncpy(nname
, name
, sizeof(nname
) - 1);
1661 nname
[sizeof(nname
) - 1] = 0;
1663 TextsFont13
.ta_Name
= nname
;
1664 TextsFont13
.ta_YSize
= size
;
1666 /* No alternate text font allowed for 640x269 or smaller */
1667 if (!HackScreen
|| !bigscreen
)
1670 /* Look for windows to set, and change them */
1672 if (DiskfontBase
= OpenLibrary("diskfont.library", amii_libvers
)) {
1673 TextsFont
= OpenDiskFont(&TextsFont13
);
1674 for (i
= 0; TextsFont
&& i
< MAXWIN
; ++i
) {
1675 if ((cw
= amii_wins
[i
]) && cw
->win
!= NULL
) {
1678 MoveWindow(cw
->win
, 0, -(size
- osize
) * 2);
1679 SizeWindow(cw
->win
, 0, (size
- osize
) * 2);
1680 SetFont(cw
->win
->RPort
, TextsFont
);
1686 SetFont(cw
->win
->RPort
, TextsFont
);
1692 CloseLibrary(DiskfontBase
);
1693 DiskfontBase
= NULL
;
1701 register struct amii_WinDesc
*cw
;
1703 /* Foreach open window in all of amii_wins[], CloseShWindow, free memory
1706 for (i
= 0; i
< MAXWIN
; ++i
) {
1707 if ((cw
= amii_wins
[i
]) && (cw
->type
!= NHW_BASE
|| all
)) {
1708 amii_destroy_nhwindow(i
);
1714 amii_cl_end(cw
, curs_pos
)
1715 register struct amii_WinDesc
*cw
;
1716 register int curs_pos
;
1718 register struct Window
*w
= cw
->win
;
1719 register int oy
, ox
;
1722 panic("NULL window pointer in amii_cl_end()");
1724 oy
= w
->RPort
->cp_y
;
1725 ox
= w
->RPort
->cp_x
;
1727 TextSpaces(w
->RPort
, cw
->cols
- curs_pos
);
1729 Move(w
->RPort
, ox
, oy
);
1736 register struct amii_WinDesc
*cw
;
1737 register struct Window
*w
;
1738 register struct RastPort
*rp
;
1745 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
) {
1746 iflags
.window_inited
= 0;
1747 panic(winpanicstr
, window
, "cursor_off");
1750 if (!(cw
->wflags
& FLMAP_CURSUP
))
1758 cw
->wflags
&= ~FLMAP_CURSUP
;
1761 /* Save the current information */
1766 dmode
= rp
->DrawMode
;
1769 SetAPen(rp
, cw
->curs_apen
);
1770 SetBPen(rp
, cw
->curs_bpen
);
1771 SetDrMd(rp
, COMPLEMENT
);
1772 /*printf("CURSOR OFF: %d %d\n",x,y);*/
1774 if (WINVERS_AMIV
&& cw
->type
== NHW_MAP
) {
1775 cursor_common(rp
, x
, y
);
1776 if (Is_rogue_level(&u
.uz
))
1777 Move(rp
, curx
, cury
);
1783 /* Put back the other stuff */
1785 Move(rp
, curx
, cury
);
1797 register struct amii_WinDesc
*cw
;
1798 register struct Window
*w
;
1799 register struct RastPort
*rp
;
1804 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
) {
1805 /* tty does this differently - is this OK? */
1806 iflags
.window_inited
= 0;
1807 panic(winpanicstr
, window
, "cursor_on");
1810 /*printf("CURSOR ON: %d %d\n",cw->win->RPort->cp_x,
1811 * cw->win->RPort->cp_y);*/
1812 if ((cw
->wflags
& FLMAP_CURSUP
))
1820 cw
->wflags
|= FLMAP_CURSUP
;
1823 /* Save the current information */
1826 if (WINVERS_AMIV
&& cw
->type
== NHW_MAP
&& !Is_rogue_level(&u
.uz
))
1827 x
= cw
->cursx
= (rp
->cp_x
& -8) + 8;
1830 x
= cw
->cursx
= rp
->cp_x
;
1831 y
= cw
->cursy
= rp
->cp_y
;
1834 dmode
= rp
->DrawMode
;
1836 /* Draw in complement mode. The cursor body will be C_WHITE */
1838 cw
->curs_apen
= 0xff; /* Last color/all planes, regardless of depth */
1839 cw
->curs_bpen
= 0xff;
1840 SetAPen(rp
, cw
->curs_apen
);
1841 SetBPen(rp
, cw
->curs_bpen
);
1842 SetDrMd(rp
, COMPLEMENT
);
1843 if (WINVERS_AMIV
&& cw
->type
== NHW_MAP
) {
1844 cursor_common(rp
, x
, y
);
1858 cursor_common(rp
, x
, y
)
1859 struct RastPort
*rp
;
1864 if (Is_rogue_level(&u
.uz
)) {
1866 y1
= y
- rp
->TxHeight
;
1867 x2
= x
+ rp
->TxWidth
+ 1;
1869 /*printf("COMM: (%d %d) (%d %d) (%d %d) (%d
1870 * %d)\n",x1,y1,x2,y2,x1+2,y1+2,x2-2,y2-2);*/
1873 y1
= y
- mysize
- 1;
1874 x2
= x
+ mxsize
- 1;
1876 RectFill(rp
, x1
, y1
, x2
, y2
);
1879 RectFill(rp
, x1
+ 2, y1
+ 2, x2
- 2, y2
- 2);
1883 amii_suspend_nhwindows(str
)
1887 ScreenToBack(HackScreen
);
1891 amii_resume_nhwindows()
1894 ScreenToFront(HackScreen
);
1907 struct amii_WinDesc
*cw
= amii_wins
[WIN_MESSAGE
];
1908 /* NB - this is sufficient for
1909 * yn_function, but that's it
1916 amii_curs(WIN_MESSAGE
, cw
->curx
+ 1, cw
->cury
);
1917 amii_cl_end(cw
, cw
->curx
);
1919 /*#endif /* AMIGA_INTUITION */
1925 display_file(PORT_HELP
, 1);
1932 * Print the glyph to the output device. Don't flush the output device.
1934 * Since this is only called from show_glyph(), it is assumed that the
1935 * position and glyph are always correct (checked there)!
1939 amii_print_glyph(win
, x
, y
, glyph
, bkglyph
)
1944 struct amii_WinDesc
*cw
;
1947 extern const int zapcolors
[];
1950 /* In order for the overview window to work, we can not clip here */
1951 if (!WINVERS_AMIV
) {
1953 /* If point not in visible part of window just skip it */
1955 if (x
<= clipx
|| y
< clipy
|| x
>= clipxmax
|| y
>= clipymax
)
1961 if (win
== WIN_ERR
|| (cw
= amii_wins
[win
]) == NULL
1962 || cw
->type
!= NHW_MAP
) {
1963 panic(winpanicstr
, win
, "amii_print_glyph");
1969 if(u
.uz
.dlevel
!= x
){
1970 fprintf(stderr
,"lvlchg: %d (%d)\n",u
.uz
.dlevel
,Is_rogue_level(&u
.uz
));
1975 if (WINVERS_AMIV
&& !Is_rogue_level(&u
.uz
)) {
1976 amii_curs(win
, x
, y
);
1977 amiga_print_glyph(win
, 0, glyph
);
1978 } else /* AMII, or Rogue level in either version */
1980 /* map glyph to character and color */
1981 (void) mapglyph(glyph
, &och
, &color
, &special
, x
, y
);
1983 if (WINVERS_AMIV
) { /* implies Rogue level here */
1984 amii_curs(win
, x
, y
);
1985 amiga_print_glyph(win
, NO_COLOR
, ch
+ 10000);
1987 /* Move the cursor. */
1988 amii_curs(win
, x
, y
+ 2);
1991 /* Turn off color if rogue level. */
1992 if (Is_rogue_level(&u
.uz
))
1995 amiga_print_glyph(win
, color
, ch
);
1997 g_putch(ch
); /* print the character */
1999 cw
->curx
++; /* one character over */
2004 /* Make sure the user sees a text string when no windowing is available */
2008 register const char *s
;
2015 amiIDisplay
->rawprint
++;
2017 if (!Initialized
) { /* Not yet screen open ... */
2023 if (Initialized
== 0 && WIN_BASE
== WIN_ERR
)
2024 init_nhwindows(&argc
, (char **) 0);
2026 if (amii_rawprwin
!= WIN_ERR
)
2027 amii_putstr(amii_rawprwin
, 0, s
);
2028 else if (WIN_MAP
!= WIN_ERR
&& amii_wins
[WIN_MAP
])
2029 amii_putstr(WIN_MAP
, 0, s
);
2030 else if (WIN_BASE
!= WIN_ERR
&& amii_wins
[WIN_BASE
])
2031 amii_putstr(WIN_BASE
, 0, s
);
2038 /* Make sure the user sees a bold text string when no windowing
2043 amii_raw_print_bold(s
)
2044 register const char *s
;
2052 amiIDisplay
->rawprint
++;
2054 if (!Initialized
) { /* Not yet screen open ... */
2060 if (Initialized
== 0 && WIN_BASE
== WIN_ERR
)
2061 init_nhwindows(&argc
, (char **) 0);
2063 if (amii_rawprwin
!= WIN_ERR
)
2064 amii_putstr(amii_rawprwin
, 1, s
);
2065 else if (WIN_MAP
!= WIN_ERR
&& amii_wins
[WIN_MAP
])
2066 amii_putstr(WIN_MAP
, 1, s
);
2067 else if (WIN_BASE
!= WIN_ERR
&& amii_wins
[WIN_BASE
])
2068 amii_putstr(WIN_BASE
, 1, s
);
2070 printf("\33[1m%s\33[0m\n", s
);
2075 /* Rebuild/update the inventory if the window is up.
2078 amii_update_inventory()
2080 register struct amii_WinDesc
*cw
;
2082 if (WIN_INVEN
!= WIN_ERR
&& (cw
= amii_wins
[WIN_INVEN
])
2083 && cw
->type
== NHW_MENU
&& cw
->win
) {
2084 display_inventory(NULL
, FALSE
);
2088 /* Humm, doesn't really do anything useful */
2095 /* anything else? do we need this much? */
2098 /* Wait for everything to sync. Nothing is asynchronous, so we just
2099 * ask for a key to be pressed.
2104 if (!amiIDisplay
|| amiIDisplay
->rawprint
) {
2106 amiIDisplay
->rawprint
= 0;
2108 if (WIN_MAP
!= WIN_ERR
) {
2109 display_nhwindow(WIN_MAP
, TRUE
);
2110 flush_glyph_buffer(amii_wins
[WIN_MAP
]->win
);
2123 /* some of this is now redundant with top of amii_cliparound XXX */
2127 /* XXX still to do: suppress scrolling if we violate the boundary but the
2128 * edge of the map is already displayed
2131 amii_cliparound(x
, y
)
2134 extern boolean restoring
;
2136 int oldx
= clipx
, oldy
= clipy
;
2137 int oldxmax
= clipxmax
, oldymax
= clipymax
;
2139 #define SCROLLCNT 1 /* Get there in 3 moves... */
2140 int scrollcnt
= SCROLLCNT
; /* ...or 1 if we changed level */
2141 if (!clipping
) /* And 1 in anycase, cleaner, simpler, quicker */
2144 if (Is_rogue_level(&u
.uz
)) {
2145 struct Window
*w
= amii_wins
[WIN_MAP
]->win
;
2146 struct RastPort
*rp
= w
->RPort
;
2148 COx
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
) / rp
->TxWidth
;
2149 LIx
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
) / rp
->TxHeight
;
2155 * On a level change, move the clipping region so that for a
2156 * reasonablely large window extra motion is avoided; for
2157 * the rogue level hopefully this means no motion at all.
2160 static d_level saved_level
= { 127, 127 }; /* XXX */
2162 if (!on_level(&u
.uz
, &saved_level
)) {
2163 scrollcnt
= 1; /* jump with blanking */
2167 saved_level
= u
.uz
; /* save as new current level */
2171 if (x
<= clipx
+ xclipbord
) {
2172 clipx
= max(0, x
- (clipxmax
- clipx
) / 2);
2173 clipxmax
= clipx
+ COx
;
2174 } else if (x
> clipxmax
- xclipbord
) {
2175 clipxmax
= min(COLNO
, x
+ (clipxmax
- clipx
) / 2);
2176 clipx
= clipxmax
- COx
;
2179 if (y
<= clipy
+ yclipbord
) {
2180 clipy
= max(0, y
- (clipymax
- clipy
) / 2);
2181 clipymax
= clipy
+ LIx
;
2182 } else if (y
> clipymax
- yclipbord
) {
2183 clipymax
= min(ROWNO
, y
+ (clipymax
- clipy
) / 2);
2184 clipy
= clipymax
- LIx
;
2188 if (clipx
!= oldx
|| clipy
!= oldy
|| clipxmax
!= oldxmax
2189 || clipymax
!= oldymax
) {
2190 #ifndef NOSCROLLRASTER
2191 struct Window
*w
= amii_wins
[WIN_MAP
]->win
;
2192 struct RastPort
*rp
= w
->RPort
;
2193 int xdelta
, ydelta
, xmod
, ymod
, i
;
2194 int incx
, incy
, mincx
, mincy
;
2195 int savex
, savey
, savexmax
, saveymax
;
2198 if (Is_rogue_level(&u
.uz
)) {
2200 scry
= rp
->TxHeight
;
2206 /* Ask that the glyph routines not draw the overview window */
2208 cursor_off(WIN_MAP
);
2210 /* Compute how far we are moving in terms of tiles */
2211 mincx
= clipx
- oldx
;
2212 mincy
= clipy
- oldy
;
2214 /* How many tiles to get there in SCROLLCNT moves */
2215 incx
= (clipx
- oldx
) / scrollcnt
;
2216 incy
= (clipy
- oldy
) / scrollcnt
;
2218 /* If less than SCROLLCNT tiles, then move by 1 tile if moving at all
2221 incx
= (mincx
!= 0);
2223 incy
= (mincy
!= 0);
2225 /* Get count of pixels to move each iteration and final pixel count */
2226 xdelta
= ((clipx
- oldx
) * scrx
) / scrollcnt
;
2227 xmod
= ((clipx
- oldx
) * scrx
) % scrollcnt
;
2228 ydelta
= ((clipy
- oldy
) * scry
) / scrollcnt
;
2229 ymod
= ((clipy
- oldy
) * scry
) % scrollcnt
;
2231 /* Preserve the final move location */
2234 saveymax
= clipymax
;
2235 savexmax
= clipxmax
;
2238 * Set clipping rectangle to be just the region that will be exposed so
2239 * that drawing will be faster
2241 #if 0 /* Doesn't seem to work quite the way it should */
2242 /* In some cases hero is 'centered' offscreen */
2246 clipxmax
= clipx
+ incx
;
2248 else if( xdelta
> 0 )
2251 clipx
= clipxmax
- incx
;
2262 clipymax
= clipy
+ incy
;
2264 else if( ydelta
> 0 )
2267 clipy
= clipymax
- incy
;
2275 /* Now, in scrollcnt moves, move the picture toward the final view */
2276 for (i
= 0; i
< scrollcnt
; ++i
) {
2278 if (i
== scrollcnt
- 1 && (xmod
!= 0 || ymod
!= 0)
2279 && (xdelta
!= 0 || ydelta
!= 0)) {
2280 incx
+= (clipx
- oldx
) % scrollcnt
;
2281 incy
+= (clipy
- oldy
) % scrollcnt
;
2286 /* Scroll the raster if we are scrolling */
2287 if (xdelta
!= 0 || ydelta
!= 0) {
2288 ScrollRaster(rp
, xdelta
, ydelta
, w
->BorderLeft
, w
->BorderTop
,
2289 w
->Width
- w
->BorderRight
- 1,
2290 w
->Height
- w
->BorderBottom
- 1);
2308 /* Draw the exposed portion */
2309 if (on_level(&u
.uz0
, &u
.uz
) && !restoring
)
2311 flush_glyph_buffer(amii_wins
[WIN_MAP
]->win
);
2317 clipymax
= saveymax
;
2318 clipxmax
= savexmax
;
2320 if (on_level(&u
.uz0
, &u
.uz
) && !restoring
&& moves
> 1)
2322 flush_glyph_buffer(amii_wins
[WIN_MAP
]->win
);
2330 struct MsgPort
*port
;
2332 struct Message
*msg
;
2333 while (msg
= GetMsg(port
))