sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_blit_slow.c (6330B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      4 
      5   This software is provided 'as-is', without any express or implied
      6   warranty.  In no event will the authors be held liable for any damages
      7   arising from the use of this software.
      8 
      9   Permission is granted to anyone to use this software for any purpose,
     10   including commercial applications, and to alter it and redistribute it
     11   freely, subject to the following restrictions:
     12 
     13   1. The origin of this software must not be misrepresented; you must not
     14      claim that you wrote the original software. If you use this software
     15      in a product, an acknowledgment in the product documentation would be
     16      appreciated but is not required.
     17   2. Altered source versions must be plainly marked as such, and must not be
     18      misrepresented as being the original software.
     19   3. This notice may not be removed or altered from any source distribution.
     20 */
     21 #include "../SDL_internal.h"
     22 
     23 #include "SDL_video.h"
     24 #include "SDL_blit.h"
     25 #include "SDL_blit_slow.h"
     26 
     27 /* The ONE TRUE BLITTER
     28  * This puppy has to handle all the unoptimized cases - yes, it's slow.
     29  */
     30 void
     31 SDL_Blit_Slow(SDL_BlitInfo * info)
     32 {
     33     const int flags = info->flags;
     34     const Uint32 modulateR = info->r;
     35     const Uint32 modulateG = info->g;
     36     const Uint32 modulateB = info->b;
     37     const Uint32 modulateA = info->a;
     38     Uint32 srcpixel;
     39     Uint32 srcR, srcG, srcB, srcA;
     40     Uint32 dstpixel;
     41     Uint32 dstR, dstG, dstB, dstA;
     42     int srcy, srcx;
     43     int posy, posx;
     44     int incy, incx;
     45     SDL_PixelFormat *src_fmt = info->src_fmt;
     46     SDL_PixelFormat *dst_fmt = info->dst_fmt;
     47     int srcbpp = src_fmt->BytesPerPixel;
     48     int dstbpp = dst_fmt->BytesPerPixel;
     49     Uint32 rgbmask = ~src_fmt->Amask;
     50     Uint32 ckey = info->colorkey & rgbmask;
     51 
     52     srcy = 0;
     53     posy = 0;
     54     incy = (info->src_h << 16) / info->dst_h;
     55     incx = (info->src_w << 16) / info->dst_w;
     56 
     57     while (info->dst_h--) {
     58         Uint8 *src = 0;
     59         Uint8 *dst = info->dst;
     60         int n = info->dst_w;
     61         srcx = -1;
     62         posx = 0x10000L;
     63         while (posy >= 0x10000L) {
     64             ++srcy;
     65             posy -= 0x10000L;
     66         }
     67         while (n--) {
     68             if (posx >= 0x10000L) {
     69                 while (posx >= 0x10000L) {
     70                     ++srcx;
     71                     posx -= 0x10000L;
     72                 }
     73                 src =
     74                     (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
     75             }
     76             if (src_fmt->Amask) {
     77                 DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
     78                               srcB, srcA);
     79             } else {
     80                 DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
     81                              srcB);
     82                 srcA = 0xFF;
     83             }
     84             if (flags & SDL_COPY_COLORKEY) {
     85                 /* srcpixel isn't set for 24 bpp */
     86                 if (srcbpp == 3) {
     87                     srcpixel = (srcR << src_fmt->Rshift) |
     88                         (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
     89                 }
     90                 if ((srcpixel & rgbmask) == ckey) {
     91                     posx += incx;
     92                     dst += dstbpp;
     93                     continue;
     94                 }
     95             }
     96             if (dst_fmt->Amask) {
     97                 DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
     98                               dstB, dstA);
     99             } else {
    100                 DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
    101                              dstB);
    102                 dstA = 0xFF;
    103             }
    104 
    105             if (flags & SDL_COPY_MODULATE_COLOR) {
    106                 srcR = (srcR * modulateR) / 255;
    107                 srcG = (srcG * modulateG) / 255;
    108                 srcB = (srcB * modulateB) / 255;
    109             }
    110             if (flags & SDL_COPY_MODULATE_ALPHA) {
    111                 srcA = (srcA * modulateA) / 255;
    112             }
    113             if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
    114                 /* This goes away if we ever use premultiplied alpha */
    115                 if (srcA < 255) {
    116                     srcR = (srcR * srcA) / 255;
    117                     srcG = (srcG * srcA) / 255;
    118                     srcB = (srcB * srcA) / 255;
    119                 }
    120             }
    121             switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) {
    122             case 0:
    123                 dstR = srcR;
    124                 dstG = srcG;
    125                 dstB = srcB;
    126                 dstA = srcA;
    127                 break;
    128             case SDL_COPY_BLEND:
    129                 dstR = srcR + ((255 - srcA) * dstR) / 255;
    130                 dstG = srcG + ((255 - srcA) * dstG) / 255;
    131                 dstB = srcB + ((255 - srcA) * dstB) / 255;
    132                 dstA = srcA + ((255 - srcA) * dstA) / 255;
    133                 break;
    134             case SDL_COPY_ADD:
    135                 dstR = srcR + dstR;
    136                 if (dstR > 255)
    137                     dstR = 255;
    138                 dstG = srcG + dstG;
    139                 if (dstG > 255)
    140                     dstG = 255;
    141                 dstB = srcB + dstB;
    142                 if (dstB > 255)
    143                     dstB = 255;
    144                 break;
    145             case SDL_COPY_MOD:
    146                 dstR = (srcR * dstR) / 255;
    147                 dstG = (srcG * dstG) / 255;
    148                 dstB = (srcB * dstB) / 255;
    149                 break;
    150             case SDL_COPY_MUL:
    151                 dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255;
    152                 if (dstR > 255)
    153                     dstR = 255;
    154                 dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255;
    155                 if (dstG > 255)
    156                     dstG = 255;
    157                 dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255;
    158                 if (dstB > 255)
    159                     dstB = 255;
    160                 dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255;
    161                 if (dstA > 255)
    162                     dstA = 255;
    163                 break;
    164             }
    165             if (dst_fmt->Amask) {
    166                 ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
    167             } else {
    168                 ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
    169             }
    170             posx += incx;
    171             dst += dstbpp;
    172         }
    173         posy += incy;
    174         info->dst += info->dst_pitch;
    175     }
    176 }
    177 
    178 /* vi: set ts=4 sw=4 expandtab: */