NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / sys / amiga / winfuncs.c
blobdb9ab78e642b0c43af50d0aca9bbc7c3391c3d23
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.
3 */
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"
10 #include "date.h"
12 extern struct TagItem scrntags[];
14 static BitMapHeader amii_bmhd;
15 static void cursor_common(struct RastPort *, int, int);
17 #ifdef CLIPPING
18 int CO, LI;
20 /* Changing clipping region, skip clear of screen in overview window. */
21 int reclip;
23 /* Must be set to at least two or you will get stuck! */
24 int xclipbord = 4, yclipbord = 2;
25 #endif
27 int mxsize, mysize;
28 struct Rectangle amii_oldover;
29 struct Rectangle amii_oldmsg;
31 extern struct TextFont *RogueFont;
33 int amii_msgAPen;
34 int amii_msgBPen;
35 int amii_statAPen;
36 int amii_statBPen;
37 int amii_menuAPen;
38 int amii_menuBPen;
39 int amii_textAPen;
40 int amii_textBPen;
41 int amii_otherAPen;
42 int amii_otherBPen;
43 long amii_libvers = LIBRARY_FONT_VERSION;
45 void
46 ami_wininit_data(dir)
47 int dir;
49 extern unsigned short amii_init_map[AMII_MAXCOLORS];
50 extern unsigned short amiv_init_map[AMII_MAXCOLORS];
52 if (dir != WININIT)
53 return;
55 if (!WINVERS_AMIV) {
56 #ifdef TEXTCOLOR
57 amii_numcolors = 8;
58 #else
59 amii_numcolors = 4;
60 #endif
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;
86 mxsize = 8;
87 mysize = 8;
89 amii_libvers = LIBRARY_FONT_VERSION;
90 memcpy(amii_initmap, amii_init_map, sizeof(amii_initmap));
91 } else {
92 mxsize = 16;
93 mysize = 16;
95 amii_numcolors = 16;
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));
125 #ifdef OPT_DISPMAP
126 dispmap_sanity();
127 #endif
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" },
138 { TAG_END, 0 },
140 #endif
142 void amii_destroy_nhwindow(win) /* just hide */
143 register winid win;
145 int i;
146 int type;
147 register struct amii_WinDesc *cw;
149 if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) {
150 panic(winpanicstr, win, "destroy_nhwindow");
153 if (WINVERS_AMIV) {
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);
164 WIN_OVER = WIN_ERR;
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,
180 (amiIDisplay->xpix
181 - amii_wins[WIN_MESSAGE]->win->LeftEdge)
182 - amii_wins[WIN_MESSAGE]->win->Width,
188 /* Tear down the Intuition stuff */
189 dismiss_nhwindow(win);
190 type = cw->type;
192 if (cw->resp) {
193 free(cw->resp);
194 cw->resp = NULL;
196 if (cw->canresp) {
197 free(cw->canresp);
198 cw->canresp = NULL;
200 if (cw->morestr) {
201 free(cw->morestr);
202 cw->morestr = NULL;
204 if (cw->hook) {
205 free(cw->hook);
206 cw->hook = NULL;
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) {
212 if (cw->data[i])
213 free(cw->data[i]);
215 free(cw->data);
218 free(cw);
219 amii_wins[win] = NULL;
221 /* Set globals to WIN_ERR for known one-of-a-kind windows. */
222 if (win == WIN_MAP)
223 WIN_MAP = WIN_ERR;
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)
229 WIN_INVEN = WIN_ERR;
232 #ifdef INTUI_NEW_LOOK
233 struct FillParams {
234 struct Layer *layer;
235 struct Rectangle bounds;
236 WORD offsetx;
237 WORD offsety;
240 #ifdef __GNUC__
241 #ifdef __PPC__
242 void PPC_LayerFillHook(void);
243 struct EmulLibEntry LayerFillHook = { TRAP_LIB, 0,
244 (void (*)(void)) PPC_LayerFillHook };
245 void
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;
251 #else
252 void
253 LayerFillHook(void)
255 register struct Hook *hk asm("a0");
256 register struct RastPort *rp asm("a2");
257 register struct FillParams *fp asm("a1");
258 #endif
259 #else
260 void
261 #ifndef _DCC
262 __interrupt
263 #endif
264 __saveds __asm LayerFillHook(register __a0 struct Hook *hk,
265 register __a2 struct RastPort *rp,
266 register __a1 struct FillParams *fp)
268 #endif
270 register long x, y, xmax, ymax;
271 register int apen;
272 struct RastPort rptmp;
274 memcpy(&rptmp, rp, sizeof(struct RastPort));
275 rptmp.Layer = NULL;
277 switch ((int) hk->h_Data) {
278 case NHW_STATUS:
279 apen = amii_statBPen;
280 break;
281 case NHW_MESSAGE:
282 apen = amii_msgBPen;
283 break;
284 case NHW_TEXT:
285 apen = amii_textBPen;
286 break;
287 case NHW_MENU:
288 apen = amii_menuBPen;
289 break;
290 case -2:
291 apen = amii_otherBPen;
292 break;
293 case NHW_BASE:
294 case NHW_MAP:
295 case NHW_OVER:
296 default:
297 apen = C_BLACK;
298 break;
301 x = fp->bounds.MinX;
302 y = fp->bounds.MinY;
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);
311 #endif
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;
319 register int newid;
320 int maph, stath, scrfontysize;
322 scrfontysize = HackScreen->Font->ta_YSize;
325 * Initial mapwindow height, this might change later in tilemode
326 * and low screen
328 maph = (21 * mxsize) + 2
329 + (bigscreen
330 ? HackScreen->WBorTop + HackScreen->WBorBottom
331 + scrfontysize + 1
332 : 0);
334 /* Status window height, avoids having to calculate many times */
335 stath =
336 txheight * 2 + 2 + (WINVERS_AMIV || bigscreen
337 ? HackScreen->WBorTop + HackScreen->WBorBottom
338 + (bigscreen ? scrfontysize + 1 : 0)
339 : 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();
354 if (!HackPort)
355 panic("no memory for msg port");
358 nw = &new_wins[type].newwin;
359 nw->Width = amiIDisplay->xpix;
360 nw->Screen = HackScreen;
362 if (WINVERS_AMIV) {
363 nw->DetailPen = C_WHITE;
364 nw->BlockPen = C_GREYBLUE;
365 } else {
366 nw->DetailPen = C_WHITE;
367 nw->BlockPen = C_BLACK;
370 if (type == NHW_BASE) {
371 nw->LeftEdge = 0;
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) {
376 nw->LeftEdge = 0;
377 nw->Height = maph;
379 if (msgwin && stwin) {
380 nw->TopEdge = stwin->TopEdge - maph;
381 } else {
382 panic("msgwin and stwin must open before map");
384 if (nw->TopEdge < 0)
385 panic("Too small screen to fit map");
386 } else if (type == NHW_MAP && WINVERS_AMIV) {
387 struct Window *w;
389 w = amii_wins[WIN_MESSAGE]->win;
390 nw->LeftEdge = 0;
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;
406 else
407 panic("No window to base STATUS location from");
409 nw->Height = stath;
410 nw->TopEdge = amiIDisplay->ypix - nw->Height;
411 nw->LeftEdge = w->LeftEdge;
413 if (nw->LeftEdge + nw->Width >= amiIDisplay->xpix)
414 nw->LeftEdge = 0;
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,
431 amii_oldmsg.MaxY);
432 } else {
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;
445 else
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)
455 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) {
465 scrollmsg = 0;
466 nw->Title = 0;
467 } else {
468 nw->FirstGadget = &MsgScroll;
469 nw->Flags |= WINDOWSIZING | WINDOWDRAG;
470 nw->Flags &= ~BORDERLESS;
472 if (WINVERS_AMIV || nw->Height == 0) {
473 if (WINVERS_AMIV) {
474 nw->Height = TextsFont->tf_YSize + HackScreen->WBorTop + 3
475 + HackScreen->WBorBottom;
476 if (bigscreen)
477 nw->Height += (txheight * 6);
478 else
479 nw->Height += (txheight * 3);
480 } else {
481 nw->Height =
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;
499 #endif
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);
508 if (WINVERS_AMIV) {
509 if (type == NHW_STATUS) {
510 nw->Flags &=
511 ~(WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING);
512 nw->IDCMPFlags &= ~NEWSIZE;
513 } else {
514 nw->Flags |=
515 (WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING);
516 nw->IDCMPFlags |= NEWSIZE;
518 } else {
519 if (HackScreen->Width < 657) {
520 nw->Flags |= (WINDOWDRAG | WINDOWDEPTH);
521 } else {
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)
538 nw->Title = 0;
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 */
546 switch (type) {
547 case NHW_MESSAGE:
548 case NHW_STATUS:
549 case NHW_TEXT:
550 case NHW_MENU:
551 case NHW_BASE:
552 case NHW_OVER:
553 case NHW_MAP:
554 if (wd) {
555 #ifdef __GNUC__
556 fillhook.h_Entry = (void *) &LayerFillHook;
557 #else
558 fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
559 #endif
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;
568 break;
572 /* Don't open MENU or TEXT windows yet */
574 if (type == NHW_MENU || type == NHW_TEXT)
575 w = NULL;
576 else
577 w = OpenShWindow((void *) nw);
579 if (w == NULL && type != NHW_MENU && type != NHW_TEXT) {
580 char buf[100];
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);
584 raw_print(buf);
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)
592 break;
595 if (newid == MAXWIN + 1)
596 panic("time to write re-alloc code\n");
598 /* Set wincnt accordingly */
600 if (newid > wincnt)
601 wincnt = newid;
603 /* Do common initialization */
605 amii_wins[newid] = wd;
607 wd->newwin = NULL;
608 wd->win = w;
609 wd->type = type;
610 wd->wflags = 0;
611 wd->active = FALSE;
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) {
624 if (scrollmsg) {
625 if (WINVERS_AMIV) {
626 WindowLimits(w, 100, w->BorderTop + w->BorderBottom
627 + ((txheight + 1) * 2) + 1,
628 0, 0);
629 } else {
630 WindowLimits(w, w->Width,
631 w->BorderTop + w->BorderBottom
632 + ((txheight + 1) * 2) + 1,
633 0, 0);
635 } else {
636 WindowLimits(w, w->Width, w->BorderTop + w->BorderBottom
637 + txheight + 2,
638 0, 0);
642 if (type != NHW_MAP) {
643 SetFont(w->RPort, TextsFont);
645 #ifdef HACKFONT
646 else if (HackFont)
647 SetFont(w->RPort, HackFont);
648 #endif
651 /* Text and menu windows are not opened yet */
652 if (w) {
653 wd->rows = (w->Height - w->BorderTop - w->BorderBottom - 2)
654 / w->RPort->TxHeight;
655 wd->cols = (w->Width - w->BorderLeft - w->BorderRight - 2)
656 / w->RPort->TxWidth;
659 /* Okay, now do the individual type initialization */
661 switch (type) {
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.
667 case NHW_MESSAGE:
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 */
680 wd->curx = -1;
681 break;
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.
696 case NHW_MENU:
697 MenuScroll.TopEdge = HackScreen->WBorTop + scrfontysize + 1;
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;
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.
710 case NHW_TEXT:
711 MenuScroll.TopEdge = HackScreen->WBorTop + scrfontysize + 1;
712 wd->rows = wd->maxrow = 0;
713 wd->cols = wd->maxcol = amiIDisplay->cols;
714 wd->data = NULL;
715 wd->morestr = NULL;
716 break;
718 /* The status window has only two lines. These are stored in
719 * wd->data[], and here we allocate the space for them.
721 case NHW_STATUS:
722 SetMenuStrip(w, MenuStrip);
723 /* wd->cols is the number of characters which fit across the
724 * screen.
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);
729 wd->data[2] = NULL;
730 break;
732 /* NHW_OVER does not use wd->data[] or the other text
733 * manipulating members of the amii_WinDesc structure.
735 case NHW_OVER:
736 SetMenuStrip(w, MenuStrip);
737 break;
739 /* NHW_MAP does not use wd->data[] or the other text
740 * manipulating members of the amii_WinDesc structure.
742 case NHW_MAP:
743 SetMenuStrip(w, MenuStrip);
744 if (WINVERS_AMIV) {
745 CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize;
746 LI = (w->Height - w->BorderTop - w->BorderBottom) / mysize;
747 amii_setclipped();
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);
752 } else {
753 if (HackFont)
754 SetFont(w->RPort, HackFont);
756 break;
758 /* The base window must exist until CleanUp() deletes it. */
759 case NHW_BASE:
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,
775 0L) != 0) {
776 Abort(AG_OpenDev | AO_ConsoleDev);
779 ConsoleDevice = (struct Library *) ConsoleIO.io_Device;
781 KbdBuffered = 0;
783 #ifdef HACKFONT
784 if (TextsFont)
785 SetFont(w->RPort, TextsFont);
786 else if (HackFont)
787 SetFont(w->RPort, HackFont);
788 #endif
789 txwidth = w->RPort->TxWidth;
790 txheight = w->RPort->TxHeight;
791 txbaseline = w->RPort->TxBaseline;
792 break;
794 default:
795 panic("bad create_nhwindow( %d )\n", type);
796 return WIN_ERR;
799 return (newid);
802 #ifdef __GNUC__
803 #ifdef __PPC__
804 int PPC_SM_Filter(void);
805 struct EmulLibEntry SM_Filter = { TRAP_LIB, 0,
806 (int (*)(void)) PPC_SM_Filter };
808 PPC_SM_Filter(void)
810 struct Hook *hk = (struct Hook *) REG_A0;
811 ULONG modeID = (ULONG) REG_A1;
812 struct ScreenModeRequester *smr = (struct ScreenModeRequester *) REG_A2;
813 #else
815 SM_Filter(void)
817 register struct Hook *hk asm("a0");
818 register ULONG modeID asm("a1");
819 register struct ScreenModeRequester *smr asm("a2");
820 #endif
821 #else
823 #ifndef _DCC
824 __interrupt
825 #endif
826 __saveds __asm SM_Filter(
827 register __a0 struct Hook *hk, register __a1 ULONG modeID,
828 register __a2 struct ScreenModeRequester *smr)
830 #endif
831 struct DimensionInfo dims;
832 struct DisplayInfo disp;
833 DisplayInfoHandle handle;
834 handle = FindDisplayInfo(modeID);
835 if (handle) {
836 GetDisplayInfoData(handle, (char *) &dims, sizeof(dims), DTAG_DIMS,
837 modeID);
838 GetDisplayInfoData(handle, (char *) &disp, sizeof(disp), DTAG_DISP,
839 modeID);
840 if (!disp.NotAvailable && dims.MaxDepth <= 8
841 && dims.StdOScan.MaxX >= WIDTH - 1
842 && dims.StdOScan.MaxY >= SCREENHEIGHT - 1) {
843 return 1;
846 return 0;
849 /* Initialize the windowing environment */
851 void
852 amii_init_nhwindows(argcp, argv)
853 int *argcp;
854 char **argv;
856 int i;
857 struct Screen *wbscr;
858 int forcenobig = 0;
860 if (HackScreen)
861 panic("init_nhwindows() called twice", 0);
863 /* run args & set bigscreen from -L(1)/-l(-1) */
865 int lclargc = *argcp;
866 int t;
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 */
874 (*argcp)--;
875 } else {
876 *argv_out = *argv_in; /* keep the flag */
877 argv_out++;
879 argv_in++;
881 *argv_out = 0;
884 WIN_MESSAGE = WIN_ERR;
885 WIN_MAP = WIN_ERR;
886 WIN_STATUS = WIN_ERR;
887 WIN_INVEN = WIN_ERR;
888 WIN_BASE = WIN_ERR;
889 WIN_OVER = 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))
907 == NULL) {
908 Abort(AG_OpenLib | AO_GadTools);
911 if ((AslBase = OpenLibrary("asl.library", amii_libvers)) == NULL) {
912 Abort(AG_OpenLib);
915 amiIDisplay =
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);
930 #endif
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;
946 bigscreen = 1;
947 } else if (GfxBase->NormalDisplayRows >= 300
948 || amiIDisplay->ypix >= 300) {
949 bigscreen = 1;
951 } else if (bigscreen == -1) {
952 bigscreen = 0;
953 forcenobig = 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;
964 if (!bigscreen) {
965 alwaysinvent = 0;
967 amiIDisplay->rows = amiIDisplay->ypix / FONTHEIGHT;
969 #ifdef HACKFONT
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
980 * courier/13.
982 TextsFont = NULL;
983 if (bigscreen)
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);
997 if (!RogueFont)
998 panic("Can't get topaz:8");
999 if (!HackFont || !TextsFont) {
1000 if (!HackFont) {
1001 HackFont = OpenFont(&Hack80);
1002 if (!HackFont)
1003 panic("Can't get a map font, topaz:8");
1006 if (!TextsFont) {
1007 TextsFont = OpenFont(&Hack80);
1008 if (!TextsFont)
1009 panic("Can't open text font");
1012 CloseLibrary(DiskfontBase);
1013 DiskfontBase = NULL;
1015 #endif
1017 /* Adjust getlin window size to font */
1019 if (TextsFont) {
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;
1042 StrWindow.Height +=
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,
1053 PATCHLEVEL);
1054 NewHackScreen.DefaultTitle = fname;
1056 #if 0
1057 NewHackScreen.BlockPen = C_BLACK;
1058 NewHackScreen.DetailPen = C_WHITE;
1059 #endif
1060 #ifdef INTUI_NEW_LOOK
1061 if (IntuitionBase->LibNode.lib_Version >= 37) {
1062 int i;
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;
1071 #ifdef HACKFONT
1072 if (TextsFont) {
1073 NewHackScreen.Font = &TextsFont13;
1075 #endif
1077 if (amii_scrnmode == 0xffffffff) {
1078 struct ScreenModeRequester *SMR;
1079 #ifdef __GNUC__
1080 SM_FilterHook.h_Entry = (void *) &SM_Filter;
1081 #else
1082 SM_FilterHook.h_Entry = (ULONG (*) ()) SM_Filter;
1083 #endif
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,
1088 TAG_END))
1089 amii_scrnmode = SMR->sm_DisplayID;
1090 else
1091 amii_scrnmode = 0;
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,
1104 modeid) <= 0
1105 || GetDisplayInfoData(handle, (char *) &disp,
1106 sizeof(disp), DTAG_DISP,
1107 modeid) <= 0) {
1108 modeid = DEFAULT_MONITOR_ID | HIRES_KEY;
1109 /* If the display database seems to not work, use the
1110 * screen
1111 * dimensions
1113 NewHackScreen.Height = wbscr->Height;
1114 NewHackScreen.Width = wbscr->Width;
1117 * Request LACE if it looks laced. For 2.1/3.0, we will
1118 * get
1119 * promoted to the users choice of modes (if promotion is
1120 * allowed)
1121 * If the user is using a dragable screen, things will get
1122 * hosed
1123 * but that is life...
1125 if (wbscr->ViewPort.Modes & LACE)
1126 NewHackScreen.ViewModes |= LACE;
1127 modeid = -1;
1128 } else {
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) {
1145 case SA_DisplayID:
1146 if (!amii_scrnmode || ModeNotAvailable(amii_scrnmode)) {
1147 if (ModeNotAvailable(modeid)) {
1148 scrntags[i].ti_Tag = TAG_IGNORE;
1149 break;
1150 } else
1151 scrntags[i].ti_Data = (long) modeid;
1152 } else
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,
1159 modeid) > 0) {
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;
1165 break;
1167 case SA_Pens:
1168 scrntags[i].ti_Data = (long) sysflags.amii_dripens;
1169 break;
1173 #endif
1175 if (WINVERS_AMIV)
1176 amii_bmhd = ReadTileImageFiles();
1177 else
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)
1184 break;
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;
1195 #ifdef HACKFONT
1196 i = max(TextsFont->tf_XSize, HackFont->tf_XSize);
1197 if (NewHackScreen.Width < 80 * i + 4)
1198 NewHackScreen.Width = 80 * i + 4;
1199 #endif
1201 /* While openscreen fails try fewer colors to see if that is the problem.
1203 while ((HackScreen = OpenScreen((void *) &NewHackScreen)) == NULL) {
1204 #ifdef TEXTCOLOR
1205 if (--NewHackScreen.Depth < 3)
1206 #else
1207 if (--NewHackScreen.Depth < 2)
1208 #endif
1209 Abort(AN_OpenScreen & ~AT_DeadEnd);
1211 amii_numcolors = 1L << NewHackScreen.Depth;
1212 if (HackScreen->Height > 300 && forcenobig == 0)
1213 bigscreen = 1;
1214 else
1215 bigscreen = 0;
1217 #ifdef INTUI_NEW_LOOK
1218 if (IntuitionBase->LibNode.lib_Version >= 37)
1219 PubScreenStatus(HackScreen, 0);
1220 #endif
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, "");
1245 Initialized = 1;
1248 void
1249 amii_sethipens(struct Window *w, int type, int attr)
1251 switch (type) {
1252 default:
1253 SetAPen(w->RPort, attr ? C_RED : amii_otherAPen);
1254 SetBPen(w->RPort, C_BLACK);
1255 break;
1256 case NHW_STATUS:
1257 SetAPen(w->RPort, attr ? C_WHITE : amii_statAPen);
1258 SetBPen(w->RPort, amii_statBPen);
1259 break;
1260 case NHW_MESSAGE:
1261 SetAPen(w->RPort, attr ? C_WHITE : amii_msgAPen);
1262 SetBPen(w->RPort, amii_msgBPen);
1263 break;
1264 case NHW_MENU:
1265 SetAPen(w->RPort, attr ? C_BLACK : amii_menuAPen);
1266 SetBPen(w->RPort, amii_menuBPen);
1267 break;
1268 case NHW_TEXT:
1269 SetAPen(w->RPort, attr ? C_BLACK : amii_textAPen);
1270 SetBPen(w->RPort, amii_textBPen);
1271 case -2:
1272 SetBPen(w->RPort, amii_otherBPen);
1273 SetAPen(w->RPort, attr ? C_RED : amii_otherAPen);
1274 break;
1278 void
1279 amii_setfillpens(struct Window *w, int type)
1281 switch (type) {
1282 case NHW_MESSAGE:
1283 SetAPen(w->RPort, amii_msgBPen);
1284 SetBPen(w->RPort, amii_msgBPen);
1285 break;
1286 case NHW_STATUS:
1287 SetAPen(w->RPort, amii_statBPen);
1288 SetBPen(w->RPort, amii_statBPen);
1289 break;
1290 case NHW_MENU:
1291 SetAPen(w->RPort, amii_menuBPen);
1292 SetBPen(w->RPort, amii_menuBPen);
1293 break;
1294 case NHW_TEXT:
1295 SetAPen(w->RPort, amii_textBPen);
1296 SetBPen(w->RPort, amii_textBPen);
1297 break;
1298 case NHW_MAP:
1299 case NHW_BASE:
1300 case NHW_OVER:
1301 default:
1302 SetAPen(w->RPort, C_BLACK);
1303 SetBPen(w->RPort, C_BLACK);
1304 break;
1305 case -2:
1306 SetAPen(w->RPort, amii_otherBPen);
1307 SetBPen(w->RPort, amii_otherBPen);
1308 break;
1312 void
1313 amii_setdrawpens(struct Window *w, int type)
1315 switch (type) {
1316 case NHW_MESSAGE:
1317 SetAPen(w->RPort, amii_msgAPen);
1318 SetBPen(w->RPort, amii_msgBPen);
1319 break;
1320 case NHW_STATUS:
1321 SetAPen(w->RPort, amii_statAPen);
1322 SetBPen(w->RPort, amii_statBPen);
1323 break;
1324 case NHW_MENU:
1325 SetAPen(w->RPort, amii_menuAPen);
1326 SetBPen(w->RPort, amii_menuBPen);
1327 break;
1328 case NHW_TEXT:
1329 SetAPen(w->RPort, amii_textAPen);
1330 SetBPen(w->RPort, amii_textBPen);
1331 break;
1332 case NHW_MAP:
1333 case NHW_BASE:
1334 case NHW_OVER:
1335 SetAPen(w->RPort, C_WHITE);
1336 SetBPen(w->RPort, C_BLACK);
1337 break;
1338 default:
1339 SetAPen(w->RPort, amii_otherAPen);
1340 SetBPen(w->RPort, amii_otherBPen);
1341 break;
1345 /* Clear the indicated window */
1347 void
1348 amii_clear_nhwindow(win)
1349 register winid win;
1351 register struct amii_WinDesc *cw;
1352 register struct Window *w;
1354 if (reclip == 2)
1355 return;
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 */
1361 if (WINVERS_AMIV
1362 && (cw->type == WIN_MAP && WIN_OVER != WIN_ERR && reclip == 0)) {
1363 amii_clear_nhwindow(WIN_OVER);
1366 if (w = cw->win)
1367 SetDrMd(w->RPort, JAM2);
1368 else
1369 return;
1371 if ((cw->wflags & FLMAP_CURSUP)) {
1372 if (cw->type != NHW_MAP)
1373 cursor_off(win);
1374 else
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);
1385 } else {
1386 if (cw->type == NHW_MESSAGE) {
1387 amii_curs(win, 1, 0);
1388 if (!scrollmsg)
1389 TextSpaces(w->RPort, cw->cols);
1390 } else {
1391 RectFill(w->RPort, w->BorderLeft, w->BorderTop,
1392 w->Width - w->BorderRight - 1,
1393 w->Height - w->BorderBottom - 1);
1397 cw->cury = 0;
1398 cw->curx = 0;
1399 amii_curs(win, 1, 0);
1402 /* Dismiss the window from the screen */
1404 void
1405 dismiss_nhwindow(win)
1406 register winid 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");
1415 w = cw->win;
1417 if (w) {
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) {
1422 ClearMenuStrip(w);
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 */
1434 CloseShWindow(w);
1435 cw->win = NULL;
1437 /* Free copy of NewWindow structure for TEXT/MENU windows. */
1438 if (cw->newwin)
1439 FreeNewWindow((void *) cw->newwin);
1440 cw->newwin = NULL;
1444 void
1445 amii_exit_nhwindows(str)
1446 const char *str;
1448 /* Seems strange to have to do this... but we need the BASE window
1449 * left behind...
1451 kill_nhwindows(0);
1452 if (WINVERS_AMIV)
1453 FreeTileImageFiles();
1455 if (str) {
1456 raw_print(""); /* be sure we're not under the top margin */
1457 raw_print(str);
1461 void
1462 amii_display_nhwindow(win, blocking)
1463 winid win;
1464 boolean blocking;
1466 menu_item *mip;
1467 int cnt;
1468 static int lastwin = -1;
1469 struct amii_WinDesc *cw;
1471 if (!Initialized)
1472 return;
1473 lastwin = win;
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)
1482 return;
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]);
1499 void
1500 amii_curs(window, x, y)
1501 winid window;
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)
1513 return;
1514 else
1515 panic("No window open yet in curs() for winid %d\n", window);
1517 amiIDisplay->lastwin = window;
1519 /* Make sure x is within bounds */
1520 if (x > 0)
1521 --x; /* column 0 is never used */
1522 else
1523 x = 0;
1525 cw->curx = x;
1526 cw->cury = y;
1528 #ifdef DEBUG
1529 if (x < 0 || y < 0 || y >= cw->rows || x >= cw->cols) {
1530 char *s = "[unknown type]";
1531 switch (cw->type) {
1532 case NHW_MESSAGE:
1533 s = "[topl window]";
1534 break;
1535 case NHW_STATUS:
1536 s = "[status window]";
1537 break;
1538 case NHW_MAP:
1539 s = "[map window]";
1540 break;
1541 case NHW_MENU:
1542 s = "[menu window]";
1543 break;
1544 case NHW_TEXT:
1545 s = "[text window]";
1546 break;
1547 case NHW_BASE:
1548 s = "[base window]";
1549 break;
1550 case NHW_OVER:
1551 s = "[overview window]";
1552 break;
1554 impossible("bad curs positioning win %d %s (%d,%d)", window, s, x, y);
1555 return;
1557 #endif
1559 #ifdef CLIPPING
1560 if (clipping && cw->type == NHW_MAP) {
1561 x -= clipx;
1562 y -= clipy;
1564 #endif
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 */
1574 rp = w->RPort;
1575 if (cw->type == NHW_MENU) {
1576 if (WINVERS_AMIV) {
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);
1583 } else {
1584 Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1,
1585 (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1);
1587 } else {
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;
1607 if (WINVERS_AMIV) {
1608 if (cw->type == NHW_MAP) {
1609 if (Is_rogue_level(&u.uz)) {
1610 #if 0
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);
1614 #endif
1615 SetAPen(w->RPort,
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);
1619 } else {
1620 Move(rp, (x * mxsize) + w->BorderLeft,
1621 w->BorderTop + ((y + 1) * mysize) + 1);
1623 } else {
1624 Move(rp, (x * w->RPort->TxWidth) + w->BorderLeft,
1625 w->BorderTop + ((y + 1) * w->RPort->TxHeight)
1626 + w->RPort->TxBaseline + 1);
1628 } else {
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);
1643 } else {
1644 Move(rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
1645 (y * w->RPort->TxHeight) + w->BorderTop + w->RPort->TxBaseline
1646 + 1);
1650 void
1651 amii_set_text_font(name, size)
1652 char *name;
1653 int size;
1655 register int i;
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)
1668 return;
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) {
1676 switch (cw->type) {
1677 case NHW_STATUS:
1678 MoveWindow(cw->win, 0, -(size - osize) * 2);
1679 SizeWindow(cw->win, 0, (size - osize) * 2);
1680 SetFont(cw->win->RPort, TextsFont);
1681 break;
1682 case NHW_MESSAGE:
1683 case NHW_MAP:
1684 case NHW_BASE:
1685 case NHW_OVER:
1686 SetFont(cw->win->RPort, TextsFont);
1687 break;
1692 CloseLibrary(DiskfontBase);
1693 DiskfontBase = NULL;
1696 void
1697 kill_nhwindows(all)
1698 register int all;
1700 register int i;
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);
1713 void
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;
1721 if (!w)
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);
1732 void
1733 cursor_off(window)
1734 winid window;
1736 register struct amii_WinDesc *cw;
1737 register struct Window *w;
1738 register struct RastPort *rp;
1739 int curx, cury;
1740 int x, y;
1741 long dmode;
1742 short apen, bpen;
1743 unsigned char ch;
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))
1751 return;
1753 w = cw->win;
1755 if (!w)
1756 return;
1758 cw->wflags &= ~FLMAP_CURSUP;
1759 rp = w->RPort;
1761 /* Save the current information */
1762 curx = rp->cp_x;
1763 cury = rp->cp_y;
1764 x = cw->cursx;
1765 y = cw->cursy;
1766 dmode = rp->DrawMode;
1767 apen = rp->FgPen;
1768 bpen = rp->BgPen;
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);
1778 } else {
1779 ch = CURSOR_CHAR;
1780 Move(rp, x, y);
1781 Text(rp, &ch, 1);
1783 /* Put back the other stuff */
1785 Move(rp, curx, cury);
1787 SetDrMd(rp, dmode);
1788 SetAPen(rp, apen);
1789 SetBPen(rp, bpen);
1792 void
1793 cursor_on(window)
1794 winid window;
1796 int x, y;
1797 register struct amii_WinDesc *cw;
1798 register struct Window *w;
1799 register struct RastPort *rp;
1800 unsigned char ch;
1801 long dmode;
1802 short apen, bpen;
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))
1813 cursor_off(window);
1815 w = cw->win;
1817 if (!w)
1818 return;
1820 cw->wflags |= FLMAP_CURSUP;
1821 rp = w->RPort;
1823 /* Save the current information */
1825 #ifdef DISPMAP
1826 if (WINVERS_AMIV && cw->type == NHW_MAP && !Is_rogue_level(&u.uz))
1827 x = cw->cursx = (rp->cp_x & -8) + 8;
1828 else
1829 #endif
1830 x = cw->cursx = rp->cp_x;
1831 y = cw->cursy = rp->cp_y;
1832 apen = rp->FgPen;
1833 bpen = rp->BgPen;
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);
1845 } else {
1846 Move(rp, x, y);
1847 ch = CURSOR_CHAR;
1848 Text(rp, &ch, 1);
1849 Move(rp, x, y);
1852 SetDrMd(rp, dmode);
1853 SetAPen(rp, apen);
1854 SetBPen(rp, bpen);
1857 static void
1858 cursor_common(rp, x, y)
1859 struct RastPort *rp;
1860 int x, y;
1862 int x1, x2, y1, y2;
1864 if (Is_rogue_level(&u.uz)) {
1865 x1 = x - 2;
1866 y1 = y - rp->TxHeight;
1867 x2 = x + rp->TxWidth + 1;
1868 y2 = y + 3;
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);*/
1871 } else {
1872 x1 = x;
1873 y1 = y - mysize - 1;
1874 x2 = x + mxsize - 1;
1875 y2 = y - 2;
1876 RectFill(rp, x1, y1, x2, y2);
1879 RectFill(rp, x1 + 2, y1 + 2, x2 - 2, y2 - 2);
1882 void
1883 amii_suspend_nhwindows(str)
1884 const char *str;
1886 if (HackScreen)
1887 ScreenToBack(HackScreen);
1890 void
1891 amii_resume_nhwindows()
1893 if (HackScreen)
1894 ScreenToFront(HackScreen);
1897 void
1898 amii_bell()
1900 DisplayBeep(NULL);
1903 void
1904 removetopl(cnt)
1905 int cnt;
1907 struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
1908 /* NB - this is sufficient for
1909 * yn_function, but that's it
1911 if (cw->curx < cnt)
1912 cw->curx = 0;
1913 else
1914 cw->curx -= cnt;
1916 amii_curs(WIN_MESSAGE, cw->curx + 1, cw->cury);
1917 amii_cl_end(cw, cw->curx);
1919 /*#endif /* AMIGA_INTUITION */
1921 #ifdef PORT_HELP
1922 void
1923 port_help()
1925 display_file(PORT_HELP, 1);
1927 #endif
1930 * print_glyph
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)!
1938 void
1939 amii_print_glyph(win, x, y, glyph, bkglyph)
1940 winid win;
1941 xchar x, y;
1942 int glyph, bkglyph;
1944 struct amii_WinDesc *cw;
1945 uchar ch;
1946 int color, och;
1947 extern const int zapcolors[];
1948 unsigned special;
1950 /* In order for the overview window to work, we can not clip here */
1951 if (!WINVERS_AMIV) {
1952 #ifdef CLIPPING
1953 /* If point not in visible part of window just skip it */
1954 if (clipping) {
1955 if (x <= clipx || y < clipy || x >= clipxmax || y >= clipymax)
1956 return;
1958 #endif
1961 if (win == WIN_ERR || (cw = amii_wins[win]) == NULL
1962 || cw->type != NHW_MAP) {
1963 panic(winpanicstr, win, "amii_print_glyph");
1966 #if 0
1968 static int x=-1;
1969 if(u.uz.dlevel != x){
1970 fprintf(stderr,"lvlchg: %d (%d)\n",u.uz.dlevel,Is_rogue_level(&u.uz));
1971 x = u.uz.dlevel;
1974 #endif
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);
1982 ch = (uchar) och;
1983 if (WINVERS_AMIV) { /* implies Rogue level here */
1984 amii_curs(win, x, y);
1985 amiga_print_glyph(win, NO_COLOR, ch + 10000);
1986 } else {
1987 /* Move the cursor. */
1988 amii_curs(win, x, y + 2);
1990 #ifdef TEXTCOLOR
1991 /* Turn off color if rogue level. */
1992 if (Is_rogue_level(&u.uz))
1993 color = NO_COLOR;
1995 amiga_print_glyph(win, color, ch);
1996 #else
1997 g_putch(ch); /* print the character */
1998 #endif
1999 cw->curx++; /* one character over */
2004 /* Make sure the user sees a text string when no windowing is available */
2006 void
2007 amii_raw_print(s)
2008 register const char *s;
2010 int argc = 0;
2012 if (!s)
2013 return;
2014 if (amiIDisplay)
2015 amiIDisplay->rawprint++;
2017 if (!Initialized) { /* Not yet screen open ... */
2018 puts(s);
2019 fflush(stdout);
2020 return;
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);
2032 else {
2033 puts(s);
2034 fflush(stdout);
2038 /* Make sure the user sees a bold text string when no windowing
2039 * is available
2042 void
2043 amii_raw_print_bold(s)
2044 register const char *s;
2046 int argc = 0;
2048 if (!s)
2049 return;
2051 if (amiIDisplay)
2052 amiIDisplay->rawprint++;
2054 if (!Initialized) { /* Not yet screen open ... */
2055 puts(s);
2056 fflush(stdout);
2057 return;
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);
2069 else {
2070 printf("\33[1m%s\33[0m\n", s);
2071 fflush(stdout);
2075 /* Rebuild/update the inventory if the window is up.
2077 void
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 */
2090 void
2091 amii_mark_synch()
2093 if (!amiIDisplay)
2094 fflush(stderr);
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.
2101 void
2102 amii_wait_synch()
2104 if (!amiIDisplay || amiIDisplay->rawprint) {
2105 if (amiIDisplay)
2106 amiIDisplay->rawprint = 0;
2107 } else {
2108 if (WIN_MAP != WIN_ERR) {
2109 display_nhwindow(WIN_MAP, TRUE);
2110 flush_glyph_buffer(amii_wins[WIN_MAP]->win);
2115 void
2116 amii_setclipped()
2118 #ifdef CLIPPING
2119 clipping = TRUE;
2120 clipx = clipy = 0;
2121 clipxmax = CO;
2122 clipymax = LI;
2123 /* some of this is now redundant with top of amii_cliparound XXX */
2124 #endif
2127 /* XXX still to do: suppress scrolling if we violate the boundary but the
2128 * edge of the map is already displayed
2130 void
2131 amii_cliparound(x, y)
2132 register int x, y;
2134 extern boolean restoring;
2135 #ifdef CLIPPING
2136 int oldx = clipx, oldy = clipy;
2137 int oldxmax = clipxmax, oldymax = clipymax;
2138 int COx, LIx;
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 */
2142 return;
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;
2150 } else {
2151 COx = CO;
2152 LIx = LI;
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 */
2164 clipx = clipy = 0;
2165 clipxmax = COx;
2166 clipymax = LIx;
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;
2187 reclip = 1;
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;
2196 int scrx, scry;
2198 if (Is_rogue_level(&u.uz)) {
2199 scrx = rp->TxWidth;
2200 scry = rp->TxHeight;
2201 } else {
2202 scrx = mxsize;
2203 scry = mysize;
2206 /* Ask that the glyph routines not draw the overview window */
2207 reclip = 2;
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
2220 if (incx == 0)
2221 incx = (mincx != 0);
2222 if (incy == 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 */
2232 savex = clipx;
2233 savey = clipy;
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 */
2243 if( xdelta < 0 )
2245 clipx = oldx;
2246 clipxmax = clipx + incx;
2248 else if( xdelta > 0 )
2250 clipxmax = oldxmax;
2251 clipx = clipxmax - incx;
2253 else
2255 clipx = oldx;
2256 clipxmax = oldxmax;
2259 if( ydelta < 0 )
2261 clipy = oldy;
2262 clipymax = clipy + incy;
2264 else if( ydelta > 0 )
2266 clipymax = oldymax;
2267 clipy = clipymax - incy;
2269 else
2271 clipy = oldy;
2272 clipymax = oldymax;
2274 #endif
2275 /* Now, in scrollcnt moves, move the picture toward the final view */
2276 for (i = 0; i < scrollcnt; ++i) {
2277 #ifdef DISPMAP
2278 if (i == scrollcnt - 1 && (xmod != 0 || ymod != 0)
2279 && (xdelta != 0 || ydelta != 0)) {
2280 incx += (clipx - oldx) % scrollcnt;
2281 incy += (clipy - oldy) % scrollcnt;
2282 xdelta += xmod;
2283 ydelta += ymod;
2285 #endif
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);
2292 if (mincx == 0)
2293 incx = 0;
2294 else
2295 mincx -= incx;
2297 clipx += incx;
2298 clipxmax += incx;
2300 if (mincy == 0)
2301 incy = 0;
2302 else
2303 mincy -= incy;
2305 clipy += incy;
2306 clipymax += incy;
2308 /* Draw the exposed portion */
2309 if (on_level(&u.uz0, &u.uz) && !restoring)
2310 (void) doredraw();
2311 flush_glyph_buffer(amii_wins[WIN_MAP]->win);
2315 clipx = savex;
2316 clipy = savey;
2317 clipymax = saveymax;
2318 clipxmax = savexmax;
2319 #endif
2320 if (on_level(&u.uz0, &u.uz) && !restoring && moves > 1)
2321 (void) doredraw();
2322 flush_glyph_buffer(amii_wins[WIN_MAP]->win);
2324 reclip = 0;
2325 #endif
2328 void
2329 flushIDCMP(port)
2330 struct MsgPort *port;
2332 struct Message *msg;
2333 while (msg = GetMsg(port))
2334 ReplyMsg(msg);