Re: [AD] getpixel conflict with alpha blended sprites

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Eric Botcazou wrote:
That said, changing getpixel() woud probably be too damaging at this point and... I also note that we never promised to return -1 _only_ when the point lies outside the bitmap ;-)

Yes, that's exactly my point of view too: we can't change the current behavior, and it's not _that_ bad as long as it's documented and there is an alternative.

So I agree to your proposition for a warning and a new helper function, which can be made inline.

OK, what about this patch?

Possible caveats: the comparisons assume 2's complement arithmetic for optimization (what is our policy there?), and the function name may not be optimal. Plus Eric sent a patch for a new clipping API just as I was going to press "Send", and I haven't checked if the two patches collide.

--
Sven
Index: docs/src/allegro._tx
===================================================================
RCS file: /cvsroot/alleg/allegro/docs/src/allegro._tx,v
retrieving revision 1.198
diff -u -r1.198 allegro._tx
--- docs/src/allegro._tx	17 Nov 2003 13:18:32 -0000	1.198
+++ docs/src/allegro._tx	22 Nov 2003 17:31:38 -0000
@@ -3677,6 +3677,7 @@
    Shortcut version of release_bitmap(screen);
 
 @@void @set_clip(BITMAP *bitmap, int x1, int y1, int x2, int y2);
+@xref is_inside_clip
 @eref ex12bit, excamera
    Each bitmap has an associated clipping rectangle, which is the area of 
    the image that it is ok to draw on. Nothing will be drawn to positions 
@@ -3690,7 +3691,8 @@
 
    There's no get_clip like function. To obtain the clipping rectangle of an
    existing bitmap, check the appropiate fields of the BITMAP structure
-   holding it.
+   holding it. The is_inside_clip() function determines if a given point is
+   inside the clipping region.
 
 
 
@@ -4201,7 +4203,7 @@
 drawing mode and the clipping rectangle of the destination bitmap.
 
 @@void @putpixel(BITMAP *bmp, int x, int y, int color);
-@domain.hid getpixel, _putpixel, drawing_mode
+@xref getpixel, _putpixel, drawing_mode, is_inside_clip
 @eref ex12bit, exalpha, exflame, exjoy, exstars, exswitch
    Writes a pixel to the specified position in the bitmap, using the current 
    drawing mode and the bitmap's clipping rectangle.
@@ -4219,20 +4221,31 @@
    mode.
 
 @@int @getpixel(BITMAP *bmp, int x, int y);
-@domain.hid putpixel, _getpixel
+@xref putpixel, _getpixel, is_inside_clip
 @eref ex12bit, exalpha, exflame, exlights
-   Reads a pixel from point x, y in the bitmap. Returns -1 if the point lies 
-   outside the bitmap.
+   Reads a pixel from point x, y in the bitmap. Returns -1 if the
+   point lies outside the bitmap (ignoring the clipping region).
+   Beware that -1 is also a legal return value for 32-bit pixels with
+   r=g=b=a=255. See is_inside_clip() for a more robust way of
+   detecting if a pixel is inside the bitmap.
 
 @@int @_getpixel(BITMAP *bmp, int x, int y);
 @@int @_getpixel15(BITMAP *bmp, int x, int y);
 @@int @_getpixel16(BITMAP *bmp, int x, int y);
 @@int @_getpixel24(BITMAP *bmp, int x, int y);
 @@int @_getpixel32(BITMAP *bmp, int x, int y);
-@domain.hid getpixel
+@xref getpixel, is_inside_clip
    Faster inline versions of getpixel() for specific color depths. These 
    won't work in mode-X, and don't do any clipping, so you must make sure 
    the point lies inside the bitmap.
+
+@@int @is_inside_clip(BITMAP *bmp, int x, int y, int clip);
+@xref getpixel, set_clip
+   Returns nonzero if point x, y is inside the BITMAP. If clip is
+   TRUE, compares with the current clipping rectangle (using the
+   cl, cr, ct, cb fields of the BITMAP structure). Otherwise, compares
+   with the actual dimensions of the BITMAP (using the w, h fields of
+   the BITMAP structure).
 
 @@void @vline(BITMAP *bmp, int x, int y1, int y2, int color);
 @xref hline, line, drawing_mode
Index: include/allegro/inline/gfx.inl
===================================================================
RCS file: /cvsroot/alleg/allegro/include/allegro/inline/gfx.inl,v
retrieving revision 1.5
diff -u -r1.5 gfx.inl
--- include/allegro/inline/gfx.inl	31 Oct 2002 12:56:24 -0000	1.5
+++ include/allegro/inline/gfx.inl	22 Nov 2003 17:31:38 -0000
@@ -182,6 +182,18 @@
 })
 
 
+AL_INLINE(int, is_inside_clip, (BITMAP *bmp, int x, int y, int clip),
+{
+   ASSERT(bmp);
+
+   if (clip)
+      return ((unsigned)(x-bmp->cl)) < (unsigned)(bmp->cr-bmp->cl)
+	     && ((unsigned)(y-bmp->ct)) < (unsigned)(bmp->cb-bmp->ct);
+   else
+      return ((unsigned)x) < bmp->w && ((unsigned)y) < bmp->h;
+})
+
+
 
 #ifdef ALLEGRO_MPW
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/