diff src/video/SDL_blit_0.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children e85e03f195b4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/SDL_blit_0.c	Thu Apr 26 16:45:43 2001 +0000
@@ -0,0 +1,475 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id$";
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "SDL_types.h"
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/* Functions to blit from bitmaps to other surfaces */
+
+static void BlitBto1(SDL_BlitInfo *info)
+{
+	int c;
+	int width, height;
+	Uint8 *src, *map, *dst;
+	int srcskip, dstskip;
+
+	/* Set up some basic variables */
+	width = info->d_width;
+	height = info->d_height;
+	src = info->s_pixels;
+	srcskip = info->s_skip;
+	dst = info->d_pixels;
+	dstskip = info->d_skip;
+	map = info->table;
+	srcskip += width-(width+7)/8;
+
+	if ( map ) {
+		while ( height-- ) {
+		        Uint8 byte = 0, bit;
+	    		for ( c=0; c<width; ++c ) {
+				if ( (c%8) == 0 ) {
+					byte = *src++;
+				}
+				bit = (byte&0x80)>>7;
+				if ( 1 ) {
+				  *dst = map[bit];
+				}
+				dst++;
+				byte <<= 1;
+			}
+			src += srcskip;
+			dst += dstskip;
+		}
+	} else {
+		while ( height-- ) {
+		        Uint8 byte = 0, bit;
+	    		for ( c=0; c<width; ++c ) {
+				if ( (c%8) == 0 ) {
+					byte = *src++;
+				}
+				bit = (byte&0x80)>>7;
+				if ( 1 ) {
+				  *dst = bit;
+				}
+				dst++;
+				byte <<= 1;
+			}
+			src += srcskip;
+			dst += dstskip;
+		}
+	}
+}
+static void BlitBto2(SDL_BlitInfo *info)
+{
+	int c;
+	int width, height;
+	Uint8 *src;
+	Uint16 *map, *dst;
+	int srcskip, dstskip;
+
+	/* Set up some basic variables */
+	width = info->d_width;
+	height = info->d_height;
+	src = info->s_pixels;
+	srcskip = info->s_skip;
+	dst = (Uint16 *)info->d_pixels;
+	dstskip = info->d_skip/2;
+	map = (Uint16 *)info->table;
+	srcskip += width-(width+7)/8;
+
+	while ( height-- ) {
+	        Uint8 byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( 1 ) {
+				*dst = map[bit];
+			}
+			byte <<= 1;
+			dst++;
+		}
+		src += srcskip;
+		dst += dstskip;
+	}
+}
+static void BlitBto3(SDL_BlitInfo *info)
+{
+	int c, o;
+	int width, height;
+	Uint8 *src, *map, *dst;
+	int srcskip, dstskip;
+
+	/* Set up some basic variables */
+	width = info->d_width;
+	height = info->d_height;
+	src = info->s_pixels;
+	srcskip = info->s_skip;
+	dst = info->d_pixels;
+	dstskip = info->d_skip;
+	map = info->table;
+	srcskip += width-(width+7)/8;
+
+	while ( height-- ) {
+	        Uint8 byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( 1 ) {
+				o = bit * 4;
+				dst[0] = map[o++];
+				dst[1] = map[o++];
+				dst[2] = map[o++];
+			}
+			byte <<= 1;
+			dst += 3;
+		}
+		src += srcskip;
+		dst += dstskip;
+	}
+}
+static void BlitBto4(SDL_BlitInfo *info)
+{
+	int width, height;
+	Uint8 *src;
+	Uint32 *map, *dst;
+	int srcskip, dstskip;
+	int c;
+
+	/* Set up some basic variables */
+	width = info->d_width;
+	height = info->d_height;
+	src = info->s_pixels;
+	srcskip = info->s_skip;
+	dst = (Uint32 *)info->d_pixels;
+	dstskip = info->d_skip/4;
+	map = (Uint32 *)info->table;
+	srcskip += width-(width+7)/8;
+
+	while ( height-- ) {
+	        Uint8 byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( 1 ) {
+				*dst = map[bit];
+			}
+			byte <<= 1;
+			dst++;
+		}
+		src += srcskip;
+		dst += dstskip;
+	}
+}
+
+static void BlitBto1Key(SDL_BlitInfo *info)
+{
+        int width = info->d_width;
+	int height = info->d_height;
+	Uint8 *src = info->s_pixels;
+	Uint8 *dst = info->d_pixels;
+	int srcskip = info->s_skip;
+	int dstskip = info->d_skip;
+	Uint32 ckey = info->src->colorkey;
+	Uint8 *palmap = info->table;
+	int c;
+
+	/* Set up some basic variables */
+	srcskip += width-(width+7)/8;
+
+	if ( palmap ) {
+		while ( height-- ) {
+		        Uint8  byte = 0, bit;
+	    		for ( c=0; c<width; ++c ) {
+				if ( (c%8) == 0 ) {
+					byte = *src++;
+				}
+				bit = (byte&0x80)>>7;
+				if ( bit != ckey ) {
+				  *dst = palmap[bit];
+				}
+				dst++;
+				byte <<= 1;
+			}
+			src += srcskip;
+			dst += dstskip;
+		}
+	} else {
+		while ( height-- ) {
+		        Uint8  byte = 0, bit;
+	    		for ( c=0; c<width; ++c ) {
+				if ( (c%8) == 0 ) {
+					byte = *src++;
+				}
+				bit = (byte&0x80)>>7;
+				if ( bit != ckey ) {
+				  *dst = bit;
+				}
+				dst++;
+				byte <<= 1;
+			}
+			src += srcskip;
+			dst += dstskip;
+		}
+	}
+}
+
+static void BlitBto2Key(SDL_BlitInfo *info)
+{
+        int width = info->d_width;
+	int height = info->d_height;
+	Uint8 *src = info->s_pixels;
+	Uint16 *dstp = (Uint16 *)info->d_pixels;
+	int srcskip = info->s_skip;
+	int dstskip = info->d_skip;
+	Uint32 ckey = info->src->colorkey;
+	Uint8 *palmap = info->table;
+	int c;
+
+	/* Set up some basic variables */
+	srcskip += width-(width+7)/8;
+	dstskip /= 2;
+
+	while ( height-- ) {
+	        Uint8 byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( bit != ckey ) {
+				*dstp=((Uint16 *)palmap)[bit];
+			}
+			byte <<= 1;
+			dstp++;
+		}
+		src += srcskip;
+		dstp += dstskip;
+	}
+}
+
+static void BlitBto3Key(SDL_BlitInfo *info)
+{
+        int width = info->d_width;
+	int height = info->d_height;
+	Uint8 *src = info->s_pixels;
+	Uint8 *dst = info->d_pixels;
+	int srcskip = info->s_skip;
+	int dstskip = info->d_skip;
+	Uint32 ckey = info->src->colorkey;
+	Uint8 *palmap = info->table;
+	int c;
+
+	/* Set up some basic variables */
+	srcskip += width-(width+7)/8;
+
+	while ( height-- ) {
+	        Uint8  byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( bit != ckey ) {
+				memcpy(dst, &palmap[bit*4], 3);
+			}
+			byte <<= 1;
+			dst += 3;
+		}
+		src += srcskip;
+		dst += dstskip;
+	}
+}
+
+static void BlitBto4Key(SDL_BlitInfo *info)
+{
+        int width = info->d_width;
+	int height = info->d_height;
+	Uint8 *src = info->s_pixels;
+	Uint32 *dstp = (Uint32 *)info->d_pixels;
+	int srcskip = info->s_skip;
+	int dstskip = info->d_skip;
+	Uint32 ckey = info->src->colorkey;
+	Uint8 *palmap = info->table;
+	int c;
+
+	/* Set up some basic variables */
+	srcskip += width-(width+7)/8;
+	dstskip /= 4;
+
+	while ( height-- ) {
+	        Uint8 byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( bit != ckey ) {
+				*dstp=((Uint32 *)palmap)[bit];
+			}
+			byte <<= 1;
+			dstp++;
+		}
+		src += srcskip;
+		dstp += dstskip;
+	}
+}
+
+static void BlitBtoNAlpha(SDL_BlitInfo *info)
+{
+        int width = info->d_width;
+	int height = info->d_height;
+	Uint8 *src = info->s_pixels;
+	Uint8 *dst = info->d_pixels;
+	int srcskip = info->s_skip;
+	int dstskip = info->d_skip;
+	const SDL_Color *srcpal	= info->src->palette->colors;
+	SDL_PixelFormat *dstfmt = info->dst;
+	int  dstbpp;
+	int c;
+	const int A = info->src->alpha;
+
+	/* Set up some basic variables */
+	dstbpp = dstfmt->BytesPerPixel;
+	srcskip += width-(width+7)/8;
+
+	while ( height-- ) {
+	        Uint8 byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( 1 ) {
+			        Uint32 pixel;
+			        unsigned sR, sG, sB;
+				unsigned dR, dG, dB;
+				sR = srcpal[bit].r;
+				sG = srcpal[bit].g;
+				sB = srcpal[bit].b;
+				DISEMBLE_RGB(dst, dstbpp, dstfmt,
+							pixel, dR, dG, dB);
+				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
+			}
+			byte <<= 1;
+			dst += dstbpp;
+		}
+		src += srcskip;
+		dst += dstskip;
+	}
+}
+
+static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
+{
+        int width = info->d_width;
+	int height = info->d_height;
+	Uint8 *src = info->s_pixels;
+	Uint8 *dst = info->d_pixels;
+	int srcskip = info->s_skip;
+	int dstskip = info->d_skip;
+	SDL_PixelFormat *srcfmt = info->src;
+	SDL_PixelFormat *dstfmt = info->dst;
+	const SDL_Color *srcpal	= srcfmt->palette->colors;
+	int dstbpp;
+	int c;
+	const int A = srcfmt->alpha;
+	Uint32 ckey = srcfmt->colorkey;
+
+	/* Set up some basic variables */
+	dstbpp = dstfmt->BytesPerPixel;
+	srcskip += width-(width+7)/8;
+
+	while ( height-- ) {
+	        Uint8  byte = 0, bit;
+	    	for ( c=0; c<width; ++c ) {
+			if ( (c%8) == 0 ) {
+				byte = *src++;
+			}
+			bit = (byte&0x80)>>7;
+			if ( bit != ckey ) {
+			        int sR, sG, sB;
+				int dR, dG, dB;
+				Uint32 pixel;
+				sR = srcpal[bit].r;
+				sG = srcpal[bit].g;
+				sB = srcpal[bit].b;
+				DISEMBLE_RGB(dst, dstbpp, dstfmt,
+							pixel, dR, dG, dB);
+				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
+			}
+			byte <<= 1;
+			dst += dstbpp;
+		}
+		src += srcskip;
+		dst += dstskip;
+	}
+}
+
+static SDL_loblit bitmap_blit[] = {
+	NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
+};
+
+static SDL_loblit colorkey_blit[] = {
+    NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
+};
+
+SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index)
+{
+	int which;
+
+	if ( surface->map->dst->format->BitsPerPixel < 8 ) {
+		which = 0;
+	} else {
+		which = surface->map->dst->format->BytesPerPixel;
+	}
+	switch(blit_index) {
+	case 0:			/* copy */
+	    return bitmap_blit[which];
+
+	case 1:			/* colorkey */
+	    return colorkey_blit[which];
+
+	case 2:			/* alpha */
+	    return which >= 2 ? BlitBtoNAlpha : NULL;
+
+	case 4:			/* alpha + colorkey */
+	    return which >= 2 ? BlitBtoNAlphaKey : NULL;
+	}
+	return NULL;
+}
+