Mercurial > sdl-ios-xcode
diff src/video/SDL_blit_slow.c @ 2824:4dba7aa7ea77
Added slow but complete blit fallback
Don't try to RLE encode surfaces that have alpha channel and alpha modulation
Don't turn on blending when converting an RGB surface to RGBA format
Do turn on blending when converting colorkey to alpha channel
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 02 Dec 2008 17:14:04 +0000 |
parents | e893d24ad8db |
children | 99210400e8b9 |
line wrap: on
line diff
--- a/src/video/SDL_blit_slow.c Tue Dec 02 17:10:05 2008 +0000 +++ b/src/video/SDL_blit_slow.c Tue Dec 02 17:14:04 2008 +0000 @@ -27,5 +27,144 @@ /* The ONE TRUE BLITTER * This puppy has to handle all the unoptimized cases - yes, it's slow. */ +void +SDL_Blit_Slow(SDL_BlitInfo * info) +{ + const int flags = info->flags; + const Uint32 modulateR = info->r; + const Uint32 modulateG = info->g; + const Uint32 modulateB = info->b; + const Uint32 modulateA = info->a; + Uint32 srcpixel; + Uint32 srcR, srcG, srcB, srcA; + Uint32 dstpixel; + Uint32 dstR, dstG, dstB, dstA; + int srcy, srcx; + int posy, posx; + int incy, incx; + SDL_PixelFormat *src_fmt = info->src_fmt; + SDL_PixelFormat *dst_fmt = info->dst_fmt; + int srcbpp = src_fmt->BytesPerPixel; + int dstbpp = dst_fmt->BytesPerPixel; + + srcy = 0; + posy = 0; + incy = (info->src_h << 16) / info->dst_h; + incx = (info->src_w << 16) / info->dst_w; + + while (info->dst_h--) { + Uint8 *src; + Uint8 *dst = (Uint8 *) info->dst; + int n = info->dst_w; + srcx = -1; + posx = 0x10000L; + while (posy >= 0x10000L) { + ++srcy; + posy -= 0x10000L; + } + while (n--) { + if (posx >= 0x10000L) { + while (posx >= 0x10000L) { + ++srcx; + posx -= 0x10000L; + } + src = + (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); + } + if (src_fmt->Amask) { + DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, + srcB, srcA); + } else { + DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, + srcB); + srcA = 0xFF; + } + if (flags & SDL_COPY_COLORKEY) { + /* srcpixel isn't set for 24 bpp */ + if (srcbpp == 24) { + srcpixel = (srcR << src_fmt->Rshift) | + (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift); + } + if (srcpixel == info->colorkey) { + posx += incx; + dst += dstbpp; + continue; + } + } + if (dst_fmt->Amask) { + DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, + dstB, dstA); + } else { + DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, + dstB); + dstA = 0xFF; + } + + if (flags & SDL_COPY_MODULATE_COLOR) { + srcR = (srcR * modulateR) / 255; + srcG = (srcG * modulateG) / 255; + srcB = (srcB * modulateB) / 255; + } + if (flags & SDL_COPY_MODULATE_ALPHA) { + srcA = (srcA * modulateA) / 255; + } + if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) { + /* This goes away if we ever use premultiplied alpha */ + if (srcA < 255) { + srcR = (srcR * srcA) / 255; + srcG = (srcG * srcA) / 255; + srcB = (srcB * srcA) / 255; + } + } + switch (flags & + (SDL_COPY_MASK | SDL_COPY_BLEND | SDL_COPY_ADD | + SDL_COPY_MOD)) { + case 0: + dstR = srcR; + dstG = srcG; + dstB = srcB; + dstA = srcA; + break; + case SDL_COPY_MASK: + if (srcA) { + dstR = srcR; + dstG = srcG; + dstB = srcB; + } + break; + case SDL_COPY_BLEND: + dstR = srcR + ((255 - srcA) * dstR) / 255; + dstG = srcG + ((255 - srcA) * dstG) / 255; + dstB = srcB + ((255 - srcA) * dstB) / 255; + break; + case SDL_COPY_ADD: + dstR = srcR + dstR; + if (dstR > 255) + dstR = 255; + dstG = srcG + dstG; + if (dstG > 255) + dstG = 255; + dstB = srcB + dstB; + if (dstB > 255) + dstB = 255; + break; + case SDL_COPY_MOD: + dstR = (srcR * dstR) / 255; + dstG = (srcG * dstG) / 255; + dstB = (srcB * dstB) / 255; + break; + } + if (dst_fmt->Amask) { + ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA); + } else { + ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB); + } + posx += incx; + dst += dstbpp; + } + posy += incy; + info->dst += info->dst_pitch; + } +} /* vi: set ts=4 sw=4 expandtab: */