Home | History | Annotate | Download | only in cybergfx
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2006 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 (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 #include "SDL_endian.h"
     25 #include "SDL_video.h"
     26 #include "../SDL_sysvideo.h"
     27 #include "../SDL_blit.h"
     28 #include "SDL_cgxvideo.h"
     29 
     30 static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
     31 					SDL_Surface *dst, SDL_Rect *dstrect);
     32 
     33 // These are needed to avoid register troubles with gcc -O2!
     34 
     35 #if defined(__SASC) || defined(__PPC__) || defined(MORPHOS)
     36 #define BMKBRP(a,b,c,d,e,f,g,h,i,j) BltMaskBitMapRastPort(a,b,c,d,e,f,g,h,i,j)
     37 #define	BBRP(a,b,c,d,e,f,g,h,i) BltBitMapRastPort(a,b,c,d,e,f,g,h,i)
     38 #define BBB(a,b,c,d,e,f,g,h,i,j,k) BltBitMap(a,b,c,d,e,f,g,h,i,j,k)
     39 #else
     40 void BMKBRP(struct BitMap *a,WORD b, WORD c,struct RastPort *d,WORD e,WORD f,WORD g,WORD h,UBYTE i,APTR j)
     41 {BltMaskBitMapRastPort(a,b,c,d,e,f,g,h,i,j);}
     42 
     43 void BBRP(struct BitMap *a,WORD b, WORD c,struct RastPort *d,WORD e,WORD f,WORD g,WORD h,UBYTE i)
     44 {BltBitMapRastPort(a,b,c,d,e,f,g,h,i);}
     45 
     46 void BBB(struct BitMap *a,WORD b, WORD c,struct BitMap *d,WORD e,WORD f,WORD g,WORD h,UBYTE i,UBYTE j,UWORD *k)
     47 {BltBitMap(a,b,c,d,e,f,g,h,i,j,k);}
     48 #endif
     49 
     50 int CGX_SetHWColorKey(_THIS,SDL_Surface *surface, Uint32 key)
     51 {
     52 	if(surface->hwdata)
     53 	{
     54 		if(surface->hwdata->mask)
     55 			SDL_free(surface->hwdata->mask);
     56 
     57 		if(surface->hwdata->mask=SDL_malloc(RASSIZE(surface->w,surface->h)))
     58 		{
     59 			Uint32 pitch,ok=0;
     60 			APTR lock;
     61 
     62 			SDL_memset(surface->hwdata->mask,255,RASSIZE(surface->w,surface->h));
     63 
     64 			D(bug("Building colorkey mask: color: %ld, size: %ld x %ld, %ld bytes...Bpp:%ld\n",key,surface->w,surface->h,RASSIZE(surface->w,surface->h),surface->format->BytesPerPixel));
     65 
     66 			if(lock=LockBitMapTags(surface->hwdata->bmap,LBMI_BASEADDRESS,(ULONG)&surface->pixels,
     67 					LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE))
     68 			{
     69 				switch(surface->format->BytesPerPixel)
     70 				{
     71 					case 1:
     72 					{
     73 						unsigned char k=key;
     74 						register int i,j,t;
     75 						register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels;
     76 
     77 						pitch-=surface->w;
     78 
     79 						for(i=0;i<surface->h;i++)
     80 						{
     81 							for(t=128,j=0;j<surface->w;j++)
     82 							{
     83 								if(*map==k)
     84 									*dest&=~t;
     85 
     86 								t>>=1;
     87 
     88 								if(t==0)
     89 								{
     90 									dest++;
     91 									t=128;
     92 								}
     93 								map++;
     94 							}
     95 							map+=pitch;
     96 						}
     97 					}
     98 					break;
     99 					case 2:
    100 					{
    101 						Uint16 k=key,*mapw;
    102 						register int i,j,t;
    103 						register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels;
    104 
    105 						for(i=surface->h;i;--i)
    106 						{
    107 							mapw=(Uint16 *)map;
    108 
    109 							for(t=128,j=surface->w;j;--j)
    110 							{
    111 								if(*mapw==k)
    112 									*dest&=~t;
    113 
    114 								t>>=1;
    115 
    116 								if(t==0)
    117 								{
    118 									dest++;
    119 									t=128;
    120 								}
    121 								mapw++;
    122 							}
    123 							map+=pitch;
    124 						}
    125 					}
    126 					break;
    127 					case 4:
    128 					{
    129 						Uint32 *mapl;
    130 						register int i,j,t;
    131 						register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels;
    132 
    133 						for(i=surface->h;i;--i)
    134 						{
    135 							mapl=(Uint32 *)map;
    136 
    137 							for(t=128,j=surface->w;j;--j)
    138 							{
    139 								if(*mapl==key)
    140 									*dest&=~t;
    141 
    142 								t>>=1;
    143 
    144 								if(t==0)
    145 								{
    146 									dest++;
    147 									t=128;
    148 								}
    149 								mapl++;
    150 							}
    151 							map+=pitch;
    152 						}
    153 
    154 					}
    155 					break;
    156 					default:
    157 						D(bug("Pixel mode non supported for color key..."));
    158 						SDL_free(surface->hwdata->mask);
    159 						surface->hwdata->mask=NULL;
    160 						ok=-1;
    161 				}
    162 				UnLockBitMap(lock);
    163 				D(bug("...Colorkey built!\n"));
    164 				return ok;
    165 			}
    166 		}
    167 	}
    168 	D(bug("HW colorkey not supported for this depth\n"));
    169 
    170 	return -1;
    171 }
    172 
    173 int CGX_CheckHWBlit(_THIS,SDL_Surface *src,SDL_Surface *dst)
    174 {
    175 // Doesn't support yet alpha blitting
    176 
    177 	if(src->hwdata&& !(src->flags & (SDL_SRCALPHA)))
    178 	{
    179 		D(bug("CheckHW blit... OK!\n"));
    180 
    181 		if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
    182 			if ( CGX_SetHWColorKey(this, src, src->format->colorkey) < 0 ) {
    183 				src->flags &= ~SDL_HWACCEL;
    184 				return -1;
    185 			}
    186 		}
    187 
    188 		src->flags|=SDL_HWACCEL;
    189 		src->map->hw_blit = CGX_HWAccelBlit;
    190 		return 1;
    191 	}
    192 	else
    193 		src->flags &= ~SDL_HWACCEL;
    194 
    195 	D(bug("CheckHW blit... NO!\n"));
    196 
    197 	return 0;
    198 }
    199 
    200 static int temprp_init=0;
    201 static struct RastPort temprp;
    202 
    203 static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
    204 					SDL_Surface *dst, SDL_Rect *dstrect)
    205 {
    206 	struct SDL_VideoDevice *this=src->hwdata->videodata;
    207 
    208 //	D(bug("Accel blit!\n"));
    209 
    210 	if(src->flags&SDL_SRCCOLORKEY && src->hwdata->mask)
    211 	{
    212 		if(dst==SDL_VideoSurface)
    213 		{
    214 			BMKBRP(src->hwdata->bmap,srcrect->x,srcrect->y,
    215 						SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop,
    216 						srcrect->w,srcrect->h,0xc0,src->hwdata->mask);
    217 		}
    218 		else if(dst->hwdata)
    219 		{
    220 			if(!temprp_init)
    221 			{
    222 				InitRastPort(&temprp);
    223 				temprp_init=1;
    224 			}
    225 			temprp.BitMap=(struct BitMap *)dst->hwdata->bmap;
    226 
    227 			BMKBRP(src->hwdata->bmap,srcrect->x,srcrect->y,
    228 						&temprp,dstrect->x,dstrect->y,
    229 						srcrect->w,srcrect->h,0xc0,src->hwdata->mask);
    230 
    231 		}
    232 	}
    233 	else if(dst==SDL_VideoSurface)
    234 	{
    235 		BBRP(src->hwdata->bmap,srcrect->x,srcrect->y,SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop,srcrect->w,srcrect->h,0xc0);
    236 	}
    237 	else if(dst->hwdata)
    238 		BBB(src->hwdata->bmap,srcrect->x,srcrect->y,dst->hwdata->bmap,dstrect->x,dstrect->y,srcrect->w,srcrect->h,0xc0,0xff,NULL);
    239 
    240 	return 0;
    241 }
    242 
    243 int CGX_FillHWRect(_THIS,SDL_Surface *dst,SDL_Rect *dstrect,Uint32 color)
    244 {
    245 	if(dst==SDL_VideoSurface)
    246 	{
    247 		FillPixelArray(SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop,dstrect->w,dstrect->h,color);
    248 	}
    249 	else if(dst->hwdata)
    250 	{
    251 		if(!temprp_init)
    252 		{
    253 			InitRastPort(&temprp);
    254 			temprp_init=1;
    255 		}
    256 
    257 		temprp.BitMap=(struct BitMap *)dst->hwdata->bmap;
    258 
    259 		FillPixelArray(&temprp,dstrect->x,dstrect->y,dstrect->w,dstrect->h,color);
    260 	}
    261 	return 0;
    262 }
    263