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