1 /* aNetHack 0.0.1 winchar.c $ANH-Date: 1432512795 2015/05/25 00:13:15 $ $ANH-Branch: master $:$ANH-Revision: 1.8 $ */
2 /* Copyright (c) Olaf Seibert (KosmoSoft), 1989, 1992 */
3 /* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993 */
4 /* Copyright (c) Gregg Wonderly, Naperville Illinois, 1994. */
5 /* aNetHack may be freely redistributed. See license for details. */
7 #include <exec/types.h>
8 #include <libraries/iffparse.h>
9 #include <graphics/scale.h>
11 #include <proto/iffparse.h>
17 #include "NH:src/tile.c"
20 #include "NH:win/share/tile.h"
22 #include "NH:sys/amiga/windefs.h"
23 #include "NH:sys/amiga/winext.h"
24 #include "NH:sys/amiga/winproto.h"
27 #define DISPMAP /* use display_map() from dispmap.s */
30 /* NH:sys/amiga/winvchar.c */
31 int main(int, char **);
32 struct BitMap
*MyAllocBitMap(int, int, int, long);
33 void MyFreeBitMap(struct BitMap
*);
34 void FreeImageFiles(char **, struct BitMap
**);
35 void amiv_flush_glyph_buffer(struct Window
*);
36 void amiv_lprint_glyph(winid
, int, int);
37 void amii_lprint_glyph(winid
, int, int);
38 void amiv_start_glyphout(winid
);
39 void amii_end_glyphout(winid
);
40 void SetMazeType(MazeType
);
42 void amii_start_glyphout(winid
);
43 void amii_end_glyphout(winid
);
44 void amii_flush_glyph_buffer(struct Window
*);
46 int amii_extraplanes
= 0;
49 struct BitMap
*MyAllocBitMap(int xsize
, int ysize
, int depth
, long mflags
);
50 void MyFreeBitMap(struct BitMap
*bmp
);
53 extern void display_map(struct Window
*);
57 * These values will be available from tile.c source
59 * #define MAXMONTILE 335
60 * #define MAXOBJTILE 722
61 * #define MAXOTHTILE 841
66 #define IMGPAGESIZE (IMGROWS * IMGCOLUMNS)
68 #define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* The type of form we use */
69 #define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* The ILBM bitmap header */
70 #define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* The ILBM camg (ignored) */
71 #define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Standard ILBM color map */
72 #define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The plane data */
73 #define ID_PDAT MAKE_ID('P', 'D', 'A', 'T') /* The PDAT structure below */
77 #define NUMTILEIMAGES 3
78 char *tileimages
[] = {
80 "aNetHack:tiles/monsters.iff",
82 "aNetHack:tiles/objects.iff",
84 "aNetHack:tiles/other.iff", 0,
87 struct BitMap
*ifftimg
[NUMTILEIMAGES
], *tile
;
90 short pens
[NUMDRIPENS
] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 };
91 main(int argc
, char **argv
)
94 struct IntuiMessage
*imsg
;
97 int i
, x
, y
, tbl
, done
= 0, num
;
101 bmhd
= ReadTileImageFiles();
103 scr
= OpenScreenTags(
104 NULL
, SA_Depth
, pictdata
.nplanes
+ amii_extraplanes
, SA_DisplayID
,
105 DBLNTSC_MONITOR_ID
| HIRESLACE_KEY
, SA_Overscan
, OSCAN_TEXT
, SA_Top
,
106 0, SA_Left
, 0, SA_Width
, STDSCREENWIDTH
, SA_Height
, STDSCREENHEIGHT
,
107 SA_Type
, CUSTOMSCREEN
, SA_DetailPen
, 0, SA_BlockPen
, 1, SA_Title
,
108 "aNetHack Chars", SA_Pens
, pens
, TAG_DONE
);
110 printf("no screen\n");
116 0, WA_CustomScreen
, scr
, WA_Flags
,
117 WFLG_DRAGBAR
| WFLG_SIZEGADGET
| WFLG_DEPTHGADGET
| WFLG_CLOSEGADGET
,
118 WA_IDCMP
, IDCMP_CLOSEWINDOW
| IDCMP_NEWSIZE
| IDCMP_MOUSEBUTTONS
,
119 WA_Left
, 0, WA_Top
, scr
->WBorTop
+ 1 + 13, WA_MinWidth
, 100,
120 WA_MinHeight
, 100, WA_MaxWidth
, 700, WA_MaxHeight
, 1000, WA_Width
,
121 640, WA_Height
, 340, WA_SmartRefresh
, TRUE
, TAG_DONE
);
124 for (i
= 0; i
< NUMTILEIMAGES
* IMGPAGESIZE
; ++i
) {
126 tbl
= i
/ IMGPAGESIZE
;
130 dx
= i
% (IMGCOLUMNS
* 2);
131 dy
= i
/ (IMGCOLUMNS
* 2);
132 BltBitMapRastPort(ifftimg
[tbl
], x
* pictdata
.xsize
,
133 y
* pictdata
.ysize
, w
->RPort
,
134 w
->BorderLeft
+ 1 + dx
* pictdata
.xsize
,
135 w
->BorderTop
+ 1 + dy
* pictdata
.ysize
,
136 pictdata
.xsize
, pictdata
.ysize
, 0xc0);
138 WaitPort(w
->UserPort
);
139 while (imsg
= (struct IntuiMessage
*) GetMsg(w
->UserPort
)) {
142 ReplyMsg((struct Message
*) imsg
);
144 case IDCMP_MOUSEBUTTONS
: {
145 x
= imsg
->MouseX
- w
->BorderLeft
;
146 y
= imsg
->MouseY
- w
->BorderTop
;
147 num
= ((y
/ pictdata
.ysize
) * IMGCOLUMNS
* 2)
148 + (x
/ pictdata
.xsize
);
149 sprintf(buf
, "Char #%d", num
);
150 SetWindowTitles(w
, buf
, buf
);
152 case IDCMP_CLOSEWINDOW
:
162 FreeImageFiles(tileimages
, ifftimg
);
172 BitMapHeader ret
= ReadImageFiles(tileimages
, ifftimg
, &errstr
);
180 ReadImageFiles(char **filenames
, struct BitMap
**iffimg
, char **errstrp
)
182 BitMapHeader
*bmhd
= NULL
, bmhds
;
186 struct IFFHandle
*iff
;
187 struct StoredProperty
*prop
;
189 IFFParseBase
= OpenLibrary("iffparse.library", 0L);
191 *errstrp
= "No iffparse.library";
196 for( i = 0; filenames[i]; ++i )
197 memset( iffimg[i], 0, sizeof( struct BitMap ) );
199 for (i
= 0; filenames
[i
]; ++i
) {
202 FreeImageFiles(filenames
, iffimg
);
203 *errstrp
= "can't start IFF processing";
206 iff
->iff_Stream
= Open(filenames
[i
], MODE_OLDFILE
);
207 if (iff
->iff_Stream
== 0) {
208 char *buf
= malloc(100 + strlen(filenames
[i
]));
209 FreeImageFiles(filenames
, iffimg
);
210 sprintf(buf
, "Can't open %s: %s", filenames
[i
], strerror(errno
));
215 OpenIFF(iff
, IFFF_READ
);
216 PropChunk(iff
, ID_BMAP
, ID_BMHD
);
217 PropChunk(iff
, ID_BMAP
, ID_CMAP
);
218 PropChunk(iff
, ID_BMAP
, ID_CAMG
);
219 PropChunk(iff
, ID_BMAP
, ID_PDAT
);
220 StopChunk(iff
, ID_BMAP
, ID_PLNE
);
221 if ((j
= ParseIFF(iff
, IFFPARSE_SCAN
)) != 0) {
222 char *buf
= malloc(100);
223 FreeImageFiles(filenames
, iffimg
);
224 sprintf(buf
, "ParseIFF failed for image %d, failure code: %d", i
,
230 if (prop
= FindProp(iff
, ID_BMAP
, ID_BMHD
)) {
231 bmhd
= (BitMapHeader
*) prop
->sp_Data
;
233 FreeImageFiles(filenames
, iffimg
);
235 Close(iff
->iff_Stream
);
237 *errstrp
= "No BMHD CHUNK in file";
241 if (prop
= FindProp(iff
, ID_BMAP
, ID_CMAP
)) {
242 cmap
= prop
->sp_Data
;
243 for (j
= 0; j
< (1L << bmhd
->nPlanes
) * 3; j
+= 3) {
245 /* Some day we will want to use the larger palette
246 * resolution available under v39 and later. i.e.
247 * 32 instead of 12 bits of color. Ususally this
248 * just means shifting the color left by 16-20 bits
249 * depending on what intensity looks best. Experience
250 * says that the higher values are better intensities.
252 * For now though we won't do this. The color table
253 * structure is incompatible with earlier versions of
254 * intuition. We would have to do some funny things
255 * to make 3*AMII_MAXCOLORS longs work like 3*AMII_MAXCOLORS
256 * UWORD's at run time... A union would help, but...
258 if( IntuitionBase
->LibNode
.lib_Version
>= 39 )
260 /* 8 bits of color, so shift to left end. */
261 amiv_init_map
[ j
+0 ] = cmap
[j
+0]<<24;
262 amiv_init_map
[ j
+1 ] = cmap
[j
+1]<<24;
263 amiv_init_map
[ j
+2 ] = cmap
[j
+2]<<24;
268 /* We can only use 4 bits of the 8 that are stored in the
269 * cmap, so mask them and then shift them into position
270 * for the UWORD value to store.
273 amii_initmap
[j
/ 3] = amiv_init_map
[j
/ 3] =
274 ((cmap
[j
+ 0] >> 4) << 8) | ((cmap
[j
+ 1] >> 4) << 4)
275 | (cmap
[j
+ 2] >> 4);
280 FreeImageFiles(filenames
, iffimg
);
282 Close(iff
->iff_Stream
);
284 *errstrp
= "No CMAP CHUNK in file";
288 if (prop
= FindProp(iff
, ID_BMAP
, ID_PDAT
)) {
291 pp
= (struct PDAT
*) prop
->sp_Data
;
294 FreeImageFiles(filenames
, iffimg
);
296 Close(iff
->iff_Stream
);
298 *errstrp
= "No PDAT CHUNK in file";
302 iffimg
[i
] = MyAllocBitMap(bmhd
->w
, bmhd
->h
,
303 pictdata
.nplanes
+ amii_extraplanes
,
304 MEMF_CHIP
| MEMF_CLEAR
);
305 if (iffimg
[i
] == NULL
) {
306 char *buf
= malloc(80);
307 FreeImageFiles(filenames
, iffimg
);
308 sprintf(buf
, "Can't allocate bitmap for image %d\n", i
);
312 for (j
= 0; j
< pictdata
.nplanes
+ amii_extraplanes
; ++j
) {
313 ReadChunkBytes(iff
, iffimg
[i
]->Planes
[j
],
314 RASSIZE(bmhd
->w
, bmhd
->h
));
318 Close(iff
->iff_Stream
);
321 CloseLibrary(IFFParseBase
);
323 tile
= MyAllocBitMap(pictdata
.xsize
, pictdata
.ysize
,
324 pictdata
.nplanes
+ amii_extraplanes
,
325 MEMF_CHIP
| MEMF_CLEAR
);
327 FreeImageFiles(filenames
, iffimg
);
328 *errstrp
= "Can't allocate tile bitmap for scaling";
340 MyAllocBitMap(int xsize
, int ysize
, int depth
, long mflags
)
345 bm
= (struct MyBitMap
*) alloc(sizeof(*bm
));
351 InitBitMap(&bm
->bm
, depth
, xsize
, ysize
);
352 for (j
= 0; j
< depth
; ++j
) {
353 if (mflags
& MEMF_CHIP
)
354 bm
->bm
.Planes
[j
] = AllocRaster(xsize
, ysize
);
356 bm
->bm
.Planes
[j
] = AllocMem(RASSIZE(xsize
, ysize
), mflags
);
358 if (bm
->bm
.Planes
[j
] == 0) {
359 MyFreeBitMap(&bm
->bm
);
362 if (mflags
& MEMF_CLEAR
)
363 memset(bm
->bm
.Planes
[j
], 0, RASSIZE(xsize
, ysize
));
369 MyFreeBitMap(struct BitMap
*bmp
)
372 struct MyBitMap
*bm
= (struct MyBitMap
*) bmp
;
374 for (j
= 0; j
< bm
->bm
.Depth
; ++j
) {
375 if (bm
->bm
.Planes
[j
]) {
376 if (bm
->mflags
& MEMF_CHIP
)
377 FreeRaster(bm
->bm
.Planes
[j
], bm
->xsize
, bm
->ysize
);
379 FreeMem(bm
->bm
.Planes
[j
], RASSIZE(bm
->xsize
, bm
->ysize
));
387 panic(s
, a1
, a2
, a3
, a4
)
390 printf(s
, a1
, a2
, a3
, a4
);
394 alloc(unsigned int x
)
396 long *p
= (long *) malloc(x
);
398 panic("malloc failed");
408 FreeImageFiles(tileimages
, ifftimg
);
412 FreeImageFiles(char **filenames
, struct BitMap
**img
)
416 for (i
= 0; filenames
[i
]; ++i
) {
418 MyFreeBitMap(img
[i
]);
421 /* REALLY ugly hack alert! */
422 if (tile
&& img
== ifftimg
)
428 * Define some stuff for our special glyph drawing routines
430 unsigned short glyph_node_index
, glyph_buffer_index
;
431 #define NUMBER_GLYPH_NODES 80
432 #define GLYPH_BUFFER_SIZE 512
433 struct amiv_glyph_node
{
435 short srcx
, srcy
, dstx
, dsty
;
436 struct BitMap
*bitmap
;
438 struct amiv_glyph_node amiv_g_nodes
[NUMBER_GLYPH_NODES
];
439 static char amiv_glyph_buffer
[GLYPH_BUFFER_SIZE
];
442 flush_glyph_buffer(vw
)
446 amiv_flush_glyph_buffer(vw
);
448 amii_flush_glyph_buffer(vw
);
452 * Routine to flush whatever is buffered
455 amiv_flush_glyph_buffer(vw
)
458 #if !defined(DISPMAP) || defined(OPT_DISPMAP)
459 int xsize
, ysize
, x
, y
;
460 struct BitScaleArgs bsa
;
461 struct BitScaleArgs bsm
;
462 struct RastPort rast
;
463 struct Window
*w
= NULL
;
464 struct BitMap
*imgbm
= 0, *bm
= 0;
467 register struct RastPort
*rp
= vw
->RPort
;
470 /* If nothing is buffered, return before we do anything */
471 if (glyph_node_index
== 0)
475 amiv_start_glyphout(WIN_MAP
);
478 if (sysflags
.fast_map
) {
486 #if !defined(DISPMAP) || defined(OPT_DISPMAP)
488 /* This is a dynamic value based on this relationship. */
490 (pictdata
.xsize
!= mxsize
|| pictdata
.ysize
!= mysize
);
492 /* If overview window is up, set up to render the correct scale there
494 if (WIN_OVER
!= WIN_ERR
&& (w
= amii_wins
[WIN_OVER
]->win
) != NULL
) {
497 /* Calculate the x and y size of each tile for a ROWNO by COLNO
499 xsize
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
) / COLNO
;
500 ysize
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
) / ROWNO
;
502 /* Get a chip memory bitmap to blit out of */
503 bm
= MyAllocBitMap(pictdata
.xsize
, pictdata
.ysize
,
504 pictdata
.nplanes
+ amii_extraplanes
,
505 MEMF_CLEAR
| MEMF_CHIP
);
509 "Can't allocate bitmap for scaling overview window");
514 memset(&bsa
, 0, sizeof(bsa
));
515 bsa
.bsa_SrcX
= bsa
.bsa_SrcY
= 0;
516 bsa
.bsa_SrcBitMap
= tile
;
517 bsa
.bsa_SrcWidth
= pictdata
.xsize
;
518 bsa
.bsa_SrcHeight
= pictdata
.ysize
;
519 bsa
.bsa_XSrcFactor
= pictdata
.xsize
;
520 bsa
.bsa_YSrcFactor
= pictdata
.ysize
;
523 bsa
.bsa_DestWidth
= xsize
;
524 bsa
.bsa_DestHeight
= ysize
;
525 bsa
.bsa_XDestFactor
= xsize
;
526 bsa
.bsa_YDestFactor
= ysize
;
527 bsa
.bsa_DestBitMap
= bm
;
530 if (scaling_needed
) {
531 /* Fill in scaling data for map rendering */
532 memset(&bsm
, 0, sizeof(bsm
));
533 bsm
.bsa_SrcX
= bsm
.bsa_SrcY
= 0;
534 bsm
.bsa_SrcBitMap
= tile
;
536 bsm
.bsa_SrcWidth
= pictdata
.xsize
;
537 bsm
.bsa_SrcHeight
= pictdata
.ysize
;
539 bsm
.bsa_XSrcFactor
= pictdata
.xsize
;
540 bsm
.bsa_YSrcFactor
= pictdata
.ysize
;
542 bsm
.bsa_DestWidth
= mxsize
;
543 bsm
.bsa_DestHeight
= mysize
;
545 bsm
.bsa_XDestFactor
= mxsize
;
546 bsm
.bsa_YDestFactor
= mysize
;
547 bsm
.bsa_DestBitMap
= rp
->BitMap
;
548 bsm
.bsa_DestY
= bsm
.bsa_DestX
= 0;
550 imgbm
= MyAllocBitMap(mxsize
, mysize
,
551 pictdata
.nplanes
+ amii_extraplanes
,
552 MEMF_CLEAR
| MEMF_CHIP
);
554 amii_putstr(WIN_MESSAGE
, 0,
555 "Can't allocate scaling bitmap for map window");
557 bsm
.bsa_DestBitMap
= imgbm
;
560 /* Go ahead and start dumping the stuff */
561 for (i
= 0; i
< glyph_node_index
; ++i
) {
563 register int offx
, offy
, j
;
564 struct BitMap
*nodebm
= amiv_g_nodes
[i
].bitmap
;
566 /* Get the unclipped coordinates */
567 x
= amiv_g_nodes
[i
].odstx
;
568 y
= amiv_g_nodes
[i
].odsty
;
570 /* If image is not in CHIP. copy each plane into tile line by line
573 offx
= amiv_g_nodes
[i
].srcx
/ 8; /* 8 is bits per byte */
574 offy
= amiv_g_nodes
[i
].srcy
* nodebm
->BytesPerRow
;
575 for (j
= 0; j
< pictdata
.nplanes
+ amii_extraplanes
; ++j
) {
576 for (k
= 0; k
< pictdata
.ysize
; ++k
) {
577 /* For a 16x16 tile, this could just be short assignments,
579 * this code is generalized to handle any size tile
582 memcpy(tile
->Planes
[j
] + ((k
* pictdata
.ysize
) / 8),
583 nodebm
->Planes
[j
] + offx
+ offy
584 + (nodebm
->BytesPerRow
* k
),
589 if (!clipping
|| (x
>= clipx
&& y
>= clipy
&& x
< clipxmax
591 /* scaling is needed, do it */
592 if (scaling_needed
) {
594 BltBitMapRastPort(imgbm
, 0, 0, rp
, amiv_g_nodes
[i
].dstx
,
595 amiv_g_nodes
[i
].dsty
, mxsize
, mysize
,
598 BltBitMapRastPort(tile
, 0, 0, rp
, amiv_g_nodes
[i
].dstx
,
599 amiv_g_nodes
[i
].dsty
, pictdata
.xsize
,
600 pictdata
.ysize
, 0xc0);
603 /* Draw the overview window unless we are scrolling the map raster
605 if (bm
&& w
&& reclip
!= 2) {
608 rast
.BitMap
, 0, 0, w
->RPort
,
609 w
->BorderLeft
+ amiv_g_nodes
[i
].odstx
* xsize
,
610 w
->BorderTop
+ amiv_g_nodes
[i
].odsty
* ysize
, xsize
,
624 amii_end_glyphout(WIN_MAP
);
627 glyph_node_index
= glyph_buffer_index
= 0;
631 * Glyph buffering routine. Called instead of WindowPuts().
634 amiv_lprint_glyph(window
, color_index
, glyph
)
636 int color_index
, glyph
;
639 struct amii_WinDesc
*cw
;
644 register int xoff
, yoff
;
646 /* Get the real icon index */
647 if (glyph
!= NO_GLYPH
)
648 icon
= GlyphToIcon(glyph
);
650 if ((cw
= amii_wins
[window
]) == (struct amii_WinDesc
*) NULL
)
651 panic("bad winid in amiv_lprint_glyph: %d", window
);
655 if (glyph
!= NO_GLYPH
&& glyph
< 10000) {
656 /* decide on which image has the needed picture */
657 if (icon
<= MAXMONTILE
) {
660 } else if (icon
<= MAXOBJTILE
) {
662 base
= MAXMONTILE
+ 1;
663 } else if (icon
<= MAXOTHTILE
) {
665 base
= MAXOBJTILE
+ 1;
667 panic("Bad icon #%d, glyph #%d, only %d icons known\n", icon
,
670 /* Get the relative offset in the page */
672 /* How many pixels to account for y distance down */
673 yoff
= ((icon
- base
) / pictdata
.across
) * pictdata
.ysize
;
675 /* How many pixels to account for x distance across */
676 xoff
= ((icon
- base
) % pictdata
.across
) * pictdata
.xsize
;
679 if (glyph
>= 10000) {
680 /* Run a single ASCII character out to the rastport right now */
681 char c
= glyph
- 10000;
683 struct RastPort
*rp
= w
->RPort
;
685 Move(rp
, xxx
= (((cw
->curx
- clipx
) * rp
->TxWidth
) + w
->BorderLeft
),
686 xxy
= (w
->BorderTop
+ (((cw
->cury
- clipy
) + 1) * rp
->TxHeight
)
689 /* XXX this shouldn't be necessary: */
690 if (cw
->cursx
== xxx
&& cw
->cursy
== xxy
) {
691 cw
->wflags
&= ~FLMAP_CURSUP
;
693 cw
->curx
+= rp
->TxWidth
; /* keep things in sync */
697 if (cw
->type
== NHW_MAP
) {
698 curx
= cw
->curx
- clipx
;
699 cury
= cw
->cury
- clipy
;
701 /* See if we're out of glyph nodes */
702 if (glyph_node_index
>= NUMBER_GLYPH_NODES
)
703 amiv_flush_glyph_buffer(w
);
705 /* Fill in the node. */
706 amiv_g_nodes
[glyph_node_index
].dsty
=
707 min(w
->BorderTop
+ (cury
* mysize
), w
->Height
- 1);
710 if (sysflags
.fast_map
) {
713 /* display_map() needs byte-aligned destinations, and we don't
715 * overwrite the window border.
717 amiv_g_nodes
[glyph_node_index
].dstx
=
718 (w
->BorderLeft
+ 8 + (curx
* mxsize
)) & -8;
723 #if !defined(DISPMAP) || defined(OPT_DISPMAP)
724 amiv_g_nodes
[glyph_node_index
].dstx
=
725 min(w
->BorderLeft
+ (curx
* mxsize
), w
->Width
- 1);
730 amiv_g_nodes
[glyph_node_index
].odsty
= cw
->cury
;
731 amiv_g_nodes
[glyph_node_index
].odstx
= cw
->curx
;
732 amiv_g_nodes
[glyph_node_index
].srcx
= xoff
;
733 amiv_g_nodes
[glyph_node_index
].srcy
= yoff
;
734 amiv_g_nodes
[glyph_node_index
].bitmap
= ifftimg
[tbl
];
738 register int j
, k
, x
, y
, apen
;
739 struct RastPort
*rp
= w
->RPort
;
740 x
= rp
->cp_x
- pictdata
.xsize
- 3;
742 if (sysflags
.fast_map
) {
753 y
= rp
->cp_y
- pictdata
.ysize
+ 1;
755 if (glyph
!= NO_GLYPH
) {
756 struct BitMap
*bm
= ifftimg
[tbl
];
758 /* 8 bits per byte */
760 yoff
*= bm
->BytesPerRow
;
761 for (j
= 0; j
< pictdata
.nplanes
; ++j
) {
762 for (k
= 0; k
< pictdata
.ysize
; ++k
) {
763 memcpy(tile
->Planes
[j
] + ((k
* pictdata
.ysize
) / 8),
764 bm
->Planes
[j
] + xoff
+ yoff
765 + (bm
->BytesPerRow
* k
),
770 BltBitMapRastPort(tile
, 0, 0, rp
, x
, y
, pictdata
.xsize
,
771 pictdata
.ysize
, 0xc0);
774 SetAPen(rp
, sysflags
.amii_dripens
[SHINEPEN
]);
775 Move(rp
, x
- 1, y
+ pictdata
.ysize
);
776 Draw(rp
, x
- 1, y
- 1);
777 Draw(rp
, x
+ pictdata
.xsize
, y
- 1);
778 SetAPen(rp
, sysflags
.amii_dripens
[SHADOWPEN
]);
779 Move(rp
, x
+ pictdata
.xsize
, y
);
780 Draw(rp
, x
+ pictdata
.xsize
, y
+ pictdata
.ysize
);
781 Draw(rp
, x
, y
+ pictdata
.ysize
);
783 } else if (x
> w
->BorderLeft
) {
787 SetAPen(rp
, amii_menuBPen
);
788 SetBPen(rp
, amii_menuBPen
);
789 RectFill(rp
, x
- 1, y
- 1, x
+ pictdata
.xsize
,
798 * Define some variables which will be used to save context when toggling
799 * back and forth between low level text and console I/O.
801 static long xsave
, ysave
, modesave
, apensave
, bpensave
;
805 * The function is called before any glyphs are driven to the screen. It
806 * removes the cursor, saves internal state of the window, then returns.
810 amiv_start_glyphout(window
)
813 struct amii_WinDesc
*cw
;
816 if ((cw
= amii_wins
[window
]) == (struct amii_WinDesc
*) NULL
)
817 panic("bad winid %d in start_glyphout()", window
);
819 if (cw
->wflags
& FLMAP_INGLYPH
)
823 panic("bad winid %d, no window ptr set", window
);
826 * Save the context of the window
828 xsave
= w
->RPort
->cp_x
;
829 ysave
= w
->RPort
->cp_y
;
830 modesave
= w
->RPort
->DrawMode
;
831 apensave
= w
->RPort
->FgPen
;
832 bpensave
= w
->RPort
->BgPen
;
835 * Set the mode, and be done with it
837 usecolor
= iflags
.use_color
;
838 iflags
.use_color
= FALSE
;
839 cw
->wflags
|= FLMAP_INGLYPH
;
843 * General cleanup routine -- flushes and restores cursor
846 amii_end_glyphout(window
)
849 struct amii_WinDesc
*cw
;
852 if ((cw
= amii_wins
[window
]) == (struct amii_WinDesc
*) NULL
)
853 panic("bad window id %d in amii_end_glyphout()", window
);
855 if ((cw
->wflags
& FLMAP_INGLYPH
) == 0)
857 cw
->wflags
&= ~(FLMAP_INGLYPH
);
860 panic("bad winid %d, no window ptr set", window
);
863 * Clean up whatever is left in the buffer
865 iflags
.use_color
= usecolor
;
868 * Reset internal data structs
870 SetAPen(w
->RPort
, apensave
);
871 SetBPen(w
->RPort
, bpensave
);
872 SetDrMd(w
->RPort
, modesave
);
874 Move(w
->RPort
, xsave
, ysave
);
877 static maze_type
= COL_MAZE_BRICK
;
880 SetMazeType(MazeType t
)
886 GlyphToIcon(int glyph
)
890 return (glyph2tile
[glyph
]);
897 * Define some stuff for our special glyph drawing routines
899 static unsigned short glyph_node_index
, glyph_buffer_index
;
900 #define NUMBER_GLYPH_NODES 80
901 #define GLYPH_BUFFER_SIZE 512
904 struct amii_glyph_node
{
908 unsigned char bg_color
;
909 unsigned char fg_color
;
912 static struct amii_glyph_node amii_g_nodes
[NUMBER_GLYPH_NODES
];
913 static char amii_glyph_buffer
[GLYPH_BUFFER_SIZE
];
917 * Map our amiga-specific colormap into the colormap specified in color.h.
918 * See winami.c for the amiga specific colormap.
921 int foreg
[AMII_MAXCOLORS
] = {
922 0, 7, 4, 2, 6, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0
924 int backg
[AMII_MAXCOLORS
] = {
925 1, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 1
931 #define CLR_BROWN 3 /* on IBM, low-intensity yellow is brown */
933 #define CLR_MAGENTA 5
935 #define CLR_GRAY 7 /* low-intensity white */
938 #define CLR_BRIGHT_GREEN 10
939 #define CLR_YELLOW 11
940 #define CLR_BRIGHT_BLUE 12
941 #define CLR_BRIGHT_MAGENTA 13
942 #define CLR_BRIGHT_CYAN 14
950 * Begin Revamped Text display routines
952 * Up until version 3.1, the only method for displaying text on the playing
953 * field was by using the console.device. This was nice for a number of
954 * reasons, the most signifigant of which was a lot of the nuts and bolts was
955 * done for you via escape sequences interpreted by said device. This did
956 * not come without a price however. And that price was speed. It has now
957 * come to a point where the speed has now been deemed unacceptable.
959 * The following series of routines are designed to drop into the current
960 * anethack display code, using hooks provided for such a measure. It works
961 * on similar principals as the WindowPuts(), buffering I/O internally
962 * until either an explicit flush or internal buffering is exceeded, thereby
963 * forcing the flush. The output (or glyphs) does not go to the
964 * console.device, however. It is driven directly to the rasterport of the
965 * anethack window via the low-level Text() calls, increasing the speed by
966 * a very signifigant factor.
969 * Routine to simply flush whatever is buffered
972 amii_flush_glyph_buffer(w
)
976 register struct RastPort
*rp
= w
->RPort
;
978 /* If nothing is buffered, return before we do anything */
979 if (glyph_node_index
== 0)
983 amii_start_glyphout(WIN_MAP
);
985 /* Set up the drawing mode */
988 /* Go ahead and start dumping the stuff */
989 for (i
= 0; i
< glyph_node_index
; ++i
) {
990 /* These coordinate calculations must be synced with the
991 * code in amii_curs() in winfuncs.c. curs_on_u() calls amii_curs()
992 * to draw the cursor on top of the player
994 y
= w
->BorderTop
+ (amii_g_nodes
[i
].y
- 2) * rp
->TxHeight
995 + rp
->TxBaseline
+ 1;
996 x
= amii_g_nodes
[i
].x
* rp
->TxWidth
+ w
->BorderLeft
;
998 /* Move pens to correct location */
999 Move(rp
, (long) x
, (long) y
);
1001 /* Setup the colors */
1002 SetAPen(rp
, (long) amii_g_nodes
[i
].fg_color
);
1003 SetBPen(rp
, (long) amii_g_nodes
[i
].bg_color
);
1006 Text(rp
, amii_g_nodes
[i
].buffer
, amii_g_nodes
[i
].len
);
1009 amii_end_glyphout(WIN_MAP
);
1011 glyph_node_index
= glyph_buffer_index
= 0;
1014 amiga_print_glyph(window
, color_index
, glyph
)
1016 int color_index
, glyph
;
1019 amiv_lprint_glyph(window
, color_index
, glyph
);
1021 amii_lprint_glyph(window
, color_index
, glyph
);
1025 * Glyph buffering routine. Called instead of WindowPuts().
1028 amii_lprint_glyph(window
, color_index
, glyph
)
1030 int color_index
, glyph
;
1032 int fg_color
, bg_color
;
1033 struct amii_WinDesc
*cw
;
1038 if ((cw
= amii_wins
[window
]) == (struct amii_WinDesc
*) NULL
)
1039 panic("bad winid in amii_lprint_glyph: %d", window
);
1046 fg_color
= foreg
[color_index
];
1047 bg_color
= backg
[color_index
];
1051 #endif /* TEXTCOLOR */
1053 /* See if we have enough character buffer space... */
1054 if (glyph_buffer_index
>= GLYPH_BUFFER_SIZE
)
1055 amii_flush_glyph_buffer(w
);
1058 * See if we can append it to the current active node of glyph buffer. It
1059 * must satisfy the following conditions:
1061 * * background colors are the same, AND
1062 * * foreground colors are the same, AND
1063 * * they are precisely side by side
1065 if ((glyph_buffer_index
!= 0)
1066 && (fg_color
== amii_g_nodes
[glyph_node_index
- 1].fg_color
)
1067 && (bg_color
== amii_g_nodes
[glyph_node_index
- 1].bg_color
)
1068 && (amii_g_nodes
[glyph_node_index
- 1].x
1069 + amii_g_nodes
[glyph_node_index
- 1].len
1070 == curx
) && (amii_g_nodes
[glyph_node_index
- 1].y
== cury
)) {
1072 * Add it to the end of the buffer
1074 amii_glyph_buffer
[glyph_buffer_index
++] = glyph
;
1075 amii_g_nodes
[glyph_node_index
- 1].len
++;
1077 /* See if we're out of glyph nodes */
1078 if (glyph_node_index
>= NUMBER_GLYPH_NODES
)
1079 amii_flush_glyph_buffer(w
);
1080 amii_g_nodes
[glyph_node_index
].len
= 1;
1081 amii_g_nodes
[glyph_node_index
].x
= curx
;
1082 amii_g_nodes
[glyph_node_index
].y
= cury
;
1083 amii_g_nodes
[glyph_node_index
].fg_color
= fg_color
;
1084 amii_g_nodes
[glyph_node_index
].bg_color
= bg_color
;
1085 amii_g_nodes
[glyph_node_index
].buffer
=
1086 &amii_glyph_buffer
[glyph_buffer_index
];
1087 amii_glyph_buffer
[glyph_buffer_index
] = glyph
;
1088 ++glyph_buffer_index
;
1092 #endif /* !TESTING */
1096 * Define some variables which will be used to save context when toggling
1097 * back and forth between low level text and console I/O.
1099 static long xsave
, ysave
, modesave
, apensave
, bpensave
;
1100 static int usecolor
;
1101 #endif /* TESTING */
1105 * The function is called before any glyphs are driven to the screen. It
1106 * removes the cursor, saves internal state of the window, then returns.
1110 amii_start_glyphout(window
)
1113 struct amii_WinDesc
*cw
;
1116 if ((cw
= amii_wins
[window
]) == (struct amii_WinDesc
*) NULL
)
1117 panic("bad winid %d in start_glyphout()", window
);
1119 if (cw
->wflags
& FLMAP_INGLYPH
)
1123 panic("bad winid %d, no window ptr set", window
);
1126 * Save the context of the window
1128 xsave
= w
->RPort
->cp_x
;
1129 ysave
= w
->RPort
->cp_y
;
1130 modesave
= w
->RPort
->DrawMode
;
1131 apensave
= w
->RPort
->FgPen
;
1132 bpensave
= w
->RPort
->BgPen
;
1135 * Set the mode, and be done with it
1137 usecolor
= iflags
.use_color
;
1138 iflags
.use_color
= FALSE
;
1139 cw
->wflags
|= FLMAP_INGLYPH
;
1141 #endif /* !TESTING */
1145 * General cleanup routine -- flushes and restores cursor
1148 amii_end_glyphout(window
)
1151 struct amii_WinDesc
*cw
;
1154 if( ( cw
= amii_wins
[ window
] ) == (struct amii_WinDesc
*)NULL
)
1155 panic("bad window id %d in amii_end_glyphout()", window
);
1157 if( ( cw
->wflags
& FLMAP_INGLYPH
) == 0 )
1159 cw
->wflags
&= ~(FLMAP_INGLYPH
);
1161 if( !(w
= cw
->win
) )
1162 panic( "bad winid %d, no window ptr set", window
);
1165 * Clean up whatever is left in the buffer
1167 iflags
.use_color
= usecolor
;
1170 * Reset internal data structs
1172 SetAPen(w
->RPort
, apensave
);
1173 SetBPen(w
->RPort
, bpensave
);
1174 SetDrMd(w
->RPort
, modesave
);
1176 Move(w
->RPort
, xsave
, ysave
);
1183 /* don't use dispmap unless x & y are 8,16,24,32,48 and equal */
1187 if (mxsize
!= mysize
|| dispmap_sanity1(mxsize
)
1188 || dispmap_sanity1(mysize
)) {
1189 sysflags
.fast_map
= 0;
1196 static unsigned char valid
[] = { 8, 16, 24, 32, 48, 0 };
1197 return !!strchr(valid
, x
);
1199 #endif /* OPT_DISPMAP */
1200 #endif /* TESTING */