src/video/SDL_blit_slow.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 03 Jan 2018 10:03:25 -0800
changeset 11811 5d94cb6b24d3
parent 10737 3406a0f8b041
child 12503 806492103856
permissions -rw-r--r--
Updated copyright for 2018
slouken@2256
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 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
*/
icculus@8093
    21
#include "../SDL_internal.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@10400
    49
    Uint32 rgbmask = ~src_fmt->Amask;
slouken@10400
    50
    Uint32 ckey = info->colorkey & rgbmask;
slouken@2824
    51
slouken@2824
    52
    srcy = 0;
slouken@2824
    53
    posy = 0;
slouken@2824
    54
    incy = (info->src_h << 16) / info->dst_h;
slouken@2824
    55
    incx = (info->src_w << 16) / info->dst_w;
slouken@2824
    56
slouken@2824
    57
    while (info->dst_h--) {
slouken@5426
    58
        Uint8 *src = 0;
slouken@2824
    59
        Uint8 *dst = (Uint8 *) info->dst;
slouken@2824
    60
        int n = info->dst_w;
slouken@2824
    61
        srcx = -1;
slouken@2824
    62
        posx = 0x10000L;
slouken@2824
    63
        while (posy >= 0x10000L) {
slouken@2824
    64
            ++srcy;
slouken@2824
    65
            posy -= 0x10000L;
slouken@2824
    66
        }
slouken@2824
    67
        while (n--) {
slouken@2824
    68
            if (posx >= 0x10000L) {
slouken@2824
    69
                while (posx >= 0x10000L) {
slouken@2824
    70
                    ++srcx;
slouken@2824
    71
                    posx -= 0x10000L;
slouken@2824
    72
                }
slouken@2824
    73
                src =
slouken@2824
    74
                    (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
slouken@2824
    75
            }
slouken@2824
    76
            if (src_fmt->Amask) {
slouken@2824
    77
                DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
slouken@2824
    78
                              srcB, srcA);
slouken@2824
    79
            } else {
slouken@2824
    80
                DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
slouken@2824
    81
                             srcB);
slouken@2824
    82
                srcA = 0xFF;
slouken@2824
    83
            }
slouken@2824
    84
            if (flags & SDL_COPY_COLORKEY) {
slouken@2824
    85
                /* srcpixel isn't set for 24 bpp */
slouken@3588
    86
                if (srcbpp == 3) {
slouken@2824
    87
                    srcpixel = (srcR << src_fmt->Rshift) |
slouken@2824
    88
                        (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
slouken@2824
    89
                }
slouken@10400
    90
                if ((srcpixel & rgbmask) == ckey) {
slouken@2824
    91
                    posx += incx;
slouken@2824
    92
                    dst += dstbpp;
slouken@2824
    93
                    continue;
slouken@2824
    94
                }
slouken@2824
    95
            }
slouken@2824
    96
            if (dst_fmt->Amask) {
slouken@2824
    97
                DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
slouken@2824
    98
                              dstB, dstA);
slouken@2824
    99
            } else {
slouken@2824
   100
                DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
slouken@2824
   101
                             dstB);
slouken@2824
   102
                dstA = 0xFF;
slouken@2824
   103
            }
slouken@2824
   104
slouken@2824
   105
            if (flags & SDL_COPY_MODULATE_COLOR) {
slouken@2824
   106
                srcR = (srcR * modulateR) / 255;
slouken@2824
   107
                srcG = (srcG * modulateG) / 255;
slouken@2824
   108
                srcB = (srcB * modulateB) / 255;
slouken@2824
   109
            }
slouken@2824
   110
            if (flags & SDL_COPY_MODULATE_ALPHA) {
slouken@2824
   111
                srcA = (srcA * modulateA) / 255;
slouken@2824
   112
            }
slouken@2824
   113
            if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
slouken@2824
   114
                /* This goes away if we ever use premultiplied alpha */
slouken@2824
   115
                if (srcA < 255) {
slouken@2824
   116
                    srcR = (srcR * srcA) / 255;
slouken@2824
   117
                    srcG = (srcG * srcA) / 255;
slouken@2824
   118
                    srcB = (srcB * srcA) / 255;
slouken@2824
   119
                }
slouken@2824
   120
            }
slouken@5184
   121
            switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | 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_BLEND:
slouken@2824
   129
                dstR = srcR + ((255 - srcA) * dstR) / 255;
slouken@2824
   130
                dstG = srcG + ((255 - srcA) * dstG) / 255;
slouken@2824
   131
                dstB = srcB + ((255 - srcA) * dstB) / 255;
slouken@10432
   132
                dstA = srcA + ((255 - srcA) * dstA) / 255;
slouken@2824
   133
                break;
slouken@2824
   134
            case SDL_COPY_ADD:
slouken@2824
   135
                dstR = srcR + dstR;
slouken@2824
   136
                if (dstR > 255)
slouken@2824
   137
                    dstR = 255;
slouken@2824
   138
                dstG = srcG + dstG;
slouken@2824
   139
                if (dstG > 255)
slouken@2824
   140
                    dstG = 255;
slouken@2824
   141
                dstB = srcB + dstB;
slouken@2824
   142
                if (dstB > 255)
slouken@2824
   143
                    dstB = 255;
slouken@2824
   144
                break;
slouken@5184
   145
            case SDL_COPY_MOD:
slouken@5184
   146
                dstR = (srcR * dstR) / 255;
slouken@5184
   147
                dstG = (srcG * dstG) / 255;
slouken@5184
   148
                dstB = (srcB * dstB) / 255;
slouken@5184
   149
                break;
slouken@2824
   150
            }
slouken@2824
   151
            if (dst_fmt->Amask) {
slouken@2824
   152
                ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
slouken@2824
   153
            } else {
slouken@2824
   154
                ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
slouken@2824
   155
            }
slouken@2824
   156
            posx += incx;
slouken@2824
   157
            dst += dstbpp;
slouken@2824
   158
        }
slouken@2824
   159
        posy += incy;
slouken@2824
   160
        info->dst += info->dst_pitch;
slouken@2824
   161
    }
slouken@2824
   162
}
slouken@2256
   163
slouken@2256
   164
/* vi: set ts=4 sw=4 expandtab: */