Re: [AD] proposal: draw_sprite_*_ex

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




Can we use a parameter to indicate the flipping? (to be combined with
bitwise OR)

    DRAW_SPRITE_NO_FLIP
    DRAW_SPRITE_H_FLIP
    DRAW_SPRITE_V_FLIP

The mode should probably be an enum, although Allegro 4.2 doesn't tend
to use them.

Ok I changed draw_sprite_ex to accept another parameter, flip which can be one of the above mentioned constants. I changed SPRITE_LIT to DRAW_SPRITE_LIT but its still just a define and not an enum. Should it be an enum?

I define the constants above as
#define DRAW_SPRITE_NO_FLIP 1
#define DRAW_SPRITE_H_FLIP 2
#define DRAW_SPRITE_V_FLIP 4

instead of starting from 0 just to make it more obvious that they should be or'ed together but they could just as easily be 0, 1, 2. Attached is the newest patch( which requires cleanup ) and the example using this.
#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 = 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;
		}
	}
}

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 );
			draw_sprite_ex( work, pic, s->x, s->y, s->draw_type, mode );
			/*
			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 + 2) % 8;
		}
		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;
			}
			*/
			if ( mode & DRAW_SPRITE_H_FLIP &&
			     mode & DRAW_SPRITE_V_FLIP ){
			    msg = "horizontal and vertical flip";
		        } else if ( mode & DRAW_SPRITE_H_FLIP ){
			    msg = "horizontal flip";
			} else if ( mode & DRAW_SPRITE_V_FLIP ){
			    msg = "vertical flip";
			} else {
			    msg = "no flipping";
			}
			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;
}
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)
@@ -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))
 
 /* Blender for RGBA sprites.  */
 #define RGBA_BLENDER           BLENDER_FUNC
@@ -79,10 +81,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)
@@ -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_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/cdefs15.h
===================================================================
--- src/c/cdefs15.h	(revision 7838)
+++ src/c/cdefs15.h	(working copy)
@@ -23,6 +23,7 @@
 #define PIXEL_PTR              unsigned short*
 #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_write15((uintptr_t) (p), (c))
@@ -48,6 +49,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 +81,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)
@@ -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)
 #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))
 
 /* Blender for RGBA sprites.  */
 #define RGBA_BLENDER           BLENDER_FUNC
@@ -80,10 +82,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,236 @@
 #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 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 (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;
+
+      if ( flip & DRAW_SPRITE_H_FLIP ){
+          /* 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;
+
+      if ( flip & DRAW_SPRITE_V_FLIP ){
+          /* 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;
+      if ( flip & DRAW_SPRITE_H_FLIP ){
+          dxbeg = dx + w - 1;
+      }
+      dybeg = dy;
+      if ( flip & DRAW_SPRITE_V_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);
+
+	 /* 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);
+	    }
+	 }
+      }
+   }
+}
+
+/*
+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 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(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 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);
+	    }
+	 }
+      }
+   }
+}
+*/
+
 /* _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 +320,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 +401,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 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(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 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);
+	    }
+	 }
+      }
+   }
+}
+
 /* _linear_draw_sprite_v_flip:
  *  Draws a sprite to a linear bitmap, flipping vertically.
  */
@@ -258,16 +584,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 +712,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 +725,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 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);
 	    }
 	 }
@@ -331,6 +751,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 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);
 	    }
 	 }
@@ -338,8 +769,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 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(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 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);
+	    }
+	 }
+      }
+   }
+}
+
 /* _linear_draw_sprite_vh_flip:
  *  Draws a sprite to a linear bitmap, flipping both vertically and horizontally.
  */
@@ -692,8 +1230,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)
@@ -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_write8((uintptr_t) (p), (c))
@@ -49,6 +50,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 +76,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, 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,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 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 +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,7 +37,16 @@
 #define GFX_AUTODETECT_WINDOWED        2
 #define GFX_SAFE                       AL_ID('S','A','F','E')
 
+/* should be an enum?? */
+#define DRAW_SPRITE_NORMAL 0
+#define DRAW_SPRITE_LIT 1
+#define DRAW_SPRITE_TRANS 2
 
+/* combined with binary or */
+#define DRAW_SPRITE_NO_FLIP 0x1
+#define DRAW_SPRITE_H_FLIP 0x2
+#define DRAW_SPRITE_V_FLIP 0x4
+
 /* Blender mode defines, for the gfx_driver->set_blender_mode() function */
 #define blender_mode_none            0
 #define blender_mode_trans           1
@@ -214,6 +223,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, int flip ));
+   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, int flip));
 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, int flip));
 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, int flip));
 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, int flip));
 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, int flip),
+{
+   ASSERT(bmp);
+   ASSERT(sprite);
 
+      ASSERT(bmp->vtable->color_depth == sprite->vtable->color_depth);
+      bmp->vtable->draw_sprite_ex(bmp, sprite, x, y, mode, flip);
+	/*
+   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);


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