view src/video/cybergfx/SDL_cgxaccel.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents d910939febfa
children 4da1ee79c9af
line wrap: on
line source

/*
    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;
}

/* vi: set ts=4 sw=4 expandtab: */