| /* |
| SDL - Simple DirectMedia Layer |
| Copyright (C) 1997-2006 Sam Lantinga |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 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 |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| |
| Sam Lantinga |
| slouken@libsdl.org |
| */ |
| #include "SDL_config.h" |
| |
| #include "SDL_endian.h" |
| #include "SDL_video.h" |
| #include "../SDL_sysvideo.h" |
| #include "../SDL_blit.h" |
| #include "SDL_cgxvideo.h" |
| |
| static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, |
| SDL_Surface *dst, SDL_Rect *dstrect); |
| |
| // These are needed to avoid register troubles with gcc -O2! |
| |
| #if defined(__SASC) || defined(__PPC__) || defined(MORPHOS) |
| #define BMKBRP(a,b,c,d,e,f,g,h,i,j) BltMaskBitMapRastPort(a,b,c,d,e,f,g,h,i,j) |
| #define BBRP(a,b,c,d,e,f,g,h,i) BltBitMapRastPort(a,b,c,d,e,f,g,h,i) |
| #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) |
| #else |
| void BMKBRP(struct BitMap *a,WORD b, WORD c,struct RastPort *d,WORD e,WORD f,WORD g,WORD h,UBYTE i,APTR j) |
| {BltMaskBitMapRastPort(a,b,c,d,e,f,g,h,i,j);} |
| |
| void BBRP(struct BitMap *a,WORD b, WORD c,struct RastPort *d,WORD e,WORD f,WORD g,WORD h,UBYTE i) |
| {BltBitMapRastPort(a,b,c,d,e,f,g,h,i);} |
| |
| 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) |
| {BltBitMap(a,b,c,d,e,f,g,h,i,j,k);} |
| #endif |
| |
| int CGX_SetHWColorKey(_THIS,SDL_Surface *surface, Uint32 key) |
| { |
| if(surface->hwdata) |
| { |
| if(surface->hwdata->mask) |
| SDL_free(surface->hwdata->mask); |
| |
| if(surface->hwdata->mask=SDL_malloc(RASSIZE(surface->w,surface->h))) |
| { |
| Uint32 pitch,ok=0; |
| APTR lock; |
| |
| SDL_memset(surface->hwdata->mask,255,RASSIZE(surface->w,surface->h)); |
| |
| 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)); |
| |
| if(lock=LockBitMapTags(surface->hwdata->bmap,LBMI_BASEADDRESS,(ULONG)&surface->pixels, |
| LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE)) |
| { |
| switch(surface->format->BytesPerPixel) |
| { |
| case 1: |
| { |
| unsigned char k=key; |
| register int i,j,t; |
| register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels; |
| |
| pitch-=surface->w; |
| |
| for(i=0;i<surface->h;i++) |
| { |
| for(t=128,j=0;j<surface->w;j++) |
| { |
| if(*map==k) |
| *dest&=~t; |
| |
| t>>=1; |
| |
| if(t==0) |
| { |
| dest++; |
| t=128; |
| } |
| map++; |
| } |
| map+=pitch; |
| } |
| } |
| break; |
| case 2: |
| { |
| Uint16 k=key,*mapw; |
| register int i,j,t; |
| register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels; |
| |
| for(i=surface->h;i;--i) |
| { |
| mapw=(Uint16 *)map; |
| |
| for(t=128,j=surface->w;j;--j) |
| { |
| if(*mapw==k) |
| *dest&=~t; |
| |
| t>>=1; |
| |
| if(t==0) |
| { |
| dest++; |
| t=128; |
| } |
| mapw++; |
| } |
| map+=pitch; |
| } |
| } |
| break; |
| case 4: |
| { |
| Uint32 *mapl; |
| register int i,j,t; |
| register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels; |
| |
| for(i=surface->h;i;--i) |
| { |
| mapl=(Uint32 *)map; |
| |
| for(t=128,j=surface->w;j;--j) |
| { |
| if(*mapl==key) |
| *dest&=~t; |
| |
| t>>=1; |
| |
| if(t==0) |
| { |
| dest++; |
| t=128; |
| } |
| mapl++; |
| } |
| map+=pitch; |
| } |
| |
| } |
| break; |
| default: |
| D(bug("Pixel mode non supported for color key...")); |
| SDL_free(surface->hwdata->mask); |
| surface->hwdata->mask=NULL; |
| ok=-1; |
| } |
| UnLockBitMap(lock); |
| D(bug("...Colorkey built!\n")); |
| return ok; |
| } |
| } |
| } |
| D(bug("HW colorkey not supported for this depth\n")); |
| |
| return -1; |
| } |
| |
| int CGX_CheckHWBlit(_THIS,SDL_Surface *src,SDL_Surface *dst) |
| { |
| // Doesn't support yet alpha blitting |
| |
| if(src->hwdata&& !(src->flags & (SDL_SRCALPHA))) |
| { |
| D(bug("CheckHW blit... OK!\n")); |
| |
| if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { |
| if ( CGX_SetHWColorKey(this, src, src->format->colorkey) < 0 ) { |
| src->flags &= ~SDL_HWACCEL; |
| return -1; |
| } |
| } |
| |
| src->flags|=SDL_HWACCEL; |
| src->map->hw_blit = CGX_HWAccelBlit; |
| return 1; |
| } |
| else |
| src->flags &= ~SDL_HWACCEL; |
| |
| D(bug("CheckHW blit... NO!\n")); |
| |
| return 0; |
| } |
| |
| static int temprp_init=0; |
| static struct RastPort temprp; |
| |
| static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, |
| SDL_Surface *dst, SDL_Rect *dstrect) |
| { |
| struct SDL_VideoDevice *this=src->hwdata->videodata; |
| |
| // D(bug("Accel blit!\n")); |
| |
| if(src->flags&SDL_SRCCOLORKEY && src->hwdata->mask) |
| { |
| if(dst==SDL_VideoSurface) |
| { |
| BMKBRP(src->hwdata->bmap,srcrect->x,srcrect->y, |
| SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop, |
| srcrect->w,srcrect->h,0xc0,src->hwdata->mask); |
| } |
| else if(dst->hwdata) |
| { |
| if(!temprp_init) |
| { |
| InitRastPort(&temprp); |
| temprp_init=1; |
| } |
| temprp.BitMap=(struct BitMap *)dst->hwdata->bmap; |
| |
| BMKBRP(src->hwdata->bmap,srcrect->x,srcrect->y, |
| &temprp,dstrect->x,dstrect->y, |
| srcrect->w,srcrect->h,0xc0,src->hwdata->mask); |
| |
| } |
| } |
| else if(dst==SDL_VideoSurface) |
| { |
| 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); |
| } |
| else if(dst->hwdata) |
| BBB(src->hwdata->bmap,srcrect->x,srcrect->y,dst->hwdata->bmap,dstrect->x,dstrect->y,srcrect->w,srcrect->h,0xc0,0xff,NULL); |
| |
| return 0; |
| } |
| |
| int CGX_FillHWRect(_THIS,SDL_Surface *dst,SDL_Rect *dstrect,Uint32 color) |
| { |
| if(dst==SDL_VideoSurface) |
| { |
| FillPixelArray(SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop,dstrect->w,dstrect->h,color); |
| } |
| else if(dst->hwdata) |
| { |
| if(!temprp_init) |
| { |
| InitRastPort(&temprp); |
| temprp_init=1; |
| } |
| |
| temprp.BitMap=(struct BitMap *)dst->hwdata->bmap; |
| |
| FillPixelArray(&temprp,dstrect->x,dstrect->y,dstrect->w,dstrect->h,color); |
| } |
| return 0; |
| } |