BlitPixie API

BlitPixie Logo

"fairie magic" written by Anders F Björklund <afb@algonet.se>

Routines | Platforms | Using BlitPixie | Prototypes

Routines

Currently the BlitPixie family of blitters consists of :

Routines | Platforms | Using BlitPixie | Prototypes

Platforms

The blitters come in one or several of four versions:

Supported compilers:

The assembly versions use CodeWarrior's inline assembly, with some #defines to make stuff more readable.
The inline assembly is separated to stand-alone assembler files for MPW's assemblers, using a script.

Shared libraries are supplied for use by all environments.

Routines | Platforms | Using BlitPixie | Prototypes

Using BlitPixie

The blitters commonly accept a baseAddr which is a pointer to the start of pixel memory, and a rowBytes which is the offset in bytes from one line of pixels to the next. Pointer parameters are declared as unsigned char * (UInt8*), and integer parameters as unsigned long (UInt32).

The blitter routines work in one of the following bit depths:
Bits per pixelBytes per pixelPointer typeColors
81unsigned char256 Colors
162unsigned shortThousands
324unsigned longMillions

Other pixel depths, such as 1,2,4 or 24 bits are not supported (except with BlitPixieAllBit on the 68k). Pixel conversions are not supported at all.

To access the pixel memory on the 68k, the processor should be put in 32-bit mode (instead of 24-bit mode) if it isn't already and the pixel map so requires. This can be checked by using PixMap32Bit and changed using SwapMMUMode. Or always use 32-bit mode...

BlitPixie and Drawing Directly to the Screen

Using BlitPixie should be no more 'dangerous' than using Quickdraw's CopyBits.

For a long time Apple, Inc.'s official position was that drawing directly to the screen in this way is not officially supported, and is not guaranteed to work with future hardware or system software. More recently, Apple has stated that direct-to-screen drawing will continue to be supported by the next generation of system software (System 8), providing certain guidelines are followed. BlitPixie follows those guidelines that are its responsibility; other guidelines are the responsibility of the programmer (you), and are described below.

In general, the major problem with direct-to-screen drawing is simply that it's difficult to guarantee that it has been done correctly and will work for all end users. Drawing to the screen is much more sensitive to differences in user's hardware and system setups than most code, so it's harder to test.

Guidelines for drawing directly to the screen

Compiled Sprites

The sprite compiler converts a pixel mask into a set of 68k assembly instructions (returned as a function ptr), that will draw the masked sprite using the image data when you call it.

NOTE: This function obviously performs no clipping, so be careful.

RLE Sprites

The Run-Length-Encoding format is designed for: All RLE tokens are 4 bytes, the first byte is the token type and the next three is the token count. After the token can additional follow extra data, see below table, but the data is always a multiple of 4 bytes wide.
typedef unsigned long       TokenDataType;
#define kTokenShift         24
#define kCountMask          0x00FFFFFFL
TokenValueCountExtra Data
kEndShapeToken00always zero-
kLineStartToken01offset to next
linestart token
-
kDrawPixelsToken02bytes to drawcount bytes of pixel data +
0-3 bytes of padding to align to next 4-byte boundary
kSkipPixelsToken03bytes to skip-
kSingleColorToken04bytes to fill4 bytes (1/2/4 pixels) to fill repeatedly with

Example:

kLineStartToken #12
- kSkipPixelsToken #12
- kDrawPixelsToken #8 $FF00FF00FF00FF00
kLineStartToken #16
- kSkipPixelsToken #16
- kDrawPixelsToken  #4 $FF00
- kSingleColorToken #20 $0000
- kDrawPixelsToken  #4 $FF00
kEndShapeToken #0

Routines | Platforms | Using BlitPixie | Prototypes

Function Prototypes

///--------------------------------------------------------------------------------------
//    BlitPixieHeader.h
//        general header for BlitPixie, a collection of fast software blitters
///--------------------------------------------------------------------------------------

#ifndef __BLITPIXIE__
#define __BLITPIXIE__

#include "BlitPixieSystem.h"        // various system-dependant type definitions

#ifndef BLITPIXIE_DEBUG                // remove debugger calls, if not debugging (release code)
#undef BLITPIXIE_DEBUGGER
#define BLITPIXIE_DEBUGGER(x)
#endif /* BLITPIXIE_DEBUG */

#ifndef BLITPIXIE_ASSERT           // debugging assertion
#define BLITPIXIE_ASSERT(x) if (!(x)) { BLITPIXIE_DEBUGGER("Assertion failed: " #x " (" __FILE__ ")"); }
#endif /* BLITPIXIE_ASSERT */

#include "BlitPixieVersion.h"       // library version

///--------------------------------------------------------------------------------------
//    Type definitions and structs
///--------------------------------------------------------------------------------------

    // The following struct is used by BlitPixieDoubleRects.
struct BlitPixieOffsetInfo
{
    long   srcOffsetAtoB;  /* offset from right of rect A to left of rect B */
    long   srcOffsetBtoA;  /* offset from right of rect B to left of rect A, in the next row */
    long   dstOffsetAtoB;
    long   dstOffsetBtoA;
};

typedef struct BlitPixieOffsetInfo    BlitPixieOffsetInfo, *BlitPixieOffsetInfoPtr;

    // which kind of CPU we're running on, see BlitPixieGetProcessorType
extern short  gBlitPixieProcessorType;

    // The following is used by the blitters, for optimal performance
enum BlitPixieProcessorTypes
{
    kUnknownProcessor = 0,

    // 68k Processors
    k68000,     
    k68010,
    k68020,
    k68030,
    k68040,

    // PPC Processors
    k601,       
    k603,
    k604,
    kG3,
    kG4
};


///--------------------------------------------------------------------------------------
//    Library functions
///--------------------------------------------------------------------------------------

    // get numeric version
unsigned long BlitPixieVersion( void );

    // get string version
void BlitPixieVersionString( char string[BLITPIXIE_VERSION_STRINGLEN] );

    // call this function once at startup
void BlitPixieGetProcessorType(void);

///--------------------------------------------------------------------------------------
//    utility functions, for C blitters to use
///--------------------------------------------------------------------------------------

    // copy a block of memory, using longwords
void BlitPixieMemCopy( unsigned char *dst, unsigned char *src, int bytes);

    // set a block of memory to a repeated longword value
void BlitPixieMemSet( unsigned char *dst, unsigned long value, int bytes );

///--------------------------------------------------------------------------------------
//    Blitters that work in 8-bits, 16-bits, and 32-bits
///--------------------------------------------------------------------------------------

void BlitPixieClear(
    unsigned char *dstPixel,      unsigned long dstRowBytes,    
    unsigned short bytes,         unsigned short rows,      
    unsigned long color);

void BlitPixieRect(
    unsigned char *srcPixel,      unsigned char *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,        
    unsigned short bytes,         unsigned short rows );

void BlitPixieDoubleRects(
    unsigned char *src,               unsigned char *dst,
    unsigned short bytesA,            unsigned short bytesB,
    unsigned short rows,          BlitPixieOffsetInfo *info );


void BlitPixieBlitClear(
    unsigned char *src,               unsigned char *dst,               unsigned long color,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows);

void BlitPixieBlitErase(
    unsigned char *src,               unsigned char *dst,               unsigned char *background,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows);


void BlitPixieMask(
    unsigned char *srcPixel,      unsigned char *dstPixel,      unsigned char *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows );

void BlitPixiePartialMask(
    unsigned char *srcPixel,      unsigned char *dstPixel,      unsigned char *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows );

void BlitPixieMaskColor(
    unsigned long srcColor,           unsigned char *dstPixel,      unsigned char *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows );

Boolean BlitPixieMaskCollision(
    unsigned char *maskPtr1,      unsigned char *maskPtr2,  
    unsigned long rowBytes1,      unsigned long rowBytes2,
    unsigned short bytes,         unsigned short rows );


///--------------------------------------------------------------------------------------
//    Blitters that have different routines for different bit depths
///--------------------------------------------------------------------------------------

void BlitPixieColorKey8Bit(
    unsigned char *srcPixel,      unsigned char *dstPixel,          
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows,              
    unsigned char colorKey);

void BlitPixieColorKey16Bit(
    unsigned short *srcPixel,     unsigned short *dstPixel,         
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows,              
    unsigned short colorKey);

void BlitPixieColorKey32Bit(
    unsigned long *srcPixel,      unsigned long *dstPixel,          
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows,              
    unsigned long colorKey);


void BlitPixieFlip8Bit(
    unsigned char *srcPixel,      unsigned char *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

void BlitPixieFlip16Bit(
    unsigned short *srcPixel,     unsigned short *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

void BlitPixieFlip32Bit(
    unsigned long *srcPixel,      unsigned long *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);


void BlitPixieFlipMask8Bit(
    unsigned char *srcPixel,      unsigned char *dstPixel,      unsigned char *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

void BlitPixieFlipMask16Bit(
    unsigned short *srcPixel,     unsigned short *dstPixel,     unsigned short *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

void BlitPixieFlipMask32Bit(
    unsigned long *srcPixel,      unsigned long *dstPixel,      unsigned long *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

Boolean BlitPixieFlipMaskCollision(
    unsigned char *maskPtr1,      unsigned char *maskPtr2,  
    unsigned long rowBytes1,      unsigned long rowBytes2,
    unsigned short bytes,         unsigned short rows );

void BlitPixieFlipMaskColor(
    unsigned long srcColor,           unsigned char *dstPixel,      unsigned char *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short bytes,         unsigned short rows );


void BlitPixieDoubled8Bit(
    unsigned char *srcPixel,      unsigned char *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

void BlitPixieDoubled16Bit(
    unsigned short *srcPixel,     unsigned short *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);

void BlitPixieDoubled32Bit(
    unsigned long *srcPixel,      unsigned long *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned short width,         unsigned short height);


void BlitPixieScale8Bit(
    unsigned char *src,   unsigned long srcBytes,   long width1, long height1, long startu,
    unsigned char *dst,   unsigned long dstBytes,   long width2, long height2, long startv );

void BlitPixieScaleMask8Bit(
    unsigned char *src,   unsigned long srcBytes,   long width1, long height1, long startu,
    unsigned char *dst,   unsigned long dstBytes,   long width2, long height2, long startv,
    unsigned char *mask );

void BlitPixieScale16Bit(
    unsigned short *src, unsigned long srcBytes, long width1, long height1, long startu,
    unsigned short *dst, unsigned long dstBytes, long width2, long height2, long startv );

void BlitPixieScaleMask16Bit(
    unsigned short *src, unsigned long srcBytes, long width1, long height1, long startu,
    unsigned short *dst, unsigned long dstBytes, long width2, long height2, long startv,
    unsigned short *mask );

void BlitPixieScale32Bit(
    unsigned long *src,   unsigned long srcBytes,   long width1, long height1, long startu,
    unsigned long *dst,   unsigned long dstBytes,   long width2, long height2, long startv );

void BlitPixieScaleMask32Bit(
    unsigned long *src,   unsigned long srcBytes,   long width1, long height1, long startu,
    unsigned long *dst,   unsigned long dstBytes,   long width2, long height2, long startv,
    unsigned long *mask );


void BlitPixieRotoZoom8Bit(
    unsigned char *srcPixel,      unsigned char *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned long width1,         unsigned long height1,        
    unsigned long width2,         unsigned long height2,
    unsigned long angle,          unsigned long zoom    );

void BlitPixieMaskRotoZoom8Bit(
    unsigned char *srcPixel,      unsigned char *dstPixel,      unsigned char *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned long width1,         unsigned long height1,        
    unsigned long width2,         unsigned long height2,
    unsigned long angle,          unsigned long zoom    );

void BlitPixieRotoZoom16Bit(
    unsigned short *srcPixel,     unsigned short *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned long width1,         unsigned long height1,        
    unsigned long width2,         unsigned long height2,
    unsigned long angle,          unsigned long zoom    );

void BlitPixieMaskRotoZoom16Bit(
    unsigned short *srcPixel,     unsigned short *dstPixel,     unsigned short *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned long width1,         unsigned long height1,        
    unsigned long width2,         unsigned long height2,
    unsigned long angle,          unsigned long zoom    );

void BlitPixieRotoZoom32Bit(
    unsigned long *srcPixel,      unsigned long *dstPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned long width1,         unsigned long height1,        
    unsigned long width2,         unsigned long height2,
    unsigned long angle,          unsigned long zoom    );

void BlitPixieMaskRotoZoom32Bit(
    unsigned long *srcPixel,      unsigned long *dstPixel,      unsigned long *maskPixel,
    unsigned long srcRowBytes,        unsigned long dstRowBytes,
    unsigned long width1,         unsigned long height1,        
    unsigned long width2,         unsigned long height2,
    unsigned long angle,          unsigned long zoom    );

///--------------------------------------------------------------------------------------
//    zero-overdraw dirty rect screen blitter, works in 8-bits, 16-bits, and 32-bits
///--------------------------------------------------------------------------------------

Boolean BlitPixieInitDirtyRects(
    unsigned char *src,
    unsigned char *dst,
    unsigned short width,
    unsigned short height,
    unsigned short depth);

void BlitPixieAddDirtyRect(
    Rect *dirtyRect );

void BlitPixieClearDirtyRects(void);

void BlitPixieExitDirtyRects(void);


void BlitPixieBlitClearDirtyRects(
    unsigned char *src,           unsigned char *dst,           unsigned long color,
    unsigned long srcRowBytes,    unsigned long dstRowBytes);

void BlitPixieBlitEraseDirtyRects(
    unsigned char *src,           unsigned char *dst,           unsigned char *background,
    unsigned long srcRowBytes,    unsigned long dstRowBytes);

///--------------------------------------------------------------------------------------
//    pre-generated RLE tokens blitter, works in 8-bits, 16-bits, and 32-bits
///--------------------------------------------------------------------------------------

#define BLITPIXIE_USE_DRAW_SPANS   1   // whether to use spans of single color ?

typedef unsigned long                TokenDataType, *TokenDataPtr, **TokenDataHdl;
#define kTokenShift                    24
#define kCountMask                 0x00FFFFFFL

#define kEndShapeToken             0x00L
#define kLineStartToken                0x01L
#define kDrawPixelsToken           0x02L
#define kSkipPixelsToken           0x03L
#if BLITPIXIE_USE_DRAW_SPANS
#define kSingleColorToken          0x04L // (this token not used in the original code)
#endif

void BlitPixieRLE(
    unsigned char *srcTokens,
    unsigned char *dstPixel,      unsigned long dstRowBytes);

void BlitPixieRLEClipped(
    unsigned char *srcTokens,
    unsigned char *dstPixel,      unsigned long dstOffset,
    Rect *dstClipRect);

void BlitPixieRLEColor(
    unsigned char *srcTokens,     unsigned long srcColor,
    unsigned char *dstPixel,      unsigned long dstRowBytes);

void BlitPixieRLEColorClipped(
    unsigned char *srcTokens,     unsigned long srcColor,
    unsigned char *dstPixel,      unsigned long dstRowBytes,
    Rect *dstClipRect );

Boolean BlitPixieRLECollision(
    unsigned char *srcTokens,     unsigned char *dstTokens,
    Rect *srcRect,                  Rect *dstRect);

#ifdef macintosh

    // on the Macintosh, the compiler returns a handle from "NewHandle"
OSErr BlitPixieRLEParsePixels(
    unsigned char *srcStartAddrP,
    unsigned char *maskStartAddrP,
    unsigned long rowBytes,
    unsigned short width,
    unsigned short height,
    unsigned short depth,
    TokenDataHdl *newPixCodeH);

#else

    // on other systems, the compiler returns a pointer from "malloc"
int BlitPixieRLEParsePixels(
    unsigned char *srcStartAddrP,
    unsigned char *maskStartAddrP,
    unsigned long rowBytes,
    unsigned short width,
    unsigned short height,
    unsigned short depth,
    TokenDataPtr *newPixCodeP);

#endif /* macintosh */

///--------------------------------------------------------------------------------------
//    68k blitter that works in depths below 8 bits per pixel too (i.e. in : 1,2,4,8,16,32)
///--------------------------------------------------------------------------------------

#if defined(macintosh) && GENERATING68K

void BlitPixieAllBitRect(
    register unsigned char *srcPixelP,
    register unsigned char *dstPixelP,
    register unsigned long srcRowBytes,
    register unsigned long dstRowBytes,
    unsigned long numBytesPerRow,
    unsigned long rowsToCopy,
    register unsigned long srcExtraStart,
    register unsigned long dstExtraStart,
    register unsigned long dstExtraEnd);
    
void BlitPixieAllBitMask(
    register unsigned char *srcPixelP,
    register unsigned char *dstPixelP,
    register unsigned char *maskPixelP,
    register unsigned long srcRowBytes,
    register unsigned long dstRowBytes,
    unsigned long numBytesPerRow,
    unsigned long rowsToCopy,
    register unsigned long srcExtraStart,
    register unsigned long dstExtraStart,
    register unsigned long dstExtraEnd);
    
void BlitPixieAllBitPartialMask(
    register unsigned char *srcPixelP,
    register unsigned char *dstPixelP,
    register unsigned char *maskPixelP,
    register unsigned long srcRowBytes,
    register unsigned long dstRowBytes,
    unsigned long numBytesPerRow,
    unsigned long rowsToCopy,
    register unsigned long srcExtraStart,
    register unsigned long dstExtraStart,
    register unsigned long dstExtraEnd);

#endif /* GENERATING68K */

///--------------------------------------------------------------------------------------
//    sprite compiler for 68k code, works in 8-bits, 16-bits, and 32-bits
///--------------------------------------------------------------------------------------

#if defined(macintosh) && GENERATING68K

    // blitter requires a pointer to external pixel data (only mask in code)
    // this compiled blitter does NOT handle ANY clipping!
    // use BlitPixieMask for that (which requires a pixel mask).
typedef void (*BlitFuncPtr)(
    long srcRowBytes,
    long dstRowBytes,
    char *srcBaseAddr,
    char *dstBaseAddr);

typedef BlitFuncPtr        *PixelCodeHdl;

OSErr BlitPixieCodeParsePixels(
    unsigned char *maskStartAddrP,
    unsigned long rowBytes,
    unsigned short numBytesPerScanLine,
    unsigned short numberOfScanLines,
    PixelCodeHdl* newPixCodeH);

#endif /* GENERATING68K */

///--------------------------------------------------------------------------------------

Routines | Platforms | Using BlitPixie | Prototypes

Last updated on 00-03-11 by afb.