src/video/SDL_blit_slow.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 07 Dec 2008 22:37:40 +0000
changeset 2853 6258fa7cd300
parent 2824 4dba7aa7ea77
child 2859 99210400e8b9
permissions -rw-r--r--
Fixed picking blit function when RLE fails
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: */