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