/variants/slashem/sys/amiga/winfuncs.c

https://bitbucket.org/clivecrous/ruhack · C · 2451 lines · 1969 code · 284 blank · 198 comment · 547 complexity · 020a8c4a9f3473ba1ab757708602a614 MD5 · raw file

Large files are truncated click here to view the full file

  1. /* SCCS Id: @(#)winfuncs.c 3.1 2000/01/12 */
  2. /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996. */
  3. /* NetHack may be freely redistributed. See license for details. */
  4. #include "NH:sys/amiga/windefs.h"
  5. #include "NH:sys/amiga/winext.h"
  6. #include "NH:sys/amiga/winproto.h"
  7. #include "patchlevel.h"
  8. extern struct TagItem scrntags[];
  9. static BitMapHeader amii_bmhd;
  10. static void cursor_common(struct RastPort *, int, int);
  11. #ifdef CLIPPING
  12. int CO, LI;
  13. /* Changing clipping region, skip clear of screen in overview window. */
  14. int reclip;
  15. /* Must be set to at least two or you will get stuck! */
  16. int xclipbord = 4, yclipbord = 2;
  17. #endif
  18. int mxsize, mysize;
  19. struct Rectangle amii_oldover;
  20. struct Rectangle amii_oldmsg;
  21. extern struct TextFont *RogueFont;
  22. int amii_msgAPen;
  23. int amii_msgBPen;
  24. int amii_statAPen;
  25. int amii_statBPen;
  26. int amii_menuAPen;
  27. int amii_menuBPen;
  28. int amii_textAPen;
  29. int amii_textBPen;
  30. int amii_otherAPen;
  31. int amii_otherBPen;
  32. long amii_libvers = LIBRARY_FONT_VERSION;
  33. void
  34. ami_wininit_data( void )
  35. {
  36. extern unsigned short amii_init_map[ AMII_MAXCOLORS ];
  37. extern unsigned short amiv_init_map[ AMII_MAXCOLORS ];
  38. if( !WINVERS_AMIV )
  39. {
  40. # ifdef TEXTCOLOR
  41. amii_numcolors = 8;
  42. # else
  43. amii_numcolors = 4;
  44. # endif
  45. amii_defpens[ 0 ] = C_BLACK; /* DETAILPEN */
  46. amii_defpens[ 1 ] = C_BLUE; /* BLOCKPEN */
  47. amii_defpens[ 2 ] = C_BROWN; /* TEXTPEN */
  48. amii_defpens[ 3 ] = C_WHITE; /* SHINEPEN */
  49. amii_defpens[ 4 ] = C_BLUE; /* SHADOWPEN */
  50. amii_defpens[ 5 ] = C_CYAN; /* FILLPEN */
  51. amii_defpens[ 6 ] = C_WHITE; /* FILLTEXTPEN */
  52. amii_defpens[ 7 ] = C_CYAN; /* BACKGROUNDPEN */
  53. amii_defpens[ 8 ] = C_RED; /* HIGHLIGHTTEXTPEN */
  54. amii_defpens[ 9 ] = C_WHITE; /* BARDETAILPEN */
  55. amii_defpens[ 10 ] = C_CYAN; /* BARBLOCKPEN */
  56. amii_defpens[ 11 ] = C_BLUE; /* BARTRIMPEN */
  57. amii_defpens[ 12 ] = (unsigned short) ~0;
  58. amii_msgAPen = C_WHITE;
  59. amii_msgBPen = C_BLACK;
  60. amii_statAPen = C_WHITE;
  61. amii_statBPen = C_BLACK;
  62. amii_menuAPen = C_WHITE;
  63. amii_menuBPen = C_BLACK;
  64. amii_textAPen = C_WHITE;
  65. amii_textBPen = C_BLACK;
  66. amii_otherAPen = C_RED;
  67. amii_otherBPen = C_BLACK;
  68. mxsize = 8;
  69. mysize = 8;
  70. amii_libvers = LIBRARY_FONT_VERSION;
  71. memcpy( amii_initmap, amii_init_map, sizeof( amii_initmap ) );
  72. }
  73. else
  74. {
  75. mxsize = 16;
  76. mysize = 16;
  77. amii_numcolors = 16;
  78. amii_defpens[ 0 ] = C_BLACK; /* DETAILPEN */
  79. amii_defpens[ 1 ] = C_WHITE; /* BLOCKPEN */
  80. amii_defpens[ 2 ] = C_BLACK; /* TEXTPEN */
  81. amii_defpens[ 3 ] = C_CYAN; /* SHINEPEN */
  82. amii_defpens[ 4 ] = C_BLUE; /* SHADOWPEN */
  83. amii_defpens[ 5 ] = C_GREYBLUE; /* FILLPEN */
  84. amii_defpens[ 6 ] = C_LTGREY; /* FILLTEXTPEN */
  85. amii_defpens[ 7 ] = C_GREYBLUE; /* BACKGROUNDPEN */
  86. amii_defpens[ 8 ] = C_RED; /* HIGHLIGHTTEXTPEN */
  87. amii_defpens[ 9 ] = C_WHITE; /* BARDETAILPEN */
  88. amii_defpens[ 10] = C_GREYBLUE; /* BARBLOCKPEN */
  89. amii_defpens[ 11] = C_BLUE; /* BARTRIMPEN */
  90. amii_defpens[ 12] = (unsigned short) ~0;
  91. amii_msgAPen = C_WHITE;
  92. amii_msgBPen = C_GREYBLUE;
  93. amii_statAPen = C_WHITE;
  94. amii_statBPen = C_GREYBLUE;
  95. amii_menuAPen = C_BLACK;
  96. amii_menuBPen = C_LTGREY;
  97. amii_textAPen = C_BLACK;
  98. amii_textBPen = C_LTGREY;
  99. amii_otherAPen = C_RED;
  100. amii_otherBPen = C_BLACK;
  101. amii_libvers = LIBRARY_TILE_VERSION;
  102. memcpy( amii_initmap, amiv_init_map, sizeof( amii_initmap ) );
  103. }
  104. #ifdef OPT_DISPMAP
  105. dispmap_sanity();
  106. #endif
  107. memcpy(flags.amii_dripens,amii_defpens,sizeof(flags.amii_dripens));
  108. }
  109. # ifdef INTUI_NEW_LOOK
  110. struct Hook SM_FilterHook;
  111. struct Hook fillhook;
  112. struct TagItem wintags[] =
  113. {
  114. { WA_BackFill, (ULONG)&fillhook },
  115. { WA_PubScreenName, (ULONG)"NetHack" },
  116. { TAG_END, 0 },
  117. };
  118. # endif
  119. void
  120. amii_destroy_nhwindow(win) /* just hide */
  121. register winid win;
  122. {
  123. int i;
  124. int type;
  125. register struct amii_WinDesc *cw;
  126. if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  127. {
  128. panic(winpanicstr,win,"destroy_nhwindow");
  129. }
  130. if( WINVERS_AMIV )
  131. {
  132. if( cw->type == NHW_MAP )
  133. {
  134. /* If inventory is up, close it now, it will be freed later */
  135. if( alwaysinvent && WIN_INVEN != WIN_ERR &&
  136. amii_wins[ WIN_INVEN ] &&
  137. amii_wins[ WIN_INVEN ]->win )
  138. {
  139. dismiss_nhwindow( WIN_INVEN );
  140. }
  141. /* Tear down overview window if it is up */
  142. if( WIN_OVER != WIN_ERR )
  143. {
  144. amii_destroy_nhwindow( WIN_OVER );
  145. WIN_OVER = WIN_ERR;
  146. }
  147. }
  148. else if( cw->type == NHW_OVER )
  149. {
  150. struct Window *w = amii_wins[ WIN_OVER ]->win;
  151. amii_oldover.MinX = w->LeftEdge;
  152. amii_oldover.MinY = w->TopEdge;
  153. amii_oldover.MaxX = w->Width;
  154. amii_oldover.MaxY = w->Height;
  155. if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
  156. {
  157. w = amii_wins[ WIN_MESSAGE ]->win;
  158. amii_oldmsg.MinX = w->LeftEdge;
  159. amii_oldmsg.MinY = w->TopEdge;
  160. amii_oldmsg.MaxX = w->Width;
  161. amii_oldmsg.MaxY = w->Height;
  162. SizeWindow( amii_wins[ WIN_MESSAGE ]->win,
  163. (amiIDisplay->xpix -
  164. amii_wins[ WIN_MESSAGE ]->win->LeftEdge) -
  165. amii_wins[ WIN_MESSAGE ]->win->Width,
  166. 0 );
  167. }
  168. }
  169. }
  170. /* Tear down the Intuition stuff */
  171. dismiss_nhwindow(win);
  172. type = cw->type;
  173. if( cw->resp ) {
  174. free( cw->resp );
  175. cw->resp = NULL;
  176. }
  177. if( cw->canresp ) {
  178. free( cw->canresp );
  179. cw->canresp = NULL;
  180. }
  181. if( cw->morestr ) {
  182. free( cw->morestr );
  183. cw->morestr = NULL;
  184. }
  185. if( cw->hook ) {
  186. free( cw->hook );
  187. cw->hook = NULL;
  188. }
  189. if( cw->data && ( cw->type == NHW_MESSAGE ||
  190. cw->type == NHW_MENU || cw->type == NHW_TEXT ) )
  191. {
  192. for( i = 0; i < cw->maxrow; ++i )
  193. {
  194. if( cw->data[ i ] )
  195. free( cw->data[ i ] );
  196. }
  197. free( cw->data );
  198. }
  199. free( cw );
  200. amii_wins[win] = NULL;
  201. /* Set globals to WIN_ERR for known one-of-a-kind windows. */
  202. if( win == WIN_MAP) WIN_MAP = WIN_ERR;
  203. else if( win == WIN_STATUS) WIN_STATUS = WIN_ERR;
  204. else if( win == WIN_MESSAGE) WIN_MESSAGE = WIN_ERR;
  205. else if( win == WIN_INVEN) WIN_INVEN = WIN_ERR;
  206. }
  207. #ifdef INTUI_NEW_LOOK
  208. struct FillParams
  209. {
  210. struct Layer *layer;
  211. struct Rectangle bounds;
  212. WORD offsetx;
  213. WORD offsety;
  214. };
  215. #ifdef __GNUC__
  216. #ifdef __PPC__
  217. void PPC_LayerFillHook(void);
  218. struct EmulLibEntry LayerFillHook = {TRAP_LIB, 0, (void (*)(void)) PPC_LayerFillHook};
  219. void PPC_LayerFillHook(void) {
  220. struct Hook *hk = (struct Hook*)REG_A0;
  221. struct RastPort *rp = (struct RastPort *)REG_A2;
  222. struct FillParams *fp = (struct FillParams*)REG_A1;
  223. #else
  224. void LayerFillHook(void) {
  225. register struct Hook *hk asm("a0");
  226. register struct RastPort *rp asm("a2");
  227. register struct FillParams *fp asm("a1");
  228. #endif
  229. #else
  230. void
  231. #ifndef _DCC
  232. __interrupt
  233. #endif
  234. __saveds __asm LayerFillHook(
  235. register __a0 struct Hook *hk,
  236. register __a2 struct RastPort *rp,
  237. register __a1 struct FillParams *fp )
  238. {
  239. #endif
  240. register long x, y, xmax, ymax;
  241. register int apen;
  242. struct RastPort rptmp;
  243. memcpy(&rptmp, rp, sizeof(struct RastPort));
  244. rptmp.Layer = NULL;
  245. switch( (int)hk->h_Data )
  246. {
  247. case NHW_STATUS:
  248. apen = amii_statBPen;
  249. break;
  250. case NHW_MESSAGE:
  251. apen = amii_msgBPen;
  252. break;
  253. case NHW_TEXT:
  254. apen = amii_textBPen;
  255. break;
  256. case NHW_MENU:
  257. apen = amii_menuBPen;
  258. break;
  259. case -2:
  260. apen = amii_otherBPen;
  261. break;
  262. case NHW_BASE:
  263. case NHW_MAP:
  264. case NHW_OVER:
  265. default:
  266. apen = C_BLACK;
  267. break;
  268. }
  269. x = fp->bounds.MinX;
  270. y = fp->bounds.MinY;
  271. xmax = fp->bounds.MaxX;
  272. ymax = fp->bounds.MaxY;
  273. SetAPen(&rptmp, apen);
  274. SetBPen(&rptmp, apen);
  275. SetDrMd(&rptmp, JAM2);
  276. RectFill(&rptmp, x, y, xmax, ymax);
  277. }
  278. #endif
  279. amii_create_nhwindow(type)
  280. register int type;
  281. {
  282. register struct Window *w = NULL;
  283. register struct NewWindow *nw = NULL;
  284. register struct amii_WinDesc *wd = NULL;
  285. struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL;
  286. register int newid;
  287. int maph, stath, scrfontysize;
  288. scrfontysize = HackScreen->Font->ta_YSize;
  289. /*
  290. * Initial mapwindow height, this might change later in tilemode
  291. * and low screen
  292. */
  293. maph = ( 21 * mxsize ) + 2 + (bigscreen ?
  294. HackScreen->WBorTop + HackScreen->WBorBottom + scrfontysize + 1 : 0);
  295. /* Status window height, avoids having to calculate many times */
  296. stath = txheight * 2 + 2 + (WINVERS_AMIV || bigscreen ?
  297. HackScreen->WBorTop + HackScreen->WBorBottom +
  298. ( bigscreen ? scrfontysize + 1 : 0 ) : 0);
  299. if( WIN_STATUS != WIN_ERR && amii_wins[ WIN_STATUS ] )
  300. stwin = amii_wins[ WIN_STATUS ]->win;
  301. if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
  302. msgwin = amii_wins[ WIN_MESSAGE ]->win;
  303. if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  304. mapwin = amii_wins[ WIN_MAP ]->win;
  305. /* Create Port anytime that we need it */
  306. if( HackPort == NULL )
  307. {
  308. HackPort = CreateMsgPort();
  309. if( !HackPort )
  310. panic( "no memory for msg port" );
  311. }
  312. nw = &new_wins[ type ].newwin;
  313. nw->Width = amiIDisplay->xpix;
  314. nw->Screen = HackScreen;
  315. if( WINVERS_AMIV )
  316. {
  317. nw->DetailPen = C_WHITE;
  318. nw->BlockPen = C_GREYBLUE;
  319. }
  320. else
  321. {
  322. nw->DetailPen = C_WHITE;
  323. nw->BlockPen = C_BLACK;
  324. }
  325. if ( type == NHW_BASE ) {
  326. nw->LeftEdge = 0;
  327. nw->TopEdge = HackScreen->BarHeight+1;
  328. nw->Width = HackScreen->Width;
  329. nw->Height = HackScreen->Height - nw->TopEdge;
  330. } else if( !WINVERS_AMIV && type == NHW_MAP ) {
  331. nw->LeftEdge = 0;
  332. nw->Height = maph;
  333. if( msgwin && stwin ) {
  334. nw->TopEdge = stwin->TopEdge - maph;
  335. } else {
  336. panic( "msgwin and stwin must open before map" );
  337. }
  338. if (nw->TopEdge < 0)
  339. panic( "Too small screen to fit map" );
  340. }
  341. else if( type == NHW_MAP && WINVERS_AMIV )
  342. {
  343. struct Window *w;
  344. w = amii_wins[ WIN_MESSAGE ]->win;
  345. nw->LeftEdge = 0;
  346. nw->TopEdge = w->TopEdge + w->Height;
  347. nw->Width = amiIDisplay->xpix - nw->LeftEdge;
  348. w = amii_wins[ WIN_STATUS ]->win;
  349. nw->Height = w->TopEdge - nw->TopEdge;
  350. nw->MaxHeight = 0xffff;
  351. nw->MaxWidth = 0xffff;
  352. if( nw->TopEdge + nw->Height > amiIDisplay->ypix - 1 )
  353. nw->Height = amiIDisplay->ypix - nw->TopEdge - 1;
  354. }
  355. else if( type == NHW_STATUS )
  356. {
  357. if( !WINVERS_AMIV && ( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] ) )
  358. w = amii_wins[ WIN_MAP ]->win;
  359. else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
  360. w = amii_wins[ WIN_BASE ]->win;
  361. else
  362. panic( "No window to base STATUS location from" );
  363. nw->Height = stath;
  364. nw->TopEdge = amiIDisplay->ypix - nw->Height;
  365. nw->LeftEdge = w->LeftEdge;
  366. if( nw->LeftEdge + nw->Width >= amiIDisplay->xpix )
  367. nw->LeftEdge = 0;
  368. if( nw->Width >= amiIDisplay->xpix - nw->LeftEdge )
  369. nw->Width = amiIDisplay->xpix - nw->LeftEdge;
  370. }
  371. else if( WINVERS_AMIV && type == NHW_OVER )
  372. {
  373. nw->Flags |= WINDOWSIZING|WINDOWDRAG|WINDOWCLOSE;
  374. nw->IDCMPFlags |= CLOSEWINDOW;
  375. /* Bring up window as half the width of the message window, and make
  376. * the message window change to one half the width...
  377. */
  378. if( amii_oldover.MaxX != 0 )
  379. {
  380. nw->LeftEdge = amii_oldover.MinX;
  381. nw->TopEdge = amii_oldover.MinY;
  382. nw->Width = amii_oldover.MaxX;
  383. nw->Height = amii_oldover.MaxY;
  384. ChangeWindowBox( amii_wins[ WIN_MESSAGE ]->win,
  385. amii_oldmsg.MinX, amii_oldmsg.MinY,
  386. amii_oldmsg.MaxX, amii_oldmsg.MaxY );
  387. }
  388. else
  389. {
  390. nw->LeftEdge = (amii_wins[ WIN_MESSAGE ]->win->Width*4)/9;
  391. nw->TopEdge = amii_wins[ WIN_MESSAGE ]->win->TopEdge;
  392. nw->Width = amiIDisplay->xpix - nw->LeftEdge;
  393. nw->Height = amii_wins[ WIN_MESSAGE ]->win->Height;
  394. SizeWindow( amii_wins[ WIN_MESSAGE ]->win,
  395. nw->LeftEdge - amii_wins[ WIN_MESSAGE ]->win->Width, 0 );
  396. }
  397. }
  398. else if( type == NHW_MESSAGE )
  399. {
  400. if( !WINVERS_AMIV && ( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] ) )
  401. w = amii_wins[ WIN_MAP ]->win;
  402. else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
  403. w = amii_wins[ WIN_BASE ]->win;
  404. else
  405. panic( "No window to base STATUS location from" );
  406. nw->TopEdge = bigscreen ? HackScreen->BarHeight+1 : 0;
  407. /* Assume highest possible message window */
  408. nw->Height = HackScreen->Height - nw->TopEdge - maph - stath;
  409. /* In tilemode we can cope with this */
  410. if (WINVERS_AMIV && nw->Height < 0)
  411. nw->Height = 0;
  412. /* If in fontmode messagewindow is too small, open it with 3 lines
  413. and overlap it with map */
  414. if (nw->Height < txheight+2) {
  415. nw->Height = txheight*4 + 3 + HackScreen->WBorTop + HackScreen->WBorBottom;
  416. }
  417. if ((nw->Height-2)/txheight < 3) {
  418. scrollmsg = 0;
  419. nw->Title = 0;
  420. } else {
  421. nw->FirstGadget = &MsgScroll;
  422. nw->Flags |= WINDOWSIZING|WINDOWDRAG;
  423. nw->Flags &= ~BORDERLESS;
  424. if( WINVERS_AMIV || nw->Height == 0) {
  425. if( WINVERS_AMIV ) {
  426. nw->Height = TextsFont->tf_YSize + HackScreen->WBorTop + 3 +
  427. HackScreen->WBorBottom;
  428. if( bigscreen )
  429. nw->Height += ( txheight * 6 );
  430. else
  431. nw->Height += ( txheight * 3 );
  432. }
  433. else
  434. {
  435. nw->Height = HackScreen->Height - nw->TopEdge - stath - maph;
  436. }
  437. }
  438. }
  439. /* Do we have room for larger message window ?
  440. * This is possible if we can show full height map in tile
  441. * mode with default scaling.
  442. */
  443. if (nw->Height + stath + maph < HackScreen->Height - nw->TopEdge )
  444. nw->Height = HackScreen->Height - nw->TopEdge - 1 - maph - stath;
  445. #ifdef INTUI_NEW_LOOK
  446. if( IntuitionBase->LibNode.lib_Version >= 37 )
  447. {
  448. MsgPropScroll.Flags |= PROPNEWLOOK;
  449. PropScroll.Flags |= PROPNEWLOOK;
  450. }
  451. #endif
  452. }
  453. nw->IDCMPFlags |= MENUPICK;
  454. /* Check if there is "Room" for all this stuff... */
  455. if( ( WINVERS_AMIV || bigscreen ) &&
  456. type != NHW_BASE )
  457. {
  458. nw->Flags &= ~( BORDERLESS | BACKDROP );
  459. if( WINVERS_AMIV )
  460. {
  461. if( type == NHW_STATUS )
  462. {
  463. nw->Flags &= ~( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING );
  464. nw->IDCMPFlags &= ~NEWSIZE;
  465. }
  466. else
  467. {
  468. nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT | WINDOWSIZING );
  469. nw->IDCMPFlags |= NEWSIZE;
  470. }
  471. }
  472. else
  473. {
  474. if( HackScreen->Width < 657 )
  475. {
  476. nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH );
  477. }
  478. else
  479. {
  480. nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT );
  481. }
  482. }
  483. }
  484. if ( WINVERS_AMII && type == NHW_MAP )
  485. nw->Flags &= ~WINDOWSIZING;
  486. if ( type == NHW_MESSAGE && scrollmsg ) {
  487. nw->Flags |= WINDOWDRAG|WINDOWDEPTH|SIZEBRIGHT|WINDOWSIZING;
  488. nw->Flags &= ~BORDERLESS;
  489. }
  490. /* No titles on a hires only screen except for messagewindow */
  491. if( !(WINVERS_AMIV && type == NHW_MAP) && !bigscreen && type != NHW_MESSAGE )
  492. nw->Title = 0;
  493. wd = (struct amii_WinDesc *)alloc(sizeof(struct amii_WinDesc));
  494. memset( wd, 0, sizeof( struct amii_WinDesc ) );
  495. /* Both, since user may have changed the pen settings so respect those */
  496. if( WINVERS_AMII || WINVERS_AMIV )
  497. {
  498. /* Special backfill for these types of layers */
  499. switch( type )
  500. {
  501. case NHW_MESSAGE:
  502. case NHW_STATUS:
  503. case NHW_TEXT:
  504. case NHW_MENU:
  505. case NHW_BASE:
  506. case NHW_OVER:
  507. case NHW_MAP:
  508. if( wd )
  509. {
  510. #ifdef __GNUC__
  511. fillhook.h_Entry = (void *)&LayerFillHook;
  512. #else
  513. fillhook.h_Entry = (ULONG(*)())LayerFillHook;
  514. #endif
  515. fillhook.h_Data = (void *)type;
  516. fillhook.h_SubEntry = 0;
  517. wd->hook = alloc( sizeof( fillhook ) );
  518. memcpy( wd->hook, &fillhook, sizeof( fillhook ) );
  519. memcpy( wd->wintags, wintags, sizeof( wd->wintags) );
  520. wd->wintags[0].ti_Data = (long)wd->hook;
  521. nw->Extension = (void *)wd->wintags;
  522. }
  523. break;
  524. }
  525. }
  526. /* Don't open MENU or TEXT windows yet */
  527. if( type == NHW_MENU || type == NHW_TEXT )
  528. w = NULL;
  529. else
  530. w=OpenShWindow( (void *)nw );
  531. if( w == NULL && type != NHW_MENU && type != NHW_TEXT )
  532. {
  533. char buf[ 100 ];
  534. sprintf( buf, "nw type (%d) dims l: %d, t: %d, w: %d, h: %d",
  535. type,
  536. nw->LeftEdge, nw->TopEdge,
  537. nw->Width, nw->Height );
  538. raw_print( buf );
  539. panic("bad openwin %d",type);
  540. }
  541. /* Check for an empty slot */
  542. for(newid = 0; newid<MAXWIN + 1; newid++)
  543. {
  544. if(amii_wins[newid] == 0)
  545. break;
  546. }
  547. if(newid==MAXWIN+1)
  548. panic("time to write re-alloc code\n");
  549. /* Set wincnt accordingly */
  550. if( newid > wincnt )
  551. wincnt = newid;
  552. /* Do common initialization */
  553. amii_wins[newid] = wd;
  554. wd->newwin = NULL;
  555. wd->win = w;
  556. wd->type = type;
  557. wd->wflags = 0;
  558. wd->active = FALSE;
  559. wd->curx=wd->cury = 0;
  560. wd->resp = wd->canresp = wd->morestr = 0; /* CHECK THESE */
  561. wd->maxrow = new_wins[type].maxrow;
  562. wd->maxcol = new_wins[type].maxcol;
  563. if( type != NHW_TEXT && type != NHW_MENU )
  564. {
  565. if( TextsFont && ( type == NHW_MESSAGE || type == NHW_STATUS ) )
  566. {
  567. SetFont(w->RPort, TextsFont);
  568. txheight = w->RPort->TxHeight;
  569. txwidth = w->RPort->TxWidth;
  570. txbaseline = w->RPort->TxBaseline;
  571. if( type == NHW_MESSAGE )
  572. {
  573. if (scrollmsg )
  574. {
  575. if( WINVERS_AMIV )
  576. {
  577. WindowLimits( w, 100, w->BorderTop +
  578. w->BorderBottom +
  579. ((txheight+1)*2) + 1, 0, 0 );
  580. }
  581. else
  582. {
  583. WindowLimits( w, w->Width, w->BorderTop +
  584. w->BorderBottom +
  585. ((txheight+1)*2) + 1, 0, 0 );
  586. }
  587. }
  588. else
  589. {
  590. WindowLimits( w, w->Width, w->BorderTop +
  591. w->BorderBottom +
  592. txheight + 2, 0, 0 );
  593. }
  594. }
  595. }
  596. if ( type != NHW_MAP) {
  597. SetFont(w->RPort, TextsFont);
  598. }
  599. #ifdef HACKFONT
  600. else if( HackFont )
  601. SetFont(w->RPort, HackFont);
  602. #endif
  603. }
  604. /* Text and menu windows are not opened yet */
  605. if( w )
  606. {
  607. wd->rows = ( w->Height - w->BorderTop -
  608. w->BorderBottom - 2 ) / w->RPort->TxHeight;
  609. wd->cols = ( w->Width - w->BorderLeft -
  610. w->BorderRight - 2 ) / w->RPort->TxWidth;
  611. }
  612. /* Okay, now do the individual type initialization */
  613. switch(type)
  614. {
  615. /* History lines for MESSAGE windows are stored in cw->data[?].
  616. * maxcol and maxrow are used as cursors. maxrow is the count
  617. * of the number of history lines stored. maxcol is the cursor
  618. * to the last line that was displayed by ^P.
  619. */
  620. case NHW_MESSAGE:
  621. SetMenuStrip(w, MenuStrip);
  622. MsgScroll.TopEdge = HackScreen->WBorTop + scrfontysize + 1;
  623. iflags.msg_history = wd->rows*10;
  624. if (iflags.msg_history < 40)
  625. iflags.msg_history = 40;
  626. if (iflags.msg_history > 400)
  627. iflags.msg_history = 400;
  628. iflags.window_inited=TRUE;
  629. wd->data = (char **)alloc( iflags.msg_history*sizeof( char * ) );
  630. memset( wd->data, 0, iflags.msg_history * sizeof( char * ) );
  631. wd->maxrow = wd->maxcol = 0;
  632. /* Indicate that we have not positioned the cursor yet */
  633. wd->curx = -1;
  634. break;
  635. /* A MENU contains a list of lines in wd->data[?]. These
  636. * lines are created in amii_putstr() by reallocating the size
  637. * of wd->data to hold enough (char *)'s. wd->rows is the
  638. * number of (char *)'s allocated. wd->maxrow is the number
  639. * used. wd->maxcol is used to track how wide the menu needs
  640. * to be. wd->resp[x] contains the characters that correspond
  641. * to selecting wd->data[x]. wd->resp[x] corresponds to
  642. * wd->data[x] for any x. Elements of wd->data[?] that are not
  643. * valid selections have the corresponding element of
  644. * wd->resp[] set to a value of '\01'; i.e. a ^A which is
  645. * not currently a valid keystroke for responding to any
  646. * MENU or TEXT window.
  647. */
  648. case NHW_MENU:
  649. MenuScroll.TopEdge = HackScreen->WBorTop + scrfontysize + 1;
  650. wd->resp=(char*)alloc(256);
  651. wd->resp[0]=0;
  652. wd->rows = wd->maxrow = 0;
  653. wd->cols = wd->maxcol = 0;
  654. wd->data = NULL;
  655. break;
  656. /* See the explanation of MENU above. Except, wd->resp[] is not
  657. * used for TEXT windows since there is no selection of a
  658. * a line performed/allowed. The window is always full
  659. * screen width.
  660. */
  661. case NHW_TEXT:
  662. MenuScroll.TopEdge = HackScreen->WBorTop + scrfontysize + 1;
  663. wd->rows = wd->maxrow = 0;
  664. wd->cols = wd->maxcol = amiIDisplay->cols;
  665. wd->data = NULL;
  666. wd->morestr = NULL;
  667. break;
  668. /* The status window has only two lines. These are stored in
  669. * wd->data[], and here we allocate the space for them.
  670. */
  671. case NHW_STATUS:
  672. SetMenuStrip(w, MenuStrip);
  673. /* wd->cols is the number of characters which fit across the
  674. * screen.
  675. */
  676. wd->data=(char **)alloc(3*sizeof(char *));
  677. wd->data[0] = (char *)alloc(wd->cols + 10);
  678. wd->data[1] = (char *)alloc(wd->cols + 10);
  679. wd->data[2] = NULL;
  680. break;
  681. /* NHW_OVER does not use wd->data[] or the other text
  682. * manipulating members of the amii_WinDesc structure.
  683. */
  684. case NHW_OVER:
  685. SetMenuStrip(w, MenuStrip);
  686. break;
  687. /* NHW_MAP does not use wd->data[] or the other text
  688. * manipulating members of the amii_WinDesc structure.
  689. */
  690. case NHW_MAP:
  691. SetMenuStrip(w, MenuStrip);
  692. if( WINVERS_AMIV )
  693. {
  694. CO = (w->Width-w->BorderLeft-w->BorderRight)/mxsize;
  695. LI = (w->Height-w->BorderTop-w->BorderBottom)/mysize;
  696. amii_setclipped();
  697. SetFont( w->RPort, RogueFont);
  698. SetAPen( w->RPort, C_WHITE); /* XXX not sufficient */
  699. SetBPen( w->RPort, C_BLACK);
  700. SetDrMd( w->RPort, JAM2);
  701. }
  702. else
  703. {
  704. if( HackFont )
  705. SetFont( w->RPort, HackFont );
  706. }
  707. break;
  708. /* The base window must exist until CleanUp() deletes it. */
  709. case NHW_BASE:
  710. SetMenuStrip(w, MenuStrip);
  711. /* Make our requesters come to our screen */
  712. {
  713. register struct Process *myProcess =
  714. (struct Process *) FindTask(NULL);
  715. pr_WindowPtr = (struct Window *)(myProcess->pr_WindowPtr);
  716. myProcess->pr_WindowPtr = (APTR) w;
  717. }
  718. /* Need this for RawKeyConvert() */
  719. ConsoleIO.io_Data = (APTR) w;
  720. ConsoleIO.io_Length = sizeof( struct Window );
  721. ConsoleIO.io_Message.mn_ReplyPort = CreateMsgPort();
  722. if( OpenDevice("console.device", -1L,
  723. (struct IORequest *) &ConsoleIO, 0L) != 0)
  724. {
  725. Abort(AG_OpenDev | AO_ConsoleDev);
  726. }
  727. ConsoleDevice = (struct Library *) ConsoleIO.io_Device;
  728. KbdBuffered = 0;
  729. #ifdef HACKFONT
  730. if( TextsFont )
  731. SetFont( w->RPort, TextsFont );
  732. else if( HackFont )
  733. SetFont( w->RPort, HackFont );
  734. #endif
  735. txwidth = w->RPort->TxWidth;
  736. txheight = w->RPort->TxHeight;
  737. txbaseline = w->RPort->TxBaseline;
  738. break;
  739. default:
  740. panic("bad create_nhwindow( %d )\n",type);
  741. return WIN_ERR;
  742. }
  743. return( newid );
  744. }
  745. #ifdef __GNUC__
  746. #ifdef __PPC__
  747. int PPC_SM_Filter(void);
  748. struct EmulLibEntry SM_Filter = {TRAP_LIB, 0, (int (*)(void)) PPC_SM_Filter};
  749. int PPC_SM_Filter(void) {
  750. struct Hook *hk = (struct Hook*)REG_A0;
  751. ULONG modeID = (ULONG)REG_A1;
  752. struct ScreenModeRequester *smr = (struct ScreenModeRequester *)REG_A2;
  753. #else
  754. int SM_Filter(void) {
  755. register struct Hook *hk asm("a0");
  756. register ULONG modeID asm("a1");
  757. register struct ScreenModeRequester *smr asm("a2");
  758. #endif
  759. #else
  760. int
  761. #ifndef _DCC
  762. __interrupt
  763. #endif
  764. __saveds __asm SM_Filter(
  765. register __a0 struct Hook *hk,
  766. register __a1 ULONG modeID,
  767. register __a2 struct ScreenModeRequester *smr)
  768. {
  769. #endif
  770. struct DimensionInfo dims;
  771. struct DisplayInfo disp;
  772. DisplayInfoHandle handle;
  773. handle = FindDisplayInfo(modeID);
  774. if (handle) {
  775. GetDisplayInfoData(handle, (char *)&dims, sizeof(dims), DTAG_DIMS, modeID);
  776. GetDisplayInfoData(handle, (char *)&disp, sizeof(disp), DTAG_DISP, modeID);
  777. if (!disp.NotAvailable &&
  778. dims.MaxDepth <= 8 &&
  779. dims.StdOScan.MaxX >= WIDTH-1 &&
  780. dims.StdOScan.MaxY >= SCREENHEIGHT-1) {
  781. return 1;
  782. }
  783. }
  784. return 0;
  785. }
  786. /* Initialize the windowing environment */
  787. void
  788. amii_init_nhwindows(argcp,argv)
  789. int *argcp;
  790. char **argv;
  791. {
  792. int i;
  793. struct Screen *wbscr;
  794. int forcenobig = 0;
  795. if( HackScreen )
  796. panic( "init_nhwindows() called twice", 0 );
  797. /* run args & set bigscreen from -L(1)/-l(-1) */
  798. {
  799. int lclargc = *argcp;
  800. int t;
  801. char **argv_in = argv;
  802. char **argv_out = argv;
  803. for(t=1;t<=lclargc;t++){
  804. if(!strcmp("-L",*argv_in) || !strcmp("-l",*argv_in)){
  805. bigscreen = (*argv_in[1]=='l') ? -1 : 1;
  806. /* and eat the flag */
  807. (*argcp)--;
  808. } else {
  809. *argv_out = *argv_in; /* keep the flag */
  810. argv_out++;
  811. }
  812. argv_in++;
  813. }
  814. *argv_out = 0;
  815. }
  816. WIN_MESSAGE = WIN_ERR;
  817. WIN_MAP = WIN_ERR;
  818. WIN_STATUS = WIN_ERR;
  819. WIN_INVEN = WIN_ERR;
  820. WIN_BASE = WIN_ERR;
  821. WIN_OVER = WIN_ERR;
  822. if ( (IntuitionBase = (struct IntuitionBase *)
  823. OpenLibrary("intuition.library", amii_libvers )) == NULL)
  824. {
  825. Abort(AG_OpenLib | AO_Intuition);
  826. }
  827. if ( (GfxBase = (struct GfxBase *)
  828. OpenLibrary("graphics.library", amii_libvers )) == NULL)
  829. {
  830. Abort(AG_OpenLib | AO_GraphicsLib);
  831. }
  832. if( (LayersBase = (struct Library *)
  833. OpenLibrary("layers.library", amii_libvers )) == NULL)
  834. {
  835. Abort(AG_OpenLib | AO_LayersLib);
  836. }
  837. if ((GadToolsBase = OpenLibrary("gadtools.library", amii_libvers)) == NULL) {
  838. Abort(AG_OpenLib | AO_GadTools);
  839. }
  840. if ((AslBase = OpenLibrary("asl.library", amii_libvers)) == NULL) {
  841. Abort(AG_OpenLib);
  842. }
  843. amiIDisplay=(struct amii_DisplayDesc *)alloc(sizeof(struct amii_DisplayDesc));
  844. memset( amiIDisplay, 0, sizeof( struct amii_DisplayDesc ) );
  845. /* Use Intuition sizes for overscan screens... */
  846. amiIDisplay->xpix = 0;
  847. #ifdef INTUI_NEW_LOOK
  848. if( IntuitionBase->LibNode.lib_Version >= 37 )
  849. {
  850. if( wbscr = LockPubScreen( "Workbench" ) )
  851. {
  852. amiIDisplay->xpix = wbscr->Width;
  853. amiIDisplay->ypix = wbscr->Height;
  854. UnlockPubScreen( NULL, wbscr );
  855. }
  856. }
  857. #endif
  858. if( amiIDisplay->xpix == 0 )
  859. {
  860. amiIDisplay->ypix = GfxBase->NormalDisplayRows;
  861. amiIDisplay->xpix = GfxBase->NormalDisplayColumns;
  862. }
  863. amiIDisplay->cols = amiIDisplay->xpix / FONTWIDTH;
  864. amiIDisplay->toplin=0;
  865. amiIDisplay->rawprint=0;
  866. amiIDisplay->lastwin=0;
  867. if( bigscreen == 0 )
  868. {
  869. if( ( GfxBase->ActiView->ViewPort->Modes & LACE ) == LACE )
  870. {
  871. amiIDisplay->ypix *= 2;
  872. NewHackScreen.ViewModes |= LACE;
  873. bigscreen = 1;
  874. }
  875. else if( GfxBase->NormalDisplayRows >= 300 ||
  876. amiIDisplay->ypix >= 300 )
  877. {
  878. bigscreen = 1;
  879. }
  880. }
  881. else if( bigscreen == -1 )
  882. {
  883. bigscreen = 0;
  884. forcenobig = 1;
  885. }
  886. else if( bigscreen )
  887. {
  888. /* If bigscreen requested and we don't have enough rows in
  889. * noninterlaced mode, switch to interlaced...
  890. */
  891. if( GfxBase->NormalDisplayRows < 300 )
  892. {
  893. amiIDisplay->ypix *= 2;
  894. NewHackScreen.ViewModes |= LACE;
  895. }
  896. }
  897. if( !bigscreen )
  898. {
  899. alwaysinvent = 0;
  900. }
  901. amiIDisplay->rows = amiIDisplay->ypix / FONTHEIGHT;
  902. #ifdef HACKFONT
  903. /*
  904. * Load the fonts that we need.
  905. */
  906. if( DiskfontBase =
  907. OpenLibrary( "diskfont.library", amii_libvers ) )
  908. {
  909. Hack80.ta_Name -= SIZEOF_DISKNAME;
  910. HackFont = OpenDiskFont( &Hack80 );
  911. Hack80.ta_Name += SIZEOF_DISKNAME;
  912. /* Textsfont13 is filled in with "FONT=" settings. The default is
  913. * courier/13.
  914. */
  915. TextsFont = NULL;
  916. if( bigscreen )
  917. TextsFont = OpenDiskFont( &TextsFont13 );
  918. /* Try hack/8 for texts if no user specified font */
  919. if( TextsFont == NULL )
  920. {
  921. Hack80.ta_Name -= SIZEOF_DISKNAME;
  922. TextsFont = OpenDiskFont( &Hack80 );
  923. Hack80.ta_Name += SIZEOF_DISKNAME;
  924. }
  925. /* If no fonts, make everything topaz 8 for non-view windows.
  926. */
  927. Hack80.ta_Name = "topaz.font";
  928. RogueFont = OpenFont( &Hack80 );
  929. if(!RogueFont) panic("Can't get topaz:8");
  930. if( !HackFont || !TextsFont )
  931. {
  932. if( !HackFont )
  933. {
  934. HackFont = OpenFont( &Hack80 );
  935. if( !HackFont )
  936. panic( "Can't get a map font, topaz:8" );
  937. }
  938. if( !TextsFont )
  939. {
  940. TextsFont = OpenFont( &Hack80 );
  941. if( !TextsFont )
  942. panic( "Can't open text font" );
  943. }
  944. }
  945. CloseLibrary(DiskfontBase);
  946. DiskfontBase = NULL;
  947. }
  948. #endif
  949. /* Adjust getlin window size to font */
  950. if (TextsFont) {
  951. extern SHORT BorderVectors1[];
  952. extern SHORT BorderVectors2[];
  953. extern struct Gadget Gadget2;
  954. extern struct Gadget String;
  955. extern struct NewWindow StrWindow;
  956. BorderVectors1[2] += (TextsFont->tf_XSize-8)*6; /* strlen("Cancel") == 6 */
  957. BorderVectors1[4] += (TextsFont->tf_XSize-8)*6;
  958. BorderVectors1[5] += TextsFont->tf_YSize-8;
  959. BorderVectors1[7] += TextsFont->tf_YSize-8;
  960. BorderVectors2[2] += (TextsFont->tf_XSize-8)*6;
  961. BorderVectors2[4] += (TextsFont->tf_XSize-8)*6;
  962. BorderVectors2[5] += TextsFont->tf_YSize-8;
  963. BorderVectors2[7] += TextsFont->tf_YSize-8;
  964. Gadget2.TopEdge += TextsFont->tf_YSize-8;
  965. Gadget2.Width += (TextsFont->tf_XSize-8)*6;
  966. Gadget2.Height += TextsFont->tf_YSize-8;
  967. String.LeftEdge += (TextsFont->tf_XSize-8)*6;
  968. String.TopEdge += TextsFont->tf_YSize-8;
  969. String.Width += TextsFont->tf_XSize-8;
  970. String.Height += TextsFont->tf_YSize-8;
  971. StrWindow.Width += (TextsFont->tf_XSize-8)*7;
  972. StrWindow.Height += (TextsFont->tf_YSize-8)*2; /* Titlebar + 1 row of gadgets */
  973. }
  974. /* This is the size screen we want to open, within reason... */
  975. NewHackScreen.Width = max( WIDTH, amiIDisplay->xpix );
  976. NewHackScreen.Height = max( SCREENHEIGHT, amiIDisplay->ypix );
  977. {
  978. static char fname[18];
  979. sprintf(fname,"NetHack %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
  980. NewHackScreen.DefaultTitle=fname;
  981. }
  982. #if 0
  983. NewHackScreen.BlockPen = C_BLACK;
  984. NewHackScreen.DetailPen = C_WHITE;
  985. #endif
  986. #ifdef INTUI_NEW_LOOK
  987. if( IntuitionBase->LibNode.lib_Version >= 37 )
  988. {
  989. int i;
  990. struct DimensionInfo dims;
  991. DisplayInfoHandle handle;
  992. struct DisplayInfo disp;
  993. ULONG modeid = DEFAULT_MONITOR_ID|HIRES_KEY;
  994. NewHackScreen.Width = STDSCREENWIDTH;
  995. NewHackScreen.Height = STDSCREENHEIGHT;
  996. #ifdef HACKFONT
  997. if (TextsFont) {
  998. NewHackScreen.Font = &TextsFont13;
  999. }
  1000. #endif
  1001. if ( amii_scrnmode == 0xffffffff ) {
  1002. struct ScreenModeRequester *SMR;
  1003. #ifdef __GNUC__
  1004. SM_FilterHook.h_Entry = (void *)&SM_Filter;
  1005. #else
  1006. SM_FilterHook.h_Entry = (ULONG(*)())SM_Filter;
  1007. #endif
  1008. SM_FilterHook.h_Data = 0;
  1009. SM_FilterHook.h_SubEntry = 0;
  1010. SMR = AllocAslRequest(ASL_ScreenModeRequest,NULL);
  1011. if (AslRequestTags(SMR,
  1012. ASLSM_FilterFunc, (ULONG)&SM_FilterHook,
  1013. TAG_END))
  1014. amii_scrnmode = SMR->sm_DisplayID;
  1015. else
  1016. amii_scrnmode = 0;
  1017. FreeAslRequest(SMR);
  1018. }
  1019. if( forcenobig == 0 )
  1020. {
  1021. if( ( wbscr = LockPubScreen( "Workbench" ) ) != NULL ||
  1022. ( wbscr = LockPubScreen( NULL ) ) != NULL )
  1023. {
  1024. /* Get the default pub screen's size */
  1025. modeid = GetVPModeID( &wbscr->ViewPort );
  1026. if( modeid == INVALID_ID ||
  1027. ModeNotAvailable( modeid ) ||
  1028. ( handle = FindDisplayInfo( modeid ) ) == NULL ||
  1029. GetDisplayInfoData( handle, (char *)&dims, sizeof( dims ),
  1030. DTAG_DIMS, modeid ) <= 0 ||
  1031. GetDisplayInfoData( handle, (char *)&disp, sizeof( disp ),
  1032. DTAG_DISP, modeid ) <= 0 )
  1033. {
  1034. modeid = DEFAULT_MONITOR_ID|HIRES_KEY;
  1035. /* If the display database seems to not work, use the screen
  1036. * dimensions
  1037. */
  1038. NewHackScreen.Height = wbscr->Height;
  1039. NewHackScreen.Width = wbscr->Width;
  1040. /*
  1041. * Request LACE if it looks laced. For 2.1/3.0, we will get
  1042. * promoted to the users choice of modes (if promotion is allowed)
  1043. * If the user is using a dragable screen, things will get hosed
  1044. * but that is life...
  1045. */
  1046. if( wbscr->ViewPort.Modes & LACE )
  1047. NewHackScreen.ViewModes |= LACE;
  1048. modeid = -1;
  1049. }
  1050. else
  1051. {
  1052. /* Use the display database to get the correct information */
  1053. if( disp.PropertyFlags & DIPF_IS_LACE )
  1054. NewHackScreen.ViewModes |= LACE;
  1055. NewHackScreen.Height = dims.StdOScan.MaxY+1;
  1056. NewHackScreen.Width = dims.StdOScan.MaxX+1;
  1057. }
  1058. NewHackScreen.TopEdge = 0;
  1059. NewHackScreen.LeftEdge = 0;
  1060. UnlockPubScreen( NULL, wbscr );
  1061. }
  1062. }
  1063. for( i = 0; scrntags[i].ti_Tag != TAG_DONE; ++i )
  1064. {
  1065. switch( scrntags[i].ti_Tag )
  1066. {
  1067. case SA_DisplayID:
  1068. if( !amii_scrnmode || ModeNotAvailable( amii_scrnmode ) )
  1069. {
  1070. if( ModeNotAvailable( modeid ) )
  1071. {
  1072. scrntags[i].ti_Tag = TAG_IGNORE;
  1073. break;
  1074. }
  1075. else
  1076. scrntags[i].ti_Data = (long)modeid;
  1077. }
  1078. else
  1079. modeid = scrntags[i].ti_Data = (long)amii_scrnmode;
  1080. if( ( handle = FindDisplayInfo( modeid ) ) != NULL &&
  1081. GetDisplayInfoData( handle, (char *)&dims, sizeof( dims ),
  1082. DTAG_DIMS, modeid ) > 0 &&
  1083. GetDisplayInfoData( handle, (char *)&disp, sizeof( disp ),
  1084. DTAG_DISP, modeid ) > 0 )
  1085. {
  1086. if( disp.PropertyFlags & DIPF_IS_LACE )
  1087. NewHackScreen.ViewModes |= LACE;
  1088. NewHackScreen.Height = dims.StdOScan.MaxY+1;
  1089. NewHackScreen.Width = dims.StdOScan.MaxX+1;
  1090. }
  1091. break;
  1092. case SA_Pens:
  1093. scrntags[i].ti_Data = (long)flags.amii_dripens;
  1094. break;
  1095. }
  1096. }
  1097. }
  1098. #endif
  1099. if( WINVERS_AMIV )
  1100. amii_bmhd = ReadTileImageFiles( );
  1101. else
  1102. memcpy( amii_initmap, amii_init_map, sizeof( amii_initmap ) );
  1103. memcpy(flags.amii_curmap,amii_initmap,sizeof(flags.amii_curmap));
  1104. /* Find out how deep the screen needs to be, 32 planes is enough! */
  1105. for( i = 0; i < 32; ++i )
  1106. {
  1107. if( ( 1L << i ) >= amii_numcolors )
  1108. break;
  1109. }
  1110. NewHackScreen.Depth = i;
  1111. /* If for some reason Height/Width became smaller than the required,
  1112. have the required one */
  1113. if (NewHackScreen.Height < SCREENHEIGHT)
  1114. NewHackScreen.Height = SCREENHEIGHT;
  1115. if (NewHackScreen.Width < WIDTH)
  1116. NewHackScreen.Width = WIDTH;
  1117. #ifdef HACKFONT
  1118. i = max(TextsFont->tf_XSize, HackFont->tf_XSize);
  1119. if (NewHackScreen.Width < 80*i+4)
  1120. NewHackScreen.Width = 80*i+4;
  1121. #endif
  1122. /* While openscreen fails try fewer colors to see if that is the problem. */
  1123. while( ( HackScreen = OpenScreen( (void *)&NewHackScreen ) ) == NULL )
  1124. {
  1125. #ifdef TEXTCOLOR
  1126. if( --NewHackScreen.Depth < 3 )
  1127. #else
  1128. if( --NewHackScreen.Depth < 2 )
  1129. #endif
  1130. Abort( AN_OpenScreen & ~AT_DeadEnd );
  1131. }
  1132. amii_numcolors = 1L << NewHackScreen.Depth;
  1133. if( HackScreen->Height > 300 && forcenobig == 0 )
  1134. bigscreen = 1;
  1135. else
  1136. bigscreen = 0;
  1137. #ifdef INTUI_NEW_LOOK
  1138. if( IntuitionBase->LibNode.lib_Version >= 37 )
  1139. PubScreenStatus( HackScreen, 0 );
  1140. #endif
  1141. amiIDisplay->ypix = HackScreen->Height;
  1142. amiIDisplay->xpix = HackScreen->Width;
  1143. LoadRGB4(&HackScreen->ViewPort, flags.amii_curmap, amii_numcolors );
  1144. VisualInfo = GetVisualInfo(HackScreen, TAG_END);
  1145. MenuStrip = CreateMenus(GTHackMenu, TAG_END);
  1146. LayoutMenus(MenuStrip, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_END);
  1147. /* Display the copyright etc... */
  1148. if( WIN_BASE == WIN_ERR )
  1149. WIN_BASE = amii_create_nhwindow( NHW_BASE );
  1150. amii_clear_nhwindow( WIN_BASE );
  1151. amii_putstr( WIN_BASE, 0, "" );
  1152. amii_putstr( WIN_BASE, 0, "" );
  1153. amii_putstr( WIN_BASE, 0, "" );
  1154. amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_A);
  1155. amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_B);
  1156. amii_putstr( WIN_BASE, 0, COPYRIGHT_BANNER_C);
  1157. amii_putstr( WIN_BASE, 0, "");
  1158. Initialized = 1;
  1159. }
  1160. void
  1161. amii_sethipens( struct Window *w, int type, int attr )
  1162. {
  1163. switch( type )
  1164. {
  1165. default:
  1166. SetAPen( w->RPort, attr ? C_RED : amii_otherAPen );
  1167. SetBPen( w->RPort, C_BLACK );
  1168. break;
  1169. case NHW_STATUS:
  1170. SetAPen( w->RPort, attr ? C_WHITE : amii_statAPen );
  1171. SetBPen( w->RPort, amii_statBPen );
  1172. break;
  1173. case NHW_MESSAGE:
  1174. SetAPen( w->RPort, attr ? C_WHITE : amii_msgAPen );
  1175. SetBPen( w->RPort, amii_msgBPen );
  1176. break;
  1177. case NHW_MENU:
  1178. SetAPen( w->RPort, attr ? C_BLACK : amii_menuAPen );
  1179. SetBPen( w->RPort, amii_menuBPen );
  1180. break;
  1181. case NHW_TEXT:
  1182. SetAPen( w->RPort, attr ? C_BLACK : amii_textAPen );
  1183. SetBPen( w->RPort, amii_textBPen );
  1184. case -2:
  1185. SetBPen( w->RPort, amii_otherBPen );
  1186. SetAPen( w->RPort, attr ? C_RED : amii_otherAPen );
  1187. break;
  1188. }
  1189. }
  1190. void
  1191. amii_setfillpens( struct Window *w, int type )
  1192. {
  1193. switch( type )
  1194. {
  1195. case NHW_MESSAGE:
  1196. SetAPen( w->RPort, amii_msgBPen );
  1197. SetBPen( w->RPort, amii_msgBPen );
  1198. break;
  1199. case NHW_STATUS:
  1200. SetAPen( w->RPort, amii_statBPen );
  1201. SetBPen( w->RPort, amii_statBPen );
  1202. break;
  1203. case NHW_MENU:
  1204. SetAPen( w->RPort, amii_menuBPen );
  1205. SetBPen( w->RPort, amii_menuBPen );
  1206. break;
  1207. case NHW_TEXT:
  1208. SetAPen( w->RPort, amii_textBPen );
  1209. SetBPen( w->RPort, amii_textBPen );
  1210. break;
  1211. case NHW_MAP:
  1212. case NHW_BASE:
  1213. case NHW_OVER:
  1214. default:
  1215. SetAPen( w->RPort, C_BLACK );
  1216. SetBPen( w->RPort, C_BLACK );
  1217. break;
  1218. case -2:
  1219. SetAPen( w->RPort, amii_otherBPen );
  1220. SetBPen( w->RPort, amii_otherBPen );
  1221. break;
  1222. }
  1223. }
  1224. void
  1225. amii_setdrawpens( struct Window *w, int type )
  1226. {
  1227. switch( type )
  1228. {
  1229. case NHW_MESSAGE:
  1230. SetAPen( w->RPort, amii_msgAPen );
  1231. SetBPen( w->RPort, amii_msgBPen );
  1232. break;
  1233. case NHW_STATUS:
  1234. SetAPen( w->RPort, amii_statAPen );
  1235. SetBPen( w->RPort, amii_statBPen );
  1236. break;
  1237. case NHW_MENU:
  1238. SetAPen( w->RPort, amii_menuAPen );
  1239. SetBPen( w->RPort, amii_menuBPen );
  1240. break;
  1241. case NHW_TEXT:
  1242. SetAPen( w->RPort, amii_textAPen );
  1243. SetBPen( w->RPort, amii_textBPen );
  1244. break;
  1245. case NHW_MAP:
  1246. case NHW_BASE:
  1247. case NHW_OVER:
  1248. SetAPen( w->RPort, C_WHITE );
  1249. SetBPen( w->RPort, C_BLACK );
  1250. break;
  1251. default:
  1252. SetAPen( w->RPort, amii_otherAPen );
  1253. SetBPen( w->RPort, amii_otherBPen );
  1254. break;
  1255. }
  1256. }
  1257. /* Clear the indicated window */
  1258. void
  1259. amii_clear_nhwindow(win)
  1260. register winid win;
  1261. {
  1262. register struct amii_WinDesc *cw;
  1263. register struct Window *w;
  1264. if( reclip == 2 ) return;
  1265. if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  1266. panic( winpanicstr, win, "clear_nhwindow" );
  1267. /* Clear the overview window too if it is displayed */
  1268. if( WINVERS_AMIV && ( cw->type == WIN_MAP && WIN_OVER != WIN_ERR && reclip == 0 ) )
  1269. {
  1270. amii_clear_nhwindow( WIN_OVER );
  1271. }
  1272. if( w = cw->win )
  1273. SetDrMd( w->RPort, JAM2);
  1274. else
  1275. return;
  1276. if( (cw->wflags & FLMAP_CURSUP ) )
  1277. {
  1278. if( cw->type != NHW_MAP )
  1279. cursor_off( win );
  1280. else
  1281. cw->wflags &= ~FLMAP_CURSUP;
  1282. }
  1283. amii_setfillpens( w, cw->type );
  1284. SetDrMd( w->RPort, JAM2 );
  1285. if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  1286. {
  1287. RectFill( w->RPort, w->BorderLeft, w->BorderTop,
  1288. w->Width - w->BorderRight-1,
  1289. w->Height - w->BorderBottom-1 );
  1290. }
  1291. else
  1292. {
  1293. if( cw->type == NHW_MESSAGE )
  1294. {
  1295. amii_curs( win, 1, 0 );
  1296. if( !scrollmsg )
  1297. TextSpaces( w->RPort, cw->cols );
  1298. }
  1299. else
  1300. {
  1301. RectFill( w->RPort, w->BorderLeft, w->BorderTop,
  1302. w->Width - w->BorderRight-1,
  1303. w->Height - w->BorderBottom-1 );
  1304. }
  1305. }
  1306. cw->cury = 0;
  1307. cw->curx = 0;
  1308. amii_curs( win, 1, 0 );
  1309. }
  1310. /* Dismiss the window from the screen */
  1311. void
  1312. dismiss_nhwindow(win)
  1313. register winid win;
  1314. {
  1315. register struct Window *w;
  1316. register struct amii_WinDesc *cw;
  1317. if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  1318. {
  1319. panic(winpanicstr,win, "dismiss_nhwindow");
  1320. }
  1321. w = cw->win;
  1322. if( w )
  1323. {
  1324. /* All windows have this stuff attached to them. */
  1325. if( cw->type == NHW_MAP ||
  1326. cw->type == NHW_OVER ||
  1327. cw->type == NHW_BASE ||
  1328. cw->type == NHW_MESSAGE ||
  1329. cw->type == NHW_STATUS )
  1330. {
  1331. ClearMenuStrip( w );
  1332. }
  1333. /* Save where user like inventory to appear */
  1334. if( win == WIN_INVEN )
  1335. {
  1336. lastinvent.MinX = w->LeftEdge;
  1337. lastinvent.MinY = w->TopEdge;
  1338. lastinvent.MaxX = w->Width;
  1339. lastinvent.MaxY = w->Height;
  1340. }
  1341. /* Close the window */
  1342. CloseShWindow( w );
  1343. cw->win = NULL;
  1344. /* Free copy of NewWindow structure for TEXT/MENU windows. */
  1345. if( cw->newwin )
  1346. FreeNewWindow( (void *)cw->newwin );
  1347. cw->newwin = NULL;
  1348. }
  1349. }
  1350. void
  1351. amii_exit_nhwindows(str)
  1352. const char *str;
  1353. {
  1354. /* Seems strange to have to do this... but we need the BASE window
  1355. * left behind...
  1356. */
  1357. kill_nhwindows( 0 );
  1358. if( WINVERS_AMIV )
  1359. FreeTileImageFiles( );
  1360. if( str )
  1361. {
  1362. raw_print( "" ); /* be sure we're not under the top margin */
  1363. raw_print( str );
  1364. }
  1365. }
  1366. void
  1367. amii_display_nhwindow(win,blocking)
  1368. winid win;
  1369. boolean blocking;
  1370. {
  1371. menu_item *mip;
  1372. int cnt;
  1373. static int lastwin = -1;
  1374. struct amii_WinDesc *cw;
  1375. if( !Initialized )
  1376. return;
  1377. lastwin = win;
  1378. if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  1379. panic(winpanicstr,win,"display_nhwindow");
  1380. if( cw->type == NHW_MESSAGE )
  1381. cw->wflags &= ~FLMAP_SKIP;
  1382. if( cw->type == NHW_MESSAGE || cw->type == NHW_STATUS )
  1383. return;
  1384. if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  1385. {
  1386. flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
  1387. }
  1388. if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  1389. {
  1390. cnt = DoMenuScroll( win, blocking, PICK_ONE, &mip );
  1391. }
  1392. else if( cw->type==NHW_MAP )
  1393. {
  1394. amii_end_glyphout( win );
  1395. /* Do more if it is time... */
  1396. if( blocking == TRUE && amii_wins[ WIN_MESSAGE ]->curx )
  1397. {
  1398. outmore( amii_wins[ WIN_MESSAGE ] );
  1399. }
  1400. }
  1401. }
  1402. void
  1403. amii_curs(window, x, y)
  1404. winid window;
  1405. register int x, y; /* not xchar: perhaps xchar is unsigned and
  1406. curx-x would be unsigned as well */
  1407. {
  1408. register struct amii_WinDesc *cw;
  1409. register struct Window *w;
  1410. register struct RastPort *rp;
  1411. if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  1412. panic(winpanicstr, window, "curs");
  1413. if( (w = cw->win) == NULL )
  1414. {
  1415. if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  1416. return;
  1417. else
  1418. panic( "No window open yet in curs() for winid %d\n", window );
  1419. }
  1420. amiIDisplay->lastwin = window;
  1421. /* Make sure x is within bounds */
  1422. if( x > 0 )
  1423. --x; /* column 0 is never used */
  1424. else
  1425. x = 0;
  1426. cw->curx = x;
  1427. cw->cury = y;
  1428. #ifdef DEBUG
  1429. if( x<0 || y<0 || y >= cw->rows || x >= cw->cols )
  1430. {
  1431. char *s = "[unknown type]";
  1432. switch(cw->type)
  1433. {
  1434. case NHW_MESSAGE: s = "[topl window]"; break;
  1435. case NHW_STATUS: s = "[status window]"; break;
  1436. case NHW_MAP: s = "[map window]"; break;
  1437. case NHW_MENU: s = "[menu window]"; break;
  1438. case NHW_TEXT: s = "[text window]"; break;
  1439. case NHW_BASE: s = "[base window]"; break;
  1440. case NHW_OVER: s = "[overview window]"; break;
  1441. }
  1442. impossible("bad curs positioning win %d %s (%d,%d)", window, s, x, y);
  1443. return;
  1444. }
  1445. #endif
  1446. #ifdef CLIPPING
  1447. if(clipping && cw->type == NHW_MAP)
  1448. {
  1449. x -= clipx;
  1450. y -= clipy;
  1451. }
  1452. #endif
  1453. /* Output all saved output before doing cursor movements for MAP */
  1454. if( cw->type == NHW_MAP )
  1455. {
  1456. flush_glyph_buffer( w );
  1457. }
  1458. /* Actually do it */
  1459. rp = w->RPort;
  1460. if( cw->type == NHW_MENU )
  1461. {
  1462. if( WINVERS_AMIV )
  1463. {
  1464. if( window == WIN_INVEN )
  1465. {
  1466. Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1 + pictdata.xsize + 4,
  1467. (y * max(rp->TxHeight,pictdata.ysize + 3) ) +
  1468. rp->TxBaseline + pictdata.ysize - rp->TxHeight + w->BorderTop + 4 );
  1469. }
  1470. else
  1471. {
  1472. Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
  1473. (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1 );
  1474. }
  1475. }
  1476. else
  1477. {
  1478. Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
  1479. (y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
  1480. }
  1481. }
  1482. else if( cw->type == NHW_TEXT )
  1483. {
  1484. Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
  1485. (y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
  1486. }
  1487. else if( cw->type == NHW_MAP || cw->type == NHW_BASE )
  1488. {
  1489. /* These coordinate calculations must be synced with those
  1490. * in flush_glyph_buffer() in winchar.c. curs_on_u() will
  1491. * use this code, all other drawing occurs through the glyph
  1492. * code. In order for the cursor to appear on top of the hero,
  1493. * the code must compute X,Y in the same manner relative to
  1494. * the RastPort coordinates.
  1495. *
  1496. * y = w->BorderTop + (g_nodes[i].y-2) * rp->TxHeight +
  1497. * rp->TxBaseline + 1;
  1498. * x = g_nodes[i].x * rp->TxWidth + w->BorderLeft;
  1499. */
  1500. if( WINVERS_AMIV )
  1501. {
  1502. if( cw->type == NHW_MAP )
  1503. {
  1504. if(Is_rogue_level(&u.uz)){
  1505. #if 0
  1506. int qqx= (x * w->RPort->TxWidth) + w->BorderLeft;
  1507. int qqy= w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1;
  1508. printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy);
  1509. #endif
  1510. SetAPen(w->RPort,C_WHITE); /* XXX should be elsewhere (was 4)*/
  1511. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
  1512. w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1 );
  1513. } else {
  1514. Move( rp, (x * mxsize) + w->BorderLeft,
  1515. w->BorderTop + ( (y+1) * mysize ) + 1 );
  1516. }
  1517. }
  1518. else
  1519. {
  1520. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
  1521. w->BorderTop + ( (y + 1) * w->RPort->TxHeight ) +
  1522. w->RPort->TxBaseline + 1 );
  1523. }
  1524. }
  1525. else
  1526. {
  1527. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
  1528. w->BorderTop + ( y * w->RPort->TxHeight ) +
  1529. w->RPort->TxBaseline + 1 );
  1530. }
  1531. }
  1532. else if( WINVERS_AMIV && cw->type == NHW_OVER )
  1533. {
  1534. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1535. w->BorderTop + w->RPort->TxBaseline + 3 );
  1536. }
  1537. else if( cw->type == NHW_MESSAGE && !scrollmsg )
  1538. {
  1539. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1540. w->BorderTop + w->RPort->TxBaseline + 3 );
  1541. }
  1542. else if( cw->type == NHW_STATUS )
  1543. {
  1544. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1545. (y*(w->RPort->TxHeight+1)) + w->BorderTop +
  1546. w->RPort->TxBaseline + 1 );
  1547. }
  1548. else
  1549. {
  1550. Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1551. (y*w->RPort->TxHeight) + w->BorderTop +
  1552. w->RPort->TxBaseline + 1 );
  1553. }
  1554. }
  1555. void
  1556. amii_set_text_font( name, size )
  1557. char *name;
  1558. int size;
  1559. {
  1560. register int i;
  1561. register struct amii_WinDesc *cw;
  1562. int osize = TextsFont13.ta_YSize;
  1563. static char nname[ 100 ];
  1564. strncpy( nname, name, sizeof( nname ) - 1 );
  1565. nname[ sizeof( nname ) - 1 ] = 0;
  1566. TextsFont13.ta_Name = nname;
  1567. TextsFont13.ta_YSize = size;
  1568. /* No alternate text font allowed for 640x269 or smaller */
  1569. if( !HackScreen || !bigscreen )
  1570. return;
  1571. /* Look for windows to set, and change them */
  1572. if( DiskfontBase =
  1573. OpenLibrary( "diskfont.library", amii_libvers ) )
  1574. {
  1575. TextsFont = OpenDiskFont( &TextsFont13 );
  1576. for( i = 0; TextsFont && i < MAXWIN; ++i )
  1577. {
  1578. if( (cw = amii_wins[ i ]) && cw->win != NULL )
  1579. {
  1580. switch( cw->type )
  1581. {
  1582. case NHW_STATUS:
  1583. MoveWindow( cw->win, 0, -( size - osize ) * 2 );
  1584. SizeWindow( cw->win, 0, ( size - osize ) * 2 );
  1585. SetFont( cw->win->RPort, TextsFont );
  1586. break;
  1587. case NHW_MESSAGE:
  1588. case NHW_MAP:
  1589. case NHW_BASE:
  1590. case NHW_OVER:
  1591. SetFont( cw->win->RPort, TextsFont );
  1592. break;
  1593. }
  1594. }
  1595. }
  1596. }
  1597. CloseLibrary(DiskfontBase);
  1598. DiskfontBase = NULL;
  1599. }
  1600. void
  1601. kill_nhwindows( all )
  1602. register int all;
  1603. {
  1604. register int i;
  1605. register struct amii_WinDesc *cw;
  1606. /* Foreach open window in all of amii_wins[], CloseShWindow, free memory */
  1607. for( i = 0; i < MAXWIN; ++i )
  1608. {
  1609. if( (cw = amii_wins[ i ]) && (cw->type != NHW_BASE || all) )
  1610. {
  1611. amii_destroy_nhwindow( i );
  1612. }
  1613. }
  1614. }
  1615. void
  1616. amii_cl_end( cw, curs_pos )
  1617. register struct amii_WinDesc *cw;
  1618. register int curs_pos;
  1619. {
  1620. register struct Window *w = cw->win;
  1621. register int oy, ox;
  1622. if( !w )
  1623. panic("NULL window pointer in amii_cl_end()");
  1624. oy = w->RPort->cp_y;
  1625. ox = w->RPort->cp_x;
  1626. TextSpaces( w->RPort, cw->cols - curs_pos );
  1627. Move( w->RPort, ox, oy );
  1628. }
  1629. void
  1630. cursor_off( window )
  1631. winid window;
  1632. {
  1633. register struct amii_WinDesc *cw;
  1634. register struct Window *w;
  1635. register struct RastPort *rp;
  1636. int curx, cury;
  1637. int x, y;
  1638. long dmode;
  1639. short apen, bpen;
  1640. unsigned char ch;
  1641. if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  1642. {
  1643. iflags.window_inited=0;
  1644. panic(winpanicstr,window, "cursor_off");
  1645. }
  1646. if( !(cw->wflags & FLMAP_CURSUP ) )
  1647. return;
  1648. w = cw->win;
  1649. if( !w )
  1650. return;
  1651. cw->wflags &= ~FLMAP_CURSUP;
  1652. rp = w->RPort;
  1653. /* Save the current information */
  1654. curx = rp->cp_x;
  1655. cury = rp->cp_y;
  1656. x = cw->cursx;
  1657. y = cw->cursy;
  1658. dmode = rp->DrawMode;
  1659. apen = rp->FgPen;
  1660. bpen = rp->BgPen;
  1661. SetAPen( rp, cw->curs_apen );
  1662. SetBPen( rp, cw->curs_bpen );
  1663. SetDrMd( rp, COMPLEMENT );
  1664. /*printf("CURSOR OFF: %d %d\n",x,y);*/
  1665. if( WINVERS_AMIV && cw->type == NHW_MAP)
  1666. {
  1667. cursor_common(rp, x, y);
  1668. if(Is_rogue_level(&u.uz))
  1669. Move(rp,curx,cury);
  1670. }
  1671. else
  1672. {
  1673. ch = CURSOR_CHAR;
  1674. Move( rp, x, y );
  1675. Text( rp, &ch, 1 );
  1676. /* Put back the other stuff */
  1677. Move( rp, curx, cury );
  1678. }
  1679. SetDrMd( rp, dmode );
  1680. SetAPen( rp, apen );
  1681. SetBPen( rp, bpen );
  1682. }
  1683. void
  1684. cursor_on( window )
  1685. winid window;
  1686. {
  1687. int x, y;
  1688. register struct amii_WinDesc *cw;
  1689. register struct Window *w;
  1690. register struct RastPort *rp;
  1691. unsigned char ch;
  1692. long dmode;
  1693. short apen, bpen;
  1694. if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  1695. {
  1696. /* tty does this differently - is this OK? */
  1697. iflags.window_inited=0;
  1698. panic(winpanicstr,window, "cursor_on");
  1699. }
  1700. /*printf("CURSOR ON: %d %d\n",cw->win->RPort->cp_x, cw->win->RPort->cp_y);*/
  1701. if( (cw->wflags & FLMAP_CURSUP ) )
  1702. cursor_off( window );
  1703. w = cw->win;
  1704. if( !w )
  1705. return;
  1706. cw->wflags |= FLMAP_CURSUP;
  1707. rp = w->RPort;
  1708. /* Save the current information */
  1709. #ifdef DISPMAP
  1710. if( WINVERS_AMIV && cw->type == NHW_MAP && !Is_rogue_level(&u.uz))
  1711. x = cw->cursx = (rp->cp_x & -8) + 8;
  1712. else
  1713. #endif
  1714. x = cw->cursx = rp->cp_x;
  1715. y = cw->cursy = rp->cp_y;
  1716. apen = rp->FgPen;
  1717. bpen = rp->BgPen;
  1718. dmode = rp->DrawMode;
  1719. /* Draw in complement mode. The cursor body will be C_WHITE */
  1720. cw->curs_apen = 0xff; /* Last color/all planes, regardless of depth */
  1721. cw->curs_bpen = 0xff;
  1722. SetAPen( rp, cw->curs_apen );
  1723. SetBPen( rp, cw->curs_bpen );
  1724. SetDrMd( rp, COMPLEMENT );
  1725. if( WINVERS_AMIV && cw->type == NHW_MAP)
  1726. {
  1727. cursor_common(rp, x, y);
  1728. }
  1729. else
  1730. {
  1731. Move( rp, x, y );
  1732. ch = CURSOR_CHAR;
  1733. Text( rp, &ch, 1 );
  1734. Move( rp, x, y );
  1735. }
  1736. SetDrMd( rp, dmode );
  1737. SetAPen( rp, apen );
  1738. SetBPen( rp, bpen );
  1739. }
  1740. static void
  1741. cursor_common(rp, x, y)
  1742. struct RastPort *rp;
  1743. int x,y;
  1744. {
  1745. int x1,x2,y1,y2;
  1746. if(Is_rogue_level(&u.uz)){
  1747. x1 = x-2; y1 = y-rp->TxHeight;
  1748. x2 = x+rp->TxWidth+1; y2 = y+3;
  1749. /*printf("COMM: (%d %d) (%d %d) (%d %d) (%d %d)\n",x1,y1,x2,y2,x1+2,y1+2,x2-2,y2-2);*/
  1750. } else {
  1751. x1 = x; y1 = y-mysize-1;
  1752. x2 = x+mxsize-1; y2 = y-2;
  1753. RectFill(rp, x1, y1, x2, y2);
  1754. }
  1755. RectFill(rp, x1+2, y1+2, x2-2, y2-2);