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.  
  26. #include "SDL_types.h"
  27. #include "SDL_video.h"
  28. #include "SDL_blit.h"
  29. #include "SDL_sysvideo.h"
  30. #include "SDL_endian.h"
  31.  
  32. /* Functions to blit from 8-bit surfaces to other surfaces */
  33.  
  34. static void Blit1to1(SDL_BlitInfo *info)
  35. {
  36. #ifndef USE_DUFFS_LOOP
  37.         int c;
  38. #endif
  39.         int width, height;
  40.         Uint8 *src, *map, *dst;
  41.         int srcskip, dstskip;
  42.  
  43.         /* Set up some basic variables */
  44.         width = info->d_width;
  45.         height = info->d_height;
  46.         src = info->s_pixels;
  47.         srcskip = info->s_skip;
  48.         dst = info->d_pixels;
  49.         dstskip = info->d_skip;
  50.         map = info->table;
  51.  
  52.         while ( height-- ) {
  53. #ifdef USE_DUFFS_LOOP
  54.                 DUFFS_LOOP(
  55.                         {
  56.                           *dst = map[*src];
  57.                         }
  58.                         dst++;
  59.                         src++;
  60.                 , width);
  61. #else
  62.                 for ( c=width; c; --c ) {
  63.                         *dst = map[*src];
  64.                         dst++;
  65.                         src++;
  66.                 }
  67. #endif
  68.                 src += srcskip;
  69.                 dst += dstskip;
  70.         }
  71. }
  72. /* This is now endian dependent */
  73. #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
  74. #define HI      1
  75. #define LO      0
  76. #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
  77. #define HI      0
  78. #define LO      1
  79. #endif
  80. static void Blit1to2(SDL_BlitInfo *info)
  81. {
  82. #ifndef USE_DUFFS_LOOP
  83.         int c;
  84. #endif
  85.         int width, height;
  86.         Uint8 *src, *dst;
  87.         Uint16 *map;
  88.         int srcskip, dstskip;
  89.  
  90.         /* Set up some basic variables */
  91.         width = info->d_width;
  92.         height = info->d_height;
  93.         src = info->s_pixels;
  94.         srcskip = info->s_skip;
  95.         dst = info->d_pixels;
  96.         dstskip = info->d_skip;
  97.         map = (Uint16 *)info->table;
  98.  
  99. #ifdef USE_DUFFS_LOOP
  100.         while ( height-- ) {
  101.                 DUFFS_LOOP(
  102.                 {
  103.                         *(Uint16 *)dst = map[*src++];
  104.                         dst += 2;
  105.                 },
  106.                 width);
  107.                 src += srcskip;
  108.                 dst += dstskip;
  109.         }
  110. #else
  111.         /* Memory align at 4-byte boundary, if necessary */
  112.         if ( (long)dst & 0x03 ) {
  113.                 /* Don't do anything if width is 0 */
  114.                 if ( width == 0 ) {
  115.                         return;
  116.                 }
  117.                 --width;
  118.  
  119.                 while ( height-- ) {
  120.                         /* Perform copy alignment */
  121.                         *(Uint16 *)dst = map[*src++];
  122.                         dst += 2;
  123.  
  124.                         /* Copy in 4 pixel chunks */
  125.                         for ( c=width/4; c; --c ) {
  126.                                 *(Uint32 *)dst =
  127.                                         (map[src[HI]]<<16)|(map[src[LO]]);
  128.                                 src += 2;
  129.                                 dst += 4;
  130.                                 *(Uint32 *)dst =
  131.                                         (map[src[HI]]<<16)|(map[src[LO]]);
  132.                                 src += 2;
  133.                                 dst += 4;
  134.                         }
  135.                         /* Get any leftovers */
  136.                         switch (width & 3) {
  137.                                 case 3:
  138.                                         *(Uint16 *)dst = map[*src++];
  139.                                         dst += 2;
  140.                                 case 2:
  141.                                         *(Uint32 *)dst =
  142.                                           (map[src[HI]]<<16)|(map[src[LO]]);
  143.                                         src += 2;
  144.                                         dst += 4;
  145.                                         break;
  146.                                 case 1:
  147.                                         *(Uint16 *)dst = map[*src++];
  148.                                         dst += 2;
  149.                                         break;
  150.                         }
  151.                         src += srcskip;
  152.                         dst += dstskip;
  153.                 }
  154.         } else {
  155.                 while ( height-- ) {
  156.                         /* Copy in 4 pixel chunks */
  157.                         for ( c=width/4; c; --c ) {
  158.                                 *(Uint32 *)dst =
  159.                                         (map[src[HI]]<<16)|(map[src[LO]]);
  160.                                 src += 2;
  161.                                 dst += 4;
  162.                                 *(Uint32 *)dst =
  163.                                         (map[src[HI]]<<16)|(map[src[LO]]);
  164.                                 src += 2;
  165.                                 dst += 4;
  166.                         }
  167.                         /* Get any leftovers */
  168.                         switch (width & 3) {
  169.                                 case 3:
  170.                                         *(Uint16 *)dst = map[*src++];
  171.                                         dst += 2;
  172.                                 case 2:
  173.                                         *(Uint32 *)dst =
  174.                                           (map[src[HI]]<<16)|(map[src[LO]]);
  175.                                         src += 2;
  176.                                         dst += 4;
  177.                                         break;
  178.                                 case 1:
  179.                                         *(Uint16 *)dst = map[*src++];
  180.                                         dst += 2;
  181.                                         break;
  182.                         }
  183.                         src += srcskip;
  184.                         dst += dstskip;
  185.                 }
  186.         }
  187. #endif /* USE_DUFFS_LOOP */
  188. }
  189. static void Blit1to3(SDL_BlitInfo *info)
  190. {
  191. #ifndef USE_DUFFS_LOOP
  192.         int c;
  193. #endif
  194.         int o;
  195.         int width, height;
  196.         Uint8 *src, *map, *dst;
  197.         int srcskip, dstskip;
  198.  
  199.         /* Set up some basic variables */
  200.         width = info->d_width;
  201.         height = info->d_height;
  202.         src = info->s_pixels;
  203.         srcskip = info->s_skip;
  204.         dst = info->d_pixels;
  205.         dstskip = info->d_skip;
  206.         map = info->table;
  207.  
  208.         while ( height-- ) {
  209. #ifdef USE_DUFFS_LOOP
  210.                 DUFFS_LOOP(
  211.                         {
  212.                                 o = *src * 4;
  213.                                 dst[0] = map[o++];
  214.                                 dst[1] = map[o++];
  215.                                 dst[2] = map[o++];
  216.                         }
  217.                         src++;
  218.                         dst += 3;
  219.                 , width);
  220. #else
  221.                 for ( c=width; c; --c ) {
  222.                         o = *src * 4;
  223.                         dst[0] = map[o++];
  224.                         dst[1] = map[o++];
  225.                         dst[2] = map[o++];
  226.                         src++;
  227.                         dst += 3;
  228.                 }
  229. #endif /* USE_DUFFS_LOOP */
  230.                 src += srcskip;
  231.                 dst += dstskip;
  232.         }
  233. }
  234. static void Blit1to4(SDL_BlitInfo *info)
  235. {
  236. #ifndef USE_DUFFS_LOOP
  237.         int c;
  238. #endif
  239.         int width, height;
  240.         Uint8 *src;
  241.         Uint32 *map, *dst;
  242.         int srcskip, dstskip;
  243.  
  244.         /* Set up some basic variables */
  245.         width = info->d_width;
  246.         height = info->d_height;
  247.         src = info->s_pixels;
  248.         srcskip = info->s_skip;
  249.         dst = (Uint32 *)info->d_pixels;
  250.         dstskip = info->d_skip/4;
  251.         map = (Uint32 *)info->table;
  252.  
  253.         while ( height-- ) {
  254. #ifdef USE_DUFFS_LOOP
  255.                 DUFFS_LOOP(
  256.                         *dst++ = map[*src++];
  257.                 , width);
  258. #else
  259.                 for ( c=width/4; c; --c ) {
  260.                         *dst++ = map[*src++];
  261.                         *dst++ = map[*src++];
  262.                         *dst++ = map[*src++];
  263.                         *dst++ = map[*src++];
  264.                 }
  265.                 switch ( width & 3 ) {
  266.                         case 3:
  267.                                 *dst++ = map[*src++];
  268.                         case 2:
  269.                                 *dst++ = map[*src++];
  270.                         case 1:
  271.                                 *dst++ = map[*src++];
  272.                 }
  273. #endif /* USE_DUFFS_LOOP */
  274.                 src += srcskip;
  275.                 dst += dstskip;
  276.         }
  277. }
  278.  
  279. static void Blit1to1Key(SDL_BlitInfo *info)
  280. {
  281.         int width = info->d_width;
  282.         int height = info->d_height;
  283.         Uint8 *src = info->s_pixels;
  284.         int srcskip = info->s_skip;
  285.         Uint8 *dst = info->d_pixels;
  286.         int dstskip = info->d_skip;
  287.         Uint8 *palmap = info->table;
  288.         Uint32 ckey = info->src->colorkey;
  289.        
  290.         if ( palmap ) {
  291.                 while ( height-- ) {
  292.                         DUFFS_LOOP(
  293.                         {
  294.                                 if ( *src != ckey ) {
  295.                                   *dst = palmap[*src];
  296.                                 }
  297.                                 dst++;
  298.                                 src++;
  299.                         },
  300.                         width);
  301.                         src += srcskip;
  302.                         dst += dstskip;
  303.                 }
  304.         } else {
  305.                 while ( height-- ) {
  306.                         DUFFS_LOOP(
  307.                         {
  308.                                 if ( *src != ckey ) {
  309.                                   *dst = *src;
  310.                                 }
  311.                                 dst++;
  312.                                 src++;
  313.                         },
  314.                         width);
  315.                         src += srcskip;
  316.                         dst += dstskip;
  317.                 }
  318.         }
  319. }
  320.  
  321. static void Blit1to2Key(SDL_BlitInfo *info)
  322. {
  323.         int width = info->d_width;
  324.         int height = info->d_height;
  325.         Uint8 *src = info->s_pixels;
  326.         int srcskip = info->s_skip;
  327.         Uint16 *dstp = (Uint16 *)info->d_pixels;
  328.         int dstskip = info->d_skip;
  329.         Uint16 *palmap = (Uint16 *)info->table;
  330.         Uint32 ckey = info->src->colorkey;
  331.  
  332.         /* Set up some basic variables */
  333.         dstskip /= 2;
  334.  
  335.         while ( height-- ) {
  336.                 DUFFS_LOOP(
  337.                 {
  338.                         if ( *src != ckey ) {
  339.                                 *dstp=palmap[*src];
  340.                         }
  341.                         src++;
  342.                         dstp++;
  343.                 },
  344.                 width);
  345.                 src += srcskip;
  346.                 dstp += dstskip;
  347.         }
  348. }
  349.  
  350. static void Blit1to3Key(SDL_BlitInfo *info)
  351. {
  352.         int width = info->d_width;
  353.         int height = info->d_height;
  354.         Uint8 *src = info->s_pixels;
  355.         int srcskip = info->s_skip;
  356.         Uint8 *dst = info->d_pixels;
  357.         int dstskip = info->d_skip;
  358.         Uint8 *palmap = info->table;
  359.         Uint32 ckey = info->src->colorkey;
  360.         int o;
  361.  
  362.         while ( height-- ) {
  363.                 DUFFS_LOOP(
  364.                 {
  365.                         if ( *src != ckey ) {
  366.                                 o = *src * 4;
  367.                                 dst[0] = palmap[o++];
  368.                                 dst[1] = palmap[o++];
  369.                                 dst[2] = palmap[o++];
  370.                         }
  371.                         src++;
  372.                         dst += 3;
  373.                 },
  374.                 width);
  375.                 src += srcskip;
  376.                 dst += dstskip;
  377.         }
  378. }
  379.  
  380. static void Blit1to4Key(SDL_BlitInfo *info)
  381. {
  382.         int width = info->d_width;
  383.         int height = info->d_height;
  384.         Uint8 *src = info->s_pixels;
  385.         int srcskip = info->s_skip;
  386.         Uint32 *dstp = (Uint32 *)info->d_pixels;
  387.         int dstskip = info->d_skip;
  388.         Uint32 *palmap = (Uint32 *)info->table;
  389.         Uint32 ckey = info->src->colorkey;
  390.  
  391.         /* Set up some basic variables */
  392.         dstskip /= 4;
  393.  
  394.         while ( height-- ) {
  395.                 DUFFS_LOOP(
  396.                 {
  397.                         if ( *src != ckey ) {
  398.                                 *dstp = palmap[*src];
  399.                         }
  400.                         src++;
  401.                         dstp++;
  402.                 },
  403.                 width);
  404.                 src += srcskip;
  405.                 dstp += dstskip;
  406.         }
  407. }
  408.  
  409. static void Blit1toNAlpha(SDL_BlitInfo *info)
  410. {
  411.         int width = info->d_width;
  412.         int height = info->d_height;
  413.         Uint8 *src = info->s_pixels;
  414.         int srcskip = info->s_skip;
  415.         Uint8 *dst = info->d_pixels;
  416.         int dstskip = info->d_skip;
  417.         SDL_PixelFormat *dstfmt = info->dst;
  418.         const SDL_Color *srcpal = info->src->palette->colors;
  419.         int dstbpp;
  420.         const int A = info->src->alpha;
  421.  
  422.         /* Set up some basic variables */
  423.         dstbpp = dstfmt->BytesPerPixel;
  424.  
  425.         while ( height-- ) {
  426.                 int sR, sG, sB;
  427.                 int dR, dG, dB;
  428.                 DUFFS_LOOP4(
  429.                         {
  430.                                 Uint32 pixel;
  431.                                 sR = srcpal[*src].r;
  432.                                 sG = srcpal[*src].g;
  433.                                 sB = srcpal[*src].b;
  434.                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
  435.                                              pixel, dR, dG, dB);
  436.                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  437.                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  438.                                 src++;
  439.                                 dst += dstbpp;
  440.                         },
  441.                         width);
  442.                 src += srcskip;
  443.                 dst += dstskip;
  444.         }
  445. }
  446.  
  447. static void Blit1toNAlphaKey(SDL_BlitInfo *info)
  448. {
  449.         int width = info->d_width;
  450.         int height = info->d_height;
  451.         Uint8 *src = info->s_pixels;
  452.         int srcskip = info->s_skip;
  453.         Uint8 *dst = info->d_pixels;
  454.         int dstskip = info->d_skip;
  455.         SDL_PixelFormat *srcfmt = info->src;
  456.         SDL_PixelFormat *dstfmt = info->dst;
  457.         const SDL_Color *srcpal = info->src->palette->colors;
  458.         Uint32 ckey = srcfmt->colorkey;
  459.         int dstbpp;
  460.         const int A = srcfmt->alpha;
  461.  
  462.         /* Set up some basic variables */
  463.         dstbpp = dstfmt->BytesPerPixel;
  464.  
  465.         while ( height-- ) {
  466.                 int sR, sG, sB;
  467.                 int dR, dG, dB;
  468.                 DUFFS_LOOP(
  469.                 {
  470.                         if ( *src != ckey ) {
  471.                                 Uint32 pixel;
  472.                                 sR = srcpal[*src].r;
  473.                                 sG = srcpal[*src].g;
  474.                                 sB = srcpal[*src].b;
  475.                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
  476.                                                         pixel, dR, dG, dB);
  477.                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  478.                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  479.                         }
  480.                         src++;
  481.                         dst += dstbpp;
  482.                 },
  483.                 width);
  484.                 src += srcskip;
  485.                 dst += dstskip;
  486.         }
  487. }
  488.  
  489. static SDL_loblit one_blit[] = {
  490.         NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
  491. };
  492.  
  493. static SDL_loblit one_blitkey[] = {
  494.         NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
  495. };
  496.  
  497. SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
  498. {
  499.         int which;
  500.         SDL_PixelFormat *dstfmt;
  501.  
  502.         dstfmt = surface->map->dst->format;
  503.         if ( dstfmt->BitsPerPixel < 8 ) {
  504.                 which = 0;
  505.         } else {
  506.                 which = dstfmt->BytesPerPixel;
  507.         }
  508.         switch(blit_index) {
  509.         case 0:                 /* copy */
  510.             return one_blit[which];
  511.  
  512.         case 1:                 /* colorkey */
  513.             return one_blitkey[which];
  514.  
  515.         case 2:                 /* alpha */
  516.             /* Supporting 8bpp->8bpp alpha is doable but requires lots of
  517.                tables which consume space and takes time to precompute,
  518.                so is better left to the user */
  519.             return which >= 2 ? Blit1toNAlpha : NULL;
  520.  
  521.         case 3:                 /* alpha + colorkey */
  522.             return which >= 2 ? Blit1toNAlphaKey : NULL;
  523.  
  524.         }
  525.         return NULL;
  526. }
  527.