2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Graphics function AllocSpriteDataA()
9 #include <aros/debug.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/utility.h>
13 #include <aros/debug.h>
14 #include <cybergraphx/cybergraphics.h>
15 #include <graphics/sprite.h>
16 #include <graphics/scale.h>
17 #include <hidd/graphics.h>
18 #include <utility/tagitem.h>
19 #include <exec/exec.h>
20 #include <proto/oop.h>
22 #include "gfxfuncsupport.h"
23 #include "graphics_intern.h"
27 #define PRINT_PIXFMT(bitmap) \
28 if (IS_HIDD_BM(bitmap)) {\
32 OOP_GetAttr(HIDD_BM_OBJ(bitmap), aHidd_BitMap_PixFmt, (IPTR *)&pf); \
33 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf); \
35 bug("[AllocSpriteData] Bitmap pixelformat: %lu\n", stdpf); \
39 #define PRINT_PIXFMT(bitmap)
44 #define PRINT_BITMAP(bitmap, xmax, ymax) \
45 bug("[AllocSpriteData] Bitmap contents:\n"); \
47 OOP_Object *bm = OBTAIN_HIDD_BM(bitmap); \
50 for (y = 0; y < ymax; y++) { \
51 for (x = 0; x < xmax; x++) { \
52 HIDDT_Pixel pix = HIDD_BM_GetPixel(bm, x, y); \
54 bug("0x%08lX ", pix); \
58 RELEASE_HIDD_BM(bm, bitmap); \
62 #define PRINT_BITMAP(bitmap, xmax, ymax)
65 /*****************************************************************************
68 #include <proto/graphics.h>
70 AROS_LH2(struct ExtSprite
*, AllocSpriteDataA
,
73 AROS_LHA(struct BitMap
*, bitmap
, A2
),
74 AROS_LHA(struct TagItem
*, tagList
, A1
),
77 struct GfxBase
*, GfxBase
, 170, Graphics
)
82 bitmap - pointer to a bitmap. This bitmap provides the source data
84 tags - pointer to a taglist
87 SPRITEA_Width (ULONG) - Width of the sprite. If bitmap is smaller it will
88 be filled on the right side with transparent
89 pixels. Defaults to 16.
90 SPRITEA_XReplication (LONG) - 0 - perform a 1 to 1 conversion
91 1 - each pixel from the source is replicated twice
92 2 - each pixel is replicated 4 times.
93 -1 - skip every 2nc pixel in the source bitmap
94 -2 - only include every fourth pixel from the source.
95 SPRITEA_YReplication (LONG) - like SPRITEA_YReplication, but for vertical direction.
96 SPRITEA_OutputHeight (ULONG) - Output height of the sprite. Must be at least as high
97 as the bitmap. Defaults to bitmap height.
98 SPRITEA_Attach - (Not implemented)
101 SpritePtr - pointer to a ExtSprite structure,
102 or NULL if there is a failure.
103 You should pass this pointer to FreeSpriteData()
104 when this sprite is not needed anymore.
119 ******************************************************************************/
123 struct ExtSprite
*sprite
= NULL
;
125 D(bug("AllocSpriteDataA(0x%08lX)\n", bitmap
));
126 if (NULL
!= bitmap
) {
127 #define SCALE_NORMAL 16
128 BOOL have_OutputHeight
= FALSE
;
129 BOOL have_OldDataFormat
= FALSE
;
132 struct TagItem
* tag
, * tstate
= tagList
;
133 struct BitMap
*friend_bm
= NULL
;
134 ULONG pixfmt
= BMF_SPECIALFMT
|SHIFT_PIXFMT(PIXFMT_LUT8
);
135 struct BitMap old_bitmap
;
136 UWORD
*planes
= NULL
;
137 ULONG planes_size
= 0;
138 struct BitScaleArgs bsa
;
139 LONG xrep
= 0, yrep
= 0;
141 memset(&bsa
, 0, sizeof(bsa
));
143 while (NULL
!= (tag
= NextTagItem(&tstate
))) {
144 switch (tag
->ti_Tag
) {
146 width
= tag
->ti_Data
;
149 case SPRITEA_XReplication
:
153 case SPRITEA_YReplication
:
157 case SPRITEA_OutputHeight
:
158 height
= tag
->ti_Data
;
159 have_OutputHeight
= TRUE
;
162 /* Currently we don't support this */
163 case SPRITEA_Attached
:
166 case SPRITEA_OldDataFormat
:
167 have_OldDataFormat
= TRUE
;
171 if (have_OldDataFormat
) {
172 /* A zero-width/height sprite is evidently legal on AOS */
173 UWORD height2
= height
== 0 ? 1 : height
;
174 UWORD
*p
, *q
, *s
= (UWORD
*)bitmap
+ 2;
177 InitBitMap(&old_bitmap
, 2, 16, height2
);
178 planes_size
= height2
* sizeof(UWORD
) * 2;
179 planes
= AllocMem(planes_size
, MEMF_CLEAR
| MEMF_CHIP
);
183 q
= &planes
[height2
];
184 mask
= ~((1 << (16 - width
)) - 1);
185 old_bitmap
.Planes
[0] = (PLANEPTR
)p
;
186 old_bitmap
.Planes
[1] = (PLANEPTR
)q
;
187 for (k
= 0; k
< height
; ++k
) {
188 *p
++ = AROS_WORD2BE(*s
++ & mask
);
189 *q
++ = AROS_WORD2BE(*s
++ & mask
);
193 bsa
.bsa_SrcBitMap
= &old_bitmap
;
194 bsa
.bsa_SrcWidth
= width
;
195 bsa
.bsa_SrcHeight
= height
;
197 bsa
.bsa_SrcBitMap
= bitmap
;
198 bsa
.bsa_SrcWidth
= GetBitMapAttr(bitmap
, BMA_WIDTH
);
199 bsa
.bsa_SrcHeight
= GetBitMapAttr(bitmap
, BMA_HEIGHT
);
200 if (have_OutputHeight
) {
201 if (height
> bsa
.bsa_SrcHeight
)
204 height
= bsa
.bsa_SrcHeight
;
206 /* This is a part of experimental truecolor pointer support.
208 Check if the source bitmap is a HIDD bitmap. If so, we do
209 not specify pixelformat and take if from original bitmap
211 In fact the whole trick is a temporary hack. Old display
212 drivers will fail to set or display pointer sprite if
213 the supplied bitmap is not in LUT8 format. This is wrong
214 by itself and needs to be fixed. */
215 if (IS_HIDD_BM(bitmap
)) {
221 D(bug("[AllocSpriteData] Source bitmap depth: %u\n", GetBitMapAttr(bsa
.bsa_SrcBitMap
, BMA_DEPTH
)));
222 PRINT_PIXFMT(bsa
.bsa_SrcBitMap
);
223 PRINT_BITMAP(bsa
.bsa_SrcBitMap
, 8, 8);
225 sprite
= AllocVec(sizeof(*sprite
), MEMF_PUBLIC
| MEMF_CLEAR
);
226 if (NULL
!= sprite
) {
228 D(bug("Source width %u Source height %u Sprite width %u Sprite height %u XReplication %u YReplication %u\n", bsa
.bsa_SrcWidth
, bsa
.bsa_SrcHeight
, width
, height
, xrep
, yrep
));
230 bsa
.bsa_XDestFactor
= SCALE_NORMAL
<< xrep
;
232 bsa
.bsa_XDestFactor
= SCALE_NORMAL
>> (-xrep
);
236 bsa
.bsa_YDestFactor
= SCALE_NORMAL
<< yrep
;
238 bsa
.bsa_YDestFactor
= SCALE_NORMAL
>> (-yrep
);
241 bsa
.bsa_XSrcFactor
= SCALE_NORMAL
;
242 bsa
.bsa_YSrcFactor
= SCALE_NORMAL
;
243 /* Graphics drivers expect mouse pointer bitmap in LUT8 format, so we give it */
244 bsa
.bsa_DestBitMap
= AllocBitMap(width
, height
, 8, BMF_CLEAR
|pixfmt
, friend_bm
);
245 if (bsa
.bsa_DestBitMap
) {
248 sprite
->es_SimpleSprite
.height
= height
;
249 sprite
->es_SimpleSprite
.x
= 0;
250 sprite
->es_SimpleSprite
.y
= 0;
251 sprite
->es_SimpleSprite
.num
= 0;
252 sprite
->es_wordwidth
= width
>> 4;
253 sprite
->es_flags
= 0;
254 sprite
->es_BitMap
= bsa
.bsa_DestBitMap
;
256 D(bug("[AllocSpriteData] Allocated sprite data 0x%08lX: bitmap 0x%08lX, height %u\n", sprite
, sprite
->es_BitMap
, sprite
->es_SimpleSprite
.height
));
257 D(bug("[AllocSpriteData] Bitmap depth: %u\n", GetBitMapAttr(bsa
.bsa_DestBitMap
, BMA_DEPTH
)));
258 PRINT_PIXFMT(bsa
.bsa_DestBitMap
);
259 PRINT_BITMAP(bsa
.bsa_DestBitMap
, 8, 8);
265 if (have_OldDataFormat
&& planes_size
)
266 FreeMem(planes
, planes_size
);
271 } /* AllocSpriteDataA */