Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 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.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26.  
  27. #include "SDL_types.h"
  28. #include "SDL_video.h"
  29. #include "SDL_blit.h"
  30.  
  31. /* Functions to blit from bitmaps to other surfaces */
  32.  
  33. static void BlitBto1(SDL_BlitInfo *info)
  34. {
  35.         int c;
  36.         int width, height;
  37.         Uint8 *src, *map, *dst;
  38.         int srcskip, dstskip;
  39.  
  40.         /* Set up some basic variables */
  41.         width = info->d_width;
  42.         height = info->d_height;
  43.         src = info->s_pixels;
  44.         srcskip = info->s_skip;
  45.         dst = info->d_pixels;
  46.         dstskip = info->d_skip;
  47.         map = info->table;
  48.         srcskip += width-(width+7)/8;
  49.  
  50.         if ( map ) {
  51.                 while ( height-- ) {
  52.                         Uint8 byte = 0, bit;
  53.                         for ( c=0; c<width; ++c ) {
  54.                                 if ( (c&7) == 0 ) {
  55.                                         byte = *src++;
  56.                                 }
  57.                                 bit = (byte&0x80)>>7;
  58.                                 if ( 1 ) {
  59.                                   *dst = map[bit];
  60.                                 }
  61.                                 dst++;
  62.                                 byte <<= 1;
  63.                         }
  64.                         src += srcskip;
  65.                         dst += dstskip;
  66.                 }
  67.         } else {
  68.                 while ( height-- ) {
  69.                         Uint8 byte = 0, bit;
  70.                         for ( c=0; c<width; ++c ) {
  71.                                 if ( (c&7) == 0 ) {
  72.                                         byte = *src++;
  73.                                 }
  74.                                 bit = (byte&0x80)>>7;
  75.                                 if ( 1 ) {
  76.                                   *dst = bit;
  77.                                 }
  78.                                 dst++;
  79.                                 byte <<= 1;
  80.                         }
  81.                         src += srcskip;
  82.                         dst += dstskip;
  83.                 }
  84.         }
  85. }
  86. static void BlitBto2(SDL_BlitInfo *info)
  87. {
  88.         int c;
  89.         int width, height;
  90.         Uint8 *src;
  91.         Uint16 *map, *dst;
  92.         int srcskip, dstskip;
  93.  
  94.         /* Set up some basic variables */
  95.         width = info->d_width;
  96.         height = info->d_height;
  97.         src = info->s_pixels;
  98.         srcskip = info->s_skip;
  99.         dst = (Uint16 *)info->d_pixels;
  100.         dstskip = info->d_skip/2;
  101.         map = (Uint16 *)info->table;
  102.         srcskip += width-(width+7)/8;
  103.  
  104.         while ( height-- ) {
  105.                 Uint8 byte = 0, bit;
  106.                 for ( c=0; c<width; ++c ) {
  107.                         if ( (c&7) == 0 ) {
  108.                                 byte = *src++;
  109.                         }
  110.                         bit = (byte&0x80)>>7;
  111.                         if ( 1 ) {
  112.                                 *dst = map[bit];
  113.                         }
  114.                         byte <<= 1;
  115.                         dst++;
  116.                 }
  117.                 src += srcskip;
  118.                 dst += dstskip;
  119.         }
  120. }
  121. static void BlitBto3(SDL_BlitInfo *info)
  122. {
  123.         int c, o;
  124.         int width, height;
  125.         Uint8 *src, *map, *dst;
  126.         int srcskip, dstskip;
  127.  
  128.         /* Set up some basic variables */
  129.         width = info->d_width;
  130.         height = info->d_height;
  131.         src = info->s_pixels;
  132.         srcskip = info->s_skip;
  133.         dst = info->d_pixels;
  134.         dstskip = info->d_skip;
  135.         map = info->table;
  136.         srcskip += width-(width+7)/8;
  137.  
  138.         while ( height-- ) {
  139.                 Uint8 byte = 0, bit;
  140.                 for ( c=0; c<width; ++c ) {
  141.                         if ( (c&7) == 0 ) {
  142.                                 byte = *src++;
  143.                         }
  144.                         bit = (byte&0x80)>>7;
  145.                         if ( 1 ) {
  146.                                 o = bit * 4;
  147.                                 dst[0] = map[o++];
  148.                                 dst[1] = map[o++];
  149.                                 dst[2] = map[o++];
  150.                         }
  151.                         byte <<= 1;
  152.                         dst += 3;
  153.                 }
  154.                 src += srcskip;
  155.                 dst += dstskip;
  156.         }
  157. }
  158. static void 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 BlitBto1Key(SDL_BlitInfo *info)
  195. {
  196.         int width = info->d_width;
  197.         int height = info->d_height;
  198.         Uint8 *src = info->s_pixels;
  199.         Uint8 *dst = info->d_pixels;
  200.         int srcskip = info->s_skip;
  201.         int dstskip = info->d_skip;
  202.         Uint32 ckey = info->src->colorkey;
  203.         Uint8 *palmap = info->table;
  204.         int c;
  205.  
  206.         /* Set up some basic variables */
  207.         srcskip += width-(width+7)/8;
  208.  
  209.         if ( palmap ) {
  210.                 while ( height-- ) {
  211.                         Uint8  byte = 0, bit;
  212.                         for ( c=0; c<width; ++c ) {
  213.                                 if ( (c&7) == 0 ) {
  214.                                         byte = *src++;
  215.                                 }
  216.                                 bit = (byte&0x80)>>7;
  217.                                 if ( bit != ckey ) {
  218.                                   *dst = palmap[bit];
  219.                                 }
  220.                                 dst++;
  221.                                 byte <<= 1;
  222.                         }
  223.                         src += srcskip;
  224.                         dst += dstskip;
  225.                 }
  226.         } else {
  227.                 while ( height-- ) {
  228.                         Uint8  byte = 0, bit;
  229.                         for ( c=0; c<width; ++c ) {
  230.                                 if ( (c&7) == 0 ) {
  231.                                         byte = *src++;
  232.                                 }
  233.                                 bit = (byte&0x80)>>7;
  234.                                 if ( bit != ckey ) {
  235.                                   *dst = bit;
  236.                                 }
  237.                                 dst++;
  238.                                 byte <<= 1;
  239.                         }
  240.                         src += srcskip;
  241.                         dst += dstskip;
  242.                 }
  243.         }
  244. }
  245.  
  246. static void BlitBto2Key(SDL_BlitInfo *info)
  247. {
  248.         int width = info->d_width;
  249.         int height = info->d_height;
  250.         Uint8 *src = info->s_pixels;
  251.         Uint16 *dstp = (Uint16 *)info->d_pixels;
  252.         int srcskip = info->s_skip;
  253.         int dstskip = info->d_skip;
  254.         Uint32 ckey = info->src->colorkey;
  255.         Uint8 *palmap = info->table;
  256.         int c;
  257.  
  258.         /* Set up some basic variables */
  259.         srcskip += width-(width+7)/8;
  260.         dstskip /= 2;
  261.  
  262.         while ( height-- ) {
  263.                 Uint8 byte = 0, bit;
  264.                 for ( c=0; c<width; ++c ) {
  265.                         if ( (c&7) == 0 ) {
  266.                                 byte = *src++;
  267.                         }
  268.                         bit = (byte&0x80)>>7;
  269.                         if ( bit != ckey ) {
  270.                                 *dstp=((Uint16 *)palmap)[bit];
  271.                         }
  272.                         byte <<= 1;
  273.                         dstp++;
  274.                 }
  275.                 src += srcskip;
  276.                 dstp += dstskip;
  277.         }
  278. }
  279.  
  280. static void BlitBto3Key(SDL_BlitInfo *info)
  281. {
  282.         int width = info->d_width;
  283.         int height = info->d_height;
  284.         Uint8 *src = info->s_pixels;
  285.         Uint8 *dst = info->d_pixels;
  286.         int srcskip = info->s_skip;
  287.         int dstskip = info->d_skip;
  288.         Uint32 ckey = info->src->colorkey;
  289.         Uint8 *palmap = info->table;
  290.         int c;
  291.  
  292.         /* Set up some basic variables */
  293.         srcskip += width-(width+7)/8;
  294.  
  295.         while ( height-- ) {
  296.                 Uint8  byte = 0, bit;
  297.                 for ( c=0; c<width; ++c ) {
  298.                         if ( (c&7) == 0 ) {
  299.                                 byte = *src++;
  300.                         }
  301.                         bit = (byte&0x80)>>7;
  302.                         if ( bit != ckey ) {
  303.                                 memcpy(dst, &palmap[bit*4], 3);
  304.                         }
  305.                         byte <<= 1;
  306.                         dst += 3;
  307.                 }
  308.                 src += srcskip;
  309.                 dst += dstskip;
  310.         }
  311. }
  312.  
  313. static void BlitBto4Key(SDL_BlitInfo *info)
  314. {
  315.         int width = info->d_width;
  316.         int height = info->d_height;
  317.         Uint8 *src = info->s_pixels;
  318.         Uint32 *dstp = (Uint32 *)info->d_pixels;
  319.         int srcskip = info->s_skip;
  320.         int dstskip = info->d_skip;
  321.         Uint32 ckey = info->src->colorkey;
  322.         Uint8 *palmap = info->table;
  323.         int c;
  324.  
  325.         /* Set up some basic variables */
  326.         srcskip += width-(width+7)/8;
  327.         dstskip /= 4;
  328.  
  329.         while ( height-- ) {
  330.                 Uint8 byte = 0, bit;
  331.                 for ( c=0; c<width; ++c ) {
  332.                         if ( (c&7) == 0 ) {
  333.                                 byte = *src++;
  334.                         }
  335.                         bit = (byte&0x80)>>7;
  336.                         if ( bit != ckey ) {
  337.                                 *dstp=((Uint32 *)palmap)[bit];
  338.                         }
  339.                         byte <<= 1;
  340.                         dstp++;
  341.                 }
  342.                 src += srcskip;
  343.                 dstp += dstskip;
  344.         }
  345. }
  346.  
  347. static void BlitBtoNAlpha(SDL_BlitInfo *info)
  348. {
  349.         int width = info->d_width;
  350.         int height = info->d_height;
  351.         Uint8 *src = info->s_pixels;
  352.         Uint8 *dst = info->d_pixels;
  353.         int srcskip = info->s_skip;
  354.         int dstskip = info->d_skip;
  355.         const SDL_Color *srcpal = info->src->palette->colors;
  356.         SDL_PixelFormat *dstfmt = info->dst;
  357.         int  dstbpp;
  358.         int c;
  359.         const int A = info->src->alpha;
  360.  
  361.         /* Set up some basic variables */
  362.         dstbpp = dstfmt->BytesPerPixel;
  363.         srcskip += width-(width+7)/8;
  364.  
  365.         while ( height-- ) {
  366.                 Uint8 byte = 0, bit;
  367.                 for ( c=0; c<width; ++c ) {
  368.                         if ( (c&7) == 0 ) {
  369.                                 byte = *src++;
  370.                         }
  371.                         bit = (byte&0x80)>>7;
  372.                         if ( 1 ) {
  373.                                 Uint32 pixel;
  374.                                 unsigned sR, sG, sB;
  375.                                 unsigned dR, dG, dB;
  376.                                 sR = srcpal[bit].r;
  377.                                 sG = srcpal[bit].g;
  378.                                 sB = srcpal[bit].b;
  379.                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
  380.                                                         pixel, dR, dG, dB);
  381.                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  382.                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  383.                         }
  384.                         byte <<= 1;
  385.                         dst += dstbpp;
  386.                 }
  387.                 src += srcskip;
  388.                 dst += dstskip;
  389.         }
  390. }
  391.  
  392. static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
  393. {
  394.         int width = info->d_width;
  395.         int height = info->d_height;
  396.         Uint8 *src = info->s_pixels;
  397.         Uint8 *dst = info->d_pixels;
  398.         int srcskip = info->s_skip;
  399.         int dstskip = info->d_skip;
  400.         SDL_PixelFormat *srcfmt = info->src;
  401.         SDL_PixelFormat *dstfmt = info->dst;
  402.         const SDL_Color *srcpal = srcfmt->palette->colors;
  403.         int dstbpp;
  404.         int c;
  405.         const int A = srcfmt->alpha;
  406.         Uint32 ckey = srcfmt->colorkey;
  407.  
  408.         /* Set up some basic variables */
  409.         dstbpp = dstfmt->BytesPerPixel;
  410.         srcskip += width-(width+7)/8;
  411.  
  412.         while ( height-- ) {
  413.                 Uint8  byte = 0, bit;
  414.                 for ( c=0; c<width; ++c ) {
  415.                         if ( (c&7) == 0 ) {
  416.                                 byte = *src++;
  417.                         }
  418.                         bit = (byte&0x80)>>7;
  419.                         if ( bit != ckey ) {
  420.                                 int sR, sG, sB;
  421.                                 int dR, dG, dB;
  422.                                 Uint32 pixel;
  423.                                 sR = srcpal[bit].r;
  424.                                 sG = srcpal[bit].g;
  425.                                 sB = srcpal[bit].b;
  426.                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
  427.                                                         pixel, dR, dG, dB);
  428.                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  429.                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  430.                         }
  431.                         byte <<= 1;
  432.                         dst += dstbpp;
  433.                 }
  434.                 src += srcskip;
  435.                 dst += dstskip;
  436.         }
  437. }
  438.  
  439. static SDL_loblit bitmap_blit[] = {
  440.         NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
  441. };
  442.  
  443. static SDL_loblit colorkey_blit[] = {
  444.     NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
  445. };
  446.  
  447. SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index)
  448. {
  449.         int which;
  450.  
  451.         if ( surface->map->dst->format->BitsPerPixel < 8 ) {
  452.                 which = 0;
  453.         } else {
  454.                 which = surface->map->dst->format->BytesPerPixel;
  455.         }
  456.         switch(blit_index) {
  457.         case 0:                 /* copy */
  458.             return bitmap_blit[which];
  459.  
  460.         case 1:                 /* colorkey */
  461.             return colorkey_blit[which];
  462.  
  463.         case 2:                 /* alpha */
  464.             return which >= 2 ? BlitBtoNAlpha : NULL;
  465.  
  466.         case 4:                 /* alpha + colorkey */
  467.             return which >= 2 ? BlitBtoNAlphaKey : NULL;
  468.         }
  469.         return NULL;
  470. }
  471.  
  472.