Mercurial > hg > dmlib
diff dmblit.c @ 0:32250b436bca
Initial re-import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 28 Sep 2012 01:54:23 +0300 |
parents | |
children | 265ce3091d88 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmblit.c Fri Sep 28 01:54:23 2012 +0300 @@ -0,0 +1,134 @@ +/* + * DMLib + * -- Sprite / surface blitting functions + * Programmed and designed by Matti 'ccr' Hamalainen + * (C) Copyright 2011 Tecnic Software productions (TNSP) + */ +#include "dmlib.h" + +//#define DM_CLIP_DEBUG + +typedef struct +{ + int v0, v1, voffs, vadd; + DMFixedPoint32 vdelta; +} DMQValue; + + +int dmClipCoord(DMQValue *pv, int v0, int v1, int v2, int clipMin, int clipMax) +{ + DMFixedPoint32 a, b; + + // Basic bounds check + if (v1 < 1 || v2 < 1 || v0 + v2 < clipMin || v0 >= clipMax) + { +#ifdef DM_CLIPDEBUG + printf("out of bounds\n"); +#endif + return -1; + } + + // Calculate delta + FP_SETHL(a, v1, 0); + FP_CONV(b, v2); + FP_DIV_R(pv->vdelta, a, b); + + // Perform clipping + if (v0 + v2 >= clipMax) + { + pv->vadd = v0; + pv->v1 = clipMax; + } + else + { + pv->vadd = clipMax - v2; + pv->v1 = v0 + v2; + } + + if (v0 < clipMin) + { + pv->voffs = clipMin - v0; + pv->v0 = clipMin; + pv->vadd -= v0 + clipMin; + } + else + { + pv->voffs = 0; + pv->v0 = v0; + } + +#ifdef DM_CLIP_DEBUG + printf("dmClipCoord(%d, (%d, %d), [%d, %d]): vdelta=", + v0, v1, v2, clipMin, clipMax); + FP_PRINTF(pv->vdelta); + printf(", v0=%d, v1=%d, voffs=%d, vadd=%d\n", + pv->v0, pv->v1, pv->voffs, pv->vadd); +#endif + + return 0; +} + +#include "dmblitfunc.h" + +static const DMScaledBlitFunc dmScaledBlitTable[DMD_NMODES][DMD_NBITDEPTHS][DMD_NBITDEPTHS] = +{ + // DMD_NONE + { + { dmScaledBlitSurface8to8 , dmScaledBlitSurface8to32 }, + { NULL , dmScaledBlitSurface32to32 }, + }, + // DMD_TRANSPARENT + { + { dmScaledBlitSurface8to8Transparent , dmScaledBlitSurface8to32Transparent }, + { NULL , dmScaledBlitSurface32to32Transparent }, + }, + // DMD_SATURATE + { + { dmScaledBlitSurface8to8Saturate , dmScaledBlitSurface8to32Saturate }, + { NULL , dmScaledBlitSurface32to32Saturate }, + }, +#if 0 + // DMD_NONE | DMD_ANTIALIAS + { + { dmScaledBlitSurface8to8Antialias , dmScaledBlitSurface8to32Antialias }, + { NULL , dmScaledBlitSurface32to32Antialias }, + }, + // DMD_TRANSPARENT | DMD_ANTIALIAS + { + { dmScaledBlitSurface8to8AATransp , dmScaledBlitSurface8to32AATransparent }, + { NULL , dmScaledBlitSurface32to32AATransparent }, + }, + // DMD_SATURATE | DMD_ANTIALIAS + { + { dmScaledBlitSurface8to8AASaturate , dmScaledBlitSurface8to32AASaturate }, + { NULL , dmScaledBlitSurface32to32AASaturate }, + }, +#endif +}; + +static const int ndmScaledBlitTable = sizeof(dmScaledBlitTable) / sizeof(dmScaledBlitTable[0]); + +DMScaledBlitFunc dmGetScaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode) +{ + int isrc, idst; + if (src == NULL || dst == NULL || mode < 0 || mode >= ndmScaledBlitTable) + return NULL; + + isrc = dmBitsPerPixel2Index(src->BitsPerPixel); + idst = dmBitsPerPixel2Index(dst->BitsPerPixel); + if (isrc < 0 || idst < 0) + return NULL; + + return dmScaledBlitTable[mode][isrc][idst]; +} + + +int dmScaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst, int mode) +{ + DMScaledBlitFunc bfunc = dmGetScaledBlitFunc(src->format, dst->format, mode); + + if (bfunc == NULL) + return -15; + + return bfunc(src, x0, y0, dwidth, dheight, dst); +}