Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / graphics / allocspritedataa.c
blobf7a2a1eb489ac966ddb46a347cf2bc2a7d9db4f1
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function AllocSpriteDataA()
6 Lang: english
7 */
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>
21 #include <string.h>
22 #include "gfxfuncsupport.h"
23 #include "graphics_intern.h"
25 #if DEBUG
27 #define PRINT_PIXFMT(bitmap) \
28 if (IS_HIDD_BM(bitmap)) {\
29 OOP_Object *pf; \
30 IPTR stdpf; \
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); \
38 #else
39 #define PRINT_PIXFMT(bitmap)
40 #endif
42 #if DEBUG > 1
44 #define PRINT_BITMAP(bitmap, xmax, ymax) \
45 bug("[AllocSpriteData] Bitmap contents:\n"); \
46 { \
47 OOP_Object *bm = OBTAIN_HIDD_BM(bitmap); \
48 ULONG x, y; \
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); \
55 } \
56 bug("\n"); \
57 } \
58 RELEASE_HIDD_BM(bm, bitmap); \
61 #else
62 #define PRINT_BITMAP(bitmap, xmax, ymax)
63 #endif
65 /*****************************************************************************
67 NAME */
68 #include <proto/graphics.h>
70 AROS_LH2(struct ExtSprite *, AllocSpriteDataA,
72 /* SYNOPSIS */
73 AROS_LHA(struct BitMap *, bitmap, A2),
74 AROS_LHA(struct TagItem *, tagList, A1),
76 /* LOCATION */
77 struct GfxBase *, GfxBase, 170, Graphics)
79 /* FUNCTION
81 INPUTS
82 bitmap - pointer to a bitmap. This bitmap provides the source data
83 for the sprite image
84 tags - pointer to a taglist
86 TAGS
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)
100 RESULT
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.
106 NOTES
108 EXAMPLE
110 BUGS
112 SEE ALSO
114 INTERNALS
116 HISTORY
119 ******************************************************************************/
121 AROS_LIBFUNC_INIT
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;
130 ULONG height = 0;
131 ULONG width = 16;
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) {
145 case SPRITEA_Width:
146 width = tag->ti_Data;
147 break;
149 case SPRITEA_XReplication:
150 xrep = tag->ti_Data;
151 break;
153 case SPRITEA_YReplication:
154 yrep = tag->ti_Data;
155 break;
157 case SPRITEA_OutputHeight:
158 height = tag->ti_Data;
159 have_OutputHeight = TRUE;
160 break;
162 /* Currently we don't support this */
163 case SPRITEA_Attached:
164 return 0;
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;
175 UWORD k, mask;
177 InitBitMap(&old_bitmap, 2, 16, height2);
178 planes_size = height2 * sizeof(UWORD) * 2;
179 planes = AllocMem(planes_size, MEMF_CLEAR | MEMF_CHIP);
180 if (!planes)
181 return NULL;
182 p = planes;
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);
191 height = height2;
192 width = 16;
193 bsa.bsa_SrcBitMap = &old_bitmap;
194 bsa.bsa_SrcWidth = width;
195 bsa.bsa_SrcHeight = height;
196 } else {
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)
202 return NULL;
203 } else
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
210 instead.
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)) {
216 friend_bm = bitmap;
217 pixfmt = 0;
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));
229 if (xrep > 0) {
230 bsa.bsa_XDestFactor = SCALE_NORMAL << xrep;
231 } else {
232 bsa.bsa_XDestFactor = SCALE_NORMAL >> (-xrep);
235 if (yrep > 0) {
236 bsa.bsa_YDestFactor = SCALE_NORMAL << yrep;
237 } else {
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) {
246 BitMapScale(&bsa);
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);
260 } else {
261 FreeVec(sprite);
262 sprite = NULL;
265 if (have_OldDataFormat && planes_size)
266 FreeMem(planes, planes_size);
268 return sprite;
270 AROS_LIBFUNC_EXIT
271 } /* AllocSpriteDataA */