--- a/src/gfx.cpp Wed Jun 13 11:17:30 2007 +0000
+++ b/src/gfx.cpp Wed Jun 13 11:45:14 2007 +0000
@@ -18,6 +18,7 @@
#include "fontcache.h"
#include "genworld.h"
#include "debug.h"
+#include "zoom.hpp"
#ifdef _DEBUG
bool _dbg_screen_rect;
@@ -64,12 +65,12 @@
void memcpy_pitch(void *dst, void *src, int w, int h, int srcpitch, int dstpitch)
{
- byte *dstp = (byte*)dst;
- byte *srcp = (byte*)src;
+ Pixel *dstp = (Pixel *)dst;
+ Pixel *srcp = (Pixel *)src;
assert(h >= 0);
for (; h != 0; --h) {
- memcpy(dstp, srcp, w);
+ memcpy(dstp, srcp, w * sizeof(Pixel));
dstp += dstpitch;
srcp += srcpitch;
}
@@ -110,7 +111,7 @@
}
for (ht = height; ht > 0; --ht) {
- memcpy(dst, src, width);
+ memcpy(dst, src, width * sizeof(Pixel));
src -= p;
dst -= p;
}
@@ -136,7 +137,7 @@
/* the y-displacement may be 0 therefore we have to use memmove,
* because source and destination may overlap */
for (ht = height; ht > 0; --ht) {
- memmove(dst, src, width);
+ memmove(dst, src, width * sizeof(Pixel));
src += p;
dst += p;
}
@@ -153,7 +154,7 @@
const int otop = top;
const int oleft = left;
- if (dpi->zoom != 0) return;
+ if (dpi->zoom != ZOOM_LVL_NORMAL) return;
if (left > right || top > bottom) return;
if (right < dpi->left || left >= dpi->left + dpi->width) return;
if (bottom < dpi->top || top >= dpi->top + dpi->height) return;
@@ -175,7 +176,7 @@
if (!HASBIT(color, PALETTE_MODIFIER_GREYOUT)) {
if (!HASBIT(color, USE_COLORTABLE)) {
do {
- memset(dst, color, right);
+ memset(dst, color, right * sizeof(Pixel));
dst += dpi->pitch;
} while (--bottom);
} else {
@@ -737,142 +738,7 @@
int pitch;
};
-static void GfxBlitTileZoomIn(BlitterParams *bp)
-{
- const byte *src_o = bp->sprite;
- const byte *src;
- int num, skip;
- byte done;
- Pixel *dst;
- const byte *ctab;
-
- src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
- switch (bp->mode) {
- case BM_COLOUR_REMAP:
- do {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src = src_o + 2;
- src_o += num + 2;
-
- dst = bp->dst;
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip;
- } else {
- src -= skip;
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
- ctab = _color_remap_ptr;
-
- for (; num >= 4; num -=4) {
- dst[3] = ctab[src[3]];
- dst[2] = ctab[src[2]];
- dst[1] = ctab[src[1]];
- dst[0] = ctab[src[0]];
- dst += 4;
- src += 4;
- }
- for (; num != 0; num--) *dst++ = ctab[*src++];
- } while (!(done & 0x80));
-
- bp->dst += bp->pitch;
- } while (--bp->height != 0);
- break;
-
- case BM_TRANSPARENT:
- do {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src_o += num + 2;
-
- dst = bp->dst;
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip;
- } else {
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
- ctab = _color_remap_ptr;
- for (; num != 0; num--) {
- *dst = ctab[*dst];
- dst++;
- }
- } while (!(done & 0x80));
-
- bp->dst += bp->pitch;
- } while (--bp->height != 0);
- break;
-
- default:
- do {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src = src_o + 2;
- src_o += num + 2;
-
- dst = bp->dst;
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip;
- } else {
- src -= skip;
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-#if defined(_WIN32)
- if (num & 1) *dst++ = *src++;
- if (num & 2) { *(uint16*)dst = *(uint16*)src; dst += 2; src += 2; }
- if (num >>= 2) {
- do {
- *(uint32*)dst = *(uint32*)src;
- dst += 4;
- src += 4;
- } while (--num != 0);
- }
-#else
- memcpy(dst, src, num);
-#endif
- } while (!(done & 0x80));
-
- bp->dst += bp->pitch;
- } while (--bp->height != 0);
- break;
- }
-}
-
-static void GfxBlitZoomInUncomp(BlitterParams *bp)
+static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom)
{
const byte *src = bp->sprite;
Pixel *dst = bp->dst;
@@ -883,62 +749,48 @@
assert(height > 0);
assert(width > 0);
+ height = UnScaleByZoom(height, zoom);
+
switch (bp->mode) {
case BM_COLOUR_REMAP: {
const byte *ctab = _color_remap_ptr;
- do {
- for (i = 0; i != width; i++) {
- byte b = ctab[src[i]];
+ for (; height != 0; height--) {
+ for (i = 0; i != UnScaleByZoom(width, zoom); i++) {
+ byte b = ctab[src[ScaleByZoom(i, zoom)]];
if (b != 0) dst[i] = b;
}
- src += bp->width_org;
+ src += ScaleByZoom(bp->width_org, zoom);
dst += bp->pitch;
- } while (--height != 0);
+ }
break;
}
case BM_TRANSPARENT: {
const byte *ctab = _color_remap_ptr;
- do {
- for (i = 0; i != width; i++)
- if (src[i] != 0) dst[i] = ctab[dst[i]];
- src += bp->width_org;
+ 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);
dst += bp->pitch;
- } while (--height != 0);
+ }
break;
}
default:
- do {
- int n = width;
-
- for (; n >= 4; n -= 4) {
- if (src[0] != 0) dst[0] = src[0];
- if (src[1] != 0) dst[1] = src[1];
- if (src[2] != 0) dst[2] = src[2];
- if (src[3] != 0) dst[3] = src[3];
-
- dst += 4;
- src += 4;
- }
-
- for (; n != 0; n--) {
- if (src[0] != 0) dst[0] = src[0];
- src++;
- dst++;
- }
-
- src += bp->width_org - width;
- dst += bp->pitch - width;
- } while (--height != 0);
+ 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);
+ dst += bp->pitch;
+ }
break;
}
}
-static void GfxBlitTileZoomMedium(BlitterParams *bp)
+static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
{
const byte *src_o = bp->sprite;
const byte *src;
@@ -948,484 +800,111 @@
const byte *ctab;
src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
- switch (bp->mode) {
- case BM_COLOUR_REMAP:
- do {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src = src_o + 2;
- src_o += num + 2;
-
- dst = bp->dst;
- if (skip & 1) {
- skip++;
- src++;
- if (--num == 0) continue;
- }
+ for (;;) {
+ do {
+ done = src_o[0];
+ num = done & 0x7F;
+ skip = src_o[1];
+ src = src_o + 2;
+ src_o += num + 2;
- if ( (skip -= bp->start_x) > 0) {
- dst += skip >> 1;
- } else {
- src -= skip;
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
+ dst = bp->dst;
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
+ if (zoom >= ZOOM_LVL_OUT_2X && (skip & 1)) {
+ skip += 1;
+ src += 1;
+ num -= 1;
+ if (num <= 0) continue;
+ }
+ if (zoom >= ZOOM_LVL_OUT_4X && (skip & 2)) {
+ skip += 2;
+ src += 2;
+ num -= 2;
+ if (num <= 0) continue;
+ }
+
+ if (zoom >= ZOOM_LVL_OUT_8X && (skip & 4)) {
+ skip += 4;
+ src += 4;
+ num -= 4;
+ if (num <= 0) continue;
+ }
+
+ if (zoom >= ZOOM_LVL_OUT_16X && (skip & 8)) {
+ skip += 8;
+ src += 8;
+ num -= 8;
+ if (num <= 0) continue;
+ }
+
+ if ( (skip -= bp->start_x) > 0) {
+ dst += UnScaleByZoom(skip, zoom);
+ } else {
+ src -= skip;
+ num += skip;
+ if (num <= 0) continue;
+ skip = 0;
+ }
+
+ skip = skip + num - bp->width;
+ if (skip > 0) {
+ num -= skip;
+ if (num <= 0) continue;
+ }
+
+ num = UnScaleByZoom(num + ScaleByZoom(1, zoom) - 1, zoom);
+
+ switch (bp->mode) {
+ case BM_COLOUR_REMAP:
ctab = _color_remap_ptr;
- num = (num + 1) >> 1;
for (; num != 0; num--) {
*dst = ctab[*src];
dst++;
- src += 2;
+ src += ScaleByZoom(1, zoom);
}
- } while (!(done & 0x80));
- bp->dst += bp->pitch;
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- } while (--bp->height != 0);
- break;
-
- case BM_TRANSPARENT:
- do {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src_o += num + 2;
+ break;
- dst = bp->dst;
-
- if (skip & 1) {
- skip++;
- if (--num == 0) continue;
- }
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip >> 1;
- } else {
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
+ case BM_TRANSPARENT:
ctab = _color_remap_ptr;
- num = (num + 1) >> 1;
for (; num != 0; num--) {
*dst = ctab[*dst];
dst++;
}
- } while (!(done & 0x80));
- bp->dst += bp->pitch;
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- } while (--bp->height != 0);
- break;
-
- default:
- do {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src = src_o + 2;
- src_o += num + 2;
-
- dst = bp->dst;
+ break;
- if (skip & 1) {
- skip++;
- src++;
- if (--num == 0) continue;
- }
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip >> 1;
- } else {
- src -= skip;
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
- num = (num + 1) >> 1;
-
+ default:
for (; num != 0; num--) {
*dst = *src;
dst++;
- src += 2;
+ src += ScaleByZoom(1, zoom);
}
-
- } while (!(done & 0x80));
-
- bp->dst += bp->pitch;
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- } while (--bp->height != 0);
- break;
- }
-}
-
-static void GfxBlitZoomMediumUncomp(BlitterParams *bp)
-{
- const byte *src = bp->sprite;
- Pixel *dst = bp->dst;
- int height = bp->height;
- int width = bp->width;
- int i;
-
- assert(height > 0);
- assert(width > 0);
-
- switch (bp->mode) {
- case BM_COLOUR_REMAP: {
- const byte *ctab = _color_remap_ptr;
+ break;
+ }
- for (height >>= 1; height != 0; height--) {
- for (i = 0; i != width >> 1; i++) {
- byte b = ctab[src[i * 2]];
-
- if (b != 0) dst[i] = b;
- }
- src += bp->width_org * 2;
- dst += bp->pitch;
- }
- break;
- }
-
- case BM_TRANSPARENT: {
- const byte *ctab = _color_remap_ptr;
- for (height >>= 1; height != 0; height--) {
- for (i = 0; i != width >> 1; i++)
- if (src[i * 2] != 0) dst[i] = ctab[dst[i]];
- src += bp->width_org * 2;
- dst += bp->pitch;
- }
- break;
+ } while (!(done & 0x80));
+
+ bp->dst += bp->pitch;
+ if (--bp->height == 0) return;
+
+ for (int i = 0; i < ScaleByZoom(1, zoom) - 1; i++) {
+ do {
+ done = src_o[0];
+ src_o += (done & 0x7F) + 2;
+ } while (!(done & 0x80));
+ if (--bp->height == 0) return;
}
-
- default:
- for (height >>= 1; height != 0; height--) {
- for (i = 0; i != width >> 1; i++)
- if (src[i * 2] != 0) dst[i] = src[i * 2];
- src += bp->width_org * 2;
- dst += bp->pitch;
- }
- break;
}
}
-static void GfxBlitTileZoomOut(BlitterParams *bp)
-{
- const byte *src_o = bp->sprite;
- const byte *src;
- int num, skip;
- byte done;
- Pixel *dst;
- const byte *ctab;
-
- src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
- switch (bp->mode) {
- case BM_COLOUR_REMAP:
- for (;;) {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src = src_o + 2;
- src_o += num + 2;
-
- dst = bp->dst;
-
- if (skip & 1) {
- skip++;
- src++;
- if (--num == 0) continue;
- }
-
- if (skip & 2) {
- skip += 2;
- src += 2;
- num -= 2;
- if (num <= 0) continue;
- }
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip >> 2;
- } else {
- src -= skip;
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
- ctab = _color_remap_ptr;
- num = (num + 3) >> 2;
- for (; num != 0; num--) {
- *dst = ctab[*src];
- dst++;
- src += 4;
- }
- } while (!(done & 0x80));
- bp->dst += bp->pitch;
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
- }
- break;
-
- case BM_TRANSPARENT:
- for (;;) {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src_o += num + 2;
-
- dst = bp->dst;
-
- if (skip & 1) {
- skip++;
- if (--num == 0) continue;
- }
-
- if (skip & 2) {
- skip += 2;
- num -= 2;
- if (num <= 0) continue;
- }
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip >> 2;
- } else {
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
- ctab = _color_remap_ptr;
- num = (num + 3) >> 2;
- for (; num != 0; num--) {
- *dst = ctab[*dst];
- dst++;
- }
-
- } while (!(done & 0x80));
- bp->dst += bp->pitch;
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
- }
- break;
-
- default:
- for (;;) {
- do {
- done = src_o[0];
- num = done & 0x7F;
- skip = src_o[1];
- src = src_o + 2;
- src_o += num + 2;
-
- dst = bp->dst;
-
- if (skip & 1) {
- skip++;
- src++;
- if (--num == 0) continue;
- }
-
- if (skip & 2) {
- skip += 2;
- src += 2;
- num -= 2;
- if (num <= 0) continue;
- }
-
- if ( (skip -= bp->start_x) > 0) {
- dst += skip >> 2;
- } else {
- src -= skip;
- num += skip;
- if (num <= 0) continue;
- skip = 0;
- }
-
- skip = skip + num - bp->width;
- if (skip > 0) {
- num -= skip;
- if (num <= 0) continue;
- }
-
- num = (num + 3) >> 2;
-
- for (; num != 0; num--) {
- *dst = *src;
- dst++;
- src += 4;
- }
- } while (!(done & 0x80));
-
- bp->dst += bp->pitch;
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
-
- do {
- done = src_o[0];
- src_o += (done & 0x7F) + 2;
- } while (!(done & 0x80));
- if (--bp->height == 0) return;
- }
- break;
- }
-}
-
-static void GfxBlitZoomOutUncomp(BlitterParams *bp)
-{
- const byte *src = bp->sprite;
- Pixel *dst = bp->dst;
- int height = bp->height;
- int width = bp->width;
- int i;
-
- assert(height > 0);
- assert(width > 0);
-
- switch (bp->mode) {
- case BM_COLOUR_REMAP: {
- const byte *ctab = _color_remap_ptr;
-
- for (height >>= 2; height != 0; height--) {
- for (i = 0; i != width >> 2; i++) {
- byte b = ctab[src[i * 4]];
-
- if (b != 0) dst[i] = b;
- }
- src += bp->width_org * 4;
- dst += bp->pitch;
- }
- break;
- }
-
- case BM_TRANSPARENT: {
- const byte *ctab = _color_remap_ptr;
-
- for (height >>= 2; height != 0; height--) {
- for (i = 0; i != width >> 2; i++)
- if (src[i * 4] != 0) dst[i] = ctab[dst[i]];
- src += bp->width_org * 4;
- dst += bp->pitch;
- }
- break;
- }
-
- default:
- for (height >>= 2; height != 0; height--) {
- for (i = 0; i != width >> 2; i++)
- if (src[i * 4] != 0) dst[i] = src[i * 4];
- src += bp->width_org * 4;
- dst += bp->pitch;
- }
- break;
- }
-}
-
-
static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
{
const DrawPixelInfo *dpi = _cur_dpi;
int start_x, start_y;
BlitterParams bp;
- int zoom_mask = ~((1 << dpi->zoom) - 1);
+ int zoom_mask = ~(ScaleByZoom(1, dpi->zoom) - 1);
/* decode sprite header */
x += sprite->x_offs;
@@ -1444,7 +923,7 @@
/* tile blit */
start_y = 0;
- if (dpi->zoom > 0) {
+ if (dpi->zoom > ZOOM_LVL_NORMAL) {
start_y += bp.height & ~zoom_mask;
bp.height &= zoom_mask;
if (bp.height == 0) return;
@@ -1457,7 +936,7 @@
start_y -= y;
y = 0;
} else {
- bp.dst += bp.pitch * (y >> dpi->zoom);
+ bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom);
}
bp.start_y = start_y;
@@ -1475,19 +954,14 @@
x = 0;
}
bp.start_x = start_x;
- bp.dst += x >> dpi->zoom;
+ bp.dst += UnScaleByZoom(x, dpi->zoom);
if ( (x = x + bp.width - dpi->width) > 0) {
bp.width -= x;
if (bp.width <= 0) return;
}
- switch (dpi->zoom) {
- default: NOT_REACHED();
- case 0: GfxBlitTileZoomIn(&bp); break;
- case 1: GfxBlitTileZoomMedium(&bp); break;
- case 2: GfxBlitTileZoomOut(&bp); break;
- }
+ GfxBlitTileZoom(&bp, dpi->zoom);
} else {
bp.sprite += bp.width * (bp.height & ~zoom_mask);
bp.height &= zoom_mask;
@@ -1501,7 +975,7 @@
bp.sprite -= bp.width * y;
y = 0;
} else {
- bp.dst += bp.pitch * (y >> dpi->zoom);
+ bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom);
}
if (bp.height > dpi->height - y) {
@@ -1517,19 +991,14 @@
bp.sprite -= x;
x = 0;
}
- bp.dst += x >> dpi->zoom;
+ bp.dst += UnScaleByZoom(x, dpi->zoom);
if (bp.width > dpi->width - x) {
bp.width = dpi->width - x;
if (bp.width <= 0) return;
}
- switch (dpi->zoom) {
- default: NOT_REACHED();
- case 0: GfxBlitZoomInUncomp(&bp); break;
- case 1: GfxBlitZoomMediumUncomp(&bp); break;
- case 2: GfxBlitZoomOutUncomp(&bp); break;
- }
+ GfxBlitZoomUncomp(&bp, dpi->zoom);
}
}
@@ -1946,7 +1415,7 @@
{
const DrawPixelInfo *o = _cur_dpi;
- n->zoom = 0;
+ n->zoom = ZOOM_LVL_NORMAL;
assert(width > 0);
assert(height > 0);