Re: [AD] proposal: draw_sprite_*_ex

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


On 2007-12-27, Milan Mimica <milan.mimica@xxxxxxxxxx> wrote:
>  Peter Wang wrote:
> > On 2007-10-07, Milan Mimica <milan.mimica@xxxxxxxxxx> wrote:
> >> DRAW_SPRITE_NO_FLIP | DRAW_SPRITE_H_FLIP Is the only open issue.
> >> Can't we just have DRAW_SPRITE_HV_FLIP and not allow or-ing?
> > I don't remember why I suggesting OR-ing, so I have no problem
> > with that.
> > The patch needs some reformatting.
> 
> 
>  Here is the reformatted and cleaned patch.
> 
>  Flipping mode flags are:
>  /* flipping modes for draw_sprite_ex() */
>  #define DRAW_SPRITE_NO_FLIP 0x0
>  #define DRAW_SPRITE_H_FLIP  0x1
>  #define DRAW_SPRITE_V_FLIP  0x2
>  #define DRAW_SPRITE_VH_FLIP 0x3
>  #define DRAW_SPRITE_HV_FLIP 0x3

I think having both VH and HV isn't worthwhile.  I can imagine searching for
HV_FLIP in the source and getting confused because it only refers to VH_FLIP.

>  - No or-ing (at least not between these).
>  - DRAW_SPRITE_NO_FLIP could be changed to DRAW_SPRITE_PLAIN but that's a 
>  minor thing.
>  - No docs.
>  - The patch is only for non-ASM version. That's the problem.
> 
>  Should we (in 4.3.10+):
>  a) remove the ASM version completely?

Yes.

>  b) just make the non-ASM version default?
> 
>  (b) is a lot easier to do. Although, it doesn't really fix anything. ASM and 
>  non-ASM would not be *API* compatible this time.

The asm code doesn't need to be removed immediately.


> Index: src/c/cdefs24.h
> ===================================================================
> --- src/c/cdefs24.h	(revision 9732)
> +++ src/c/cdefs24.h	(working copy)
> @@ -24,6 +24,7 @@
>  #define PTR_PER_PIXEL          3
>  #define OFFSET_PIXEL_PTR(p,x)  ((PIXEL_PTR) (p) + 3 * (x))
>  #define INC_PIXEL_PTR(p)       ((p) += 3)
> +#define INC_PIXEL_PTR_EX(p,d)  ((p) += 3 * d)
>  #define DEC_PIXEL_PTR(p)       ((p) -= 3)
>  
>  #define PUT_PIXEL(p,c)         bmp_write24((uintptr_t) (p), (c))
> @@ -48,6 +49,7 @@
>  #define DLS_BLENDER            BLENDER_FUNC
>  #define MAKE_DLS_BLENDER(a)    _blender_func24
>  #define DLS_BLEND(b,a,n)       ((*(b))(_blender_col_24, (n), (a)))
> +#define DLSX_BLEND(b,n)       ((*(b))(_blender_col_24, (n), _blender_alpha))

Align that with an extra space.


> Index: src/c/cdefs32.h
> ===================================================================
> --- src/c/cdefs32.h	(revision 9732)
> +++ src/c/cdefs32.h	(working copy)
> @@ -24,6 +24,7 @@
>  #define PTR_PER_PIXEL          1
>  #define OFFSET_PIXEL_PTR(p,x)  ((PIXEL_PTR) (p) + (x))
>  #define INC_PIXEL_PTR(p)       ((p)++)
> +#define INC_PIXEL_PTR_EX(p,d)  ((p) += d)

Maybe name this INC_PIXEL_PTR_N?  Ditto elsewhere.

>  #define DEC_PIXEL_PTR(p)       ((p)--)
>  
>  #define PUT_PIXEL(p,c)         bmp_write32((uintptr_t) (p), (c))
> @@ -49,6 +50,7 @@
>  #define DLS_BLENDER            BLENDER_FUNC
>  #define MAKE_DLS_BLENDER(a)    _blender_func32
>  #define DLS_BLEND(b,a,n)       ((*(b))(_blender_col_32, (n), (a)))
> +#define DLSX_BLEND(b,n)       ((*(b))(_blender_col_32, (n), _blender_alpha))
>  
>  /* Blender for poly_scanline_*_lit.  */
>  #define PS_BLENDER             BLENDER_FUNC
> @@ -75,10 +77,14 @@
>  #define FUNC_LINEAR_VLINE                   _linear_vline32
>  
>  #define FUNC_LINEAR_DRAW_SPRITE             _linear_draw_sprite32
> +#define FUNC_LINEAR_DRAW_SPRITE_EX          _linear_draw_sprite_ex32
>  #define FUNC_LINEAR_DRAW_256_SPRITE         _linear_draw_256_sprite32
>  #define FUNC_LINEAR_DRAW_SPRITE_V_FLIP      _linear_draw_sprite_v_flip32
> +#define FUNC_LINEAR_DRAW_SPRITE_V_FLIP_EX   _linear_draw_sprite_v_flip_ex32
>  #define FUNC_LINEAR_DRAW_SPRITE_H_FLIP      _linear_draw_sprite_h_flip32
> +#define FUNC_LINEAR_DRAW_SPRITE_H_FLIP_EX   _linear_draw_sprite_h_flip_ex32
>  #define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP     _linear_draw_sprite_vh_flip32
> +#define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP_EX  _linear_draw_sprite_vh_flip_ex32
>  #define FUNC_LINEAR_DRAW_TRANS_SPRITE       _linear_draw_trans_sprite32
>  #define FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE  _linear_draw_trans_rgba_sprite32
>  #define FUNC_LINEAR_DRAW_LIT_SPRITE         _linear_draw_lit_sprite32

> Index: src/c/cdefs16.h
> ===================================================================
> --- src/c/cdefs16.h	(revision 9732)
> +++ src/c/cdefs16.h	(working copy)
> @@ -24,6 +24,7 @@
>  #define PTR_PER_PIXEL          1
>  #define OFFSET_PIXEL_PTR(p,x)  ((PIXEL_PTR) (p) + (x))
>  #define INC_PIXEL_PTR(p)       ((p)++)
> +#define INC_PIXEL_PTR_EX(p,d)  ((p) += d)
>  #define DEC_PIXEL_PTR(p)       ((p)--)
>  
>  #define PUT_PIXEL(p,c)         bmp_write16((uintptr_t) (p), (c))
> @@ -37,7 +38,7 @@
>  
>  /* Blender for putpixel (DRAW_MODE_TRANS).  */
>  #define PP_BLENDER             BLENDER_FUNC
> -#define MAKE_PP_BLENDER(c)     _blender_func16
> +#define MAKE_PP_BLENDER(c)     (!_blender_func16 && (al_assert(__FILE__,__LINE__), 0), _blender_func16)

That's a bit ugly :-P

>  #define PP_BLEND(b,o,n)        ((*(b))((n), (o), _blender_alpha))
>  
>  /* Blender for draw_trans_*_sprite.  */
> @@ -49,6 +50,7 @@
>  #define DLS_BLENDER            BLENDER_FUNC
>  #define MAKE_DLS_BLENDER(a)    _blender_func16
>  #define DLS_BLEND(b,a,n)       ((*(b))(_blender_col_16, (n), (a)))
> +#define DLSX_BLEND(b,n)       ((*(b))(_blender_col_16, (n), _blender_alpha))

Alignment.

> Index: src/c/cspr.h
> ===================================================================
> --- src/c/cspr.h	(revision 9732)
> +++ src/c/cspr.h	(working copy)
> @@ -18,6 +18,138 @@
>  #ifndef __bma_cspr_h
>  #define __bma_cspr_h
>  

Please add a comment to describe this a bit.

> +void FUNC_LINEAR_DRAW_SPRITE_EX(BITMAP * dst, BITMAP * src, int dx, int dy, int mode, int flip)
> +{
> +   int x, y, w, h;
> +   int x_dir = 1, y_dir = 1;
> +   int dxbeg, dybeg;
> +   int sxbeg, sybeg;
> +   DLS_BLENDER lit_blender;
> +   DTS_BLENDER trans_blender;
> +
> +   ASSERT(dst);
> +   ASSERT(src);
> +
> +   if (flip == DRAW_SPRITE_V_FLIP) {
> +      y_dir = -1;
> +   }
> +   if (flip == DRAW_SPRITE_H_FLIP) {
> +      x_dir = -1;
> +   }
> +   if (flip == DRAW_SPRITE_VH_FLIP) {
> +      y_dir = -1;
> +      x_dir = -1;
> +   }
> +
> +   if (dst->clip) {
> +      int tmp;
> +
> +      tmp = dst->cl - dx;
> +      sxbeg = ((tmp < 0) ? 0 : tmp);

You can use MAX().

> +      dxbeg = sxbeg + dx;
> +
> +      tmp = dst->cr - dx;
> +      w = ((tmp > src->w) ? src->w : tmp) - sxbeg;

MIN()

> +      if (w <= 0)
> +	 return;

Expand the tab there.

> +
> +      if (flip == DRAW_SPRITE_H_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
> +          /* use backward drawing onto dst */
> +          sxbeg = src->w - (sxbeg + w);
> +          dxbeg += w - 1;
> +      }

That block is 4-space indented.

> +
> +      tmp = dst->ct - dy;
> +      sybeg = ((tmp < 0) ? 0 : tmp);
> +      dybeg = sybeg + dy;
> +
> +      tmp = dst->cb - dy;
> +      h = ((tmp > src->h) ? src->h : tmp) - sybeg;
> +      if (h <= 0)
> +	 return;
> +
> +      if (flip == DRAW_SPRITE_V_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
> +          /* use backward drawing onto dst */
> +          sybeg = src->h - (sybeg + h);
> +          dybeg += h - 1;
> +      }

Ditto.

> +   }
> +   else {
> +      w = src->w;
> +      h = src->h;
> +      sxbeg = 0;
> +      sybeg = 0;
> +      dxbeg = dx;
> +      if (flip == DRAW_SPRITE_H_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
> +         dxbeg = dx + w - 1;
> +      }
> +      dybeg = dy;
> +      if (flip == DRAW_SPRITE_V_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
> +         dybeg = dy + h - 1;
> +      }
> +   }
> +
> +   lit_blender = MAKE_DLS_BLENDER(0);
> +   trans_blender = MAKE_DTS_BLENDER();
> +
> +   if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
> +      bmp_select(dst);
> +
> +      for (y = 0; y < h; y++) {
> +	 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
> +
> +	 /* flipped if y_dir is -1 */
> +	 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
> +

Indentation below is screwed due to tabs.  Also, reformat the switch in the
usual way.

> +	 /* d is incremented by x_dir, -1 if flipped */
> +	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR_EX(d,x_dir), x--) {
> +	    unsigned long c = GET_MEMORY_PIXEL(s);
> +	    if (!IS_SPRITE_MASK(src, c)) {
> +	       switch(mode) {
> +		  case DRAW_SPRITE_NORMAL : break;
> +		  case DRAW_SPRITE_LIT : {
> +		     c = DLSX_BLEND(lit_blender, c);
> +		     break;
> +		  }
> +		  case DRAW_SPRITE_TRANS : {
> +		     c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
> +		     break;
> +		  }
> +	       }
> +	       PUT_PIXEL(d, c);
> +	    }
> +	 }
> +      }

> +
> +      bmp_unwrite_line(dst);
> +   }
> +   else {
> +      for (y = 0; y < h; y++) {
> +	 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
> +	 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
> +
> +	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR_EX(d,x_dir), x--) {
> +	    unsigned long c = GET_MEMORY_PIXEL(s);
> +	    if (!IS_SPRITE_MASK(src, c)) {
> +	       switch(mode) {
> +		  case DRAW_SPRITE_NORMAL : break;
> +		  case DRAW_SPRITE_LIT : {
> +		     c = DLSX_BLEND(lit_blender, c);
> +		     break;
> +		  }
> +		  case DRAW_SPRITE_TRANS : {
> +		     c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
> +		     break;
> +		  }
> +	       }
> +	       PUT_MEMORY_PIXEL(d, c);
> +	    }
> +	 }
> +      }

Ditto.

The same problems occur a few more times in the patch.

> Index: src/x/xvtable.c
> ===================================================================
> --- src/x/xvtable.c	(revision 9732)
> +++ src/x/xvtable.c	(working copy)
> @@ -33,10 +33,14 @@
>  static void _xwin_hline(BITMAP *dst, int dx1, int dy, int dx2, int color);
>  static void _xwin_rectfill(BITMAP *dst, int dx1, int dy1, int dx2, int dy2, int color);
>  static void _xwin_draw_sprite(BITMAP *dst, BITMAP *src, int dx, int dy);
> +static void _xwin_draw_sprite_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode, int flip);
>  static void _xwin_draw_256_sprite(BITMAP *dst, BITMAP *src, int dx, int dy);
>  static void _xwin_draw_sprite_v_flip(BITMAP *dst, BITMAP *src, int dx, int dy);
> +static void _xwin_draw_sprite_v_flip_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode);
>  static void _xwin_draw_sprite_h_flip(BITMAP *dst, BITMAP *src, int dx, int dy);
> +static void _xwin_draw_sprite_h_flip_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode);
>  static void _xwin_draw_sprite_vh_flip(BITMAP *dst, BITMAP *src, int dx, int dy);
> +static void _xwin_draw_sprite_vh_flip_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode);
>  static void _xwin_draw_trans_sprite(BITMAP *dst, BITMAP *src, int dx, int dy);
>  static void _xwin_draw_trans_rgba_sprite(BITMAP *dst, BITMAP *src, int dx, int dy);
>  static void _xwin_draw_lit_sprite(BITMAP *dst, BITMAP *src, int dx, int dy, int color);
> @@ -233,10 +237,14 @@
>     vtable->hfill = _xwin_hline;
>     vtable->rectfill = _xwin_rectfill;
>     vtable->draw_sprite = _xwin_draw_sprite;
> +   vtable->draw_sprite_ex = _xwin_draw_sprite_ex;
>     vtable->draw_256_sprite = _xwin_draw_256_sprite;
>     vtable->draw_sprite_v_flip = _xwin_draw_sprite_v_flip;
> +   vtable->draw_sprite_v_flip_ex = _xwin_draw_sprite_v_flip_ex;
>     vtable->draw_sprite_h_flip = _xwin_draw_sprite_h_flip;
> +   vtable->draw_sprite_h_flip_ex = _xwin_draw_sprite_h_flip_ex;
>     vtable->draw_sprite_vh_flip = _xwin_draw_sprite_vh_flip;
> +   vtable->draw_sprite_vh_flip_ex = _xwin_draw_sprite_vh_flip_ex;
>     vtable->draw_trans_sprite = _xwin_draw_trans_sprite;
>     vtable->draw_trans_rgba_sprite = _xwin_draw_trans_rgba_sprite;
>     vtable->draw_lit_sprite = _xwin_draw_lit_sprite;
> @@ -569,8 +577,26 @@
>     _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
>  }
>  
> +/* _xwin_draw_sprite_ex:
> + *  Wrapper for draw_sprite_ex.
> + */
> +static void _xwin_draw_sprite_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode, int flip)
> +{
> +   int dxbeg, dybeg, w, h;
>  
> +   if (_xwin_in_gfx_call) {
> +      _xwin_vtable.draw_sprite_ex(dst, src, dx, dy, mode, flip);
> +      return;
> +   }
>  
> +   CLIP_BOX(dst, dxbeg, dybeg, w, h, dx, dy, src->w, src->h)
> +
> +   _xwin_in_gfx_call = 1;
> +   _xwin_vtable.draw_sprite_ex(dst, src, dx, dy, mode, flip);
> +   _xwin_in_gfx_call = 0;
> +   _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
> +}
> +
>  /* _xwin_draw_256_sprite:
>   *  Wrapper for draw_256_sprite.
>   */
> @@ -613,8 +639,28 @@
>     _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
>  }
>  
> +/* _xwin_draw_sprite_v_flip:
> + *  Wrapper for draw_sprite_v_flip.
> + */
> +static void _xwin_draw_sprite_v_flip_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode)
> +{
> +   int dxbeg, dybeg, w, h;
>  
> +   if (_xwin_in_gfx_call) {
> +      _xwin_vtable.draw_sprite_v_flip_ex(dst, src, dx, dy, mode);
> +      return;
> +   }
>  
> +   CLIP_BOX(dst, dxbeg, dybeg, w, h, dx, dy, src->w, src->h)
> +
> +   _xwin_in_gfx_call = 1;
> +   _xwin_vtable.draw_sprite_v_flip_ex(dst, src, dx, dy, mode);
> +   _xwin_in_gfx_call = 0;
> +   _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
> +}
> +
> +
> +
>  /* _xwin_draw_sprite_h_flip:
>   *  Wrapper for draw_sprite_h_flip.
>   */
> @@ -635,8 +681,26 @@
>     _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
>  }
>  
> +/* _xwin_draw_sprite_h_flip_ex:
> + *  Wrapper for draw_sprite_h_flip_ex.
> + */
> +static void _xwin_draw_sprite_h_flip_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode)
> +{
> +   int dxbeg, dybeg, w, h;
>  
> +   if (_xwin_in_gfx_call) {
> +      _xwin_vtable.draw_sprite_h_flip_ex(dst, src, dx, dy, mode);
> +      return;
> +   }
>  
> +   CLIP_BOX(dst, dxbeg, dybeg, w, h, dx, dy, src->w, src->h)
> +
> +   _xwin_in_gfx_call = 1;
> +   _xwin_vtable.draw_sprite_h_flip_ex(dst, src, dx, dy, mode);
> +   _xwin_in_gfx_call = 0;
> +   _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
> +}
> +
>  /* _xwin_draw_sprite_vh_flip:
>   *  Wrapper for draw_sprite_vh_flip.
>   */
> @@ -657,8 +721,26 @@
>     _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
>  }
>  
> +/* _xwin_draw_sprite_vh_flip_ex:
> + *  Wrapper for draw_sprite_vh_flip_ex.
> + */
> +static void _xwin_draw_sprite_vh_flip_ex(BITMAP *dst, BITMAP *src, int dx, int dy, int mode)
> +{
> +   int dxbeg, dybeg, w, h;
>  
> +   if (_xwin_in_gfx_call) {
> +      _xwin_vtable.draw_sprite_vh_flip_ex(dst, src, dx, dy, mode);
> +      return;
> +   }
>  
> +   CLIP_BOX(dst, dxbeg, dybeg, w, h, dx, dy, src->w, src->h)
> +
> +   _xwin_in_gfx_call = 1;
> +   _xwin_vtable.draw_sprite_vh_flip_ex(dst, src, dx, dy, mode);
> +   _xwin_in_gfx_call = 0;
> +   _xwin_update_video_bitmap(dst, dxbeg, dybeg, w, h);
> +}
> +
>  /* _xwin_draw_trans_sprite:
>   *  Wrapper for draw_trans_sprite.
>   */

> Index: examples/extrans2.c
> ===================================================================
> --- examples/extrans2.c	(revision 0)
> +++ examples/extrans2.c	(revision 0)
> @@ -0,0 +1,241 @@
> +/*
> + *   Example program for the Allegro library, by Jon Rafkind.
> + *
> + *   This program demonstrates how to draw trans and lit sprites and flip them
> + *   at the same time, using draw_trans_sprite_ex() function.
> + *   It displays several images moving around using different drawing modes
> + *   while you can press space key to change the flipping mode.
> + */
> +
> +#include <stdio.h>
> +
> +#include <allegro.h>
> +
> +#define UP 0
> +#define LEFT 1
> +#define DOWN 2
> +#define RIGHT 3
> +
> +/* define the number of sprites that will be displayed */
> +#define SPRITE_COUNT 20
> +
> +
> +/* define our sprite */
> +typedef struct {
> +   int x;
> +   int y;
> +
> +   /* 0 = up, 1 = left, 2 = down, 3 = right */
> +   int direction;

Might as well use an enum DIR and delete the comment.

> +
> +   /* what order to draw this sprite at, lower before higher */
> +   int level;
> +
> +   /* SPRITE_NORMAL, SPRITE_TRANS, or SPRITE_LIT */
> +   int draw_type;
> +} sprite;

Name this SPRITE to avoid confusion with a variable named sprite.

> +
> +
> +/* puts the sprite somewhere on the screen and sets its initial state */
> +void setup_sprite(sprite *s, int i)
> +{
> +   switch (i % 4) {
> +      case 0 : {
> +         s->x = -100 + i * 50;
> +         s->y = 40 + (i % 3) * 100;
> +         s->direction = RIGHT;
> +         s->draw_type = DRAW_SPRITE_NORMAL;
> +         s->level = 0;
> +         break;
> +      }
> +      case 1 : {
> +         s->x = 640 + 100 - i * 70;
> +         s->y = 50 + (i % 3) * 110;
> +         s->direction = LEFT;
> +         s->draw_type = DRAW_SPRITE_TRANS;
> +         s->level = 1;
> +         break;
> +      }
> +      case 2 : {
> +         s->x = 90 + (i % 3) * 200;
> +         s->y = -100 + i * 70;
> +         s->direction = DOWN;
> +         s->draw_type = DRAW_SPRITE_LIT;
> +         s->level = 2;
> +         break;
> +      }
> +      case 3 : {
> +         s->x = 50 + (i % 3) * 200;
> +         s->y = 480 + 100 - i * 70;
> +         s->direction = UP;
> +         s->draw_type = DRAW_SPRITE_TRANS;
> +         s->level = 3;
> +         break;
> +      }
> +   }
> +}
> +
> +
> +/* used by sort function to compare sprites */
> +int compare(AL_CONST void * a, AL_CONST void * b) {

Name this compare_sprite.  Move the opening brace down, here and elsewhere.

> +   sprite * s1 = (sprite *)a;
> +   sprite * s2 = (sprite *)b;
> +   if (s1->level < s2->level) {
> +      return -1;
> +   }
> +   if (s1->level > s2->level) {
> +      return 1;
> +   }
> +   return 0;
> +}

You can write:

    return s1->level - s2->level;


Peter





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