view dmblit.c @ 96:6bf5220fa47e

Urgh .. use memset to silence some bogus GCC warnings about using potentially uninitialized values, while that will not actually be possible. In any case, it is annoying.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 02 Oct 2012 18:52:28 +0300
parents 0430f484641b
children e74ad60b1e85
line wrap: on
line source

/*
 * 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 dmScaledClipCoord(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;
}


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"


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);
}


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);
}