src/gfx.cpp
changeset 7300 6c3d987e8e6d
parent 7149 ba2798e551a3
child 7327 fa2e72e31f59
--- a/src/gfx.cpp	Tue Jun 05 10:40:29 2007 +0000
+++ b/src/gfx.cpp	Tue Jun 05 12:01:50 2007 +0000
@@ -51,7 +51,8 @@
 	BM_TRANSPARENT,
 };
 
-static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode);
+template <BlitterMode Tmode>
+static inline void GfxMainBlitter(const Sprite *sprite, int x, int y);
 
 FontSize _cur_fontsize;
 static FontSize _last_fontsize;
@@ -682,7 +683,7 @@
 		if (IsPrintable(c)) {
 			if (x >= dpi->left + dpi->width) goto skip_char;
 			if (x + 26 >= dpi->left) {
-				GfxMainBlitter(GetGlyph(size, c), x, y, BM_COLOUR_REMAP);
+				GfxMainBlitter<BM_COLOUR_REMAP>(GetGlyph(size, c), x, y);
 			}
 			x += GetCharacterWidth(size, c);
 		} else if (c == '\n') { // newline = {}
@@ -719,12 +720,12 @@
 {
 	if (HASBIT(img, PALETTE_MODIFIER_TRANSPARENT)) {
 		_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
-		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT);
+		GfxMainBlitter<BM_TRANSPARENT>(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y);
 	} else if (pal != PAL_NONE) {
 		_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
-		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP);
+		GfxMainBlitter<BM_COLOUR_REMAP>(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y);
 	} else {
-		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL);
+		GfxMainBlitter<BM_NORMAL>(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y);
 	}
 }
 
@@ -732,15 +733,15 @@
 	int start_x, start_y;
 	const byte *sprite;
 	Pixel *dst;
-	BlitterMode mode;
 	int width, height;
 	int width_org;
 	int pitch;
 };
 
-static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom)
+template <BlitterMode Tmode, ZoomLevel Tzoom>
+static inline void GfxBlitZoomUncomp(BlitterParams *bp)
 {
-	const byte *src = bp->sprite;
+	const byte *src = bp->sprite + bp->start_y * bp->width_org + bp->start_x;
 	Pixel *dst = bp->dst;
 	int height = bp->height;
 	int width = bp->width;
@@ -749,19 +750,19 @@
 	assert(height > 0);
 	assert(width > 0);
 
-	height = UnScaleByZoom(height, zoom);
+	height = UnScaleByZoom(height, Tzoom);
 
-	switch (bp->mode) {
+	switch (Tmode) {
 		case BM_COLOUR_REMAP: {
 			const byte *ctab = _color_remap_ptr;
 
 			for (; height != 0; height--) {
-				for (i = 0; i != UnScaleByZoom(width, zoom); i++) {
-					byte b = ctab[src[ScaleByZoom(i, zoom)]];
+				for (i = 0; i != UnScaleByZoom(width, Tzoom); i++) {
+					byte b = ctab[src[ScaleByZoom(i, Tzoom)]];
 
 					if (b != 0) dst[i] = b;
 				}
-				src += ScaleByZoom(bp->width_org, zoom);
+				src += ScaleByZoom(bp->width_org, Tzoom);
 				dst += bp->pitch;
 			}
 			break;
@@ -771,9 +772,9 @@
 			const byte *ctab = _color_remap_ptr;
 
 			for (; height != 0; height--) {
-				for (i = 0; i != UnScaleByZoom(width, zoom); i++)
-					if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = ctab[dst[i]];
-				src += ScaleByZoom(bp->width_org, zoom);
+				for (i = 0; i != UnScaleByZoom(width, Tzoom); i++)
+					if (src[ScaleByZoom(i, Tzoom)] != 0) dst[i] = ctab[dst[i]];
+				src += ScaleByZoom(bp->width_org, Tzoom);
 				dst += bp->pitch;
 			}
 			break;
@@ -781,16 +782,17 @@
 
 		default:
 			for (; height != 0; height--) {
-				for (i = 0; i != UnScaleByZoom(width, zoom); i++)
-					if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = src[ScaleByZoom(i, zoom)];
-				src += ScaleByZoom(bp->width_org, zoom);
+				for (i = 0; i != UnScaleByZoom(width, Tzoom); i++)
+					if (src[ScaleByZoom(i, Tzoom)] != 0) dst[i] = src[ScaleByZoom(i, Tzoom)];
+				src += ScaleByZoom(bp->width_org, Tzoom);
 				dst += bp->pitch;
 			}
 			break;
 	}
 }
 
-static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
+template <BlitterMode Tmode, ZoomLevel Tzoom>
+static inline void GfxBlitTileZoom(BlitterParams *bp)
 {
 	const byte *src_o = bp->sprite;
 	const byte *src;
@@ -811,28 +813,28 @@
 
 			dst = bp->dst;
 
-			if (zoom >= ZOOM_LVL_OUT_2X && (skip & 1)) {
+			if (Tzoom >= ZOOM_LVL_OUT_2X && (skip & 1)) {
 				skip += 1;
 				src += 1;
 				num -= 1;
 				if (num <= 0) continue;
 			}
 
-			if (zoom >= ZOOM_LVL_OUT_4X && (skip & 2)) {
+			if (Tzoom >= ZOOM_LVL_OUT_4X && (skip & 2)) {
 				skip += 2;
 				src += 2;
 				num -= 2;
 				if (num <= 0) continue;
 			}
 
-			if (zoom >= ZOOM_LVL_OUT_8X && (skip & 4)) {
+			if (Tzoom >= ZOOM_LVL_OUT_8X && (skip & 4)) {
 				skip += 4;
 				src += 4;
 				num -= 4;
 				if (num <= 0) continue;
 			}
 
-			if (zoom >= ZOOM_LVL_OUT_16X && (skip & 8)) {
+			if (Tzoom >= ZOOM_LVL_OUT_16X && (skip & 8)) {
 				skip += 8;
 				src += 8;
 				num -= 8;
@@ -840,7 +842,7 @@
 			}
 
 			if ( (skip -= bp->start_x) > 0) {
-				dst += UnScaleByZoom(skip, zoom);
+				dst += UnScaleByZoom(skip, Tzoom);
 			} else {
 				src -= skip;
 				num += skip;
@@ -854,15 +856,15 @@
 				if (num <= 0) continue;
 			}
 
-			num = UnScaleByZoom(num + ScaleByZoom(1, zoom) - 1, zoom);
+			num = UnScaleByZoom(num + ScaleByZoom(1, Tzoom) - 1, Tzoom);
 
-			switch (bp->mode) {
+			switch (Tmode) {
 				case BM_COLOUR_REMAP:
 					ctab = _color_remap_ptr;
 					for (; num != 0; num--) {
 							*dst = ctab[*src];
 							dst++;
-							src += ScaleByZoom(1, zoom);
+							src += ScaleByZoom(1, Tzoom);
 					}
 					break;
 
@@ -875,10 +877,14 @@
 					break;
 
 				default:
-					for (; num != 0; num--) {
-							*dst = *src;
-							dst++;
-							src += ScaleByZoom(1, zoom);
+					if (Tzoom == ZOOM_LVL_NORMAL) {
+						memcpy(dst, src, num);
+					} else {
+						for (; num != 0; num--) {
+								*dst = *src;
+								dst++;
+								src += ScaleByZoom(1, Tzoom);
+						}
 					}
 					break;
 			}
@@ -889,7 +895,7 @@
 		bp->dst += bp->pitch;
 		if (--bp->height == 0) return;
 
-		for (int i = 0; i < ScaleByZoom(1, zoom) - 1; i++) {
+		for (int i = 0; i < ScaleByZoom(1, Tzoom) - 1; i++) {
 			do {
 				done = src_o[0];
 				src_o += (done & 0x7F) + 2;
@@ -899,7 +905,8 @@
 	}
 }
 
-static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
+template <BlitterMode Tmode>
+static inline void GfxMainBlitter(const Sprite *sprite, int x, int y)
 {
 	const DrawPixelInfo *dpi = _cur_dpi;
 	int start_x, start_y;
@@ -913,92 +920,68 @@
 	bp.height = sprite->height;
 	bp.sprite = sprite->data;
 	bp.dst = dpi->dst_ptr;
-	bp.mode = mode;
 	bp.pitch = dpi->pitch;
 
 	assert(bp.height > 0);
 	assert(bp.width > 0);
 
-	if (sprite->info & 8) {
-		/* tile blit */
-		start_y = 0;
-
-		if (dpi->zoom > ZOOM_LVL_NORMAL) {
-			start_y += bp.height & ~zoom_mask;
-			bp.height &= zoom_mask;
-			if (bp.height == 0) return;
-			y &= zoom_mask;
-		}
-
-		if ( (y -= dpi->top) < 0) {
-			bp.height += y;
-			if (bp.height <= 0) return;
-			start_y -= y;
-			y = 0;
-		} else {
-			bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom);
-		}
-		bp.start_y = start_y;
-
-		if ( (y = y + bp.height - dpi->height) > 0) {
-			bp.height -= y;
-			if (bp.height <= 0) return;
-		}
-
-		start_x = 0;
-		x &= zoom_mask;
-		if ( (x -= dpi->left) < 0) {
-			bp.width += x;
-			if (bp.width <= 0) return;
-			start_x -= x;
-			x = 0;
-		}
-		bp.start_x = start_x;
-		bp.dst += UnScaleByZoom(x, dpi->zoom);
-
-		if ( (x = x + bp.width - dpi->width) > 0) {
-			bp.width -= x;
-			if (bp.width <= 0) return;
-		}
-
-		GfxBlitTileZoom(&bp, dpi->zoom);
-	} else {
-		bp.sprite += bp.width * (bp.height & ~zoom_mask);
+	start_y = 0;
+	if (dpi->zoom > ZOOM_LVL_NORMAL) {
+		start_y += bp.height & ~zoom_mask;
 		bp.height &= zoom_mask;
 		if (bp.height == 0) return;
-
 		y &= zoom_mask;
+	}
 
-		if ( (y -= dpi->top) < 0) {
-			bp.height += y;
-			if (bp.height <= 0) return;
-			bp.sprite -= bp.width * y;
-			y = 0;
-		} else {
-			bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom);
-		}
+	if ( (y -= dpi->top) < 0) {
+		bp.height += y;
+		if (bp.height <= 0) return;
+		start_y -= y;
+		y = 0;
+	} else {
+		bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom);
+	}
+	bp.start_y = start_y;
 
-		if (bp.height > dpi->height - y) {
-			bp.height = dpi->height - y;
-			if (bp.height <= 0) return;
+	if ( (y = y + bp.height - dpi->height) > 0) {
+		bp.height -= y;
+		if (bp.height <= 0) return;
+	}
+
+	start_x = 0;
+	x &= zoom_mask;
+	if ( (x -= dpi->left) < 0) {
+		bp.width += x;
+		if (bp.width <= 0) return;
+		start_x -= x;
+		x = 0;
+	}
+	bp.start_x = start_x;
+	bp.dst += UnScaleByZoom(x, dpi->zoom);
+
+	if ( (x = x + bp.width - dpi->width) > 0) {
+		bp.width -= x;
+		if (bp.width <= 0) return;
+	}
+
+	if (sprite->info & 8) {
+		switch (dpi->zoom) {
+			case ZOOM_LVL_NORMAL:  GfxBlitTileZoom<Tmode, ZOOM_LVL_NORMAL>(&bp);  break;
+			case ZOOM_LVL_OUT_2X:  GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_2X>(&bp);  break;
+			case ZOOM_LVL_OUT_4X:  GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_4X>(&bp);  break;
+			case ZOOM_LVL_OUT_8X:  GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_8X>(&bp);  break;
+			case ZOOM_LVL_OUT_16X: GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_16X>(&bp); break;
+			default: NOT_REACHED();
 		}
-
-		x &= zoom_mask;
-
-		if ( (x -= dpi->left) < 0) {
-			bp.width += x;
-			if (bp.width <= 0) return;
-			bp.sprite -= x;
-			x = 0;
+	} else {
+		switch (dpi->zoom) {
+			case ZOOM_LVL_NORMAL:  GfxBlitZoomUncomp<Tmode, ZOOM_LVL_NORMAL>(&bp);  break;
+			case ZOOM_LVL_OUT_2X:  GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_2X>(&bp);  break;
+			case ZOOM_LVL_OUT_4X:  GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_4X>(&bp);  break;
+			case ZOOM_LVL_OUT_8X:  GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_8X>(&bp);  break;
+			case ZOOM_LVL_OUT_16X: GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_16X>(&bp); break;
+			default: NOT_REACHED();
 		}
-		bp.dst += UnScaleByZoom(x, dpi->zoom);
-
-		if (bp.width > dpi->width - x) {
-			bp.width = dpi->width - x;
-			if (bp.width <= 0) return;
-		}
-
-		GfxBlitZoomUncomp(&bp, dpi->zoom);
 	}
 }