src/video/SDL_blit_slow.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 02 Dec 2008 17:14:04 +0000
changeset 2824 4dba7aa7ea77
parent 2256 e893d24ad8db
child 2859 99210400e8b9
permissions -rw-r--r--
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
slouken@2256
     1
/*
slouken@2256
     2
    SDL - Simple DirectMedia Layer
slouken@2256
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@2256
     4
slouken@2256
     5
    This library is free software; you can redistribute it and/or
slouken@2256
     6
    modify it under the terms of the GNU Lesser General Public
slouken@2256
     7
    License as published by the Free Software Foundation; either
slouken@2256
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@2256
     9
slouken@2256
    10
    This library is distributed in the hope that it will be useful,
slouken@2256
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@2256
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@2256
    13
    Lesser General Public License for more details.
slouken@2256
    14
slouken@2256
    15
    You should have received a copy of the GNU Lesser General Public
slouken@2256
    16
    License along with this library; if not, write to the Free Software
slouken@2256
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@2256
    18
slouken@2256
    19
    Sam Lantinga
slouken@2256
    20
    slouken@libsdl.org
slouken@2256
    21
*/
slouken@2256
    22
#include "SDL_config.h"
slouken@2256
    23
slouken@2256
    24
#include "SDL_video.h"
slouken@2256
    25
#include "SDL_blit.h"
slouken@2256
    26
slouken@2256
    27
/* The ONE TRUE BLITTER
slouken@2256
    28
 * This puppy has to handle all the unoptimized cases - yes, it's slow.
slouken@2256
    29
 */
slouken@2824
    30
void
slouken@2824
    31
SDL_Blit_Slow(SDL_BlitInfo * info)
slouken@2824
    32
{
slouken@2824
    33
    const int flags = info->flags;
slouken@2824
    34
    const Uint32 modulateR = info->r;
slouken@2824
    35
    const Uint32 modulateG = info->g;
slouken@2824
    36
    const Uint32 modulateB = info->b;
slouken@2824
    37
    const Uint32 modulateA = info->a;
slouken@2824
    38
    Uint32 srcpixel;
slouken@2824
    39
    Uint32 srcR, srcG, srcB, srcA;
slouken@2824
    40
    Uint32 dstpixel;
slouken@2824
    41
    Uint32 dstR, dstG, dstB, dstA;
slouken@2824
    42
    int srcy, srcx;
slouken@2824
    43
    int posy, posx;
slouken@2824
    44
    int incy, incx;
slouken@2824
    45
    SDL_PixelFormat *src_fmt = info->src_fmt;
slouken@2824
    46
    SDL_PixelFormat *dst_fmt = info->dst_fmt;
slouken@2824
    47
    int srcbpp = src_fmt->BytesPerPixel;
slouken@2824
    48
    int dstbpp = dst_fmt->BytesPerPixel;
slouken@2824
    49
slouken@2824
    50
    srcy = 0;
slouken@2824
    51
    posy = 0;
slouken@2824
    52
    incy = (info->src_h << 16) / info->dst_h;
slouken@2824
    53
    incx = (info->src_w << 16) / info->dst_w;
slouken@2824
    54
slouken@2824
    55
    while (info->dst_h--) {
slouken@2824
    56
        Uint8 *src;
slouken@2824
    57
        Uint8 *dst = (Uint8 *) info->dst;
slouken@2824
    58
        int n = info->dst_w;
slouken@2824
    59
        srcx = -1;
slouken@2824
    60
        posx = 0x10000L;
slouken@2824
    61
        while (posy >= 0x10000L) {
slouken@2824
    62
            ++srcy;
slouken@2824
    63
            posy -= 0x10000L;
slouken@2824
    64
        }
slouken@2824
    65
        while (n--) {
slouken@2824
    66
            if (posx >= 0x10000L) {
slouken@2824
    67
                while (posx >= 0x10000L) {
slouken@2824
    68
                    ++srcx;
slouken@2824
    69
                    posx -= 0x10000L;
slouken@2824
    70
                }
slouken@2824
    71
                src =
slouken@2824
    72
                    (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
slouken@2824
    73
            }
slouken@2824
    74
            if (src_fmt->Amask) {
slouken@2824
    75
                DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
slouken@2824
    76
                              srcB, srcA);
slouken@2824
    77
            } else {
slouken@2824
    78
                DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
slouken@2824
    79
                             srcB);
slouken@2824
    80
                srcA = 0xFF;
slouken@2824
    81
            }
slouken@2824
    82
            if (flags & SDL_COPY_COLORKEY) {
slouken@2824
    83
                /* srcpixel isn't set for 24 bpp */
slouken@2824
    84
                if (srcbpp == 24) {
slouken@2824
    85
                    srcpixel = (srcR << src_fmt->Rshift) |
slouken@2824
    86
                        (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
slouken@2824
    87
                }
slouken@2824
    88
                if (srcpixel == info->colorkey) {
slouken@2824
    89
                    posx += incx;
slouken@2824
    90
                    dst += dstbpp;
slouken@2824
    91
                    continue;
slouken@2824
    92
                }
slouken@2824
    93
            }
slouken@2824
    94
            if (dst_fmt->Amask) {
slouken@2824
    95
                DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
slouken@2824
    96
                              dstB, dstA);
slouken@2824
    97
            } else {
slouken@2824
    98
                DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
slouken@2824
    99
                             dstB);
slouken@2824
   100
                dstA = 0xFF;
slouken@2824
   101
            }
slouken@2824
   102
slouken@2824
   103
            if (flags & SDL_COPY_MODULATE_COLOR) {
slouken@2824
   104
                srcR = (srcR * modulateR) / 255;
slouken@2824
   105
                srcG = (srcG * modulateG) / 255;
slouken@2824
   106
                srcB = (srcB * modulateB) / 255;
slouken@2824
   107
            }
slouken@2824
   108
            if (flags & SDL_COPY_MODULATE_ALPHA) {
slouken@2824
   109
                srcA = (srcA * modulateA) / 255;
slouken@2824
   110
            }
slouken@2824
   111
            if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
slouken@2824
   112
                /* This goes away if we ever use premultiplied alpha */
slouken@2824
   113
                if (srcA < 255) {
slouken@2824
   114
                    srcR = (srcR * srcA) / 255;
slouken@2824
   115
                    srcG = (srcG * srcA) / 255;
slouken@2824
   116
                    srcB = (srcB * srcA) / 255;
slouken@2824
   117
                }
slouken@2824
   118
            }
slouken@2824
   119
            switch (flags &
slouken@2824
   120
                    (SDL_COPY_MASK | SDL_COPY_BLEND | SDL_COPY_ADD |
slouken@2824
   121
                     SDL_COPY_MOD)) {
slouken@2824
   122
            case 0:
slouken@2824
   123
                dstR = srcR;
slouken@2824
   124
                dstG = srcG;
slouken@2824
   125
                dstB = srcB;
slouken@2824
   126
                dstA = srcA;
slouken@2824
   127
                break;
slouken@2824
   128
            case SDL_COPY_MASK:
slouken@2824
   129
                if (srcA) {
slouken@2824
   130
                    dstR = srcR;
slouken@2824
   131
                    dstG = srcG;
slouken@2824
   132
                    dstB = srcB;
slouken@2824
   133
                }
slouken@2824
   134
                break;
slouken@2824
   135
            case SDL_COPY_BLEND:
slouken@2824
   136
                dstR = srcR + ((255 - srcA) * dstR) / 255;
slouken@2824
   137
                dstG = srcG + ((255 - srcA) * dstG) / 255;
slouken@2824
   138
                dstB = srcB + ((255 - srcA) * dstB) / 255;
slouken@2824
   139
                break;
slouken@2824
   140
            case SDL_COPY_ADD:
slouken@2824
   141
                dstR = srcR + dstR;
slouken@2824
   142
                if (dstR > 255)
slouken@2824
   143
                    dstR = 255;
slouken@2824
   144
                dstG = srcG + dstG;
slouken@2824
   145
                if (dstG > 255)
slouken@2824
   146
                    dstG = 255;
slouken@2824
   147
                dstB = srcB + dstB;
slouken@2824
   148
                if (dstB > 255)
slouken@2824
   149
                    dstB = 255;
slouken@2824
   150
                break;
slouken@2824
   151
            case SDL_COPY_MOD:
slouken@2824
   152
                dstR = (srcR * dstR) / 255;
slouken@2824
   153
                dstG = (srcG * dstG) / 255;
slouken@2824
   154
                dstB = (srcB * dstB) / 255;
slouken@2824
   155
                break;
slouken@2824
   156
            }
slouken@2824
   157
            if (dst_fmt->Amask) {
slouken@2824
   158
                ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
slouken@2824
   159
            } else {
slouken@2824
   160
                ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
slouken@2824
   161
            }
slouken@2824
   162
            posx += incx;
slouken@2824
   163
            dst += dstbpp;
slouken@2824
   164
        }
slouken@2824
   165
        posy += incy;
slouken@2824
   166
        info->dst += info->dst_pitch;
slouken@2824
   167
    }
slouken@2824
   168
}
slouken@2256
   169
slouken@2256
   170
/* vi: set ts=4 sw=4 expandtab: */