Re: [AD] v/h flip for draw_lit/trans

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




Jon Rafkind wrote:
I wanted to use draw_lit_h_flip_sprite today but realized it doesn't exist. I suppose in the mean time I can make a new bitmap, draw_sprite_h_flip and draw_lit that but I would rather have a native draw_lit_h_flip_sprite or something similar.

Actually its probably not worth adding *_h/f/rotate_sprite for lit and trans routines but rather make draw_sprite respect drawing_mode. I wondered why this is not the case anyway, anyone know why? Looking through cspr.c it might be tricky to make fast, non-sucky code that can do normal/lit/trans mode's for all the drawing routines but I'm sure something can be arranged. Perhaps the code could be auto-generated or something. Just wanted to bring it up before I submit a patch of sorts.

Just to get things going the attached patch( which is ugly in every way possible ) uses _drawing_mode to detect what sort of drawing routine to use( normal/lit/translucent ), although right now it just does normal and lit and I only changed draw_sprite and draw_sprite_h_flip. One hurdle that I see is draw_lit_sprite takes a color parameter, ignoring alpha from set_trans_blender for some reason, which obviously can't be passed to draw_sprite so I had to default it to 50 for now just to make my tests work. I'd say just make draw_lit_sprite use the alpha value set in set_trans_blender but that would be super non-backwards compatible I'm sure.

Oh also I had to add a new DRAW_MODE_LIT to draw.h which would have no affect on primitives, just *_sprite routines.
Index: src/c/cdefs16.h
===================================================================
--- src/c/cdefs16.h	(revision 7764)
+++ 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.  */
Index: src/c/cspr.h
===================================================================
--- src/c/cspr.h	(revision 7764)
+++ src/c/cspr.h	(working copy)
@@ -18,12 +18,101 @@
 #ifndef __bma_cspr_h
 #define __bma_cspr_h
 
+static void linear_mode_draw_sprite( BITMAP * dst, BITMAP * src, int dx, int dy, int color, int mode ){
+   int x, y, w, h;
+   int dxbeg, dybeg;
+   int sxbeg, sybeg;
+   DLS_BLENDER lit_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(color);
+
+   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_MODE_SOLID : break;
+			    case DRAW_MODE_LIT : {
+					c = DLS_BLEND(lit_blender, color, 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_MODE_SOLID : break;
+			    case DRAW_MODE_LIT : {
+					c = DLS_BLEND(lit_blender, color, 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)
 {
+	linear_mode_draw_sprite( dst, src, dx, dy, 50, _drawing_mode );
+#if 0
    int x, y, w, h;
    int dxbeg, dybeg;
    int sxbeg, sybeg;
@@ -61,6 +150,8 @@
       dybeg = dy;
    }
 
+   lit_blender = MAKE_DLS_BLENDER();
+
    if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
       bmp_select(dst);
 
@@ -71,6 +162,13 @@
 	 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_MODE_SOLID : break;
+			    case DRAW_MODE_LIT : {
+					c = DLS_BLEND(lit_blender, color, c);
+					break;
+			 }
+		    }
 	       PUT_PIXEL(d, c);
 	    }
 	 }
@@ -91,12 +189,13 @@
 	 }
       }
    }
+
+#endif
 }
 
 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.
@@ -258,13 +357,105 @@
    }
 }
 
+static void linear_mode_draw_sprite_h_flip( BITMAP * dst, BITMAP * src, int dx, int dy, int color, int mode ){
+	int x, y, w, h;
+	int dxbeg, dybeg;
+	int sxbeg, sybeg;
+	DLS_BLENDER lit_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;
+	}
+	else {
+		w = src->w;
+		h = src->h;
+		sxbeg = 0;
+		sybeg = 0;
+		dxbeg = dx + w - 1;
+		dybeg = dy;
+	}
+	
+	lit_blender = MAKE_DLS_BLENDER(color);
+
+	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_MODE_SOLID : break;
+						case DRAW_MODE_LIT : {
+							c = DLS_BLEND(lit_blender, color, 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_MODE_SOLID : break;
+						case DRAW_MODE_LIT : {
+							c = DLS_BLEND(lit_blender, color, c);
+							break;
+						}
+					}
+					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)
 {
+	linear_mode_draw_sprite_h_flip( dst, src, dx, dy, 50, _drawing_mode );
+
+#if 0
    int x, y, w, h;
    int dxbeg, dybeg;
    int sxbeg, sybeg;
@@ -336,10 +527,9 @@
 	 }
       }
    }
+#endif
 }
 
-
-
 /* _linear_draw_sprite_vh_flip:
  *  Draws a sprite to a linear bitmap, flipping both vertically and horizontally.
  */
@@ -616,6 +806,8 @@
  */
 void FUNC_LINEAR_DRAW_LIT_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy, int color)
 {
+	linear_mode_draw_sprite( dst, src, dx, dy, color, DRAW_MODE_LIT );
+#if 0
    int x, y, w, h;
    int dxbeg, dybeg;
    int sxbeg, sybeg;
@@ -690,6 +882,7 @@
 	 }
       }
    }
+#endif
 }
 
 
Index: include/allegro/draw.h
===================================================================
--- include/allegro/draw.h	(revision 7764)
+++ include/allegro/draw.h	(working copy)
@@ -33,6 +33,7 @@
 #define DRAW_MODE_SOLID_PATTERN     3
 #define DRAW_MODE_MASKED_PATTERN    4
 #define DRAW_MODE_TRANS             5
+#define DRAW_MODE_LIT               6
 
 AL_FUNC(void, drawing_mode, (int mode, struct BITMAP *pattern, int x_anchor, int y_anchor));
 AL_FUNC(void, xor_mode, (int on));


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