symbian-qemu-0.9.1-12/libsdl-trunk/src/video/SDL_blit.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 #ifndef _SDL_blit_h
       
    25 #define _SDL_blit_h
       
    26 
       
    27 #include "SDL_endian.h"
       
    28 
       
    29 /* The structure passed to the low level blit functions */
       
    30 typedef struct {
       
    31 	Uint8 *s_pixels;
       
    32 	int s_width;
       
    33 	int s_height;
       
    34 	int s_skip;
       
    35 	Uint8 *d_pixels;
       
    36 	int d_width;
       
    37 	int d_height;
       
    38 	int d_skip;
       
    39 	void *aux_data;
       
    40 	SDL_PixelFormat *src;
       
    41 	Uint8 *table;
       
    42 	SDL_PixelFormat *dst;
       
    43 } SDL_BlitInfo;
       
    44 
       
    45 /* The type definition for the low level blit functions */
       
    46 typedef void (*SDL_loblit)(SDL_BlitInfo *info);
       
    47 
       
    48 /* This is the private info structure for software accelerated blits */
       
    49 struct private_swaccel {
       
    50 	SDL_loblit blit;
       
    51 	void *aux_data;
       
    52 };
       
    53 
       
    54 /* Blit mapping definition */
       
    55 typedef struct SDL_BlitMap {
       
    56 	SDL_Surface *dst;
       
    57 	int identity;
       
    58 	Uint8 *table;
       
    59 	SDL_blit hw_blit;
       
    60 	SDL_blit sw_blit;
       
    61 	struct private_hwaccel *hw_data;
       
    62 	struct private_swaccel *sw_data;
       
    63 
       
    64 	/* the version count matches the destination; mismatch indicates
       
    65 	   an invalid mapping */
       
    66         unsigned int format_version;
       
    67 } SDL_BlitMap;
       
    68 
       
    69 
       
    70 /* Functions found in SDL_blit.c */
       
    71 extern int SDL_CalculateBlit(SDL_Surface *surface);
       
    72 
       
    73 /* Functions found in SDL_blit_{0,1,N,A}.c */
       
    74 extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex);
       
    75 extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex);
       
    76 extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex);
       
    77 extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex);
       
    78 
       
    79 /*
       
    80  * Useful macros for blitting routines
       
    81  */
       
    82 
       
    83 #define FORMAT_EQUAL(A, B)						\
       
    84     ((A)->BitsPerPixel == (B)->BitsPerPixel				\
       
    85      && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask))
       
    86 
       
    87 /* Load pixel of the specified format from a buffer and get its R-G-B values */
       
    88 /* FIXME: rescale values to 0..255 here? */
       
    89 #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)				\
       
    90 {									\
       
    91 	r = (((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss); 		\
       
    92 	g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss); 		\
       
    93 	b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss); 		\
       
    94 }
       
    95 #define RGB_FROM_RGB565(Pixel, r, g, b)					\
       
    96 {									\
       
    97 	r = (((Pixel&0xF800)>>11)<<3);		 			\
       
    98 	g = (((Pixel&0x07E0)>>5)<<2); 					\
       
    99 	b = ((Pixel&0x001F)<<3); 					\
       
   100 }
       
   101 #define RGB_FROM_RGB555(Pixel, r, g, b)					\
       
   102 {									\
       
   103 	r = (((Pixel&0x7C00)>>10)<<3);		 			\
       
   104 	g = (((Pixel&0x03E0)>>5)<<3); 					\
       
   105 	b = ((Pixel&0x001F)<<3); 					\
       
   106 }
       
   107 #define RGB_FROM_RGB888(Pixel, r, g, b)					\
       
   108 {									\
       
   109 	r = ((Pixel&0xFF0000)>>16);		 			\
       
   110 	g = ((Pixel&0xFF00)>>8);		 			\
       
   111 	b = (Pixel&0xFF);			 			\
       
   112 }
       
   113 #define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel)				   \
       
   114 do {									   \
       
   115 	switch (bpp) {							   \
       
   116 		case 2:							   \
       
   117 			Pixel = *((Uint16 *)(buf));			   \
       
   118 		break;							   \
       
   119 									   \
       
   120 		case 3: {						   \
       
   121 		        Uint8 *B = (Uint8 *)(buf);			   \
       
   122 			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		   \
       
   123 			        Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
       
   124 			} else {					   \
       
   125 			        Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
       
   126 			}						   \
       
   127 		}							   \
       
   128 		break;							   \
       
   129 									   \
       
   130 		case 4:							   \
       
   131 			Pixel = *((Uint32 *)(buf));			   \
       
   132 		break;							   \
       
   133 									   \
       
   134 		default:						   \
       
   135 			Pixel = 0; /* appease gcc */			   \
       
   136 		break;							   \
       
   137 	}								   \
       
   138 } while(0)
       
   139 
       
   140 #define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b)			   \
       
   141 do {									   \
       
   142 	switch (bpp) {							   \
       
   143 		case 2:							   \
       
   144 			Pixel = *((Uint16 *)(buf));			   \
       
   145 		break;							   \
       
   146 									   \
       
   147 		case 3: {						   \
       
   148 		        Uint8 *B = (Uint8 *)buf;			   \
       
   149 			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		   \
       
   150 			        Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
       
   151 			} else {					   \
       
   152 			        Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
       
   153 			}						   \
       
   154 		}							   \
       
   155 		break;							   \
       
   156 									   \
       
   157 		case 4:							   \
       
   158 			Pixel = *((Uint32 *)(buf));			   \
       
   159 		break;							   \
       
   160 									   \
       
   161 	        default:						   \
       
   162 		        Pixel = 0;	/* prevent gcc from complaining */ \
       
   163 		break;							   \
       
   164 	}								   \
       
   165 	RGB_FROM_PIXEL(Pixel, fmt, r, g, b);				   \
       
   166 } while(0)
       
   167 
       
   168 /* Assemble R-G-B values into a specified pixel format and store them */
       
   169 #ifdef __NDS__ // FIXME
       
   170 #define PIXEL_FROM_RGB(Pixel, fmt, r, g, b)				\
       
   171 {									\
       
   172 	Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|				\
       
   173 		((g>>fmt->Gloss)<<fmt->Gshift)|				\
       
   174 		((b>>fmt->Bloss)<<fmt->Bshift) | (1<<15);				\
       
   175 }
       
   176 #else
       
   177 #define PIXEL_FROM_RGB(Pixel, fmt, r, g, b)				\
       
   178 {									\
       
   179 	Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|				\
       
   180 		((g>>fmt->Gloss)<<fmt->Gshift)|				\
       
   181 		((b>>fmt->Bloss)<<fmt->Bshift);				\
       
   182 }
       
   183 #endif // __NDS__ FIXME
       
   184 #define RGB565_FROM_RGB(Pixel, r, g, b)					\
       
   185 {									\
       
   186 	Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);			\
       
   187 }
       
   188 #define RGB555_FROM_RGB(Pixel, r, g, b)					\
       
   189 {									\
       
   190 	Pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3);			\
       
   191 }
       
   192 #define RGB888_FROM_RGB(Pixel, r, g, b)					\
       
   193 {									\
       
   194 	Pixel = (r<<16)|(g<<8)|b;					\
       
   195 }
       
   196 #define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) 				\
       
   197 {									\
       
   198 	switch (bpp) {							\
       
   199 		case 2: {						\
       
   200 			Uint16 Pixel;					\
       
   201 									\
       
   202 			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
       
   203 			*((Uint16 *)(buf)) = Pixel;			\
       
   204 		}							\
       
   205 		break;							\
       
   206 									\
       
   207 		case 3: {						\
       
   208                         if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		\
       
   209 			        *((buf)+fmt->Rshift/8) = r;		\
       
   210 				*((buf)+fmt->Gshift/8) = g;		\
       
   211 				*((buf)+fmt->Bshift/8) = b;		\
       
   212 			} else {					\
       
   213 			        *((buf)+2-fmt->Rshift/8) = r;		\
       
   214 				*((buf)+2-fmt->Gshift/8) = g;		\
       
   215 				*((buf)+2-fmt->Bshift/8) = b;		\
       
   216 			}						\
       
   217 		}							\
       
   218 		break;							\
       
   219 									\
       
   220 		case 4: {						\
       
   221 			Uint32 Pixel;					\
       
   222 									\
       
   223 			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
       
   224 			*((Uint32 *)(buf)) = Pixel;			\
       
   225 		}							\
       
   226 		break;							\
       
   227 	}								\
       
   228 }
       
   229 #define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask)		\
       
   230 {									\
       
   231 	switch (bpp) {							\
       
   232 		case 2: {						\
       
   233 			Uint16 *bufp;					\
       
   234 			Uint16 Pixel;					\
       
   235 									\
       
   236 			bufp = (Uint16 *)buf;				\
       
   237 			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
       
   238 			*bufp = Pixel | (*bufp & Amask);		\
       
   239 		}							\
       
   240 		break;							\
       
   241 									\
       
   242 		case 3: {						\
       
   243                         if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		\
       
   244 			        *((buf)+fmt->Rshift/8) = r;		\
       
   245 				*((buf)+fmt->Gshift/8) = g;		\
       
   246 				*((buf)+fmt->Bshift/8) = b;		\
       
   247 			} else {					\
       
   248 			        *((buf)+2-fmt->Rshift/8) = r;		\
       
   249 				*((buf)+2-fmt->Gshift/8) = g;		\
       
   250 				*((buf)+2-fmt->Bshift/8) = b;		\
       
   251 			}						\
       
   252 		}							\
       
   253 		break;							\
       
   254 									\
       
   255 		case 4: {						\
       
   256 			Uint32 *bufp;					\
       
   257 			Uint32 Pixel;					\
       
   258 									\
       
   259 			bufp = (Uint32 *)buf;				\
       
   260 			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
       
   261 			*bufp = Pixel | (*bufp & Amask);		\
       
   262 		}							\
       
   263 		break;							\
       
   264 	}								\
       
   265 }
       
   266 
       
   267 /* FIXME: Should we rescale alpha into 0..255 here? */
       
   268 #define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a)				\
       
   269 {									\
       
   270 	r = ((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss; 		\
       
   271 	g = ((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss; 		\
       
   272 	b = ((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; 		\
       
   273 	a = ((Pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;	 	\
       
   274 }
       
   275 #define RGBA_FROM_8888(Pixel, fmt, r, g, b, a)	\
       
   276 {						\
       
   277 	r = (Pixel&fmt->Rmask)>>fmt->Rshift;	\
       
   278 	g = (Pixel&fmt->Gmask)>>fmt->Gshift;	\
       
   279 	b = (Pixel&fmt->Bmask)>>fmt->Bshift;	\
       
   280 	a = (Pixel&fmt->Amask)>>fmt->Ashift;	\
       
   281 }
       
   282 #define RGBA_FROM_RGBA8888(Pixel, r, g, b, a)				\
       
   283 {									\
       
   284 	r = (Pixel>>24);						\
       
   285 	g = ((Pixel>>16)&0xFF);						\
       
   286 	b = ((Pixel>>8)&0xFF);						\
       
   287 	a = (Pixel&0xFF);						\
       
   288 }
       
   289 #define RGBA_FROM_ARGB8888(Pixel, r, g, b, a)				\
       
   290 {									\
       
   291 	r = ((Pixel>>16)&0xFF);						\
       
   292 	g = ((Pixel>>8)&0xFF);						\
       
   293 	b = (Pixel&0xFF);						\
       
   294 	a = (Pixel>>24);						\
       
   295 }
       
   296 #define RGBA_FROM_ABGR8888(Pixel, r, g, b, a)				\
       
   297 {									\
       
   298 	r = (Pixel&0xFF);						\
       
   299 	g = ((Pixel>>8)&0xFF);						\
       
   300 	b = ((Pixel>>16)&0xFF);						\
       
   301 	a = (Pixel>>24);						\
       
   302 }
       
   303 #define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)			   \
       
   304 do {									   \
       
   305 	switch (bpp) {							   \
       
   306 		case 2:							   \
       
   307 			Pixel = *((Uint16 *)(buf));			   \
       
   308 		break;							   \
       
   309 									   \
       
   310 		case 3:	{/* FIXME: broken code (no alpha) */		   \
       
   311 		        Uint8 *b = (Uint8 *)buf;			   \
       
   312 			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		   \
       
   313 			        Pixel = b[0] + (b[1] << 8) + (b[2] << 16); \
       
   314 			} else {					   \
       
   315 			        Pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \
       
   316 			}						   \
       
   317 		}							   \
       
   318 		break;							   \
       
   319 									   \
       
   320 		case 4:							   \
       
   321 			Pixel = *((Uint32 *)(buf));			   \
       
   322 		break;							   \
       
   323 									   \
       
   324 		default:						   \
       
   325 		        Pixel = 0; /* stop gcc complaints */		   \
       
   326 		break;							   \
       
   327 	}								   \
       
   328 	RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a);			   \
       
   329 	Pixel &= ~fmt->Amask;						   \
       
   330 } while(0)
       
   331 
       
   332 /* FIXME: this isn't correct, especially for Alpha (maximum != 255) */
       
   333 #ifdef __NDS__ // FIXME
       
   334 #define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a)				\
       
   335 {									\
       
   336 	Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|				\
       
   337 		((g>>fmt->Gloss)<<fmt->Gshift)|				\
       
   338 		((b>>fmt->Bloss)<<fmt->Bshift)|				\
       
   339 		((a>>fmt->Aloss)<<fmt->Ashift) | (1<<15);				\
       
   340 }
       
   341 #else
       
   342 #define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a)				\
       
   343 {									\
       
   344 	Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|				\
       
   345 		((g>>fmt->Gloss)<<fmt->Gshift)|				\
       
   346 		((b>>fmt->Bloss)<<fmt->Bshift)|				\
       
   347 		((a>>fmt->Aloss)<<fmt->Ashift);				\
       
   348 }
       
   349 #endif // __NDS__ FIXME
       
   350 #define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)			\
       
   351 {									\
       
   352 	switch (bpp) {							\
       
   353 		case 2: {						\
       
   354 			Uint16 Pixel;					\
       
   355 									\
       
   356 			PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a);	\
       
   357 			*((Uint16 *)(buf)) = Pixel;			\
       
   358 		}							\
       
   359 		break;							\
       
   360 									\
       
   361 		case 3: { /* FIXME: broken code (no alpha) */		\
       
   362                         if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		\
       
   363 			        *((buf)+fmt->Rshift/8) = r;		\
       
   364 				*((buf)+fmt->Gshift/8) = g;		\
       
   365 				*((buf)+fmt->Bshift/8) = b;		\
       
   366 			} else {					\
       
   367 			        *((buf)+2-fmt->Rshift/8) = r;		\
       
   368 				*((buf)+2-fmt->Gshift/8) = g;		\
       
   369 				*((buf)+2-fmt->Bshift/8) = b;		\
       
   370 			}						\
       
   371 		}							\
       
   372 		break;							\
       
   373 									\
       
   374 		case 4: {						\
       
   375 			Uint32 Pixel;					\
       
   376 									\
       
   377 			PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a);	\
       
   378 			*((Uint32 *)(buf)) = Pixel;			\
       
   379 		}							\
       
   380 		break;							\
       
   381 	}								\
       
   382 }
       
   383 
       
   384 /* Blend the RGB values of two Pixels based on a source alpha value */
       
   385 #define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB)	\
       
   386 do {						\
       
   387 	dR = (((sR-dR)*(A))>>8)+dR;		\
       
   388 	dG = (((sG-dG)*(A))>>8)+dG;		\
       
   389 	dB = (((sB-dB)*(A))>>8)+dB;		\
       
   390 } while(0)
       
   391 
       
   392 /* Blend the RGB values of two Pixels based on a source alpha value */
       
   393 #define ACCURATE_ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB)	\
       
   394 do {						\
       
   395     unsigned tR, tG, tB, tA; \
       
   396     tA = 255 - sA; \
       
   397     tR = 1 + (sR * sA) + (dR * tA); \
       
   398     dR = (tR + (tR >> 8)) >> 8; \
       
   399     tG = 1 + (sG * sA) + (dG * tA); \
       
   400     dG = (tG + (tG >> 8)) >> 8; \
       
   401     tB = 1 + (sB * sA) + (dB * tA); \
       
   402     dB = (tB + (tB >> 8)) >> 8; \
       
   403 } while(0)
       
   404 
       
   405 
       
   406 /* This is a very useful loop for optimizing blitters */
       
   407 #if defined(_MSC_VER) && (_MSC_VER == 1300)
       
   408 /* There's a bug in the Visual C++ 7 optimizer when compiling this code */
       
   409 #else
       
   410 #define USE_DUFFS_LOOP
       
   411 #endif
       
   412 #ifdef USE_DUFFS_LOOP
       
   413 
       
   414 /* 8-times unrolled loop */
       
   415 #define DUFFS_LOOP8(pixel_copy_increment, width)			\
       
   416 { int n = (width+7)/8;							\
       
   417 	switch (width & 7) {						\
       
   418 	case 0: do {	pixel_copy_increment;				\
       
   419 	case 7:		pixel_copy_increment;				\
       
   420 	case 6:		pixel_copy_increment;				\
       
   421 	case 5:		pixel_copy_increment;				\
       
   422 	case 4:		pixel_copy_increment;				\
       
   423 	case 3:		pixel_copy_increment;				\
       
   424 	case 2:		pixel_copy_increment;				\
       
   425 	case 1:		pixel_copy_increment;				\
       
   426 		} while ( --n > 0 );					\
       
   427 	}								\
       
   428 }
       
   429 
       
   430 /* 4-times unrolled loop */
       
   431 #define DUFFS_LOOP4(pixel_copy_increment, width)			\
       
   432 { int n = (width+3)/4;							\
       
   433 	switch (width & 3) {						\
       
   434 	case 0: do {	pixel_copy_increment;				\
       
   435 	case 3:		pixel_copy_increment;				\
       
   436 	case 2:		pixel_copy_increment;				\
       
   437 	case 1:		pixel_copy_increment;				\
       
   438 		} while ( --n > 0 );					\
       
   439 	}								\
       
   440 }
       
   441 
       
   442 /* 2 - times unrolled loop */
       
   443 #define DUFFS_LOOP_DOUBLE2(pixel_copy_increment,			\
       
   444 				double_pixel_copy_increment, width)	\
       
   445 { int n, w = width;							\
       
   446 	if( w & 1 ) {							\
       
   447 	    pixel_copy_increment;					\
       
   448 	    w--;							\
       
   449 	}								\
       
   450 	if ( w > 0 )	{						\
       
   451 	    n = ( w + 2) / 4;						\
       
   452 	    switch( w & 2 ) {						\
       
   453 	    case 0: do {	double_pixel_copy_increment;		\
       
   454 	    case 2:		double_pixel_copy_increment;		\
       
   455 		    } while ( --n > 0 );					\
       
   456 	    }								\
       
   457 	}								\
       
   458 }
       
   459 
       
   460 /* 2 - times unrolled loop 4 pixels */
       
   461 #define DUFFS_LOOP_QUATRO2(pixel_copy_increment,			\
       
   462 				double_pixel_copy_increment,		\
       
   463 				quatro_pixel_copy_increment, width)	\
       
   464 { int n, w = width;								\
       
   465         if(w & 1) {							\
       
   466 	  pixel_copy_increment;						\
       
   467 	  w--;								\
       
   468 	}								\
       
   469 	if(w & 2) {							\
       
   470 	  double_pixel_copy_increment;					\
       
   471 	  w -= 2;							\
       
   472 	}								\
       
   473 	if ( w > 0 ) {							\
       
   474 	    n = ( w + 7 ) / 8;						\
       
   475 	    switch( w & 4 ) {						\
       
   476 	    case 0: do {	quatro_pixel_copy_increment;		\
       
   477 	    case 4:		quatro_pixel_copy_increment;		\
       
   478 		    } while ( --n > 0 );					\
       
   479 	    }								\
       
   480 	}								\
       
   481 }
       
   482 
       
   483 /* Use the 8-times version of the loop by default */
       
   484 #define DUFFS_LOOP(pixel_copy_increment, width)				\
       
   485 	DUFFS_LOOP8(pixel_copy_increment, width)
       
   486 
       
   487 #else
       
   488 
       
   489 /* Don't use Duff's device to unroll loops */
       
   490 #define DUFFS_LOOP_DOUBLE2(pixel_copy_increment,			\
       
   491 			 double_pixel_copy_increment, width)		\
       
   492 { int n = width;								\
       
   493     if( n & 1 ) {							\
       
   494 	pixel_copy_increment;						\
       
   495 	n--;								\
       
   496     }									\
       
   497     n=n>>1;								\
       
   498     for(; n > 0; --n) {   						\
       
   499 	double_pixel_copy_increment;					\
       
   500     }									\
       
   501 }
       
   502 
       
   503 /* Don't use Duff's device to unroll loops */
       
   504 #define DUFFS_LOOP_QUATRO2(pixel_copy_increment,			\
       
   505 				double_pixel_copy_increment,		\
       
   506 				quatro_pixel_copy_increment, width)	\
       
   507 { int n = width;								\
       
   508         if(n & 1) {							\
       
   509 	  pixel_copy_increment;						\
       
   510 	  n--;								\
       
   511 	}								\
       
   512 	if(n & 2) {							\
       
   513 	  double_pixel_copy_increment;					\
       
   514 	  n -= 2;							\
       
   515 	}								\
       
   516 	n=n>>2;								\
       
   517 	for(; n > 0; --n) {   						\
       
   518 	  quatro_pixel_copy_increment;					\
       
   519         }								\
       
   520 }
       
   521 
       
   522 /* Don't use Duff's device to unroll loops */
       
   523 #define DUFFS_LOOP(pixel_copy_increment, width)				\
       
   524 { int n;								\
       
   525 	for ( n=width; n > 0; --n ) {					\
       
   526 		pixel_copy_increment;					\
       
   527 	}								\
       
   528 }
       
   529 #define DUFFS_LOOP8(pixel_copy_increment, width)			\
       
   530 	DUFFS_LOOP(pixel_copy_increment, width)
       
   531 #define DUFFS_LOOP4(pixel_copy_increment, width)			\
       
   532 	DUFFS_LOOP(pixel_copy_increment, width)
       
   533 
       
   534 #endif /* USE_DUFFS_LOOP */
       
   535 
       
   536 /* Prevent Visual C++ 6.0 from printing out stupid warnings */
       
   537 #if defined(_MSC_VER) && (_MSC_VER >= 600)
       
   538 #pragma warning(disable: 4550)
       
   539 #endif
       
   540 
       
   541 #endif /* _SDL_blit_h */