# HG changeset patch # User Matti Hamalainen # Date 1349193076 -10800 # Node ID 0430f484641b2b0fc4c8a11b46ce8c2992b64022 # Parent 4bbfc0274b29af0f15e28d77ba4b5bc79b47455c Add unscaled blitting functions. diff -r 4bbfc0274b29 -r 0430f484641b Makefile.gen --- a/Makefile.gen Tue Oct 02 18:14:44 2012 +0300 +++ b/Makefile.gen Tue Oct 02 18:51:16 2012 +0300 @@ -222,7 +222,7 @@ @echo " CC $+" @$(CC) $(CFLAGS) -c -o $@ $< $(DM_CFLAGS) -$(OBJPATH)dmblit.o: $(DMLIB)dmblit.c $(DMLIB)dmscaledblit.h $(DMLIB)dmblitfunc.h +$(OBJPATH)dmblit.o: $(DMLIB)dmblit.c $(DMLIB)dmscaledblit.h $(DMLIB)dmunscaledblit.h $(DMLIB)dmblitfunc.h @echo " CC $+" @$(CC) $(CFLAGS) -c -o $@ $< $(DM_CFLAGS) diff -r 4bbfc0274b29 -r 0430f484641b dmblit.c --- a/dmblit.c Tue Oct 02 18:14:44 2012 +0300 +++ b/dmblit.c Tue Oct 02 18:51:16 2012 +0300 @@ -15,7 +15,7 @@ } DMQValue; -int dmClipCoord(DMQValue *pv, int v0, int v1, int v2, int clipMin, int clipMax) +int dmScaledClipCoord(DMQValue *pv, int v0, int v1, int v2, int clipMin, int clipMax) { DMFixedPoint32 a, b; @@ -69,6 +69,40 @@ } +int dmUnscaledClipCoord(DMQValue *pv, int v0, int v1, int clipMin, int clipMax) +{ + // Basic bounds check + if (v1 < 1 || v0 + v1 < clipMin || v0 >= clipMax) + return -1; + + // Perform clipping + if (v0 + v1 >= clipMax) + { + pv->vadd = v0; + pv->v1 = clipMax; + } + else + { + pv->vadd = clipMax - v1; + pv->v1 = v0 + v1; + } + + if (v0 < clipMin) + { + pv->voffs = clipMin - v0; + pv->v0 = clipMin; + pv->vadd -= v0 + clipMin; + } + else + { + pv->voffs = 0; + pv->v0 = v0; + } + + return 0; +} + + #include "dmblitfunc.h" @@ -110,6 +144,7 @@ static const int ndmScaledBlitTable = sizeof(dmScaledBlitTable) / sizeof(dmScaledBlitTable[0]); + DMScaledBlitFunc dmGetScaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode) { int isrc, idst; @@ -134,3 +169,69 @@ return bfunc(src, x0, y0, dwidth, dheight, dst); } + + +static const DMUnscaledBlitFunc dmUnscaledBlitTable[DMD_NMODES][DMD_NBITDEPTHS][DMD_NBITDEPTHS] = +{ + // DMD_NONE + { + { dmUnscaledBlitSurface8to8 , dmUnscaledBlitSurface8to32 }, + { NULL , dmUnscaledBlitSurface32to32 }, + }, + // DMD_TRANSPARENT + { + { dmUnscaledBlitSurface8to8Transparent, dmUnscaledBlitSurface8to32Transparent }, + { NULL , dmUnscaledBlitSurface32to32Transparent }, + }, + // DMD_SATURATE + { + { dmUnscaledBlitSurface8to8Saturate , dmUnscaledBlitSurface8to32Saturate }, + { NULL , dmUnscaledBlitSurface32to32Saturate }, + }, +#if 0 + // DMD_NONE | DMD_ANTIALIAS + { + { dmUnscaledBlitSurface8to8Antialias , dmUnscaledBlitSurface8to32Antialias }, + { NULL , dmUnscaledBlitSurface32to32Antialias }, + }, + // DMD_TRANSPARENT | DMD_ANTIALIAS + { + { dmUnscaledBlitSurface8to8AATransp , dmUnscaledBlitSurface8to32AATransparent }, + { NULL , dmUnscaledBlitSurface32to32AATransparent }, + }, + // DMD_SATURATE | DMD_ANTIALIAS + { + { dmUnscaledBlitSurface8to8AASaturate , dmUnscaledBlitSurface8to32AASaturate }, + { NULL , dmUnscaledBlitSurface32to32AASaturate }, + }, +#endif +}; + +static const int ndmUnscaledBlitTable = sizeof(dmUnscaledBlitTable) / sizeof(dmUnscaledBlitTable[0]); + + + +DMUnscaledBlitFunc dmGetUnscaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode) +{ + int isrc, idst; + if (src == NULL || dst == NULL || mode < 0 || mode >= ndmUnscaledBlitTable) + return NULL; + + isrc = dmBitsPerPixel2Index(src->BitsPerPixel); + idst = dmBitsPerPixel2Index(dst->BitsPerPixel); + if (isrc < 0 || idst < 0) + return NULL; + + return dmUnscaledBlitTable[mode][isrc][idst]; +} + + +int dmUnscaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst, int mode) +{ + DMUnscaledBlitFunc bfunc = dmGetUnscaledBlitFunc(src->format, dst->format, mode); + + if (bfunc == NULL) + return -15; + + return bfunc(src, x0, y0, dst); +} diff -r 4bbfc0274b29 -r 0430f484641b dmblitfunc.h --- a/dmblitfunc.h Tue Oct 02 18:14:44 2012 +0300 +++ b/dmblitfunc.h Tue Oct 02 18:51:16 2012 +0300 @@ -309,5 +309,237 @@ #include "dmscaledblit.h" + // ======================================================================= // ======================================================================= + + + +// ======================================================================= +// DMD_NONE +// ======================================================================= + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface8to8 +#define DM_BLITFUNC_SRC_BYTES 1 +#define DM_BLITFUNC_DST_BYTES 1 +#define DM_BLITFUNC_SRC_TYPE Uint8 +#define DM_BLITFUNC_DST_TYPE Uint8 + +#define DM_BLITFUNC_INNER *dp++ = sp[xv]; + +#include "dmunscaledblit.h" + +// ----------------------------------------------------------------------- + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface8to32 +#define DM_BLITFUNC_SRC_BYTES 1 +#define DM_BLITFUNC_DST_BYTES 4 +#define DM_BLITFUNC_SRC_TYPE Uint8 +#define DM_BLITFUNC_DST_TYPE Uint32 + +#define DM_BLITFUNC_VARS const Uint32 *pal; +#define DM_BLITFUNC_INIT \ + if (src->format->palette == NULL || src->format->palette->ncolors < 256) return -2; \ + pal = (Uint32 *) src->format->palette->colors; + +#define DM_BLITFUNC_INNER *dp++ = pal[sp[xv]]; + +#include "dmunscaledblit.h" + +// ----------------------------------------------------------------------- + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface32to32 +#define DM_BLITFUNC_SRC_BYTES 4 +#define DM_BLITFUNC_DST_BYTES 4 +#define DM_BLITFUNC_SRC_TYPE Uint32 +#define DM_BLITFUNC_DST_TYPE Uint32 +#define DM_BLITFUNC_INIT +#define DM_BLITFUNC_INNER *dp++ = sp[xv]; + +#include "dmunscaledblit.h" + + +// ======================================================================= +// DMD_TRANSPARENT +// ======================================================================= + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface8to8Transparent +#define DM_BLITFUNC_SRC_BYTES 1 +#define DM_BLITFUNC_DST_BYTES 1 +#define DM_BLITFUNC_SRC_TYPE Uint8 +#define DM_BLITFUNC_DST_TYPE Uint8 + +#define DM_BLITFUNC_INNER \ + *dp = sp[xv] ? sp[xv] : *dp; dp++; + +#include "dmunscaledblit.h" + +// ----------------------------------------------------------------------- + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface8to32Transparent +#define DM_BLITFUNC_SRC_BYTES 1 +#define DM_BLITFUNC_DST_BYTES 4 +#define DM_BLITFUNC_SRC_TYPE Uint8 +#define DM_BLITFUNC_DST_TYPE DMRGBA32 +#define DM_BLITFUNC_VARS const DMRGBA32 *pal; +#define DM_BLITFUNC_INIT \ + if (src->format->palette == NULL || src->format->palette->ncolors < 256) return -2; \ + pal = (DMRGBA32 *) src->format->palette->colors; + +#define DM_BLITFUNC_INNER \ + const DMRGBA32 q = pal[sp[xv]]; \ + dp->r += ((q.r - dp->r) * q.a) >> 8; \ + dp->g += ((q.g - dp->g) * q.a) >> 8; \ + dp->b += ((q.b - dp->b) * q.a) >> 8; \ + dp->a = q.a; \ + dp++; + +#include "dmunscaledblit.h" + + +// ----------------------------------------------------------------------- + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface32to32Transparent +#define DM_BLITFUNC_SRC_BYTES 4 +#define DM_BLITFUNC_DST_BYTES 4 + +#ifdef DM_USE_SIMD +#define DM_BLITFUNC_VARS \ + const Uint32 qpdmask = 0xff000000; \ + const Uint64 qpdrm = 0xff00ff00ff00ffULL; + +#define DM_BLITFUNC_SRC_TYPE Uint32 +#define DM_BLITFUNC_DST_TYPE Uint32 +#define DM_BLITFUNC_INNER \ + asm( \ + "movd %2, %%mm1\n" \ + \ + "movd %3, %%mm2\n" \ + "movq %%mm1, %%mm5\n" \ + "pand %%mm2, %%mm5\n" \ + "psrlw $8, %%mm5\n" \ + "punpcklwd %%mm5, %%mm5\n" \ + "punpckhwd %%mm5, %%mm5\n" \ + \ + "pxor %%mm2, %%mm2\n" \ + "movd %1, %%mm3\n" \ + "punpcklbw %%mm2, %%mm1\n" \ + "punpcklbw %%mm2, %%mm3\n" \ + \ + "psubw %%mm3, %%mm1\n" \ + "pmullw %%mm5, %%mm1\n" \ + "psraw $8, %%mm1\n" \ + "paddw %%mm3, %%mm1\n" \ + "pand %4, %%mm1\n" \ + "packuswb %%mm2, %%mm1\n" \ + "movd %%mm1, %0\n" \ + : "=m" (*dp) \ + : "m" (*dp), "m" (sp[xv]), "m" (qpdmask), "m" (qpdrm) \ + : "memory", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5" ); dp++; + +#define DM_BLITFUNC_FINISH asm("emms\n"); + +#else + +#define DM_BLITFUNC_SRC_TYPE DMRGBA32 +#define DM_BLITFUNC_DST_TYPE DMRGBA32 +#define DM_BLITFUNC_INNER \ + const DMRGBA32 q = sp[xv]; \ + dp->r += ((q.r - dp->r) * q.a) >> 8; \ + dp->g += ((q.g - dp->g) * q.a) >> 8; \ + dp->b += ((q.b - dp->b) * q.a) >> 8; \ + dp->a = q.a; \ + dp++; +#endif + +#include "dmunscaledblit.h" + + +// ======================================================================= +// DMD_SATURATE +// ======================================================================= + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface8to8Saturate +#define DM_BLITFUNC_SRC_BYTES 1 +#define DM_BLITFUNC_DST_BYTES 1 +#define DM_BLITFUNC_SRC_TYPE Uint8 +#define DM_BLITFUNC_DST_TYPE Uint8 +#define DM_BLITFUNC_INNER \ + const int q = sp[xv] + *dp; \ + *(dp++) = q < 256 ? q : 255; + +#include "dmunscaledblit.h" + +// ----------------------------------------------------------------------- + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface8to32Saturate +#define DM_BLITFUNC_SRC_BYTES 1 +#define DM_BLITFUNC_DST_BYTES 4 +#define DM_BLITFUNC_SRC_TYPE Uint8 +#define DM_BLITFUNC_DST_TYPE DMRGBA32 +#define DM_BLITFUNC_VARS const DMRGBA32 *pal; +#define DM_BLITFUNC_INIT \ + if (src->format->palette == NULL || src->format->palette->ncolors < 256) return -2; \ + pal = (DMRGBA32 *) src->format->palette->colors; + +#ifdef DM_USE_SIMD +#define DM_BLITFUNC_INNER \ + asm("movd %2, %%mm1\n" \ + "movd %1, %%mm2\n" \ + "paddusb %%mm2, %%mm1\n" \ + "movd %%mm1, %0\n" \ + : "=m" (*dp) \ + : "m" (*dp), "m" (pal[sp[xv]]) \ + : "memory", "%mm1", "%mm2" ); dp++; + +#define DM_BLITFUNC_FINISH asm("emms\n"); +#else +#define DM_BLITFUNC_INNER \ + const DMRGBA32 q = pal[sp[xv]]; \ + const int qr = dp->r + q.r, qg = dp->g + q.g, qb = dp->b + q.b; \ + dp->r = qr < 256 ? qr : 255; \ + dp->g = qg < 256 ? qg : 255; \ + dp->b = qb < 256 ? qb : 255; \ + dp->a = q.a; \ + dp++; +#endif + +#include "dmunscaledblit.h" + +// ----------------------------------------------------------------------- + +#define DM_BLITFUNC_NAME dmUnscaledBlitSurface32to32Saturate +#define DM_BLITFUNC_SRC_BYTES 4 +#define DM_BLITFUNC_DST_BYTES 4 +#define DM_BLITFUNC_INIT + +#ifdef DM_USE_SIMD +#define DM_BLITFUNC_SRC_TYPE Uint32 +#define DM_BLITFUNC_DST_TYPE Uint32 +#define DM_BLITFUNC_INNER \ + asm("movd %2, %%mm1\n" \ + "movd %1, %%mm2\n" \ + "paddusb %%mm2, %%mm1\n" \ + "movd %%mm1, %0\n" \ + : "=m" (*dp) \ + : "m" (*dp), "m" (sp[xv]) \ + : "memory", "%mm1", "%mm2" ); dp++; + +#define DM_BLITFUNC_FINISH asm("emms\n"); +#else +#define DM_BLITFUNC_SRC_TYPE DMRGBA32 +#define DM_BLITFUNC_DST_TYPE DMRGBA32 +#define DM_BLITFUNC_INNER \ + const DMRGBA32 q = sp[xv]; \ + const int qr = dp->r + q.r, qg = dp->g + q.g, qb = dp->b + q.b; \ + dp->r = qr < 256 ? qr : 255; \ + dp->g = qg < 256 ? qg : 255; \ + dp->b = qb < 256 ? qb : 255; \ + dp->a = q.a; \ + dp++; +#endif + +#include "dmunscaledblit.h" + + +// ======================================================================= diff -r 4bbfc0274b29 -r 0430f484641b dmlib.h --- a/dmlib.h Tue Oct 02 18:14:44 2012 +0300 +++ b/dmlib.h Tue Oct 02 18:51:16 2012 +0300 @@ -225,7 +225,8 @@ int dmDrawLineAny(SDL_Surface *src, int x0, int y0, int x1, int y1, const Uint32 color, int mode); #endif -/* Scaled blitting functions + +/* Various blitting functions */ #ifdef DM_GFX_BLITS typedef int (*DMScaledBlitFunc)(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst); @@ -235,8 +236,15 @@ int dmScaledBlitSurface32to32TransparentX(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst); int dmScaledBlitSurface32to32TransparentGA(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst, Uint32 alpha); + + +typedef int (*DMUnscaledBlitFunc)(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst); + +DMUnscaledBlitFunc dmGetUnscaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode); +int dmUnscaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst, int mode); #endif + /* Misc functions */ #ifdef DM_GFX_MISC diff -r 4bbfc0274b29 -r 0430f484641b dmscaledblit.h --- a/dmscaledblit.h Tue Oct 02 18:14:44 2012 +0300 +++ b/dmscaledblit.h Tue Oct 02 18:51:16 2012 +0300 @@ -23,10 +23,10 @@ #endif // Clip coordinates - if (dmClipCoord(&xr, x0, src->w, dwidth, + if (dmScaledClipCoord(&xr, x0, src->w, dwidth, dst->clip_rect.x, dst->clip_rect.x + dst->clip_rect.w) || - dmClipCoord(&yr, y0, src->h, dheight, + dmScaledClipCoord(&yr, y0, src->h, dheight, dst->clip_rect.y, dst->clip_rect.y + dst->clip_rect.h)) return -1; @@ -42,7 +42,7 @@ FP_MUL_R(dx, dx, xr.vdelta); // Take pitch into account - const int xadd = xr.vadd - dst->clip_rect.w + dst->clip_rect.x + (dst->pitch / DM_BLITFUNC_DST_BYTES); + const int dstadd = xr.vadd - dst->clip_rect.w + dst->clip_rect.x + (dst->pitch / DM_BLITFUNC_DST_BYTES); // Blit scaled DM_BLITFUNC_DST_TYPE * dp = ((DM_BLITFUNC_DST_TYPE *) dst->pixels) + (yr.v0 * dst->pitch) / DM_BLITFUNC_DST_BYTES + xr.v0; @@ -61,7 +61,7 @@ FP_ADD(xv, xr.vdelta); } FP_ADD(yv, yr.vdelta); - dp += xadd; + dp += dstadd; } #ifdef DM_BLITFUNC_FINISH diff -r 4bbfc0274b29 -r 0430f484641b dmunscaledblit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmunscaledblit.h Tue Oct 02 18:51:16 2012 +0300 @@ -0,0 +1,72 @@ +/* + * DMLib + * -- Unscaled sprite / surface blitting function template + * Programmed and designed by Matti 'ccr' Hamalainen + * (C) Copyright 2012 Tecnic Software productions (TNSP) + */ + +int DM_BLITFUNC_NAME (SDL_Surface *src, + const int x0, const int y0, + SDL_Surface *dst +#ifdef DM_BLITFUNC_ARGS + DM_BLITFUNC_ARGS +#endif + ) +{ + int yc; + DMQValue xr, yr; +#ifdef DM_BLITFUNC_VARS + DM_BLITFUNC_VARS +#endif + + // Clip coordinates + if (dmUnscaledClipCoord(&xr, x0, src->w, + dst->clip_rect.x, dst->clip_rect.x + dst->clip_rect.w) + || + dmUnscaledClipCoord(&yr, y0, src->h, + dst->clip_rect.y, dst->clip_rect.y + dst->clip_rect.h)) + return -1; + +#ifdef DM_BLITFUNC_INIT + DM_BLITFUNC_INIT +#endif + const int srcadd = src->pitch / DM_BLITFUNC_SRC_BYTES; + const int dstadd = xr.vadd - dst->clip_rect.w + dst->clip_rect.x + (dst->pitch / DM_BLITFUNC_DST_BYTES); + + DM_BLITFUNC_SRC_TYPE * sp = ((DM_BLITFUNC_SRC_TYPE *) src->pixels) + (yr.voffs * src->pitch) / DM_BLITFUNC_SRC_BYTES; + DM_BLITFUNC_DST_TYPE * dp = ((DM_BLITFUNC_DST_TYPE *) dst->pixels) + (yr.v0 * dst->pitch) / DM_BLITFUNC_DST_BYTES + xr.v0; + + for (yc = yr.v0; yc < yr.v1; yc++) + { + int xv, xc; + +#ifdef DM_BLITFUNC_INNER_INIT + DM_BLITFUNC_INNER_INIT +#endif + + for (xv = xr.voffs, xc = xr.v0; xc < xr.v1; xc++, xv++) + { + DM_BLITFUNC_INNER + } + sp += srcadd; + dp += dstadd; + } + +#ifdef DM_BLITFUNC_FINISH + DM_BLITFUNC_FINISH +#endif + return 0; +} + + +#undef DM_BLITFUNC_NAME +#undef DM_BLITFUNC_ARGS +#undef DM_BLITFUNC_SRC_BYTES +#undef DM_BLITFUNC_DST_BYTES +#undef DM_BLITFUNC_SRC_TYPE +#undef DM_BLITFUNC_DST_TYPE +#undef DM_BLITFUNC_VARS +#undef DM_BLITFUNC_INIT +#undef DM_BLITFUNC_INNER_INIT +#undef DM_BLITFUNC_INNER +#undef DM_BLITFUNC_FINISH