Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 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
 
24
#include 
25
 
26
#include "SDL_types.h"
27
#include "SDL_video.h"
28
#include "SDL_blit.h"
29
#include "SDL_sysvideo.h"
30
#include "SDL_endian.h"
31
 
32
/* Functions to blit from 8-bit surfaces to other surfaces */
33
 
34
static void Blit1to1(SDL_BlitInfo *info)
35
{
36
#ifndef USE_DUFFS_LOOP
37
	int c;
38
#endif
39
	int width, height;
40
	Uint8 *src, *map, *dst;
41
	int srcskip, dstskip;
42
 
43
	/* Set up some basic variables */
44
	width = info->d_width;
45
	height = info->d_height;
46
	src = info->s_pixels;
47
	srcskip = info->s_skip;
48
	dst = info->d_pixels;
49
	dstskip = info->d_skip;
50
	map = info->table;
51
 
52
	while ( height-- ) {
53
#ifdef USE_DUFFS_LOOP
54
		DUFFS_LOOP(
55
			{
56
			  *dst = map[*src];
57
			}
58
			dst++;
59
			src++;
60
		, width);
61
#else
62
		for ( c=width; c; --c ) {
63
		        *dst = map[*src];
64
			dst++;
65
			src++;
66
		}
67
#endif
68
		src += srcskip;
69
		dst += dstskip;
70
	}
71
}
72
/* This is now endian dependent */
73
#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
74
#define HI	1
75
#define LO	0
76
#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
77
#define HI	0
78
#define LO	1
79
#endif
80
static void Blit1to2(SDL_BlitInfo *info)
81
{
82
#ifndef USE_DUFFS_LOOP
83
	int c;
84
#endif
85
	int width, height;
86
	Uint8 *src, *dst;
87
	Uint16 *map;
88
	int srcskip, dstskip;
89
 
90
	/* Set up some basic variables */
91
	width = info->d_width;
92
	height = info->d_height;
93
	src = info->s_pixels;
94
	srcskip = info->s_skip;
95
	dst = info->d_pixels;
96
	dstskip = info->d_skip;
97
	map = (Uint16 *)info->table;
98
 
99
#ifdef USE_DUFFS_LOOP
100
	while ( height-- ) {
101
		DUFFS_LOOP(
102
		{
103
			*(Uint16 *)dst = map[*src++];
104
			dst += 2;
105
		},
106
		width);
107
		src += srcskip;
108
		dst += dstskip;
109
	}
110
#else
111
	/* Memory align at 4-byte boundary, if necessary */
112
	if ( (long)dst & 0x03 ) {
113
		/* Don't do anything if width is 0 */
114
		if ( width == 0 ) {
115
			return;
116
		}
117
		--width;
118
 
119
		while ( height-- ) {
120
			/* Perform copy alignment */
121
			*(Uint16 *)dst = map[*src++];
122
			dst += 2;
123
 
124
			/* Copy in 4 pixel chunks */
125
			for ( c=width/4; c; --c ) {
126
				*(Uint32 *)dst =
127
					(map[src[HI]]<<16)|(map[src[LO]]);
128
				src += 2;
129
				dst += 4;
130
				*(Uint32 *)dst =
131
					(map[src[HI]]<<16)|(map[src[LO]]);
132
				src += 2;
133
				dst += 4;
134
			}
135
			/* Get any leftovers */
136
			switch (width & 3) {
137
				case 3:
138
					*(Uint16 *)dst = map[*src++];
139
					dst += 2;
140
				case 2:
141
					*(Uint32 *)dst =
142
					  (map[src[HI]]<<16)|(map[src[LO]]);
143
					src += 2;
144
					dst += 4;
145
					break;
146
				case 1:
147
					*(Uint16 *)dst = map[*src++];
148
					dst += 2;
149
					break;
150
			}
151
			src += srcskip;
152
			dst += dstskip;
153
		}
154
	} else {
155
		while ( height-- ) {
156
			/* Copy in 4 pixel chunks */
157
			for ( c=width/4; c; --c ) {
158
				*(Uint32 *)dst =
159
					(map[src[HI]]<<16)|(map[src[LO]]);
160
				src += 2;
161
				dst += 4;
162
				*(Uint32 *)dst =
163
					(map[src[HI]]<<16)|(map[src[LO]]);
164
				src += 2;
165
				dst += 4;
166
			}
167
			/* Get any leftovers */
168
			switch (width & 3) {
169
				case 3:
170
					*(Uint16 *)dst = map[*src++];
171
					dst += 2;
172
				case 2:
173
					*(Uint32 *)dst =
174
					  (map[src[HI]]<<16)|(map[src[LO]]);
175
					src += 2;
176
					dst += 4;
177
					break;
178
				case 1:
179
					*(Uint16 *)dst = map[*src++];
180
					dst += 2;
181
					break;
182
			}
183
			src += srcskip;
184
			dst += dstskip;
185
		}
186
	}
187
#endif /* USE_DUFFS_LOOP */
188
}
189
static void Blit1to3(SDL_BlitInfo *info)
190
{
191
#ifndef USE_DUFFS_LOOP
192
	int c;
193
#endif
194
	int o;
195
	int width, height;
196
	Uint8 *src, *map, *dst;
197
	int srcskip, dstskip;
198
 
199
	/* Set up some basic variables */
200
	width = info->d_width;
201
	height = info->d_height;
202
	src = info->s_pixels;
203
	srcskip = info->s_skip;
204
	dst = info->d_pixels;
205
	dstskip = info->d_skip;
206
	map = info->table;
207
 
208
	while ( height-- ) {
209
#ifdef USE_DUFFS_LOOP
210
		DUFFS_LOOP(
211
			{
212
				o = *src * 4;
213
				dst[0] = map[o++];
214
				dst[1] = map[o++];
215
				dst[2] = map[o++];
216
			}
217
			src++;
218
			dst += 3;
219
		, width);
220
#else
221
		for ( c=width; c; --c ) {
222
			o = *src * 4;
223
			dst[0] = map[o++];
224
			dst[1] = map[o++];
225
			dst[2] = map[o++];
226
			src++;
227
			dst += 3;
228
		}
229
#endif /* USE_DUFFS_LOOP */
230
		src += srcskip;
231
		dst += dstskip;
232
	}
233
}
234
static void Blit1to4(SDL_BlitInfo *info)
235
{
236
#ifndef USE_DUFFS_LOOP
237
	int c;
238
#endif
239
	int width, height;
240
	Uint8 *src;
241
	Uint32 *map, *dst;
242
	int srcskip, dstskip;
243
 
244
	/* Set up some basic variables */
245
	width = info->d_width;
246
	height = info->d_height;
247
	src = info->s_pixels;
248
	srcskip = info->s_skip;
249
	dst = (Uint32 *)info->d_pixels;
250
	dstskip = info->d_skip/4;
251
	map = (Uint32 *)info->table;
252
 
253
	while ( height-- ) {
254
#ifdef USE_DUFFS_LOOP
255
		DUFFS_LOOP(
256
			*dst++ = map[*src++];
257
		, width);
258
#else
259
		for ( c=width/4; c; --c ) {
260
			*dst++ = map[*src++];
261
			*dst++ = map[*src++];
262
			*dst++ = map[*src++];
263
			*dst++ = map[*src++];
264
		}
265
		switch ( width & 3 ) {
266
			case 3:
267
				*dst++ = map[*src++];
268
			case 2:
269
				*dst++ = map[*src++];
270
			case 1:
271
				*dst++ = map[*src++];
272
		}
273
#endif /* USE_DUFFS_LOOP */
274
		src += srcskip;
275
		dst += dstskip;
276
	}
277
}
278
 
279
static void Blit1to1Key(SDL_BlitInfo *info)
280
{
281
	int width = info->d_width;
282
	int height = info->d_height;
283
	Uint8 *src = info->s_pixels;
284
	int srcskip = info->s_skip;
285
	Uint8 *dst = info->d_pixels;
286
	int dstskip = info->d_skip;
287
	Uint8 *palmap = info->table;
288
	Uint32 ckey = info->src->colorkey;
289
 
290
	if ( palmap ) {
291
		while ( height-- ) {
292
			DUFFS_LOOP(
293
			{
294
				if ( *src != ckey ) {
295
				  *dst = palmap[*src];
296
				}
297
				dst++;
298
				src++;
299
			},
300
			width);
301
			src += srcskip;
302
			dst += dstskip;
303
		}
304
	} else {
305
		while ( height-- ) {
306
			DUFFS_LOOP(
307
			{
308
				if ( *src != ckey ) {
309
				  *dst = *src;
310
				}
311
				dst++;
312
				src++;
313
			},
314
			width);
315
			src += srcskip;
316
			dst += dstskip;
317
		}
318
	}
319
}
320
 
321
static void Blit1to2Key(SDL_BlitInfo *info)
322
{
323
	int width = info->d_width;
324
	int height = info->d_height;
325
	Uint8 *src = info->s_pixels;
326
	int srcskip = info->s_skip;
327
	Uint16 *dstp = (Uint16 *)info->d_pixels;
328
	int dstskip = info->d_skip;
329
	Uint16 *palmap = (Uint16 *)info->table;
330
	Uint32 ckey = info->src->colorkey;
331
 
332
	/* Set up some basic variables */
333
	dstskip /= 2;
334
 
335
	while ( height-- ) {
336
		DUFFS_LOOP(
337
		{
338
			if ( *src != ckey ) {
339
				*dstp=palmap[*src];
340
			}
341
			src++;
342
			dstp++;
343
		},
344
		width);
345
		src += srcskip;
346
		dstp += dstskip;
347
	}
348
}
349
 
350
static void Blit1to3Key(SDL_BlitInfo *info)
351
{
352
	int width = info->d_width;
353
	int height = info->d_height;
354
	Uint8 *src = info->s_pixels;
355
	int srcskip = info->s_skip;
356
	Uint8 *dst = info->d_pixels;
357
	int dstskip = info->d_skip;
358
	Uint8 *palmap = info->table;
359
	Uint32 ckey = info->src->colorkey;
360
	int o;
361
 
362
	while ( height-- ) {
363
		DUFFS_LOOP(
364
		{
365
			if ( *src != ckey ) {
366
				o = *src * 4;
367
				dst[0] = palmap[o++];
368
				dst[1] = palmap[o++];
369
				dst[2] = palmap[o++];
370
			}
371
			src++;
372
			dst += 3;
373
		},
374
		width);
375
		src += srcskip;
376
		dst += dstskip;
377
	}
378
}
379
 
380
static void Blit1to4Key(SDL_BlitInfo *info)
381
{
382
	int width = info->d_width;
383
	int height = info->d_height;
384
	Uint8 *src = info->s_pixels;
385
	int srcskip = info->s_skip;
386
	Uint32 *dstp = (Uint32 *)info->d_pixels;
387
	int dstskip = info->d_skip;
388
	Uint32 *palmap = (Uint32 *)info->table;
389
	Uint32 ckey = info->src->colorkey;
390
 
391
	/* Set up some basic variables */
392
	dstskip /= 4;
393
 
394
	while ( height-- ) {
395
		DUFFS_LOOP(
396
		{
397
			if ( *src != ckey ) {
398
				*dstp = palmap[*src];
399
			}
400
			src++;
401
			dstp++;
402
		},
403
		width);
404
		src += srcskip;
405
		dstp += dstskip;
406
	}
407
}
408
 
409
static void Blit1toNAlpha(SDL_BlitInfo *info)
410
{
411
	int width = info->d_width;
412
	int height = info->d_height;
413
	Uint8 *src = info->s_pixels;
414
	int srcskip = info->s_skip;
415
	Uint8 *dst = info->d_pixels;
416
	int dstskip = info->d_skip;
417
	SDL_PixelFormat *dstfmt = info->dst;
418
	const SDL_Color *srcpal	= info->src->palette->colors;
419
	int dstbpp;
420
	const int A = info->src->alpha;
421
 
422
	/* Set up some basic variables */
423
	dstbpp = dstfmt->BytesPerPixel;
424
 
425
	while ( height-- ) {
426
	        int sR, sG, sB;
427
		int dR, dG, dB;
428
	    	DUFFS_LOOP4(
429
			{
430
			        Uint32 pixel;
431
				sR = srcpal[*src].r;
432
				sG = srcpal[*src].g;
433
				sB = srcpal[*src].b;
434
				DISEMBLE_RGB(dst, dstbpp, dstfmt,
435
					     pixel, dR, dG, dB);
436
				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
437
			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
438
				src++;
439
				dst += dstbpp;
440
			},
441
			width);
442
		src += srcskip;
443
		dst += dstskip;
444
	}
445
}
446
 
447
static void Blit1toNAlphaKey(SDL_BlitInfo *info)
448
{
449
	int width = info->d_width;
450
	int height = info->d_height;
451
	Uint8 *src = info->s_pixels;
452
	int srcskip = info->s_skip;
453
	Uint8 *dst = info->d_pixels;
454
	int dstskip = info->d_skip;
455
	SDL_PixelFormat *srcfmt = info->src;
456
	SDL_PixelFormat *dstfmt = info->dst;
457
	const SDL_Color *srcpal	= info->src->palette->colors;
458
	Uint32 ckey = srcfmt->colorkey;
459
	int dstbpp;
460
	const int A = srcfmt->alpha;
461
 
462
	/* Set up some basic variables */
463
	dstbpp = dstfmt->BytesPerPixel;
464
 
465
	while ( height-- ) {
466
	        int sR, sG, sB;
467
		int dR, dG, dB;
468
		DUFFS_LOOP(
469
		{
470
			if ( *src != ckey ) {
471
			        Uint32 pixel;
472
				sR = srcpal[*src].r;
473
				sG = srcpal[*src].g;
474
				sB = srcpal[*src].b;
475
				DISEMBLE_RGB(dst, dstbpp, dstfmt,
476
							pixel, dR, dG, dB);
477
				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
478
			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
479
			}
480
			src++;
481
			dst += dstbpp;
482
		},
483
		width);
484
		src += srcskip;
485
		dst += dstskip;
486
	}
487
}
488
 
489
static SDL_loblit one_blit[] = {
490
	NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
491
};
492
 
493
static SDL_loblit one_blitkey[] = {
494
        NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
495
};
496
 
497
SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
498
{
499
	int which;
500
	SDL_PixelFormat *dstfmt;
501
 
502
	dstfmt = surface->map->dst->format;
503
	if ( dstfmt->BitsPerPixel < 8 ) {
504
		which = 0;
505
	} else {
506
		which = dstfmt->BytesPerPixel;
507
	}
508
	switch(blit_index) {
509
	case 0:			/* copy */
510
	    return one_blit[which];
511
 
512
	case 1:			/* colorkey */
513
	    return one_blitkey[which];
514
 
515
	case 2:			/* alpha */
516
	    /* Supporting 8bpp->8bpp alpha is doable but requires lots of
517
	       tables which consume space and takes time to precompute,
518
	       so is better left to the user */
519
	    return which >= 2 ? Blit1toNAlpha : NULL;
520
 
521
	case 3:			/* alpha + colorkey */
522
	    return which >= 2 ? Blit1toNAlphaKey : NULL;
523
 
524
	}
525
	return NULL;
526
}