src/video/SDL_blit_slow.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 02 Mar 2013 20:44:16 -0800
changeset 6950 1ddb72193079
parent 6885 700f1b25f77f
child 8093 b43765095a6f
permissions -rw-r--r--
Added a mouse ID to the mouse events, which set to the special value SDL_TOUCH_MOUSEID for mouse events simulated by touch input.
slouken@2256
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@2256
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@2256
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@2256
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@2256
    20
*/
slouken@2256
    21
#include "SDL_config.h"
slouken@2256
    22
slouken@2256
    23
#include "SDL_video.h"
slouken@2256
    24
#include "SDL_blit.h"
slouken@4472
    25
#include "SDL_blit_slow.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@5426
    56
        Uint8 *src = 0;
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@3588
    84
                if (srcbpp == 3) {
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@5184
   119
            switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
slouken@2824
   120
            case 0:
slouken@2824
   121
                dstR = srcR;
slouken@2824
   122
                dstG = srcG;
slouken@2824
   123
                dstB = srcB;
slouken@2824
   124
                dstA = srcA;
slouken@2824
   125
                break;
slouken@2824
   126
            case SDL_COPY_BLEND:
slouken@2824
   127
                dstR = srcR + ((255 - srcA) * dstR) / 255;
slouken@2824
   128
                dstG = srcG + ((255 - srcA) * dstG) / 255;
slouken@2824
   129
                dstB = srcB + ((255 - srcA) * dstB) / 255;
slouken@2824
   130
                break;
slouken@2824
   131
            case SDL_COPY_ADD:
slouken@2824
   132
                dstR = srcR + dstR;
slouken@2824
   133
                if (dstR > 255)
slouken@2824
   134
                    dstR = 255;
slouken@2824
   135
                dstG = srcG + dstG;
slouken@2824
   136
                if (dstG > 255)
slouken@2824
   137
                    dstG = 255;
slouken@2824
   138
                dstB = srcB + dstB;
slouken@2824
   139
                if (dstB > 255)
slouken@2824
   140
                    dstB = 255;
slouken@2824
   141
                break;
slouken@5184
   142
            case SDL_COPY_MOD:
slouken@5184
   143
                dstR = (srcR * dstR) / 255;
slouken@5184
   144
                dstG = (srcG * dstG) / 255;
slouken@5184
   145
                dstB = (srcB * dstB) / 255;
slouken@5184
   146
                break;
slouken@2824
   147
            }
slouken@2824
   148
            if (dst_fmt->Amask) {
slouken@2824
   149
                ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
slouken@2824
   150
            } else {
slouken@2824
   151
                ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
slouken@2824
   152
            }
slouken@2824
   153
            posx += incx;
slouken@2824
   154
            dst += dstbpp;
slouken@2824
   155
        }
slouken@2824
   156
        posy += incy;
slouken@2824
   157
        info->dst += info->dst_pitch;
slouken@2824
   158
    }
slouken@2824
   159
}
slouken@2256
   160
slouken@2256
   161
/* vi: set ts=4 sw=4 expandtab: */