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: */