src/video/SDL_blit.h
author Sam Lantinga
Wed, 10 Mar 2010 15:02:58 +0000
changeset 4426 1bceff8f008f
parent 3697 f7b03b6838cb
child 5140 e743b9c3f6d6
permissions -rw-r--r--
Fixed bug #943

Ozkan Sezer 2010-02-06 12:31:06 PST

Hi:

Here are some small fixes for compiling SDL against mingw-w64.
(see http://mingw-w64.sourceforge.net/ . Despite the name, it
supports both win32 and win64.)

src/audio/windx5/directx.h and src/video/windx5/directx.h (both
SDL-1.2 and SDL-1.3.) I get compilation errors about some union
not having a member named u1 and alike, because of other system
headers being included before this one and them already defining
DUMMYUNIONNAME and stuff. This header probably assumes that those
stuff are defined in windef.h, but mingw-w64 headers define them
in _mingw.h. Easily fixed by moving NONAMELESSUNION definition to
the top of the file.

src/thread/win32/SDL_systhread.c (both SDL-1.2 and SDL-1.3.) :
The __GNUC__ case for pfnSDL_CurrentBeginThread is 32-bit centric
because _beginthreadex returns uintptr_t, not unsigned long which
is 32 bits in win64. Changing the return type to uintptr_t fixes
it.

video/SDL_blit.h (and configure.in) (SDL-1.3-only) : MinGW-w64
uses msvcrt version of _aligned_malloc and _aligned_free and
they are defined in intrin.h (similar to VC). Adding proper
ifdefs fixes it. (Notes about macros to check: __MINGW32__ is
defined for both mingw.org and for mingw-w64 for both win32 and
win64, __MINGW64__ is only defined for _WIN64, so __MINGW64__
can't be used to detect mingw-w64: including _mingw.h and then
checking for __MINGW64_VERSION_MAJOR does the trick.)

SDL_win32video.h (SDL-1.3-only) : Tweaked the VINWER definition
and location in order to avoid multiple redefinition warnings.

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