view dmblitfunc.h @ 60:f28cd66356f6

Initial work for bitmapped fonts and text drawing. Also moved TTF header stuff to dmtext.h.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 01 Oct 2012 09:46:56 +0300
parents 49cc9a173427
children ba1987562a73
line wrap: on
line source

/*
 * DMLib
 * -- Sprite / surface blitting functions
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2011-2012 Tecnic Software productions (TNSP)
 */

// =======================================================================
// DMD_NONE
// =======================================================================

#define DM_SCALED_NAME dmScaledBlitSurface8to8
#define DM_SCALED_SRC_BYTES 1
#define DM_SCALED_DST_BYTES 1
#define DM_SCALED_SRC_TYPE Uint8
#define DM_SCALED_DST_TYPE Uint8

#define DM_SCALED_INNER *dp++ = sp[FP_GETH(xv)];

#include "dmscaledblit.h"

// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface8to32
#define DM_SCALED_SRC_BYTES 1
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_SRC_TYPE Uint8
#define DM_SCALED_DST_TYPE Uint32

#define DM_SCALED_VARS const Uint32 *pal;
#define DM_SCALED_INIT \
    if (src->format->palette == NULL || src->format->palette->ncolors < 256) return -2;	\
    pal = (Uint32 *) src->format->palette->colors;

#define DM_SCALED_INNER *dp++ = pal[sp[FP_GETH(xv)]];

#include "dmscaledblit.h"

// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface32to32
#define DM_SCALED_SRC_BYTES 4
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_SRC_TYPE Uint32
#define DM_SCALED_DST_TYPE Uint32
#define DM_SCALED_INIT
#define DM_SCALED_INNER *dp++ = sp[FP_GETH(xv)];

#include "dmscaledblit.h"


// =======================================================================
// DMD_TRANSPARENT
// =======================================================================

#define DM_SCALED_NAME dmScaledBlitSurface8to8Transparent
#define DM_SCALED_SRC_BYTES 1
#define DM_SCALED_DST_BYTES 1
#define DM_SCALED_SRC_TYPE Uint8
#define DM_SCALED_DST_TYPE Uint8

#define DM_SCALED_INNER \
    *dp = sp[FP_GETH(xv)] ? sp[FP_GETH(xv)] : *dp; dp++;

#include "dmscaledblit.h"

// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface8to32Transparent
#define DM_SCALED_SRC_BYTES 1
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_SRC_TYPE Uint8
#define DM_SCALED_DST_TYPE DMRGBA32
#define DM_SCALED_VARS const DMRGBA32 *pal;
#define DM_SCALED_INIT \
    if (src->format->palette == NULL || src->format->palette->ncolors < 256) return -2;	\
    pal = (DMRGBA32 *) src->format->palette->colors;

#define DM_SCALED_INNER \
    const DMRGBA32 q = pal[sp[FP_GETH(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 "dmscaledblit.h"


// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface32to32Transparent
#define DM_SCALED_SRC_BYTES 4
#define DM_SCALED_DST_BYTES 4

#ifdef DM_USE_SIMD
#define DM_SCALED_VARS \
    const Uint32 qpdmask =       0xff000000; \
    const Uint64 qpdrm   = 0xff00ff00ff00ffULL;
    
#define DM_SCALED_SRC_TYPE Uint32
#define DM_SCALED_DST_TYPE Uint32
#define DM_SCALED_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[FP_GETH(xv)]), "m" (qpdmask), "m" (qpdrm)	\
        : "memory", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5" ); dp++;

#define DM_SCALED_FINISH asm("emms\n");

#else

#define DM_SCALED_SRC_TYPE DMRGBA32
#define DM_SCALED_DST_TYPE DMRGBA32
#define DM_SCALED_INNER \
    const DMRGBA32 q = sp[FP_GETH(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 "dmscaledblit.h"

// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface32to32TransparentX
#define DM_SCALED_SRC_BYTES 4
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_SRC_TYPE DMRGBA32
#define DM_SCALED_DST_TYPE DMRGBA32
#define DM_SCALED_INIT

#define DM_SCALED_INNER \
    const DMRGBA32 q = sp[FP_GETH(xv)]; \
    dp->r = (q.r * q.a + dp->r * dp->a) >> 8; \
    dp->g = (q.g * q.a + dp->g * dp->a) >> 8; \
    dp->b = (q.b * q.a + dp->b * dp->a) >> 8; \
    dp->a = q.a ? q.a : dp->a; \
    dp++;

#include "dmscaledblit.h"


// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface32to32TransparentGA
#define DM_SCALED_SRC_BYTES 4
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_ARGS , Uint32 alpha

#ifdef DM_USE_SIMD
#define DM_SCALED_VARS \
    const Uint64 qpdrm   = 0xff00ff00ff00ffULL;

#define DM_SCALED_SRC_TYPE Uint32
#define DM_SCALED_DST_TYPE Uint32
#define DM_SCALED_INNER_INIT \
    asm(					\
        "movd        %0,     %%mm4\n"		\
        "punpcklwd   %%mm4,  %%mm4\n"		\
        "punpckldq   %%mm4,  %%mm4\n"		\
        : 					\
        : "m" (alpha)				\
        : "%mm4" );

#define DM_SCALED_INNER				\
    asm(					\
        "movd        %2,     %%mm1\n"		\
        "pxor        %%mm2,  %%mm2\n"		\
        "movd        %1,     %%mm3\n"		\
        "punpcklbw   %%mm2,  %%mm1\n"		\
        "punpcklbw   %%mm2,  %%mm3\n"		\
        \
        "psubw       %%mm3,  %%mm1\n"		\
        "pmullw      %%mm4,  %%mm1\n"		\
        "psraw       $8,     %%mm1\n"		\
        "paddw       %%mm3,  %%mm1\n"		\
        "pand        %3,     %%mm1\n"		\
        "packuswb    %%mm2,  %%mm1\n"		\
        "movd        %%mm1,  %0\n"		\
        : "=m" (*dp)				\
        : "m" (*dp), "m" (sp[FP_GETH(xv)]), "m" (qpdrm)	\
        : "memory", "%mm1", "%mm2", "%mm3", "%mm4" ); dp++;

#define DM_SCALED_FINISH asm("emms\n");

#else

#define DM_SCALED_SRC_TYPE DMRGBA32
#define DM_SCALED_DST_TYPE DMRGBA32
#define DM_SCALED_INNER \
    const DMRGBA32 q = sp[FP_GETH(xv)]; \
    dp->r += ((q.r - dp->r) * alpha) >> 8; \
    dp->g += ((q.g - dp->g) * alpha) >> 8; \
    dp->b += ((q.b - dp->b) * alpha) >> 8; \
    dp->a  = alpha; \
    dp++;
#endif

#include "dmscaledblit.h"

// =======================================================================
// DMD_SATURATE
// =======================================================================

#define DM_SCALED_NAME dmScaledBlitSurface8to8Saturate
#define DM_SCALED_SRC_BYTES 1
#define DM_SCALED_DST_BYTES 1
#define DM_SCALED_SRC_TYPE Uint8
#define DM_SCALED_DST_TYPE Uint8
#define DM_SCALED_INNER *(dp++) += sp[FP_GETH(xv)];
#include "dmscaledblit.h"

// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface8to32Saturate
#define DM_SCALED_SRC_BYTES 1
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_SRC_TYPE Uint8
#define DM_SCALED_DST_TYPE DMRGBA32
#define DM_SCALED_VARS const DMRGBA32 *pal;
#define DM_SCALED_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_SCALED_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[FP_GETH(xv)]])	\
        : "memory", "%mm1", "%mm2" ); dp++;

#define DM_SCALED_FINISH asm("emms\n");
#else
#define DM_SCALED_INNER \
    const DMRGBA32 q = pal[sp[FP_GETH(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 "dmscaledblit.h"

// -----------------------------------------------------------------------

#define DM_SCALED_NAME dmScaledBlitSurface32to32Saturate
#define DM_SCALED_SRC_BYTES 4
#define DM_SCALED_DST_BYTES 4
#define DM_SCALED_INIT

#ifdef DM_USE_SIMD
#define DM_SCALED_SRC_TYPE Uint32
#define DM_SCALED_DST_TYPE Uint32
#define DM_SCALED_INNER				\
    asm("movd        %2,     %%mm1\n"		\
        "movd        %1,     %%mm2\n"		\
        "paddusb     %%mm2,  %%mm1\n"		\
        "movd        %%mm1,  %0\n"		\
        : "=m" (*dp)				\
        : "m" (*dp), "m" (sp[FP_GETH(xv)])	\
        : "memory", "%mm1", "%mm2" ); dp++;

#define DM_SCALED_FINISH asm("emms\n");
#else
#define DM_SCALED_SRC_TYPE DMRGBA32
#define DM_SCALED_DST_TYPE DMRGBA32
#define DM_SCALED_INNER \
    const DMRGBA32 q = sp[FP_GETH(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 "dmscaledblit.h"


// =======================================================================
// =======================================================================