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