00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 )
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 )
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 )
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
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);
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);
00364 }
00365
00366 target->unlock();
00367 }