[AD] proposal: draw_sprite_*_ex

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


Proposal: The addition of new functions, draw_sprite_ex, draw_sprite_h_flip_ex, draw_sprite_v_flip_ex, draw_sprite_vh_flip_ex, which act as their non-ex counterparts but with the addition of a parameter to specify the modification of the pixels as they are drawn. This last parameter can be one of the following
   SPRITE_NORMAL - draw sprite as normal
   SPRITE_TRANS - draw trans sprite
   SPRITE_LIT - draw lit sprite

Other modes can easily be added as long as the mode depends on existing parameters + global state only. The prototypes for these functions are

draw_sprite_*_ex( BITMAP *bmp, BITMAP *sprite, int x, int y, int mode );

Pros: usage of _flip functions without the need for a temporary bitmap( performance ). can be cleanly added to cspr.h Cons: don't have asm versions of these functions for the "optimized" routines in win32.

Attached is ex.patch against the latest svn for the 4.2 branch and an example program that shows the use of the functions.

Notes: the rotate* functions can probably be altered in a similar way but I only took a quick look at the code and didn't try to hack it yet.

Index: src/vtable24.c
===================================================================
--- src/vtable24.c	(revision 7838)
+++ src/vtable24.c	(working copy)
@@ -91,7 +91,11 @@
    _soft_triangle3d,
    _soft_triangle3d_f,
    _soft_quad3d,
-   _soft_quad3d_f
+   _soft_quad3d_f,
+   _linear_draw_sprite_ex24,
+   _linear_draw_sprite_h_flip_ex24,
+   _linear_draw_sprite_v_flip_ex24,
+   _linear_draw_sprite_vh_flip_ex24
 };
 
 
Index: src/vtable16.c
===================================================================
--- src/vtable16.c	(revision 7838)
+++ src/vtable16.c	(working copy)
@@ -91,7 +91,11 @@
    _soft_triangle3d,
    _soft_triangle3d_f,
    _soft_quad3d,
-   _soft_quad3d_f
+   _soft_quad3d_f,
+   _linear_draw_sprite_ex16,
+   _linear_draw_sprite_h_flip_ex16,
+   _linear_draw_sprite_v_flip_ex16,
+   _linear_draw_sprite_vh_flip_ex16
 };
 
 
Index: src/c/cdefs24.h
===================================================================
--- src/c/cdefs24.h	(revision 7838)
+++ src/c/cdefs24.h	(working copy)
@@ -48,6 +48,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))
 
 /* Blender for RGBA sprites.  */
 #define RGBA_BLENDER           BLENDER_FUNC
@@ -79,10 +80,14 @@
 #define FUNC_LINEAR_VLINE                   _linear_vline24
 
 #define FUNC_LINEAR_DRAW_SPRITE             _linear_draw_sprite24
+#define FUNC_LINEAR_DRAW_SPRITE_EX          _linear_draw_sprite_ex24
 #define FUNC_LINEAR_DRAW_256_SPRITE         _linear_draw_256_sprite24
 #define FUNC_LINEAR_DRAW_SPRITE_V_FLIP      _linear_draw_sprite_v_flip24
+#define FUNC_LINEAR_DRAW_SPRITE_V_FLIP_EX   _linear_draw_sprite_v_flip_ex24
 #define FUNC_LINEAR_DRAW_SPRITE_H_FLIP      _linear_draw_sprite_h_flip24
+#define FUNC_LINEAR_DRAW_SPRITE_H_FLIP_EX   _linear_draw_sprite_h_flip_ex24
 #define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP     _linear_draw_sprite_vh_flip24
+#define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP_EX  _linear_draw_sprite_vh_flip_ex24
 #define FUNC_LINEAR_DRAW_TRANS_SPRITE       _linear_draw_trans_sprite24
 #define FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE  _linear_draw_trans_rgba_sprite24
 #define FUNC_LINEAR_DRAW_LIT_SPRITE         _linear_draw_lit_sprite24
Index: src/c/cdefs32.h
===================================================================
--- src/c/cdefs32.h	(revision 7838)
+++ src/c/cdefs32.h	(working copy)
@@ -49,6 +49,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 +76,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/cdefs15.h
===================================================================
--- src/c/cdefs15.h	(revision 7838)
+++ src/c/cdefs15.h	(working copy)
@@ -48,6 +48,7 @@
 #define DLS_BLENDER            BLENDER_FUNC
 #define MAKE_DLS_BLENDER(a)    _blender_func15
 #define DLS_BLEND(b,a,n)       ((*(b))(_blender_col_15, (n), (a)))
+#define DLSX_BLEND(b,n)       ((*(b))(_blender_col_15, (n), _blender_alpha))
 
 /* Blender for RGBA sprites.  */
 #define RGBA_BLENDER           BLENDER_FUNC
@@ -79,10 +80,14 @@
 #define FUNC_LINEAR_VLINE                   _linear_vline15
 
 #define FUNC_LINEAR_DRAW_SPRITE             _linear_draw_sprite15
+#define FUNC_LINEAR_DRAW_SPRITE_EX          _linear_draw_sprite_ex15
 #define FUNC_LINEAR_DRAW_256_SPRITE         _linear_draw_256_sprite15
 #define FUNC_LINEAR_DRAW_SPRITE_V_FLIP      _linear_draw_sprite_v_flip15
+#define FUNC_LINEAR_DRAW_SPRITE_V_FLIP_EX   _linear_draw_sprite_v_flip_ex15
 #define FUNC_LINEAR_DRAW_SPRITE_H_FLIP      _linear_draw_sprite_h_flip15
+#define FUNC_LINEAR_DRAW_SPRITE_H_FLIP_EX   _linear_draw_sprite_h_flip_ex15
 #define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP     _linear_draw_sprite_vh_flip15
+#define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP_EX  _linear_draw_sprite_vh_flip_ex15
 #define FUNC_LINEAR_DRAW_TRANS_SPRITE       _linear_draw_trans_sprite15
 #define FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE  _linear_draw_trans_rgba_sprite15
 #define FUNC_LINEAR_DRAW_LIT_SPRITE         _linear_draw_lit_sprite15
Index: src/c/cdefs16.h
===================================================================
--- src/c/cdefs16.h	(revision 7838)
+++ src/c/cdefs16.h	(working copy)
@@ -37,7 +37,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)
 #define PP_BLEND(b,o,n)        ((*(b))((n), (o), _blender_alpha))
 
 /* Blender for draw_trans_*_sprite.  */
@@ -49,6 +49,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))
 
 /* Blender for RGBA sprites.  */
 #define RGBA_BLENDER           BLENDER_FUNC
@@ -80,10 +81,14 @@
 #define FUNC_LINEAR_VLINE                   _linear_vline16
 
 #define FUNC_LINEAR_DRAW_SPRITE             _linear_draw_sprite16
+#define FUNC_LINEAR_DRAW_SPRITE_EX          _linear_draw_sprite_ex16
 #define FUNC_LINEAR_DRAW_256_SPRITE         _linear_draw_256_sprite16
 #define FUNC_LINEAR_DRAW_SPRITE_V_FLIP      _linear_draw_sprite_v_flip16
+#define FUNC_LINEAR_DRAW_SPRITE_V_FLIP_EX   _linear_draw_sprite_v_flip_ex16
 #define FUNC_LINEAR_DRAW_SPRITE_H_FLIP      _linear_draw_sprite_h_flip16
+#define FUNC_LINEAR_DRAW_SPRITE_H_FLIP_EX   _linear_draw_sprite_h_flip_ex16
 #define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP     _linear_draw_sprite_vh_flip16
+#define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP_EX  _linear_draw_sprite_vh_flip_ex16
 #define FUNC_LINEAR_DRAW_TRANS_SPRITE       _linear_draw_trans_sprite16
 #define FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE  _linear_draw_trans_rgba_sprite16
 #define FUNC_LINEAR_DRAW_LIT_SPRITE         _linear_draw_lit_sprite16
Index: src/c/cspr.h
===================================================================
--- src/c/cspr.h	(revision 7838)
+++ src/c/cspr.h	(working copy)
@@ -18,12 +18,108 @@
 #ifndef __bma_cspr_h
 #define __bma_cspr_h
 
+void FUNC_LINEAR_DRAW_SPRITE_EX( BITMAP * dst, BITMAP * src, int dx, int dy, int mode ){
+   int x, y, w, h;
+   int dxbeg, dybeg;
+   int sxbeg, sybeg;
+   DLS_BLENDER lit_blender;
+   DTS_BLENDER trans_blender;
+
+   ASSERT(dst);
+   ASSERT(src);
+
+   if (dst->clip) {
+      int tmp;
+
+      tmp = dst->cl - dx;
+      sxbeg = ((tmp < 0) ? 0 : tmp);
+      dxbeg = sxbeg + dx;
+
+      tmp = dst->cr - dx;
+      w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
+      if (w <= 0)
+	 return;
+
+      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;
+   }
+   else {
+      w = src->w;
+      h = src->h;
+      sxbeg = 0;
+      sybeg = 0;
+      dxbeg = dx;
+      dybeg = dy;
+   }
+
+   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);
+	 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case 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(dst->line[dybeg + y], dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+	                    case SPRITE_TRANS : {
+			    		c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
+					break;
+			    }
+			 }
+		    }
+	       PUT_MEMORY_PIXEL(d, c);
+	    }
+	 }
+      }
+   }
+}
+
 /* _linear_draw_sprite:
  *  Draws a sprite onto a linear bitmap at the specified x, y position,
  *  using a masked drawing mode where zero pixels are not output.
  */
-void FUNC_LINEAR_DRAW_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy)
-{
+void FUNC_LINEAR_DRAW_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy){
    int x, y, w, h;
    int dxbeg, dybeg;
    int sxbeg, sybeg;
@@ -96,7 +192,6 @@
 void FUNC_LINEAR_DRAW_SPRITE_END(void) { }
 
 
-
 /* _linear_draw_256_sprite:
  *  Draws a 256 coor sprite onto a linear bitmap at the specified x, y
  *  position, using a masked drawing mode where zero pixels are not output.
@@ -178,8 +273,111 @@
    }
 }
 
+/* _linear_draw_sprite_v_flip_ex:
+ *  Draws a sprite to a linear bitmap, flipping vertically.
+ */
+void FUNC_LINEAR_DRAW_SPRITE_V_FLIP_EX(BITMAP *dst, BITMAP *src, int dx, int dy, int mode )
+{
+   int x, y, w, h;
+   int dxbeg, dybeg;
+   int sxbeg, sybeg;
+   DLS_BLENDER lit_blender;
+   DTS_BLENDER trans_blender;
 
+   ASSERT(dst);
+   ASSERT(src);
 
+   if (dst->clip) {
+      int tmp;
+
+      tmp = dst->cl - dx;
+      sxbeg = ((tmp < 0) ? 0 : tmp);
+      dxbeg = sxbeg + dx;
+
+      tmp = dst->cr - dx;
+      w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
+      if (w <= 0)
+	 return;
+
+      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;
+
+      /* use backward drawing onto dst */
+      sybeg = src->h - (sybeg + h);
+      dybeg += h - 1;
+   }
+   else {
+      w = src->w;
+      h = src->h;
+      sxbeg = 0;
+      sybeg = 0;
+      dxbeg = dx;
+      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);
+	 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg - y), dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case 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(dst->line[dybeg - y], dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case SPRITE_TRANS : {
+			    		c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
+					break;
+			    }
+			 }
+		    }
+	       PUT_MEMORY_PIXEL(d, c);
+	    }
+	 }
+      }
+   }
+}
+
 /* _linear_draw_sprite_v_flip:
  *  Draws a sprite to a linear bitmap, flipping vertically.
  */
@@ -258,16 +456,96 @@
    }
 }
 
+/* _linear_draw_sprite_h_flip:
+ *  Draws a sprite to a linear bitmap, flipping horizontally.
+ */
+void FUNC_LINEAR_DRAW_SPRITE_H_FLIP(BITMAP *dst, BITMAP *src, int dx, int dy)
+{
 
+   int x, y, w, h;
+   int dxbeg, dybeg;
+   int sxbeg, sybeg;
 
+   ASSERT(dst);
+   ASSERT(src);
+
+   if (dst->clip) {
+      int tmp;
+
+      tmp = dst->cl - dx;
+      sxbeg = ((tmp < 0) ? 0 : tmp);
+      dxbeg = sxbeg + dx;
+
+      tmp = dst->cr - dx;
+      w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
+      if (w <= 0)
+	 return;
+
+      /* use backward drawing onto dst */
+      sxbeg = src->w - (sxbeg + w);
+      dxbeg += w - 1;
+
+      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;
+   }
+   else {
+      w = src->w;
+      h = src->h;
+      sxbeg = 0;
+      sybeg = 0;
+      dxbeg = dx + w - 1;
+      dybeg = dy;
+   }
+
+   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);
+	 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+	       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(dst->line[dybeg + y], dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+	       PUT_MEMORY_PIXEL(d, c);
+	    }
+	 }
+      }
+   }
+}
+
 /* _linear_draw_sprite_h_flip:
  *  Draws a sprite to a linear bitmap, flipping horizontally.
  */
-void FUNC_LINEAR_DRAW_SPRITE_H_FLIP(BITMAP *dst, BITMAP *src, int dx, int dy)
+void FUNC_LINEAR_DRAW_SPRITE_H_FLIP_EX(BITMAP *dst, BITMAP *src, int dx, int dy, int mode )
 {
+
    int x, y, w, h;
    int dxbeg, dybeg;
    int sxbeg, sybeg;
+   DLS_BLENDER lit_blender;
+   DTS_BLENDER trans_blender;
 
    ASSERT(dst);
    ASSERT(src);
@@ -306,6 +584,9 @@
       dybeg = dy;
    }
 
+   lit_blender = MAKE_DLS_BLENDER(0);
+   trans_blender = MAKE_DTS_BLENDER();
+
    if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
       bmp_select(dst);
 
@@ -316,6 +597,17 @@
 	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
 	    unsigned long c = GET_MEMORY_PIXEL(s);
 	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case SPRITE_TRANS : {
+			    		c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
+					break;
+			    }
+			 }
+		    }
 	       PUT_PIXEL(d, c);
 	    }
 	 }
@@ -331,6 +623,17 @@
 	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
 	    unsigned long c = GET_MEMORY_PIXEL(s);
 	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case SPRITE_TRANS : {
+			    		c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
+					break;
+			    }
+			 }
+		    }
 	       PUT_MEMORY_PIXEL(d, c);
 	    }
 	 }
@@ -338,8 +641,115 @@
    }
 }
 
+/* _linear_draw_sprite_vh_flip_ex:
+ *  Draws a sprite to a linear bitmap, flipping both vertically and horizontally.
+ */
+void FUNC_LINEAR_DRAW_SPRITE_VH_FLIP_EX(BITMAP *dst, BITMAP *src, int dx, int dy, int mode)
+{
+   int x, y, w, h;
+   int dxbeg, dybeg;
+   int sxbeg, sybeg;
+   DLS_BLENDER lit_blender;
+   DTS_BLENDER trans_blender;
 
+   ASSERT(dst);
+   ASSERT(src);
 
+   if (dst->clip) {
+      int tmp;
+
+      tmp = dst->cl - dx;
+      sxbeg = ((tmp < 0) ? 0 : tmp);
+      dxbeg = sxbeg + dx;
+
+      tmp = dst->cr - dx;
+      w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
+      if (w <= 0)
+	 return;
+
+      /* use backward drawing onto dst */
+      sxbeg = src->w - (sxbeg + w);
+      dxbeg += w - 1;
+
+      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;
+
+      /* use backward drawing onto dst */
+      sybeg = src->h - (sybeg + h);
+      dybeg += h - 1;
+   }
+   else {
+      w = src->w;
+      h = src->h;
+      sxbeg = 0;
+      sybeg = 0;
+      dxbeg = dx + w - 1;
+      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);
+	 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg - y), dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case 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(dst->line[dybeg - y], dxbeg);
+
+	 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
+	    unsigned long c = GET_MEMORY_PIXEL(s);
+	    if (!IS_SPRITE_MASK(src, c)) {
+		    switch( mode ){
+			    case SPRITE_NORMAL : break;
+			    case SPRITE_LIT : {
+					c = DLSX_BLEND(lit_blender, c);
+					break;
+			    case SPRITE_TRANS : {
+			    		c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
+					break;
+			    }
+			 }
+		    }
+	       PUT_MEMORY_PIXEL(d, c);
+	    }
+	 }
+      }
+   }
+}
+
 /* _linear_draw_sprite_vh_flip:
  *  Draws a sprite to a linear bitmap, flipping both vertically and horizontally.
  */
@@ -692,8 +1102,6 @@
    }
 }
 
-
-
 /* _linear_draw_character:
  *  For proportional font output onto a linear bitmap: uses the sprite as
  *  a mask, replacing all set pixels with the specified color.
Index: src/c/cdefs8.h
===================================================================
--- src/c/cdefs8.h	(revision 7838)
+++ src/c/cdefs8.h	(working copy)
@@ -49,6 +49,7 @@
 #define DLS_BLENDER            unsigned char*
 #define MAKE_DLS_BLENDER(a)    (color_map->data[(a) & 0xFF])
 #define DLS_BLEND(b,a,c)       ((b)[(c) & 0xFF])
+#define DLSX_BLEND(b,c)       ((b)[(c) & 0xFF])
 
 /* Blender for poly_scanline_*_lit.  */
 #define PS_BLENDER             COLOR_MAP*
@@ -74,10 +75,14 @@
 #define FUNC_LINEAR_VLINE                   _linear_vline8
 
 #define FUNC_LINEAR_DRAW_SPRITE             _linear_draw_sprite8
+#define FUNC_LINEAR_DRAW_SPRITE_EX          _linear_draw_sprite_ex8
 #define FUNC_LINEAR_DRAW_256_SPRITE         _linear_draw_256_sprite8
 #define FUNC_LINEAR_DRAW_SPRITE_V_FLIP      _linear_draw_sprite_v_flip8
+#define FUNC_LINEAR_DRAW_SPRITE_V_FLIP_EX   _linear_draw_sprite_v_flip_ex8
 #define FUNC_LINEAR_DRAW_SPRITE_H_FLIP      _linear_draw_sprite_h_flip8
+#define FUNC_LINEAR_DRAW_SPRITE_H_FLIP_EX   _linear_draw_sprite_h_flip_ex8
 #define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP     _linear_draw_sprite_vh_flip8
+#define FUNC_LINEAR_DRAW_SPRITE_VH_FLIP_EX  _linear_draw_sprite_vh_flip_ex8
 #define FUNC_LINEAR_DRAW_TRANS_SPRITE       _linear_draw_trans_sprite8
 #define FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE  _linear_draw_trans_rgba_sprite8
 #define FUNC_LINEAR_DRAW_LIT_SPRITE         _linear_draw_lit_sprite8
Index: src/vtable8.c
===================================================================
--- src/vtable8.c	(revision 7838)
+++ src/vtable8.c	(working copy)
@@ -91,7 +91,11 @@
    _soft_triangle3d,
    _soft_triangle3d_f,
    _soft_quad3d,
-   _soft_quad3d_f
+   _soft_quad3d_f,
+   _linear_draw_sprite_ex8,
+   _linear_draw_sprite_h_flip_ex8,
+   _linear_draw_sprite_v_flip_ex8,
+   _linear_draw_sprite_vh_flip_ex8
 };
 
 
Index: src/vtable32.c
===================================================================
--- src/vtable32.c	(revision 7838)
+++ src/vtable32.c	(working copy)
@@ -91,7 +91,11 @@
    _soft_triangle3d,
    _soft_triangle3d_f,
    _soft_quad3d,
-   _soft_quad3d_f
+   _soft_quad3d_f,
+   _linear_draw_sprite_ex32,
+   _linear_draw_sprite_h_flip_ex32,
+   _linear_draw_sprite_v_flip_ex32,
+   _linear_draw_sprite_vh_flip_ex32
 };
 
 
Index: src/vtable15.c
===================================================================
--- src/vtable15.c	(revision 7838)
+++ src/vtable15.c	(working copy)
@@ -91,7 +91,11 @@
    _soft_triangle3d,
    _soft_triangle3d_f,
    _soft_quad3d,
-   _soft_quad3d_f
+   _soft_quad3d_f,
+   _linear_draw_sprite_ex16,
+   _linear_draw_sprite_h_flip_ex16,
+   _linear_draw_sprite_v_flip_ex16,
+   _linear_draw_sprite_vh_flip_ex16
 };
 
 
Index: src/x/xvtable.c
===================================================================
--- src/x/xvtable.c	(revision 7838)
+++ 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 );
 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,25 @@
    _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 dxbeg, dybeg, w, h;
 
+   if (_xwin_in_gfx_call) {
+      _xwin_vtable.draw_sprite_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_ex(dst, src, dx, dy, mode);
+   _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 +638,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 +680,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 +720,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: makefile.lst
===================================================================
--- makefile.lst	(revision 7838)
+++ makefile.lst	(working copy)
@@ -564,6 +564,7 @@
 	examples/exswitch.c \
 	examples/extimer.c \
 	examples/extrans.c \
+	examples/extrans2.c \
 	examples/extruec.c \
 	examples/exunicod.c \
 	examples/exupdate.c \
@@ -614,7 +615,7 @@
 	examples/exstream \
 	examples/exswitch \
 	examples/extimer \
-	examples/extrans \
+	examples/extrans2 \
 	examples/extruec \
 	examples/exunicod \
 	examples/exupdate \
Index: include/allegro/gfx.h
===================================================================
--- include/allegro/gfx.h	(revision 7838)
+++ include/allegro/gfx.h	(working copy)
@@ -37,6 +37,9 @@
 #define GFX_AUTODETECT_WINDOWED        2
 #define GFX_SAFE                       AL_ID('S','A','F','E')
 
+#define SPRITE_NORMAL 0
+#define SPRITE_LIT 1
+#define SPRITE_TRANS 2
 
 /* Blender mode defines, for the gfx_driver->set_blender_mode() function */
 #define blender_mode_none            0
@@ -214,6 +217,11 @@
    AL_METHOD(void, triangle3d_f, (struct BITMAP *bmp, int type, struct BITMAP *texture, V3D_f *v1, V3D_f *v2, V3D_f *v3));
    AL_METHOD(void, quad3d, (struct BITMAP *bmp, int type, struct BITMAP *texture, V3D *v1, V3D *v2, V3D *v3, V3D *v4));
    AL_METHOD(void, quad3d_f, (struct BITMAP *bmp, int type, struct BITMAP *texture, V3D_f *v1, V3D_f *v2, V3D_f *v3, V3D_f *v4));
+
+   AL_METHOD(void, draw_sprite_ex, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int mode ));
+   AL_METHOD(void, draw_sprite_h_flip_ex, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int mode ));
+   AL_METHOD(void, draw_sprite_v_flip_ex, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int mode ));
+   AL_METHOD(void, draw_sprite_vh_flip_ex, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int mode ));
 } GFX_VTABLE;
 
 
Index: include/allegro/internal/aintern.h
===================================================================
--- include/allegro/internal/aintern.h	(revision 7838)
+++ include/allegro/internal/aintern.h	(working copy)
@@ -541,9 +541,13 @@
 AL_FUNC(void, _linear_vline8, (BITMAP *bmp, int x, int y_1, int y2, int color));
 AL_FUNC(void, _linear_hline8, (BITMAP *bmp, int x1, int y, int x2, int color));
 AL_FUNC(void, _linear_draw_sprite8, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_ex8, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_v_flip8, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_v_flip_ex8, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_h_flip8, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_h_flip_ex8, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_vh_flip8, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_vh_flip_ex8, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_trans_sprite8, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_lit_sprite8, (BITMAP *bmp, BITMAP *sprite, int x, int y, int color));
 AL_FUNC(void, _linear_draw_rle_sprite8, (BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y));
@@ -576,10 +580,14 @@
 AL_FUNC(void, _linear_vline16, (BITMAP *bmp, int x, int y_1, int y2, int color));
 AL_FUNC(void, _linear_hline16, (BITMAP *bmp, int x1, int y, int x2, int color));
 AL_FUNC(void, _linear_draw_sprite16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_ex16, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_256_sprite16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_sprite_v_flip16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_v_flip_ex16, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_h_flip16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_h_flip_ex16, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_vh_flip16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_vh_flip_ex16, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_trans_sprite16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_trans_rgba_sprite16, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_lit_sprite16, (BITMAP *bmp, BITMAP *sprite, int x, int y, int color));
@@ -603,10 +611,14 @@
 AL_FUNC(void, _linear_vline24, (BITMAP *bmp, int x, int y_1, int y2, int color));
 AL_FUNC(void, _linear_hline24, (BITMAP *bmp, int x1, int y, int x2, int color));
 AL_FUNC(void, _linear_draw_sprite24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_ex24, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_256_sprite24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_sprite_v_flip24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_v_flip_ex24, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_h_flip24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_h_flip_ex24, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_vh_flip24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_vh_flip_ex24, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_trans_sprite24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_trans_rgba_sprite24, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_lit_sprite24, (BITMAP *bmp, BITMAP *sprite, int x, int y, int color));
@@ -630,10 +642,14 @@
 AL_FUNC(void, _linear_vline32, (BITMAP *bmp, int x, int y_1, int y2, int color));
 AL_FUNC(void, _linear_hline32, (BITMAP *bmp, int x1, int y, int x2, int color));
 AL_FUNC(void, _linear_draw_sprite32, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_ex32, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_256_sprite32, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_sprite_v_flip32, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_v_flip_ex32, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_h_flip32, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_h_flip_ex32, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_sprite_vh_flip32, (BITMAP *bmp, BITMAP *sprite, int x, int y));
+AL_FUNC(void, _linear_draw_sprite_vh_flip_ex32, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode));
 AL_FUNC(void, _linear_draw_trans_sprite32, (BITMAP *bmp, BITMAP *sprite, int x, int y));
 AL_FUNC(void, _linear_draw_lit_sprite32, (BITMAP *bmp, BITMAP *sprite, int x, int y, int color));
 AL_FUNC(void, _linear_draw_rle_sprite32, (BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y));
Index: include/allegro/inline/draw.inl
===================================================================
--- include/allegro/inline/draw.inl	(revision 7838)
+++ include/allegro/inline/draw.inl	(working copy)
@@ -249,7 +249,25 @@
    }
 })
 
+AL_INLINE(void, draw_sprite_ex, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode),
+{
+   ASSERT(bmp);
+   ASSERT(sprite);
 
+      ASSERT(bmp->vtable->color_depth == sprite->vtable->color_depth);
+      bmp->vtable->draw_sprite_ex(bmp, sprite, x, y, mode);
+	/*
+   if (sprite->vtable->color_depth == 8) {
+      bmp->vtable->draw_256_sprite(bmp, sprite, x, y);
+   }
+   else {
+      ASSERT(bmp->vtable->color_depth == sprite->vtable->color_depth);
+      bmp->vtable->draw_sprite(bmp, sprite, x, y);
+   }
+   */
+})
+
+
 AL_INLINE(void, draw_sprite_v_flip, (BITMAP *bmp, BITMAP *sprite, int x, int y),{
    ASSERT(bmp);
    ASSERT(sprite);
@@ -258,7 +276,14 @@
    bmp->vtable->draw_sprite_v_flip(bmp, sprite, x, y);
 })
 
+AL_INLINE(void, draw_sprite_v_flip_ex, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode),{
+   ASSERT(bmp);
+   ASSERT(sprite);
+   ASSERT(bmp->vtable->color_depth == sprite->vtable->color_depth);
 
+   bmp->vtable->draw_sprite_v_flip_ex(bmp, sprite, x, y, mode);
+})
+
 AL_INLINE(void, draw_sprite_h_flip, (BITMAP *bmp, BITMAP *sprite, int x, int y),{
    ASSERT(bmp);
    ASSERT(sprite);
@@ -267,7 +292,14 @@
    bmp->vtable->draw_sprite_h_flip(bmp, sprite, x, y);
 })
 
+AL_INLINE(void, draw_sprite_h_flip_ex, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode ),{
+   ASSERT(bmp);
+   ASSERT(sprite);
+   ASSERT(bmp->vtable->color_depth == sprite->vtable->color_depth);
 
+   bmp->vtable->draw_sprite_h_flip_ex(bmp, sprite, x, y, mode);
+})
+
 AL_INLINE(void, draw_sprite_vh_flip, (BITMAP *bmp, BITMAP *sprite, int x, int y),
 {
    ASSERT(bmp);
@@ -277,7 +309,15 @@
    bmp->vtable->draw_sprite_vh_flip(bmp, sprite, x, y);
 })
 
+AL_INLINE(void, draw_sprite_vh_flip_ex, (BITMAP *bmp, BITMAP *sprite, int x, int y, int mode),
+{
+   ASSERT(bmp);
+   ASSERT(sprite);
+   ASSERT(bmp->vtable->color_depth == sprite->vtable->color_depth);
 
+   bmp->vtable->draw_sprite_vh_flip_ex(bmp, sprite, x, y, mode);
+})
+
 AL_INLINE(void, draw_trans_sprite, (BITMAP *bmp, BITMAP *sprite, int x, int y),
 {
    ASSERT(bmp);
#include <stdio.h>
#include <allegro.h>

#define UP 0
#define LEFT 1
#define DOWN 2
#define RIGHT 3

typedef struct {
	int x;
	int y;

	/* 0 = up, 1 = left, 2 = down, 3 = right */
	int direction;

	/* what order to draw this sprite at, lower before higher */
	int level;

	/* SPRITE_NORMAL, SPRITE_TRANS, or SPRITE_LIT */
	int draw_type;
} sprite;

/* 0 = success, 1 = fail */
int init(){
	if ( allegro_init() != 0 ){
		return 1;
	}

	if ( install_timer() != 0 ){
		return 1;
	}

	if ( install_keyboard() != 0 ){
		return 1;
	}

	return 0;
}

void setupSprite( 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 = 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 = 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 = 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 = SPRITE_TRANS;
			s->level = 3;
			break;
		}
	}
}

int compare( const void * a, const void * b ){
	sprite * s1 = (sprite *)a;
	sprite * s2 = (sprite *)b;
	if ( s1->level < s2->level ){
		return -1;
	}
	if ( s1->level > s2->level ){
		return 1;
	}
	return 0;
}

void moveSprite( sprite * s ){
	switch ( s->direction ){
		case UP : {
			s->y--;
			if ( s->y < -64 ){
				s->y = 480;
			}
			break;
		}
		case DOWN : {
			s->y++;
			if ( s->y > 480 ){
				s->y = -64;
			}
			break;
		}
		case RIGHT : {
			s->x++;
			if ( s->x > 640 ){
				s->x = -64;
			}
			break;
		}
		case LEFT : {
			s->x--;
			if ( s->x < -64 ){
				s->x = 640;
			}
			break;
		}
	}
}

int main( int argc, char ** argv ){

	sprite sprites[ 20 ];
	BITMAP * work;
	BITMAP * pic;
	BITMAP * tmp;
	char buf[ 1024 ];
	char * filename;
	int mode = 0;
	int i;
	int hold_space = 0;

	if ( init() ){
		return 1;
	}

	set_color_depth( 16 );
	if ( set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0 ) != 0 ){
		if ( set_gfx_mode( GFX_SAFE, 640, 480, 0, 0 ) != 0 ){
			return 1;
		}
	}

	for ( i = 0; i < sizeof( sprites ) / sizeof( sprite ); i++ ){
		setupSprite( &sprites[ i ], i );
	}
	/* sort the sprites by drawing level */
	qsort( sprites, sizeof( sprites ) / sizeof( sprite ), sizeof( sprite ), compare );

	if ( argc > 1 ){
		filename = argv[ 1 ];
	} else {
		replace_filename(buf, argv[0], "allegro.pcx", sizeof(buf));
		filename = buf;
	}

	tmp = load_bitmap( filename, NULL );
	pic = create_bitmap( 64, 64 );
	stretch_blit( tmp, pic, 0, 0, tmp->w, tmp->h, 0, 0, pic->w, pic->h ); 
	destroy_bitmap( tmp );

	work = create_bitmap( screen->w, screen->h );

	set_trans_blender( 128, 0, 64, 128 );

	while ( ! key[ KEY_ESC ] ){

		for ( i = 0; i < sizeof( sprites ) / sizeof( sprite ); i++ ){
			sprite * s = &sprites[ i ];
			moveSprite( s );
			switch( mode ){
				case 0 : {
					draw_sprite_ex( work, pic, s->x, s->y, s->draw_type );
					break;
				}
				case 1 : {
					draw_sprite_h_flip_ex( work, pic, s->x, s->y, s->draw_type );
					break;
				}
				case 2 : {
					draw_sprite_v_flip_ex( work, pic, s->x, s->y, s->draw_type );
					break;
				}
				case 3 : {
					draw_sprite_vh_flip_ex( work, pic, s->x, s->y, s->draw_type );
					break;
				}
			}
		}

		if ( key[ KEY_SPACE ] && ! hold_space ){
			hold_space = 1;
			mode = (mode + 1) % 4;
		}
		if ( ! key[ KEY_SPACE ] ){
			hold_space = 0;
		}

		{
			char * msg = 0;
			switch ( mode ){
				case 0 : msg = "draw_sprite_ex"; break;
				case 1 : msg = "draw_sprite_h_flip_ex"; break;
				case 2 : msg = "draw_sprite_v_flip_ex"; break;
				case 3 : msg = "draw_sprite_vh_flip_ex"; break;
			}
			textprintf_ex( work, font, 1, 1, makecol( 255, 255, 255 ), -1, msg );
		}

		blit( work, screen, 0, 0, 0, 0, work->w, work->h );
		clear_bitmap( work );

		rest( 20 );
	}

	destroy_bitmap( pic );
	destroy_bitmap( work );

	printf( "Exiting normally\n" );
	set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );

	return 0;
}


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