Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / graphics / gels_internal.c
blobdd8acb5fb03d12dc304464bb5a6ee69b51fdaa75
1 /*
2 Copyright © 1995-2016, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Internal function for improved gels handling.
6 Lang: english
7 */
8 #include <aros/debug.h>
10 #include <graphics/gels.h>
11 #include <graphics/rastport.h>
12 #include <exec/memory.h>
13 #include <proto/graphics.h>
14 #include <proto/exec.h>
15 #include "gels_internal.h"
16 #include "graphics_intern.h"
18 struct IntVSprite * _CreateIntVSprite(struct VSprite * vs,
19 struct RastPort * rp,
20 struct GfxBase * GfxBase)
22 struct IntVSprite * ivs = AllocMem(sizeof(struct IntVSprite),
23 MEMF_CLEAR);
24 if (NULL != ivs) {
25 ivs -> VSprite = vs;
26 vs->IntVSprite = ivs;
28 /*
29 * Don't call the validate function when rp=NULL, i.e. when
30 * called by InitGels().
32 if (NULL != rp)
33 _ValidateIntVSprite(ivs,
34 rp,
35 FALSE,
36 GfxBase);
38 return ivs;
42 VOID _DeleteIntVSprite(struct VSprite * vs,
43 struct GfxBase * GfxBase)
45 struct IntVSprite * ivs = vs->IntVSprite;
47 if (NULL != ivs) {
48 if (NULL != ivs->ImageData)
49 FreeBitMap(ivs->ImageData);
51 if (NULL != ivs->SaveBuffer)
52 FreeBitMap(ivs->SaveBuffer);
54 FreeMem(ivs, sizeof(struct IntVSprite));
55 vs->IntVSprite = NULL;
61 * Check whether the appearance of the VSprite has been changed
62 * somehow. If for example the Image Data has changed, then
63 * I will try to update the BitMap of the IntVSprite structure
64 * to the new image data.
66 BOOL _ValidateIntVSprite(struct IntVSprite * ivs,
67 struct RastPort * rp,
68 BOOL force_change,
69 struct GfxBase * GfxBase)
71 struct VSprite * vs = ivs->VSprite;
73 /* We don't support a depth > 32 currently */
74 if (vs->Depth > 32)
75 return FALSE;
78 * Check whether the ImageData pointer has changed
80 if (vs->ImageData != ivs->OrigImageData ||
81 force_change) {
82 /* Why the weird struct? Well, if we InitBitMap()
83 * a Depth > 8 on a plain BitMap, we'll scribble over
84 * our stack. Therefore we pad on some extra IPTRs
85 * to the end.
87 struct {
88 struct BitMap bm;
89 IPTR planes[32-8];
90 } x = {};
92 #if 0
93 kprintf("%s: Imagedata has changed (old:%p-new:%p)!\n",
94 __FUNCTION__,
95 vs->ImageData,
96 ivs->OrigImageData);
97 kprintf("PlanePick: %02x, rp->BitMap:%p\n",vs->PlanePick,rp->BitMap);
98 #endif
100 * Only need to get a new bitmap if
101 * something in the size of the bob has changed.
103 if ((ivs->Width != vs->Width ) ||
104 (ivs->Height != vs->Height) ||
105 (ivs->Depth != vs->Depth ) ) {
106 if (NULL != ivs->ImageData)
107 FreeBitMap(ivs->ImageData);
109 if (NULL != ivs->SaveBuffer)
110 FreeBitMap(ivs->SaveBuffer);
112 * Now get a new bitmap
115 ivs->ImageData = AllocBitMap(vs->Width<<4,
116 vs->Height,
117 vs->Depth,
118 BMF_CLEAR,
119 rp->BitMap);
121 ivs->SaveBuffer = AllocBitMap(vs->Width<<4,
122 vs->Height,
123 vs->Depth,
125 rp->BitMap);
126 ivs->Width = vs->Width;
127 ivs->Height = vs->Height;
128 ivs->Depth = vs->Depth;
131 ivs->OrigImageData = vs->ImageData;
134 * Blit the image data from the VSprite into the
135 * ImageData (BitMap) of the IntVSprite
137 InitBitMap(&x.bm,
138 ivs->Depth,
139 ivs->Width<<4,
140 ivs->Height);
143 UBYTE *imagedata = (UBYTE *)vs->ImageData;
144 WORD d, shift;
146 for (d = 0, shift = 1; d < 8; d++, shift *= 2)
148 if (vs->PlanePick & shift)
150 x.bm.Planes[d] = imagedata;
151 imagedata += (x.bm.Rows * x.bm.BytesPerRow);
153 else
155 x.bm.Planes[d] = (vs->PlaneOnOff & shift) ? (PLANEPTR)-1 : NULL;
160 BltBitMap(&x.bm,
163 ivs->ImageData,
166 ivs->Width << 4,
167 ivs->Height,
168 0x0c0,
169 vs->PlanePick,
170 NULL);
174 return TRUE;
178 * Erase the VSprite from the list and follow the clear path
179 * first, if necessary! This way of organizing the ClearPath
180 * makes it easy to implement RemIBob but it leads to a recursion!
181 * RemIBob could simply call this function here and then redraw
182 * all cleared Bobs.
183 * If a recursion is not what we want this can be easily
184 * changed.
187 void _ClearBobAndFollowClearPath(struct VSprite * CurVSprite,
188 struct RastPort * rp,
189 struct GfxBase * GfxBase)
192 * If the bob has not been drawn, yet, then don't do anything.
193 * If the bob has already been cleared, then also leave here!
194 * It does happen that this routine gets called for
195 * a sprite that has been cleared already.
197 if (0 != (CurVSprite->VSBob->Flags & (BWAITING|BOBNIX))) {
198 CurVSprite->VSBob->Flags &= ~BWAITING;
199 return;
202 if (NULL != CurVSprite->ClearPath) {
204 * Clear the next one first. (recursion!!!)
206 _ClearBobAndFollowClearPath(CurVSprite->ClearPath,
208 GfxBase);
209 CurVSprite->ClearPath = NULL;
214 * Only restore the background if the bob image
215 * that is currently there is to be replaced by
216 * the background. If SAVEBOB is set the user
217 * might want some kind of a brush effect.
220 if (0 == (CurVSprite->Flags & SAVEBOB)) {
221 if (0 != (CurVSprite->Flags & BACKSAVED)) {
222 BltBitMapRastPort(CurVSprite->IntVSprite->SaveBuffer,
226 CurVSprite->OldX,
227 CurVSprite->OldY,
228 CurVSprite->Width << 4,
229 CurVSprite->Height,
230 0x0c0);
231 CurVSprite->Flags &= ~BACKSAVED;
233 } /* if (0 != (CurVSprite->Flags & BACKSAVED)) */
234 else {
236 * No background was saved. So let's restore the
237 * standard background!
239 EraseRect(rp,
240 CurVSprite->OldX,
241 CurVSprite->OldY,
242 CurVSprite->OldX + ( CurVSprite->Width << 4 ) - 1,
243 CurVSprite->OldY + CurVSprite->Height - 1);
246 * Mark the BOB as cleared.
248 CurVSprite->VSBob->Flags |= BOBNIX;
249 } /* if (0 == (CurVSprite->Flags & SAVEBOB)) */