⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_blit_a.c

📁 Simple DirectMedia Layer - Simple DirectMedia Layer 是一个跨平台的多媒体库设计用来提供快速图形framebuffer和音频驱动。应用MPEG为软件
💻 C
📖 第 1 页 / 共 2 页
字号:
			while(w > 1) {				Uint32 sw = *(Uint32 *)srcp;				Uint32 dw = *(Uint32 *)dstp;				*(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask);				srcp += 2;				dstp += 2;				w -= 2;			}			/* last odd pixel? */			if(w) {				Uint16 d = *dstp, s = *srcp;				*dstp = BLEND16_50(d, s, mask);				srcp++;				dstp++;			}			srcp += srcskip;			dstp += dstskip;		}	}}/* fast RGB565->RGB565 blending with surface alpha */static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info){	unsigned alpha = info->src->alpha;	if(alpha == 128) {		Blit16to16SurfaceAlpha128(info, 0xf7de);	} else {		int width = info->d_width;		int height = info->d_height;		Uint16 *srcp = (Uint16 *)info->s_pixels;		int srcskip = info->s_skip >> 1;		Uint16 *dstp = (Uint16 *)info->d_pixels;		int dstskip = info->d_skip >> 1;		alpha >>= 3;	/* downscale alpha to 5 bits */		while(height--) {			DUFFS_LOOP4({				Uint32 s = *srcp++;				Uint32 d = *dstp;				/*				 * shift out the middle component (green) to				 * the high 16 bits, and process all three RGB				 * components at the same time.				 */				s = (s | s << 16) & 0x07e0f81f;				d = (d | d << 16) & 0x07e0f81f;				d += (s - d) * alpha >> 5;				d &= 0x07e0f81f;				*dstp++ = d | d >> 16;			}, width);			srcp += srcskip;			dstp += dstskip;		}	}}/* fast RGB555->RGB555 blending with surface alpha */static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info){	unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */	if(alpha == 128) {		Blit16to16SurfaceAlpha128(info, 0xfbde);	} else {		int width = info->d_width;		int height = info->d_height;		Uint16 *srcp = (Uint16 *)info->s_pixels;		int srcskip = info->s_skip >> 1;		Uint16 *dstp = (Uint16 *)info->d_pixels;		int dstskip = info->d_skip >> 1;		alpha >>= 3;		/* downscale alpha to 5 bits */		while(height--) {			DUFFS_LOOP4({				Uint32 s = *srcp++;				Uint32 d = *dstp;				/*				 * shift out the middle component (green) to				 * the high 16 bits, and process all three RGB				 * components at the same time.				 */				s = (s | s << 16) & 0x03e07c1f;				d = (d | d << 16) & 0x03e07c1f;				d += (s - d) * alpha >> 5;				d &= 0x03e07c1f;				*dstp++ = d | d >> 16;			}, width);			srcp += srcskip;			dstp += dstskip;		}	}}/* fast ARGB8888->RGB565 blending with pixel alpha */static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint32 *srcp = (Uint32 *)info->s_pixels;	int srcskip = info->s_skip >> 2;	Uint16 *dstp = (Uint16 *)info->d_pixels;	int dstskip = info->d_skip >> 1;	while(height--) {	    DUFFS_LOOP4({		Uint32 s = *srcp;		unsigned alpha = s >> 27; /* downscale alpha to 5 bits */		/* FIXME: Here we special-case opaque alpha since the		   compositioning used (>>8 instead of /255) doesn't handle		   it correctly. Also special-case alpha=0 for speed?		   Benchmark this! */		if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {		    *dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0)			  + (s >> 3  & 0x1f);		} else {		    Uint32 d = *dstp;		    /*		     * convert source and destination to G0RAB65565		     * and blend all components at the same time		     */		    s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)		      + (s >> 3 & 0x1f);		    d = (d | d << 16) & 0x07e0f81f;		    d += (s - d) * alpha >> 5;		    d &= 0x07e0f81f;		    *dstp = d | d >> 16;		}		srcp++;		dstp++;	    }, width);	    srcp += srcskip;	    dstp += dstskip;	}}/* fast ARGB8888->RGB555 blending with pixel alpha */static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint32 *srcp = (Uint32 *)info->s_pixels;	int srcskip = info->s_skip >> 2;	Uint16 *dstp = (Uint16 *)info->d_pixels;	int dstskip = info->d_skip >> 1;	while(height--) {	    DUFFS_LOOP4({		unsigned alpha;		Uint32 s = *srcp;		alpha = s >> 27; /* downscale alpha to 5 bits */		/* FIXME: Here we special-case opaque alpha since the		   compositioning used (>>8 instead of /255) doesn't handle		   it correctly. Also special-case alpha=0 for speed?		   Benchmark this! */		if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {		    *dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0)			  + (s >> 3  & 0x1f);		} else {		    Uint32 d = *dstp;		    /*		     * convert source and destination to G0RAB65565		     * and blend all components at the same time		     */		    s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00)		      + (s >> 3 & 0x1f);		    d = (d | d << 16) & 0x03e07c1f;		    d += (s - d) * alpha >> 5;		    d &= 0x03e07c1f;		    *dstp = d | d >> 16;		}		srcp++;		dstp++;	    }, width);	    srcp += srcskip;	    dstp += dstskip;	}}/* General (slow) N->N blending with per-surface alpha */static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint8 *src = info->s_pixels;	int srcskip = info->s_skip;	Uint8 *dst = info->d_pixels;	int dstskip = info->d_skip;	SDL_PixelFormat *srcfmt = info->src;	SDL_PixelFormat *dstfmt = info->dst;	int srcbpp = srcfmt->BytesPerPixel;	int dstbpp = dstfmt->BytesPerPixel;	unsigned sA = srcfmt->alpha;	unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;	while ( height-- ) {	    DUFFS_LOOP4(	    {		Uint32 pixel;		unsigned sR;		unsigned sG;		unsigned sB;		unsigned dR;		unsigned dG;		unsigned dB;		DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);		DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);		ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);		ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);		src += srcbpp;		dst += dstbpp;	    },	    width);	    src += srcskip;	    dst += dstskip;	}}/* General (slow) colorkeyed N->N blending with per-surface alpha */static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint8 *src = info->s_pixels;	int srcskip = info->s_skip;	Uint8 *dst = info->d_pixels;	int dstskip = info->d_skip;	SDL_PixelFormat *srcfmt = info->src;	SDL_PixelFormat *dstfmt = info->dst;	Uint32 ckey = srcfmt->colorkey;	int srcbpp = srcfmt->BytesPerPixel;	int dstbpp = dstfmt->BytesPerPixel;	unsigned sA = srcfmt->alpha;	unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;	while ( height-- ) {	    DUFFS_LOOP4(	    {		Uint32 pixel;		unsigned sR;		unsigned sG;		unsigned sB;		unsigned dR;		unsigned dG;		unsigned dB;		RETRIEVE_RGB_PIXEL(src, srcbpp, pixel);		if(pixel != ckey) {		    RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB);		    DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);		    ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);		    ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);		}		src += srcbpp;		dst += dstbpp;	    },	    width);	    src += srcskip;	    dst += dstskip;	}}/* General (slow) N->N blending with pixel alpha */static void BlitNtoNPixelAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint8 *src = info->s_pixels;	int srcskip = info->s_skip;	Uint8 *dst = info->d_pixels;	int dstskip = info->d_skip;	SDL_PixelFormat *srcfmt = info->src;	SDL_PixelFormat *dstfmt = info->dst;	int  srcbpp;	int  dstbpp;	/* Set up some basic variables */	srcbpp = srcfmt->BytesPerPixel;	dstbpp = dstfmt->BytesPerPixel;	/* FIXME: for 8bpp source alpha, this doesn't get opaque values	   quite right. for <8bpp source alpha, it gets them very wrong	   (check all macros!)	   It is unclear whether there is a good general solution that doesn't	   need a branch (or a divide). */	while ( height-- ) {	    DUFFS_LOOP4(	    {		Uint32 pixel;		unsigned sR;		unsigned sG;		unsigned sB;		unsigned dR;		unsigned dG;		unsigned dB;		unsigned sA;		unsigned dA;		DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);		DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);		ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);		ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);		src += srcbpp;		dst += dstbpp;	    },	    width);	    src += srcskip;	    dst += dstskip;	}}SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index){    SDL_PixelFormat *sf = surface->format;    SDL_PixelFormat *df = surface->map->dst->format;    if(sf->Amask == 0) {	if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {	    if(df->BytesPerPixel == 1)		return BlitNto1SurfaceAlphaKey;	    else		return BlitNtoNSurfaceAlphaKey;	} else {	    /* Per-surface alpha blits */	    switch(df->BytesPerPixel) {	    case 1:		return BlitNto1SurfaceAlpha;	    case 2:		if(surface->map->identity) {		    if(df->Gmask == 0x7e0)			return Blit565to565SurfaceAlpha;		    else if(df->Gmask == 0x3e0)			return Blit555to555SurfaceAlpha;		}		return BlitNtoNSurfaceAlpha;	    case 4:		if(sf->Rmask == df->Rmask		   && sf->Gmask == df->Gmask		   && sf->Bmask == df->Bmask		   && (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff		   && sf->BytesPerPixel == 4)		    return BlitRGBtoRGBSurfaceAlpha;		else		    return BlitNtoNSurfaceAlpha;	    case 3:	    default:		return BlitNtoNSurfaceAlpha;	    }	}    } else {	/* Per-pixel alpha blits */	switch(df->BytesPerPixel) {	case 1:	    return BlitNto1PixelAlpha;	case 2:	    if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000	       && sf->Gmask == 0xff00	       && ((sf->Rmask == 0xff && df->Rmask == 0x1f)		   || (sf->Bmask == 0xff && df->Bmask == 0x1f))) {		if(df->Gmask == 0x7e0)		    return BlitARGBto565PixelAlpha;		else if(df->Gmask == 0x3e0)		    return BlitARGBto555PixelAlpha;	    }	    return BlitNtoNPixelAlpha;	case 4:	    if(sf->Amask == 0xff000000	       && sf->Rmask == df->Rmask	       && sf->Gmask == df->Gmask	       && sf->Bmask == df->Bmask	       && sf->BytesPerPixel == 4)		return BlitRGBtoRGBPixelAlpha;	    return BlitNtoNPixelAlpha;	case 3:	default:	    return BlitNtoNPixelAlpha;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -