Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8210 maxcodehac 1
/*
2
    SDL - Simple DirectMedia Layer
3
    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
4
 
5
    This library is free software; you can redistribute it and/or
6
    modify it under the terms of the GNU Library General Public
7
    License as published by the Free Software Foundation; either
8
    version 2 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
    Library General Public License for more details.
14
 
15
    You should have received a copy of the GNU Library General Public
16
    License along with this library; if not, write to the Free
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
19
    Sam Lantinga
20
    slouken@devolution.com
21
*/
22
 
23
#ifdef SAVE_RCSID
24
static char rcsid =
25
 "@(#) $Id: SDL_blit.h,v 1.3 2001/07/07 20:20:16 hercules Exp $";
26
#endif
27
 
28
#ifndef _SDL_blit_h
29
#define _SDL_blit_h
30
 
31
#include "SDL_endian.h"
32
 
33
/* The structure passed to the low level blit functions */
34
typedef struct {
35
	Uint8 *s_pixels;
36
	int s_width;
37
	int s_height;
38
	int s_skip;
39
	Uint8 *d_pixels;
40
	int d_width;
41
	int d_height;
42
	int d_skip;
43
	void *aux_data;
44
	SDL_PixelFormat *src;
45
	Uint8 *table;
46
	SDL_PixelFormat *dst;
47
} SDL_BlitInfo;
48
 
49
/* The type definition for the low level blit functions */
50
typedef void (*SDL_loblit)(SDL_BlitInfo *info);
51
 
52
/* This is the private info structure for software accelerated blits */
53
struct private_swaccel {
54
	SDL_loblit blit;
55
	void *aux_data;
56
};
57
 
58
/* Blit mapping definition */
59
typedef struct SDL_BlitMap {
60
	SDL_Surface *dst;
61
	int identity;
62
	Uint8 *table;
63
	SDL_blit hw_blit;
64
	SDL_blit sw_blit;
65
	struct private_hwaccel *hw_data;
66
	struct private_swaccel *sw_data;
67
 
68
	/* the version count matches the destination; mismatch indicates
69
	   an invalid mapping */
70
        unsigned int format_version;
71
} SDL_BlitMap;
72
 
73
 
74
/* Definitions for special global blit functions */
75
#include "SDL_blit_A.h"
76
 
77
/* Functions found in SDL_blit.c */
78
extern int SDL_CalculateBlit(SDL_Surface *surface);
79
 
80
/* Functions found in SDL_blit_{0,1,N,A}.c */
81
extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex);
82
extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex);
83
extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex);
84
extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex);
85
 
86
/*
87
 * Useful macros for blitting routines
88
 */
89
 
90
#define FORMAT_EQUAL(A, B)						\
91
    ((A)->BitsPerPixel == (B)->BitsPerPixel				\
92
     && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask))
93
 
94
/* Load pixel of the specified format from a buffer and get its R-G-B values */
95
/* FIXME: rescale values to 0..255 here? */
96
#define RGB_FROM_PIXEL(pixel, fmt, r, g, b)				\
97
{									\
98
	r = (((pixel&fmt->Rmask)>>fmt->Rshift)<Rloss); 		\
99
	g = (((pixel&fmt->Gmask)>>fmt->Gshift)<Gloss); 		\
100
	b = (((pixel&fmt->Bmask)>>fmt->Bshift)<Bloss); 		\
101
}
102
#define RGB_FROM_RGB565(pixel, r, g, b)					\
103
{									\
104
	r = (((pixel&0xF800)>>11)<<3);		 			\
105
	g = (((pixel&0x07E0)>>5)<<2); 					\
106
	b = ((pixel&0x001F)<<3); 					\
107
}
108
#define RGB_FROM_RGB555(pixel, r, g, b)					\
109
{									\
110
	r = (((pixel&0x7C00)>>10)<<3);		 			\
111
	g = (((pixel&0x03E0)>>5)<<3); 					\
112
	b = ((pixel&0x001F)<<3); 					\
113
}
114
#define RGB_FROM_RGB888(pixel, r, g, b)					\
115
{									\
116
	r = ((pixel&0xFF0000)>>16);		 			\
117
	g = ((pixel&0xFF00)>>8);		 			\
118
	b = (pixel&0xFF);			 			\
119
}
120
#define RETRIEVE_RGB_PIXEL(buf, bpp, pixel)				   \
121
do {									   \
122
	switch (bpp) {							   \
123
		case 2:							   \
124
			pixel = *((Uint16 *)(buf));			   \
125
		break;							   \
126
									   \
127
		case 3: {						   \
128
		        Uint8 *B = (Uint8 *)(buf);			   \
129
			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		   \
130
			        pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
131
			} else {					   \
132
			        pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
133
			}						   \
134
		}							   \
135
		break;							   \
136
									   \
137
		case 4:							   \
138
			pixel = *((Uint32 *)(buf));			   \
139
		break;							   \
140
									   \
141
		default:						   \
142
			pixel = 0; /* appease gcc */			   \
143
		break;							   \
144
	}								   \
145
} while(0)
146
 
147
#define DISEMBLE_RGB(buf, bpp, fmt, pixel, r, g, b)			   \
148
do {									   \
149
	switch (bpp) {							   \
150
		case 2:							   \
151
			pixel = *((Uint16 *)(buf));			   \
152
		break;							   \
153
									   \
154
		case 3: {						   \
155
		        Uint8 *B = (Uint8 *)buf;			   \
156
			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		   \
157
			        pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
158
			} else {					   \
159
			        pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
160
			}						   \
161
		}							   \
162
		break;							   \
163
									   \
164
		case 4:							   \
165
			pixel = *((Uint32 *)(buf));			   \
166
		break;							   \
167
									   \
168
	        default:						   \
169
		        pixel = 0;	/* prevent gcc from complaining */ \
170
		break;							   \
171
	}								   \
172
	RGB_FROM_PIXEL(pixel, fmt, r, g, b);				   \
173
} while(0)
174
 
175
/* Assemble R-G-B values into a specified pixel format and store them */
176
#define PIXEL_FROM_RGB(pixel, fmt, r, g, b)				\
177
{									\
178
	pixel = ((r>>fmt->Rloss)<Rshift)|				\
179
		((g>>fmt->Gloss)<Gshift)|				\
180
		((b>>fmt->Bloss)<Bshift);				\
181
}
182
#define RGB565_FROM_RGB(pixel, r, g, b)					\
183
{									\
184
	pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);			\
185
}
186
#define RGB555_FROM_RGB(pixel, r, g, b)					\
187
{									\
188
	pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3);			\
189
}
190
#define RGB888_FROM_RGB(pixel, r, g, b)					\
191
{									\
192
	pixel = (r<<16)|(g<<8)|b;					\
193
}
194
#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) 				\
195
{									\
196
	switch (bpp) {							\
197
		case 2: {						\
198
			Uint16 pixel;					\
199
									\
200
			PIXEL_FROM_RGB(pixel, fmt, r, g, b);		\
201
			*((Uint16 *)(buf)) = pixel;			\
202
		}							\
203
		break;							\
204
									\
205
		case 3: {						\
206
                        if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		\
207
			        *((buf)+fmt->Rshift/8) = r;		\
208
				*((buf)+fmt->Gshift/8) = g;		\
209
				*((buf)+fmt->Bshift/8) = b;		\
210
			} else {					\
211
			        *((buf)+2-fmt->Rshift/8) = r;		\
212
				*((buf)+2-fmt->Gshift/8) = g;		\
213
				*((buf)+2-fmt->Bshift/8) = b;		\
214
			}						\
215
		}							\
216
		break;							\
217
									\
218
		case 4: {						\
219
			Uint32 pixel;					\
220
									\
221
			PIXEL_FROM_RGB(pixel, fmt, r, g, b);		\
222
			*((Uint32 *)(buf)) = pixel;			\
223
		}							\
224
		break;							\
225
	}								\
226
}
227
#define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask)		\
228
{									\
229
	switch (bpp) {							\
230
		case 2: {						\
231
			Uint16 *bufp;					\
232
			Uint16 pixel;					\
233
									\
234
			bufp = (Uint16 *)buf;				\
235
			PIXEL_FROM_RGB(pixel, fmt, r, g, b);		\
236
			*bufp = pixel | (*bufp & Amask);		\
237
		}							\
238
		break;							\
239
									\
240
		case 3: {						\
241
                        if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		\
242
			        *((buf)+fmt->Rshift/8) = r;		\
243
				*((buf)+fmt->Gshift/8) = g;		\
244
				*((buf)+fmt->Bshift/8) = b;		\
245
			} else {					\
246
			        *((buf)+2-fmt->Rshift/8) = r;		\
247
				*((buf)+2-fmt->Gshift/8) = g;		\
248
				*((buf)+2-fmt->Bshift/8) = b;		\
249
			}						\
250
		}							\
251
		break;							\
252
									\
253
		case 4: {						\
254
			Uint32 *bufp;					\
255
			Uint32 pixel;					\
256
									\
257
			bufp = (Uint32 *)buf;				\
258
			PIXEL_FROM_RGB(pixel, fmt, r, g, b);		\
259
			*bufp = pixel | (*bufp & Amask);		\
260
		}							\
261
		break;							\
262
	}								\
263
}
264
 
265
/* FIXME: Should we rescale alpha into 0..255 here? */
266
#define RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a)				\
267
{									\
268
	r = ((pixel&fmt->Rmask)>>fmt->Rshift)<Rloss; 		\
269
	g = ((pixel&fmt->Gmask)>>fmt->Gshift)<Gloss; 		\
270
	b = ((pixel&fmt->Bmask)>>fmt->Bshift)<Bloss; 		\
271
	a = ((pixel&fmt->Amask)>>fmt->Ashift)<Aloss;	 	\
272
}
273
#define RGBA_FROM_8888(pixel, fmt, r, g, b, a)	\
274
{						\
275
	r = (pixel&fmt->Rmask)>>fmt->Rshift;	\
276
	g = (pixel&fmt->Gmask)>>fmt->Gshift;	\
277
	b = (pixel&fmt->Bmask)>>fmt->Bshift;	\
278
	a = (pixel&fmt->Amask)>>fmt->Ashift;	\
279
}
280
#define RGBA_FROM_RGBA8888(pixel, r, g, b, a)				\
281
{									\
282
	r = (pixel>>24);						\
283
	g = ((pixel>>16)&0xFF);						\
284
	b = ((pixel>>8)&0xFF);						\
285
	a = (pixel&0xFF);						\
286
}
287
#define RGBA_FROM_ARGB8888(pixel, r, g, b, a)				\
288
{									\
289
	r = ((pixel>>16)&0xFF);						\
290
	g = ((pixel>>8)&0xFF);						\
291
	b = (pixel&0xFF);						\
292
	a = (pixel>>24);						\
293
}
294
#define RGBA_FROM_ABGR8888(pixel, r, g, b, a)				\
295
{									\
296
	r = (pixel&0xFF);						\
297
	g = ((pixel>>8)&0xFF);						\
298
	b = ((pixel>>16)&0xFF);						\
299
	a = (pixel>>24);						\
300
}
301
#define DISEMBLE_RGBA(buf, bpp, fmt, pixel, r, g, b, a)			   \
302
do {									   \
303
	switch (bpp) {							   \
304
		case 2:							   \
305
			pixel = *((Uint16 *)(buf));			   \
306
		break;							   \
307
									   \
308
		case 3:	{/* FIXME: broken code (no alpha) */		   \
309
		        Uint8 *b = (Uint8 *)buf;			   \
310
			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		   \
311
			        pixel = b[0] + (b[1] << 8) + (b[2] << 16); \
312
			} else {					   \
313
			        pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \
314
			}						   \
315
		}							   \
316
		break;							   \
317
									   \
318
		case 4:							   \
319
			pixel = *((Uint32 *)(buf));			   \
320
		break;							   \
321
									   \
322
		default:						   \
323
		        pixel = 0; /* stop gcc complaints */		   \
324
		break;							   \
325
	}								   \
326
	RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a);			   \
327
	pixel &= ~fmt->Amask;						   \
328
} while(0)
329
 
330
/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */
331
#define PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a)				\
332
{									\
333
	pixel = ((r>>fmt->Rloss)<Rshift)|				\
334
		((g>>fmt->Gloss)<Gshift)|				\
335
		((b>>fmt->Bloss)<Bshift)|				\
336
		((a<Aloss)<Ashift);				\
337
}
338
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)			\
339
{									\
340
	switch (bpp) {							\
341
		case 2: {						\
342
			Uint16 pixel;					\
343
									\
344
			PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a);	\
345
			*((Uint16 *)(buf)) = pixel;			\
346
		}							\
347
		break;							\
348
									\
349
		case 3: { /* FIXME: broken code (no alpha) */		\
350
                        if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {		\
351
			        *((buf)+fmt->Rshift/8) = r;		\
352
				*((buf)+fmt->Gshift/8) = g;		\
353
				*((buf)+fmt->Bshift/8) = b;		\
354
			} else {					\
355
			        *((buf)+2-fmt->Rshift/8) = r;		\
356
				*((buf)+2-fmt->Gshift/8) = g;		\
357
				*((buf)+2-fmt->Bshift/8) = b;		\
358
			}						\
359
		}							\
360
		break;							\
361
									\
362
		case 4: {						\
363
			Uint32 pixel;					\
364
									\
365
			PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a);	\
366
			*((Uint32 *)(buf)) = pixel;			\
367
		}							\
368
		break;							\
369
	}								\
370
}
371
 
372
/* Blend the RGB values of two pixels based on a source alpha value */
373
#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB)	\
374
do {						\
375
	dR = (((sR-dR)*(A))>>8)+dR;		\
376
	dG = (((sG-dG)*(A))>>8)+dG;		\
377
	dB = (((sB-dB)*(A))>>8)+dB;		\
378
} while(0)
379
 
380
/* This is a very useful loop for optimizing blitters */
381
#define USE_DUFFS_LOOP
382
#ifdef USE_DUFFS_LOOP
383
 
384
/* 8-times unrolled loop */
385
#define DUFFS_LOOP8(pixel_copy_increment, width)			\
386
{ int n = (width+7)/8;							\
387
	switch (width & 7) {						\
388
	case 0: do {	pixel_copy_increment;				\
389
	case 7:		pixel_copy_increment;				\
390
	case 6:		pixel_copy_increment;				\
391
	case 5:		pixel_copy_increment;				\
392
	case 4:		pixel_copy_increment;				\
393
	case 3:		pixel_copy_increment;				\
394
	case 2:		pixel_copy_increment;				\
395
	case 1:		pixel_copy_increment;				\
396
		} while ( --n > 0 );					\
397
	}								\
398
}
399
 
400
/* 4-times unrolled loop */
401
#define DUFFS_LOOP4(pixel_copy_increment, width)			\
402
{ int n = (width+3)/4;							\
403
	switch (width & 3) {						\
404
	case 0: do {	pixel_copy_increment;				\
405
	case 3:		pixel_copy_increment;				\
406
	case 2:		pixel_copy_increment;				\
407
	case 1:		pixel_copy_increment;				\
408
		} while ( --n > 0 );					\
409
	}								\
410
}
411
 
412
/* Use the 8-times version of the loop by default */
413
#define DUFFS_LOOP(pixel_copy_increment, width)				\
414
	DUFFS_LOOP8(pixel_copy_increment, width)
415
 
416
#else
417
 
418
/* Don't use Duff's device to unroll loops */
419
#define DUFFS_LOOP(pixel_copy_increment, width)				\
420
{ int n;								\
421
	for ( n=width; n > 0; --n ) {					\
422
		pixel_copy_increment;					\
423
	}								\
424
}
425
#define DUFFS_LOOP8(pixel_copy_increment, width)			\
426
	DUFFS_LOOP(pixel_copy_increment, width)
427
#define DUFFS_LOOP4(pixel_copy_increment, width)			\
428
	DUFFS_LOOP(pixel_copy_increment, width)
429
 
430
#endif /* USE_DUFFS_LOOP */
431
 
432
/* Prevent Visual C++ 6.0 from printing out stupid warnings */
433
#if defined(_MSC_VER) && (_MSC_VER >= 600)
434
#pragma warning(disable: 4550)
435
#endif
436
 
437
#endif /* _SDL_blit_h */