src/video/SDL_blit_0.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1402 d910939febfa
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

The headers are being converted to automatically generate doxygen documentation.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 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 
    27 /* Functions to blit from bitmaps to other surfaces */
    28 
    29 static void
    30 BlitBto1 (SDL_BlitInfo * info)
    31 {
    32     int c;
    33     int width, height;
    34     Uint8 *src, *map, *dst;
    35     int srcskip, dstskip;
    36 
    37     /* Set up some basic variables */
    38     width = info->d_width;
    39     height = info->d_height;
    40     src = info->s_pixels;
    41     srcskip = info->s_skip;
    42     dst = info->d_pixels;
    43     dstskip = info->d_skip;
    44     map = info->table;
    45     srcskip += width - (width + 7) / 8;
    46 
    47     if (map) {
    48         while (height--) {
    49             Uint8 byte = 0, bit;
    50             for (c = 0; c < width; ++c) {
    51                 if ((c & 7) == 0) {
    52                     byte = *src++;
    53                 }
    54                 bit = (byte & 0x80) >> 7;
    55                 if (1) {
    56                     *dst = map[bit];
    57                 }
    58                 dst++;
    59                 byte <<= 1;
    60             }
    61             src += srcskip;
    62             dst += dstskip;
    63         }
    64     } else {
    65         while (height--) {
    66             Uint8 byte = 0, bit;
    67             for (c = 0; c < width; ++c) {
    68                 if ((c & 7) == 0) {
    69                     byte = *src++;
    70                 }
    71                 bit = (byte & 0x80) >> 7;
    72                 if (1) {
    73                     *dst = bit;
    74                 }
    75                 dst++;
    76                 byte <<= 1;
    77             }
    78             src += srcskip;
    79             dst += dstskip;
    80         }
    81     }
    82 }
    83 static void
    84 BlitBto2 (SDL_BlitInfo * info)
    85 {
    86     int c;
    87     int width, height;
    88     Uint8 *src;
    89     Uint16 *map, *dst;
    90     int srcskip, dstskip;
    91 
    92     /* Set up some basic variables */
    93     width = info->d_width;
    94     height = info->d_height;
    95     src = info->s_pixels;
    96     srcskip = info->s_skip;
    97     dst = (Uint16 *) info->d_pixels;
    98     dstskip = info->d_skip / 2;
    99     map = (Uint16 *) info->table;
   100     srcskip += width - (width + 7) / 8;
   101 
   102     while (height--) {
   103         Uint8 byte = 0, bit;
   104         for (c = 0; c < width; ++c) {
   105             if ((c & 7) == 0) {
   106                 byte = *src++;
   107             }
   108             bit = (byte & 0x80) >> 7;
   109             if (1) {
   110                 *dst = map[bit];
   111             }
   112             byte <<= 1;
   113             dst++;
   114         }
   115         src += srcskip;
   116         dst += dstskip;
   117     }
   118 }
   119 static void
   120 BlitBto3 (SDL_BlitInfo * info)
   121 {
   122     int c, o;
   123     int width, height;
   124     Uint8 *src, *map, *dst;
   125     int srcskip, dstskip;
   126 
   127     /* Set up some basic variables */
   128     width = info->d_width;
   129     height = info->d_height;
   130     src = info->s_pixels;
   131     srcskip = info->s_skip;
   132     dst = info->d_pixels;
   133     dstskip = info->d_skip;
   134     map = info->table;
   135     srcskip += width - (width + 7) / 8;
   136 
   137     while (height--) {
   138         Uint8 byte = 0, bit;
   139         for (c = 0; c < width; ++c) {
   140             if ((c & 7) == 0) {
   141                 byte = *src++;
   142             }
   143             bit = (byte & 0x80) >> 7;
   144             if (1) {
   145                 o = bit * 4;
   146                 dst[0] = map[o++];
   147                 dst[1] = map[o++];
   148                 dst[2] = map[o++];
   149             }
   150             byte <<= 1;
   151             dst += 3;
   152         }
   153         src += srcskip;
   154         dst += dstskip;
   155     }
   156 }
   157 static void
   158 BlitBto4 (SDL_BlitInfo * info)
   159 {
   160     int width, height;
   161     Uint8 *src;
   162     Uint32 *map, *dst;
   163     int srcskip, dstskip;
   164     int c;
   165 
   166     /* Set up some basic variables */
   167     width = info->d_width;
   168     height = info->d_height;
   169     src = info->s_pixels;
   170     srcskip = info->s_skip;
   171     dst = (Uint32 *) info->d_pixels;
   172     dstskip = info->d_skip / 4;
   173     map = (Uint32 *) info->table;
   174     srcskip += width - (width + 7) / 8;
   175 
   176     while (height--) {
   177         Uint8 byte = 0, bit;
   178         for (c = 0; c < width; ++c) {
   179             if ((c & 7) == 0) {
   180                 byte = *src++;
   181             }
   182             bit = (byte & 0x80) >> 7;
   183             if (1) {
   184                 *dst = map[bit];
   185             }
   186             byte <<= 1;
   187             dst++;
   188         }
   189         src += srcskip;
   190         dst += dstskip;
   191     }
   192 }
   193 
   194 static void
   195 BlitBto1Key (SDL_BlitInfo * info)
   196 {
   197     int width = info->d_width;
   198     int height = info->d_height;
   199     Uint8 *src = info->s_pixels;
   200     Uint8 *dst = info->d_pixels;
   201     int srcskip = info->s_skip;
   202     int dstskip = info->d_skip;
   203     Uint32 ckey = info->src->colorkey;
   204     Uint8 *palmap = info->table;
   205     int c;
   206 
   207     /* Set up some basic variables */
   208     srcskip += width - (width + 7) / 8;
   209 
   210     if (palmap) {
   211         while (height--) {
   212             Uint8 byte = 0, bit;
   213             for (c = 0; c < width; ++c) {
   214                 if ((c & 7) == 0) {
   215                     byte = *src++;
   216                 }
   217                 bit = (byte & 0x80) >> 7;
   218                 if (bit != ckey) {
   219                     *dst = palmap[bit];
   220                 }
   221                 dst++;
   222                 byte <<= 1;
   223             }
   224             src += srcskip;
   225             dst += dstskip;
   226         }
   227     } else {
   228         while (height--) {
   229             Uint8 byte = 0, bit;
   230             for (c = 0; c < width; ++c) {
   231                 if ((c & 7) == 0) {
   232                     byte = *src++;
   233                 }
   234                 bit = (byte & 0x80) >> 7;
   235                 if (bit != ckey) {
   236                     *dst = bit;
   237                 }
   238                 dst++;
   239                 byte <<= 1;
   240             }
   241             src += srcskip;
   242             dst += dstskip;
   243         }
   244     }
   245 }
   246 
   247 static void
   248 BlitBto2Key (SDL_BlitInfo * info)
   249 {
   250     int width = info->d_width;
   251     int height = info->d_height;
   252     Uint8 *src = info->s_pixels;
   253     Uint16 *dstp = (Uint16 *) info->d_pixels;
   254     int srcskip = info->s_skip;
   255     int dstskip = info->d_skip;
   256     Uint32 ckey = info->src->colorkey;
   257     Uint8 *palmap = info->table;
   258     int c;
   259 
   260     /* Set up some basic variables */
   261     srcskip += width - (width + 7) / 8;
   262     dstskip /= 2;
   263 
   264     while (height--) {
   265         Uint8 byte = 0, bit;
   266         for (c = 0; c < width; ++c) {
   267             if ((c & 7) == 0) {
   268                 byte = *src++;
   269             }
   270             bit = (byte & 0x80) >> 7;
   271             if (bit != ckey) {
   272                 *dstp = ((Uint16 *) palmap)[bit];
   273             }
   274             byte <<= 1;
   275             dstp++;
   276         }
   277         src += srcskip;
   278         dstp += dstskip;
   279     }
   280 }
   281 
   282 static void
   283 BlitBto3Key (SDL_BlitInfo * info)
   284 {
   285     int width = info->d_width;
   286     int height = info->d_height;
   287     Uint8 *src = info->s_pixels;
   288     Uint8 *dst = info->d_pixels;
   289     int srcskip = info->s_skip;
   290     int dstskip = info->d_skip;
   291     Uint32 ckey = info->src->colorkey;
   292     Uint8 *palmap = info->table;
   293     int c;
   294 
   295     /* Set up some basic variables */
   296     srcskip += width - (width + 7) / 8;
   297 
   298     while (height--) {
   299         Uint8 byte = 0, bit;
   300         for (c = 0; c < width; ++c) {
   301             if ((c & 7) == 0) {
   302                 byte = *src++;
   303             }
   304             bit = (byte & 0x80) >> 7;
   305             if (bit != ckey) {
   306                 SDL_memcpy (dst, &palmap[bit * 4], 3);
   307             }
   308             byte <<= 1;
   309             dst += 3;
   310         }
   311         src += srcskip;
   312         dst += dstskip;
   313     }
   314 }
   315 
   316 static void
   317 BlitBto4Key (SDL_BlitInfo * info)
   318 {
   319     int width = info->d_width;
   320     int height = info->d_height;
   321     Uint8 *src = info->s_pixels;
   322     Uint32 *dstp = (Uint32 *) info->d_pixels;
   323     int srcskip = info->s_skip;
   324     int dstskip = info->d_skip;
   325     Uint32 ckey = info->src->colorkey;
   326     Uint8 *palmap = info->table;
   327     int c;
   328 
   329     /* Set up some basic variables */
   330     srcskip += width - (width + 7) / 8;
   331     dstskip /= 4;
   332 
   333     while (height--) {
   334         Uint8 byte = 0, bit;
   335         for (c = 0; c < width; ++c) {
   336             if ((c & 7) == 0) {
   337                 byte = *src++;
   338             }
   339             bit = (byte & 0x80) >> 7;
   340             if (bit != ckey) {
   341                 *dstp = ((Uint32 *) palmap)[bit];
   342             }
   343             byte <<= 1;
   344             dstp++;
   345         }
   346         src += srcskip;
   347         dstp += dstskip;
   348     }
   349 }
   350 
   351 static void
   352 BlitBtoNAlpha (SDL_BlitInfo * info)
   353 {
   354     int width = info->d_width;
   355     int height = info->d_height;
   356     Uint8 *src = info->s_pixels;
   357     Uint8 *dst = info->d_pixels;
   358     int srcskip = info->s_skip;
   359     int dstskip = info->d_skip;
   360     const SDL_Color *srcpal = info->src->palette->colors;
   361     SDL_PixelFormat *dstfmt = info->dst;
   362     int dstbpp;
   363     int c;
   364     const int A = info->src->alpha;
   365 
   366     /* Set up some basic variables */
   367     dstbpp = dstfmt->BytesPerPixel;
   368     srcskip += width - (width + 7) / 8;
   369 
   370     while (height--) {
   371         Uint8 byte = 0, bit;
   372         for (c = 0; c < width; ++c) {
   373             if ((c & 7) == 0) {
   374                 byte = *src++;
   375             }
   376             bit = (byte & 0x80) >> 7;
   377             if (1) {
   378                 Uint32 pixel;
   379                 unsigned sR, sG, sB;
   380                 unsigned dR, dG, dB;
   381                 sR = srcpal[bit].r;
   382                 sG = srcpal[bit].g;
   383                 sB = srcpal[bit].b;
   384                 DISEMBLE_RGB (dst, dstbpp, dstfmt, pixel, dR, dG, dB);
   385                 ALPHA_BLEND (sR, sG, sB, A, dR, dG, dB);
   386                 ASSEMBLE_RGB (dst, dstbpp, dstfmt, dR, dG, dB);
   387             }
   388             byte <<= 1;
   389             dst += dstbpp;
   390         }
   391         src += srcskip;
   392         dst += dstskip;
   393     }
   394 }
   395 
   396 static void
   397 BlitBtoNAlphaKey (SDL_BlitInfo * info)
   398 {
   399     int width = info->d_width;
   400     int height = info->d_height;
   401     Uint8 *src = info->s_pixels;
   402     Uint8 *dst = info->d_pixels;
   403     int srcskip = info->s_skip;
   404     int dstskip = info->d_skip;
   405     SDL_PixelFormat *srcfmt = info->src;
   406     SDL_PixelFormat *dstfmt = info->dst;
   407     const SDL_Color *srcpal = srcfmt->palette->colors;
   408     int dstbpp;
   409     int c;
   410     const int A = srcfmt->alpha;
   411     Uint32 ckey = srcfmt->colorkey;
   412 
   413     /* Set up some basic variables */
   414     dstbpp = dstfmt->BytesPerPixel;
   415     srcskip += width - (width + 7) / 8;
   416 
   417     while (height--) {
   418         Uint8 byte = 0, bit;
   419         for (c = 0; c < width; ++c) {
   420             if ((c & 7) == 0) {
   421                 byte = *src++;
   422             }
   423             bit = (byte & 0x80) >> 7;
   424             if (bit != ckey) {
   425                 int sR, sG, sB;
   426                 int dR, dG, dB;
   427                 Uint32 pixel;
   428                 sR = srcpal[bit].r;
   429                 sG = srcpal[bit].g;
   430                 sB = srcpal[bit].b;
   431                 DISEMBLE_RGB (dst, dstbpp, dstfmt, pixel, dR, dG, dB);
   432                 ALPHA_BLEND (sR, sG, sB, A, dR, dG, dB);
   433                 ASSEMBLE_RGB (dst, dstbpp, dstfmt, dR, dG, dB);
   434             }
   435             byte <<= 1;
   436             dst += dstbpp;
   437         }
   438         src += srcskip;
   439         dst += dstskip;
   440     }
   441 }
   442 
   443 static SDL_loblit bitmap_blit[] = {
   444     NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
   445 };
   446 
   447 static SDL_loblit colorkey_blit[] = {
   448     NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
   449 };
   450 
   451 SDL_loblit
   452 SDL_CalculateBlit0 (SDL_Surface * surface, int blit_index)
   453 {
   454     int which;
   455 
   456     if (surface->format->BitsPerPixel != 1) {
   457         /* We don't support sub 8-bit packed pixel modes */
   458         return NULL;
   459     }
   460     if (surface->map->dst->format->BitsPerPixel < 8) {
   461         which = 0;
   462     } else {
   463         which = surface->map->dst->format->BytesPerPixel;
   464     }
   465     switch (blit_index) {
   466     case 0:                    /* copy */
   467         return bitmap_blit[which];
   468 
   469     case 1:                    /* colorkey */
   470         return colorkey_blit[which];
   471 
   472     case 2:                    /* alpha */
   473         return which >= 2 ? BlitBtoNAlpha : NULL;
   474 
   475     case 4:                    /* alpha + colorkey */
   476         return which >= 2 ? BlitBtoNAlphaKey : NULL;
   477     }
   478     return NULL;
   479 }
   480 
   481 /* vi: set ts=4 sw=4 expandtab: */