Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

blit_opaque.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: blit_opaque.cpp,v 1.1 2001/03/06 15:09:17 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #include "Core/precomp.h"
00016 #include "API/Display/Display/surfaceprovider.h"
00017 #include <Display/Display/Generic/pixeldata.h>
00018 
00019 #include <Display/Display/Generic/blit_opaque.h>
00020 #ifdef __BEOS__
00021         #include "Core/System/Generic/string_asm.h"
00022 #else
00023         #define fast_memmove memcpy
00024 #endif
00025 
00026 CL_Blit_Opaque::CL_Blit_Opaque(
00027         CL_SurfaceProvider *provider,
00028         int bytes_per_pixel,
00029         CL_Target *target)
00030 {
00031         width = provider->get_width();
00032         height = provider->get_height();
00033         no_sprs = provider->get_num_frames();
00034         image_pitch = width*bytes_per_pixel;
00035         image_bytes_per_pixel = bytes_per_pixel;
00036         image = new unsigned char[width*height*no_sprs*bytes_per_pixel];
00037 
00038         CL_PixelData input(
00039                 target->get_red_mask(),
00040                 target->get_green_mask(),
00041                 target->get_blue_mask(),
00042                 target->get_alpha_mask(),
00043                 provider,
00044                 bytes_per_pixel);
00045 
00046         for (unsigned int y=0; y<height*no_sprs; y++)
00047                 fast_memmove(
00048                         (char *) &image[y*image_pitch],
00049                         (char *) input.get_line_pixel(y),
00050                         image_pitch);
00051 }
00052 
00053 CL_Blit_Opaque::~CL_Blit_Opaque()
00054 {
00055         delete[] image;
00056 }
00057 
00058 void CL_Blit_Opaque::blt_noclip(
00059         CL_Target *target,
00060         int x,
00061         int y,
00062         int spr_no)
00063 {
00064         target->lock();
00065         
00066         unsigned int dest_bytes_per_pixel = (target->get_depth()+7)/8;
00067         unsigned int dest_pitch = target->get_pitch();
00068 
00069         unsigned char *src = image;
00070         unsigned char *dest = (unsigned char *) target->get_data();
00071 
00072         src += image_pitch*height*spr_no;
00073         dest += x*dest_bytes_per_pixel + y*dest_pitch;
00074 
00075         for (unsigned int yy=0; yy<height; yy++)
00076         {
00077                 fast_memmove((char *) dest, (char *) src, image_pitch);
00078 
00079                 src += image_pitch;
00080                 dest += dest_pitch;
00081         }
00082 
00083         target->unlock();
00084 }
00085 
00086 void CL_Blit_Opaque::blt_clip(
00087         CL_Target *target,
00088         int x,
00089         int y,
00090         int spr_no,
00091         const CL_ClipRect & clip)
00092 {
00093         CL_ClipRect dest_clip(x, y, x+width, y+height);
00094         CL_ClipRect clipped = clip.clip(dest_clip);
00095         
00096         if (clipped.m_x1 >= clipped.m_x2 ||
00097             clipped.m_y1 >= clipped.m_y2) return;
00098 
00099         int t_width = target->get_width();
00100         int t_height = target->get_height();
00101 
00102         if( clipped.m_x2 < 0 || clipped.m_x1 > t_width ||
00103             clipped.m_y2 < 0 || clipped.m_y1 > t_height ) return;
00104 
00105         target->lock();
00106 
00107         unsigned int dest_bytes_per_pixel = (target->get_depth()+7)/8;
00108         unsigned int dest_pitch = target->get_pitch();
00109 
00110         unsigned char *src = image;
00111         unsigned char *dest = (unsigned char *) target->get_data();
00112 
00113         src += image_pitch*height*spr_no;
00114         src += (clipped.m_x1-dest_clip.m_x1)*dest_bytes_per_pixel +
00115                (clipped.m_y1-dest_clip.m_y1)*image_pitch;
00116         dest += clipped.m_x1*dest_bytes_per_pixel + clipped.m_y1*dest_pitch;
00117 
00118         if ( clipped.m_x1 < 0 ) dest = (unsigned char *) target->get_data()
00119                                                                         + clipped.m_y1*dest_pitch;
00120 
00121         if ( clipped.m_y1 < 0 && clipped.m_x1 >= 0 )
00122         {
00123                 src = image;
00124                 src += image_pitch*height*spr_no;
00125                 src += (-y + clipped.m_y1) * image_pitch;
00126                 src += ( -clipped.m_y1 * image_pitch ) + ( (clipped.m_x1-x) * image_bytes_per_pixel );
00127                 dest = (unsigned char *) target->get_data() + clipped.m_x1*dest_bytes_per_pixel;
00128         }
00129         else if ( clipped.m_y1 < 0 && clipped.m_x1 < 0 )
00130         {
00131                 src = image;
00132                 src += image_pitch*height*spr_no;
00133                 src += (-y + clipped.m_y1) * image_pitch;
00134                 src += -clipped.m_y1 * image_pitch;
00135                 src += (-x + clipped.m_x1) * image_bytes_per_pixel;
00136                 dest = (unsigned char *) target->get_data();
00137         }
00138 
00139         int rows = clipped.m_y2 - clipped.m_y1;
00140         if( rows > clipped.m_y2 ) rows = clipped.m_y2;
00141         if( rows + clipped.m_y1 > t_height )
00142                 rows = t_height - clipped.m_y1;
00143 
00144         for (int yy=0; yy<rows; yy++)
00145         {
00146                 if ( clipped.m_x1 >= 0 && clipped.m_x2 <= t_width ) // line fits on target
00147                 {
00148                         fast_memmove((char *) dest, (char *) src, sizeof(unsigned char) * (clipped.m_x2 - clipped.m_x1) * dest_bytes_per_pixel );
00149                 }
00150                 else if ( clipped.m_x1 > 0 && clipped.m_x2 > t_width ) // Cut end.
00151                 {
00152                         short length = t_width - clipped.m_x1;
00153                         fast_memmove((char *) dest, (char *) src, sizeof(unsigned char) * length * dest_bytes_per_pixel );
00154                 }
00155                 else if ( clipped.m_x1 < 0 && clipped.m_x2 > t_width ) // Cut both ends.
00156                 {
00157                         short length_begin = -clipped.m_x1;
00158                         fast_memmove( (char *) dest, (char *)(src+ (length_begin * dest_bytes_per_pixel)),
00159                                                  (sizeof(unsigned char) * t_width * image_bytes_per_pixel) );
00160                 }
00161                 else  // cut beginning of line.
00162                 {
00163                         short length_begin = -clipped.m_x1;
00164                         fast_memmove( (char *) dest, (char *)(src + (length_begin * dest_bytes_per_pixel)),
00165                                                  (sizeof(unsigned char) * (clipped.m_x2) * dest_bytes_per_pixel) );
00166                 }
00167                 
00168                 src += image_pitch;
00169                 dest += dest_pitch;
00170         }
00171         target->unlock();
00172 }
00173 
00174 void CL_Blit_Opaque::blt_scale_noclip(
00175         CL_Target *target,
00176         int x,
00177         int y,
00178         int dest_width,
00179         int dest_height,
00180         int spr_no)
00181 {
00182         if (dest_width <= 0 || dest_height <= 0) return;
00183         target->lock();
00184 
00185         unsigned int dest_bytes_per_pixel = (target->get_depth()+7)/8;
00186         unsigned int dest_pitch = target->get_pitch();
00187 
00188         unsigned char *_dest = (unsigned char*) target->get_data();
00189         _dest += x*dest_bytes_per_pixel + y*dest_pitch;
00190 
00191         unsigned int stepX = (width<<16) / dest_width;
00192         unsigned int stepY = (height<<16) / dest_height;
00193         unsigned int posX = 0;
00194         unsigned int posY = 0;
00195 
00196         switch(dest_bytes_per_pixel)
00197         {
00198         case 1:
00199                 {
00200                         for (int yy=0; yy<dest_height; yy++)
00201                         {
00202                                 unsigned char *src = (unsigned char *) image;
00203                                 src += (spr_no*height+(posY>>16))*width;
00204 
00205                                 unsigned char *dest = (unsigned char *) (_dest+yy*dest_pitch);
00206 
00207                                 posX=0;
00208                                 for (int xx=0; xx<dest_width; xx++)
00209                                 {
00210                                         dest[xx] = src[(posX>>16)];
00211                                         posX+=stepX;
00212                                 }
00213                                 posY+=stepY;
00214                         }
00215                 }
00216                 break;
00217         
00218         case 2:
00219                 {
00220                         for (int yy=0; yy<dest_height; yy++)
00221                         {
00222                                 unsigned short *src = (unsigned short *) image;
00223                                 src += (spr_no*height+(posY>>16))*width;
00224 
00225                                 unsigned short *dest = (unsigned short *) (_dest+yy*dest_pitch);
00226 
00227                                 posX=0;
00228                                 for (int xx=0; xx<dest_width; xx++)
00229                                 {
00230                                         dest[xx] = src[(posX>>16)];
00231                                         posX+=stepX;
00232                                 }
00233                                 posY+=stepY;
00234                         }
00235                 }
00236                 break;
00237 
00238         case 4:
00239                 {
00240                         for (int yy=0; yy<dest_height; yy++)
00241                         {
00242                                 unsigned int *src = (unsigned int *) image;
00243                                 src += (spr_no*height+(posY>>16))*width;
00244 
00245                                 unsigned int *dest = (unsigned int *) (_dest+yy*dest_pitch);
00246 
00247                                 posX=0;
00248                                 for (int xx=0; xx<dest_width; xx++)
00249                                 {
00250                                         dest[xx] = src[(posX>>16)];
00251                                         posX+=stepX;
00252                                 }
00253                                 posY+=stepY;
00254                         }
00255                 }
00256                 break;
00257 
00258         default:
00259                 cl_assert(false); // unsupported pixel depth!
00260         }
00261         target->unlock();
00262 }
00263 
00264 void CL_Blit_Opaque::blt_scale_clip(
00265         CL_Target * target,
00266         int x,
00267         int y,
00268         int dest_width,
00269         int dest_height,
00270         int spr_no,
00271         const CL_ClipRect & clip)
00272 {
00273         if (dest_width <= 0 || dest_height <= 0) return;
00274 
00275         CL_ClipRect dest_clip(x, y, x+dest_width, y+dest_height);
00276         CL_ClipRect clipped = clip.clip(dest_clip);
00277         
00278         if (clipped.m_x1 >= clipped.m_x2 ||
00279             clipped.m_y1 >= clipped.m_y2) return;
00280         target->lock();
00281 
00282         unsigned int dest_bytes_per_pixel = (target->get_depth()+7)/8;
00283         unsigned int dest_pitch = target->get_pitch();
00284 
00285         unsigned char *_dest = (unsigned char*) target->get_data();
00286         _dest += clipped.m_x1*dest_bytes_per_pixel + clipped.m_y1*dest_pitch;
00287 
00288         unsigned int stepX = (width<<16) / dest_width;
00289         unsigned int stepY = (height<<16) / dest_height;
00290 
00291         unsigned int clipX = stepX*(clipped.m_x1-x);
00292         unsigned int clipY = stepY*(clipped.m_y1-y);
00293 
00294         unsigned int posX = clipX;
00295         unsigned int posY = clipY;
00296 
00297         dest_width = clipped.m_x2-clipped.m_x1;
00298         dest_height = clipped.m_y2-clipped.m_y1;
00299 
00300         switch(dest_bytes_per_pixel)
00301         {
00302         case 1:
00303                 {
00304                         for (int yy=0; yy<dest_height; yy++)
00305                         {
00306                                 unsigned char *src = (unsigned char *) image;
00307                                 src += (spr_no*height+(posY>>16))*width;
00308 
00309                                 unsigned char *dest = (unsigned char *) (_dest+yy*dest_pitch);
00310 
00311                                 posX=clipX;
00312                                 for (int xx=0; xx<dest_width; xx++)
00313                                 {
00314                                         dest[xx] = src[(posX>>16)];
00315                                         posX+=stepX;
00316                                 }
00317                                 posY+=stepY;
00318                         }
00319                 }
00320                 break;
00321         
00322         case 2:
00323                 {
00324                         for (int yy=0; yy<dest_height; yy++)
00325                         {
00326                                 unsigned short *src = (unsigned short *) image;
00327                                 src += (spr_no*height+(posY>>16))*width;
00328 
00329                                 unsigned short *dest = (unsigned short *) (_dest+yy*dest_pitch);
00330 
00331                                 posX=clipX;
00332                                 for (int xx=0; xx<dest_width; xx++)
00333                                 {
00334                                         dest[xx] = src[(posX>>16)];
00335                                         posX+=stepX;
00336                                 }
00337                                 posY+=stepY;
00338                         }
00339                 }
00340                 break;
00341 
00342         case 4:
00343                 {
00344                         for (int yy=0; yy<dest_height; yy++)
00345                         {
00346                                 unsigned int *src = (unsigned int *) image;
00347                                 src += (spr_no*height+(posY>>16))*width;
00348 
00349                                 unsigned int *dest = (unsigned int *) (_dest+yy*dest_pitch);
00350 
00351                                 posX=clipX;
00352                                 for (int xx=0; xx<dest_width; xx++)
00353                                 {
00354                                         dest[xx] = src[(posX>>16)];
00355                                         posX+=stepX;
00356                                 }
00357                                 posY+=stepY;
00358                         }
00359                 }
00360                 break;
00361 
00362         default:
00363                 cl_assert(false); // unsupported pixel depth!
00364         }
00365         
00366         target->unlock();
00367 }

Generated at Wed Apr 4 19:53:58 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001